diff options
author | Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> | 2014-04-04 13:07:43 +0900 |
---|---|---|
committer | Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp> | 2014-04-04 13:13:34 +0900 |
commit | 90d80dd175856fed6fc63a8bb93b57a66d1af0a6 (patch) | |
tree | ecfa5d32e82d73f05b02ba327bd141d07a7caef9 | |
parent | dd73ccdbc3293debb34f01e5384f70e92daaac02 (diff) | |
download | weston-90d80dd175856fed6fc63a8bb93b57a66d1af0a6.tar.gz |
Reference implmeentation of input panel for ivi-shell.
The basement of this code is from input-panel.c of desktop shell.
Signed-off-by: Nobuhiko Tanibata <NOBUHIKO_TANIBATA@xddp.denso.co.jp>
-rw-r--r-- | ivi-shell/Makefile.am | 2 | ||||
-rw-r--r-- | ivi-shell/input-panel-ivi.c | 359 | ||||
-rw-r--r-- | ivi-shell/ivi-shell.c | 48 | ||||
-rw-r--r-- | ivi-shell/ivi-shell.h | 64 | ||||
-rw-r--r-- | ivi-shell/weston-layout.c | 42 | ||||
-rw-r--r-- | ivi-shell/weston.ini.in | 3 |
6 files changed, 479 insertions, 39 deletions
diff --git a/ivi-shell/Makefile.am b/ivi-shell/Makefile.am index 333abb70..41f3bb40 100644 --- a/ivi-shell/Makefile.am +++ b/ivi-shell/Makefile.am @@ -35,7 +35,9 @@ ivi_shell_la_LDFLAGS = -module -avoid-version ivi_shell_la_LIBADD = $(COMPOSITOR_LIBS) $(IVI_SHELL_LIBS) ./libweston-layout.la ivi_shell_la_CFLAGS = $(GCC_CFLAGS) $(COMPOSITOR_CFLAGS) $(IVI_SHELL_CFLAGS) ivi_shell_la_SOURCES = \ + ivi-shell.h \ ivi-shell.c \ + input-panel-ivi.c \ weston-layout.h \ ivi-application-protocol.c \ ivi-application-server-protocol.h diff --git a/ivi-shell/input-panel-ivi.c b/ivi-shell/input-panel-ivi.c new file mode 100644 index 00000000..061e78e7 --- /dev/null +++ b/ivi-shell/input-panel-ivi.c @@ -0,0 +1,359 @@ +/* + * Copyright © 2010-2012 Intel Corporation + * Copyright © 2011-2012 Collabora, Ltd. + * Copyright © 2013 Raspberry Pi Foundation + * Copyright © 2013 DENSO CORPORATION + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The copyright holders make + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "config.h" + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "ivi-shell.h" +#include "input-method-server-protocol.h" +#include "weston-layout.h" + +struct input_panel_surface { + struct wl_resource *resource; + struct wl_signal destroy_signal; + + struct ivi_shell *shell; + + struct wl_list link; + struct weston_surface *surface; + struct weston_view *view; + struct wl_listener surface_destroy_listener; + + struct weston_output *output; + uint32_t panel; +}; + +static void +show_input_panels(struct wl_listener *listener, void *data) +{ + struct ivi_shell *shell = + container_of(listener, struct ivi_shell, + show_input_panel_listener); + struct input_panel_surface *ipsurf, *next; + + shell->text_input.surface = (struct weston_surface*)data; + + if (shell->showing_input_panels) + return; + + shell->showing_input_panels = true; + + if (!shell->locked) + wl_list_insert(&shell->panel_layer.link, + &shell->input_panel_layer.link); + + wl_list_for_each_safe(ipsurf, next, + &shell->input_panel.surfaces, link) { + if (ipsurf->surface->width == 0) + continue; + wl_list_insert(&shell->input_panel_layer.view_list, + &ipsurf->view->layer_link); + weston_view_geometry_dirty(ipsurf->view); + weston_view_update_transform(ipsurf->view); + weston_surface_damage(ipsurf->surface); + weston_slide_run(ipsurf->view, ipsurf->surface->height * 0.9, + 0, NULL, NULL); + } +} + +static void +hide_input_panels(struct wl_listener *listener, void *data) +{ + struct ivi_shell *shell = + container_of(listener, struct ivi_shell, + hide_input_panel_listener); + struct weston_view *view, *next; + + if (!shell->showing_input_panels) + return; + + shell->showing_input_panels = false; + + if (!shell->locked) + wl_list_remove(&shell->input_panel_layer.link); + + wl_list_for_each_safe(view, next, + &shell->input_panel_layer.view_list, layer_link) + weston_view_unmap(view); +} + +static void +update_input_panels(struct wl_listener *listener, void *data) +{ + struct ivi_shell *shell = + container_of(listener, struct ivi_shell, + update_input_panel_listener); + + memcpy(&shell->text_input.cursor_rectangle, data, sizeof(pixman_box32_t)); +} + +static void +input_panel_configure(struct weston_surface *surface, int32_t sx, int32_t sy) +{ + struct input_panel_surface *ip_surface = surface->configure_private; + struct ivi_shell *shell = ip_surface->shell; + struct weston_view *view; + float x, y; + + if (surface->width == 0) + return; + + if (ip_surface->panel) { + view = get_default_view(shell->text_input.surface); + if (view == NULL) + return; + x = view->geometry.x + shell->text_input.cursor_rectangle.x2; + y = view->geometry.y + shell->text_input.cursor_rectangle.y2; + } else { + x = ip_surface->output->x + (ip_surface->output->width - surface->width) / 2; + y = ip_surface->output->y + ip_surface->output->height - surface->height; + } + + weston_view_set_position(ip_surface->view, x, y); + + if (!weston_surface_is_mapped(surface) && shell->showing_input_panels) { + wl_list_insert(&shell->input_panel_layer.view_list, + &ip_surface->view->layer_link); + weston_view_update_transform(ip_surface->view); + weston_surface_damage(surface); + weston_slide_run(ip_surface->view, ip_surface->view->surface->height * 0.9, 0, NULL, NULL); + } +} + +static void +destroy_input_panel_surface(struct input_panel_surface *input_panel_surface) +{ + wl_signal_emit(&input_panel_surface->destroy_signal, input_panel_surface); + + wl_list_remove(&input_panel_surface->surface_destroy_listener.link); + wl_list_remove(&input_panel_surface->link); + + input_panel_surface->surface->configure = NULL; + weston_view_destroy(input_panel_surface->view); + + free(input_panel_surface); +} + +static struct input_panel_surface * +get_input_panel_surface(struct weston_surface *surface) +{ + if (surface->configure == input_panel_configure) { + return surface->configure_private; + } else { + return NULL; + } +} + +static void +input_panel_handle_surface_destroy(struct wl_listener *listener, void *data) +{ + struct input_panel_surface *ipsurface = container_of(listener, + struct input_panel_surface, + surface_destroy_listener); + + if (ipsurface->resource) { + wl_resource_destroy(ipsurface->resource); + } else { + destroy_input_panel_surface(ipsurface); + } +} + +static struct input_panel_surface * +create_input_panel_surface(struct ivi_shell *shell, + struct weston_surface *surface) +{ + struct input_panel_surface *input_panel_surface; + + input_panel_surface = calloc(1, sizeof *input_panel_surface); + if (!input_panel_surface) + return NULL; + + surface->configure = input_panel_configure; + surface->configure_private = input_panel_surface; + + input_panel_surface->shell = shell; + + input_panel_surface->surface = surface; + input_panel_surface->view = weston_view_create(surface); + + wl_signal_init(&input_panel_surface->destroy_signal); + input_panel_surface->surface_destroy_listener.notify = input_panel_handle_surface_destroy; + wl_signal_add(&surface->destroy_signal, + &input_panel_surface->surface_destroy_listener); + + wl_list_init(&input_panel_surface->link); + + return input_panel_surface; +} + +static void +input_panel_surface_set_toplevel(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *output_resource, + uint32_t position) +{ + struct input_panel_surface *input_panel_surface = + wl_resource_get_user_data(resource); + struct ivi_shell *shell = input_panel_surface->shell; + + wl_list_insert(&shell->input_panel.surfaces, + &input_panel_surface->link); + + input_panel_surface->output = wl_resource_get_user_data(output_resource); + input_panel_surface->panel = 0; +} + +static void +input_panel_surface_set_overlay_panel(struct wl_client *client, + struct wl_resource *resource) +{ + struct input_panel_surface *input_panel_surface = + wl_resource_get_user_data(resource); + struct ivi_shell *shell = input_panel_surface->shell; + + wl_list_insert(&shell->input_panel.surfaces, + &input_panel_surface->link); + + input_panel_surface->panel = 1; +} + +static const struct wl_input_panel_surface_interface input_panel_surface_implementation = { + input_panel_surface_set_toplevel, + input_panel_surface_set_overlay_panel +}; + +static void +destroy_input_panel_surface_resource(struct wl_resource *resource) +{ + struct input_panel_surface *ipsurf = + wl_resource_get_user_data(resource); + + destroy_input_panel_surface(ipsurf); +} + +static void +input_panel_get_input_panel_surface(struct wl_client *client, + struct wl_resource *resource, + uint32_t id, + struct wl_resource *surface_resource) +{ + struct weston_surface *surface = + wl_resource_get_user_data(surface_resource); + struct ivi_shell *shell = wl_resource_get_user_data(resource); + struct input_panel_surface *ipsurf; + + if (get_input_panel_surface(surface)) { + wl_resource_post_error(surface_resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "wl_input_panel::get_input_panel_surface already requested"); + return; + } + + ipsurf = create_input_panel_surface(shell, surface); + if (!ipsurf) { + wl_resource_post_error(surface_resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "surface->configure already set"); + return; + } + + ipsurf->resource = + wl_resource_create(client, + &wl_input_panel_surface_interface, 1, id); + wl_resource_set_implementation(ipsurf->resource, + &input_panel_surface_implementation, + ipsurf, + destroy_input_panel_surface_resource); +} + +static const struct wl_input_panel_interface input_panel_implementation = { + input_panel_get_input_panel_surface +}; + +static void +unbind_input_panel(struct wl_resource *resource) +{ + struct ivi_shell *shell = wl_resource_get_user_data(resource); + + shell->input_panel.binding = NULL; +} + +static void +bind_input_panel(struct wl_client *client, + void *data, uint32_t version, uint32_t id) +{ + struct ivi_shell *shell = data; + struct wl_resource *resource; + + resource = wl_resource_create(client, + &wl_input_panel_interface, 1, id); + + if (shell->input_panel.binding == NULL) { + wl_resource_set_implementation(resource, + &input_panel_implementation, + shell, unbind_input_panel); + shell->input_panel.binding = resource; + return; + } + + wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT, + "interface object already bound"); + wl_resource_destroy(resource); +} + +void +input_panel_destroy(struct ivi_shell *shell) +{ + wl_list_remove(&shell->show_input_panel_listener.link); + wl_list_remove(&shell->hide_input_panel_listener.link); +} + +int +input_panel_setup(struct ivi_shell *shell) +{ + struct weston_compositor *ec = shell->compositor; + + shell->show_input_panel_listener.notify = show_input_panels; + wl_signal_add(&ec->show_input_panel_signal, + &shell->show_input_panel_listener); + shell->hide_input_panel_listener.notify = hide_input_panels; + wl_signal_add(&ec->hide_input_panel_signal, + &shell->hide_input_panel_listener); + shell->update_input_panel_listener.notify = update_input_panels; + wl_signal_add(&ec->update_input_panel_signal, + &shell->update_input_panel_listener); + + wl_list_init(&shell->input_panel.surfaces); + + if (wl_global_create(shell->compositor->wl_display, + &wl_input_panel_interface, 1, + shell, bind_input_panel) == NULL) + return -1; + + return 0; +} diff --git a/ivi-shell/ivi-shell.c b/ivi-shell/ivi-shell.c index 31d39ccf..ae8d06eb 100644 --- a/ivi-shell/ivi-shell.c +++ b/ivi-shell/ivi-shell.c @@ -39,12 +39,10 @@ #include <string.h> #include <linux/input.h> -#include "compositor.h" +#include "ivi-shell.h" #include "ivi-application-server-protocol.h" #include "weston-layout.h" -struct ivi_shell; - struct ivi_shell_surface { struct ivi_shell *shell; @@ -59,16 +57,6 @@ struct ivi_shell_surface struct wl_list link; }; -struct ivi_shell -{ - struct wl_resource *resource; - struct wl_listener destroy_listener; - - struct weston_compositor *compositor; - - struct wl_list ivi_surface_list; /* struct ivi_shell_surface::link */ -}; - /* ------------------------------------------------------------------------- */ /* common functions */ /* ------------------------------------------------------------------------- */ @@ -255,6 +243,29 @@ bind_ivi_application(struct wl_client *client, shell, NULL); } +struct weston_view * +get_default_view(struct weston_surface *surface) +{ + struct ivi_shell_surface *shsurf; + struct weston_view *view; + + if (!surface || wl_list_empty(&surface->views)) + return NULL; + + shsurf = get_ivi_shell_surface(surface); + if (shsurf && shsurf->layout_surface) { + view = weston_layout_get_weston_view(shsurf->layout_surface); + if (view) + return view; + } + + wl_list_for_each(view, &surface->views, surface_link) + if (weston_view_is_mapped(view)) + return view; + + return container_of(surface->views.next, struct weston_view, surface_link); +} + /** * Initialization/destruction method of ivi-shell */ @@ -265,6 +276,8 @@ shell_destroy(struct wl_listener *listener, void *data) container_of(listener, struct ivi_shell, destroy_listener); struct ivi_shell_surface *ivisurf, *next; + input_panel_destroy(shell); + wl_list_for_each_safe(ivisurf, next, &shell->ivi_surface_list, link) { wl_list_remove(&ivisurf->link); free(ivisurf); @@ -277,9 +290,10 @@ static void init_ivi_shell(struct weston_compositor *ec, struct ivi_shell *shell) { shell->compositor = ec; - - wl_list_init(&ec->layer_list); wl_list_init(&shell->ivi_surface_list); + + weston_layer_init(&shell->panel_layer, &ec->cursor_layer.link); + weston_layer_init(&shell->input_panel_layer, NULL); } /** @@ -300,11 +314,15 @@ module_init(struct weston_compositor *ec, } init_ivi_shell(ec, shell); + weston_layout_initWithCompositor(ec); shell->destroy_listener.notify = shell_destroy; wl_signal_add(&ec->destroy_signal, &shell->destroy_listener); + if (input_panel_setup(shell) < 0) + return -1; + if (wl_global_create(ec->wl_display, &ivi_application_interface, 1, shell, bind_ivi_application) == NULL) { return -1; diff --git a/ivi-shell/ivi-shell.h b/ivi-shell/ivi-shell.h new file mode 100644 index 00000000..ad94f642 --- /dev/null +++ b/ivi-shell/ivi-shell.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2013 DENSO CORPORATION + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The copyright holders make + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stdbool.h> + +#include "compositor.h" + +struct ivi_shell +{ + struct wl_resource *resource; + struct wl_listener destroy_listener; + + struct weston_compositor *compositor; + + struct wl_list ivi_surface_list; /* struct ivi_shell_surface::link */ + + struct wl_listener show_input_panel_listener; + struct wl_listener hide_input_panel_listener; + struct wl_listener update_input_panel_listener; + + struct weston_layer panel_layer; + struct weston_layer input_panel_layer; + + bool locked; + bool showing_input_panels; + + struct { + struct weston_surface *surface; + pixman_box32_t cursor_rectangle; + } text_input; + + struct { + struct wl_resource *binding; + struct wl_list surfaces; + } input_panel; +}; + +struct weston_view * +get_default_view(struct weston_surface *surface); + +int +input_panel_setup(struct ivi_shell *shell); + +void +input_panel_destroy(struct ivi_shell *shell); diff --git a/ivi-shell/weston-layout.c b/ivi-shell/weston-layout.c index ca76fe6a..1d44d8b8 100644 --- a/ivi-shell/weston-layout.c +++ b/ivi-shell/weston-layout.c @@ -169,7 +169,6 @@ struct weston_layout_layer { uint32_t id_layer; struct weston_layout *layout; - struct weston_layer el; struct weston_layout_LayerProperties prop; uint32_t event_mask; @@ -224,8 +223,7 @@ struct weston_layout { struct wl_list list_configure; } surface_notification; - /* to enable displaying cursor*/ - int32_t is_cursor_enabled; + struct weston_layer layout_layer; }; struct weston_layout ivilayout = {0}; @@ -794,7 +792,6 @@ commit_list_layer(struct weston_layout *layout) static void commit_list_screen(struct weston_layout *layout) { - struct weston_compositor *ec = layout->compositor; struct weston_layout_screen *iviscrn = NULL; struct weston_layout_layer *ivilayer = NULL; struct weston_layout_layer *next = NULL; @@ -823,36 +820,28 @@ commit_list_screen(struct weston_layout *layout) iviscrn->event_mask = 0; } - /* For rendering */ - wl_list_init(&ec->layer_list); + /* Clear view list of layout layer */ + wl_list_init(&layout->layout_layer.view_list); + wl_list_for_each(ivilayer, &iviscrn->order.list_layer, order.link) { - if (ivilayer->prop.visibility == 0) { - continue; - } - wl_list_insert(&ec->layer_list, &ivilayer->el.link); - wl_list_init(&ivilayer->el.view_list); + if (ivilayer->prop.visibility == 0) + continue; wl_list_for_each(ivisurf, &ivilayer->order.list_surface, order.link) { - if (ivisurf->prop.visibility == 0) { - continue; - } - if (ivisurf->surface == NULL || ivisurf->view == NULL) { + if (ivisurf->prop.visibility == 0) + continue; + if (ivisurf->surface == NULL || ivisurf->view == NULL) continue; - } - wl_list_insert(&ivilayer->el.view_list, + wl_list_insert(&layout->layout_layer.view_list, &ivisurf->view->layer_link); + ivisurf->surface->output = iviscrn->output; } } - /*Add cursor layer if cursor is configured.*/ - if (layout->is_cursor_enabled) { - wl_list_insert(&ec->layer_list, &ec->cursor_layer.link); - } - break; } } @@ -928,6 +917,9 @@ weston_layout_initWithCompositor(struct weston_compositor *ec) wl_list_init(&layout->surface_notification.list_remove); wl_list_init(&layout->surface_notification.list_configure); + /* Add layout_layer at the last of weston_compositor.layer_list */ + weston_layer_init(&layout->layout_layer, ec->layer_list.prev); + create_screen(ec); struct weston_config *config = weston_config_parse("weston.ini"); @@ -937,8 +929,10 @@ weston_layout_initWithCompositor(struct weston_compositor *ec) /*A cursor is configured if weston.ini has keys.*/ char* cursor_theme = NULL; weston_config_section_get_string(s, "cursor-theme", &cursor_theme, NULL); - layout->is_cursor_enabled = (NULL != cursor_theme); - free(cursor_theme); + if (cursor_theme) + free(cursor_theme); + else + wl_list_remove(&ec->cursor_layer.link); weston_config_destroy(config); } diff --git a/ivi-shell/weston.ini.in b/ivi-shell/weston.ini.in index c9a6861f..3552604a 100644 --- a/ivi-shell/weston.ini.in +++ b/ivi-shell/weston.ini.in @@ -28,6 +28,9 @@ home-id=1007 workspace-background-color=0x99000000 workspace-background-id=2001 +[input-method] +path=@libexecdir@/weston-keyboard + [ivi-launcher] workspace-id=0 icon=@abs_top_builddir@/data/icon_ivi_flower.png |