keyrouter: Replace get_keyroutes() with notify_key() 42/278242/1
authorSeunghun Lee <shiin.lee@samsung.com>
Wed, 6 Jul 2022 01:54:44 +0000 (10:54 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Mon, 18 Jul 2022 05:59:17 +0000 (14:59 +0900)
Instead of returning key routes list to the compositor, it will deal
with keyboard key events on the behalf of the compositor according to
keyrouter extension protocol.

Change-Id: I6b7085402c6bb5cad0160f356c327af1467f9726

include/libds-tizen/keyrouter.h
src/keyrouter/keyrouter.c
src/keyrouter/keyrouter.h
src/keyrouter/keyrouter_grab.c

index bd47b54..1be7944 100644 (file)
@@ -2,6 +2,8 @@
 #define LIBDS_TIZEN_KEYROUTER_H
 
 #include <wayland-server.h>
+#include <libds/seat.h>
+#include <libds/surface.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -13,39 +15,6 @@ extern "C" {
 struct ds_tizen_keyrouter;
 
 /**
- * The information of keyroute
- */
-struct ds_tizen_keyroute_info
-{
-    struct wl_client *wl_client;
-};
-
-/**
- * Keyroute mode of keyroutes returned by ds_tizen_keyrouter_get_keyroutes()
- * for a given keycode.
- */
-enum ds_tizen_keyroute_mode {
-    /**
-     * The keycode is not under any keyroute mode.
-     * The compositor may send a keycode to a focused wayland cliet as usual.
-     */
-    DS_TIZEN_KEYROUTE_MODE_NONE,
-    /**
-     * Exclusive mode means that a given keycode is required to be sent
-     * exclusively to wayland clients of returned keyroutes. So the compositor
-     * must not send this keycode to any other wayland clients except for
-     * returned wayland clients.
-     */
-    DS_TIZEN_KEYROUTE_MODE_EXCLUSIVE,
-    /**
-     * The keycode is required to be shared with returned wayland clients.
-     * The compositor must send the keycode not only to returned wayland
-     * clients, but also to a focused wayland client.
-     */
-    DS_TIZEN_KEYROUTE_MODE_SHARED,
-};
-
-/**
  * Creates a ds_tizen_keyrouter.
  */
 struct ds_tizen_keyrouter *
@@ -59,18 +28,21 @@ ds_tizen_keyrouter_add_destroy_listener(struct ds_tizen_keyrouter *keyrouter,
         struct wl_listener *listener);
 
 /**
- * Gets keyroutes and mode for a given keycode.
- * The compositor must send a keycode to returned wayland clients according to
- * the mode. The parameter, topmost_client, should be given to determine whether
- * the given topmost_client require a keycode exclusively when one of its
- * surfaces is on very top of stack. See tizen_keyrouter protocol in
- * tizen-extension.xml for more detail.
+ * Notify the keyrouter that a key has been pressed on the keyboard.
+ * This will eventually notify a given seat of key events, and if there is
+ * no destination to be routed, then it sends key events to the focused one
+ * automatically. So, if you call this, you don't need to call
+ * ds_seat_keyboard_notify_key() manually unless you want to do something
+ * differently.
+ * The parameter, topmost_surface, should be given for the keyrouter to
+ * determine whether the given topmost_surface require a keycode exclusively
+ * when the surface is on very top of stack.
+ * See tizen_keyrouter protocol in tizen-extension.xml for more detail.
  */
-enum ds_tizen_keyroute_mode
-ds_tizen_keyrouter_get_keyroutes(struct ds_tizen_keyrouter *keyrouter,
-        int keycode, struct wl_client *topmost_client,
-        struct wl_array *keyroutes);
-
+void
+ds_tizen_keyrouter_notify_key(struct ds_tizen_keyrouter *keyrouter,
+        struct ds_seat *seat, struct ds_surface *topmost_surface,
+        uint32_t time_msec, uint32_t key, uint32_t state);
 #ifdef __cplusplus
 }
 #endif
index 2e825c6..097f4df 100644 (file)
@@ -29,6 +29,9 @@ static int keyrouter_client_grab_key(struct keyrouter_client *client, int mode,
         int keycode);
 static int keyrouter_client_ungrab_key(struct keyrouter_client *client,
         int keycode);
