summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Udaltsov <svu@gnome.org>2008-11-16 23:59:09 +0000
committerSergey Udaltsov <svu@gnome.org>2008-11-16 23:59:09 +0000
commit53da1f88aa97623939d88267831148ae7f24bcb0 (patch)
treed8d08ffedc33ff82994aebe1eca036ab162d7100
parent2c4baea56ff5ba98b195f91b8729a5f33bdfd342 (diff)
downloadlibxklavier-53da1f88aa97623939d88267831148ae7f24bcb0.tar.gz
added device discovery
-rw-r--r--libxklavier/xkl_engine.h9
-rw-r--r--libxklavier/xklavier.c6
-rw-r--r--libxklavier/xklavier_evt_xkb.c29
-rw-r--r--libxklavier/xklavier_private_xkb.h5
-rw-r--r--libxklavier/xklavier_xkb.c25
5 files changed, 70 insertions, 4 deletions
diff --git a/libxklavier/xkl_engine.h b/libxklavier/xkl_engine.h
index 04b4a87..ae3bf05 100644
--- a/libxklavier/xkl_engine.h
+++ b/libxklavier/xkl_engine.h
@@ -64,6 +64,7 @@ extern "C" {
XKLF_CAN_OUTPUT_CONFIG_AS_BINARY = 0x04,
XKLF_MULTIPLE_LAYOUTS_SUPPORTED = 0x08,
XKLF_REQUIRES_MANUAL_LAYOUT_MANAGEMENT = 0x10,
+ XKLF_DEVICE_DISCOVERY = 0x20,
} XklEngineFeatures;
/**
@@ -138,6 +139,14 @@ extern "C" {
XklEngineStateChange change_type,
gint group, gboolean restore);
+/**
+ * XklEngine::new_device_notify
+ * @engine: the object on which the signal is emitted
+ *
+ * Used for notifying application of the new keyboard attached
+ */
+ void (*new_device_notify) (XklEngine * engine);
+
};
diff --git a/libxklavier/xklavier.c b/libxklavier/xklavier.c
index d6dcf5b..bbb4dd7 100644
--- a/libxklavier/xklavier.c
+++ b/libxklavier/xklavier.c
@@ -891,6 +891,11 @@ xkl_engine_class_init(XklEngineClass * klass)
config_notify),
NULL, NULL, xkl_engine_VOID__VOID, G_TYPE_NONE, 0);
+ g_signal_new("X-new-device", XKL_TYPE_ENGINE,
+ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(XklEngineClass,
+ new_device_notify),
+ NULL, NULL, xkl_engine_VOID__VOID, G_TYPE_NONE, 0);
+
g_signal_new("new-toplevel-window", XKL_TYPE_ENGINE,
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(XklEngineClass,
new_window_notify),
@@ -905,7 +910,6 @@ xkl_engine_class_init(XklEngineClass * klass)
G_TYPE_NONE, 3, state_change_type, G_TYPE_INT,
G_TYPE_BOOLEAN);
- /* 2 Windows passed */
/* static stuff initialized */
sdl = g_getenv("XKL_DEBUG");
diff --git a/libxklavier/xklavier_evt_xkb.c b/libxklavier/xklavier_evt_xkb.c
index cff5ce4..64cea89 100644
--- a/libxklavier/xklavier_evt_xkb.c
+++ b/libxklavier/xklavier_evt_xkb.c
@@ -26,6 +26,23 @@
#include "xklavier_private.h"
#include "xklavier_private_xkb.h"
+#ifdef HAVE_XINPUT
+#include "config.h"
+#include "X11/extensions/XInput.h"
+
+static gint
+xkl_xinput_process_x_event(XklEngine * engine, XEvent * xev)
+{
+ XDevicePresenceNotifyEvent* dpne = (XDevicePresenceNotifyEvent*)xev;
+ xkl_debug(200, "XInput event detected: %d\n", dpne->devchange);
+ if (dpne->devchange == DeviceEnabled) {
+ xkl_debug(150, "Device enabled: %d\n", dpne->deviceid);
+ g_signal_emit_by_name(engine, "X-new-device");
+ }
+ return 1;
+}
+#endif
+
/*
* XKB event handler
*/
@@ -38,13 +55,19 @@ xkl_xkb_process_x_event(XklEngine * engine, XEvent * xev)
guint inds;
XkbEvent *kev = (XkbEvent *) xev;
- if (xev->type != xkl_engine_backend(engine, XklXkb, event_type))
- return 0;
-
if (!(xkl_engine_priv(engine, listener_type) &
(XKLL_MANAGE_WINDOW_STATES | XKLL_TRACK_KEYBOARD_STATE)))
return 0;
+#ifdef HAVE_XINPUT
+ /* Special case XInput event */
+ if (xev->type == xkl_engine_backend(engine, XklXkb, xi_event_type))
+ return xkl_xinput_process_x_event(engine, xev);
+#endif
+
+ if (xev->type != xkl_engine_backend(engine, XklXkb, event_type))
+ return 0;
+
xkl_debug(150, "Xkb event detected\n");
switch (kev->any.xkb_type) {
diff --git a/libxklavier/xklavier_private_xkb.h b/libxklavier/xklavier_private_xkb.h
index 94af509..920aeeb 100644
--- a/libxklavier/xklavier_private_xkb.h
+++ b/libxklavier/xklavier_private_xkb.h
@@ -22,6 +22,7 @@
#ifdef LIBXKBFILE_PRESENT
+#include <config.h>
#include <X11/XKBlib.h>
#include <X11/extensions/XKBrules.h>
@@ -44,6 +45,10 @@ typedef struct _XklXkb {
gchar *group_names[XkbNumKbdGroups];
int device_id;
+
+#ifdef HAVE_XINPUT
+ gint xi_event_type;
+#endif
} XklXkb;
extern void xkl_engine_dump_xkb_desc(XklEngine * engine,
diff --git a/libxklavier/xklavier_xkb.c b/libxklavier/xklavier_xkb.c
index 739a0b4..134fcc1 100644
--- a/libxklavier/xklavier_xkb.c
+++ b/libxklavier/xklavier_xkb.c
@@ -27,6 +27,11 @@
#include "xklavier_private.h"
#include "xklavier_private_xkb.h"
+#ifdef HAVE_XINPUT
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XInput.h>
+#endif
+
#ifdef LIBXKBFILE_PRESENT
const gchar **
@@ -55,6 +60,10 @@ xkl_xkb_pause_listen(XklEngine * engine)
gint
xkl_xkb_resume_listen(XklEngine * engine)
{
+#ifdef HAVE_XINPUT
+ int xitype;
+ XEventClass xiclass;
+#endif
/* What events we want */
#define XKB_EVT_MASK \
(XkbStateNotifyMask| \
@@ -86,6 +95,13 @@ xkl_xkb_resume_listen(XklEngine * engine)
device_id),
XkbNamesNotify, XKB_NAMES_EVT_DTL_MASK,
XKB_NAMES_EVT_DTL_MASK);
+#ifdef HAVE_XINPUT
+ DevicePresence(display, xitype, xiclass);
+ XSelectExtensionEvent(display,
+ xkl_engine_priv(engine, root_window),
+ &xiclass, 1);
+ xkl_engine_backend(engine, XklXkb, xi_event_type) = xitype;
+#endif
return 0;
}
@@ -522,6 +538,7 @@ xkl_xkb_init(XklEngine * engine)
#ifdef LIBXKBFILE_PRESENT
gint opcode;
gboolean xkl_xkb_ext_present;
+ int xi_opc, xi_event_type, xi_error_code;
xkl_engine_priv(engine, backend_id) = "XKB";
xkl_engine_priv(engine, features) = XKLF_CAN_TOGGLE_INDICATORS |
@@ -599,6 +616,14 @@ xkl_xkb_init(XklEngine * engine)
xkl_engine_priv(engine, features) |=
XKLF_MULTIPLE_LAYOUTS_SUPPORTED;
+ if (XQueryExtension
+ (display, "XInputExtension", &xi_opc,
+ &xi_event_type, &xi_error_code)) {
+ xkl_debug(150, "XInputExtension found (%d, %d, %d)\n",
+ xi_opc, xi_event_type, xi_error_code);
+ xkl_engine_priv(engine, features) |= XKLF_DEVICE_DISCOVERY;
+ } else
+ xkl_debug(0, "XInputExtension not found\n");
return 0;
#else
xkl_debug(160,