diff options
author | Jonathan Maw <jonathan.maw@codethink.co.uk> | 2014-10-24 12:04:28 +0000 |
---|---|---|
committer | Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> | 2014-11-06 17:09:37 +0900 |
commit | dd01ca51e0699e188ba98e599f4f34ae5a1bab9c (patch) | |
tree | 0dc96de00ea1384d270e863b9d289f20d73b97c4 | |
parent | da782dd73eb23b384aa7861053f9910b7b39bdc1 (diff) | |
download | weston-dd01ca51e0699e188ba98e599f4f34ae5a1bab9c.tar.gz |
ivi-shell: Implement SetKeyboardFocus
This commit implements ivi_layout_SetKeyboardFocusOn.
It also extends ivi-layout.h and ivi-layout-export.h to store
keyboard focus on a per-surface basis.
Signed-off-by: James Thomas <james.thomas@codethink.co.uk>
-rw-r--r-- | ivi-shell/ivi-layout-export.h | 1 | ||||
-rw-r--r-- | ivi-shell/ivi-layout.c | 119 | ||||
-rw-r--r-- | ivi-shell/ivi-layout.h | 1 |
3 files changed, 119 insertions, 2 deletions
diff --git a/ivi-shell/ivi-layout-export.h b/ivi-shell/ivi-layout-export.h index f24fa994..3d1afc95 100644 --- a/ivi-shell/ivi-layout-export.h +++ b/ivi-shell/ivi-layout-export.h @@ -68,6 +68,7 @@ enum ivi_layout_notification_mask { IVI_NOTIFICATION_ADD = (1 << 9), IVI_NOTIFICATION_REMOVE = (1 << 10), IVI_NOTIFICATION_CONFIGURE = (1 << 11), + IVI_NOTIFICATION_KEYBOARD_FOCUS = (1 << 12), IVI_NOTIFICATION_ALL = 0xFFFF }; diff --git a/ivi-shell/ivi-layout.c b/ivi-shell/ivi-layout.c index 17a9a742..e7ac2f14 100644 --- a/ivi-shell/ivi-layout.c +++ b/ivi-shell/ivi-layout.c @@ -2419,8 +2419,41 @@ ivi_layout_surfaceGetOpacity(struct ivi_layout_surface *ivisurf, WL_EXPORT int32_t ivi_layout_SetKeyboardFocusOn(struct ivi_layout_surface *ivisurf) { - /* TODO */ - (void)ivisurf; + struct ivi_layout *layout = get_instance(); + struct wl_list *seat_list = &layout->compositor->seat_list; + struct wl_list *surface_list = &layout->list_surface; + struct ivi_layout_surface *current_surf; + + if (ivisurf == NULL) { + weston_log("%s: invalid argument\n", __FUNCTION__); + return -1; + } + + if (seat_list == NULL) { + weston_log("%s: seat list is NULL\n", __FUNCTION__); + return -1; + } + + if (ivisurf->surface == NULL) { + weston_log("%s: ivisurf has no surface\n", __FUNCTION__); + return -1; + } + + if (surface_list == NULL) { + weston_log("%s: surface list is NULL\n", __FUNCTION__); + return -1; + } + + wl_list_for_each(current_surf, &layout->list_surface, link) { + if (current_surf == ivisurf) { + current_surf->prop.hasKeyboardFocus = 1; + current_surf->pending.prop.hasKeyboardFocus = 1; + } else { + current_surf->prop.hasKeyboardFocus = 0; + current_surf->pending.prop.hasKeyboardFocus = 0; + } + current_surf->event_mask |= IVI_NOTIFICATION_KEYBOARD_FOCUS; + } return 0; } @@ -3166,6 +3199,32 @@ static void keyboard_grab_key(struct weston_keyboard_grab *grab, uint32_t time, uint32_t key, uint32_t state) { + struct ivi_layout *layout = get_instance(); + struct weston_keyboard *keyboard = grab->keyboard; + struct wl_display *display = keyboard->seat->compositor->wl_display; + struct ivi_layout_surface *surf; + struct wl_resource *resource; + uint32_t serial; + + wl_list_for_each(surf, &layout->list_surface, link) { + if (surf->prop.hasKeyboardFocus) { + resource = wl_resource_find_for_client( + &keyboard->resource_list, + wl_resource_get_client(surf->surface->resource)); + if (!resource) + resource = wl_resource_find_for_client( + &keyboard->focus_resource_list, + wl_resource_get_client(surf->surface->resource)); + + if (resource) { + serial = wl_display_next_serial(display); + wl_keyboard_send_key(resource, serial, time, key, state); + } else { + weston_log("%s: No resource found for surface %d\n", + __FUNCTION__, surf->id_surface); + } + } + } } static void @@ -3173,6 +3232,62 @@ keyboard_grab_modifiers(struct weston_keyboard_grab *grab, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) { + struct ivi_layout *layout = get_instance(); + struct weston_keyboard *keyboard = grab->keyboard; + struct ivi_layout_surface *surf; + struct wl_resource *resource; + int sent_to_pointer_client = 0; + struct weston_pointer *pointer = keyboard->seat->pointer; + + /* Send modifiers to focussed surface */ + wl_list_for_each(surf, &layout->list_surface, link) { + if (surf->prop.hasKeyboardFocus) { + resource = wl_resource_find_for_client( + &keyboard->resource_list, + wl_resource_get_client(surf->surface->resource)); + if (!resource) + resource = wl_resource_find_for_client( + &keyboard->focus_resource_list, + wl_resource_get_client(surf->surface->resource)); + + if (resource) { + wl_keyboard_send_modifiers(resource, serial, + mods_depressed, + mods_latched, mods_locked, + group); + if (pointer && pointer->focus + && pointer->focus->surface->resource + && pointer->focus->surface == surf->surface) + sent_to_pointer_client = 1; + } else { + weston_log("%s: No resource found for surface %d\n", + __FUNCTION__, surf->id_surface); + } + } + } + + /* Send modifiers to pointer's client, if not already sent */ + if (!sent_to_pointer_client && pointer && pointer->focus + && pointer->focus->surface->resource) { + struct wl_client *pointer_client = + wl_resource_get_client(pointer->focus->surface->resource); + wl_resource_for_each(resource, &keyboard->resource_list) { + if (wl_resource_get_client(resource) == pointer_client) { + sent_to_pointer_client = 1; + wl_keyboard_send_modifiers(resource, serial, mods_depressed, + mods_latched, mods_locked, group); + break; + } + } + + if (!sent_to_pointer_client) { + wl_resource_for_each(resource, &keyboard->focus_resource_list) { + wl_keyboard_send_modifiers(resource, serial, mods_depressed, + mods_latched, mods_locked, group); + break; + } + } + } } static void diff --git a/ivi-shell/ivi-layout.h b/ivi-shell/ivi-layout.h index 4622a46f..e6f2eef0 100644 --- a/ivi-shell/ivi-layout.h +++ b/ivi-shell/ivi-layout.h @@ -87,6 +87,7 @@ struct ivi_layout_SurfaceProperties int32_t creatorPid; int32_t transitionType; uint32_t transitionDuration; + uint32_t hasKeyboardFocus; }; struct ivi_layout_LayerProperties |