Add XInput2 input devices implementation

This commit is contained in:
Carlos Garnacho 2011-06-12 19:09:16 +02:00
parent 722420df3a
commit 884e13474b
4 changed files with 402 additions and 0 deletions

View File

@ -263,6 +263,8 @@ if test x$have_xinput2 = xyes; then
AC_DEFINE(HAVE_XINPUT2, , [Building with XInput2 support])
fi
AM_CONDITIONAL(HAVE_XINPUT2, test "$have_xinput2" = "yes")
PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES)
AC_PATH_XTRA

View File

@ -168,6 +168,12 @@ libmutter_la_SOURCES = \
ui/preview-widget.c \
$(mutter_built_sources)
if HAVE_XINPUT2
libmutter_la_SOURCES += \
core/devices-xi2.c \
core/devices-xi2.h
endif
libmutter_la_LDFLAGS = -no-undefined
libmutter_la_LIBADD = $(MUTTER_LIBS)

307
src/core/devices-xi2.c Normal file
View File

@ -0,0 +1,307 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* XInput2 devices implementation */
/*
* Copyright (C) 2011 Carlos Garnacho
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include <config.h>
#include "devices-xi2.h"
#include "display-private.h"
#include "screen-private.h"
#include <X11/extensions/XInput2.h>
/* Common functions */
static void
meta_device_xi2_common_allow_events (MetaDevice *device,
int mode,
Time time)
{
MetaDisplay *display;
gint device_id;
display = meta_device_get_display (device);
device_id = meta_device_get_id (device);
switch (mode)
{
case AsyncPointer:
case AsyncKeyboard:
mode = XIAsyncDevice;
break;
case SyncPointer:
case SyncKeyboard:
mode = XISyncDevice;
break;
case ReplayPointer:
case ReplayKeyboard:
mode = XIReplayDevice;
break;
case AsyncBoth:
mode = XIAsyncPair;
break;
case SyncBoth:
mode = XISyncPair;
break;
}
XIAllowEvents (display->xdisplay, device_id, mode, time);
}
static guchar *
translate_event_mask (guint evmask,
gint *len)
{
guchar *mask;
*len = XIMaskLen (XI_LASTEVENT);
mask = g_new0 (guchar, *len);
if (evmask & KeyPressMask)
XISetMask (mask, XI_KeyPress);
if (evmask & KeyReleaseMask)
XISetMask (mask, XI_KeyRelease);
if (evmask & ButtonPressMask)
XISetMask (mask, XI_ButtonPress);
if (evmask & ButtonReleaseMask)
XISetMask (mask, XI_ButtonRelease);
if (evmask & EnterWindowMask)
XISetMask (mask, XI_Enter);
if (evmask & LeaveWindowMask)
XISetMask (mask, XI_Leave);
/* No motion hints in XI2 at the moment... */
if (evmask & PointerMotionMask ||
evmask & PointerMotionHintMask)
XISetMask (mask, XI_Motion);
if (evmask & FocusChangeMask)
{
XISetMask (mask, XI_FocusIn);
XISetMask (mask, XI_FocusOut);
}
return mask;
}
static gboolean
meta_device_xi2_common_grab (MetaDevice *device,
Window xwindow,
guint evmask,
MetaCursor cursor,
gboolean owner_events,
gboolean sync,
Time time)
{
MetaDisplay *display;
XIEventMask mask;
gint device_id, retval;
Cursor xcursor;
display = meta_device_get_display (device);
device_id = meta_device_get_id (device);
xcursor = meta_display_create_x_cursor (display, cursor);
mask.deviceid = device_id;
mask.mask = translate_event_mask (evmask, &mask.mask_len);
retval = XIGrabDevice (display->xdisplay,
device_id, xwindow,
time, xcursor,
(sync) ? GrabModeSync : GrabModeAsync,
(sync) ? GrabModeSync : GrabModeAsync,
owner_events, &mask);
if (xcursor != None)
XFreeCursor (display->xdisplay, xcursor);
return (retval == Success);
}
static void
meta_device_xi2_common_ungrab (MetaDevice *device,
Time time)
{
MetaDisplay *display;
gint device_id;
display = meta_device_get_display (device);
device_id = meta_device_get_id (device);
XIUngrabDevice (display->xdisplay, device_id, time);
}
/* Pointer */
G_DEFINE_TYPE (MetaDevicePointerXI2,
meta_device_pointer_xi2,
META_TYPE_DEVICE_POINTER)
static void
meta_device_pointer_xi2_warp (MetaDevicePointer *pointer,
MetaScreen *screen,
gint x,
gint y)
{
MetaDisplay *display;
int device_id;
display = meta_device_get_display (META_DEVICE (pointer));
device_id = meta_device_get_id (META_DEVICE (pointer));
XIWarpPointer (display->xdisplay,
device_id,
None, screen->xroot,
0, 0, 0, 0, x, y);
}
static void
meta_device_pointer_xi2_set_window_cursor (MetaDevicePointer *pointer,
Window xwindow,
MetaCursor cursor)
{
MetaDisplay *display;
Cursor xcursor;
int device_id;
display = meta_device_get_display (META_DEVICE (pointer));
device_id = meta_device_get_id (META_DEVICE (pointer));
xcursor = meta_display_create_x_cursor (display, cursor);
if (xcursor != None)
{
XIDefineCursor (display->xdisplay, device_id, xwindow, xcursor);
XFreeCursor (display->xdisplay, xcursor);
}
else
XIUndefineCursor (display->xdisplay, device_id, xwindow);
}
static void
meta_device_pointer_xi2_query_position (MetaDevicePointer *pointer,
Window xwindow,
Window *root_ret,
Window *child_ret,
gint *root_x_ret,
gint *root_y_ret,
gint *x_ret,
gint *y_ret,
guint *mask_ret)
{
MetaDisplay *display;
XIModifierState mods;
XIGroupState group_unused;
XIButtonState buttons;
gdouble root_x, root_y, x, y;
int device_id;
display = meta_device_get_display (META_DEVICE (pointer));
device_id = meta_device_get_id (META_DEVICE (pointer));
XIQueryPointer (display->xdisplay,
device_id, xwindow,
root_ret, child_ret,
&root_x, &root_y, &x, &y,
&buttons, &mods,
&group_unused);
if (mask_ret)
{
*mask_ret = mods.effective;
if (XIMaskIsSet (buttons.mask, 1))
*mask_ret |= Button1Mask;
else if (XIMaskIsSet (buttons.mask, 2))
*mask_ret |= Button2Mask;
else if (XIMaskIsSet (buttons.mask, 3))
*mask_ret |= Button3Mask;
}
if (root_x_ret)
*root_x_ret = (int) root_x;
if (root_y_ret)
*root_y_ret = (int) root_y;
if (x_ret)
*x_ret = (int) x;
if (y_ret)
*y_ret = (int) y;
}
static void
meta_device_pointer_xi2_class_init (MetaDevicePointerXI2Class *klass)
{
MetaDevicePointerClass *pointer_class = META_DEVICE_POINTER_CLASS (klass);
MetaDeviceClass *device_class = META_DEVICE_CLASS (klass);
device_class->allow_events = meta_device_xi2_common_allow_events;
device_class->grab = meta_device_xi2_common_grab;
device_class->ungrab = meta_device_xi2_common_ungrab;
pointer_class->warp = meta_device_pointer_xi2_warp;
pointer_class->set_window_cursor = meta_device_pointer_xi2_set_window_cursor;
pointer_class->query_position = meta_device_pointer_xi2_query_position;
}
static void
meta_device_pointer_xi2_init (MetaDevicePointerXI2 *pointer)
{
}
MetaDevice *
meta_device_pointer_xi2_new (MetaDisplay *display,
gint device_id)
{
return g_object_new (META_TYPE_DEVICE_POINTER_XI2,
"device-id", device_id,
"display", display,
NULL);
}
/* Keyboard */
G_DEFINE_TYPE (MetaDeviceKeyboardXI2,
meta_device_keyboard_xi2,
META_TYPE_DEVICE_KEYBOARD)
static void
meta_device_keyboard_xi2_class_init (MetaDeviceKeyboardXI2Class *klass)
{
MetaDeviceClass *device_class = META_DEVICE_CLASS (klass);
device_class->allow_events = meta_device_xi2_common_allow_events;
device_class->grab = meta_device_xi2_common_grab;
device_class->ungrab = meta_device_xi2_common_ungrab;
}
static void
meta_device_keyboard_xi2_init (MetaDeviceKeyboardXI2 *keyboard)
{
}
MetaDevice *
meta_device_keyboard_xi2_new (MetaDisplay *display,
gint device_id)
{
return g_object_new (META_TYPE_DEVICE_KEYBOARD_XI2,
"device-id", device_id,
"display", display,
NULL);
}

