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;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 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);
}
Ejemplo n.º 5
0
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);
        }
    }
}
Ejemplo n.º 7
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);
}
Ejemplo n.º 8
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;
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
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);
	}
}
Ejemplo n.º 11
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;
}
Ejemplo n.º 12
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;
}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
0
Archivo: events.c Proyecto: Limsik/e17
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 );
            }
        }
    }
}
Ejemplo n.º 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;
}
Ejemplo n.º 17
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;
}
Ejemplo n.º 18
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 )
{
    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 );
}
Ejemplo n.º 19
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);
}
Ejemplo n.º 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;
        }
    }
}
Ejemplo n.º 21
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;
        }
    }
}
Ejemplo n.º 22
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;
		}
	}
}
Ejemplo n.º 23
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;

}
Ejemplo n.º 24
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;
        }
    }
}
Ejemplo n.º 25
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;
}
Ejemplo n.º 26
0
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;
}
Ejemplo n.º 27
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 );
}
Ejemplo n.º 28
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;
}
Ejemplo n.º 29
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);
		}
	}
}
Ejemplo n.º 30
0
/**
 * 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;
}