[mutter/wip/xinput2r: 6/68] core: Add helper code to handle input events
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/xinput2r: 6/68] core: Add helper code to handle input events
- Date: Wed, 24 Oct 2012 16:09:50 +0000 (UTC)
commit facfa526234237955d2e5c481165af1e7113c10c
Author: Carlos Garnacho <carlosg gnome org>
Date: Wed Jun 8 10:18:35 2011 +0200
core: Add helper code to handle input events
These will be used with every input event out there so they're
dealt with uniformly.
src/Makefile.am | 2 +
src/core/input-events.c | 497 +++++++++++++++++++++++++++++++++++++++++++++++
src/core/input-events.h | 64 ++++++
3 files changed, 563 insertions(+), 0 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index d5b398c..3a73afd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -97,6 +97,8 @@ libmutter_la_SOURCES = \
meta/group.h \
core/iconcache.c \
core/iconcache.h \
+ core/input-events.c \
+ core/input-events.h \
core/keybindings.c \
core/keybindings-private.h \
core/main.c \
diff --git a/src/core/input-events.c b/src/core/input-events.c
new file mode 100644
index 0000000..fbd9d2a
--- /dev/null
+++ b/src/core/input-events.c
@@ -0,0 +1,497 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/* XEvent utility methods */
+
+/*
+ * 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 "input-events.h"
+#include <X11/Xlib.h>
+
+#ifdef HAVE_XINPUT2
+#include <X11/extensions/XInput2.h>
+#endif
+
+/* Quite a hack: normalizes XI2 events to their
+ * core event equivalent, so most code is shared
+ * for both implementations, code handling input
+ * events should use the helper functions so
+ * the actual event is treated correctly.
+ */
+gboolean
+meta_input_event_get_type (MetaDisplay *display,
+ XEvent *ev,
+ guint *ev_type)
+{
+ guint type = 0; /* Silence gcc */
+ gboolean retval = TRUE;
+
+#ifdef HAVE_XINPUT2
+ if (display->have_xinput2 &&
+ ev->type == GenericEvent &&
+ ev->xcookie.extension == display->xinput2_opcode)
+ {
+ XIEvent *xev;
+
+ /* NB: GDK event filters already have generic events
+ * allocated, so no need to do XGetEventData() on our own
+ */
+ xev = (XIEvent *) ev->xcookie.data;
+
+ switch (xev->evtype)
+ {
+ case XI_Motion:
+ type = MotionNotify;
+ break;
+ case XI_ButtonPress:
+ type = ButtonPress;
+ break;
+ case XI_ButtonRelease:
+ type = ButtonRelease;
+ break;
+ case XI_KeyPress:
+ type = KeyPress;
+ break;
+ case XI_KeyRelease:
+ type = KeyRelease;
+ break;
+ case XI_FocusIn:
+ type = FocusIn;
+ break;
+ case XI_FocusOut:
+ type = FocusOut;
+ break;
+ case XI_Enter:
+ type = EnterNotify;
+ break;
+ case XI_Leave:
+ type = LeaveNotify;
+ break;
+ default:
+ retval = FALSE;
+ break;
+ }
+ }
+ else
+#endif /* HAVE_XINPUT2 */
+ {
+ switch (ev->type)
+ {
+ case MotionNotify:
+ case ButtonPress:
+ case ButtonRelease:
+ case KeyPress:
+ case KeyRelease:
+ case FocusIn:
+ case FocusOut:
+ case EnterNotify:
+ case LeaveNotify:
+ type = ev->type;
+ break;
+ default:
+ retval = FALSE;
+ break;
+ }
+ }
+
+ if (retval)
+ {
+ if (ev_type)
+ *ev_type = type;
+
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+
+Window
+meta_input_event_get_window (MetaDisplay *display,
+ XEvent *ev)
+{
+#ifdef HAVE_XINPUT2
+ if (ev->type == GenericEvent &&
+ ev->xcookie.extension == display->xinput2_opcode)
+ {
+ XIEvent *xev;
+
+ g_assert (display->have_xinput2 == TRUE);
+
+ /* GDK event filters already have generic events allocated */
+ xev = (XIEvent *) ev->xcookie.data;
+
+ switch (xev->evtype)
+ {
+ case XI_Motion:
+ case XI_ButtonPress:
+ case XI_ButtonRelease:
+ case XI_KeyPress:
+ case XI_KeyRelease:
+ return ((XIDeviceEvent *) xev)->event;
+ case XI_FocusIn:
+ case XI_FocusOut:
+ case XI_Enter:
+ case XI_Leave:
+ return ((XIEnterEvent *) xev)->event;
+ default:
+ return None;
+ }
+ }
+ else
+#endif /* HAVE_XINPUT2 */
+ return ev->xany.window;
+}
+
+Window
+meta_input_event_get_root_window (MetaDisplay *display,
+ XEvent *ev)
+{
+#ifdef HAVE_XINPUT2
+ if (ev->type == GenericEvent &&
+ ev->xcookie.extension == display->xinput2_opcode)
+ {
+ XIEvent *xev;
+
+ g_assert (display->have_xinput2 == TRUE);
+
+ xev = (XIEvent *) ev->xcookie.data;
+
+ switch (xev->evtype)
+ {
+ case XI_Motion:
+ case XI_ButtonPress:
+ case XI_ButtonRelease:
+ case XI_KeyPress:
+ case XI_KeyRelease:
+ return ((XIDeviceEvent *) xev)->root;
+ case XI_FocusIn:
+ case XI_FocusOut:
+ case XI_Enter:
+ case XI_Leave:
+ return ((XIEnterEvent *) xev)->root;
+ default:
+ break;
+ }
+ }
+ else
+#endif /* HAVE_XINPUT2 */
+ {
+ switch (ev->type)
+ {
+ case KeyPress:
+ case KeyRelease:
+ return ev->xkey.root;
+ case ButtonPress:
+ case ButtonRelease:
+ return ev->xbutton.root;
+ case EnterNotify:
+ case LeaveNotify:
+ return ev->xcrossing.root;
+ case MotionNotify:
+ return ev->xbutton.root;
+ default:
+ break;
+ }
+ }
+
+ return None;
+}
+
+Time
+meta_input_event_get_time (MetaDisplay *display,
+ XEvent *ev)
+{
+#ifdef HAVE_XINPUT2
+ if (ev->type == GenericEvent &&
+ ev->xcookie.extension == display->xinput2_opcode)
+ {
+ XIEvent *xev;
+
+ g_assert (display->have_xinput2 == TRUE);
+
+ xev = (XIEvent *) ev->xcookie.data;
+
+ switch (xev->evtype)
+ {
+ case XI_Motion:
+ case XI_ButtonPress:
+ case XI_ButtonRelease:
+ case XI_KeyPress:
+ case XI_KeyRelease:
+ return ((XIDeviceEvent *) xev)->time;
+ case XI_FocusIn:
+ case XI_FocusOut:
+ case XI_Enter:
+ case XI_Leave:
+ return ((XIEnterEvent *) xev)->time;
+ default:
+ break;
+ }
+ }
+ else
+#endif /* HAVE_XINPUT2 */
+ {
+ switch (ev->type)
+ {
+ case KeyPress:
+ case KeyRelease:
+ return ev->xkey.time;
+ case ButtonPress:
+ case ButtonRelease:
+ return ev->xbutton.time;
+ case EnterNotify:
+ case LeaveNotify:
+ return ev->xcrossing.time;
+ case MotionNotify:
+ return ev->xmotion.time;
+ default:
+ break;
+ }
+ }
+
+ return CurrentTime;
+}
+
+gboolean
+meta_input_event_get_coordinates (MetaDisplay *display,
+ XEvent *ev,
+ gdouble *x_ret,
+ gdouble *y_ret,
+ gdouble *x_root_ret,
+ gdouble *y_root_ret)
+{
+ gdouble x, y, x_root, y_root;
+ gboolean retval = TRUE;
+
+#ifdef HAVE_XINPUT2
+ if (ev->type == GenericEvent &&
+ ev->xcookie.extension == display->xinput2_opcode)
+ {
+ XIEvent *xev;
+
+ g_assert (display->have_xinput2 == TRUE);
+
+ xev = (XIEvent *) ev->xcookie.data;
+
+ switch (xev->evtype)
+ {
+ case XI_Motion:
+ case XI_ButtonPress:
+ case XI_ButtonRelease:
+ case XI_KeyPress:
+ case XI_KeyRelease:
+ {
+ XIDeviceEvent *event = (XIDeviceEvent *) xev;
+
+ x = event->event_x;
+ y = event->event_y;
+ x_root = event->root_x;
+ y_root = event->root_y;
+ }
+
+ break;
+ case XI_FocusIn:
+ case XI_FocusOut:
+ case XI_Enter:
+ case XI_Leave:
+ {
+ XIEnterEvent *event = (XIEnterEvent *) xev;
+
+ x = event->event_x;
+ y = event->event_y;
+ x_root = event->root_x;
+ y_root = event->root_y;
+ }
+
+ break;
+ default:
+ retval = FALSE;
+ break;
+ }
+ }
+ else
+#endif /* HAVE_XINPUT2 */
+ {
+ switch (ev->type)
+ {
+ case KeyPress:
+ case KeyRelease:
+ x = ev->xkey.x;
+ y = ev->xkey.y;
+ x_root = ev->xkey.x_root;
+ y_root = ev->xkey.y_root;
+ break;
+ case ButtonPress:
+ case ButtonRelease:
+ x = ev->xbutton.x;
+ y = ev->xbutton.y;
+ x_root = ev->xbutton.x_root;
+ y_root = ev->xbutton.y_root;
+ break;
+ case EnterNotify:
+ case LeaveNotify:
+ x = ev->xcrossing.x;
+ y = ev->xcrossing.y;
+ x_root = ev->xcrossing.x_root;
+ y_root = ev->xcrossing.y_root;
+ break;
+ case MotionNotify:
+ x = ev->xmotion.x;
+ y = ev->xmotion.y;
+ x_root = ev->xmotion.x_root;
+ y_root = ev->xmotion.y_root;
+ break;
+ default:
+ retval = FALSE;
+ break;
+ }
+ }
+
+ if (retval)
+ {
+ if (x_ret)
+ *x_ret = x;
+
+ if (y_ret)
+ *y_ret = y;
+
+ if (x_root_ret)
+ *x_root_ret = x_root;
+
+ if (y_root_ret)
+ *y_root_ret = y_root;
+ }
+
+ return retval;
+}
+
+gboolean
+meta_input_event_get_state (MetaDisplay *display,
+ XEvent *ev,
+ guint *state)
+{
+ gboolean retval = TRUE;
+ guint s;
+
+#ifdef HAVE_XINPUT2
+ if (ev->type == GenericEvent &&
+ ev->xcookie.extension == display->xinput2_opcode)
+ {
+ XIEvent *xev;
+
+ g_assert (display->have_xinput2 == TRUE);
+
+ xev = (XIEvent *) ev->xcookie.data;
+
+ switch (xev->evtype)
+ {
+ case XI_Motion:
+ case XI_ButtonPress:
+ case XI_ButtonRelease:
+ case XI_KeyPress:
+ case XI_KeyRelease:
+ s = ((XIDeviceEvent *) xev)->mods.effective;
+ break;
+ case XI_FocusIn:
+ case XI_FocusOut:
+ case XI_Enter:
+ case XI_Leave:
+ s = ((XIDeviceEvent *) xev)->mods.effective;
+ break;
+ default:
+ retval = FALSE;
+ break;
+ }
+ }
+ else
+#endif /* HAVE_XINPUT2 */
+ {
+ switch (ev->type)
+ {
+ case KeyPress:
+ case KeyRelease:
+ s = ev->xkey.state;
+ break;
+ case ButtonPress:
+ case ButtonRelease:
+ s = ev->xbutton.state;
+ break;
+ case EnterNotify:
+ case LeaveNotify:
+ s = ev->xcrossing.state;
+ break;
+ case MotionNotify:
+ s = ev->xmotion.state;
+ break;
+ default:
+ retval = FALSE;
+ break;
+ }
+ }
+
+ if (retval && state)
+ *state = s;
+
+ return retval;
+}
+
+gboolean
+meta_input_event_get_keycode (MetaDisplay *display,
+ XEvent *ev,
+ guint *keycode)
+{
+#ifdef HAVE_XINPUT2
+ if (ev->type == GenericEvent &&
+ ev->xcookie.extension == display->xinput2_opcode)
+ {
+ XIEvent *xev;
+
+ g_assert (display->have_xinput2 == TRUE);
+
+ xev = (XIEvent *) ev->xcookie.data;
+
+ if (xev->evtype == XI_KeyPress ||
+ xev->evtype == XI_KeyRelease)
+ {
+ if (keycode)
+ {
+ /* The detail field contains keycode for key events */
+ *keycode = ((XIDeviceEvent *) xev)->detail;
+ }
+
+ return TRUE;
+ }
+ }
+ else
+#endif /* HAVE_XINPUT2 */
+ {
+ if (ev->type == KeyPress ||
+ ev->type == KeyRelease)
+ {
+ if (keycode)
+ *keycode = ev->xkey.keycode;
+
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
diff --git a/src/core/input-events.h b/src/core/input-events.h
new file mode 100644
index 0000000..ea2c12e
--- /dev/null
+++ b/src/core/input-events.h
@@ -0,0 +1,64 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/**
+ * \file event.h Utility functions for handling events
+ *
+ * Handling events.
+ * This file contains helper methods to handle events, specially
+ * input events, which can be either core or XInput2.
+ */
+
+/*
+ * 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_EVENT_H
+#define META_EVENT_H
+
+#include <config.h>
+#include <X11/Xlib.h>
+#include "display-private.h"
+
+
+gboolean meta_input_event_get_type (MetaDisplay *display,
+ XEvent *ev,
+ guint *ev_type);
+
+Window meta_input_event_get_window (MetaDisplay *display,
+ XEvent *ev);
+Window meta_input_event_get_root_window (MetaDisplay *display,
+ XEvent *ev);
+
+Time meta_input_event_get_time (MetaDisplay *display,
+ XEvent *ev);
+
+gboolean meta_input_event_get_coordinates (MetaDisplay *display,
+ XEvent *ev,
+ gdouble *x_ret,
+ gdouble *y_ret,
+ gdouble *x_root_ret,
+ gdouble *y_root_ret);
+
+gboolean meta_input_event_get_state (MetaDisplay *display,
+ XEvent *ev,
+ guint *state);
+gboolean meta_input_event_get_keycode (MetaDisplay *display,
+ XEvent *ev,
+ guint *keycode);
+
+#endif /* META_EVENT_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]