87
src/core/devices-xi2.h Normal file
View File

@ -0,0 +1,87 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/**
* \file devices-xi2.h XInput2 input devices implementation
*
* Input devices.
* This file contains the XInput2 implementation of input devices.
*/
/*
* Copyright (C) 2011 Carlos Garnacho
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef META_DEVICES_XI2_H
#define META_DEVICES_XI2_H
#include "device-pointer.h"
#include "device-keyboard.h"
/* Pointer */
#define META_TYPE_DEVICE_POINTER_XI2 (meta_device_pointer_xi2_get_type ())
#define META_DEVICE_POINTER_XI2(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE_POINTER_XI2, MetaDevicePointerXI2))
#define META_DEVICE_POINTER_XI2_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_DEVICE_POINTER_XI2, MetaDevicePointerXI2Class))
#define META_IS_DEVICE_POINTER_XI2(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_DEVICE_POINTER_XI2))
#define META_IS_DEVICE_POINTER_XI2_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_DEVICE_POINTER_XI2))
#define META_DEVICE_POINTER_XI2_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_DEVICE_POINTER_XI2, MetaDevicePointerXI2Class))
typedef struct _MetaDevicePointerXI2 MetaDevicePointerXI2;
typedef struct _MetaDevicePointerXI2Class MetaDevicePointerXI2Class;
struct _MetaDevicePointerXI2
{
MetaDevicePointer parent_instance;
};
struct _MetaDevicePointerXI2Class
{
MetaDevicePointerClass parent_class;
};
GType meta_device_pointer_xi2_get_type (void) G_GNUC_CONST;
MetaDevice *meta_device_pointer_xi2_new (MetaDisplay *display,
gint device_id);
/* Keyboard */
#define META_TYPE_DEVICE_KEYBOARD_XI2 (meta_device_keyboard_xi2_get_type ())
#define META_DEVICE_KEYBOARD_XI2(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_DEVICE_KEYBOARD_XI2, MetaDeviceKeyboardXI2))
#define META_DEVICE_KEYBOARD_XI2_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_DEVICE_KEYBOARD_XI2, MetaDeviceKeyboardXI2Class))
#define META_IS_DEVICE_KEYBOARD_XI2(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_DEVICE_KEYBOARD_XI2))
#define META_IS_DEVICE_KEYBOARD_XI2_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_DEVICE_KEYBOARD_XI2))
#define META_DEVICE_KEYBOARD_XI2_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_DEVICE_KEYBOARD_XI2, MetaDeviceKeyboardXI2Class))
typedef struct _MetaDeviceKeyboardXI2 MetaDeviceKeyboardXI2;
typedef struct _MetaDeviceKeyboardXI2Class MetaDeviceKeyboardXI2Class;
struct _MetaDeviceKeyboardXI2
{
MetaDeviceKeyboard parent_instance;
};
struct _MetaDeviceKeyboardXI2Class
{
MetaDeviceKeyboardClass parent_class;
};
GType meta_device_keyboard_xi2_get_type (void) G_GNUC_CONST;
MetaDevice *meta_device_keyboard_xi2_new (MetaDisplay *display,
gint device_id);
#endif /* META_DEVICES_XI2_H */