コード例 #1
0
static int setup_events(Display *dpy)
{
    XIEventMask mask[2];
    Window root;
    int dummy;

    if (!XQueryExtension(dpy, "XInputExtension", &xinput, &dummy, &dummy)) {
        puts("Could not query XInputExtension");
        return -1;
    }
    root = DefaultRootWindow(dpy);

    mask[0].deviceid = XIAllDevices;
    mask[0].mask_len = XIMaskLen(XI_LASTEVENT);
    mask[0].mask = calloc(mask[0].mask_len, sizeof(char));

    mask[1].deviceid = XIAllMasterDevices;
    mask[1].mask_len = XIMaskLen(XI_LASTEVENT);
    mask[1].mask = calloc(mask[1].mask_len, sizeof(char));
    XISetMask(mask[1].mask, XI_RawKeyPress);
    XISetMask(mask[1].mask, XI_RawButtonPress);

    XISelectEvents(dpy, root, &mask[0], 2);

    if (!XSync(dpy, False)) {
        puts("Could not sync display");
        return -1;
    }

    free(mask[0].mask);
    free(mask[1].mask);

    return 0;
}
コード例 #2
0
ファイル: main.c プロジェクト: C-o-r-E/xtouch
static void select_events(Display *dpy, Window win)
{
    XIEventMask evmasks[2];
    unsigned char mask1[(XI_LASTEVENT + 7)/8];
    unsigned char mask2[(XI_LASTEVENT + 7)/8];

    memset(mask1, 0, sizeof(mask1));

    /* select for button and key events from all master devices */
    /*XISetMask(mask1, XI_ButtonPress);
    XISetMask(mask1, XI_ButtonRelease);
    XISetMask(mask1, XI_KeyPress);
    XISetMask(mask1, XI_KeyRelease);
*/

   	XISetMask(mask1, XI_TouchBegin);
	XISetMask(mask1, XI_TouchUpdate);
	XISetMask(mask1, XI_TouchEnd);

    evmasks[0].deviceid = XIAllDevices;
    evmasks[0].mask_len = sizeof(mask1);
    evmasks[0].mask = mask1;

    memset(mask2, 0, sizeof(mask2));

    /* Select for motion from the default cursor */
    XISetMask(mask2, XI_Motion);

    evmasks[1].deviceid = 2; /* the default cursor */
    evmasks[1].mask_len = sizeof(mask2);
    evmasks[1].mask = mask2;

    XISelectEvents(dpy, win, evmasks, 1);
    XFlush(dpy);
}
コード例 #3
0
ファイル: freeglut_xinput.c プロジェクト: JulianGu/MRDev
/**
 * \brief Sets window up for XI2 events.
 */
