text: Move input_panel interface to input-method
authorJan Arne Petersen <jpetersen@openismus.com>
Wed, 16 Jan 2013 20:26:55 +0000 (21:26 +0100)
committerKristian Høgsberg <krh@bitplanet.net>
Fri, 15 Feb 2013 22:05:04 +0000 (17:05 -0500)
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>
clients/keyboard.c
protocol/desktop-shell.xml
protocol/input-method.xml
src/shell.c

index 564afef..986dcff 100644 (file)
@@ -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
index 2b6afbd..d48c3dd 100644 (file)
     </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>
index d23b0b8..b4ffa72 100644 (file)
       <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>
index 1b304e1..4d5a4f3 100644 (file)
@@ -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