diff options
| author | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2014-02-14 12:13:57 +0100 |
|---|---|---|
| committer | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2014-02-14 12:13:57 +0100 |
| commit | a3b3d15a3d3acc3df39615ead685dafcb9371650 (patch) | |
| tree | fe17178d59bca479f75b4c49f723a9baa7f7468f /shell | |
| parent | 933c927284e9cc51d52d6aee8dcdcd18fa228541 (diff) | |
| download | graynard-a3b3d15a3d3acc3df39615ead685dafcb9371650.tar.gz graynard-a3b3d15a3d3acc3df39615ead685dafcb9371650.zip | |
shell-helper: implement interface in weston module
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/Makefile.am | 22 | ||||
| -rw-r--r-- | shell/gtk-shell.c | 12 | ||||
| -rw-r--r-- | shell/shell-helper.c | 255 |
3 files changed, 286 insertions, 3 deletions
diff --git a/shell/Makefile.am b/shell/Makefile.am index dfbf2eb..ca52883 100644 --- a/shell/Makefile.am +++ b/shell/Makefile.am @@ -27,12 +27,16 @@ weston_gtk_shell_SOURCES = \ weston-gtk-shell-resources.h \ desktop-shell-client-protocol.h \ desktop-shell-protocol.c \ + shell-helper-client-protocol.h \ + shell-helper-protocol.c \ $(external_sources) weston_gtk_shell_LDADD = $(GTK_LIBS) BUILT_SOURCES = \ desktop-shell-client-protocol.h \ desktop-shell-protocol.c \ + shell-helper-client-protocol.h \ + shell-helper-protocol.c \ weston-gtk-shell-resources.c \ weston-gtk-shell-resources.h @@ -45,6 +49,24 @@ weston-gtk-shell-resources.h: weston-gtk-shell.gresource.xml $(resource_files) EXTRA_DIST = style.css +# shell-helper weston module +moduledir = $(libdir)/weston +module_LTLIBRARIES = shell-helper.la + +# otherwise shell-helper-protocol.c is generated twice- once with +# libtool and once without +mod-%-protocol.c : $(wayland_protocoldir)/%.xml + $(AM_V_GEN)$(wayland_scanner) code < $< > $@ + +shell_helper_la_LDFLAGS = -module -avoid-version +shell_helper_la_LIBADD = $(GTK_LIBS) +shell_helper_la_SOURCES = \ + shell-helper.c +nodist_shell_helper_la_SOURCES = \ + mod-shell-helper-protocol.c \ + shell-helper-server-protocol.h + +BUILT_SOURCES += $(nodist_shell_helper_la_SOURCES) CLEANFILES = $(BUILT_SOURCES) @wayland_scanner_rules@ diff --git a/shell/gtk-shell.c b/shell/gtk-shell.c index a899a1e..a448947 100644 --- a/shell/gtk-shell.c +++ b/shell/gtk-shell.c @@ -5,6 +5,7 @@ #include <gdk/gdkwayland.h> #include "desktop-shell-client-protocol.h" +#include "shell-helper-client-protocol.h" #include "weston-gtk-shell-resources.h" @@ -28,6 +29,7 @@ struct desktop { struct wl_registry *registry; struct desktop_shell *shell; struct wl_output *output; + struct shell_helper *helper; GdkDisplay *gdk_display; @@ -269,6 +271,9 @@ registry_handle_global(void *data, struct wl_registry *registry, /* TODO: create multiple outputs */ d->output = wl_registry_bind(registry, name, &wl_output_interface, 1); + } else if (!strcmp(interface, "shell_helper")) { + d->helper = wl_registry_bind(registry, name, + &shell_helper_interface, 1); } } @@ -297,6 +302,7 @@ main(int argc, char *argv[]) desktop = malloc(sizeof *desktop); desktop->output = NULL; desktop->shell = NULL; + desktop->helper = NULL; desktop->gdk_display = gdk_display_get_default(); desktop->display = @@ -310,9 +316,9 @@ main(int argc, char *argv[]) wl_registry_add_listener(desktop->registry, ®istry_listener, desktop); - /* Wait until we have been notified about the compositor and shell - * objects */ - while (!desktop->output || !desktop->shell) + /* Wait until we have been notified about the compositor, + * shell, and shell helper objects */ + while (!desktop->output || !desktop->shell || !desktop->helper) wl_display_roundtrip (desktop->display); css_setup(desktop); diff --git a/shell/shell-helper.c b/shell/shell-helper.c new file mode 100644 index 0000000..71e9b6f --- /dev/null +++ b/shell/shell-helper.c @@ -0,0 +1,255 @@ +#include <stdio.h> +#include <assert.h> + +#include <weston/compositor.h> + +#include "shell-helper-server-protocol.h" + +struct shell_helper { + struct weston_compositor *compositor; + + struct wl_listener destroy_listener; + + struct wl_list slide_list; +}; + +static void +shell_helper_move_surface(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *surface_resource, + int32_t x, + int32_t y) +{ + struct shell_helper *helper = wl_resource_get_user_data(resource); + struct weston_surface *surface = + wl_resource_get_user_data(surface_resource); + struct weston_view *view; + + view = container_of(surface->views.next, struct weston_view, surface_link); + + if (!view) + return; + + weston_view_set_position(view, x, y); + weston_view_update_transform(view); +} + +enum SlideState { + SLIDE_STATE_NONE, + SLIDE_STATE_SLIDING_OUT, + SLIDE_STATE_OUT, + SLIDE_STATE_SLIDING_BACK, + SLIDE_STATE_BACK +}; + +enum SlideRequest { + SLIDE_REQUEST_NONE, + SLIDE_REQUEST_OUT, + SLIDE_REQUEST_BACK +}; + +struct slide { + struct weston_surface *surface; + struct weston_view *view; + int x; + int y; + + enum SlideState state; + enum SlideRequest request; + + struct weston_transform transform; + + struct wl_list link; +}; + +static void slide_back(struct slide *slide); + +static void +slide_done_cb(struct weston_view_animation *animation, void *data) +{ + struct slide *slide = data; + + slide->state = SLIDE_STATE_OUT; + + wl_list_insert(&slide->view->transform.position.link, + &slide->transform.link); + weston_matrix_init(&slide->transform.matrix); + weston_matrix_translate(&slide->transform.matrix, + slide->x, + slide->y, + 0); + + weston_view_geometry_dirty(slide->view); + weston_compositor_schedule_repaint(slide->surface->compositor); + + if (slide->request == SLIDE_REQUEST_BACK) { + slide->request = SLIDE_REQUEST_NONE; + slide_back(slide); + } +} + +static void +slide_out(struct slide *slide) +{ + assert(slide->state == SLIDE_STATE_NONE || slide->state == SLIDE_STATE_BACK); + + slide->state = SLIDE_STATE_SLIDING_OUT; + + weston_move_scale_run(slide->view, slide->x, slide->y, + 1.0, 1.0, 0, + slide_done_cb, slide); +} + +static void +slide_back_done_cb(struct weston_view_animation *animation, void *data) +{ + struct slide *slide = data; + + slide->state = SLIDE_STATE_BACK; + + wl_list_remove(&slide->transform.link); + weston_view_geometry_dirty(slide->view); + + if (slide->request == SLIDE_REQUEST_OUT) { + slide->request = SLIDE_REQUEST_NONE; + slide_out(slide); + } else { + wl_list_remove(&slide->link); + free(slide); + } +} + +static void +slide_back(struct slide *slide) +{ + assert(slide->state == SLIDE_STATE_OUT); + + slide->state = SLIDE_STATE_SLIDING_BACK; + + weston_move_scale_run(slide->view, -slide->x, -slide->y, + 1.0, 1.0, 0, + slide_back_done_cb, slide); +} + +static void +shell_helper_slide_surface(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *surface_resource, + int32_t x, + int32_t y) +{ + struct shell_helper *helper = wl_resource_get_user_data(resource); + struct weston_surface *surface = + wl_resource_get_user_data(surface_resource); + struct weston_view *view; + struct slide *slide; + + wl_list_for_each(slide, &helper->slide_list, link) { + if (slide->surface == surface) { + if (slide->state == SLIDE_STATE_SLIDING_BACK) + slide->request = SLIDE_REQUEST_OUT; + return; + } + } + + view = container_of(surface->views.next, struct weston_view, surface_link); + + if (!view) + return; + + slide = malloc(sizeof *slide); + if (!slide) + return; + + slide->surface = surface; + slide->view = view; + slide->x = x; + slide->y = y; + + slide->state = SLIDE_STATE_NONE; + slide->request = SLIDE_REQUEST_NONE; + + wl_list_insert(&helper->slide_list, + &slide->link); + + slide_out(slide); +} + +static void +shell_helper_slide_surface_back(struct wl_client *client, + struct wl_resource *resource, + struct wl_resource *surface_resource) +{ + struct shell_helper *helper = wl_resource_get_user_data(resource); + struct weston_surface *surface = + wl_resource_get_user_data(surface_resource); + struct weston_view *view; + int found = 0; + struct slide *slide; + + wl_list_for_each(slide, &helper->slide_list, link) { + if (slide->surface == surface) { + found = 1; + break; + } + } + + if (!found || slide->state == SLIDE_STATE_SLIDING_BACK) + return; + + if (slide->state == SLIDE_STATE_SLIDING_OUT) + slide->request = SLIDE_REQUEST_BACK; + else + slide_back(slide); +} + +static const struct shell_helper_interface helper_implementation = { + shell_helper_move_surface, + shell_helper_slide_surface, + shell_helper_slide_surface_back +}; + +static void +bind_helper(struct wl_client *client, void *data, uint32_t version, uint32_t id) +{ + struct shell_helper *helper = data; + struct wl_resource *resource; + + resource = wl_resource_create(client, &shell_helper_interface, 1, id); + if (resource) + wl_resource_set_implementation(resource, &helper_implementation, + helper, NULL); +} + +static void +helper_destroy(struct wl_listener *listener, void *data) +{ + struct shell_helper *helper = + container_of(listener, struct shell_helper, destroy_listener); + + free(helper); +} + +WL_EXPORT int +module_init(struct weston_compositor *ec, + int *argc, char *argv[]) +{ + struct shell_helper *helper; + + helper = zalloc(sizeof *helper); + if (helper == NULL) + return -1; + + helper->compositor = ec; + + wl_list_init(&helper->slide_list); + + helper->destroy_listener.notify = helper_destroy; + wl_signal_add(&ec->destroy_signal, &helper->destroy_listener); + + if (wl_global_create(ec->wl_display, &shell_helper_interface, 1, + helper, bind_helper) == NULL) + return -1; + + return 0; +} |
