bool EdgeBarrierController::Impl::HandleEvent(XEvent xevent) { Display *dpy = nux::GetGraphicsDisplay()->GetX11Display(); XGenericEventCookie *cookie = &xevent.xcookie; bool ret = false; switch (cookie->evtype) { case (XI_BarrierHit): { if (XGetEventData(dpy, cookie)) { XIBarrierEvent* barrier_event = (XIBarrierEvent*)cookie->data; PointerBarrierWrapper::Ptr wrapper = FindBarrierEventOwner(barrier_event); if (wrapper) ret = wrapper->HandleBarrierEvent(barrier_event); } XFreeEventData(dpy, cookie); break; } default: break; } return ret; }
int main(int, char **) { // need XGenericEventCookie for XInput2 to work Display *dpy = 0; XEvent xevent; if (XGetEventData(dpy, &xevent.xcookie)) { XFreeEventData(dpy, &xevent.xcookie); } XIEvent *xievent; xievent = 0; XIDeviceEvent *xideviceevent; xideviceevent = 0; XIHierarchyEvent *xihierarchyevent; xihierarchyevent = 0; int deviceid = 0; int len = 0; Atom *atoms = XIListProperties(dpy, deviceid, &len); if (atoms) XFree(atoms); return 0; }
static int xinput_process_events(int index) { XEvent ev; XGenericEventCookie *cookie = &ev.xcookie; while (XPending(dpy)) { XFlush(dpy); XPending(dpy); XNextEvent(dpy, &ev); if (XGetEventData(dpy, cookie)) { XIRawEvent* revent = cookie->data; if(cookie->type == GenericEvent && cookie->extension == xi_opcode) { xinput_process_event(revent); } XFreeEventData(dpy, cookie); } } return 0; }
static void X11_HandleGenericEvent(SDL_VideoData *videodata,XEvent event) { XGenericEventCookie *cookie = &event.xcookie; XGetEventData(videodata->display, cookie); X11_HandleXinput2Event(videodata,cookie); XFreeEventData(videodata->display,cookie); }
static void events_queue (ClutterBackendX11 *backend_x11) { ClutterBackend *backend = CLUTTER_BACKEND (backend_x11); Display *xdisplay = backend_x11->xdpy; ClutterEvent *event; XEvent xevent; while (!clutter_events_pending () && XPending (xdisplay)) { XNextEvent (xdisplay, &xevent); event = clutter_event_new (CLUTTER_NOTHING); #ifdef HAVE_XGE XGetEventData (xdisplay, &xevent.xcookie); #endif if (_clutter_backend_translate_event (backend, &xevent, event)) _clutter_event_push (event, FALSE); else clutter_event_free (event); #ifdef HAVE_XGE XFreeEventData (xdisplay, &xevent.xcookie); #endif } }
void XLibWindowManagerAdapterPrivate::onNewEvent() { XSetErrorHandler(xErrorHandler); XSync(m_display, False); XEvent event; while (XPending(m_display)) { XNextEvent(m_display, &event); if (event.type == PropertyNotify && event.xproperty.atom == XInternAtom(m_display, "_NET_CLIENT_LIST", False)) { //Window Event Window *clients; unsigned long len = 0; if (getClients(&clients, &len)) { if (len > m_numberOfClients) { // A window created handleCreatedWindow(clients[len - 1]); } else if (len < m_numberOfClients) { // A window destroyed unsigned long i, j; for (i = 0; i < m_numberOfClients; ++i) { for (j = 0; j < len; ++j) { if (m_clients[i] == clients[j]) { break; } } if (j == len && i < m_numberOfClients) { handleDestroyedWindow(m_clients[i]); break; } } } else { // This is strange, but happens. qWarning("A window neither created nor destroyed"); } // Set new clients and the number of clients XFree(m_clients); m_clients = clients; m_numberOfClients = len; } } if (event.type == GenericEvent) { //Touch Event XGenericEventCookie *xcookie = &event.xcookie; if (!XGetEventData(m_display, xcookie)) { qWarning("Failed to get X generic event data\n"); continue; } if (q_ptr->m_listener) { q_ptr->m_listener->onTouchEvent(xcookie); // In case TouchManager changes error handler XSetErrorHandler(xErrorHandler); } XFreeEventData(m_display, xcookie); } } }
static void handle_host_xevent (MetaBackend *backend, XEvent *event) { MetaBackendX11 *x11 = META_BACKEND_X11 (backend); MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); gboolean bypass_clutter = FALSE; XGetEventData (priv->xdisplay, &event->xcookie); { MetaDisplay *display = meta_get_display (); if (display) { MetaCompositor *compositor = display->compositor; if (meta_plugin_manager_xevent_filter (compositor->plugin_mgr, event)) bypass_clutter = TRUE; } } if (event->type == (priv->xsync_event_base + XSyncAlarmNotify)) handle_alarm_notify (backend, event); if (event->type == priv->xkb_event_base) { XkbAnyEvent *xkb_ev = (XkbAnyEvent *) event; if (xkb_ev->device == META_VIRTUAL_CORE_KEYBOARD_ID) { switch (xkb_ev->xkb_type) { case XkbNewKeyboardNotify: case XkbMapNotify: keymap_changed (backend); default: break; } } } { MetaMonitorManager *manager = meta_backend_get_monitor_manager (backend); if (META_IS_MONITOR_MANAGER_XRANDR (manager) && meta_monitor_manager_xrandr_handle_xevent (META_MONITOR_MANAGER_XRANDR (manager), event)) bypass_clutter = TRUE; } if (!bypass_clutter) { handle_input_event (x11, event); clutter_x11_handle_event (event); } XFreeEventData (priv->xdisplay, &event->xcookie); }
void *cursor_motion_thread(void *targs) { struct MCursor *this = (struct MCursor *)targs; Display *dpy; int xi_opcode, event, error; XEvent ev; dpy = XOpenDisplay(NULL); if (!dpy) { MLOGE("Failed to open display.\n"); return (void *)-1; } if (!XQueryExtension(dpy, "XInputExtension", &xi_opcode, &event, &error)) { MLOGE("X Input extension not available.\n"); XCloseDisplay(dpy); return (void *)-1; } if (!has_xi2(dpy)){ XCloseDisplay(dpy); return (void *)-1; } /* select for XI2 events */ select_events(dpy, DefaultRootWindow(dpy)); while(1) { XGenericEventCookie *cookie = &ev.xcookie; Window root_ret, child_ret; int root_x, root_y; int win_x, win_y; unsigned int mask; XNextEvent(dpy, &ev); if (cookie->type == GenericEvent && cookie->extension == xi_opcode && XGetEventData(dpy, cookie)){ if (cookie->evtype == XI_RawMotion) { XQueryPointer(dpy, DefaultRootWindow(dpy), &root_ret, &child_ret, &root_x, &root_y, &win_x, &win_y, &mask); update_cursor(dpy, this->mMdpy, &this->mBuffer, root_x, root_y); } XFreeEventData(dpy, cookie); } } XCloseDisplay(dpy); return NULL; }
extern int fbread(struct fb *fb) { XEvent ev; XGenericEventCookie *cookie = &ev.xcookie; int mice_ev = 0; static int firstrun = 1; if(fb->hw->mice.dx) { mice_ev = fb->hw->mice.dx<<16 | MICE_DX; fb->hw->mice.dx = 0; } else if(fb->hw->mice.dy) { mice_ev = fb->hw->mice.dy<<16 | MICE_DY; fb->hw->mice.dy = 0; } if(mice_ev) return mice_ev; while(XPending(fb->hw->display) > 0) { XNextEvent(fb->hw->display, &ev); switch(ev.type) { case KeyPress: if(firstrun) firstrun = 0; printf("xkey.keycode=%d\n", ev.xkey.keycode - fb->hw->min_keycode); return ev.xkey.keycode - fb->hw->min_keycode; case KeyRelease: if(firstrun) { firstrun = 0; continue; /* something like a hack, ignory the first keyrelease event comes from terminal */} printf("xkey.keycode=%d (release)\n", ev.xkey.keycode - fb->hw->min_keycode); return (ev.xkey.keycode - fb->hw->min_keycode) | 0x8000; case ButtonPress: printf("xbutton.button=%d\n", ev.xbutton.button); if(ev.xbutton.button == Button1) return MICE_LEFT; if(ev.xbutton.button == Button2) return MICE_MIDDLE; if(ev.xbutton.button == Button3) return MICE_RIGHT; break; case ButtonRelease: printf("xbutton.button=%d (release)\n", ev.xbutton.button); if(ev.xbutton.button == Button1) return MICE_LEFT | 0x8000; if(ev.xbutton.button == Button2) return MICE_MIDDLE | 0x8000; if(ev.xbutton.button == Button3) return MICE_RIGHT | 0x8000; break; #ifdef HAVE_X11_XINPUT2 case GenericEvent: /*if(cookie->extension != xi_opcode) break;*/ if(!XGetEventData(fb->hw->display, cookie)) break; if(cookie->evtype == XI_RawMotion) { XIRawEvent *re = cookie->data; fb->hw->mice.dx = (int)re->raw_values[0]; fb->hw->mice.dy = (int)re->raw_values[1]; printf("xmotion.dx=%d, xmotion.dy=%d\n", fb->hw->mice.dx, fb->hw->mice.dy); } #endif break; default: break; } } return 0; }
void wait_for_movement(Display *d, int *x, int *y) { XEvent ev; XGenericEventCookie *cookie = &ev.xcookie; XNextEvent(d, &ev); if (XGetEventData(d, cookie)) { XIDeviceEvent *xd; switch(cookie->evtype) { case XI_Motion: xd = cookie->data; *x = xd->root_x; *y = xd->root_y; break; } XFreeEventData(d, cookie); } }
int main (int argc, char **argv) { Display *dpy; int xi_opcode, event, error; Window win; XEvent ev; dpy = XOpenDisplay(NULL); if (!dpy) { fprintf(stderr, "Failed to open display.\n"); return -1; } if (!XQueryExtension(dpy, "XInputExtension", &xi_opcode, &event, &error)) { printf("X Input extension not available.\n"); return -1; } if (!has_xi2(dpy)) return -1; /* Create a simple window */ win = create_win(dpy); /* select for XI2 events */ select_events(dpy, win); while(1) { XGenericEventCookie *cookie = &ev.xcookie; XNextEvent(dpy, &ev); if (cookie->type != GenericEvent || cookie->extension != xi_opcode) continue; if (XGetEventData(dpy, cookie)) { printf("Event type %d received\n", cookie->evtype); XFreeEventData(dpy, &ev.xcookie); } } return 0; }
int XInputMTInputDevice::filterEvent(const SDL_Event * pEvent) { // This is a hook into libsdl event processing. Since libsdl doesn't know about // XInput 2, it doesn't call XGetEventData either. By the time the event arrives // in handleXIEvent(), other events may have arrived and XGetEventData can't be // called anymore. Hence this function, which calls XGetEventData for each event // that has a cookie. if (pEvent->type == SDL_SYSWMEVENT) { SDL_SysWMmsg* pMsg = pEvent->syswm.msg; AVG_ASSERT(pMsg->subsystem == SDL_SYSWM_X11); XEvent* pXEvent = &pMsg->event.xevent; XGenericEventCookie* pCookie = (XGenericEventCookie*)&(pXEvent->xcookie); // cerr << "---- filter xinput event: " << xEventTypeToName(pXEvent->type) << ", " // << cookieTypeToName(pCookie->evtype) << endl; XGetEventData(s_pDisplay, pCookie); } else { // cerr << "---- filter: " << int(pEvent->type) << endl; } return 1; }
gboolean xfwm_device_check_mask_event (XfwmDevices *devices, Display *display, guint event_mask, XfwmEvent *event) { gboolean result; #ifdef HAVE_XI2 XI2CheckMaskContext context; #endif #ifdef HAVE_XI2 if (devices->xi2_available && event->meta.device != None) { context.devices = devices; context.event = event; xfwm_device_fill_xi2_event_mask (&context.xievent_mask, event_mask); result = XCheckIfEvent (display, event->meta.x, xfwm_device_check_mask_event_xi2_predicate, (XPointer)&context); g_free (context.xievent_mask.mask); if (result) { /* Previos data was released in predicate, allocate a new data for the new event */ XGetEventData (display, &event->meta.x->xcookie); } } else #endif { result = XCheckMaskEvent (display, event_mask, event->meta.x); } if (result) { xfwm_device_translate_event (devices, event->meta.x, event); } return result; }
static void EventFetchXI2(XEvent * ev) { XIDeviceEvent *xie; if (!XGetEventData(disp, &ev->xcookie)) return; xie = (XIDeviceEvent *) ev->xcookie.data; if (EDebug(EDBUG_TYPE_XI2)) Eprintf("%s: %#lx: XI2 ext=%d type=%d devid=%d srcid=%d\n", "EventsFetch", xie->event, xie->extension, xie->evtype, xie->deviceid, xie->sourceid); switch (ev->xcookie.evtype) { default: break; case XI_ButtonPress: case XI_ButtonRelease: case XI_Motion: ev->type = ev->xcookie.evtype; ev->xbutton.window = xie->event; ev->xbutton.root = xie->root; ev->xbutton.subwindow = xie->child; ev->xbutton.time = xie->time; ev->xbutton.x = (int)xie->event_x; ev->xbutton.y = (int)xie->event_y; ev->xbutton.x_root = (int)xie->root_x; ev->xbutton.y_root = (int)xie->root_y; ev->xbutton.button = xie->detail; ev->xbutton.state = xie->mods.effective; ev->xbutton.same_screen = 1; /* FIXME */ break; } XFreeEventData(disp, &ev->xcookie); }
void xLoop() { XEvent ev; while (1) { XNextEvent(display, &ev); if(ev.type == 101) { /* Why isn't this magic constant explained anywhere?? */ pthread_mutex_lock( &profilesMutex ); handleDisplayChange((XRRScreenChangeNotifyEvent *) &ev); pthread_mutex_unlock( &profilesMutex ); } else if(XGetEventData(display, &ev.xcookie)) { if(ev.xcookie.evtype == XI_HierarchyChanged) { pthread_mutex_lock( &profilesMutex ); if(debugMode) { printf("XInput device change, reload devices.\n"); } handleDeviceChange(); XFreeEventData(display, &ev.xcookie); pthread_mutex_unlock( &profilesMutex ); } } } }
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; }
bool KeyboardMouse::UpdateInput() { XFlush(m_display); // Get the absolute position of the mouse pointer UpdateCursor(); // for the axis controls float delta_x = 0.0f, delta_y = 0.0f; double delta_delta; // Iterate through the event queue - update the axis controls, mouse // button controls, and keyboard controls. XEvent event; while (XPending(m_display)) { XNextEvent(m_display, &event); if (event.xcookie.type != GenericEvent) continue; if (event.xcookie.extension != xi_opcode) continue; if (!XGetEventData(m_display, &event.xcookie)) continue; // only one of these will get used XIDeviceEvent* dev_event = (XIDeviceEvent*)event.xcookie.data; XIRawEvent* raw_event = (XIRawEvent*)event.xcookie.data; switch (event.xcookie.evtype) { case XI_ButtonPress: m_state.buttons |= 1<<(dev_event->detail-1); break; case XI_ButtonRelease: m_state.buttons &= ~(1<<(dev_event->detail-1)); break; case XI_KeyPress: m_state.keyboard[dev_event->detail / 8] |= 1<<(dev_event->detail % 8); break; case XI_KeyRelease: m_state.keyboard[dev_event->detail / 8] &= ~(1<<(dev_event->detail % 8)); break; case XI_RawMotion: // always safe because there is always at least one byte in // raw_event->valuators.mask, and if a bit is set in the mask, // then the value in raw_values is also available. if (XIMaskIsSet(raw_event->valuators.mask, 0)) { delta_delta = raw_event->raw_values[0]; // test for inf and nan if (delta_delta == delta_delta && 1+delta_delta != delta_delta) delta_x += delta_delta; } if (XIMaskIsSet(raw_event->valuators.mask, 1)) { delta_delta = raw_event->raw_values[1]; // test for inf and nan if (delta_delta == delta_delta && 1+delta_delta != delta_delta) delta_y += delta_delta; } break; } XFreeEventData(m_display, &event.xcookie); } // apply axis smoothing m_state.axis.x *= MOUSE_AXIS_SMOOTHING; m_state.axis.x += delta_x; m_state.axis.x /= MOUSE_AXIS_SMOOTHING+1.0f; m_state.axis.y *= MOUSE_AXIS_SMOOTHING; m_state.axis.y += delta_y; m_state.axis.y /= MOUSE_AXIS_SMOOTHING+1.0f; return true; }
/** * \brief This function is called when an Extension Event is received * and calls the corresponding callback functions for these events. */ void fgHandleExtensionEvents( XEvent* base_ev ) { XEvent std_ev; /* standard single-pointer event to be added to the event queue */ int i, button = 0; XGenericEventCookie* cookie = (XGenericEventCookie*)&(base_ev->xcookie); /* initialize the generic fields from base_ev */ std_ev.xany = base_ev->xany; if ( XGetEventData( fgDisplay.pDisplay.Display, cookie ) && (cookie->type == GenericEvent) && (cookie->extension == xi_opcode) ) { XIDeviceEvent* event = (XIDeviceEvent*)(cookie->data); XIEnterEvent *evcross; /*printf("XI2 event type: %d - %d\n", cookie->evtype, event->type );*/ SFG_Window* window = fgWindowByHandle( event->event ); if (!window) return; switch (cookie->evtype) { case XI_Enter: case XI_Leave: evcross = (XIEnterEvent*)event; fgState.Modifiers = fgPlatformGetModifiers( evcross->mods.base ); INVOKE_WCB( *window, MultiEntry, ( event->deviceid, (event->evtype == XI_Enter ? GLUT_ENTERED : GLUT_LEFT) )); #if _DEBUG fgPrintXILeaveEvent((XILeaveEvent*)event); #endif /* Also process the standard crossing event */ std_ev.type = evcross->evtype == XI_Enter ? EnterNotify : LeaveNotify; std_ev.xcrossing.window = evcross->event; std_ev.xcrossing.root = evcross->root; std_ev.xcrossing.subwindow = evcross->child; std_ev.xcrossing.x = evcross->event_x; std_ev.xcrossing.y = evcross->event_y; std_ev.xcrossing.x_root = evcross->root_x; std_ev.xcrossing.y_root = evcross->root_y; std_ev.xcrossing.mode = evcross->mode; std_ev.xcrossing.detail = evcross->detail; std_ev.xcrossing.same_screen = evcross->same_screen; std_ev.xcrossing.focus = evcross->focus; std_ev.xcrossing.state = BUTTON_MASK(*(unsigned int*)evcross->buttons.mask); XPutBackEvent(fgDisplay.pDisplay.Display, &std_ev); break; case XI_ButtonPress: case XI_ButtonRelease: fgState.Modifiers = fgPlatformGetModifiers( event->mods.base ); INVOKE_WCB( *window, MultiButton, ( event->deviceid, event->event_x, event->event_y, event->detail-1, (event->evtype == XI_ButtonPress ? GLUT_DOWN : GLUT_UP) )); /* Also process the standard button event */ std_ev.type = event->evtype == XI_ButtonPress ? ButtonPress : ButtonRelease; std_ev.xbutton.window = event->event; std_ev.xbutton.root = event->root; std_ev.xbutton.subwindow = event->child; std_ev.xbutton.x = event->event_x; std_ev.xbutton.y = event->event_y; std_ev.xbutton.x_root = event->root_x; std_ev.xbutton.y_root = event->root_y; std_ev.xbutton.state = event->mods.base; std_ev.xbutton.button = event->detail; XPutBackEvent(fgDisplay.pDisplay.Display, &std_ev); break; case XI_Motion: fgState.Modifiers = fgPlatformGetModifiers( event->mods.base ); for (i = 0; i < event->buttons.mask_len; i++) { if (event->buttons.mask[i]) { button = 1; } } if (button) { INVOKE_WCB( *window, MultiMotion, ( event->deviceid, event->event_x, event->event_y ) ); } else { INVOKE_WCB( *window, MultiPassive, ( event->deviceid, event->event_x, event->event_y ) ); } #if _DEBUG fgPrintXIDeviceEvent(event); #endif /* Also process the standard motion event */ std_ev.type = MotionNotify; std_ev.xmotion.window = event->event; std_ev.xmotion.root = event->root; std_ev.xmotion.subwindow = event->child; std_ev.xmotion.time = event->time; std_ev.xmotion.x = event->event_x; std_ev.xmotion.y = event->event_y; std_ev.xmotion.x_root = event->root_x; std_ev.xmotion.y_root = event->root_y; std_ev.xmotion.state = BUTTON_MASK(*(unsigned int*)event->buttons.mask); std_ev.xmotion.is_hint = NotifyNormal; XPutBackEvent(fgDisplay.pDisplay.Display, &std_ev); break; default: #if _DEBUG fgWarning( "Unknown XI2 device event:" ); fgPrintXIDeviceEvent( event ); #endif break; } fgState.Modifiers = INVALID_MODIFIERS; } XFreeEventData( fgDisplay.pDisplay.Display, cookie ); }
static void handle_host_xevent (MetaBackend *backend, XEvent *event) { MetaBackendX11 *x11 = META_BACKEND_X11 (backend); MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11); gboolean bypass_clutter = FALSE; XGetEventData (priv->xdisplay, &event->xcookie); { MetaDisplay *display = meta_get_display (); if (display) { MetaCompositor *compositor = display->compositor; if (meta_plugin_manager_xevent_filter (compositor->plugin_mgr, event)) bypass_clutter = TRUE; } } if (priv->mode == META_BACKEND_X11_MODE_NESTED && event->type == FocusIn) { #ifdef HAVE_WAYLAND Window xwin = meta_backend_x11_get_xwindow(x11); XEvent xev; if (event->xfocus.window == xwin) { /* Since we've selected for KeymapStateMask, every FocusIn is followed immediately * by a KeymapNotify event */ XMaskEvent(priv->xdisplay, KeymapStateMask, &xev); MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default (); meta_wayland_compositor_update_key_state (compositor, xev.xkeymap.key_vector, 32, 8); } #else g_assert_not_reached (); #endif } if (event->type == (priv->xsync_event_base + XSyncAlarmNotify)) handle_alarm_notify (backend, event); if (event->type == priv->xkb_event_base) { XkbEvent *xkb_ev = (XkbEvent *) event; if (xkb_ev->any.device == META_VIRTUAL_CORE_KEYBOARD_ID) { switch (xkb_ev->any.xkb_type) { case XkbNewKeyboardNotify: case XkbMapNotify: keymap_changed (backend); break; case XkbStateNotify: if (xkb_ev->state.changed & XkbGroupLockMask) { if (priv->locked_group != xkb_ev->state.locked_group) XkbLockGroup (priv->xdisplay, XkbUseCoreKbd, priv->locked_group); } break; default: break; } } } { MetaMonitorManager *manager = meta_backend_get_monitor_manager (backend); if (META_IS_MONITOR_MANAGER_XRANDR (manager) && meta_monitor_manager_xrandr_handle_xevent (META_MONITOR_MANAGER_XRANDR (manager), event)) bypass_clutter = TRUE; } if (!bypass_clutter) { handle_input_event (x11, event); clutter_x11_handle_event (event); } XFreeEventData (priv->xdisplay, &event->xcookie); }
// Process the specified X event // static void processEvent(XEvent *event) { _GLFWwindow* window = NULL; if (event->type != GenericEvent) { window = _glfwFindWindowByHandle(event->xany.window); if (window == NULL) { // This is an event for a window that has already been destroyed return; } } switch (event->type) { case KeyPress: { const int key = translateKey(event->xkey.keycode); const int mods = translateState(event->xkey.state); const int character = translateChar(&event->xkey); _glfwInputKey(window, key, event->xkey.keycode, GLFW_PRESS, mods); if (character != -1) _glfwInputChar(window, character); break; } case KeyRelease: { const int key = translateKey(event->xkey.keycode); const int mods = translateState(event->xkey.state); _glfwInputKey(window, key, event->xkey.keycode, GLFW_RELEASE, mods); break; } case ButtonPress: { const int mods = translateState(event->xbutton.state); if (event->xbutton.button == Button1) _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS, mods); else if (event->xbutton.button == Button2) _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS, mods); else if (event->xbutton.button == Button3) _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS, mods); // Modern X provides scroll events as mouse button presses else if (event->xbutton.button == Button4) _glfwInputScroll(window, 0.0, 1.0); else if (event->xbutton.button == Button5) _glfwInputScroll(window, 0.0, -1.0); else if (event->xbutton.button == Button6) _glfwInputScroll(window, -1.0, 0.0); else if (event->xbutton.button == Button7) _glfwInputScroll(window, 1.0, 0.0); break; } case ButtonRelease: { const int mods = translateState(event->xbutton.state); if (event->xbutton.button == Button1) { _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_RELEASE, mods); } else if (event->xbutton.button == Button2) { _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_RELEASE, mods); } else if (event->xbutton.button == Button3) { _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_RELEASE, mods); } break; } case EnterNotify: { if (window->cursorMode == GLFW_CURSOR_HIDDEN) hideCursor(window); _glfwInputCursorEnter(window, GL_TRUE); break; } case LeaveNotify: { if (window->cursorMode == GLFW_CURSOR_HIDDEN) showCursor(window); _glfwInputCursorEnter(window, GL_FALSE); break; } case MotionNotify: { if (event->xmotion.x != window->x11.warpPosX || event->xmotion.y != window->x11.warpPosY) { // The cursor was moved by something other than GLFW int x, y; if (window->cursorMode == GLFW_CURSOR_DISABLED) { if (_glfw.focusedWindow != window) break; x = event->xmotion.x - window->x11.cursorPosX; y = event->xmotion.y - window->x11.cursorPosY; } else { x = event->xmotion.x; y = event->xmotion.y; } _glfwInputCursorMotion(window, x, y); } window->x11.cursorPosX = event->xmotion.x; window->x11.cursorPosY = event->xmotion.y; break; } case ConfigureNotify: { if (event->xconfigure.width != window->x11.width || event->xconfigure.height != window->x11.height) { _glfwInputFramebufferSize(window, event->xconfigure.width, event->xconfigure.height); _glfwInputWindowSize(window, event->xconfigure.width, event->xconfigure.height); window->x11.width = event->xconfigure.width; window->x11.height = event->xconfigure.height; } if (event->xconfigure.x != window->x11.xpos || event->xconfigure.y != window->x11.ypos) { _glfwInputWindowPos(window, event->xconfigure.x, event->xconfigure.y); window->x11.xpos = event->xconfigure.x; window->x11.ypos = event->xconfigure.y; } break; } case ClientMessage: { // Custom client message, probably from the window manager if ((Atom) event->xclient.data.l[0] == _glfw.x11.WM_DELETE_WINDOW) { // The window manager was asked to close the window, for example by // the user pressing a 'close' window decoration button _glfwInputWindowCloseRequest(window); } else if (_glfw.x11.NET_WM_PING != None && (Atom) event->xclient.data.l[0] == _glfw.x11.NET_WM_PING) { // The window manager is pinging the application to ensure it's // still responding to events event->xclient.window = _glfw.x11.root; XSendEvent(_glfw.x11.display, event->xclient.window, False, SubstructureNotifyMask | SubstructureRedirectMask, event); } break; } case MapNotify: { _glfwInputWindowVisibility(window, GL_TRUE); break; } case UnmapNotify: { _glfwInputWindowVisibility(window, GL_FALSE); break; } case FocusIn: { _glfwInputWindowFocus(window, GL_TRUE); if (window->cursorMode == GLFW_CURSOR_DISABLED) captureCursor(window); break; } case FocusOut: { _glfwInputWindowFocus(window, GL_FALSE); if (window->cursorMode == GLFW_CURSOR_DISABLED) showCursor(window); break; } case Expose: { _glfwInputWindowDamage(window); break; } case PropertyNotify: { if (event->xproperty.atom == _glfw.x11.WM_STATE && event->xproperty.state == PropertyNewValue) { struct { CARD32 state; Window icon; } *state = NULL; if (_glfwGetWindowProperty(window->x11.handle, _glfw.x11.WM_STATE, _glfw.x11.WM_STATE, (unsigned char**) &state) >= 2) { if (state->state == IconicState) _glfwInputWindowIconify(window, GL_TRUE); else if (state->state == NormalState) _glfwInputWindowIconify(window, GL_FALSE); } XFree(state); } break; } case SelectionClear: { _glfwHandleSelectionClear(event); break; } case SelectionRequest: { _glfwHandleSelectionRequest(event); break; } case DestroyNotify: return; case GenericEvent: { if (event->xcookie.extension == _glfw.x11.xi.majorOpcode && XGetEventData(_glfw.x11.display, &event->xcookie)) { /* if (event->xcookie.evtype == XI_Motion) { XIDeviceEvent* data = (XIDeviceEvent*) event->xcookie.data; window = _glfwFindWindowByHandle(data->event); if (window) { if (data->event_x != window->x11.warpPosX || data->event_y != window->x11.warpPosY) { // The cursor was moved by something other than GLFW double x, y; if (window->cursorMode == GLFW_CURSOR_DISABLED) { if (_glfw.focusedWindow != window) break; x = data->event_x - window->x11.cursorPosX; y = data->event_y - window->x11.cursorPosY; } else { x = data->event_x; y = data->event_y; } _glfwInputCursorMotion(window, x, y); } window->x11.cursorPosX = data->event_x; window->x11.cursorPosY = data->event_y; } }*/ } XFreeEventData(_glfw.x11.display, &event->xcookie); break; } default: { /* switch (event->type - _glfw.x11.randr.eventBase) { case RRScreenChangeNotify: { XRRUpdateConfiguration(event); break; } } */ break; } } }
// Process the specified X event // static void processEvent(XEvent *event) { _GLFWwindow* window = NULL; if (event->type != GenericEvent) { window = _glfwFindWindowByHandle(event->xany.window); if (window == NULL) { // This is an event for a window that has already been destroyed return; } } switch (event->type) { case KeyPress: { const int key = translateKey(event->xkey.keycode); const int mods = translateState(event->xkey.state); const int character = translateChar(&event->xkey); _glfwInputKey(window, key, event->xkey.keycode, GLFW_PRESS, mods); if (character != -1) _glfwInputChar(window, character); break; } case KeyRelease: { const int key = translateKey(event->xkey.keycode); const int mods = translateState(event->xkey.state); _glfwInputKey(window, key, event->xkey.keycode, GLFW_RELEASE, mods); break; } case ButtonPress: { const int mods = translateState(event->xbutton.state); if (event->xbutton.button == Button1) _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS, mods); else if (event->xbutton.button == Button2) _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS, mods); else if (event->xbutton.button == Button3) _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS, mods); // Modern X provides scroll events as mouse button presses else if (event->xbutton.button == Button4) _glfwInputScroll(window, 0.0, 1.0); else if (event->xbutton.button == Button5) _glfwInputScroll(window, 0.0, -1.0); else if (event->xbutton.button == Button6) _glfwInputScroll(window, -1.0, 0.0); else if (event->xbutton.button == Button7) _glfwInputScroll(window, 1.0, 0.0); else { // Additional buttons after 7 are treated as regular buttons // We subtract 4 to fill the gap left by scroll input above _glfwInputMouseClick(window, event->xbutton.button - 4, GLFW_PRESS, mods); } break; } case ButtonRelease: { const int mods = translateState(event->xbutton.state); if (event->xbutton.button == Button1) { _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_RELEASE, mods); } else if (event->xbutton.button == Button2) { _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_RELEASE, mods); } else if (event->xbutton.button == Button3) { _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_RELEASE, mods); } else if (event->xbutton.button > Button7) { // Additional buttons after 7 are treated as regular buttons // We subtract 4 to fill the gap left by scroll input above _glfwInputMouseClick(window, event->xbutton.button - 4, GLFW_RELEASE, mods); } break; } case EnterNotify: { _glfwInputCursorEnter(window, GL_TRUE); break; } case LeaveNotify: { _glfwInputCursorEnter(window, GL_FALSE); break; } case MotionNotify: { if (event->xmotion.x != window->x11.warpPosX || event->xmotion.y != window->x11.warpPosY) { // The cursor was moved by something other than GLFW int x, y; if (window->cursorMode == GLFW_CURSOR_DISABLED) { if (_glfw.focusedWindow != window) break; x = event->xmotion.x - window->x11.cursorPosX; y = event->xmotion.y - window->x11.cursorPosY; } else { x = event->xmotion.x; y = event->xmotion.y; } _glfwInputCursorMotion(window, x, y); } window->x11.cursorPosX = event->xmotion.x; window->x11.cursorPosY = event->xmotion.y; break; } case ConfigureNotify: { if (event->xconfigure.width != window->x11.width || event->xconfigure.height != window->x11.height) { _glfwInputFramebufferSize(window, event->xconfigure.width, event->xconfigure.height); _glfwInputWindowSize(window, event->xconfigure.width, event->xconfigure.height); window->x11.width = event->xconfigure.width; window->x11.height = event->xconfigure.height; } if (event->xconfigure.x != window->x11.xpos || event->xconfigure.y != window->x11.ypos) { _glfwInputWindowPos(window, event->xconfigure.x, event->xconfigure.y); window->x11.xpos = event->xconfigure.x; window->x11.ypos = event->xconfigure.y; } break; } case ClientMessage: { // Custom client message, probably from the window manager if ((Atom) event->xclient.data.l[0] == _glfw.x11.WM_DELETE_WINDOW) { // The window manager was asked to close the window, for example by // the user pressing a 'close' window decoration button _glfwInputWindowCloseRequest(window); } else if (_glfw.x11.NET_WM_PING && (Atom) event->xclient.data.l[0] == _glfw.x11.NET_WM_PING) { // The window manager is pinging the application to ensure it's // still responding to events event->xclient.window = _glfw.x11.root; XSendEvent(_glfw.x11.display, event->xclient.window, False, SubstructureNotifyMask | SubstructureRedirectMask, event); } else if (event->xclient.message_type == _glfw.x11.XdndEnter) { // A drag operation has entered the window // TODO: Check if UTF-8 string is supported by the source } else if (event->xclient.message_type == _glfw.x11.XdndDrop) { // The drag operation has finished dropping on // the window, ask to convert it to a UTF-8 string _glfw.x11.xdnd.source = event->xclient.data.l[0]; XConvertSelection(_glfw.x11.display, _glfw.x11.XdndSelection, _glfw.x11.UTF8_STRING, _glfw.x11.XdndSelection, window->x11.handle, CurrentTime); } else if (event->xclient.message_type == _glfw.x11.XdndPosition) { // The drag operation has moved over the window const int absX = (event->xclient.data.l[2] >> 16) & 0xFFFF; const int absY = (event->xclient.data.l[2]) & 0xFFFF; int x, y; _glfwPlatformGetWindowPos(window, &x, &y); _glfwInputCursorMotion(window, absX - x, absY - y); // Reply that we are ready to copy the dragged data XEvent reply; memset(&reply, 0, sizeof(reply)); reply.type = ClientMessage; reply.xclient.window = event->xclient.data.l[0]; reply.xclient.message_type = _glfw.x11.XdndStatus; reply.xclient.format = 32; reply.xclient.data.l[0] = window->x11.handle; reply.xclient.data.l[1] = 1; // Always accept the dnd with no rectangle reply.xclient.data.l[2] = 0; // Specify an empty rectangle reply.xclient.data.l[3] = 0; reply.xclient.data.l[4] = _glfw.x11.XdndActionCopy; XSendEvent(_glfw.x11.display, event->xclient.data.l[0], False, NoEventMask, &reply); XFlush(_glfw.x11.display); } break; } case SelectionNotify: { if (event->xselection.property) { // The converted data from the drag operation has arrived char* data; const int result = _glfwGetWindowProperty(event->xselection.requestor, event->xselection.property, event->xselection.target, (unsigned char**) &data); if (result) { int i, count; char** names = splitUriList(data, &count); _glfwInputDrop(window, count, (const char**) names); for (i = 0; i < count; i++) free(names[i]); free(names); } XFree(data); XEvent reply; memset(&reply, 0, sizeof(reply)); reply.type = ClientMessage; reply.xclient.window = _glfw.x11.xdnd.source; reply.xclient.message_type = _glfw.x11.XdndFinished; reply.xclient.format = 32; reply.xclient.data.l[0] = window->x11.handle; reply.xclient.data.l[1] = result; reply.xclient.data.l[2] = _glfw.x11.XdndActionCopy; // Reply that all is well XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.source, False, NoEventMask, &reply); XFlush(_glfw.x11.display); } break; } case MapNotify: { _glfwInputWindowVisibility(window, GL_TRUE); break; } case UnmapNotify: { _glfwInputWindowVisibility(window, GL_FALSE); break; } case FocusIn: { _glfwInputWindowFocus(window, GL_TRUE); if (window->cursorMode == GLFW_CURSOR_DISABLED) disableCursor(window); break; } case FocusOut: { _glfwInputWindowFocus(window, GL_FALSE); if (window->cursorMode == GLFW_CURSOR_DISABLED) restoreCursor(window); break; } case Expose: { _glfwInputWindowDamage(window); break; } case PropertyNotify: { if (event->xproperty.atom == _glfw.x11.WM_STATE && event->xproperty.state == PropertyNewValue) { struct { CARD32 state; Window icon; } *state = NULL; if (_glfwGetWindowProperty(window->x11.handle, _glfw.x11.WM_STATE, _glfw.x11.WM_STATE, (unsigned char**) &state) >= 2) { if (state->state == IconicState) _glfwInputWindowIconify(window, GL_TRUE); else if (state->state == NormalState) _glfwInputWindowIconify(window, GL_FALSE); } XFree(state); } break; } case SelectionClear: { _glfwHandleSelectionClear(event); break; } case SelectionRequest: { _glfwHandleSelectionRequest(event); break; } case DestroyNotify: return; case GenericEvent: { if (event->xcookie.extension == _glfw.x11.xi.majorOpcode && XGetEventData(_glfw.x11.display, &event->xcookie)) { if (event->xcookie.evtype == XI_Motion) { XIDeviceEvent* data = (XIDeviceEvent*) event->xcookie.data; window = _glfwFindWindowByHandle(data->event); if (window) { if (data->event_x != window->x11.warpPosX || data->event_y != window->x11.warpPosY) { // The cursor was moved by something other than GLFW double x, y; if (window->cursorMode == GLFW_CURSOR_DISABLED) { if (_glfw.focusedWindow != window) break; x = data->event_x - window->x11.cursorPosX; y = data->event_y - window->x11.cursorPosY; } else { x = data->event_x; y = data->event_y; } _glfwInputCursorMotion(window, x, y); } window->x11.cursorPosX = data->event_x; window->x11.cursorPosY = data->event_y; } } } XFreeEventData(_glfw.x11.display, &event->xcookie); break; } default: { switch (event->type - _glfw.x11.randr.eventBase) { case RRScreenChangeNotify: { XRRUpdateConfiguration(event); break; } } break; } } }
static void HandleEvents( void ) { XEvent event, response; XSelectionRequestEvent* request; assert( x11display.dpy && x11display.win ); while( XPending( x11display.dpy ) ) { XGenericEventCookie *cookie = &event.xcookie; XNextEvent( x11display.dpy, &event ); if( cookie->type == GenericEvent && cookie->extension == xi_opcode && XGetEventData( x11display.dpy, cookie ) ) { handle_cookie( cookie ); XFreeEventData( x11display.dpy, cookie ); continue; } switch( event.type ) { case FocusIn: if( event.xfocus.mode == NotifyGrab || event.xfocus.mode == NotifyUngrab ) { // Someone is handling a global hotkey, ignore it continue; } if( !focus ) { focus = qtrue; install_grabs_keyboard(); } break; case FocusOut: if( event.xfocus.mode == NotifyGrab || event.xfocus.mode == NotifyUngrab ) { // Someone is handling a global hotkey, ignore it continue; } if( focus ) { if( Cvar_Value( "vid_fullscreen" ) ) { Cbuf_ExecuteText( EXEC_APPEND, "set vid_fullscreen 0\n" ); } uninstall_grabs_keyboard(); Key_ClearStates(); focus = qfalse; shift_level = 0; } break; case ClientMessage: if( event.xclient.data.l[0] == x11display.wmDeleteWindow ) Cbuf_ExecuteText( EXEC_NOW, "quit" ); break; case ConfigureNotify: VID_AppActivate( qtrue, qfalse ); break; case PropertyNotify: if( event.xproperty.window == x11display.win ) { if ( event.xproperty.atom == x11display.wmState ) { qboolean was_minimized = minimized; _X11_CheckWMSTATE(); if( minimized != was_minimized ) { // FIXME: find a better place for this?.. CL_SoundModule_Activate( !minimized ); } } } break; case SelectionClear: // Another app took clipboard ownership away // There's not actually anything we need to do here break; case SelectionRequest: // Another app is requesting clipboard information request = &event.xselectionrequest; memset( &response, 0, sizeof( response ) ); response.xselection.type = SelectionNotify; response.xselection.display = request->display; response.xselection.requestor = request->requestor; response.xselection.selection = request->selection; response.xselection.target = request->target; response.xselection.time = request->time; response.xselection.property = Sys_ClipboardProperty( request ); // Send the response XSendEvent( x11display.dpy, request->requestor, 0, 0, &response ); break; } } }
int main (int argc, char** argv) { /* Connect to the X server */ Display *display = XOpenDisplay(NULL); int screen_num; XGCValues values; Colormap colormap; /* Check if the XInput Extension is available */ int opcode, event, error; if (!XQueryExtension(display, "XInputExtension", &opcode, &event, &error)) { printf("X Input extension not available.\n"); return -1; } /* Check for XI2 support */ int major = 2, minor = 0; if (XIQueryVersion(display, &major, &minor) == BadRequest) { printf("XI2 not available. Server supports %d.%d\n", major, minor); return -1; } /* Get screen size from display structure macro */ screen_num = DefaultScreen(display); int display_width = DisplayWidth(display, screen_num); int display_height = DisplayHeight(display, screen_num); printf("screen_num: %d\n", screen_num); printf("display_width: %d\n", display_width); printf("display_height: %d\n", display_height); /* set window dimensions */ int width = display_width/4*3; int height = display_height/4*3; int border_width = 3; printf("width: %d\n", width); printf("height: %d\n", height); /* create opaque window */ Window win = XCreateSimpleWindow(display, DefaultRootWindow(display), 0, 0, width, height, border_width, WhitePixel(display, screen_num), BlackPixel(display,screen_num)); printf("win: %d\n", (int)win); /* Display window */ XMapWindow(display, win); XSync( display, False ); /* Set default values for pens (GCs) to draw lines with */ values.foreground = WhitePixel(display, screen_num); values.line_width = 10; values.line_style = LineSolid; values.cap_style = CapRound; /* Create colormap */ colormap = DefaultColormap(display, screen_num); /* Set up MPX events */ XIEventMask eventmask; unsigned char mask[1] = { 0 }; eventmask.deviceid = XIAllMasterDevices; eventmask.mask_len = sizeof(mask); eventmask.mask = mask; /* Events we want to listen for */ XISetMask(mask, XI_Motion); XISetMask(mask, XI_ButtonPress); XISetMask(mask, XI_ButtonRelease); XISetMask(mask, XI_KeyPress); XISetMask(mask, XI_KeyRelease); /* Register events on the window */ XISelectEvents(display, win, &eventmask, 1); /* Maximum pointer count */ const unsigned int numPointers = 0xFF; Pointer pointers[numPointers]; /* Initialize pointers */ int i; for(i=0; i<numPointers; i++) { pointers[i].down = 0; pointers[i].p.x = -1; pointers[i].p.y = -1; pointers[i].lastp.x = -1; pointers[i].lastp.y = -1; } /* Event loop */ while(1) { XEvent ev; /* Get next event; blocks until an event occurs */ XNextEvent(display, &ev); if (ev.xcookie.type == GenericEvent && ev.xcookie.extension == opcode && XGetEventData(display, &ev.xcookie)) { XIDeviceEvent* evData = (XIDeviceEvent*)(ev.xcookie.data); int deviceID = evData->deviceid; Pointer *pointer = &pointers[deviceID]; switch(ev.xcookie.evtype) { case XI_Motion: printf("motion\n"); if(pointer->down) { /* Draw a line from the last point to the next one; multiple lines of these create a stroke */ XDrawLine(display, win, pointer->gc, pointer->lastp.x, pointer->lastp.y, evData->event_x, evData->event_y); // Comment out the following for interesting structures pointer->lastp.x = evData->event_x; pointer->lastp.y = evData->event_y; } break; case XI_ButtonPress: printf("click - "); printf("button: %d - ", evData->detail); printf("abs X:%f Y:%f - ", evData->root_x, evData->root_y); printf("win X:%f Y:%f\n", evData->event_x, evData->event_y); /* Create random color for each stroke */ values.foreground = rand() % 0xFFFFFF; pointer->gc = XCreateGC(display, win, GCForeground|GCLineWidth|GCLineStyle|GCCapStyle, &values); XDrawLine(display, win, pointer->gc, evData->event_x, evData->event_y, evData->event_x, evData->event_y); pointer->down = 1; pointer->p.x = evData->event_x; pointer->p.y = evData->event_y; pointer->lastp.x = evData->event_x; pointer->lastp.y = evData->event_y; break; case XI_ButtonRelease: printf("unclick\n"); pointer->down = 0; break; case XI_KeyPress: printf("key down\n"); break; case XI_KeyRelease: printf("key up\n"); break; } } XFreeEventData(display, &ev.xcookie); } XDestroyWindow(display, win); return 0; }
// Process the specified X event // static void processEvent(XEvent *event) { _GLFWwindow* window = NULL; if (event->type != GenericEvent) { window = _glfwFindWindowByHandle(event->xany.window); if (window == NULL) { // This is either an event for a destroyed GLFW window or an event // of a type not currently supported by GLFW return; } } switch (event->type) { case KeyPress: { _glfwInputKey(window, translateKey(event->xkey.keycode), GLFW_PRESS); if (!(event->xkey.state & ControlMask) && !(event->xkey.state & Mod1Mask /*Alt*/)) { _glfwInputChar(window, translateChar(&event->xkey)); } break; } case KeyRelease: { _glfwInputKey(window, translateKey(event->xkey.keycode), GLFW_RELEASE); break; } case ButtonPress: { if (event->xbutton.button == Button1) _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_PRESS); else if (event->xbutton.button == Button2) _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_PRESS); else if (event->xbutton.button == Button3) _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_PRESS); // Modern X provides scroll events as mouse button presses else if (event->xbutton.button == Button4) _glfwInputScroll(window, 0.0, 1.0); else if (event->xbutton.button == Button5) _glfwInputScroll(window, 0.0, -1.0); else if (event->xbutton.button == Button6) _glfwInputScroll(window, -1.0, 0.0); else if (event->xbutton.button == Button7) _glfwInputScroll(window, 1.0, 0.0); break; } case ButtonRelease: { if (event->xbutton.button == Button1) { _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_LEFT, GLFW_RELEASE); } else if (event->xbutton.button == Button2) { _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_MIDDLE, GLFW_RELEASE); } else if (event->xbutton.button == Button3) { _glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_RIGHT, GLFW_RELEASE); } break; } case EnterNotify: { if (window->cursorMode == GLFW_CURSOR_HIDDEN) hideCursor(window); _glfwInputCursorEnter(window, GL_TRUE); break; } case LeaveNotify: { if (window->cursorMode == GLFW_CURSOR_HIDDEN) showCursor(window); _glfwInputCursorEnter(window, GL_FALSE); break; } case MotionNotify: { if (event->xmotion.x != window->x11.cursorPosX || event->xmotion.y != window->x11.cursorPosY) { // The cursor was moved by something other than GLFW int x, y; if (window->cursorMode == GLFW_CURSOR_CAPTURED) { if (_glfw.focusedWindow != window) break; x = event->xmotion.x - window->x11.cursorPosX; y = event->xmotion.y - window->x11.cursorPosY; } else { x = event->xmotion.x; y = event->xmotion.y; } window->x11.cursorPosX = event->xmotion.x; window->x11.cursorPosY = event->xmotion.y; window->x11.cursorCentered = GL_FALSE; _glfwInputCursorMotion(window, x, y); } break; } case ConfigureNotify: { _glfwInputWindowSize(window, event->xconfigure.width, event->xconfigure.height); _glfwInputWindowPos(window, event->xconfigure.x, event->xconfigure.y); break; } case ClientMessage: { // Custom client message, probably from the window manager if ((Atom) event->xclient.data.l[0] == _glfw.x11.WM_DELETE_WINDOW) { // The window manager was asked to close the window, for example by // the user pressing a 'close' window decoration button _glfwInputWindowCloseRequest(window); } else if (_glfw.x11.NET_WM_PING != None && (Atom) event->xclient.data.l[0] == _glfw.x11.NET_WM_PING) { // The window manager is pinging the application to ensure it's // still responding to events event->xclient.window = _glfw.x11.root; XSendEvent(_glfw.x11.display, event->xclient.window, False, SubstructureNotifyMask | SubstructureRedirectMask, event); } break; } case MapNotify: { _glfwInputWindowVisibility(window, GL_TRUE); break; } case UnmapNotify: { _glfwInputWindowVisibility(window, GL_FALSE); break; } case FocusIn: { _glfwInputWindowFocus(window, GL_TRUE); if (window->cursorMode == GLFW_CURSOR_CAPTURED) captureCursor(window); break; } case FocusOut: { _glfwInputWindowFocus(window, GL_FALSE); if (window->cursorMode == GLFW_CURSOR_CAPTURED) showCursor(window); break; } case Expose: { _glfwInputWindowDamage(window); break; } case PropertyNotify: { if (event->xproperty.atom == _glfw.x11.WM_STATE && event->xproperty.state == PropertyNewValue) { struct { CARD32 state; Window icon; } *state = NULL; if (_glfwGetWindowProperty(window->x11.handle, _glfw.x11.WM_STATE, _glfw.x11.WM_STATE, (unsigned char**) &state) >= 2) { if (state->state == IconicState) _glfwInputWindowIconify(window, GL_TRUE); else if (state->state == NormalState) _glfwInputWindowIconify(window, GL_FALSE); } XFree(state); } break; } case SelectionClear: { // The ownership of the clipboard selection was lost free(_glfw.x11.selection.string); _glfw.x11.selection.string = NULL; break; } case SelectionRequest: { // The contents of the clipboard selection was requested XSelectionRequestEvent* request = &event->xselectionrequest; XEvent response; memset(&response, 0, sizeof(response)); response.xselection.property = _glfwWriteSelection(request); response.xselection.type = SelectionNotify; response.xselection.display = request->display; response.xselection.requestor = request->requestor; response.xselection.selection = request->selection; response.xselection.target = request->target; response.xselection.time = request->time; XSendEvent(_glfw.x11.display, request->requestor, False, 0, &response); break; } case DestroyNotify: return; case GenericEvent: { if (event->xcookie.extension == _glfw.x11.xi2.majorOpcode && XGetEventData(_glfw.x11.display, &event->xcookie)) { if (event->xcookie.evtype == XI_Motion) { XIDeviceEvent* data = (XIDeviceEvent*) event->xcookie.data; window = _glfwFindWindowByHandle(data->event); if (window) { if (data->event_x != window->x11.cursorPosX || data->event_y != window->x11.cursorPosY) { // The cursor was moved by something other than GLFW double x, y; if (window->cursorMode == GLFW_CURSOR_CAPTURED) { if (_glfw.focusedWindow != window) break; x = data->event_x - window->x11.cursorPosX; y = data->event_y - window->x11.cursorPosY; } else { x = data->event_x; y = data->event_y; } window->x11.cursorPosX = data->event_x; window->x11.cursorPosY = data->event_y; window->x11.cursorCentered = GL_FALSE; _glfwInputCursorMotion(window, x, y); } } } } XFreeEventData(_glfw.x11.display, &event->xcookie); break; } default: { switch (event->type - _glfw.x11.randr.eventBase) { case RRScreenChangeNotify: { XRRUpdateConfiguration(event); break; } } break; } } }
static GdkEvent * gdk_event_source_translate_event (GdkEventSource *event_source, XEvent *xevent) { GdkEvent *event = gdk_event_new (GDK_NOTHING); GdkFilterReturn result = GDK_FILTER_CONTINUE; GdkEventTranslator *event_translator; GdkWindow *filter_window; Display *dpy; dpy = GDK_DISPLAY_XDISPLAY (event_source->display); #ifdef HAVE_XGENERICEVENTS /* Get cookie data here so it's available * to every event translator and event filter. */ if (xevent->type == GenericEvent) XGetEventData (dpy, &xevent->xcookie); #endif filter_window = gdk_event_source_get_filter_window (event_source, xevent, &event_translator); if (filter_window) event->any.window = g_object_ref (filter_window); /* Run default filters */ if (_gdk_default_filters) { /* Apply global filters */ result = gdk_event_apply_filters (xevent, event, NULL); } if (result == GDK_FILTER_CONTINUE && filter_window && filter_window->filters) { /* Apply per-window filters */ result = gdk_event_apply_filters (xevent, event, filter_window); } if (result != GDK_FILTER_CONTINUE) { #ifdef HAVE_XGENERICEVENTS if (xevent->type == GenericEvent) XFreeEventData (dpy, &xevent->xcookie); #endif if (result == GDK_FILTER_REMOVE) { gdk_event_free (event); return NULL; } else /* GDK_FILTER_TRANSLATE */ return event; } gdk_event_free (event); event = NULL; if (event_translator) { /* Event translator was gotten before in get_filter_window() */ event = _gdk_x11_event_translator_translate (event_translator, event_source->display, xevent); } else { GList *list = event_source->translators; while (list && !event) { GdkEventTranslator *translator = list->data; list = list->next; event = _gdk_x11_event_translator_translate (translator, event_source->display, xevent); } } if (event && (event->type == GDK_ENTER_NOTIFY || event->type == GDK_LEAVE_NOTIFY) && event->crossing.window != NULL) { /* Handle focusing (in the case where no window manager is running */ handle_focus_change (&event->crossing); } #ifdef HAVE_XGENERICEVENTS if (xevent->type == GenericEvent) XFreeEventData (dpy, &xevent->xcookie); #endif return event; }
bool rawinput_msg_x11(Display *display,int opcode,XEvent *ev, int *inputs,int *mx,int *my,int *mz) { XGenericEventCookie *cookie = &ev->xcookie; if(cookie->type!=GenericEvent) { return false; } if(cookie->extension != opcode) { return false; } if(!XGetEventData(display, cookie)) { return false; } XIRawEvent *xiEvent = (XIRawEvent*)cookie->data; double *raw_valuator = xiEvent->raw_values; double *valuator = xiEvent->valuators.values; if(cookie->evtype==XI_RawButtonPress) { if(xiEvent->detail == 1) { if(inputs[MOUSE_LEFT]!=INPUT_DOWN) { inputs[MOUSE_LEFT]=INPUT_PRESS; } } else if(xiEvent->detail == 2) { if(inputs[MOUSE_MIDDLE]!=INPUT_DOWN) { inputs[MOUSE_MIDDLE]=INPUT_PRESS; } } else if(xiEvent->detail == 3) { if(inputs[MOUSE_RIGHT]!=INPUT_DOWN) { inputs[MOUSE_RIGHT]=INPUT_PRESS; } } } else if(cookie->evtype==XI_RawButtonRelease) { if(xiEvent->detail == 1 ) {// if(inputs[MOUSE_LEFT]!=INPUT_UP) { inputs[MOUSE_LEFT]=INPUT_RELEASE; } } else if(xiEvent->detail == 2) { if(inputs[MOUSE_MIDDLE]!=INPUT_UP) { inputs[MOUSE_MIDDLE]=INPUT_RELEASE; } } else if(xiEvent->detail == 3) { if(inputs[MOUSE_RIGHT]!=INPUT_UP) { inputs[MOUSE_RIGHT]=INPUT_RELEASE; } } } else if(cookie->evtype==XI_RawKeyPress) { int k=key_convert_x11(xiEvent->detail); if(inputs[k]!=INPUT_DOWN) { inputs[k]=INPUT_PRESS; } } else if(cookie->evtype==XI_RawKeyRelease) { int k=key_convert_x11(xiEvent->detail); if(inputs[k]!=INPUT_UP) { inputs[k]=INPUT_RELEASE; } } else if(cookie->evtype==XI_RawMotion) { int i; for (i = 0; i < xiEvent->valuators.mask_len * 8; i++) { if (XIMaskIsSet(xiEvent->valuators.mask, i) ) { if(i==0 && valuator[i]!=0.0) {//x *mx=(int)valuator[i];//- raw_valuator[i]; } else if(i==1 && valuator[i]!=0.0) {//y *my=(int)valuator[i];//- raw_valuator[i]; } else if(i==2 && valuator[i]!=0.0) {//z *mz=(int)valuator[i];//- raw_valuator[i]; } else if(i==3 && valuator[i]!=0.0) {//z } } } } return true; }
/** * \brief This function is called when an Extension Event is received * and calls the corresponding callback functions for these events. */ void fgHandleExtensionEvents( XEvent* base_ev ) { int i, button = 0; XGenericEventCookie* cookie = (XGenericEventCookie*)&(base_ev->xcookie); if ( XGetEventData( fgDisplay.Display, cookie ) && (cookie->type == GenericEvent) && (cookie->extension == xi_opcode) ) { XIDeviceEvent* event = (XIDeviceEvent*)(cookie->data); /*printf("XI2 event type: %d - %d\n", cookie->evtype, event->type );*/ SFG_Window* window = fgWindowByHandle( event->event ); if (!window) return; switch (cookie->evtype) { case XI_Enter: case XI_Leave: fgState.Modifiers = fghGetXModifiers( ((XIEnterEvent*)event)->mods.base ); INVOKE_WCB( *window, MultiEntry, ( event->deviceid, (event->evtype == XI_Enter ? GLUT_ENTERED : GLUT_LEFT) )); #if _DEBUG fgPrintXILeaveEvent((XILeaveEvent*)event); #endif break; case XI_ButtonPress: case XI_ButtonRelease: fgState.Modifiers = fghGetXModifiers( event->mods.base ); INVOKE_WCB( *window, MultiButton, ( event->deviceid, event->event_x, event->event_y, (event->detail)-1, (event->evtype == XI_ButtonPress ? GLUT_DOWN : GLUT_UP) )); INVOKE_WCB( *window, Mouse, ( (event->detail)-1, (event->evtype == XI_ButtonPress ? GLUT_DOWN : GLUT_UP), event->event_x, event->event_y )); break; case XI_Motion: fgState.Modifiers = fghGetXModifiers( event->mods.base ); for (i = 0; i < event->buttons.mask_len; i++) if (event->buttons.mask[i]) button = 1; if (button) { INVOKE_WCB( *window, MultiMotion, ( event->deviceid, event->event_x, event->event_y ) ); INVOKE_WCB( *window, Motion, ( event->event_x, event->event_y ) ); } else { INVOKE_WCB( *window, MultiPassive, ( event->deviceid, event->event_x, event->event_y ) ); INVOKE_WCB( *window, Passive, ( event->event_x, event->event_y ) ); } #if _DEBUG fgPrintXIDeviceEvent(event); #endif break; default: #if _DEBUG fgWarning( "Unknown XI2 device event:" ); fgPrintXIDeviceEvent( event ); #endif break; } fgState.Modifiers = INVALID_MODIFIERS; } XFreeEventData( fgDisplay.Display, cookie ); }
void EventHandler::run() { qDebug("EventHandler::run"); XInitThreads(); Display *display; int xi_opcode, event, error; display = XOpenDisplay(NULL); if (!display) { qDebug("Could not open display."); return; } if (!XQueryExtension(display, "XInputExtension", &xi_opcode, &event, &error)) { qDebug("XInputExtension is not available."); return; } XIEventMask mask; XSelectInput(display, DefaultRootWindow(display), ExposureMask); mask.deviceid = XIAllDevices; mask.mask_len = sizeof(mask); mask.mask = (unsigned char*)calloc(mask.mask_len, sizeof(char)); XISetMask(mask.mask, XI_Motion); XISetMask(mask.mask, XI_ButtonPress); XISetMask(mask.mask, XI_ButtonRelease); XISelectEvents(display, DefaultRootWindow(display), &mask, 1); free(mask.mask); XMapWindow(display, DefaultRootWindow(display)); XSync(display, True); while(1) { XEvent ev; XGenericEventCookie *cookie = (XGenericEventCookie*)&ev.xcookie; XNextEvent(display, (XEvent*)&ev); if (XGetEventData(display, cookie) && cookie->type == GenericEvent && cookie->extension == xi_opcode) { switch (cookie->evtype) { case XI_ButtonPress: { XIDeviceEvent *e = (XIDeviceEvent*)(cookie->data); #ifndef ANN_TRAINING qDebug("XI_ButtonPress, x: %.2f, y: %.2f", e->root_x, e->root_y); #endif QList<QPoint> points; parseTouchPoints(e->valuators, points); m_targetDist = 0.0; m_distance = 0.0; m_time.restart(); emit this->touchPress(points); } break; case XI_ButtonRelease: { XIDeviceEvent *e = (XIDeviceEvent*)(cookie->data); #ifndef ANN_TRAINING qDebug("Button release, x: %.2f, y: %.2f", e->root_x, e->root_y); #endif QList<QPoint> points; parseTouchPoints(e->valuators, points); //qDebug("%d ms since previous event", m_time.elapsed()); //m_server->touchRelease(points); emit this->touchRelease(points); } break; case XI_Motion: { XIDeviceEvent *e = (XIDeviceEvent*)(cookie->data); #ifndef ANN_TRAINING //qDebug("XI_Motion, x: %.2f, y: %.2f", e->root_x, e->root_y); #endif QList<QPoint> points; parseTouchPoints(e->valuators, points); m_targetDist = m_time.elapsed()*TARGET_SPEED; m_curPoint = QPoint(e->root_x, e->root_y); m_distance += QPointF(m_curPoint-m_prevPoint).manhattanLength(); m_prevPoint = m_curPoint; if ( m_distance >= m_targetDist ) { emit this->touchMove(points); m_distance = 0; } m_time.restart(); } break; default: break; } } XFreeEventData(display, cookie); } qDebug() << "GestureHandler Thread exiting." << endl; }
/* X thread that processes X events in parallel to kernel device loop */ void handleXEvent() { XEvent ev; XNextEvent(display, &ev); //if(debugMode) printf("Handle event\n"); if (XGetEventData(display, &(ev.xcookie))) { XGenericEventCookie *cookie = &(ev.xcookie); // Touch events don't work right now //if (cookie->evtype == XI_TouchBegin) { // if(debugMode) printf("Touch begin\n"); //} else if (cookie->evtype == XI_TouchUpdate) { // if(debugMode) printf("Touch update\n"); //} else if (cookie->evtype == XI_TouchEnd) { // if(debugMode) printf("Touch end\n"); if (cookie->evtype == XI_Motion) { if(debugMode) printf("Motion event\n"); //int r = XIAllowEvents(display, deviceID, XIReplayDevice, CurrentTime); //printf("XIAllowEvents result: %i\n", r); } else if (cookie->evtype == XI_PropertyEvent) { /* Device properties changed -> recalibrate. */ if(debugMode) printf("Device properties changed.\n"); readCalibrationData(0); } else if(cookie->evtype == XI_ButtonPress) { if(debugMode) printf("Button Press\n"); //int r = XIAllowEvents(display, deviceID, XIReplayDevice, CurrentTime); //printf("XIAllowEvents result: %i\n", r); } // In an ideal world, the following would work. But unfortunately the touch events // delivered by evdev are often crap on the eGalax screen, with missing events when there // should be some. So we still have to read directly from the input device, as bad as that is. //if (cookie->evtype == XI_TouchBegin || cookie->evtype == XI_TouchUpdate || cookie->evtype == XI_TouchEnd) { // XIDeviceEvent * devEvt = (XIDeviceEvent*) cookie->data; // printf("Detail: %i\n", devEvt->detail); // printf("Mask[0]: %i\n", (int) devEvt->valuators.mask[0]); // // /* 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].id == devEvt->detail) { // index = i; // break; // } // } // // /* No slot for this id found, look for free one */ // 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 = devEvt->detail; // break; // } // } // } // // /* We have found a slot */ // if(index != -1) { // fingerInfos[index].slotUsed = (cookie->evtype != XI_TouchEnd ? 1 : 0); // // i = 0; // if((devEvt->valuators.mask[0] & 1) == 1) // { // fingerInfos[index].rawX = (int) devEvt->valuators.values[i++]; // } // if((devEvt->valuators.mask[0] & 2) == 2) // { // fingerInfos[index].rawY = (int) devEvt->valuators.values[i++]; // } // if((devEvt->valuators.mask[0] & 4) == 4) // { // fingerInfos[index].rawZ = (int) devEvt->valuators.values[i++]; // } // } // // processFingers(); //} XFreeEventData(display, &(ev.xcookie)); } else { if(ev.type == 101) { /* Why isn't this magic constant explained anywhere?? */ setScreenSize((XRRScreenChangeNotifyEvent *) &ev); } } }
/** * clutter_x11_handle_event: * @xevent: pointer to XEvent structure * * This function processes a single X event; it can be used to hook * into external X11 event processing (for example, a GDK filter * function). * * If clutter_x11_disable_event_retrieval() has been called, you must * let this function process events to update Clutter's internal state. * * Return value: #ClutterX11FilterReturn. %CLUTTER_X11_FILTER_REMOVE * indicates that Clutter has internally handled the event and the * caller should do no further processing. %CLUTTER_X11_FILTER_CONTINUE * indicates that Clutter is either not interested in the event, * or has used the event to update internal state without taking * any exclusive action. %CLUTTER_X11_FILTER_TRANSLATE will not * occur. * * Since: 0.8 */ ClutterX11FilterReturn clutter_x11_handle_event (XEvent *xevent) { ClutterX11FilterReturn result; ClutterBackend *backend; ClutterEvent *event; gint spin = 1; #ifdef HAVE_XGE ClutterBackendX11 *backend_x11; Display *xdisplay; gboolean allocated_event; #endif /* The return values here are someone approximate; we return * CLUTTER_X11_FILTER_REMOVE if a clutter event is * generated for the event. This mostly, but not entirely, * corresponds to whether other event processing should be * excluded. As long as the stage window is not shared with another * toolkit it should be safe, and never return * %CLUTTER_X11_FILTER_REMOVE when more processing is needed. */ result = CLUTTER_X11_FILTER_CONTINUE; _clutter_threads_acquire_lock (); backend = clutter_get_default_backend (); event = clutter_event_new (CLUTTER_NOTHING); #ifdef HAVE_XGE backend_x11 = CLUTTER_BACKEND_X11 (backend); xdisplay = backend_x11->xdpy; allocated_event = XGetEventData (xdisplay, &xevent->xcookie); #endif if (_clutter_backend_translate_event (backend, xevent, event)) { _clutter_event_push (event, FALSE); result = CLUTTER_X11_FILTER_REMOVE; } else { clutter_event_free (event); goto out; } /* * Motion events can generate synthetic enter and leave events, so if we * are processing a motion event, we need to spin the event loop at least * two extra times to pump the enter/leave events through (otherwise they * just get pushed down the queue and never processed). */ if (event->type == CLUTTER_MOTION) spin += 2; while (spin > 0 && (event = clutter_event_get ())) { /* forward the event into clutter for emission etc. */ _clutter_stage_queue_event (event->any.stage, event, FALSE); --spin; } out: #ifdef HAVE_XGE if (allocated_event) XFreeEventData (xdisplay, &xevent->xcookie); #endif _clutter_threads_release_lock (); return result; }