+static void
+keyrouter_seat_broadcast_key(struct ds_seat *seat, struct wl_array *keyroutes,
+        bool with_focus, uint32_t time_msec, uint32_t keycode, uint32_t state);
 
 WL_EXPORT struct ds_tizen_keyrouter *
 ds_tizen_keyrouter_create(struct wl_display *display)
@@ -76,13 +79,45 @@ ds_tizen_keyrouter_add_destroy_listener(struct ds_tizen_keyrouter *keyrouter,
     wl_signal_add(&keyrouter->events.destroy, listener);
 }
 
-WL_EXPORT enum ds_tizen_keyroute_mode
-ds_tizen_keyrouter_get_keyroutes(struct ds_tizen_keyrouter *keyrouter,
-        int keycode, struct wl_client *topmost_client,
-        struct wl_array *keyroutes)
+WL_EXPORT void
+ds_tizen_keyrouter_notify_key(struct ds_tizen_keyrouter *keyrouter,
+        struct ds_seat *seat, struct ds_surface *topmost_surface,
+        uint32_t time_msec, uint32_t keycode, uint32_t state)
 {
-    return keyrouter_grab_get_keyroutes(&keyrouter->keygrab,
-            keycode, topmost_client, keyroutes);
+    struct wl_client *topmost_wl_client = NULL;
+    struct wl_resource *surface_resource;
+    struct wl_array keyroutes;
+    enum keyroute_mode mode;
+
+    wl_array_init(&keyroutes);
+
+    if (topmost_surface) {
+        surface_resource = ds_surface_get_wl_resource(topmost_surface);
+        if (surface_resource) {
+            topmost_wl_client = wl_resource_get_client(
+                    ds_surface_get_wl_resource(topmost_surface));
+        }
+    }
+
+    mode = keyrouter_grab_get_keyroutes(&keyrouter->keygrab, keycode + 8,
+            topmost_wl_client, &keyroutes);
+
+    if (mode == KEYROUTE_MODE_EXCLUSIVE) {
+        keyrouter_seat_broadcast_key(seat, &keyroutes, true,
+                time_msec, keycode, state);
+
+        goto end;
+    }
+
+    if (mode == KEYROUTE_MODE_SHARED) {
+        keyrouter_seat_broadcast_key(seat, &keyroutes, false,
+                time_msec, keycode, state);
+    }
+
+    ds_seat_keyboard_notify_key(seat, time_msec, keycode, state);
+
+end:
+    wl_array_release(&keyroutes);
 }
 
 static void
@@ -424,3 +459,30 @@ keyrouter_client_ungrab_key(struct keyrouter_client *client, int keycode)
 
     return TIZEN_KEYROUTER_ERROR_NONE;
 }
+
+static void
+keyrouter_seat_broadcast_key(struct ds_seat *seat, struct wl_array *keyroutes,
+        bool with_focus, uint32_t time_msec, uint32_t keycode, uint32_t state)
+{
+    struct ds_seat_client *seat_client, *focused_client;
+    struct wl_client **wl_client_ptr;
+
+    focused_client = ds_seat_keyboard_get_focused_client(seat);
+
+    wl_array_for_each(wl_client_ptr, keyroutes) {
+        seat_client = ds_seat_client_for_wl_client(seat, *wl_client_ptr);
+        if (!seat_client) {
+            ds_inf("Could not find ds_seat_client for given wl_client(%p)",
+                    *wl_client_ptr);
+            continue;
+        }
+
+        if (seat_client == focused_client) {
+            if (with_focus)
+                ds_seat_keyboard_notify_key(seat, time_msec, keycode, state);
+        }
+        else {
+            ds_seat_client_send_key(seat_client, time_msec, keycode, state);
+        }
+    }
+}
index bea9ab1..bd3faa9 100644 (file)
@@ -9,6 +9,31 @@
 
 #define KEYROUTER_MAX_KEYS 512
 
