mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 09:30:45 -05:00
Add XInput2 input devices implementation
This commit is contained in:
parent
e1679cb35b
commit
22a44bf007
@ -250,6 +250,8 @@ if test x$have_xinput2 = xyes; then
|
|||||||
AC_DEFINE(HAVE_XINPUT2, , [Building with XInput2 support])
|
AC_DEFINE(HAVE_XINPUT2, , [Building with XInput2 support])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AM_CONDITIONAL(HAVE_XINPUT2, test "$have_xinput2" = "yes")
|
||||||
|
|
||||||
PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES)
|
PKG_CHECK_MODULES(MUTTER, $MUTTER_PC_MODULES)
|
||||||
|
|
||||||
AC_PATH_XTRA
|
AC_PATH_XTRA
|
||||||
|
@ -171,6 +171,12 @@ libmutter_la_SOURCES = \
|
|||||||
ui/preview-widget.c \
|
ui/preview-widget.c \
|
||||||
$(mutter_built_sources)
|
$(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_LDFLAGS = -no-undefined
|
||||||
libmutter_la_LIBADD = $(MUTTER_LIBS)
|
libmutter_la_LIBADD = $(MUTTER_LIBS)
|
||||||
|
|
||||||
|
307
src/core/devices-xi2.c
Normal file
307
src/core/devices-xi2.c
Normal 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
87
src/core/devices-xi2.h
Normal 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 */
|
Loading…
Reference in New Issue
Block a user