diff options
author | Sergey Udaltsov <svu@gnome.org> | 2008-11-16 23:59:09 +0000 |
---|---|---|
committer | Sergey Udaltsov <svu@gnome.org> | 2008-11-16 23:59:09 +0000 |
commit | 53da1f88aa97623939d88267831148ae7f24bcb0 (patch) | |
tree | d8d08ffedc33ff82994aebe1eca036ab162d7100 | |
parent | 2c4baea56ff5ba98b195f91b8729a5f33bdfd342 (diff) | |
download | libxklavier-53da1f88aa97623939d88267831148ae7f24bcb0.tar.gz |
added device discovery
-rw-r--r-- | libxklavier/xkl_engine.h | 9 | ||||
-rw-r--r-- | libxklavier/xklavier.c | 6 | ||||
-rw-r--r-- | libxklavier/xklavier_evt_xkb.c | 29 | ||||
-rw-r--r-- | libxklavier/xklavier_private_xkb.h | 5 | ||||
-rw-r--r-- | libxklavier/xklavier_xkb.c | 25 |
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, |