x11: feed keyboard event
authorJaehoon Jeong <jh01.j@samsung.com>
Tue, 18 Aug 2015 12:51:04 +0000 (21:51 +0900)
committer김태균 <tkq.kim@samsung.com>
Thu, 20 Aug 2015 05:38:51 +0000 (14:38 +0900)
    - Use xkbcommon, xkbcommon-x11 libs for translate keycode to keysym
    - TODO: Handle additional modifiers

Change-Id: I90ff5411e42ae662013d270a346e3a2e2fc1d570

configure.ac
src/lib/x11/x11-common.c
src/lib/x11/x11-input.c
src/lib/x11/x11-internal.h

index e3ba781..c26a4ce 100644 (file)
@@ -135,7 +135,7 @@ AC_ARG_ENABLE(x11,
 AM_CONDITIONAL(ENABLE_X11, test x$enable_x11 = xyes)
 
 if test x$enable_x11 = xyes; then
-    PEPPER_X11_REQUIRES="x11 xcb-shm x11-xcb"
+    PEPPER_X11_REQUIRES="x11 xcb-shm x11-xcb xkbcommon xkbcommon-x11"
     PKG_CHECK_MODULES(PEPPER_X11, [$PEPPER_X11_REQUIRES])
     PEPPER_X11_REQUIRES="$PEPPER_X11_REQUIRES pepper pepper-render"
 
index a6759ac..2cc18a5 100644 (file)
@@ -87,6 +87,9 @@ x11_handle_event(int fd, uint32_t mask, void *data)
             break;
         case XCB_KEYMAP_NOTIFY:
             PEPPER_TRACE("XCB_KEYMAP_NOTIFY\n");
+            {
+                /* TODO: ignore at this time. */
+            }
             break;
         case XCB_CONFIGURE_NOTIFY:
             /* Window moved */
index a0b850a..2488db5 100644 (file)
@@ -19,7 +19,30 @@ x11_handle_input_event(x11_seat_t* seat, uint32_t type, xcb_generic_event_t* xev
         }
         break;
     case XCB_KEY_PRESS:
+        {
+            xcb_key_press_event_t       *kp = (xcb_key_press_event_t *)xev;
+            pepper_keyboard_key_event_t  event;
+
+            event.time  = kp->time;
+            event.key   = xkb_state_key_get_one_sym(seat->xkb_state, kp->detail);
+            event.state = WL_KEYBOARD_KEY_STATE_PRESSED;    /* FIXME */
+
+            pepper_object_emit_event((pepper_object_t *)seat->keyboard,
+                                     PEPPER_EVENT_INPUT_DEVICE_KEYBOARD_KEY, &event);
+        }
+        break;
     case XCB_KEY_RELEASE:
+        {
+            xcb_key_release_event_t     *kr = (xcb_key_release_event_t *)xev;
+            pepper_keyboard_key_event_t  event;
+
+            event.time  = kr->time;
+            event.key   = xkb_state_key_get_one_sym(seat->xkb_state, kr->detail);
+            event.state = WL_KEYBOARD_KEY_STATE_RELEASED;    /* FIXME */
+
+            pepper_object_emit_event((pepper_object_t *)seat->keyboard,
+                                     PEPPER_EVENT_INPUT_DEVICE_KEYBOARD_KEY, &event);
+        }
         break;
     case XCB_BUTTON_PRESS:
         {
@@ -131,6 +154,15 @@ x11_seat_destroy(void *data)
     if (seat->conn)
         seat->conn->seat = NULL;
 
+    if (seat->xkb_state)
+        xkb_state_unref(seat->xkb_state);
+
+    if (seat->keymap)
+        xkb_keymap_unref(seat->keymap);
+
+    if (seat->xkb_ctx)
+        xkb_context_unref(seat->xkb_ctx);
+
     free(seat);
 }
 
@@ -173,6 +205,42 @@ pepper_x11_input_create(pepper_x11_connection_t* conn)
 
     seat->id = X11_BACKEND_INPUT_ID;
 
+    /* Init XKB extension */
+    seat->xkb_ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
+    if (!seat->xkb_ctx)
+    {
+        PEPPER_ERROR("xkb_context_new failed\n");
+
+        goto failed;
+    }
+
+    seat->device_id = xkb_x11_get_core_keyboard_device_id(conn->xcb_connection);
+    if (seat->device_id == -1)
+    {
+        PEPPER_ERROR("xkb_x11_get_core_keyboard_device_id failed\n");
+
+        goto failed;
+    }
+
+    seat->keymap = xkb_x11_keymap_new_from_device(seat->xkb_ctx,
+                                                  conn->xcb_connection,
+                                                  seat->device_id,
+                                                  XKB_KEYMAP_COMPILE_NO_FLAGS);
+    if (!seat->keymap)
+    {
+        PEPPER_ERROR("xkb_x11_keymap_new_from_device failed\n");
+
+        goto failed;
+    }
+
+    seat->xkb_state = xkb_x11_state_new_from_device(seat->keymap, conn->xcb_connection, seat->device_id);
+    if (!seat->xkb_state)
+    {
+        PEPPER_ERROR("xkb_x11_state_new_from_device failed\n");
+
+        goto failed;
+    }
+
     /* Hard-coded: */
     seat->pointer = pepper_input_device_create(conn->compositor, WL_SEAT_CAPABILITY_POINTER,
                                                NULL, NULL);
@@ -180,8 +248,7 @@ pepper_x11_input_create(pepper_x11_connection_t* conn)
     {
         PEPPER_ERROR("failed to create pepper pointer device\n");
 
-        x11_seat_destroy(seat);
-        return PEPPER_FALSE;
+        goto failed;
     }
     seat->caps |= WL_SEAT_CAPABILITY_POINTER;
 
@@ -191,8 +258,7 @@ pepper_x11_input_create(pepper_x11_connection_t* conn)
     {
         PEPPER_ERROR("failed to create pepper keyboard device\n");
 
-        x11_seat_destroy(seat);
-        return PEPPER_FALSE;
+        goto failed;
     }
     seat->caps |= WL_SEAT_CAPABILITY_KEYBOARD;
 
@@ -201,4 +267,8 @@ pepper_x11_input_create(pepper_x11_connection_t* conn)
     seat->conn = conn;
 
     return PEPPER_TRUE;
+
+failed:
+    x11_seat_destroy(seat);
+    return PEPPER_FALSE;
 }
index 69e1d27..e671546 100644 (file)
@@ -5,6 +5,8 @@
 
 #include <xcb/xcb.h>
 #include <xcb/shm.h>
+#include <xkbcommon/xkbcommon.h>
+#include <xkbcommon/xkbcommon-x11.h>
 #include <X11/Xlib.h>
 #include <X11/Xlib-xcb.h>
 #include <string.h>
@@ -78,6 +80,11 @@ struct x11_seat
     uint32_t                        caps;
     char                           *name;
 
+    struct xkb_context             *xkb_ctx;
+    int32_t                         device_id;
+    struct xkb_keymap              *keymap;
+    struct xkb_state               *xkb_state;
+
     struct wl_list                  link;
 
     struct wl_listener              conn_destroy_listener;