static int setup_events(Display *dpy) { XIEventMask mask[2]; Window root; int dummy; if (!XQueryExtension(dpy, "XInputExtension", &xinput, &dummy, &dummy)) { puts("Could not query XInputExtension"); return -1; } root = DefaultRootWindow(dpy); mask[0].deviceid = XIAllDevices; mask[0].mask_len = XIMaskLen(XI_LASTEVENT); mask[0].mask = calloc(mask[0].mask_len, sizeof(char)); mask[1].deviceid = XIAllMasterDevices; mask[1].mask_len = XIMaskLen(XI_LASTEVENT); mask[1].mask = calloc(mask[1].mask_len, sizeof(char)); XISetMask(mask[1].mask, XI_RawKeyPress); XISetMask(mask[1].mask, XI_RawButtonPress); XISelectEvents(dpy, root, &mask[0], 2); if (!XSync(dpy, False)) { puts("Could not sync display"); return -1; } free(mask[0].mask); free(mask[1].mask); return 0; }
static gboolean meta_backend_x11_grab_device (MetaBackend *backend, int device_id, uint32_t timestamp) { MetaBackendX11 *x11 = META_BACKEND_X11 (backend); MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; int ret; if (timestamp != CurrentTime) timestamp = MAX (timestamp, priv->latest_evtime); XISetMask (mask.mask, XI_ButtonPress); XISetMask (mask.mask, XI_ButtonRelease); XISetMask (mask.mask, XI_Enter); XISetMask (mask.mask, XI_Leave); XISetMask (mask.mask, XI_Motion); XISetMask (mask.mask, XI_KeyPress); XISetMask (mask.mask, XI_KeyRelease); ret = XIGrabDevice (priv->xdisplay, device_id, meta_backend_x11_get_xwindow (x11), timestamp, None, XIGrabModeAsync, XIGrabModeAsync, False, /* owner_events */ &mask); return (ret == Success); }
void SetupXI2Events() { Display *dpy = nux::GetGraphicsDisplay()->GetX11Display(); unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; XISetMask(mask.mask, XI_BarrierHit); XISetMask(mask.mask, XI_BarrierLeave); XISelectEvents (dpy, DefaultRootWindow(dpy), &mask, 1); }
static void install_grabs_mouse( void ) { int i; int num_devices; XIDeviceInfo *info; XIEventMask mask; assert( x11display.dpy && x11display.win ); if( mouse_active ) return; XDefineCursor(x11display.dpy, x11display.win, CreateNullCursor(x11display.dpy, x11display.win)); mask.deviceid = XIAllDevices; mask.mask_len = XIMaskLen(XI_LASTEVENT); mask.mask = calloc(mask.mask_len, sizeof(char)); XISetMask(mask.mask, XI_Enter); XISetMask(mask.mask, XI_Leave); XISetMask(mask.mask, XI_ButtonPress); XISetMask(mask.mask, XI_ButtonRelease); info = XIQueryDevice(x11display.dpy, XIAllDevices, &num_devices); for(i = 0; i < num_devices; i++) { int id = info[i].deviceid; if(info[i].use == XISlavePointer) { mask.deviceid = id; XIGrabDevice(x11display.dpy, id, x11display.win, CurrentTime, None, GrabModeSync, GrabModeSync, True, &mask); } else if(info[i].use == XIMasterPointer) { if (x11display.features.wmStateFullscreen) XIWarpPointer(x11display.dpy, id, None, x11display.win, 0, 0, 0, 0, 0, 0); else XIWarpPointer(x11display.dpy, id, None, x11display.win, 0, 0, 0, 0, x11display.win_width/2, x11display.win_height/2); } } XIFreeDeviceInfo(info); mask.deviceid = XIAllDevices; memset(mask.mask, 0, mask.mask_len); XISetMask(mask.mask, XI_RawMotion); XISelectEvents(x11display.dpy, DefaultRootWindow(x11display.dpy), &mask, 1); free(mask.mask); XSync(x11display.dpy, True); mx = my = 0; mouse_active = qtrue; }
void grab_all_keys(Window window, int is_grab) { if (is_grab) { // Grab all keys... XGrabKey(main_window->display, AnyKey, AnyModifier, window, FALSE, GrabModeAsync, GrabModeAsync); // ...without ModKeys. grab_modifier_keys(window, FALSE); XIEventMask mask; mask.deviceid = XIAllMasterDevices; mask.mask_len = XIMaskLen(XI_KeyPress)+ XIMaskLen(XI_KeyRelease); mask.mask = (void *)calloc(mask.mask_len, sizeof(char)); XISetMask(mask.mask, XI_KeyPress); XISetMask(mask.mask, XI_KeyRelease); XISelectEvents(main_window->display, window, &mask, 1); free(mask.mask); // Not used, XISelectEvents get actions //grab_action(window); //grab_user_action(window); } else { // Ungrab all keys in app window... XUngrabKey(main_window->display, AnyKey, AnyModifier, window); XIEventMask mask; mask.deviceid = XIAllMasterDevices; mask.mask_len = XIMaskLen(XI_KeyPress); mask.mask = (void *)calloc(mask.mask_len, sizeof(char)); XISetMask(mask.mask, 0); XISelectEvents(main_window->display, window, &mask, 1); free(mask.mask); } XSelectInput(main_window->display, window, FOCUS_CHANGE_MASK); }
void grab_button(int is_grab) { if (is_grab) { XIEventMask mask; mask.deviceid = XIAllMasterDevices; mask.mask_len = XIMaskLen(XI_RawButtonPress); mask.mask = (void *)calloc(mask.mask_len, sizeof(char)); XISetMask(mask.mask, XI_RawButtonPress); XISelectEvents(main_window->display, DefaultRootWindow(main_window->display), &mask, 1); free(mask.mask); } else { XIEventMask mask; mask.deviceid = XIAllMasterDevices; mask.mask_len = XIMaskLen(XI_RawButtonPress); mask.mask = (void *)calloc(mask.mask_len, sizeof(char)); XISetMask(mask.mask, 0); XISelectEvents(main_window->display, DefaultRootWindow(main_window->display), &mask, 1); free(mask.mask); } }
static void meta_backend_x11_select_stage_events (MetaBackend *backend) { MetaBackendX11 *x11 = META_BACKEND_X11 (backend); MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); Window xwin = meta_backend_x11_get_xwindow (x11); unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; XISetMask (mask.mask, XI_KeyPress); XISetMask (mask.mask, XI_KeyRelease); XISetMask (mask.mask, XI_ButtonPress); XISetMask (mask.mask, XI_ButtonRelease); XISetMask (mask.mask, XI_Enter); XISetMask (mask.mask, XI_Leave); XISetMask (mask.mask, XI_FocusIn); XISetMask (mask.mask, XI_FocusOut); XISetMask (mask.mask, XI_Motion); if (priv->mode == META_BACKEND_X11_MODE_NESTED) { /* When we're an X11 compositor, we can't take these events or else * replaying events from our passive root window grab will cause * them to come back to us. * * When we're a nested application, we want to behave like any other * application, so select these events like normal apps do. */ XISetMask (mask.mask, XI_TouchBegin); XISetMask (mask.mask, XI_TouchEnd); XISetMask (mask.mask, XI_TouchUpdate); } XISelectEvents (priv->xdisplay, xwin, &mask, 1); if (priv->mode == META_BACKEND_X11_MODE_NESTED) { /* We have no way of tracking key changes when the stage doesn't have * focus, so we select for KeymapStateMask so that we get a complete * dump of the keyboard state in a KeymapNotify event that immediately * follows each FocusIn (and EnterNotify, but we ignore that.) */ XWindowAttributes xwa; XGetWindowAttributes(priv->xdisplay, xwin, &xwa); XSelectInput(priv->xdisplay, xwin, xwa.your_event_mask | FocusChangeMask | KeymapStateMask); } }
static void take_touch_grab (MetaBackend *backend) { MetaBackendX11 *x11 = META_BACKEND_X11 (backend); MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; XIEventMask mask = { META_VIRTUAL_CORE_POINTER_ID, sizeof (mask_bits), mask_bits }; XIGrabModifiers mods = { XIAnyModifier, 0 }; XISetMask (mask.mask, XI_TouchBegin); XISetMask (mask.mask, XI_TouchUpdate); XISetMask (mask.mask, XI_TouchEnd); XIGrabTouchBegin (priv->xdisplay, META_VIRTUAL_CORE_POINTER_ID, DefaultRootWindow (priv->xdisplay), False, &mask, 1, &mods); }
XLibWindowManagerAdapterPrivate::XLibWindowManagerAdapterPrivate( XLibWindowManagerAdapter *q) :q_ptr(q) { Window root; Status status; int xi_major = 2; int xi_minor = 2; m_mods.modifiers = XIAnyModifier; m_mods.status = 0; m_display = XOpenDisplay(NULL); Q_ASSERT_X(m_display, "XLibWindowManagerAdapter", "Failed to open connection to X server"); status = XIQueryVersion(m_display, &xi_major, &xi_minor); Q_ASSERT_X(status == Success, "XLibWindowManagerAdapter", "Failed to query XInput version"); if (xi_major < 2 || xi_minor < 2) { qFatal("XInput version of the server is too old (%d.%d)" , xi_major, xi_minor); } root = XDefaultRootWindow(m_display); XSelectInput(m_display, root, PropertyChangeMask); XMapWindow(m_display, root); XFlush(m_display); m_mask.deviceid = XIAllMasterDevices; m_mask.mask_len = XIMaskLen(XI_LASTEVENT); m_mask.mask = (unsigned char*)calloc(m_mask.mask_len, sizeof(unsigned char)); XISetMask(m_mask.mask, XI_TouchBegin); XISetMask(m_mask.mask, XI_TouchUpdate); XISetMask(m_mask.mask, XI_TouchEnd); XISetMask(m_mask.mask, XI_TouchOwnership); XISetMask(m_mask.mask, XI_HierarchyChanged); XIGrabTouchBegin(m_display, XIAllMasterDevices, root, 0, &m_mask, 1, &m_mods); }
static void xfwm_device_fill_xi2_event_mask (XIEventMask *xievent_mask, gulong core_mask) { gint len = XIMaskLen (XI_LASTEVENT); guchar *mask = g_new0 (guchar, len); guint i; xievent_mask->deviceid = XIAllMasterDevices; xievent_mask->mask_len = sizeof (mask); xievent_mask->mask = mask; for (i = 0; i < G_N_ELEMENTS (core_to_xi2); i++) { if ((core_mask & core_to_xi2[i].core_mask) == core_to_xi2[i].core_mask) { XISetMask (mask, core_to_xi2[i].xi2_event); } } #undef xi2_set_mask }
static void select_events(Display *dpy, Window win) { XIEventMask evmasks[1]; unsigned char mask1[XIMaskLen(XI_RawMotion)]; memset(mask1, 0, sizeof(mask1)); /* Select for motion from the default cursor */ XISetMask(mask1, XI_RawMotion); int pointer_dev_id; XIGetClientPointer(dpy, None, &pointer_dev_id); evmasks[0].deviceid = pointer_dev_id; evmasks[0].mask_len = sizeof(mask1); evmasks[0].mask = mask1; XISelectEvents(dpy, win, evmasks, 1); XFlush(dpy); }
static void install_grabs_keyboard( void ) { int i; int num_devices; XIDeviceInfo *info; XIEventMask mask; assert( x11display.dpy && x11display.win ); if( input_active ) return; XDefineCursor(x11display.dpy, x11display.win, CreateNullCursor(x11display.dpy, x11display.win)); mask.deviceid = XIAllMasterDevices; mask.mask_len = XIMaskLen(XI_LASTEVENT); mask.mask = calloc(mask.mask_len, sizeof(char)); XISetMask(mask.mask, XI_KeyPress); XISetMask(mask.mask, XI_KeyRelease); XISetMask(mask.mask, XI_ButtonPress); XISetMask(mask.mask, XI_ButtonRelease); XISelectEvents(x11display.dpy, x11display.win, &mask, 1); info = XIQueryDevice(x11display.dpy, XIAllDevices, &num_devices); for(i = 0; i < num_devices; i++) { int id = info[i].deviceid; if(info[i].use == XIMasterKeyboard) { XIGrabDevice(x11display.dpy, id, x11display.win, CurrentTime, None, GrabModeAsync, GrabModeAsync, False, &mask); } } XIFreeDeviceInfo(info); free(mask.mask); XSync(x11display.dpy, True); input_active = qtrue; }
static void meta_backend_x11_select_stage_events (MetaBackend *backend) { MetaBackendX11 *x11 = META_BACKEND_X11 (backend); MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); Window xwin = meta_backend_x11_get_xwindow (x11); unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; XISetMask (mask.mask, XI_KeyPress); XISetMask (mask.mask, XI_KeyRelease); XISetMask (mask.mask, XI_ButtonPress); XISetMask (mask.mask, XI_ButtonRelease); XISetMask (mask.mask, XI_Enter); XISetMask (mask.mask, XI_Leave); XISetMask (mask.mask, XI_FocusIn); XISetMask (mask.mask, XI_FocusOut); XISetMask (mask.mask, XI_Motion); XIClearMask (mask.mask, XI_TouchBegin); XIClearMask (mask.mask, XI_TouchEnd); XIClearMask (mask.mask, XI_TouchUpdate); XISelectEvents (priv->xdisplay, xwin, &mask, 1); }
static Window create_win(Display *dpy) { XIEventMask mask; Window win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, 1, 1, 0, 0, 0); mask.deviceid = XIAllDevices; mask.mask_len = XIMaskLen(XI_RawMotion); mask.mask = calloc(mask.mask_len, sizeof(char)); XISetMask(mask.mask, XI_RawButtonPress); XISetMask(mask.mask, XI_RawButtonRelease); XISetMask(mask.mask, XI_RawKeyPress); XISetMask(mask.mask, XI_RawKeyRelease); XISetMask(mask.mask, XI_RawMotion); XISelectEvents(dpy, DefaultRootWindow(dpy), &mask, 1); free(mask.mask); XMapWindow(dpy, win); XSync(dpy, True); return win; }
void XInputMTInputDevice::start() { Status status; SDLDisplayEngine * pEngine = Player::get()->getDisplayEngine(); glm::vec2 size(pEngine->getSize()); glm::vec2 windowSize(pEngine->getWindowSize()); m_DisplayScale.x = size.x/windowSize.x; m_DisplayScale.y = size.y/windowSize.y; SDL_SysWMinfo info; SDL_VERSION(&info.version); int rc = SDL_GetWMInfo(&info); AVG_ASSERT(rc != -1); s_pDisplay = info.info.x11.display; m_SDLLockFunc = info.info.x11.lock_func; m_SDLUnlockFunc = info.info.x11.unlock_func; m_SDLLockFunc(); // XInput Extension available? int event, error; bool bOk = XQueryExtension(s_pDisplay, "XInputExtension", &m_XIOpcode, &event, &error); if (!bOk) { throw Exception(AVG_ERR_MT_INIT, "XInput multitouch event source: X Input extension not available."); } // Which version of XI2? int major; int minor; status = XIQueryVersion(s_pDisplay, &major, &minor); if (status == BadRequest) { throw Exception(AVG_ERR_MT_INIT, "XInput 2.1 multitouch event source: Server does not support XI2"); } if (major < 2 || minor < 1) { throw Exception(AVG_ERR_MT_INIT, "XInput multitouch event source: Supported version is " +toString(major)+"."+toString(minor)+". At least 2.1 is needed."); } findMTDevice(); // SDL grabs the pointer in full screen mode. This breaks touchscreen usage. // Can't use SDL_WM_GrabInput(SDL_GRAB_OFF) because it doesn't work in full // screen mode. Get the display connection and do it manually. XUngrabPointer(info.info.x11.display, CurrentTime); XIEventMask mask; mask.deviceid = m_DeviceID; mask.mask_len = XIMaskLen(XI_LASTEVENT); mask.mask = (unsigned char *)calloc(mask.mask_len, sizeof(char)); memset(mask.mask, 0, mask.mask_len); XISetMask(mask.mask, XI_TouchBegin); XISetMask(mask.mask, XI_TouchUpdate); XISetMask(mask.mask, XI_TouchEnd); status = XISelectEvents(s_pDisplay, info.info.x11.window, &mask, 1); AVG_ASSERT(status == Success); m_SDLUnlockFunc(); SDL_SetEventFilter(XInputMTInputDevice::filterEvent); XIDetachSlaveInfo detInfo; detInfo.type = XIDetachSlave; detInfo.deviceid = m_DeviceID; XIChangeHierarchy(s_pDisplay, (XIAnyHierarchyChangeInfo *)&detInfo, 1); pEngine->setXIMTInputDevice(this); MultitouchInputDevice::start(); AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO, "XInput Multitouch event source created."); }
static bool xdpy_create_display_window(ALLEGRO_SYSTEM_XGLX *system, ALLEGRO_DISPLAY_XGLX *d, int w, int h, int adapter) { ALLEGRO_DISPLAY *display = (ALLEGRO_DISPLAY *)d; /* Create a colormap. */ Colormap cmap = XCreateColormap(system->x11display, RootWindow(system->x11display, d->xvinfo->screen), d->xvinfo->visual, AllocNone); /* Create an X11 window */ XSetWindowAttributes swa; int mask = CWBorderPixel | CWColormap | CWEventMask; swa.colormap = cmap; swa.border_pixel = 0; swa.event_mask = KeyPressMask | KeyReleaseMask | StructureNotifyMask | EnterWindowMask | LeaveWindowMask | FocusChangeMask | ExposureMask | PropertyChangeMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask; /* For a non-compositing window manager, a black background can look * less broken if the application doesn't react to expose events fast * enough. However in some cases like resizing, the black background * causes horrible flicker. */ if (!(display->flags & ALLEGRO_RESIZABLE)) { mask |= CWBackPixel; swa.background_pixel = BlackPixel(system->x11display, d->xvinfo->screen); } int x_off = INT_MAX; int y_off = INT_MAX; if (display->flags & ALLEGRO_FULLSCREEN) { _al_xglx_get_display_offset(system, d->adapter, &x_off, &y_off); } else { /* We want new_display_adapter's offset to add to the * new_window_position. */ int xscr_x = 0; int xscr_y = 0; al_get_new_window_position(&x_off, &y_off); if (adapter >= 0) { /* Non default adapter. I'm assuming this means the user wants the * window to be placed on the adapter offset by new display pos. */ _al_xglx_get_display_offset(system, d->adapter, &xscr_x, &xscr_y); if (x_off != INT_MAX) x_off += xscr_x; if (y_off != INT_MAX) y_off += xscr_y; } } d->window = XCreateWindow(system->x11display, RootWindow(system->x11display, d->xvinfo->screen), x_off != INT_MAX ? x_off : 0, y_off != INT_MAX ? y_off : 0, w, h, 0, d->xvinfo->depth, InputOutput, d->xvinfo->visual, mask, &swa); ALLEGRO_DEBUG("Window ID: %ld\n", (long)d->window); /* Try to set full screen mode if requested, fail if we can't. */ if (display->flags & ALLEGRO_FULLSCREEN) { /* According to the spec, the window manager is supposed to disable * window decorations when _NET_WM_STATE_FULLSCREEN is in effect. * However, some WMs may not be fully compliant, e.g. Fluxbox. */ _al_xwin_set_frame(display, false); _al_xwin_set_above(display, 1); if (!_al_xglx_fullscreen_set_mode(system, d, w, h, 0, display->refresh_rate)) { ALLEGRO_DEBUG("xdpy: failed to set fullscreen mode.\n"); return false; } } if (display->flags & ALLEGRO_FRAMELESS) { _al_xwin_set_frame(display, false); } ALLEGRO_DEBUG("X11 window created.\n"); /* Set the PID related to the window. */ Atom _NET_WM_PID = XInternAtom(system->x11display, "_NET_WM_PID", False); int pid = getpid(); XChangeProperty(system->x11display, d->window, _NET_WM_PID, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&pid, 1); _al_xwin_set_size_hints(display, x_off, y_off); /* Let the window manager know we're a "normal" window */ Atom _NET_WM_WINDOW_TYPE; Atom _NET_WM_WINDOW_TYPE_NORMAL; _NET_WM_WINDOW_TYPE = XInternAtom(system->x11display, "_NET_WM_WINDOW_TYPE", False); _NET_WM_WINDOW_TYPE_NORMAL = XInternAtom(system->x11display, "_NET_WM_WINDOW_TYPE_NORMAL", False); XChangeProperty(system->x11display, d->window, _NET_WM_WINDOW_TYPE, XA_ATOM, 32, PropModeReplace, (unsigned char *)&_NET_WM_WINDOW_TYPE_NORMAL, 1); /* This seems like a good idea */ const long _NET_WM_BYPASS_COMPOSITOR_HINT_ON = 1; Atom _NET_WM_BYPASS_COMPOSITOR; _NET_WM_BYPASS_COMPOSITOR = XInternAtom(system->x11display, "_NET_WM_BYPASS_COMPOSITOR", False); XChangeProperty(system->x11display, d->window, _NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&_NET_WM_BYPASS_COMPOSITOR_HINT_ON, 1); #ifdef ALLEGRO_XWINDOWS_WITH_XINPUT2 /* listen for touchscreen events */ XIEventMask event_mask; event_mask.deviceid = XIAllMasterDevices; event_mask.mask_len = XIMaskLen(XI_TouchEnd); event_mask.mask = (unsigned char*)al_calloc(3, sizeof(char)); XISetMask(event_mask.mask, XI_TouchBegin); XISetMask(event_mask.mask, XI_TouchUpdate); XISetMask(event_mask.mask, XI_TouchEnd); XISelectEvents(system->x11display, d->window, &event_mask, 1); al_free(event_mask.mask); #endif return true; }
static XIEventMask* set_hierarchy_mask(::Display *display, int *nmasks_out, bool *was_set, bool *was_created) { XIEventMask *masks; int nmasks; bool mask_toggled = false; bool new_mask_created = false; XIEventMask *all_devices_mask = NULL; masks = XIGetSelectedEvents(display, DefaultRootWindow(display), &nmasks); /* masks is in a quirky data format (one chunk of memory). Change into a format easier to manipulate. */ /* extra one, in case we have zero masks or no XIAllDevices mask */ XIEventMask *new_masks = new XIEventMask[nmasks + 1]; for (int i = 0; i < nmasks; i++) { XIEventMask *m = &new_masks[i]; *m = masks[i]; if (masks[i].deviceid == XIAllDevices) { all_devices_mask = m; if (masks[i].mask_len < XIMaskLen(XI_HierarchyChanged)) { m->mask_len = XIMaskLen(XI_HierarchyChanged); mask_toggled = true; } else mask_toggled = !XIMaskIsSet(m->mask, XI_HierarchyChanged); } m->mask = new unsigned char[m->mask_len](); memcpy(m->mask, masks[i].mask, masks[i].mask_len); if (mask_toggled && m->deviceid == XIAllDevices) XISetMask(m->mask, XI_HierarchyChanged); } if (!all_devices_mask) { all_devices_mask = &new_masks[nmasks++]; all_devices_mask->deviceid = XIAllDevices; all_devices_mask->mask_len = XIMaskLen(XI_HierarchyChanged); all_devices_mask->mask = new unsigned char[all_devices_mask->mask_len](); XISetMask(all_devices_mask->mask, XI_HierarchyChanged); new_mask_created = true; } XFree(masks); masks = NULL; if (new_mask_created || mask_toggled) { XISelectEvents(display, DefaultRootWindow(display), new_masks, nmasks); XFlush(display); } *was_set = mask_toggled; *was_created = new_mask_created; *nmasks_out = nmasks; return new_masks; }
int test_xi2(Display *display, int argc, char *argv[], char *name, char *desc) { XIEventMask mask[2]; XIEventMask *m; Window win; int deviceid = -1; int use_root = 0; int rc; setvbuf(stdout, NULL, _IOLBF, 0); if (argc >= 1 && strcmp(argv[0], "--root") == 0) { use_root = 1; argc--; argv++; } rc = list(display, argc, argv, name, desc); if (rc != EXIT_SUCCESS) return rc; if (use_root) win = DefaultRootWindow(display); else win = create_win(display); if (argc >= 1) { XIDeviceInfo *info; info = xi2_find_device_info(display, argv[0]); deviceid = info->deviceid; } /* Select for motion events */ m = &mask[0]; m->deviceid = (deviceid == -1) ? XIAllDevices : deviceid; m->mask_len = XIMaskLen(XI_LASTEVENT); m->mask = calloc(m->mask_len, sizeof(char)); XISetMask(m->mask, XI_ButtonPress); XISetMask(m->mask, XI_ButtonRelease); XISetMask(m->mask, XI_KeyPress); XISetMask(m->mask, XI_KeyRelease); XISetMask(m->mask, XI_Motion); XISetMask(m->mask, XI_DeviceChanged); XISetMask(m->mask, XI_Enter); XISetMask(m->mask, XI_Leave); XISetMask(m->mask, XI_FocusIn); XISetMask(m->mask, XI_FocusOut); #ifdef HAVE_XI22 XISetMask(m->mask, XI_TouchBegin); XISetMask(m->mask, XI_TouchUpdate); XISetMask(m->mask, XI_TouchEnd); #endif if (m->deviceid == XIAllDevices) XISetMask(m->mask, XI_HierarchyChanged); XISetMask(m->mask, XI_PropertyEvent); m = &mask[1]; m->deviceid = (deviceid == -1) ? XIAllMasterDevices : deviceid; m->mask_len = XIMaskLen(XI_LASTEVENT); m->mask = calloc(m->mask_len, sizeof(char)); XISetMask(m->mask, XI_RawKeyPress); XISetMask(m->mask, XI_RawKeyRelease); XISetMask(m->mask, XI_RawButtonPress); XISetMask(m->mask, XI_RawButtonRelease); XISetMask(m->mask, XI_RawMotion); #ifdef HAVE_XI22 XISetMask(m->mask, XI_RawTouchBegin); XISetMask(m->mask, XI_RawTouchUpdate); XISetMask(m->mask, XI_RawTouchEnd); #endif XISelectEvents(display, win, &mask[0], use_root ? 2 : 1); if (!use_root) { XISelectEvents(display, DefaultRootWindow(display), &mask[1], 1); XMapWindow(display, win); } XSync(display, False); free(mask[0].mask); free(mask[1].mask); if (!use_root) { XEvent event; XMaskEvent(display, ExposureMask, &event); XSelectInput(display, win, 0); } /* test_sync_grab(display, win); */ while(1) { XEvent ev; XGenericEventCookie *cookie = (XGenericEventCookie*)&ev.xcookie; XNextEvent(display, (XEvent*)&ev); if (XGetEventData(display, cookie) && cookie->type == GenericEvent && cookie->extension == xi_opcode) { printf("EVENT type %d (%s)\n", cookie->evtype, type_to_name(cookie->evtype)); switch (cookie->evtype) { case XI_DeviceChanged: print_devicechangedevent(display, cookie->data); break; case XI_HierarchyChanged: print_hierarchychangedevent(cookie->data); break; case XI_RawKeyPress: case XI_RawKeyRelease: case XI_RawButtonPress: case XI_RawButtonRelease: case XI_RawMotion: case XI_RawTouchBegin: case XI_RawTouchUpdate: case XI_RawTouchEnd: print_rawevent(cookie->data); break; case XI_Enter: case XI_Leave: case XI_FocusIn: case XI_FocusOut: print_enterleave(cookie->data); break; case XI_PropertyEvent: print_propertyevent(display, cookie->data); break; default: print_deviceevent(cookie->data); break; } } XFreeEventData(display, cookie); } XDestroyWindow(display, win); return EXIT_SUCCESS; }
void meta_compositor_manage (MetaCompositor *compositor) { MetaDisplay *display = compositor->display; Display *xdisplay = display->xdisplay; MetaScreen *screen = display->screen; Window xwin = 0; gint width, height; meta_screen_set_cm_selection (display->screen); if (meta_is_wayland_compositor ()) { MetaWaylandCompositor *wayland_compositor = meta_wayland_compositor_get_default (); compositor->stage = meta_stage_new (); wayland_compositor->stage = compositor->stage; meta_screen_get_size (screen, &width, &height); clutter_actor_set_size (compositor->stage, width, height); clutter_actor_show (compositor->stage); } else { compositor->stage = clutter_stage_new (); meta_screen_get_size (screen, &width, &height); clutter_actor_realize (compositor->stage); xwin = clutter_x11_get_stage_window (CLUTTER_STAGE (compositor->stage)); XResizeWindow (xdisplay, xwin, width, height); { MetaBackendX11 *backend = META_BACKEND_X11 (meta_get_backend ()); Display *backend_xdisplay = meta_backend_x11_get_xdisplay (backend); unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; XISetMask (mask.mask, XI_KeyPress); XISetMask (mask.mask, XI_KeyRelease); XISetMask (mask.mask, XI_ButtonPress); XISetMask (mask.mask, XI_ButtonRelease); XISetMask (mask.mask, XI_Enter); XISetMask (mask.mask, XI_Leave); XISetMask (mask.mask, XI_FocusIn); XISetMask (mask.mask, XI_FocusOut); XISetMask (mask.mask, XI_Motion); XIClearMask (mask.mask, XI_TouchBegin); XIClearMask (mask.mask, XI_TouchEnd); XIClearMask (mask.mask, XI_TouchUpdate); XISelectEvents (backend_xdisplay, xwin, &mask, 1); } } /* We use connect_after() here to accomodate code in GNOME Shell that, * when benchmarking drawing performance, connects to ::after-paint * and calls glFinish(). The timing information from that will be * more accurate if we hold off until that completes before we signal * apps to begin drawing the next frame. If there are no other * connections to ::after-paint, connect() vs. connect_after() doesn't * matter. */ g_signal_connect_after (CLUTTER_STAGE (compositor->stage), "after-paint", G_CALLBACK (after_stage_paint), compositor); clutter_stage_set_sync_delay (CLUTTER_STAGE (compositor->stage), META_SYNC_DELAY); compositor->window_group = meta_window_group_new (screen); compositor->top_window_group = meta_window_group_new (screen); clutter_actor_add_child (compositor->stage, compositor->window_group); clutter_actor_add_child (compositor->stage, compositor->top_window_group); if (meta_is_wayland_compositor ()) { /* NB: When running as a wayland compositor we don't need an X * composite overlay window, and we don't need to play any input * region tricks to redirect events into clutter. */ compositor->output = None; } else { compositor->output = screen->composite_overlay_window; XReparentWindow (xdisplay, xwin, compositor->output, 0, 0); meta_empty_stage_input_region (screen); /* Make sure there isn't any left-over output shape on the * overlay window by setting the whole screen to be an * output region. * * Note: there doesn't seem to be any real chance of that * because the X server will destroy the overlay window * when the last client using it exits. */ XFixesSetWindowShapeRegion (xdisplay, compositor->output, ShapeBounding, 0, 0, None); /* Map overlay window before redirecting windows offscreen so we catch their * contents until we show the stage. */ XMapWindow (xdisplay, compositor->output); } redirect_windows (display->screen); compositor->plugin_mgr = meta_plugin_manager_new (compositor); }
void meta_window_ensure_frame (MetaWindow *window) { MetaFrame *frame; MetaScreen *screen; XSetWindowAttributes attrs; XVisualInfo visual_info; Visual *visual; int status; if (window->frame) return; /* See comment below for why this is required. */ meta_display_grab (window->display); frame = g_new (MetaFrame, 1); frame->window = window; frame->xwindow = None; frame->rect = window->rect; frame->child_x = 0; frame->child_y = 0; frame->bottom_height = 0; frame->right_width = 0; frame->current_cursor = 0; frame->mapped = TRUE; frame->need_reapply_frame_shape = TRUE; frame->is_flashing = FALSE; meta_verbose ("Framing window %s: visual %s default, depth %d default depth %d\n", window->desc, XVisualIDFromVisual (window->xvisual) == XVisualIDFromVisual (window->screen->default_xvisual) ? "is" : "is not", window->depth, window->screen->default_depth); meta_verbose ("Frame geometry %d,%d %dx%d\n", frame->rect.x, frame->rect.y, frame->rect.width, frame->rect.height); /* Default depth/visual handles clients with weird visuals; they can * always be children of the root depth/visual obviously, but * e.g. DRI games can't be children of a parent that has the same * visual as the client. NULL means default visual. * * We look for an ARGB visual if we can find one, otherwise use * the default of NULL. */ screen = meta_window_get_screen (window); status = XMatchVisualInfo (window->display->xdisplay, XScreenNumberOfScreen (screen->xscreen), 32, TrueColor, &visual_info); if (!status) { /* Special case for depth 32 windows (assumed to be ARGB), * we use the window's visual. Otherwise we just use the system visual. */ if (window->depth == 32) visual = window->xvisual; else visual = NULL; } else visual = visual_info.visual; frame->xwindow = meta_ui_create_frame_window (window->screen->ui, window->display->xdisplay, visual, frame->rect.x, frame->rect.y, frame->rect.width, frame->rect.height, frame->window->screen->number); meta_verbose ("Frame for %s is 0x%lx\n", frame->window->desc, frame->xwindow); attrs.event_mask = EVENT_MASK; XChangeWindowAttributes (window->display->xdisplay, frame->xwindow, CWEventMask, &attrs); meta_display_register_x_window (window->display, &frame->xwindow, window); /* Reparent the client window; it may be destroyed, * thus the error trap. We'll get a destroy notify later * and free everything. Comment in FVWM source code says * we need a server grab or the child can get its MapNotify * before we've finished reparenting and getting the decoration * window onscreen, so ensure_frame must be called with * a grab. */ meta_error_trap_push (window->display); if (window->mapped) { window->mapped = FALSE; /* the reparent will unmap the window, * we don't want to take that as a withdraw */ meta_topic (META_DEBUG_WINDOW_STATE, "Incrementing unmaps_pending on %s for reparent\n", window->desc); window->unmaps_pending += 1; } /* window was reparented to this position */ window->rect.x = 0; window->rect.y = 0; XReparentWindow (window->display->xdisplay, window->xwindow, frame->xwindow, window->rect.x, window->rect.y); /* FIXME handle this error */ meta_error_trap_pop (window->display, FALSE); /* stick frame to the window */ window->frame = frame; meta_ui_map_frame (window->screen->ui, window->frame->xwindow); /* Now that frame->xwindow is registered with window, we can set its * style and background. */ meta_ui_update_frame_style (window->screen->ui, frame->xwindow); if (window->title) meta_ui_set_frame_title (window->screen->ui, window->frame->xwindow, window->title); /* Move keybindings to frame instead of window */ meta_window_grab_keys (window); /* Shape mask */ meta_ui_apply_frame_shape (frame->window->screen->ui, frame->xwindow, frame->rect.width, frame->rect.height, frame->window->has_shape); frame->need_reapply_frame_shape = FALSE; meta_display_ungrab (window->display); { Display* xdisplay = window->display->xdisplay; unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; XISetMask (mask.mask, XI_ButtonPress); XISetMask (mask.mask, XI_ButtonRelease); XISetMask (mask.mask, XI_Motion); XISetMask (mask.mask, XI_Enter); XISetMask (mask.mask, XI_Leave); XISelectEvents (xdisplay, frame->xwindow, &mask, 1); } meta_prefs_add_listener (prefs_changed_callback, frame); }
void meta_window_ensure_frame (MetaWindow *window) { MetaFrame *frame; XSetWindowAttributes attrs; gulong create_serial; if (window->frame) return; frame = g_new (MetaFrame, 1); frame->window = window; frame->xwindow = None; frame->rect = window->rect; frame->child_x = 0; frame->child_y = 0; frame->bottom_height = 0; frame->right_width = 0; frame->current_cursor = 0; frame->is_flashing = FALSE; frame->borders_cached = FALSE; meta_verbose ("Frame geometry %d,%d %dx%d\n", frame->rect.x, frame->rect.y, frame->rect.width, frame->rect.height); frame->ui_frame = meta_ui_create_frame (window->screen->ui, window->display->xdisplay, frame->window, window->xvisual, frame->rect.x, frame->rect.y, frame->rect.width, frame->rect.height, &create_serial); frame->xwindow = frame->ui_frame->xwindow; meta_stack_tracker_record_add (window->screen->stack_tracker, frame->xwindow, create_serial); meta_verbose ("Frame for %s is 0x%lx\n", frame->window->desc, frame->xwindow); attrs.event_mask = EVENT_MASK; XChangeWindowAttributes (window->display->xdisplay, frame->xwindow, CWEventMask, &attrs); meta_display_register_x_window (window->display, &frame->xwindow, window); meta_error_trap_push (window->display); if (window->mapped) { window->mapped = FALSE; /* the reparent will unmap the window, * we don't want to take that as a withdraw */ meta_topic (META_DEBUG_WINDOW_STATE, "Incrementing unmaps_pending on %s for reparent\n", window->desc); window->unmaps_pending += 1; } meta_stack_tracker_record_remove (window->screen->stack_tracker, window->xwindow, XNextRequest (window->display->xdisplay)); XReparentWindow (window->display->xdisplay, window->xwindow, frame->xwindow, frame->child_x, frame->child_y); /* FIXME handle this error */ meta_error_trap_pop (window->display); /* stick frame to the window */ window->frame = frame; /* Now that frame->xwindow is registered with window, we can set its * style and background. */ meta_frame_update_style (frame); meta_frame_update_title (frame); meta_ui_map_frame (frame->window->screen->ui, frame->xwindow); { MetaBackend *backend = meta_get_backend (); if (META_IS_BACKEND_X11 (backend)) { Display *xdisplay = meta_backend_x11_get_xdisplay (META_BACKEND_X11 (backend)); /* Since the backend selects for events on another connection, * make sure to sync the GTK+ connection to ensure that the * frame window has been created on the server at this point. */ XSync (window->display->xdisplay, False); unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 }; XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits }; XISelectEvents (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow, &mask, 1); XISetMask (mask.mask, XI_ButtonPress); XISetMask (mask.mask, XI_ButtonRelease); XISetMask (mask.mask, XI_Motion); XISetMask (mask.mask, XI_Enter); XISetMask (mask.mask, XI_Leave); XISelectEvents (xdisplay, frame->xwindow, &mask, 1); } } /* Move keybindings to frame instead of window */ meta_window_grab_keys (window); }