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 void select_events(Display *dpy, Window win) { XIEventMask evmasks[2]; unsigned char mask1[(XI_LASTEVENT + 7)/8]; unsigned char mask2[(XI_LASTEVENT + 7)/8]; memset(mask1, 0, sizeof(mask1)); /* select for button and key events from all master devices */ /*XISetMask(mask1, XI_ButtonPress); XISetMask(mask1, XI_ButtonRelease); XISetMask(mask1, XI_KeyPress); XISetMask(mask1, XI_KeyRelease); */ XISetMask(mask1, XI_TouchBegin); XISetMask(mask1, XI_TouchUpdate); XISetMask(mask1, XI_TouchEnd); evmasks[0].deviceid = XIAllDevices; evmasks[0].mask_len = sizeof(mask1); evmasks[0].mask = mask1; memset(mask2, 0, sizeof(mask2)); /* Select for motion from the default cursor */ XISetMask(mask2, XI_Motion); evmasks[1].deviceid = 2; /* the default cursor */ evmasks[1].mask_len = sizeof(mask2); evmasks[1].mask = mask2; XISelectEvents(dpy, win, evmasks, 1); XFlush(dpy); }
/** * \brief Sets window up for XI2 events. */ void fgRegisterDevices( Display* dpy, Window* win ) { XIEventMask mask; unsigned char flags[2] = { 0, 0 }; int event, error; /*Display* dpy = fgDisplay.Display; Window* win = glutGetXWindow();*/ /* get XInput extension opcode */ if (!XQueryExtension( dpy, "XInputExtension", &xi_opcode, &event, &error )) { xi_opcode = -1; } /* Select for motion events */ mask.deviceid = XIAllMasterDevices; mask.mask_len = 2; mask.mask = flags; XISetMask(mask.mask, XI_Enter); XISetMask(mask.mask, XI_Motion); XISetMask(mask.mask, XI_ButtonPress); XISetMask(mask.mask, XI_ButtonRelease); XISetMask(mask.mask, XI_Leave); /*XISetMask(mask.mask, XI_KeyPress); XISetMask(mask.mask, XI_KeyRelease); XISetMask(mask.mask, XI_DeviceChanged); XISetMask(mask.mask, XI_RawEvent); XISetMask(mask.mask, XI_FocusIn); XISetMask(mask.mask, XI_FocusOut); XISetMask(mask.mask, XI_HierarchyChanged);*/ XISelectEvents( dpy, *win, &mask, 1 ); }
int setupXiInput(Display *display) { int opcode; Window defaultRootWin; defaultRootWin=DefaultRootWindow(display); // int major = 2, minor = 0; // (XIQueryVersion(display, &major, &minor) == BadRequest) int event, error; if(XQueryExtension(display, "XInputExtension", &opcode, &event, &error) == 0) { fprintf(stderr,"window_create: X Input extension not available.\n"); return 0; } XIEventMask eventmask; unsigned char mask[4]={0,0,0,0}; eventmask.deviceid = XIAllMasterDevices; eventmask.mask_len = sizeof(mask); eventmask.mask = mask; XISetMask(mask, XI_RawMotion); XISetMask(mask, XI_RawButtonPress); XISetMask(mask, XI_RawButtonRelease); XISetMask(mask, XI_RawKeyPress); XISetMask(mask, XI_RawKeyRelease); XISelectEvents(display, defaultRootWin, &eventmask, 1); return opcode; }
EAPI Eina_Bool ecore_x_input_raw_select(Ecore_X_Window win) { #ifdef ECORE_XI2 XIEventMask emask; unsigned char mask[4] = { 0 }; if (!_ecore_x_xi2_devs) return EINA_FALSE; LOGFN(__FILE__, __LINE__, __FUNCTION__); emask.deviceid = XIAllMasterDevices; emask.mask_len = sizeof(mask); emask.mask = mask; #ifdef XI_RawButtonPress XISetMask(emask.mask, XI_RawButtonPress); #endif #ifdef XI_RawButtonRelease XISetMask(emask.mask, XI_RawButtonRelease); #endif #ifdef XI_RawMotion XISetMask(emask.mask, XI_RawMotion); #endif XISelectEvents(_ecore_x_disp, win, &emask, 1); return EINA_TRUE; #else return EINA_FALSE; #endif }
KeyboardMouse::KeyboardMouse(Window window, int opcode, int pointer, int keyboard) : m_window(window), xi_opcode(opcode), pointer_deviceid(pointer), keyboard_deviceid(keyboard) { memset(&m_state, 0, sizeof(m_state)); // The cool thing about each KeyboardMouse object having its own Display // is that each one gets its own separate copy of the X11 event stream, // which it can individually filter to get just the events it's interested // in. So be aware that each KeyboardMouse object actually has its own X11 // "context." m_display = XOpenDisplay(nullptr); int min_keycode, max_keycode; XDisplayKeycodes(m_display, &min_keycode, &max_keycode); int unused; // should always be 1 XIDeviceInfo* pointer_device = XIQueryDevice(m_display, pointer_deviceid, &unused); name = std::string(pointer_device->name); XIFreeDeviceInfo(pointer_device); XIEventMask mask; unsigned char mask_buf[(XI_LASTEVENT + 7)/8]; mask.mask_len = sizeof(mask_buf); mask.mask = mask_buf; memset(mask_buf, 0, sizeof(mask_buf)); XISetMask(mask_buf, XI_ButtonPress); XISetMask(mask_buf, XI_ButtonRelease); XISetMask(mask_buf, XI_RawMotion); XISetMask(mask_buf, XI_KeyPress); XISetMask(mask_buf, XI_KeyRelease); SelectEventsForDevice(DefaultRootWindow(m_display), &mask, pointer_deviceid); SelectEventsForDevice(DefaultRootWindow(m_display), &mask, keyboard_deviceid); // Keyboard Keys for (int i = min_keycode; i <= max_keycode; ++i) { Key* temp_key = new Key(m_display, i, m_state.keyboard); if (temp_key->m_keyname.length()) AddInput(temp_key); else delete temp_key; } // Mouse Buttons for (int i = 0; i < 5; i++) AddInput(new Button(i, m_state.buttons)); // Mouse Cursor, X-/+ and Y-/+ for (int i = 0; i != 4; ++i) AddInput(new Cursor(!!(i & 2), !!(i & 1), (&m_state.cursor.x)[!!(i & 2)])); // Mouse Axis, X-/+ and Y-/+ for (int i = 0; i != 4; ++i) AddInput(new Axis(!!(i & 2), !!(i & 1), (&m_state.axis.x)[!!(i & 2)])); }
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_button (int deviceid, gboolean grab, GdkScreen *screen) { GdkWindow *root; XIGrabModifiers mods; root = gdk_screen_get_root_window (screen); mods.modifiers = XIAnyModifier; if (grab) { XIEventMask evmask; unsigned char mask[(XI_LASTEVENT + 7)/8]; memset (mask, 0, sizeof (mask)); XISetMask (mask, XI_ButtonRelease); XISetMask (mask, XI_ButtonPress); evmask.deviceid = deviceid; evmask.mask_len = sizeof (mask); evmask.mask = mask; gdk_error_trap_push(); XIGrabButton (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), deviceid, XIAnyButton, GDK_WINDOW_XID (root), None, GrabModeAsync, GrabModeAsync, False, &evmask, 1, &mods); gdk_error_trap_pop_ignored (); } else { gdk_error_trap_push(); XIUngrabButton (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), deviceid, XIAnyButton, GDK_WINDOW_XID (root), 1, &mods); gdk_error_trap_pop_ignored (); } }
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); }
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 init_xinput(Display *d) { XIEventMask eventmask; unsigned char mask[1] = {0}; eventmask.deviceid = XIAllDevices; eventmask.mask_len = sizeof(mask); eventmask.mask = mask; XISetMask(mask, XI_Motion); XISelectEvents(d, RootWindow(d, DefaultScreen (d)), &eventmask, 1); }
static int register_for_events(Display *dpy) { XIEventMask evmask; unsigned char mask[3] = { 0, 0, 0 }; XISetMask(mask, XI_HierarchyChanged); XISetMask(mask, XI_RawMotion); XISetMask(mask, XI_RawButtonPress); XISetMask(mask, XI_RawButtonRelease); evmask.deviceid = XIAllDevices; evmask.mask_len = sizeof (mask); evmask.mask = mask; /* !!! FIXME: retval? */ pXISelectEvents(dpy, DefaultRootWindow(dpy), &evmask, 1); return 1; } /* register_for_events */
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); }
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); }
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; }
void ESelectInput(Win win, unsigned int event_mask) { #if USE_XI2 #define EVENTS_TO_XI \ (/* KeyPressMask | KeyReleaseMask | */ \ ButtonPressMask | ButtonReleaseMask | PointerMotionMask) win->event_mask = event_mask; if (Mode.server.extensions & XEXT_XI) { XIEventMask em; unsigned char mask[(XI_LASTEVENT + 8) / 8]; em.deviceid = XIAllMasterDevices; /* XIAllDevices; */ em.mask_len = sizeof(mask); em.mask = mask; memset(mask, 0, sizeof(mask)); #if 0 if (event_mask & KeyPressMask) XISetMask(mask, XI_KeyPress); if (event_mask & KeyReleaseMask) XISetMask(mask, XI_KeyRelease); #endif if (event_mask & ButtonPressMask) XISetMask(mask, XI_ButtonPress); if (event_mask & ButtonReleaseMask) XISetMask(mask, XI_ButtonRelease); if (event_mask & PointerMotionMask) XISetMask(mask, XI_Motion); XISelectEvents(disp, win->xwin, &em, 1); event_mask &= ~EVENTS_TO_XI; } #endif XSelectInput(disp, win->xwin, event_mask); }
static void grab_key_real (guint keycode, GdkWindow *root, gboolean grab, XIGrabModifiers *mods, int num_mods) { XIEventMask evmask; unsigned char mask[(XI_LASTEVENT + 7)/8]; memset (mask, 0, sizeof (mask)); XISetMask (mask, XI_KeyPress); XISetMask (mask, XI_KeyRelease); evmask.deviceid = XIAllMasterDevices; evmask.mask_len = sizeof (mask); evmask.mask = mask; if (grab) { XIGrabKeycode (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), XIAllMasterDevices, keycode, GDK_WINDOW_XID (root), GrabModeAsync, GrabModeAsync, False, &evmask, num_mods, mods); } else { XIUngrabKeycode (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), XIAllMasterDevices, keycode, GDK_WINDOW_XID (root), num_mods, mods); } }
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); } }
void ColorButton::registerEvent(int ev) { XIEventMask mask; unsigned char bits[4] = {0}; mask.mask = bits; mask.mask_len = sizeof(bits); // which ones? mask.deviceid = XIAllMasterDevices; // what? XISetMask(bits, ev); XISelectEvents(x11->dpy, win, &mask, 1); }
/* Grab the device so input is captured */ void grab(Display* display, int grabDeviceID) { XIEventMask device_mask; unsigned char mask_data[8] = { 0,0,0,0,0,0,0,0 }; device_mask.mask_len = sizeof(mask_data); device_mask.mask = mask_data; XISetMask(device_mask.mask, XI_Motion); XISetMask(device_mask.mask, XI_ButtonPress); /* Experiments with X MT support, not working yet */ // XISetMask(device_mask.mask, XI_TouchBegin); // XISetMask(device_mask.mask, XI_TouchUpdate); // XISetMask(device_mask.mask, XI_TouchEnd); // XIGrabModifiers modifiers; // modifiers.modifiers = XIAnyModifier; // int r = XIGrabButton(display, grabDeviceID, XIAnyButton, root, None, GrabModeSync, // GrabModeAsync, True, &device_mask, 1, &modifiers); // int r = XIGrabTouchBegin(display, grabDeviceID, root, None, &device_mask, 0, modifiers); int r = XIGrabDevice(display, grabDeviceID, root, CurrentTime, None, GrabModeAsync, GrabModeAsync, False, &device_mask); if(debugMode) printf("Grab Result: %i\n", r); }
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; }
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); }
void test_sync_grab(Display *display, Window win) { int loop = 3; int rc; XIEventMask mask; /* Select for motion events */ mask.deviceid = XIAllDevices; mask.mask_len = 2; mask.mask = calloc(2, sizeof(char)); XISetMask(mask.mask, XI_ButtonPress); if ((rc = XIGrabDevice(display, 2, win, CurrentTime, None, GrabModeSync, GrabModeAsync, False, &mask)) != GrabSuccess) { fprintf(stderr, "Grab failed with %d\n", rc); return; } free(mask.mask); XSync(display, True); XIAllowEvents(display, 2, SyncPointer, CurrentTime); XFlush(display); printf("Holding sync grab for %d button presses.\n", loop); while(loop--) { XIEvent ev; XNextEvent(display, (XEvent*)&ev); if (ev.type == GenericEvent && ev.extension == xi_opcode ) { XIDeviceEvent *event = (XIDeviceEvent*)&ev; print_deviceevent(event); XIAllowEvents(display, 2, SyncPointer, CurrentTime); } } XIUngrabDevice(display, 2, CurrentTime); printf("Done\n"); }
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 int xwinitxi2(struct fb *fb) { int major = 2; int minor = 2; int xi_opcode, event, error; XIEventMask evmask[1]; unsigned char mask[(XI_LASTEVENT + 7)/8] = {0}; if(!XQueryExtension(fb->hw->display, "XInputExtension", &xi_opcode, &event, &error)) { printf("XInputExtension is not available\n"); return -1; } if(XIQueryVersion(fb->hw->display, &major, &minor) == BadRequest) { printf("XI2 is not supported, server supports version %d.%d only\n", major, minor); return -1; } XISetMask(mask, XI_RawMotion); evmask[0].deviceid = XIAllMasterDevices; evmask[0].mask_len = sizeof(mask); evmask[0].mask = mask; XISelectEvents(fb->hw->display, DefaultRootWindow(fb->hw->display), evmask, 1); XFlush(fb->hw->display); return 0; }
/* Main function, contains kernel driver event loop */ int main(int argc, char **argv) { char* devname = 0; int doDaemonize = 1; int doWait = 0; int clickMode = 2; int i; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "--debug") == 0) { doDaemonize = 0; debugMode = 1; } else if (strcmp(argv[i], "--wait") == 0) { doWait = 1; } else if (strcmp(argv[i], "--click=first") == 0) { clickMode = 0; } else if (strcmp(argv[i], "--click=second") == 0) { clickMode = 1; } else if (strcmp(argv[i], "--click=center") == 0) { clickMode = 2; } else { devname = argv[i]; } } initGestures(clickMode); if (doDaemonize) { daemonize(); } if (doWait) { /* Wait until all necessary things are loaded */ sleep(10); } /* Connect to X server */ if ((display = XOpenDisplay(NULL)) == NULL) { fprintf(stderr, "Couldn't connect to X server\n"); exit(1); } /* Read X data */ screenNum = DefaultScreen(display); root = RootWindow(display, screenNum); // realDisplayWidth = DisplayWidth(display, screenNum); // realDisplayHeight = DisplayHeight(display, screenNum); WM_CLASS = XInternAtom(display, "WM_CLASS", 0); /* Get notified about new windows */ XSelectInput(display, root, StructureNotifyMask | SubstructureNotifyMask); //TODO load blacklist and profiles from file(s) /* Device file name */ if (devname == 0) { devname = "/dev/twofingtouch"; } /* Try to read from device file */ int fileDesc; if ((fileDesc = open(devname, O_RDONLY)) < 0) { perror("twofing"); return 1; } fd_set fileDescSet; FD_ZERO(&fileDescSet); int eventQueueDesc = XConnectionNumber(display); while (1) { /* Perform initialization at beginning and after module has been re-loaded */ int rd, i; struct input_event ev[64]; char name[256] = "Unknown"; /* Read device name */ ioctl(fileDesc, EVIOCGNAME(sizeof(name)), name); printf("Input device name: \"%s\"\n", name); //TODO activate again? //XSetErrorHandler(invalidWindowHandler); int opcode, event, error; if (!XQueryExtension(display, "RANDR", &opcode, &event, &error)) { printf("X RANDR extension not available.\n"); XCloseDisplay(display); exit(1); } /* Which version of XRandR? We support 1.3 */ int major = 1, minor = 3; if (!XRRQueryVersion(display, &major, &minor)) { printf("XRandR version not available.\n"); XCloseDisplay(display); exit(1); } else if(!(major>1 || (major == 1 && minor >= 3))) { printf("XRandR 1.3 not available. Server supports %d.%d\n", major, minor); XCloseDisplay(display); exit(1); } /* XInput Extension available? */ if (!XQueryExtension(display, "XInputExtension", &opcode, &event, &error)) { printf("X Input extension not available.\n"); XCloseDisplay(display); exit(1); } /* Which version of XI2? We support 2.1 */ major = 2; minor = 1; if (XIQueryVersion(display, &major, &minor) == BadRequest) { printf("XI 2.1 not available. Server supports %d.%d\n", major, minor); XCloseDisplay(display); exit(1); } screenWidth = XDisplayWidth(display, screenNum); screenHeight = XDisplayHeight(display, screenNum); int n; XIDeviceInfo *info = XIQueryDevice(display, XIAllDevices, &n); if (!info) { printf("No XInput devices available\n"); exit(1); } /* Go through input devices and look for that with the same name as the given device */ int devindex; for (devindex = 0; devindex < n; devindex++) { if (info[devindex].use == XIMasterPointer || info[devindex].use == XIMasterKeyboard) continue; if (strcmp(info[devindex].name, name) == 0) { deviceID = info[devindex].deviceid; break; } } if (deviceID == -1) { printf("Input device not found in XInput device list.\n"); exit(1); } XIFreeDeviceInfo(info); if(debugMode) printf("XInput device id is %i.\n", deviceID); /* Prepare by reading calibration */ readCalibrationData(1); /* Receive device property change events */ XIEventMask device_mask2; unsigned char mask_data2[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; device_mask2.deviceid = deviceID; device_mask2.mask_len = sizeof(mask_data2); device_mask2.mask = mask_data2; XISetMask(device_mask2.mask, XI_PropertyEvent); XISetMask(device_mask2.mask, XI_ButtonPress); //XISetMask(device_mask2.mask, XI_TouchBegin); //XISetMask(device_mask2.mask, XI_TouchUpdate); //XISetMask(device_mask2.mask, XI_TouchEnd); XISelectEvents(display, root, &device_mask2, 1); /* Recieve events when screen size changes */ XRRSelectInput(display, root, RRScreenChangeNotifyMask); /* Receive touch events */ /* Needed for XTest to work correctly */ XTestGrabControl(display, True); /* Needed for some reason to receive events */ /* XGrabPointer(display, root, False, 0, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); XUngrabPointer(display, CurrentTime);*/ grab(display, deviceID); printf("Reading input from device ... (interrupt to exit)\n"); /* We perform raw event reading here as X touch events don't seem too reliable */ int currentSlot = 0; /* If we use the legacy protocol, we collect all data of one finger into tempFingerInfo and set it to the correct slot once MT_SYNC occurs. */ FingerInfo tempFingerInfo = { .rawX=0, .rawY=0, .rawZ=0, .id = -1, .slotUsed = 0, .setThisTime = 0 }; while (1) { FD_SET(fileDesc, &fileDescSet); FD_SET(eventQueueDesc, &fileDescSet); select(MAX(fileDesc, eventQueueDesc) + 1, &fileDescSet, NULL, NULL, getEasingStepTimeVal()); checkEasingStep(); if(FD_ISSET(fileDesc, &fileDescSet)) { rd = read(fileDesc, ev, sizeof(struct input_event) * 64); if (rd < (int) sizeof(struct input_event)) { printf("Data stream stopped\n"); break; } for (i = 0; i < rd / sizeof(struct input_event); i++) { if (ev[i].type == EV_SYN) { if (0 == ev[i].code) { // Ev_Sync event end /* All finger data received, so process now. */ if(useLegacyProtocol) { /* Clear slots not set this time */ int i; for(i = 0; i < 2; i++) { if(fingerInfos[i].setThisTime) { fingerInfos[i].setThisTime = 0; } else { /* Clear slot */ fingerInfos[i].slotUsed = 0; } } tempFingerInfo.slotUsed = 0; } processFingers(); } else if (2 == ev[i].code) { // MT_Sync : Multitouch event end if(!useLegacyProtocol) { /* This messsage indicates we use legacy protocol, so switch */ useLegacyProtocol = 1; currentSlot = -1; tempFingerInfo.slotUsed = 0; if(debugMode) printf("Switch to legacy protocol.\n"); } else { if(tempFingerInfo.slotUsed) { /* Finger info for one finger collected in tempFingerInfo, so save it to fingerInfos. */ /* Look for slot to put the data into by looking at the tracking ids */ int index = -1; int i; for(i = 0; i < 2; i++) { if(fingerInfos[i].slotUsed && fingerInfos[i].id == tempFingerInfo.id) { index = i; break; } } if(index == -1) { for(i = 0; i < 2; i++) { if(!fingerInfos[i].slotUsed) { /* "Empty" slot, so we can add it. */ index = i; fingerInfos[i].id = tempFingerInfo.id; fingerInfos[i].slotUsed = 1; break; } } } if(index != -1) { /* Copy temporary data to slot */ fingerInfos[index].setThisTime = 1; fingerInfos[index].rawX = tempFingerInfo.rawX; fingerInfos[index].rawY = tempFingerInfo.rawY; fingerInfos[index].rawZ = tempFingerInfo.rawZ; } } } } } else if (ev[i].type == EV_MSC && (ev[i].code == MSC_RAW || ev[i].code == MSC_SCAN)) { } else if (ev[i].code == 47) { currentSlot = ev[i].value; if(currentSlot < 0 || currentSlot > 1) currentSlot = -1; } else { /* Set finger info values for current finger */ if (ev[i].code == 57) { /* ABS_MT_TRACKING_ID */ if(currentSlot != -1) { if(ev[i].value == -1) { fingerInfos[currentSlot].slotUsed = 0; } else { fingerInfos[currentSlot].id = ev[i].value; fingerInfos[currentSlot].slotUsed = 1; } } else if(useLegacyProtocol) { tempFingerInfo.id = ev[i].value; tempFingerInfo.slotUsed = 1; } }; if (ev[i].code == 53) { if(currentSlot != -1) { fingerInfos[currentSlot].rawX = ev[i].value; } else if(useLegacyProtocol) { tempFingerInfo.rawX = ev[i].value; } }; if (ev[i].code == 54) { if(currentSlot != -1) { fingerInfos[currentSlot].rawY = ev[i].value; } else if(useLegacyProtocol) { tempFingerInfo.rawY = ev[i].value; } }; if (ev[i].code == 58) { if(currentSlot != -1) { fingerInfos[currentSlot].rawZ = ev[i].value; } else if(useLegacyProtocol) { tempFingerInfo.rawZ = ev[i].value; } }; } } } if(FD_ISSET(eventQueueDesc, &fileDescSet)) { handleXEvent(); } } /* Stream stopped, probably because module has been unloaded */ close(fileDesc); /* Clean up */ releaseButton(); ungrab(display, deviceID); /* Wait until device file is there again */ while ((fileDesc = open(devname, O_RDONLY)) < 0) { sleep(1); } } }
// Create the X11 window (and its colormap) // static GLboolean createWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig) { unsigned long wamask; XSetWindowAttributes wa; XVisualInfo* visual = _GLFW_X11_CONTEXT_VISUAL; // Every window needs a colormap // Create one based on the visual used by the current context // TODO: Decouple this from context creation window->x11.colormap = XCreateColormap(_glfw.x11.display, _glfw.x11.root, visual->visual, AllocNone); // Create the actual window { wamask = CWBorderPixel | CWColormap | CWEventMask; wa.colormap = window->x11.colormap; wa.border_pixel = 0; wa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | ExposureMask | FocusChangeMask | VisibilityChangeMask | EnterWindowMask | LeaveWindowMask | PropertyChangeMask; if (wndconfig->monitor == NULL) { // HACK: This is a workaround for windows without a background pixel // not getting any decorations on certain older versions of Compiz // running on Intel hardware wa.background_pixel = BlackPixel(_glfw.x11.display, _glfw.x11.screen); wamask |= CWBackPixel; } window->x11.handle = XCreateWindow(_glfw.x11.display, _glfw.x11.root, 0, 0, wndconfig->width, wndconfig->height, 0, // Border width visual->depth, // Color depth InputOutput, visual->visual, wamask, &wa); if (!window->x11.handle) { // TODO: Handle all the various error codes here and translate them // to GLFW errors _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to create window"); return GL_FALSE; } if (wndconfig->undecorated) { Atom motif_hints_atom = XInternAtom(_glfw.x11.display, "_MOTIF_WM_HINTS", False); MotifWmHints motif_hints; motif_hints.flags = MWM_HINTS_DECORATIONS; motif_hints.decorations = 0; XChangeProperty(_glfw.x11.display, window->x11.handle, motif_hints_atom, motif_hints_atom, 32, PropModeReplace, (unsigned char *)&motif_hints, sizeof(MotifWmHints) / sizeof(long)); } } if (window->monitor && !_glfw.x11.hasEWMH) { // This is the butcher's way of removing window decorations // Setting the override-redirect attribute on a window makes the window // manager ignore the window completely (ICCCM, section 4) // The good thing is that this makes undecorated fullscreen windows // easy to do; the bad thing is that we have to do everything manually // and some things (like iconify/restore) won't work at all, as those // are tasks usually performed by the window manager XSetWindowAttributes attributes; attributes.override_redirect = True; XChangeWindowAttributes(_glfw.x11.display, window->x11.handle, CWOverrideRedirect, &attributes); window->x11.overrideRedirect = GL_TRUE; } // Declare the WM protocols supported by GLFW { int count = 0; Atom protocols[2]; // The WM_DELETE_WINDOW ICCCM protocol // Basic window close notification protocol if (_glfw.x11.WM_DELETE_WINDOW != None) protocols[count++] = _glfw.x11.WM_DELETE_WINDOW; // The _NET_WM_PING EWMH protocol // Tells the WM to ping the GLFW window and flag the application as // unresponsive if the WM doesn't get a reply within a few seconds if (_glfw.x11.NET_WM_PING != None) protocols[count++] = _glfw.x11.NET_WM_PING; if (count > 0) { XSetWMProtocols(_glfw.x11.display, window->x11.handle, protocols, count); } } // Set ICCCM WM_HINTS property { XWMHints* hints = XAllocWMHints(); if (!hints) { _glfwInputError(GLFW_OUT_OF_MEMORY, "X11: Failed to allocate WM hints"); return GL_FALSE; } hints->flags = StateHint; hints->initial_state = NormalState; XSetWMHints(_glfw.x11.display, window->x11.handle, hints); XFree(hints); } // Set ICCCM WM_NORMAL_HINTS property (even if no parts are set) { XSizeHints* hints = XAllocSizeHints(); hints->flags = 0; if (wndconfig->monitor) { hints->flags |= PPosition; _glfwPlatformGetMonitorPos(wndconfig->monitor, &hints->x, &hints->y); } if (!wndconfig->resizable) { hints->flags |= (PMinSize | PMaxSize); hints->min_width = hints->max_width = wndconfig->width; hints->min_height = hints->max_height = wndconfig->height; } XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints); XFree(hints); } if (_glfw.x11.xi2.available) { // Select for XInput2 events XIEventMask eventmask; unsigned char mask[] = { 0 }; eventmask.deviceid = 2; eventmask.mask_len = sizeof(mask); eventmask.mask = mask; XISetMask(mask, XI_Motion); XISelectEvents(_glfw.x11.display, window->x11.handle, &eventmask, 1); } _glfwPlatformSetWindowTitle(window, wndconfig->title); XRRSelectInput(_glfw.x11.display, window->x11.handle, RRScreenChangeNotifyMask); return GL_TRUE; }
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."); }