void fgRegisterDevices( Display* dpy, Window* win ) {

	XIEventMask mask;
	unsigned char flags[2] = { 0, 0 };
	int event, error;

	/*Display* dpy = fgDisplay.Display;
	Window* win = glutGetXWindow();*/

	/* get XInput extension opcode */
	if (!XQueryExtension( dpy, "XInputExtension", &xi_opcode, &event, &error )) { xi_opcode = -1; }

	/* Select for motion events */
	mask.deviceid = XIAllMasterDevices;
	mask.mask_len = 2;
	mask.mask = flags;

	XISetMask(mask.mask, XI_Enter);
	XISetMask(mask.mask, XI_Motion);
	XISetMask(mask.mask, XI_ButtonPress);
	XISetMask(mask.mask, XI_ButtonRelease);
	XISetMask(mask.mask, XI_Leave);
	/*XISetMask(mask.mask, XI_KeyPress);
	XISetMask(mask.mask, XI_KeyRelease);
	XISetMask(mask.mask, XI_DeviceChanged);
	XISetMask(mask.mask, XI_RawEvent);
	XISetMask(mask.mask, XI_FocusIn);
	XISetMask(mask.mask, XI_FocusOut);
	XISetMask(mask.mask, XI_HierarchyChanged);*/

	XISelectEvents( dpy, *win, &mask, 1 );
}
コード例 #4
0
int setupXiInput(Display *display) {
   int opcode;
   Window defaultRootWin;
   defaultRootWin=DefaultRootWindow(display);

  // int major = 2, minor = 0;
   // (XIQueryVersion(display, &major, &minor) == BadRequest)

  int event, error;

  if(XQueryExtension(display, "XInputExtension", &opcode, &event, &error) == 0) {
    fprintf(stderr,"window_create: X Input extension not available.\n");
    return 0;
  }

  XIEventMask eventmask;
  unsigned char mask[4]={0,0,0,0};

  eventmask.deviceid = XIAllMasterDevices;
  eventmask.mask_len = sizeof(mask);
  eventmask.mask = mask;

  XISetMask(mask, XI_RawMotion);
  XISetMask(mask, XI_RawButtonPress);
  XISetMask(mask, XI_RawButtonRelease);
  XISetMask(mask, XI_RawKeyPress);
  XISetMask(mask, XI_RawKeyRelease);

  XISelectEvents(display, defaultRootWin, &eventmask, 1);

  return opcode;
}
コード例 #5
0
EAPI Eina_Bool
ecore_x_input_raw_select(Ecore_X_Window win)
{
#ifdef ECORE_XI2
   XIEventMask emask;
   unsigned char mask[4] = { 0 };

   if (!_ecore_x_xi2_devs)
     return EINA_FALSE;

   LOGFN(__FILE__, __LINE__, __FUNCTION__);
   emask.deviceid = XIAllMasterDevices;
   emask.mask_len = sizeof(mask);
   emask.mask = mask;
#ifdef XI_RawButtonPress
   XISetMask(emask.mask, XI_RawButtonPress);
#endif
#ifdef XI_RawButtonRelease
   XISetMask(emask.mask, XI_RawButtonRelease);
#endif
#ifdef XI_RawMotion
   XISetMask(emask.mask, XI_RawMotion);
#endif

   XISelectEvents(_ecore_x_disp, win, &emask, 1);

   return EINA_TRUE;
#else
   return EINA_FALSE;
#endif
}
コード例 #6
0
ファイル: XInput2.cpp プロジェクト: Blackbird88/dolphin
KeyboardMouse::KeyboardMouse(Window window, int opcode, int pointer, int keyboard)
	: m_window(window), xi_opcode(opcode), pointer_deviceid(pointer), keyboard_deviceid(keyboard)
{
	memset(&m_state, 0, sizeof(m_state));

	// The cool thing about each KeyboardMouse object having its own Display
	// is that each one gets its own separate copy of the X11 event stream,
	// which it can individually filter to get just the events it's interested
	// in. So be aware that each KeyboardMouse object actually has its own X11
	// "context."
	m_display = XOpenDisplay(nullptr);

	int min_keycode, max_keycode;
	XDisplayKeycodes(m_display, &min_keycode, &max_keycode);

	int unused; // should always be 1
	XIDeviceInfo* pointer_device = XIQueryDevice(m_display, pointer_deviceid, &unused);
	name = std::string(pointer_device->name);
	XIFreeDeviceInfo(pointer_device);

	XIEventMask   mask;
	unsigned char mask_buf[(XI_LASTEVENT + 7)/8];

	mask.mask_len = sizeof(mask_buf);
	mask.mask = mask_buf;
	memset(mask_buf, 0, sizeof(mask_buf));

	XISetMask(mask_buf, XI_ButtonPress);
	XISetMask(mask_buf, XI_ButtonRelease);
	XISetMask(mask_buf, XI_RawMotion);
	XISetMask(mask_buf, XI_KeyPress);
	XISetMask(mask_buf, XI_KeyRelease);

	SelectEventsForDevice(DefaultRootWindow(m_display), &mask, pointer_deviceid);
	SelectEventsForDevice(DefaultRootWindow(m_display), &mask, keyboard_deviceid);

	// Keyboard Keys
	for (int i = min_keycode; i <= max_keycode; ++i)
	{
		Key* temp_key = new Key(m_display, i, m_state.keyboard);
		if (temp_key->m_keyname.length())
			AddInput(temp_key);
		else
			delete temp_key;
	}

	// Mouse Buttons
	for (int i = 0; i < 5; i++)
		AddInput(new Button(i, m_state.buttons));

	// Mouse Cursor, X-/+ and Y-/+
	for (int i = 0; i != 4; ++i)
		AddInput(new Cursor(!!(i & 2), !!(i & 1), (&m_state.cursor.x)[!!(i & 2)]));

	// Mouse Axis, X-/+ and Y-/+
	for (int i = 0; i != 4; ++i)
		AddInput(new Axis(!!(i & 2), !!(i & 1), (&m_state.axis.x)[!!(i & 2)]));
}
コード例 #7
0
void SetupXI2Events()
{
  Display *dpy = nux::GetGraphicsDisplay()->GetX11Display();

  unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
  XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };

  XISetMask(mask.mask, XI_BarrierHit);
  XISetMask(mask.mask, XI_BarrierLeave);
  XISelectEvents (dpy, DefaultRootWindow(dpy), &mask, 1);
}
コード例 #8
0
ファイル: unix_input.c プロジェクト: Turupawn/DogeWarsow
static void install_grabs_mouse( void )
{
	int i;
	int num_devices;
	XIDeviceInfo *info;
	XIEventMask mask;

	assert( x11display.dpy && x11display.win );

	if( mouse_active )
		return;

	XDefineCursor(x11display.dpy, x11display.win, CreateNullCursor(x11display.dpy, x11display.win));

	mask.deviceid = XIAllDevices;
	mask.mask_len = XIMaskLen(XI_LASTEVENT);
	mask.mask = calloc(mask.mask_len, sizeof(char));
	XISetMask(mask.mask, XI_Enter);
	XISetMask(mask.mask, XI_Leave);
	XISetMask(mask.mask, XI_ButtonPress);
	XISetMask(mask.mask, XI_ButtonRelease);

	info = XIQueryDevice(x11display.dpy, XIAllDevices, &num_devices);
	for(i = 0; i < num_devices; i++) {
		int id = info[i].deviceid;
		if(info[i].use == XISlavePointer) {
			mask.deviceid = id;
			XIGrabDevice(x11display.dpy, id, x11display.win, CurrentTime, None, GrabModeSync,
				GrabModeSync, True, &mask);
		}
		else if(info[i].use == XIMasterPointer) {
			if (x11display.features.wmStateFullscreen)
				XIWarpPointer(x11display.dpy, id, None, x11display.win, 0, 0, 0, 0, 0, 0);
			else
				XIWarpPointer(x11display.dpy, id, None, x11display.win, 0, 0, 0, 0, x11display.win_width/2, x11display.win_height/2);
		}
	}
	XIFreeDeviceInfo(info);

	mask.deviceid = XIAllDevices;
	memset(mask.mask, 0, mask.mask_len);
	XISetMask(mask.mask, XI_RawMotion);

	XISelectEvents(x11display.dpy, DefaultRootWindow(x11display.dpy), &mask, 1);

	free(mask.mask);

	XSync(x11display.dpy, True);

	mx = my = 0;
	mouse_active = qtrue;
}
コード例 #9
0
void
grab_button (int        deviceid,
             gboolean   grab,
             GdkScreen *screen)
{
	GdkWindow *root;
	XIGrabModifiers mods;

	root = gdk_screen_get_root_window (screen);
	mods.modifiers = XIAnyModifier;

	if (grab) {
		XIEventMask evmask;
		unsigned char mask[(XI_LASTEVENT + 7)/8];

		memset (mask, 0, sizeof (mask));
		XISetMask (mask, XI_ButtonRelease);
		XISetMask (mask, XI_ButtonPress);

		evmask.deviceid = deviceid;
		evmask.mask_len = sizeof (mask);
		evmask.mask = mask;

		gdk_error_trap_push();
		XIGrabButton (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
			      deviceid,
			      XIAnyButton,
			      GDK_WINDOW_XID (root),
			      None,
			      GrabModeAsync,
			      GrabModeAsync,
			      False,
			      &evmask,
			      1,
			      &mods);
		gdk_error_trap_pop_ignored ();
	} else {
		gdk_error_trap_push();
		XIUngrabButton (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
				deviceid,
				XIAnyButton,
		                GDK_WINDOW_XID (root),
				1, &mods);
		gdk_error_trap_pop_ignored ();
	}
}
コード例 #10
0
static void
take_touch_grab (MetaBackend *backend)
{
  MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
  MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
  unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
  XIEventMask mask = { META_VIRTUAL_CORE_POINTER_ID, sizeof (mask_bits), mask_bits };
  XIGrabModifiers mods = { XIAnyModifier, 0 };

  XISetMask (mask.mask, XI_TouchBegin);
  XISetMask (mask.mask, XI_TouchUpdate);
  XISetMask (mask.mask, XI_TouchEnd);

  XIGrabTouchBegin (priv->xdisplay, META_VIRTUAL_CORE_POINTER_ID,
                    DefaultRootWindow (priv->xdisplay),
                    False, &mask, 1, &mods);
}
コード例 #11
0
static gboolean
meta_backend_x11_grab_device (MetaBackend *backend,
                              int          device_id,
                              uint32_t     timestamp)
{
  MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
  MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
  unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
  XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };
  int ret;

  if (timestamp != CurrentTime)
    timestamp = MAX (timestamp, priv->latest_evtime);

  XISetMask (mask.mask, XI_ButtonPress);
  XISetMask (mask.mask, XI_ButtonRelease);
  XISetMask (mask.mask, XI_Enter);
  XISetMask (mask.mask, XI_Leave);
  XISetMask (mask.mask, XI_Motion);
  XISetMask (mask.mask, XI_KeyPress);
  XISetMask (mask.mask, XI_KeyRelease);

  ret = XIGrabDevice (priv->xdisplay, device_id,
                      meta_backend_x11_get_xwindow (x11),
                      timestamp,
                      None,
                      XIGrabModeAsync, XIGrabModeAsync,
                      False, /* owner_events */
                      &mask);

  return (ret == Success);
}
コード例 #12
0
ファイル: pixeltrack.c プロジェクト: wertarbyte/PhysicalPixel
void init_xinput(Display *d) {
	XIEventMask eventmask;
	unsigned char mask[1] = {0};
	eventmask.deviceid = XIAllDevices;
	eventmask.mask_len = sizeof(mask);
	eventmask.mask = mask;
	XISetMask(mask, XI_Motion);
	XISelectEvents(d, RootWindow(d, DefaultScreen (d)), &eventmask, 1);
}
コード例 #13
0
static int register_for_events(Display *dpy)
{
    XIEventMask evmask;
    unsigned char mask[3] = { 0, 0, 0 };

    XISetMask(mask, XI_HierarchyChanged);
    XISetMask(mask, XI_RawMotion);
    XISetMask(mask, XI_RawButtonPress);
    XISetMask(mask, XI_RawButtonRelease);

    evmask.deviceid = XIAllDevices;
    evmask.mask_len = sizeof (mask);
    evmask.mask = mask;

    /* !!! FIXME: retval? */
    pXISelectEvents(dpy, DefaultRootWindow(dpy), &evmask, 1);
    return 1;
} /* register_for_events */
コード例 #14
0
XLibWindowManagerAdapterPrivate::XLibWindowManagerAdapterPrivate(
                                   XLibWindowManagerAdapter *q)
    :q_ptr(q)
{
    Window root;
    Status status;
    int xi_major = 2;
    int xi_minor = 2;
    m_mods.modifiers = XIAnyModifier;
    m_mods.status = 0;

    m_display = XOpenDisplay(NULL);
    Q_ASSERT_X(m_display, "XLibWindowManagerAdapter",
               "Failed to open connection to X server");

    status = XIQueryVersion(m_display, &xi_major, &xi_minor);
    Q_ASSERT_X(status == Success, "XLibWindowManagerAdapter",
               "Failed to query XInput version");

    if (xi_major < 2 || xi_minor < 2) {
        qFatal("XInput version of the server is too old (%d.%d)" ,
                  xi_major, xi_minor);
    }

    root = XDefaultRootWindow(m_display);
    XSelectInput(m_display, root, PropertyChangeMask);
    XMapWindow(m_display, root);
    XFlush(m_display);

    m_mask.deviceid = XIAllMasterDevices;
    m_mask.mask_len = XIMaskLen(XI_LASTEVENT);
    m_mask.mask = (unsigned char*)calloc(m_mask.mask_len, sizeof(unsigned char));

    XISetMask(m_mask.mask, XI_TouchBegin);
    XISetMask(m_mask.mask, XI_TouchUpdate);
    XISetMask(m_mask.mask, XI_TouchEnd);
    XISetMask(m_mask.mask, XI_TouchOwnership);
    XISetMask(m_mask.mask, XI_HierarchyChanged);

    XIGrabTouchBegin(m_display, XIAllMasterDevices, root, 0,
                     &m_mask, 1, &m_mods);
}
コード例 #15
0
void grab_all_keys(Window window, int is_grab)
{
	if (is_grab)
	{
		// Grab all keys...
		XGrabKey(main_window->display, AnyKey, AnyModifier, window, FALSE, GrabModeAsync, GrabModeAsync);
		// ...without ModKeys.
		grab_modifier_keys(window, FALSE);	
		
		XIEventMask mask;
		mask.deviceid = XIAllMasterDevices;
		mask.mask_len = XIMaskLen(XI_KeyPress)+
						XIMaskLen(XI_KeyRelease);
		mask.mask = (void *)calloc(mask.mask_len, sizeof(char));
		XISetMask(mask.mask, XI_KeyPress);
		XISetMask(mask.mask, XI_KeyRelease);
		XISelectEvents(main_window->display, window, &mask, 1);
		free(mask.mask);

		// Not used, XISelectEvents get actions 
		//grab_action(window); 
		//grab_user_action(window);
	}
	else
	{
		// Ungrab all keys in app window...
		XUngrabKey(main_window->display, AnyKey, AnyModifier, window);

		XIEventMask mask;
		mask.deviceid = XIAllMasterDevices;
		mask.mask_len = XIMaskLen(XI_KeyPress);
		mask.mask = (void *)calloc(mask.mask_len, sizeof(char));
		XISetMask(mask.mask, 0);
		XISelectEvents(main_window->display, window, &mask, 1);
		free(mask.mask);
	}
	
	XSelectInput(main_window->display, window, FOCUS_CHANGE_MASK);
}
コード例 #16
0
ファイル: unix_input.c プロジェクト: Turupawn/DogeWarsow
static void install_grabs_keyboard( void )
{
	int i;
	int num_devices;
	XIDeviceInfo *info;
	XIEventMask mask;

	assert( x11display.dpy && x11display.win );

	if( input_active )
		return;

	XDefineCursor(x11display.dpy, x11display.win, CreateNullCursor(x11display.dpy, x11display.win));

	mask.deviceid = XIAllMasterDevices;
	mask.mask_len = XIMaskLen(XI_LASTEVENT);
	mask.mask = calloc(mask.mask_len, sizeof(char));
	XISetMask(mask.mask, XI_KeyPress);
	XISetMask(mask.mask, XI_KeyRelease);
	XISetMask(mask.mask, XI_ButtonPress);
	XISetMask(mask.mask, XI_ButtonRelease);
	XISelectEvents(x11display.dpy, x11display.win, &mask, 1);

	info = XIQueryDevice(x11display.dpy, XIAllDevices, &num_devices);
	for(i = 0; i < num_devices; i++) {
		int id = info[i].deviceid;
		if(info[i].use == XIMasterKeyboard)
		{
			XIGrabDevice(x11display.dpy, id, x11display.win, CurrentTime, None, GrabModeAsync, GrabModeAsync, False, &mask);
		}
	}
	XIFreeDeviceInfo(info);

	free(mask.mask);

	XSync(x11display.dpy, True);

	input_active = qtrue;
}
コード例 #17
0
ファイル: x.c プロジェクト: Limsik/e17
void
ESelectInput(Win win, unsigned int event_mask)
{
#if USE_XI2

#define EVENTS_TO_XI \
  (/* KeyPressMask | KeyReleaseMask | */ \
   ButtonPressMask | ButtonReleaseMask | PointerMotionMask)

   win->event_mask = event_mask;

   if (Mode.server.extensions & XEXT_XI)
     {
	XIEventMask         em;
	unsigned char       mask[(XI_LASTEVENT + 8) / 8];

	em.deviceid = XIAllMasterDevices;	/* XIAllDevices; */
	em.mask_len = sizeof(mask);
	em.mask = mask;
	memset(mask, 0, sizeof(mask));
#if 0
	if (event_mask & KeyPressMask)
	   XISetMask(mask, XI_KeyPress);
	if (event_mask & KeyReleaseMask)
	   XISetMask(mask, XI_KeyRelease);
#endif
	if (event_mask & ButtonPressMask)
	   XISetMask(mask, XI_ButtonPress);
	if (event_mask & ButtonReleaseMask)
	   XISetMask(mask, XI_ButtonRelease);
	if (event_mask & PointerMotionMask)
	   XISetMask(mask, XI_Motion);
	XISelectEvents(disp, win->xwin, &em, 1);
	event_mask &= ~EVENTS_TO_XI;
     }
#endif

   XSelectInput(disp, win->xwin, event_mask);
}
コード例 #18
0
static void
grab_key_real (guint      keycode,
               GdkWindow *root,
               gboolean   grab,
               XIGrabModifiers *mods,
               int        num_mods)
{
	XIEventMask evmask;
	unsigned char mask[(XI_LASTEVENT + 7)/8];

	memset (mask, 0, sizeof (mask));
	XISetMask (mask, XI_KeyPress);
	XISetMask (mask, XI_KeyRelease);

	evmask.deviceid = XIAllMasterDevices;
	evmask.mask_len = sizeof (mask);
	evmask.mask = mask;

        if (grab) {
                XIGrabKeycode (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
                               XIAllMasterDevices,
                               keycode,
                               GDK_WINDOW_XID (root),
                               GrabModeAsync,
                               GrabModeAsync,
                               False,
                               &evmask,
                               num_mods,
                               mods);
        } else {
                XIUngrabKeycode (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
                                 XIAllMasterDevices,
                                 keycode,
                                 GDK_WINDOW_XID (root),
                                 num_mods,
                                 mods);
        }
}
コード例 #19
0
void grab_button(int is_grab)
{
	if (is_grab)
	{
		XIEventMask mask;
		mask.deviceid = XIAllMasterDevices;
		mask.mask_len = XIMaskLen(XI_RawButtonPress);
		mask.mask = (void *)calloc(mask.mask_len, sizeof(char));
		XISetMask(mask.mask, XI_RawButtonPress);
		XISelectEvents(main_window->display, DefaultRootWindow(main_window->display), &mask, 1);
		free(mask.mask);
	}
	else
	{
		XIEventMask mask;
		mask.deviceid = XIAllMasterDevices;
		mask.mask_len = XIMaskLen(XI_RawButtonPress);
		mask.mask = (void *)calloc(mask.mask_len, sizeof(char));
		XISetMask(mask.mask, 0);
		XISelectEvents(main_window->display, DefaultRootWindow(main_window->display), &mask, 1);
		free(mask.mask);
	}
}
コード例 #20
0
ファイル: ColorButton.cpp プロジェクト: bk138/MalaMinya
void ColorButton::registerEvent(int ev)
{
  XIEventMask mask;
  unsigned char bits[4] = {0};

  mask.mask = bits;
  mask.mask_len = sizeof(bits);
  // which ones?
  mask.deviceid = XIAllMasterDevices;
  // what?
  XISetMask(bits, ev);

  XISelectEvents(x11->dpy, win, &mask, 1);
}
コード例 #21
0
/* Grab the device so input is captured */
void grab(Display* display, int grabDeviceID) {
	XIEventMask device_mask;
	unsigned char mask_data[8] = { 0,0,0,0,0,0,0,0 };
	device_mask.mask_len = sizeof(mask_data);
	device_mask.mask = mask_data;
	XISetMask(device_mask.mask, XI_Motion);
	XISetMask(device_mask.mask, XI_ButtonPress);

/* Experiments with X MT support, not working yet */
//	XISetMask(device_mask.mask, XI_TouchBegin);
//	XISetMask(device_mask.mask, XI_TouchUpdate);
//	XISetMask(device_mask.mask, XI_TouchEnd);
//	XIGrabModifiers modifiers;
//	modifiers.modifiers = XIAnyModifier;
//	int r = XIGrabButton(display, grabDeviceID, XIAnyButton, root, None, GrabModeSync,
//			GrabModeAsync, True, &device_mask, 1, &modifiers);
//	int r = XIGrabTouchBegin(display, grabDeviceID, root, None, &device_mask, 0, modifiers);

	int r = XIGrabDevice(display, grabDeviceID, root, CurrentTime, None, GrabModeAsync, GrabModeAsync, False, &device_mask);

	if(debugMode) printf("Grab Result: %i\n", r);

}
コード例 #22
0
ファイル: xinput.c プロジェクト: NoPublic/GIMX
static Window create_win(Display *dpy)
{
  XIEventMask mask;

  Window win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, 1, 1, 0, 0, 0);

  mask.deviceid = XIAllDevices;
  mask.mask_len = XIMaskLen(XI_RawMotion);
  mask.mask = calloc(mask.mask_len, sizeof(char));

  XISetMask(mask.mask, XI_RawButtonPress);
  XISetMask(mask.mask, XI_RawButtonRelease);
  XISetMask(mask.mask, XI_RawKeyPress);
  XISetMask(mask.mask, XI_RawKeyRelease);
  XISetMask(mask.mask, XI_RawMotion);

  XISelectEvents(dpy, DefaultRootWindow(dpy), &mask, 1);

  free(mask.mask);
  XMapWindow(dpy, win);
  XSync(dpy, True);

  return win;
}
コード例 #23
0
ファイル: meta-backend-x11.c プロジェクト: ueno/mutter
static void
meta_backend_x11_select_stage_events (MetaBackend *backend)
{
  MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
  MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
  Window xwin = meta_backend_x11_get_xwindow (x11);
  unsigned char mask_bits[XIMaskLen (XI_LASTEVENT)] = { 0 };
  XIEventMask mask = { XIAllMasterDevices, sizeof (mask_bits), mask_bits };

  XISetMask (mask.mask, XI_KeyPress);
  XISetMask (mask.mask, XI_KeyRelease);
  XISetMask (mask.mask, XI_ButtonPress);
  XISetMask (mask.mask, XI_ButtonRelease);
  XISetMask (mask.mask, XI_Enter);
  XISetMask (mask.mask, XI_Leave);
  XISetMask (mask.mask, XI_FocusIn);
  XISetMask (mask.mask, XI_FocusOut);
  XISetMask (mask.mask, XI_Motion);
  XIClearMask (mask.mask, XI_TouchBegin);
  XIClearMask (mask.mask, XI_TouchEnd);
  XIClearMask (mask.mask, XI_TouchUpdate);
  XISelectEvents (priv->xdisplay, xwin, &mask, 1);
}
コード例 #24
0
ファイル: test_xi2.c プロジェクト: Ramsey16/xinput
void
test_sync_grab(Display *display, Window win)
{
    int loop = 3;
    int rc;
    XIEventMask mask;

    /* Select for motion events */
    mask.deviceid = XIAllDevices;
    mask.mask_len = 2;
    mask.mask = calloc(2, sizeof(char));
    XISetMask(mask.mask, XI_ButtonPress);

    if ((rc = XIGrabDevice(display, 2,  win, CurrentTime, None, GrabModeSync,
                           GrabModeAsync, False, &mask)) != GrabSuccess)
    {
        fprintf(stderr, "Grab failed with %d\n", rc);
        return;
    }
    free(mask.mask);

    XSync(display, True);
    XIAllowEvents(display, 2, SyncPointer, CurrentTime);
    XFlush(display);

    printf("Holding sync grab for %d button presses.\n", loop);

    while(loop--)
    {
        XIEvent ev;

        XNextEvent(display, (XEvent*)&ev);
        if (ev.type == GenericEvent && ev.extension == xi_opcode )
        {
            XIDeviceEvent *event = (XIDeviceEvent*)&ev;
            print_deviceevent(event);
            XIAllowEvents(display, 2, SyncPointer, CurrentTime);
        }
    }

    XIUngrabDevice(display, 2, CurrentTime);
    printf("Done\n");
}
コード例 #25
0
ファイル: device.c プロジェクト: iglosiggio/xfwm4
static void
xfwm_device_fill_xi2_event_mask (XIEventMask *xievent_mask, gulong core_mask)
{
    gint len = XIMaskLen (XI_LASTEVENT);
    guchar *mask = g_new0 (guchar, len);
    guint i;

    xievent_mask->deviceid = XIAllMasterDevices;
    xievent_mask->mask_len = sizeof (mask);
    xievent_mask->mask = mask;

    for (i = 0; i < G_N_ELEMENTS (core_to_xi2); i++)
    {
        if ((core_mask & core_to_xi2[i].core_mask) == core_to_xi2[i].core_mask)
        {
            XISetMask (mask, core_to_xi2[i].xi2_event);
        }
    }

    #undef xi2_set_mask
}
コード例 #26
0
ファイル: mcursor.c プロジェクト: maruos/mflinger
static void select_events(Display *dpy, Window win)
{
    XIEventMask evmasks[1];
    unsigned char mask1[XIMaskLen(XI_RawMotion)];

    memset(mask1, 0, sizeof(mask1));

    /* Select for motion from the default cursor */
    XISetMask(mask1, XI_RawMotion);

    int pointer_dev_id;

    XIGetClientPointer(dpy, None, &pointer_dev_id);

    evmasks[0].deviceid = pointer_dev_id;
    evmasks[0].mask_len = sizeof(mask1);
    evmasks[0].mask = mask1;

    XISelectEvents(dpy, win, evmasks, 1);
    XFlush(dpy);
}
コード例 #27
0
static int xwinitxi2(struct fb *fb)
{
	int major = 2;
	int minor = 2;
	int xi_opcode, event, error;
	XIEventMask evmask[1];
	unsigned char mask[(XI_LASTEVENT + 7)/8] = {0};

	if(!XQueryExtension(fb->hw->display, "XInputExtension", &xi_opcode, &event, &error)) {
		printf("XInputExtension is not available\n");
		return -1;
	}
	if(XIQueryVersion(fb->hw->display, &major, &minor) == BadRequest) {
		printf("XI2 is not supported, server supports version %d.%d only\n", major, minor);
		return -1;
	} 
	XISetMask(mask, XI_RawMotion);
	evmask[0].deviceid = XIAllMasterDevices;
	evmask[0].mask_len = sizeof(mask);
	evmask[0].mask = mask;
	XISelectEvents(fb->hw->display, DefaultRootWindow(fb->hw->display), evmask, 1);
	XFlush(fb->hw->display);
	return 0;
}
コード例 #28
0
/* Main function, contains kernel driver event loop */
int main(int argc, char **argv) {

	char* devname = 0;
	int doDaemonize = 1;
	int doWait = 0;
	int clickMode = 2;

	int i;
	for (i = 1; i < argc; i++) {
		if (strcmp(argv[i], "--debug") == 0) {
			doDaemonize = 0;
			debugMode = 1;
		} else if (strcmp(argv[i], "--wait") == 0) {
			doWait = 1;
		} else if (strcmp(argv[i], "--click=first") == 0) {
			clickMode = 0;
		} else if (strcmp(argv[i], "--click=second") == 0) {
			clickMode = 1;
		} else if (strcmp(argv[i], "--click=center") == 0) {
			clickMode = 2;
		} else {
			devname = argv[i];
		}

	}

	initGestures(clickMode);



	if (doDaemonize) {
		daemonize();
	}

	if (doWait) {
		/* Wait until all necessary things are loaded */
		sleep(10);
	}


	/* Connect to X server */
	if ((display = XOpenDisplay(NULL)) == NULL) {
		fprintf(stderr, "Couldn't connect to X server\n");
		exit(1);
	}

	/* Read X data */
	screenNum = DefaultScreen(display);

	root = RootWindow(display, screenNum);

//	realDisplayWidth = DisplayWidth(display, screenNum);
//	realDisplayHeight = DisplayHeight(display, screenNum);

	WM_CLASS = XInternAtom(display, "WM_CLASS", 0);

	/* Get notified about new windows */
	XSelectInput(display, root, StructureNotifyMask | SubstructureNotifyMask);

	//TODO load blacklist and profiles from file(s)

	/* Device file name */
	if (devname == 0) {
		devname = "/dev/twofingtouch";
	}

	/* Try to read from device file */
	int fileDesc;
	if ((fileDesc = open(devname, O_RDONLY)) < 0) {
		perror("twofing");
		return 1;
	}

	fd_set fileDescSet;
	FD_ZERO(&fileDescSet);

	int eventQueueDesc = XConnectionNumber(display);	

	while (1) {
		/* Perform initialization at beginning and after module has been re-loaded */
		int rd, i;
		struct input_event ev[64];

		char name[256] = "Unknown";

		/* Read device name */
		ioctl(fileDesc, EVIOCGNAME(sizeof(name)), name);
		printf("Input device name: \"%s\"\n", name);

		//TODO activate again?
		//XSetErrorHandler(invalidWindowHandler);


		int opcode, event, error;
		if (!XQueryExtension(display, "RANDR", &opcode, &event,
				&error)) {
			printf("X RANDR extension not available.\n");
			XCloseDisplay(display);
			exit(1);
		}

		/* Which version of XRandR? We support 1.3 */
		int major = 1, minor = 3;
		if (!XRRQueryVersion(display, &major, &minor)) {
			printf("XRandR version not available.\n");
			XCloseDisplay(display);
			exit(1);
		} else if(!(major>1 || (major == 1 && minor >= 3))) {
			printf("XRandR 1.3 not available. Server supports %d.%d\n", major, minor);
			XCloseDisplay(display);
			exit(1);
		}

		/* XInput Extension available? */
		if (!XQueryExtension(display, "XInputExtension", &opcode, &event,
				&error)) {
			printf("X Input extension not available.\n");
			XCloseDisplay(display);
			exit(1);
		}

		/* Which version of XI2? We support 2.1 */
		major = 2; minor = 1;
		if (XIQueryVersion(display, &major, &minor) == BadRequest) {
			printf("XI 2.1 not available. Server supports %d.%d\n", major, minor);
			XCloseDisplay(display);
			exit(1);
		}

		screenWidth = XDisplayWidth(display, screenNum);
		screenHeight = XDisplayHeight(display, screenNum);

		int n;
		XIDeviceInfo *info = XIQueryDevice(display, XIAllDevices, &n);
		if (!info) {
			printf("No XInput devices available\n");
			exit(1);
		}

		/* Go through input devices and look for that with the same name as the given device */
		int devindex;
		for (devindex = 0; devindex < n; devindex++) {
			if (info[devindex].use == XIMasterPointer || info[devindex].use
					== XIMasterKeyboard)
				continue;

			if (strcmp(info[devindex].name, name) == 0) {
				deviceID = info[devindex].deviceid;

				break;
			}

		}
		if (deviceID == -1) {
			printf("Input device not found in XInput device list.\n");
			exit(1);
		}

		XIFreeDeviceInfo(info);

		if(debugMode) printf("XInput device id is %i.\n", deviceID);

		/* Prepare by reading calibration */
		readCalibrationData(1);

		/* Receive device property change events */
		XIEventMask device_mask2;
		unsigned char mask_data2[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
		device_mask2.deviceid = deviceID;
		device_mask2.mask_len = sizeof(mask_data2);
		device_mask2.mask = mask_data2;
		XISetMask(device_mask2.mask, XI_PropertyEvent);
		XISetMask(device_mask2.mask, XI_ButtonPress);
		//XISetMask(device_mask2.mask, XI_TouchBegin);
		//XISetMask(device_mask2.mask, XI_TouchUpdate);
		//XISetMask(device_mask2.mask, XI_TouchEnd);
		XISelectEvents(display, root, &device_mask2, 1);

		/* Recieve events when screen size changes */
		XRRSelectInput(display, root, RRScreenChangeNotifyMask);


		/* Receive touch events */



		/* Needed for XTest to work correctly */
		XTestGrabControl(display, True);


		/* Needed for some reason to receive events */
/*		XGrabPointer(display, root, False, 0, GrabModeAsync, GrabModeAsync,
				None, None, CurrentTime);
		XUngrabPointer(display, CurrentTime);*/

		grab(display, deviceID);		

		printf("Reading input from device ... (interrupt to exit)\n");

		/* We perform raw event reading here as X touch events don't seem too reliable */
		int currentSlot = 0;

		/* If we use the legacy protocol, we collect all data of one finger into tempFingerInfo and set
		   it to the correct slot once MT_SYNC occurs. */
		FingerInfo tempFingerInfo = { .rawX=0, .rawY=0, .rawZ=0, .id = -1, .slotUsed = 0, .setThisTime = 0 };

		while (1) {


			FD_SET(fileDesc, &fileDescSet);
			FD_SET(eventQueueDesc, &fileDescSet);

			select(MAX(fileDesc, eventQueueDesc) + 1, &fileDescSet, NULL, NULL, getEasingStepTimeVal());
			
			checkEasingStep();

			if(FD_ISSET(fileDesc, &fileDescSet))
			{


				rd = read(fileDesc, ev, sizeof(struct input_event) * 64);
				if (rd < (int) sizeof(struct input_event)) {
					printf("Data stream stopped\n");
					break;
				}
				for (i = 0; i < rd / sizeof(struct input_event); i++) {

					if (ev[i].type == EV_SYN) {
						if (0 == ev[i].code) { // Ev_Sync event end
							/* All finger data received, so process now. */

							if(useLegacyProtocol) {
								/* Clear slots not set this time */
								int i;
								for(i = 0; i < 2; i++) {
									if(fingerInfos[i].setThisTime) {
										fingerInfos[i].setThisTime = 0;
									} else {
										/* Clear slot */
										fingerInfos[i].slotUsed = 0;
									}
								}
								tempFingerInfo.slotUsed = 0;
							}

							processFingers();

						} else if (2 == ev[i].code) { // MT_Sync : Multitouch event end

							if(!useLegacyProtocol) {

								/* This messsage indicates we use legacy protocol, so switch */
								useLegacyProtocol = 1;
								currentSlot = -1;
								tempFingerInfo.slotUsed = 0;
								if(debugMode) printf("Switch to legacy protocol.\n");
							} else {
								if(tempFingerInfo.slotUsed) {
									/* Finger info for one finger collected in tempFingerInfo, so save it to fingerInfos. */

									/* Look for slot to put the data into by looking at the tracking ids */
									int index = -1;
									int i;
									for(i = 0; i < 2; i++) {
										if(fingerInfos[i].slotUsed && fingerInfos[i].id == tempFingerInfo.id) {
											index = i;
											break;
										}
									}
							
									if(index == -1) {
										for(i = 0; i < 2; i++) {
											if(!fingerInfos[i].slotUsed) {
												/* "Empty" slot, so we can add it. */
												index = i;
												fingerInfos[i].id = tempFingerInfo.id;
												fingerInfos[i].slotUsed = 1;
												break;
											}
										}
									}

									if(index != -1) {
										/* Copy temporary data to slot */
										fingerInfos[index].setThisTime = 1;
										fingerInfos[index].rawX = tempFingerInfo.rawX;
										fingerInfos[index].rawY = tempFingerInfo.rawY;
										fingerInfos[index].rawZ = tempFingerInfo.rawZ;
									}
								}
							}
						}

					} else if (ev[i].type == EV_MSC && (ev[i].code == MSC_RAW
							|| ev[i].code == MSC_SCAN)) {
					} else if (ev[i].code == 47) {
						currentSlot = ev[i].value;
						if(currentSlot < 0 || currentSlot > 1) currentSlot = -1;
					} else {
						/* Set finger info values for current finger */
						if (ev[i].code == 57) {
							/* ABS_MT_TRACKING_ID */
							if(currentSlot != -1) {
								if(ev[i].value == -1)
								{
									fingerInfos[currentSlot].slotUsed = 0;
								}
								else
								{
									fingerInfos[currentSlot].id = ev[i].value;
									fingerInfos[currentSlot].slotUsed = 1;
								}
							} else if(useLegacyProtocol) {
								tempFingerInfo.id = ev[i].value;
								tempFingerInfo.slotUsed = 1;
							}
						};
						if (ev[i].code == 53) {
							if(currentSlot != -1) {
								fingerInfos[currentSlot].rawX = ev[i].value;
							} else if(useLegacyProtocol) {
								tempFingerInfo.rawX = ev[i].value;
							}
						};
						if (ev[i].code == 54) {
							if(currentSlot != -1) {
								fingerInfos[currentSlot].rawY = ev[i].value;
							} else if(useLegacyProtocol) {
								tempFingerInfo.rawY = ev[i].value;
							}
						};
						if (ev[i].code == 58) {
							if(currentSlot != -1) {
								fingerInfos[currentSlot].rawZ = ev[i].value;
							} else if(useLegacyProtocol) {
								tempFingerInfo.rawZ = ev[i].value;
							}
						};
					}
				}

			}

			if(FD_ISSET(eventQueueDesc, &fileDescSet)) {
				handleXEvent();
			}
		}

		/* Stream stopped, probably because module has been unloaded */
		close(fileDesc);

		/* Clean up */
		releaseButton();
		ungrab(display, deviceID);

		/* Wait until device file is there again */
		while ((fileDesc = open(devname, O_RDONLY)) < 0) {
			sleep(1);
		}

	}

}
コード例 #29
0
ファイル: x11_window.c プロジェクト: NathanSweet/glfw
// Create the X11 window (and its colormap)
//
static GLboolean createWindow(_GLFWwindow* window,
                              const _GLFWwndconfig* wndconfig)
{
    unsigned long wamask;
    XSetWindowAttributes wa;
    XVisualInfo* visual = _GLFW_X11_CONTEXT_VISUAL;

    // Every window needs a colormap
    // Create one based on the visual used by the current context
    // TODO: Decouple this from context creation

    window->x11.colormap = XCreateColormap(_glfw.x11.display,
                                           _glfw.x11.root,
                                           visual->visual,
                                           AllocNone);

    // Create the actual window
    {
        wamask = CWBorderPixel | CWColormap | CWEventMask;

        wa.colormap = window->x11.colormap;
        wa.border_pixel = 0;
        wa.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask |
                        PointerMotionMask | ButtonPressMask | ButtonReleaseMask |
                        ExposureMask | FocusChangeMask | VisibilityChangeMask |
                        EnterWindowMask | LeaveWindowMask | PropertyChangeMask;

        if (wndconfig->monitor == NULL)
        {
            // HACK: This is a workaround for windows without a background pixel
            // not getting any decorations on certain older versions of Compiz
            // running on Intel hardware
            wa.background_pixel = BlackPixel(_glfw.x11.display,
                                             _glfw.x11.screen);
            wamask |= CWBackPixel;
        }

        window->x11.handle = XCreateWindow(_glfw.x11.display,
                                           _glfw.x11.root,
                                           0, 0,
                                           wndconfig->width, wndconfig->height,
                                           0,              // Border width
                                           visual->depth,  // Color depth
                                           InputOutput,
                                           visual->visual,
                                           wamask,
                                           &wa);

        if (!window->x11.handle)
        {
            // TODO: Handle all the various error codes here and translate them
            // to GLFW errors

            _glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to create window");
            return GL_FALSE;
        }

        if (wndconfig->undecorated) {
            Atom motif_hints_atom = XInternAtom(_glfw.x11.display, "_MOTIF_WM_HINTS", False);
            MotifWmHints motif_hints;
            motif_hints.flags = MWM_HINTS_DECORATIONS;
            motif_hints.decorations = 0;
            XChangeProperty(_glfw.x11.display, window->x11.handle,
                motif_hints_atom, motif_hints_atom, 32,
                PropModeReplace,
                (unsigned char *)&motif_hints, sizeof(MotifWmHints) / sizeof(long));
        }
    }

    if (window->monitor && !_glfw.x11.hasEWMH)
    {
        // This is the butcher's way of removing window decorations
        // Setting the override-redirect attribute on a window makes the window
        // manager ignore the window completely (ICCCM, section 4)
        // The good thing is that this makes undecorated fullscreen windows
        // easy to do; the bad thing is that we have to do everything manually
        // and some things (like iconify/restore) won't work at all, as those
        // are tasks usually performed by the window manager

        XSetWindowAttributes attributes;
        attributes.override_redirect = True;
        XChangeWindowAttributes(_glfw.x11.display,
                                window->x11.handle,
                                CWOverrideRedirect,
                                &attributes);

        window->x11.overrideRedirect = GL_TRUE;
    }

    // Declare the WM protocols supported by GLFW
    {
        int count = 0;
        Atom protocols[2];

        // The WM_DELETE_WINDOW ICCCM protocol
        // Basic window close notification protocol
        if (_glfw.x11.WM_DELETE_WINDOW != None)
            protocols[count++] = _glfw.x11.WM_DELETE_WINDOW;

        // The _NET_WM_PING EWMH protocol
        // Tells the WM to ping the GLFW window and flag the application as
        // unresponsive if the WM doesn't get a reply within a few seconds
        if (_glfw.x11.NET_WM_PING != None)
            protocols[count++] = _glfw.x11.NET_WM_PING;

        if (count > 0)
        {
            XSetWMProtocols(_glfw.x11.display, window->x11.handle,
                            protocols, count);
        }
    }

    // Set ICCCM WM_HINTS property
    {
        XWMHints* hints = XAllocWMHints();
        if (!hints)
        {
            _glfwInputError(GLFW_OUT_OF_MEMORY,
                            "X11: Failed to allocate WM hints");
            return GL_FALSE;
        }

        hints->flags = StateHint;
        hints->initial_state = NormalState;

        XSetWMHints(_glfw.x11.display, window->x11.handle, hints);
        XFree(hints);
    }

    // Set ICCCM WM_NORMAL_HINTS property (even if no parts are set)
    {
        XSizeHints* hints = XAllocSizeHints();
        hints->flags = 0;

        if (wndconfig->monitor)
        {
            hints->flags |= PPosition;
            _glfwPlatformGetMonitorPos(wndconfig->monitor, &hints->x, &hints->y);
        }

        if (!wndconfig->resizable)
        {
            hints->flags |= (PMinSize | PMaxSize);
            hints->min_width  = hints->max_width  = wndconfig->width;
            hints->min_height = hints->max_height = wndconfig->height;
        }

        XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints);
        XFree(hints);
    }

    if (_glfw.x11.xi2.available)
    {
        // Select for XInput2 events

        XIEventMask eventmask;
        unsigned char mask[] = { 0 };

        eventmask.deviceid = 2;
        eventmask.mask_len = sizeof(mask);
        eventmask.mask = mask;
        XISetMask(mask, XI_Motion);

        XISelectEvents(_glfw.x11.display, window->x11.handle, &eventmask, 1);
    }

    _glfwPlatformSetWindowTitle(window, wndconfig->title);

    XRRSelectInput(_glfw.x11.display, window->x11.handle,
                   RRScreenChangeNotifyMask);

    return GL_TRUE;
}
コード例 #30
0
ファイル: XInputMTInputDevice.cpp プロジェクト: lynxis/libavg
void XInputMTInputDevice::start()
{
    Status status;
    SDLDisplayEngine * pEngine = Player::get()->getDisplayEngine();
    glm::vec2 size(pEngine->getSize());
    glm::vec2 windowSize(pEngine->getWindowSize());
    m_DisplayScale.x = size.x/windowSize.x;
    m_DisplayScale.y = size.y/windowSize.y;

    SDL_SysWMinfo info;
    SDL_VERSION(&info.version);
    int rc = SDL_GetWMInfo(&info);
    AVG_ASSERT(rc != -1);
    s_pDisplay = info.info.x11.display;
    m_SDLLockFunc = info.info.x11.lock_func;
    m_SDLUnlockFunc = info.info.x11.unlock_func;

    m_SDLLockFunc();
    // XInput Extension available?
    int event, error;
    bool bOk = XQueryExtension(s_pDisplay, "XInputExtension", &m_XIOpcode, 
            &event, &error);
    if (!bOk) {
        throw Exception(AVG_ERR_MT_INIT, 
                "XInput multitouch event source: X Input extension not available.");
    }

    // Which version of XI2? 
    int major;
    int minor;
    status = XIQueryVersion(s_pDisplay, &major, &minor);
    if (status == BadRequest) {
        throw Exception(AVG_ERR_MT_INIT, 
                "XInput 2.1 multitouch event source: Server does not support XI2");
    }
    if (major < 2 || minor < 1) {
        throw Exception(AVG_ERR_MT_INIT, 
                "XInput multitouch event source: Supported version is "
                +toString(major)+"."+toString(minor)+". At least 2.1 is needed.");
    }
    findMTDevice();

    // SDL grabs the pointer in full screen mode. This breaks touchscreen usage.
    // Can't use SDL_WM_GrabInput(SDL_GRAB_OFF) because it doesn't work in full
    // screen mode. Get the display connection and do it manually.
    XUngrabPointer(info.info.x11.display, CurrentTime);

    XIEventMask mask;
    mask.deviceid = m_DeviceID;
    mask.mask_len = XIMaskLen(XI_LASTEVENT);
    mask.mask = (unsigned char *)calloc(mask.mask_len, sizeof(char));
    memset(mask.mask, 0, mask.mask_len);
    XISetMask(mask.mask, XI_TouchBegin);
    XISetMask(mask.mask, XI_TouchUpdate);
    XISetMask(mask.mask, XI_TouchEnd);

    status = XISelectEvents(s_pDisplay, info.info.x11.window, &mask, 1);
    AVG_ASSERT(status == Success);

    m_SDLUnlockFunc();

    SDL_SetEventFilter(XInputMTInputDevice::filterEvent);
  
    
    XIDetachSlaveInfo detInfo;
    detInfo.type = XIDetachSlave;
    detInfo.deviceid = m_DeviceID;
    XIChangeHierarchy(s_pDisplay, (XIAnyHierarchyChangeInfo *)&detInfo, 1);

    pEngine->setXIMTInputDevice(this);
    MultitouchInputDevice::start();
    AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
            "XInput Multitouch event source created.");
}