EAPI void ecore_x_window_shape_events_select(Ecore_X_Window win, Eina_Bool on) { LOGFN(__FILE__, __LINE__, __FUNCTION__); if (on) XShapeSelectInput(_ecore_x_disp, win, ShapeNotifyMask); else XShapeSelectInput(_ecore_x_disp, win, 0); } /* ecore_x_window_shape_events_select */
static void reparent(client_t *c, strut_t *s) { XSetWindowAttributes pattr; geom_t f; f = frame_geom(c); pattr.override_redirect = True; pattr.background_pixel = bg.pixel; pattr.border_pixel = bd.pixel; pattr.event_mask = SubMask|ButtonPressMask|ExposureMask|EnterWindowMask; c->frame = XCreateWindow(dpy, root, f.x, f.y, f.w, f.h, BW(c), DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWEventMask, &pattr); #ifdef SHAPE if (shape) { XShapeSelectInput(dpy, c->win, ShapeNotifyMask); set_shape(c); } #endif #ifdef XFT c->xftdraw = XftDrawCreate(dpy, (Drawable)c->frame, DefaultVisual(dpy, DefaultScreen(dpy)), DefaultColormap(dpy, DefaultScreen(dpy))); #endif XAddToSaveSet(dpy, c->win); XSelectInput(dpy, c->win, ColormapChangeMask|PropertyChangeMask); XSetWindowBorderWidth(dpy, c->win, 0); XResizeWindow(dpy, c->win, c->geom.w, c->geom.h); XReparentWindow(dpy, c->win, c->frame, 0, frame_height(c)); send_config(c); }
bool Frame::query_shape() const { int ns, order; XFree(XShapeGetRectangles(QX11Info::display(), c_win, ShapeBounding, &ns, &order)); XShapeSelectInput(QX11Info::display(), c_win, ShapeNotifyMask); if (ns > 1) { qDebug() << "Frame is shape:" << winId() << "Name:" << wm_name << "Client:" << c_win << "State:" << state; return true; } return false; }
/*ARGSUSED*/ extern void setShape(Client *c) { #ifdef SHAPE int n; int order; XRectangle *rect; if (shape) { XShapeSelectInput(dpy, c->window, ShapeNotifyMask); rect = XShapeGetRectangles(dpy, c->window, ShapeBounding, &n, &order); if (n > 1) XShapeCombineShape(dpy, c->parent, ShapeBounding, border - 1, border - 1, c->window, ShapeBounding, ShapeSet); XFree(rect); } #else #endif }
compzillaWindow::compzillaWindow(Display *display, Window win, XWindowAttributes *attrs) : mAttr(*attrs), mDisplay(display), mWindow(win), mPixmap(None), mDamage(None), mLastEntered(None), mIsDestroyed(false), mIsRedirected(false), mIsResizePending(false) { XSelectInput (display, win, (PropertyChangeMask | EnterWindowMask | FocusChangeMask)); #if HAVE_XSHAPE XShapeSelectInput (display, win, ShapeNotifyMask); #endif // Get notified of global cursor changes. // FIXME: This is not very useful, as X has no way of fetching the Cursor // for a given window. //XFixesSelectCursorInput (display, win, XFixesDisplayCursorNotifyMask); XGrabButton (display, AnyButton, AnyModifier, win, true, (ButtonPressMask | ButtonReleaseMask | ButtonMotionMask), GrabModeSync, GrabModeSync, None, None); /* * Set up damage notification. RawRectangles gives us smaller grain * changes, versus NonEmpty which seems to always include the entire * contents. */ mDamage = XDamageCreate (mDisplay, mWindow, XDamageReportRawRectangles); if (mAttr.map_state == IsViewable) { mAttr.map_state = IsUnmapped; Mapped (mAttr.override_redirect); } }
/* The main function */ int main(int argc, char const *argv[]) { Display *dpy; GString *line; unsigned xeventmask; int error_base, shape_event, damage_event; struct { Bool children, creation, mapping, configure, shape; Bool properties, clientmsg; Bool visibility, exposure, damages; Bool pointer, keyboard; } track; dpy = XOpenDisplay(NULL); XSetErrorHandler(xerror_handler); XA_utf8_string = XInternAtom(dpy, "UTF8_STRING", False); XA_wm_state = XInternAtom(dpy, "WM_STATE", False); if (argv[1] && !strcmp(argv[1], "-t")) { Opt_timestamp = 1; optind++; } /* Choose which events we're interested in. */ memset(&track, 0, sizeof(track)); track.children = True; track.creation = True; track.mapping = True; track.configure = True; track.shape = True; track.properties = True; track.clientmsg = True; track.visibility = True; track.keyboard = True; for (; argv[optind]; optind++) { char const *opt; Bool add, del, *which; opt = argv[optind]; add = opt[0] == '+'; del = opt[0] == '-'; if (add || del) opt++; if (!strcmp(opt, "children")) which = &track.children; else if (!strcmp(opt, "create")) which = &track.creation; else if (!strcmp(opt, "map")) which = &track.mapping; else if (!strcmp(opt, "config")) which = &track.configure; else if (!strcmp(opt, "shape")) which = &track.shape; else if (!strcmp(opt, "prop")) which = &track.properties; else if (!strcmp(opt, "ipc")) which = &track.clientmsg; else if (!strcmp(opt, "visibility")) which = &track.visibility; else if (!strcmp(opt, "expose")) which = &track.exposure; else if (!strcmp(opt, "damage")) which = &track.damages; else if (!strcmp(opt, "ptr")) which = &track.pointer; else if (!strcmp(opt, "kbd")) which = &track.keyboard; else break; if (!add && !del) memset(&track, 0, sizeof(track)); *which = !del; } /* for */ xeventmask = 0; if (track.creation || track.mapping || track.configure || track.clientmsg) xeventmask |= track.children ? SubstructureNotifyMask : StructureNotifyMask; if (track.shape) XShapeQueryExtension(dpy, &shape_event, &error_base); if (track.properties) xeventmask |= PropertyChangeMask; if (track.visibility) xeventmask |= VisibilityChangeMask; if (track.exposure) xeventmask |= ExposureMask; if (track.damages) XDamageQueryExtension(dpy, &damage_event, &error_base); if (track.pointer); xeventmask |= EnterWindowMask|LeaveWindowMask; if (track.keyboard) xeventmask |= KeyPressMask|KeyReleaseMask; /* XSelectInput() the windows we're interested in * or the root window. */ if (argv[optind]) do { Window win; char const *errp; win = strtoul(argv[optind], (char **)&errp, 0); if (errp == argv[optind] || *errp) { fprintf(stderr, "%s: what is `%s'?\n", argv[0], argv[optind]); exit(1); } XSelectInput(dpy, win, xeventmask); if (track.shape) XShapeSelectInput(dpy, win, ShapeNotifyMask); if (track.damages) XDamageCreate(dpy, win, XDamageReportRawRectangles); } while (argv[++optind]); else XSelectInput(dpy, DefaultRootWindow(dpy), xeventmask); /* The main loop */ line = g_string_new(""); for (;;) { XEvent ev; /* Wait for, get and process the next event. */ XNextEvent(dpy, &ev); if (ev.type == CreateNotify) { XCreateWindowEvent const *create = &ev.xcreatewindow; if (!track.creation) continue; fmtxid(line, create->parent); g_string_append_printf(line, "Create(0x%lx)", create->window); output(line, ev.xany.send_event); } else if (ev.type == DestroyNotify) { XDestroyWindowEvent const *destroy = &ev.xdestroywindow; if (!track.creation) continue; fmtxid(line, destroy->event); g_string_append_printf(line, "Destroy(0x%lx)", destroy->window); output(line, ev.xany.send_event); } else if (ev.type == MapNotify) { XMapEvent const *map = &ev.xmap; if (!track.mapping) continue; fmtxid(line, map->event); g_string_append_printf(line, "Map(0x%lx%s)", map->window, map->override_redirect ? ", override_redirected" : ""); output(line, ev.xany.send_event); } else if (ev.type == UnmapNotify) { XUnmapEvent const *unmap = &ev.xunmap; if (!track.mapping) continue; fmtxid(line, unmap->event); g_string_append_printf(line, "Unmap(0x%lx%s)", unmap->window, unmap->from_configure ? ", from_configure" : ""); output(line, ev.xany.send_event); } else if (ev.type == ReparentNotify) { XReparentEvent const *reparent = &ev.xreparent; if (!track.configure) continue; fmtxid(line, reparent->event); g_string_append_printf(line, "Reparent(0x%lx => 0x%lx)", reparent->window, reparent->parent); output(line, ev.xany.send_event); } else if (ev.type == ConfigureNotify) { XConfigureEvent const *cfg = &ev.xconfigure; if (!track.configure) continue; fmtxid(line, cfg->event); g_string_append_printf(line, "Configure(0x%lx => %dx%d%+d%+d, " "above=0x%lx%s)", cfg->window, cfg->width, cfg->height, cfg->x, cfg->y, cfg->above, cfg->override_redirect ? ", override_redirected" : ""); output(line, ev.xany.send_event); } else if (track.shape && ev.type == shape_event + ShapeNotify) { static char const *shapes[] = { "Bounding", "Clip", "Input" }; XShapeEvent sev; memcpy(&sev, &ev, sizeof(sev)); fmtxid(line, sev.window); g_string_append_printf(line, "Shape(%s => %dx%d%+d%+d)", shapes[sev.kind], sev.width, sev.height, sev.x, sev.y); output(line, ev.xany.send_event); } else if (ev.type == PropertyNotify) { assert(track.properties); property_event(dpy, &ev.xproperty, line); } else if (ev.type == ClientMessage) { if (!track.clientmsg) continue; client_message(dpy, &ev.xclient, line); } else if (ev.type == VisibilityNotify) { static char const *visibilities[] = { "unobscured", "partially obscured", "fully obscured", }; XVisibilityEvent const *vis = &ev.xvisibility; assert(track.visibility); fmtxid(line, vis->window); g_string_append_printf(line, "Visibility=%s", visibilities[vis->state]); output(line, ev.xany.send_event); } else if (ev.type == Expose) { XExposeEvent const *ex = &ev.xexpose; assert(track.exposure); fmtxid(line, ex->window); g_string_append_printf(line, "Expose(%dx%d%+d%+d)", ex->width, ex->height, ex->x, ex->y); output(line, ev.xany.send_event); } else if (track.damages && ev.type == damage_event) { XDamageNotifyEvent dev; memcpy(&dev, &ev, sizeof(dev)); fmtxid(line, dev.drawable); g_string_append_printf(line, "Damage(%dx%d%+d%+d)", dev.area.width, dev.area.height, dev.area.x, dev.area.y); output(line, ev.xany.send_event); XDamageSubtract(dpy, dev.damage, None, None); } else if (ev.type == EnterNotify || ev.type == LeaveNotify) { XCrossingEvent const *cross = &ev.xcrossing; if (!track.pointer) continue; fmtxid(line, cross->window); g_string_append_printf(line, "%s(%dx%d", cross->type == EnterNotify ? "Enter" : "Leave", cross->x, cross->y); if (cross->mode == NotifyGrab) g_string_append(line, ", grab"); else if (cross->mode == NotifyUngrab) g_string_append(line, ", ungrab"); g_string_append_c(line, ')'); output(line, ev.xany.send_event); } else if (ev.type == KeyPress || ev.type == KeyRelease) { static struct { int mask; char const *name; } states[] = { { ShiftMask, "Shift" }, { LockMask, "Lock" }, { ControlMask, "Ctrl" }, { Mod1Mask, "Mod1" }, { Mod2Mask, "Mod2" }, { Mod3Mask, "Mod3" }, { Mod4Mask, "Mod4" }, { Mod5Mask, "Mod5" }, }; unsigned i; int has_modifiers; XKeyEvent const *key; assert(track.keyboard); key = &ev.xkey; fmtxid(line, key->window); /* Prepend with the list of modifiers. */ has_modifiers = 0; for (i = 0; i < G_N_ELEMENTS(states); i++) if (key->state & states[i].mask) { if (!has_modifiers) { g_string_append_c(line, ' '); has_modifiers = 1; } else g_string_append_c(line, '-'); g_string_append(line, states[i].name); } if (has_modifiers) g_string_append_c(line, '-'); g_string_append_printf(line, "%s %s", XKeysymToString(XKeycodeToKeysym(dpy, key->keycode, 0)), ev.type == KeyPress ? "pressed" : "released"); output(line, ev.xany.send_event); } /* if */ } /* for ever */ return 0; } /* main */