diff --git a/ivi-input-modules/ivi-input-controller/CMakeLists.txt b/ivi-input-modules/ivi-input-controller/CMakeLists.txt index 62b08c88..7d59fc48 100644 --- a/ivi-input-modules/ivi-input-controller/CMakeLists.txt +++ b/ivi-input-modules/ivi-input-controller/CMakeLists.txt @@ -53,12 +53,14 @@ include_directories( ${ILM_COMMON_INCLUDE_DIRS} ${IVI_CONTROLLER_INCLUDE_DIRS} ${WAYLAND_SERVER_INCLUDE_DIRS} + ${LIBWESTON_INCLUDE_DIRS} ${WESTON_INCLUDE_DIRS} ${PIXMAN_INCLUDE_DIRS} ) link_directories( ${WAYLAND_SERVER_LIBRARY_DIRS} + ${LIBWESTON_LIBRARY_DIRS} ${WESTON_LIBRARY_DIRS} ${PIXMAN_LIBRARY_DIRS} ) @@ -82,6 +84,7 @@ add_dependencies(${PROJECT_NAME} set(LIBS ${LIBS} ${WAYLAND_SERVER_LIBRARIES} + ${LIBWESTON_LIBRARIES} ${WESTON_LIBRARIES} ) diff --git a/ivi-input-modules/ivi-input-controller/src/ivi-input-controller.c b/ivi-input-modules/ivi-input-controller/src/ivi-input-controller.c index 661215e2..4e33c560 100644 --- a/ivi-input-modules/ivi-input-controller/src/ivi-input-controller.c +++ b/ivi-input-modules/ivi-input-controller/src/ivi-input-controller.c @@ -31,6 +31,7 @@ #include #include +#include #include #include "ilm_types.h" @@ -96,6 +97,26 @@ struct wl_keyboard_data { uint32_t serial; }; +/** + * Get the only view associated with the surface. + * Return NULL if the surface has no views/multiple views + * associated with it. + */ +static struct weston_view * +weston_surface_get_only_view(struct weston_surface *surface) +{ + struct weston_view *view; + + if (!surface) + return NULL; + + if (wl_list_length(&surface->views) != 1) + return NULL; + + return wl_container_of(surface->views.prev, view, + surface_link); +} + static struct seat_focus * get_accepted_seat(struct ivisurface *surface, struct seat_ctx *seat_ctx) { @@ -182,15 +203,28 @@ send_input_acceptance(struct input_context *ctx, uint32_t surface_id, const char } static void -send_input_focus(struct input_context *ctx, struct ivisurface *surf_ctx, - ilmInputDevice device, t_ilm_bool enabled) +send_input_focus(struct ivisurface *surf_ctx, struct seat_ctx *ctx_seat, + ilmInputDevice device, struct iviscreen *scrn_ctx, + t_ilm_bool enabled) { struct wl_resource *resource; + struct weston_seat *west_seat = ctx_seat->west_seat; + struct input_context *ctx = ctx_seat->input_ctx; const struct ivi_layout_interface *lyt_if = ctx->ivishell->interface; t_ilm_surface surface_id = lyt_if->get_id_of_surface(surf_ctx->layout_surface); + t_ilm_display screen_id = INVALID_ID; + + if (scrn_ctx) + screen_id = scrn_ctx->id_screen; wl_resource_for_each(resource, &ctx->resource_list) { ivi_input_send_input_focus(resource, surface_id, device, enabled); + + if (wl_resource_get_version(resource) >= + IVI_INPUT_INPUT_FOCUS_CHANGE_SINCE_VERSION) { + ivi_input_send_input_focus_change(resource, surface_id, + west_seat->seat_name, device, screen_id, enabled); + } } } @@ -239,6 +273,51 @@ input_ctrl_get_surf_ctx_from_surf(struct input_context *ctx, return surf_ctx; } +static struct iviscreen * +input_ctrl_get_scrn_ctx_from_output(struct input_context *ctx, + struct weston_output *output) +{ + struct ivishell *shell = ctx->ivishell; + struct iviscreen* iviscrn; + + wl_list_for_each(iviscrn, &shell->list_screen, link) { + if (output == iviscrn->output) + return iviscrn; + } + + return NULL; +} + +/** + * Retrive the ivi screen context of a weston surface + * + * Fetch the weston output related to the surface. + * If the surface has only one view, get the primary output of the + * view. Or else if surface have multiple views, then get it's vsync + * output. Else return NULL, if surface has no views. + * + * Then get the ivi screen context associated with the weston output. + */ +static struct iviscreen * +input_ctrl_get_scrn_ctx_from_surface(struct input_context *ctx, + struct weston_surface *surface) +{ + struct weston_view *view; + struct weston_output *output = NULL; + + view = weston_surface_get_only_view(surface); + if (view) { + output = view->output; + } else if (!view && (wl_list_length(&surface->views) > 1)) { + output = surface->output; + } + + if (output) + return input_ctrl_get_scrn_ctx_from_output(ctx, output); + + return NULL; +} + static void input_ctrl_kbd_snd_event_resource(struct seat_ctx *ctx_seat, struct weston_keyboard *keyboard, struct wl_resource *resource, @@ -341,8 +420,8 @@ input_ctrl_kbd_leave_surf(struct seat_ctx *ctx_seat, ctx_seat->keyboard_grab.keyboard, &kbd_data); st_focus->focus &= ~ILM_INPUT_DEVICE_KEYBOARD; - send_input_focus(ctx, surf_ctx, - ILM_INPUT_DEVICE_KEYBOARD, ILM_FALSE); + send_input_focus(surf_ctx, ctx_seat, + ILM_INPUT_DEVICE_KEYBOARD, NULL, ILM_FALSE); } } @@ -366,8 +445,8 @@ input_ctrl_kbd_enter_surf(struct seat_ctx *ctx_seat, ctx_seat->keyboard_grab.keyboard, &kbd_data); st_focus->focus |= ILM_INPUT_DEVICE_KEYBOARD; - send_input_focus(ctx, surf_ctx, - ILM_INPUT_DEVICE_KEYBOARD, ILM_TRUE); + send_input_focus(surf_ctx, ctx_seat, + ILM_INPUT_DEVICE_KEYBOARD, NULL, ILM_TRUE); } } @@ -491,9 +570,8 @@ static struct weston_keyboard_grab_interface keyboard_grab_interface = { struct seat_focus * input_ctrl_snd_focus_to_controller(struct ivisurface *surf_ctx, struct seat_ctx *ctx_seat, ilmInputDevice device, - int32_t enabled) + struct iviscreen *scrn_ctx, int32_t enabled) { - struct input_context *ctx = ctx_seat->input_ctx; struct seat_focus *st_focus = NULL; if (NULL != surf_ctx) { @@ -505,7 +583,8 @@ input_ctrl_snd_focus_to_controller(struct ivisurface *surf_ctx, } else { st_focus->focus &= ~device; } - send_input_focus(ctx, surf_ctx, device, enabled); + send_input_focus(surf_ctx, ctx_seat, device, + scrn_ctx, enabled); } } return st_focus; @@ -516,14 +595,18 @@ input_ctrl_ptr_leave_west_focus(struct seat_ctx *ctx_seat, struct weston_pointer *pointer) { struct ivisurface *surf_ctx; + struct iviscreen *scrn_ctx; struct input_context *ctx = ctx_seat->input_ctx; if (NULL != pointer->focus) { surf_ctx = input_ctrl_get_surf_ctx_from_surf(ctx, pointer->focus->surface); + scrn_ctx = input_ctrl_get_scrn_ctx_from_output(ctx, + pointer->focus->output); + input_ctrl_snd_focus_to_controller(surf_ctx, ctx_seat, - ILM_INPUT_DEVICE_POINTER, ILM_FALSE); + ILM_INPUT_DEVICE_POINTER, scrn_ctx, ILM_FALSE); weston_pointer_clear_focus(pointer); } @@ -536,6 +619,7 @@ input_ctrl_ptr_set_west_focus(struct seat_ctx *ctx_seat, { struct weston_view *view = w_view; struct ivisurface *surf_ctx; + struct iviscreen *scrn_ctx; struct input_context *ctx = ctx_seat->input_ctx; struct seat_focus *st_focus; wl_fixed_t sx, sy; @@ -554,19 +638,23 @@ input_ctrl_ptr_set_west_focus(struct seat_ctx *ctx_seat, if (NULL != pointer->focus) { surf_ctx = input_ctrl_get_surf_ctx_from_surf(ctx, pointer->focus->surface); + + scrn_ctx = input_ctrl_get_scrn_ctx_from_output(ctx, + pointer->focus->output); /*Leave existing pointer focus*/ input_ctrl_snd_focus_to_controller(surf_ctx, ctx_seat, - ILM_INPUT_DEVICE_POINTER, ILM_FALSE); + ILM_INPUT_DEVICE_POINTER, scrn_ctx, ILM_FALSE); } if (NULL != view) { surf_ctx = input_ctrl_get_surf_ctx_from_surf(ctx, view->surface); + scrn_ctx = input_ctrl_get_scrn_ctx_from_output(ctx, view->output); if (NULL != surf_ctx) { /*Enter into new pointer focus is seat accepts*/ st_focus = input_ctrl_snd_focus_to_controller(surf_ctx, - ctx_seat, ILM_INPUT_DEVICE_POINTER, ILM_TRUE); + ctx_seat, ILM_INPUT_DEVICE_POINTER, scrn_ctx, ILM_TRUE); if (st_focus != NULL) { weston_pointer_set_focus(pointer, view, sx, sy); @@ -732,6 +820,7 @@ input_ctrl_touch_set_west_focus(struct seat_ctx *ctx_seat, { /*Weston would have set the focus here*/ struct ivisurface *surf_ctx; + struct iviscreen *scrn_ctx; struct seat_focus *st_focus; if (touch->focus == NULL) @@ -740,10 +829,13 @@ input_ctrl_touch_set_west_focus(struct seat_ctx *ctx_seat, surf_ctx = input_ctrl_get_surf_ctx_from_surf(ctx_seat->input_ctx, touch->focus->surface); + scrn_ctx = input_ctrl_get_scrn_ctx_from_output(ctx_seat->input_ctx, + touch->focus->output); + if (NULL != surf_ctx) { if (touch->num_tp == 1) { st_focus = input_ctrl_snd_focus_to_controller(surf_ctx, ctx_seat, - ILM_INPUT_DEVICE_TOUCH, ILM_TRUE); + ILM_INPUT_DEVICE_TOUCH, scrn_ctx, ILM_TRUE); } else { st_focus = get_accepted_seat(surf_ctx, ctx_seat); } @@ -796,14 +888,18 @@ input_ctrl_touch_clear_focus(struct seat_ctx *ctx_seat) struct input_context *ctx = ctx_seat->input_ctx; struct weston_touch *touch = ctx_seat->touch_grab.touch; struct ivisurface *surf_ctx; + struct iviscreen *scrn_ctx; if (touch->focus != NULL) { surf_ctx = input_ctrl_get_surf_ctx_from_surf(ctx, touch->focus->surface); + scrn_ctx = input_ctrl_get_scrn_ctx_from_output(ctx, + touch->focus->output); + input_ctrl_snd_focus_to_controller(surf_ctx, ctx_seat, - ILM_INPUT_DEVICE_TOUCH, ILM_FALSE); + ILM_INPUT_DEVICE_TOUCH, scrn_ctx, ILM_FALSE); input_ctrl_touch_west_send_cancel(touch); @@ -833,14 +929,18 @@ touch_grab_up(struct weston_touch_grab *grab, const struct timespec *time, struct input_context *ctx = seat->input_ctx; struct weston_touch *touch = grab->touch; struct ivisurface *surf_ctx; + struct iviscreen *scrn_ctx; if (NULL != touch->focus) { if (touch->num_tp == 0) { surf_ctx = input_ctrl_get_surf_ctx_from_surf(ctx, touch->focus->surface); + scrn_ctx = input_ctrl_get_scrn_ctx_from_output(ctx, + touch->focus->output); + input_ctrl_snd_focus_to_controller(surf_ctx, - seat, ILM_INPUT_DEVICE_TOUCH, ILM_FALSE); + seat, ILM_INPUT_DEVICE_TOUCH, scrn_ctx, ILM_FALSE); } weston_touch_send_up(touch, time, touch_id); } @@ -1031,6 +1131,43 @@ input_ctrl_free_surf_ctx(struct input_context *ctx, struct ivisurface *surf_ctx) } } +static void +advertise_input_focus_change_for_surface(struct input_context *ctx, + struct ivisurface *surf, bool status) +{ + const struct ivi_layout_interface *interface = + ctx->ivishell->interface; + struct weston_surface * weston_surface = + interface->surface_get_weston_surface( + surf->layout_surface); + + struct iviscreen *scrn = input_ctrl_get_scrn_ctx_from_surface( + ctx, weston_surface); + struct seat_focus *st_focus; + struct seat_ctx *seat_ctx; + ilmInputDevice device; + + wl_list_for_each(st_focus, &surf->accepted_seat_list, link) { + seat_ctx = st_focus->seat_ctx; + device = st_focus->focus; + + if (device & ILM_INPUT_DEVICE_POINTER) { + send_input_focus(surf, seat_ctx, ILM_INPUT_DEVICE_POINTER, + scrn, status); + } + + if (device & ILM_INPUT_DEVICE_KEYBOARD) { + send_input_focus(surf, seat_ctx, ILM_INPUT_DEVICE_KEYBOARD, + scrn, status); + } + + if (device & ILM_INPUT_DEVICE_TOUCH) { + send_input_focus(surf, seat_ctx, ILM_INPUT_DEVICE_TOUCH, + scrn, status); + } + } +} + static void handle_surface_destroy(struct wl_listener *listener, void *data) { @@ -1038,8 +1175,10 @@ handle_surface_destroy(struct wl_listener *listener, void *data) wl_container_of(listener, ctx, surface_destroyed); struct ivisurface *surf = (struct ivisurface *) data; - if (NULL != surf) + if (NULL != surf) { + advertise_input_focus_change_for_surface(ctx, surf, false); input_ctrl_free_surf_ctx(ctx, surf); + } } static void @@ -1074,8 +1213,12 @@ setup_input_focus(struct input_context *ctx, uint32_t surface, uint32_t device, int32_t enabled) { struct ivisurface *surf = NULL; + struct iviscreen *scrn = NULL; struct seat_focus *st_focus; struct seat_ctx *ctx_seat; + struct weston_surface *weston_surface; + const struct ivi_layout_interface *interface = + ctx->ivishell->interface; surf = input_ctrl_get_surf_ctx_from_id(ctx, surface); if (NULL != surf) { @@ -1092,7 +1235,12 @@ setup_input_focus(struct input_context *ctx, uint32_t surface, /*Touch focus cannot be forced to a particular surface. * Preserve the old behaviour by sending it to controller. * TODO: Should we just remove focus setting for touch?*/ - send_input_focus(ctx, surf, device, enabled); + weston_surface = interface->surface_get_weston_surface( + surf->layout_surface); + + scrn = input_ctrl_get_scrn_ctx_from_surface(ctx, + weston_surface); + send_input_focus(surf, ctx_seat, device, scrn, enabled); } } } @@ -1208,15 +1356,17 @@ bind_ivi_input(struct wl_client *client, void *data, { struct input_context *ctx = data; struct weston_seat *seat; + struct weston_surface *weston_surface; struct wl_resource *resource; struct ivisurface *ivisurface; + struct iviscreen *iviscreen = NULL; const struct ivi_layout_interface *interface = ctx->ivishell->interface; struct seat_focus *st_focus; uint32_t ivi_surf_id; int32_t is_default_seat = ILM_FALSE; - resource = wl_resource_create(client, &ivi_input_interface, 1, id); + resource = wl_resource_create(client, &ivi_input_interface, version, id); wl_resource_set_implementation(resource, &input_implementation, ctx, unbind_resource_controller); @@ -1232,11 +1382,30 @@ bind_ivi_input(struct wl_client *client, void *data, /* Send focus and acceptance events for all known surfaces to the client */ wl_list_for_each(ivisurface, &ctx->ivishell->list_surface, link) { ivi_surf_id = interface->get_id_of_surface(ivisurface->layout_surface); + weston_surface = interface->surface_get_weston_surface( + ivisurface->layout_surface); + wl_list_for_each(st_focus, &ivisurface->accepted_seat_list, link) { + seat = st_focus->seat_ctx->west_seat; + ivi_input_send_input_focus(resource, ivi_surf_id, st_focus->focus, ILM_TRUE); + + if (wl_resource_get_version(resource) >= + IVI_INPUT_INPUT_FOCUS_CHANGE_SINCE_VERSION) { + iviscreen = input_ctrl_get_scrn_ctx_from_surface(ctx, + weston_surface); + /* set screen ID as INAVLID_ID when there are multiple views + * associated with the surface. + */ + ivi_input_send_input_focus_change(resource, ivi_surf_id, + seat->seat_name, st_focus->focus, + iviscreen != NULL ? iviscreen->id_screen : INVALID_ID, + ILM_TRUE); + } + ivi_input_send_input_acceptance(resource, ivi_surf_id, - st_focus->seat_ctx->west_seat->seat_name, + seat->seat_name, ILM_TRUE); } } diff --git a/ivi-layermanagement-api/ilmCommon/include/ilm_types.h b/ivi-layermanagement-api/ilmCommon/include/ilm_types.h index 64e30a71..4d903a3d 100644 --- a/ivi-layermanagement-api/ilmCommon/include/ilm_types.h +++ b/ivi-layermanagement-api/ilmCommon/include/ilm_types.h @@ -316,4 +316,27 @@ typedef ilmErrorTypes(*screenshotDoneNotificationFunc)(void *user_data, typedef void(*screenshotErrorNotificationFunc)(void *user_data, t_ilm_uint error, const char *message); + +/** + * Typedef for notification callback on input focus change. + * Callback parameters: + * surface_id : surface id on which the input device focus change happened. + * device : one of the touch, pointer and keyboard devices. + * seatName : seat to which the device is assigned to. This pointer + * is freed by ilm library after callback returns. + * screen_id : screen_id on which this focus change happened. This + * makes sense only for pointer and touch devices. For + * keyboard, this parameter is set to INVALID_ID which is 0xFFFFFFFF. + * status : set to true if focus is moved into the surface and false + * if focus is moved out of the surface + * user_data : This is the parameter passed to ilm_registerInputFocusNotification + * API. + */ +typedef void (*inputFocusNotificationFunc)(t_ilm_surface surface_id, + ilmInputDevice device, + t_ilm_string seat_name, + t_ilm_display screen_id, + t_ilm_bool status, + void* user_data); + #endif /* _ILM_TYPES_H_*/ diff --git a/ivi-layermanagement-api/ilmControl/include/ilm_control.h b/ivi-layermanagement-api/ilmControl/include/ilm_control.h index c67152a7..a8662073 100644 --- a/ivi-layermanagement-api/ilmControl/include/ilm_control.h +++ b/ivi-layermanagement-api/ilmControl/include/ilm_control.h @@ -473,6 +473,26 @@ ilmErrorTypes ilm_registerNotification(notificationFunc callback, void *user_dat */ ilmErrorTypes ilm_unregisterNotification(); +/** + * \brief register for notification on change of focus surface for Touch, Pointer and keyboard + * \ingroup ilmControl + * \param[in] callback pointer to function to be called for notification + * \param[in] user_data pointer to user defined data + * \return ILM_SUCCESS if the method call was successful + * \return ILM_FAILED if the client can not call the method on the service. + * \return ILM_ERROR_INVALID_ARGUMENT if the current process already has notification callback registered + */ +ilmErrorTypes ilm_registerInputFocusNotification(inputFocusNotificationFunc callback, void *user_data); + +/** + * \brief remove notification on change of focus surface for Touch, Pointer and keyboard + * \ingroup ilmControl + * \return ILM_SUCCESS if the method call was successful + * \return ILM_FAILED if the client can not call the method on the service. + * \return ILM_ERROR_INVALID_ARGUMENT if the current process has no notification callback registered + */ +ilmErrorTypes ilm_unregisterInputFocusNotification(); + /** * \brief returns the global error flag. * When compositor sends an error, the error flag is set to appropriate error code diff --git a/ivi-layermanagement-api/ilmControl/include/ilm_control_platform.h b/ivi-layermanagement-api/ilmControl/include/ilm_control_platform.h index 5053b194..68636d32 100644 --- a/ivi-layermanagement-api/ilmControl/include/ilm_control_platform.h +++ b/ivi-layermanagement-api/ilmControl/include/ilm_control_platform.h @@ -46,6 +46,11 @@ struct wayland_context { ilmErrorTypes error_flag; struct ivi_input *input_controller; + + struct { + inputFocusNotificationFunc callback; + void *user_data; + } input_focus_notification; }; struct ilm_control_context { diff --git a/ivi-layermanagement-api/ilmControl/src/ilm_control_wayland_platform.c b/ivi-layermanagement-api/ilmControl/src/ilm_control_wayland_platform.c index bed3c8dc..231a0c5d 100644 --- a/ivi-layermanagement-api/ilmControl/src/ilm_control_wayland_platform.c +++ b/ivi-layermanagement-api/ilmControl/src/ilm_control_wayland_platform.c @@ -815,17 +815,7 @@ input_listener_input_focus(void *data, struct ivi_input *ivi_input, uint32_t surface, uint32_t device, int32_t enabled) { - struct wayland_context *ctx = data; - struct surface_context *surf_ctx; - wl_list_for_each(surf_ctx, &ctx->list_surface, link) { - if (surface != surf_ctx->id_surface) - continue; - - if (enabled == ILM_TRUE) - surf_ctx->prop.focus |= device; - else - surf_ctx->prop.focus &= ~device; - } +/* XXX: deprecated */ } static void @@ -889,12 +879,42 @@ input_listener_input_acceptance(void *data, wl_list_insert(&surface_ctx->list_accepted_seats, &accepted_seat->link); } +static void +input_listener_input_focus_change(void *data, + struct ivi_input *ivi_input, + uint32_t surface, const char *seat, + uint32_t device, uint32_t screen, + int32_t enabled) +{ + struct wayland_context *ctx = data; + struct surface_context *surf_ctx; + + wl_list_for_each(surf_ctx, &ctx->list_surface, link) { + if (surface != surf_ctx->id_surface) + continue; + + if (enabled == ILM_TRUE) + surf_ctx->prop.focus |= device; + else + surf_ctx->prop.focus &= ~device; + } + + // enabled = true, focus changed to surface + // enabled = false, focus changed from surface + if (ctx->input_focus_notification.callback) + ctx->input_focus_notification.callback( + surface, device, (char *) seat, + screen, enabled, + ctx->input_focus_notification.user_data); +} + static struct ivi_input_listener input_listener = { input_listener_seat_created, input_listener_seat_capabilities, input_listener_seat_destroyed, input_listener_input_focus, - input_listener_input_acceptance + input_listener_input_acceptance, + input_listener_input_focus_change }; static void @@ -1110,6 +1130,53 @@ ilmControl_registerShutdownNotification(shutdownNotificationFunc callback, void return returnValue; } +ILM_EXPORT ilmErrorTypes +ilm_registerInputFocusNotification(inputFocusNotificationFunc callback, void *user_data) +{ + ilmErrorTypes returnValue = ILM_FAILED; + struct ilm_control_context *ctx = sync_and_acquire_instance(); + + if (!callback) { + fprintf(stderr, "[Error] focusNotificationFunc is invalid\n"); + goto error; + } + + if (ctx->wl.input_focus_notification.callback) { + fprintf(stderr, "[Error] input focus notification is already registered \n"); + goto error; + } + + ctx->wl.input_focus_notification.callback = callback; + ctx->wl.input_focus_notification.user_data = user_data; + + returnValue = ILM_SUCCESS; + +error: + release_instance(); + return returnValue; +} + +ILM_EXPORT ilmErrorTypes +ilm_unregisterInputFocusNotification() +{ + ilmErrorTypes returnValue = ILM_FAILED; + struct ilm_control_context *ctx = sync_and_acquire_instance(); + + if (!ctx->wl.input_focus_notification.callback) { + fprintf(stderr, "[Error] input focus notification is not registered \n"); + goto error; + } + + ctx->wl.input_focus_notification.callback = NULL; + ctx->wl.input_focus_notification.user_data = NULL; + + returnValue = ILM_SUCCESS; + +error: + release_instance(); + return returnValue; +} + ILM_EXPORT void ilmControl_destroy(void) { @@ -1295,6 +1362,9 @@ init_control(void) struct screen_context *ctx_scrn; int ret = 0; + wl->input_focus_notification.callback = NULL; + wl->input_focus_notification.user_data = NULL; + wl->queue = wl_display_create_queue(wl->display); if (! wl->queue) { fprintf(stderr, "Could not create wayland event queue\n"); diff --git a/ivi-layermanagement-examples/layer-add-surfaces/src/layer-add-surfaces.c b/ivi-layermanagement-examples/layer-add-surfaces/src/layer-add-surfaces.c index a271da2c..39f41339 100644 --- a/ivi-layermanagement-examples/layer-add-surfaces/src/layer-add-surfaces.c +++ b/ivi-layermanagement-examples/layer-add-surfaces/src/layer-add-surfaces.c @@ -125,6 +125,21 @@ static void shutdownCallbackFunction(t_ilm_shutdown_error_type error_type, exit(1); } +static void inputFocusCallbackFunction(t_ilm_surface surface_id, ilmInputDevice device, + t_ilm_string seat_name, t_ilm_uint screen_id, + t_ilm_bool status, void* user_data) +{ + (void) user_data; + + printf("layer-add-surfaces: input focus change event: %s device '%s' %s on " + "surface %d of screen %d \n", + device == ILM_INPUT_DEVICE_KEYBOARD ? "keyboard" : + device == ILM_INPUT_DEVICE_POINTER ? "pointer" : + device == ILM_INPUT_DEVICE_TOUCH ? "touch" : "unknown", + seat_name, status ? "enabled" : "disabled", + surface_id, screen_id); +} + /* Choose the display with the largest resolution.*/ static t_ilm_uint choose_screen(void) { @@ -266,6 +281,11 @@ int main (int argc, char *argv[]) ilm_registerShutdownNotification(shutdownCallbackFunction, NULL); + if (ilm_registerInputFocusNotification(inputFocusCallbackFunction, NULL) != ILM_SUCCESS) { + fprintf(stderr, "layer-add-surfaces: failed to register for input focus" + " change notification\n"); + } + screen_ID = choose_screen(); ilm_layerCreateWithDimension(&layer, screenWidth, screenHeight); printf("layer-add-surfaces: layer (%d) destination region: x:0 y:0 w:%u h:%u\n", layer, screenWidth, screenHeight); @@ -280,6 +300,11 @@ int main (int argc, char *argv[]) pthread_cond_wait( &waiterVariable, &mutex); } + if (ilm_unregisterInputFocusNotification() != ILM_SUCCESS) { + fprintf(stderr, "layer-add-surfaces: failed to unregister for input focus" + " change notification\n"); + } + ilm_unregisterNotification(); ilm_destroy(); diff --git a/protocol/ivi-input.xml b/protocol/ivi-input.xml index 50eb19d8..74f6ee29 100644 --- a/protocol/ivi-input.xml +++ b/protocol/ivi-input.xml @@ -97,5 +97,25 @@ + + + + + + The new input focus state is provided in argument enabled: + If enabled is ILM_TRUE, this surface now has input focus enabled. + If enabled is not ILM_TRUE, this surface no longer has input focus. + Additionaly the event indicates: + - the seat whose focus has changed. + - the screen on which the focus change happened. (which is relevant + only for pointer and touch devices, and set to INVALID_ID for + keyboard devices) + + + + + + + diff --git a/weston-ivi-shell/src/ivi-controller.c b/weston-ivi-shell/src/ivi-controller.c index b68f992c..4bf9d16a 100644 --- a/weston-ivi-shell/src/ivi-controller.c +++ b/weston-ivi-shell/src/ivi-controller.c @@ -48,7 +48,6 @@ #define IVI_CLIENT_ENABLE_CURSOR_ENV_NAME "IVI_CLIENT_ENABLE_CURSOR" struct ivilayer; -struct iviscreen; struct notification { struct wl_list link; @@ -65,14 +64,6 @@ struct ivilayer { struct wl_list notification_list; }; -struct iviscreen { - struct wl_list link; - struct ivishell *shell; - uint32_t id_screen; - struct weston_output *output; - struct wl_list resource_list; -}; - struct ivicontroller { struct wl_resource *resource; uint32_t id; diff --git a/weston-ivi-shell/src/ivi-controller.h b/weston-ivi-shell/src/ivi-controller.h index 67599bd1..40e06b53 100644 --- a/weston-ivi-shell/src/ivi-controller.h +++ b/weston-ivi-shell/src/ivi-controller.h @@ -54,6 +54,14 @@ struct ivisurface { struct wl_list accepted_seat_list; }; +struct iviscreen { + struct wl_list link; + struct ivishell *shell; + uint32_t id_screen; + struct weston_output *output; + struct wl_list resource_list; +}; + struct ivishell { struct weston_compositor *compositor; const struct ivi_layout_interface *interface;