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;
}
Exemple #2
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;
}
Exemple #3
0
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;
}
Exemple #4
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);
        }
    }
}
Exemple #7
0
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;
}
Exemple #8
0
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 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);
	}
}
Exemple #10
0
static gboolean
xfwm_device_check_mask_event_xi2_predicate (Display *display, XEvent *xevent, XPointer user_data)
{
    XI2CheckMaskContext *context = (void *)user_data;

    if (xevent->type == GenericEvent &&
        xevent->xgeneric.extension == context->devices->xi2_opcode &&
        XIMaskIsSet (context->xievent_mask.mask, xevent->xgeneric.evtype))
    {
        /* GDK holds XI2 event data which we are replacing so it should be released here */
        XFreeEventData (display, &context->event->meta.x->xcookie);
        return TRUE;
    }

    return FALSE;
}
Exemple #11
0
void XInputMTInputDevice::handleXIEvent(const XEvent& xEvent)
{
    m_SDLLockFunc();
    XGenericEventCookie* pCookie = (XGenericEventCookie*)&xEvent.xcookie;
    if (pCookie->type == GenericEvent && pCookie->extension == m_XIOpcode) {
        XIDeviceEvent* pDevEvent = (XIDeviceEvent*)(pCookie->data);
        IntPoint pos(pDevEvent->event_x, pDevEvent->event_y);
        int xid = pDevEvent->detail;
        switch (pCookie->evtype) {
            case XI_TouchBegin:
                {
//                    cerr << "TouchBegin " << xid << ", " << pos << endl;
                    m_LastID++;
                    TouchEventPtr pEvent = createEvent(m_LastID, Event::CURSOR_DOWN, pos);
                    addTouchStatus(xid, pEvent);
                }
                break;
            case XI_TouchUpdate:
                {
//                    cerr << "TouchUpdate " << xid << ", " << pos << endl;
                    TouchEventPtr pEvent = createEvent(0, Event::CURSOR_MOTION, pos); 
                    TouchStatusPtr pTouchStatus = getTouchStatus(xid);
                    AVG_ASSERT(pTouchStatus);
                    pTouchStatus->pushEvent(pEvent);
                }
                break;
            case XI_TouchEnd:
                {
//                    cerr << "TouchEnd " << xid << ", " << pos << endl;
                    TouchStatusPtr pTouchStatus = getTouchStatus(xid);
                    AVG_ASSERT(pTouchStatus);
                    TouchEventPtr pEvent = createEvent(0, Event::CURSOR_UP, pos); 
                    pTouchStatus->pushEvent(pEvent);
                }
                break;
            default:
                ;
//                cerr << "Unhandled XInput event, type: " 
//                        << cookieTypeToName(pCookie->evtype) << endl;
        }
    } else {
//        cerr << "Unhandled X11 Event: " << xEvent.type << endl;
    }

    XFreeEventData(s_pDisplay, pCookie);
    m_SDLUnlockFunc();
}
Exemple #12
0
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;
}
Exemple #13
0
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 );
            }
        }
    }
}
Exemple #15
0
bool xorg::testing::XServer::WaitForDevice(::Display *display, const std::string &name,
                                           time_t timeout)
{
    int opcode;
    int event_start;
    int error_start;
    bool device_found = false;

    if (!XQueryExtension(display, "XInputExtension", &opcode, &event_start,
                         &error_start))
        throw std::runtime_error("Failed to query XInput extension");

    XIEventMask *masks;
    int nmasks;
    bool mask_set, mask_created;
    masks = set_hierarchy_mask(display, &nmasks, &mask_set, &mask_created);

    XIDeviceInfo *info;
    int ndevices;

    info = XIQueryDevice(display, XIAllDevices, &ndevices);
    for (int i = 0; !device_found && i < ndevices; i++) {
      device_found = (name.compare(info[i].name) == 0);
    }
    XIFreeDeviceInfo(info);

    while (!device_found &&
           WaitForEventOfType(display, GenericEvent, opcode,
                              XI_HierarchyChanged, timeout)) {
        XEvent event;
        if (XNextEvent(display, &event) != Success)
            throw std::runtime_error("Failed to get X event");

        XGenericEventCookie *xcookie =
            reinterpret_cast<XGenericEventCookie*>(&event.xcookie);
        if (!XGetEventData(display, xcookie))
            throw std::runtime_error("Failed to get X event data");

        XIHierarchyEvent *hierarchy_event =
            reinterpret_cast<XIHierarchyEvent*>(xcookie->data);

        if (!(hierarchy_event->flags & XIDeviceEnabled)) {
            XFreeEventData(display, xcookie);
            continue;
        }

        device_found = false;
        for (int i = 0; i < hierarchy_event->num_info; i++) {
            if (!(hierarchy_event->info[i].flags & XIDeviceEnabled))
                continue;

            int num_devices;
            XIDeviceInfo *device_info =
                XIQueryDevice(display, hierarchy_event->info[i].deviceid,
                              &num_devices);
            if (num_devices != 1 || !device_info)
                throw std::runtime_error("Failed to query device");

            if (name.compare(device_info[0].name) == 0) {
                device_found = true;
                break;
            }
        }

        XFreeEventData(display, xcookie);

        if (device_found)
          break;
    }

    unset_hierarchy_mask(display, masks, nmasks, mask_set, mask_created);

    return device_found;
}
Exemple #16
0
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;
}
Exemple #17
0
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);
}
/**
 * \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 );
}
Exemple #19
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 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;
        }
    }
}
Exemple #20
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 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;
        }
    }
}
Exemple #21
0
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;
}
Exemple #22
0
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;
}
Exemple #23
0
/**
 * \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 );
}
bool window_update() {
  bool focused=false;
  windowData.restored=false;

  windowData.mouseX=0;
  windowData.mouseY=0;
  windowData.mouseZ=0;
  //
  int i;

  //
  for(i=0;i<INPUTS_SIZE;i++) {
    if(windowData.inputs[i]==INPUT_PRESS) {
      windowData.inputs[i]=INPUT_DOWN;
    } else if(windowData.inputs[i]==INPUT_RELEASE) {
      windowData.inputs[i]=INPUT_UP;
    }
  }

  //
  while(1) {
    XEvent ev;

    while(XPending(windowData.display)) {
      XNextEvent(windowData.display,&ev);

      if(ev.type==DestroyNotify) {
        printf("Exit\n");
        return false;
      }

      if(ev.type==ClientMessage) {
        if ((Atom)ev.xclient.data.l[0] == windowData.wmDelete) {
          printf("Exit2\n");
          return false;
        }
      }

      rawinput_msg_x11(windowData.display,windowData.xiopcode,&ev,windowData.inputs,
                       &windowData.mouseX,&windowData.mouseY,&windowData.mouseZ);

      XFreeEventData(windowData.display, &ev.xcookie);
    }

    //

    //
    windowData.iconic=iconic_x11(windowData.display,windowData.win);

    //
    if(!windowData.iconic) {
      break;
    }

    windowData.restored=true;
    sched_yield();
  }

  //
  focused=window_focused_x11(windowData.display,windowData.win);

  //
  int clientWidth,clientHeight;

  client_size_x11(windowData.display,windowData.win,&clientWidth,&clientHeight);
  windowData.sized=windowData.clientWidth!=clientWidth || windowData.clientHeight!=clientHeight;
  windowData.clientWidth=clientWidth;
  windowData.clientHeight=clientHeight;

  //
  cursor_pos_x11(windowData.display,windowData.win,
                 &windowData.cursorX,&windowData.cursorY);

  //
  if(!windowData.cursorLocked) {
    windowData.lockedCursorX=windowData.cursorX;
    windowData.lockedCursorY=windowData.cursorY;
  }

  //
  lock_cursor_x11(windowData.lockCursor && focused,
                  &windowData.cursorLocked,
                  windowData.display,windowData.win,
                  windowData.blankCursor,
                  windowData.lockedCursorX,windowData.lockedCursorY);

  //
  if(!focused || windowData.restored) {
    for(i=0;i<INPUTS_SIZE;i++) {
      if(windowData.inputs[i]!=INPUT_UP) {
        windowData.inputs[i]=INPUT_RELEASE;
      }
    }

    windowData.cursorX=-1;
    windowData.cursorY=-1;
  }

  windowData.lockCursor=false;
  return true;
}
/**
 * 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;
}
Exemple #26
0
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;
}
Exemple #27
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;
        }
    }
}
Exemple #28
0
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;

}
/* 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);
		}
	}
}
Exemple #30
0
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;
		}
	}
}