diff options
author | Jan Arne Petersen <jpetersen@openismus.com> | 2013-01-16 21:26:55 +0100 |
---|---|---|
committer | Kristian Høgsberg <krh@bitplanet.net> | 2013-02-15 17:05:04 -0500 |
commit | ffbb20f730e63b6d5d1710fa06f37931271f0de0 (patch) | |
tree | e7e77d8516b3f8205bb3dfa4887027a47483646a /src/shell.c | |
parent | 23ccfb3ef95efa4620498db1e5f77ae6c4c273e3 (diff) |
text: Move input_panel interface to input-method
Move the input_panel interface from desktop-shell to input-method (since
it is not really tied to desktop-shell).
Add an input_panel_surface interface like wl_shell_surface to make it
easier to extend it. Also add a parameter to the set_toplevel request to
be able to specify where to show an input panel surface on the screen.
Signed-off-by: Jan Arne Petersen <jpetersen@openismus.com>
Diffstat (limited to 'src/shell.c')
-rw-r--r-- | src/shell.c | 141 |
1 files changed, 108 insertions, 33 deletions
diff --git a/src/shell.c b/src/shell.c index 1b304e1..4d5a4f3 100644 --- a/src/shell.c +++ b/src/shell.c @@ -35,6 +35,7 @@ #include <wayland-server.h> #include "compositor.h" #include "desktop-shell-server-protocol.h" +#include "input-method-server-protocol.h" #include "workspaces-server-protocol.h" #include "../shared/config-parser.h" @@ -65,9 +66,13 @@ struct workspace { }; struct input_panel_surface { + struct wl_resource resource; + + struct desktop_shell *shell; + struct wl_list link; struct weston_surface *surface; - struct wl_listener listener; + struct wl_listener surface_destroy_listener; }; struct desktop_shell { @@ -3282,59 +3287,129 @@ input_panel_configure(struct weston_surface *surface, int32_t sx, int32_t sy) } static void -destroy_input_panel_surface(struct wl_listener *listener, - void *data) +destroy_input_panel_surface(struct input_panel_surface *input_panel_surface) { - struct input_panel_surface *input_panel_surface = - container_of(listener, struct input_panel_surface, listener); - - wl_list_remove(&listener->link); + wl_list_remove(&input_panel_surface->surface_destroy_listener.link); wl_list_remove(&input_panel_surface->link); + input_panel_surface->surface->configure = NULL; + 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->private; + } else { + return NULL; + } +} + static void -input_panel_set_surface(struct wl_client *client, - struct wl_resource *resource, - struct wl_resource *surface_resource, - struct wl_resource *output_resource) +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.client) { + wl_resource_destroy(&ipsurface->resource); + } else { + wl_signal_emit(&ipsurface->resource.destroy_signal, + &ipsurface->resource); + destroy_input_panel_surface(ipsurface); + } +} +static struct input_panel_surface * +create_input_panel_surface(struct desktop_shell *shell, + struct weston_surface *surface) { - struct desktop_shell *shell = resource->data; - struct weston_surface *surface = surface_resource->data; - struct weston_output *output = output_resource->data; 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->private = shell; - surface->output = output; + surface->private = input_panel_surface; - /* Do not do anything when surface is already in the list of - * input panel surfaces - */ - wl_list_for_each(input_panel_surface, &shell->input_panel.surfaces, link) { - if (input_panel_surface->surface == surface) - return; - } - - input_panel_surface = malloc(sizeof *input_panel_surface); - if (!input_panel_surface) { - wl_resource_post_no_memory(resource); - return; - } + input_panel_surface->shell = shell; input_panel_surface->surface = surface; - input_panel_surface->listener.notify = destroy_input_panel_surface; - wl_signal_add(&surface_resource->destroy_signal, - &input_panel_surface->listener); + wl_signal_init(&input_panel_surface->resource.destroy_signal); + input_panel_surface->surface_destroy_listener.notify = input_panel_handle_surface_destroy; + wl_signal_add(&surface->surface.resource.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, + uint32_t position) +{ + struct input_panel_surface *input_panel_surface = resource->data; + struct desktop_shell *shell = input_panel_surface->shell; wl_list_insert(&shell->input_panel.surfaces, &input_panel_surface->link); } +static const struct input_panel_surface_interface input_panel_surface_implementation = { + input_panel_surface_set_toplevel +}; + +static void +destroy_input_panel_surface_resource(struct wl_resource *resource) +{ + struct input_panel_surface *ipsurf = resource->data; + + 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 = surface_resource->data; + struct desktop_shell *shell = resource->data; + struct input_panel_surface *ipsurf; + + if (get_input_panel_surface(surface)) { + wl_resource_post_error(surface_resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "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.destroy = destroy_input_panel_surface_resource; + ipsurf->resource.object.id = id; + ipsurf->resource.object.interface = &input_panel_surface_interface; + ipsurf->resource.object.implementation = + (void (**)(void)) &input_panel_surface_implementation; + ipsurf->resource.data = ipsurf; + + wl_client_add_resource(client, &ipsurf->resource); +} + static const struct input_panel_interface input_panel_implementation = { - input_panel_set_surface + input_panel_get_input_panel_surface }; static void |