+/**
+ * Keyroute mode of keyroutes returned by keyrouter_grab_get_keyroutes()
+ * for a given keycode.
+ */
+enum keyroute_mode {
+    /**
+     * The keycode is not under any keyroute mode.
+     * The compositor may send a keycode to a focused wayland cliet as usual.
+     */
+    KEYROUTE_MODE_NONE,
+    /**
+     * Exclusive mode means that a given keycode is required to be sent
+     * exclusively to wayland clients of returned keyroutes. So the compositor
+     * must not send this keycode to any other wayland clients except for
+     * returned wayland clients.
+     */
+    KEYROUTE_MODE_EXCLUSIVE,
+    /**
+     * The keycode is required to be shared with returned wayland clients.
+     * The compositor must send the keycode not only to returned wayland
+     * clients, but also to a focused wayland client.
+     */
+    KEYROUTE_MODE_SHARED,
+};
+
 struct keyroute_info
 {
     struct wl_client *wl_client;
@@ -92,7 +117,7 @@ int keyrouter_grab_grab_key(struct keyrouter_grab *keygrab, int mode,
 void keyrouter_grab_ungrab_key(struct keyrouter_grab *keygrab, int mode,
         int keycode, struct wl_client *wl_client);
 
-enum ds_tizen_keyroute_mode
+enum keyroute_mode
 keyrouter_grab_get_keyroutes(struct keyrouter_grab *keygrab, int keycode,
         struct wl_client *topmost_client, struct wl_array *keyroutes);
 
index fed301b..4f27ea1 100644 (file)
@@ -31,7 +31,7 @@ keyrouter_grab_topmost_find(struct keyrouter_grab *keygrab, int keycode,
         struct wl_client *topmost_client);
 static bool keyrouter_grab_get_shared_keyroutes(struct keyrouter_grab *keygrab,
         int keycode, struct wl_array *keyroutes);
-static bool keyroutes_add_info(struct wl_array *keyroutes,
+static bool keyroutes_add_wl_client(struct wl_array *keyroutes,
         struct wl_client *wl_client);
 
 void
@@ -58,7 +58,7 @@ keyrouter_grab_finish(struct keyrouter_grab *keygrab)
     }
 }
 
-enum ds_tizen_keyroute_mode
+enum keyroute_mode
 keyrouter_grab_get_keyroutes(struct keyrouter_grab *keygrab, int keycode,
         struct wl_client *topmost_client, struct wl_array *keyroutes)
 {
@@ -82,16 +82,16 @@ keyrouter_grab_get_keyroutes(struct keyrouter_grab *keygrab, int keycode,
         goto exclusive_out;
 
     if (keyrouter_grab_get_shared_keyroutes(keygrab, keycode, keyroutes))
-        return DS_TIZEN_KEYROUTE_MODE_SHARED;
+        return KEYROUTE_MODE_SHARED;
 
 none_out:
-    return DS_TIZEN_KEYROUTE_MODE_NONE;
+    return KEYROUTE_MODE_NONE;
 
 exclusive_out:
-    if (!keyroutes_add_info(keyroutes, info->wl_client))
+    if (!keyroutes_add_wl_client(keyroutes, info->wl_client))
         ds_err("Could not add wl_client to keyroutes");
 
-    return DS_TIZEN_KEYROUTE_MODE_EXCLUSIVE;
+    return KEYROUTE_MODE_EXCLUSIVE;
 }
 
 int
@@ -299,7 +299,7 @@ keyrouter_grab_get_shared_keyroutes(struct keyrouter_grab *keygrab,
     int count = 0;
 
     wl_list_for_each(info, list, link) {
-        if (!keyroutes_add_info(keyroutes, info->wl_client)) {
+        if (!keyroutes_add_wl_client(keyroutes, info->wl_client)) {
             ds_err("Could not prepend wl_client to delivery_list");
             continue;
         }
@@ -314,16 +314,15 @@ keyrouter_grab_get_shared_keyroutes(struct keyrouter_grab *keygrab,
 }
 
 static bool
-keyroutes_add_info(struct wl_array *keyroutes,
-        struct wl_client *wl_client)
+keyroutes_add_wl_client(struct wl_array *keyroutes, struct wl_client *wl_client)
 {
-    struct ds_tizen_keyroute_info *info;
+    struct wl_client **p;
 
-    info = wl_array_add(keyroutes, sizeof *info);
-    if (!info)
+    p = wl_array_add(keyroutes, sizeof(struct wl_client *));
+    if (!p)
         return false;
 
-    info->wl_client = wl_client;
+    *p = wl_client;
 
     return true;
 }