[PATCH 18/18] text: Move input_panel interface to input-method
Jan Arne Petersen
jpetersen at openismus.com
Wed Jan 16 12:26:55 PST 2013
From: Jan Arne Petersen <jpetersen at openismus.com>
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 at openismus.com>
---
clients/keyboard.c | 11 ++--
protocol/desktop-shell.xml | 18 ------
protocol/input-method.xml | 24 ++++++++
src/shell.c | 141 ++++++++++++++++++++++++++++++++++-----------
4 files changed, 138 insertions(+), 56 deletions(-)
diff --git a/clients/keyboard.c b/clients/keyboard.c
index 564afef..986dcff 100644
--- a/clients/keyboard.c
+++ b/clients/keyboard.c
@@ -31,8 +31,6 @@
#include "window.h"
#include "input-method-client-protocol.h"
#include "text-client-protocol.h"
-#include "desktop-shell-client-protocol.h"
-
struct virtual_keyboard {
struct input_panel *input_panel;
@@ -641,6 +639,7 @@ keyboard_create(struct output *output, struct virtual_keyboard *virtual_keyboard
{
struct keyboard *keyboard;
const struct layout *layout;
+ struct input_panel_surface *ips;
layout = get_current_layout(virtual_keyboard);
@@ -664,9 +663,11 @@ keyboard_create(struct output *output, struct virtual_keyboard *virtual_keyboard
layout->columns * key_width,
layout->rows * key_height);
- input_panel_set_surface(virtual_keyboard->input_panel,
- window_get_wl_surface(keyboard->window),
- output_get_wl_output(output));
+
+ ips = input_panel_get_input_panel_surface(virtual_keyboard->input_panel,
+ window_get_wl_surface(keyboard->window));
+
+ input_panel_surface_set_toplevel(ips, INPUT_PANEL_SURFACE_POSITION_CENTER_BOTTOM);
}
static void
diff --git a/protocol/desktop-shell.xml b/protocol/desktop-shell.xml
index 2b6afbd..d48c3dd 100644
--- a/protocol/desktop-shell.xml
+++ b/protocol/desktop-shell.xml
@@ -98,22 +98,4 @@
</request>
</interface>
-
- <interface name="input_panel" version="1">
- <description summary="interface for implementing keyboards">
- Only one client can bind this interface at a time.
- </description>
-
- <request name="set_surface">
- <description summary="set the surface type as a keyboard">
- A keybaord surface is only shown, when a text model is active
- </description>
-
- <arg name="surface" type="object" interface="wl_surface"/>
- <arg name="output" type="object" interface="wl_output"/>
- </request>
-
- </interface>
-
-
</protocol>
diff --git a/protocol/input-method.xml b/protocol/input-method.xml
index d23b0b8..b4ffa72 100644
--- a/protocol/input-method.xml
+++ b/protocol/input-method.xml
@@ -157,4 +157,28 @@
<arg name="context" type="object" interface="input_method_context"/>
</event>
</interface>
+
+ <interface name="input_panel" version="1">
+ <description summary="interface for implementing keyboards">
+ Only one client can bind this interface at a time.
+ </description>
+
+ <request name="get_input_panel_surface">
+ <arg name="id" type="new_id" interface="input_panel_surface"/>
+ <arg name="surface" type="object" interface="wl_surface"/>
+ </request>
+ </interface>
+
+ <interface name="input_panel_surface" version="1">
+ <enum name="position">
+ <entry name="center_bottom" value="0"/>
+ </enum>
+
+ <request name="set_toplevel">
+ <description summary="set the surface type as a keyboard">
+ A keybaord surface is only shown, when a text model is active
+ </description>
+ <arg name="position" type="uint"/>
+ </request>
+ </interface>
</protocol>
diff --git a/src/shell.c b/src/shell.c
index 898d228..a3b9d4c 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 {
@@ -3245,59 +3250,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
--
1.8.1
More information about the wayland-devel
mailing list