#define LIBDS_TIZEN_KEYROUTER_H
#include <wayland-server.h>
+#include <libds/seat.h>
+#include <libds/surface.h>
#ifdef __cplusplus
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 *
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
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)
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
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);
+ }
+ }
+}
#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;
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);
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
}
}
-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)
{
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
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;
}
}
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;
}