From 02ec0a5d3a42ff7ceff54acdcd57fad8c5573912 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Kristian=20H=C3=B8gsberg?= Date: Sat, 23 Apr 2011 13:04:11 -0400 Subject: [PATCH] compositor: Support loadable shells The shell module is responsible for implementing the higher level compositor behavior. We default to the desktop-lite shell built in to the compositor. --- compositor/Makefile.am | 4 ++- compositor/compositor-x11.c | 5 +-- compositor/compositor.c | 84 ++++++++++++++++++++++++++++----------------- compositor/compositor.h | 12 ++++--- compositor/shell.c | 56 +++++++++++++++++++++--------- configure.ac | 8 +++++ 6 files changed, 113 insertions(+), 56 deletions(-) diff --git a/compositor/Makefile.am b/compositor/Makefile.am index 47f8091..7855feb 100644 --- a/compositor/Makefile.am +++ b/compositor/Makefile.am @@ -8,8 +8,10 @@ AM_CPPFLAGS = \ AM_CFLAGS = $(GCC_CFLAGS) +compositor_LDFLAGS = -export-dynamic compositor_LDADD = \ - $(COMPOSITOR_LIBS) + $(COMPOSITOR_LIBS) \ + $(DLOPEN_LIBS) if ENABLE_DRM_COMPOSITOR drm_compositor_sources = compositor-drm.c tty.c evdev.c diff --git a/compositor/compositor-x11.c b/compositor/compositor-x11.c index fe8038b..2f02ec3 100644 --- a/compositor/compositor-x11.c +++ b/compositor/compositor-x11.c @@ -448,7 +448,7 @@ x11_compositor_handle_event(int fd, uint32_t mask, void *data) output = x11_compositor_find_output(c, focus_in->event); notify_keyboard_focus(c->base.input_device, - get_time(), + wlsc_compositor_get_time(), &output->base, &c->keys); free(prev); @@ -540,7 +540,8 @@ x11_compositor_handle_event(int fd, uint32_t mask, void *data) if (focus_in->mode == XCB_NOTIFY_MODE_WHILE_GRABBED) break; notify_keyboard_focus(c->base.input_device, - get_time(), NULL, NULL); + wlsc_compositor_get_time(), + NULL, NULL); break; default: diff --git a/compositor/compositor.c b/compositor/compositor.c index 9be57df..b76f301 100644 --- a/compositor/compositor.c +++ b/compositor/compositor.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "wayland-server.h" #include "compositor.h" @@ -42,6 +43,7 @@ static const char *option_socket_name = NULL; static const char *option_background = "background.jpg"; static const char *option_geometry = "1024x640"; +static const char *option_shell = NULL; static int option_idle_time = 5; static int option_connector = 0; @@ -56,6 +58,8 @@ static const GOptionEntry option_entries[] = { &option_socket_name, "Socket Name" }, { "idle-time", 'i', 0, G_OPTION_ARG_INT, &option_idle_time, "Screensaver idle time" }, + { "shell", 'i', 0, G_OPTION_ARG_STRING, + &option_shell, "Shell module" }, { NULL } }; @@ -123,7 +127,7 @@ wlsc_matrix_transform(struct wlsc_matrix *matrix, struct wlsc_vector *v) *v = t; } -void +WL_EXPORT void wlsc_tweener_init(struct wlsc_tweener *tweener, double k, double current, double target) { @@ -133,7 +137,7 @@ wlsc_tweener_init(struct wlsc_tweener *tweener, tweener->target = target; } -void +WL_EXPORT void wlsc_tweener_update(struct wlsc_tweener *tweener, uint32_t msec) { double force, current, step; @@ -160,14 +164,14 @@ wlsc_tweener_update(struct wlsc_tweener *tweener, uint32_t msec) } } -int +WL_EXPORT int wlsc_tweener_done(struct wlsc_tweener *tweener) { return fabs(tweener->previous - tweener->target) < 0.0002 && fabs(tweener->current - tweener->target) < 0.0002; } -struct wlsc_surface * +WL_EXPORT struct wlsc_surface * wlsc_surface_create(struct wlsc_compositor *compositor, int32_t x, int32_t y, int32_t width, int32_t height) { @@ -209,7 +213,7 @@ wlsc_surface_create(struct wlsc_compositor *compositor, return surface; } -void +WL_EXPORT void wlsc_surface_damage_rectangle(struct wlsc_surface *surface, int32_t x, int32_t y, int32_t width, int32_t height) @@ -223,15 +227,15 @@ wlsc_surface_damage_rectangle(struct wlsc_surface *surface, wlsc_compositor_schedule_repaint(compositor); } -void +WL_EXPORT void wlsc_surface_damage(struct wlsc_surface *surface) { wlsc_surface_damage_rectangle(surface, 0, 0, surface->width, surface->height); } -uint32_t -get_time(void) +WL_EXPORT uint32_t +wlsc_compositor_get_time(void) { struct timeval tv; @@ -263,7 +267,7 @@ destroy_surface(struct wl_resource *resource, struct wl_client *client) wl_list_remove(&surface->buffer_link); - time = get_time(); + time = wlsc_compositor_get_time(); wl_list_for_each_safe(l, next, &surface->surface.destroy_listener_list, link) l->func(l, &surface->surface, time); @@ -586,7 +590,7 @@ wlsc_surface_raise(struct wlsc_surface *surface) wl_list_insert(&compositor->surface_list, &surface->link); } -void +WL_EXPORT void wlsc_surface_update_matrix(struct wlsc_surface *es) { wlsc_matrix_init(&es->matrix); @@ -599,7 +603,7 @@ wlsc_surface_update_matrix(struct wlsc_surface *es) 1.0 / es->width, 1.0 / es->height, 1); } -void +WL_EXPORT void wlsc_compositor_damage_all(struct wlsc_compositor *compositor) { struct wlsc_output *output; @@ -608,7 +612,7 @@ wlsc_compositor_damage_all(struct wlsc_compositor *compositor) wlsc_output_damage(output); } -void +WL_EXPORT void wlsc_output_finish_frame(struct wlsc_output *output, int msecs) { struct wlsc_compositor *compositor = output->compositor; @@ -632,7 +636,7 @@ wlsc_output_finish_frame(struct wlsc_output *output, int msecs) animation->frame(animation, output, msecs); } -void +WL_EXPORT void wlsc_output_damage(struct wlsc_output *output) { struct wlsc_compositor *compositor = output->compositor; @@ -654,8 +658,10 @@ fade_frame(struct wlsc_animation *animation, wlsc_tweener_update(&compositor->fade.tweener, msecs); if (wlsc_tweener_done(&compositor->fade.tweener)) { - if (compositor->fade.tweener.current > 0.999) + if (compositor->fade.tweener.current > 0.999) { compositor->state = WLSC_COMPOSITOR_SLEEPING; + compositor->shell->lock(compositor->shell); + } compositor->fade.tweener.current = compositor->fade.tweener.target; wl_list_remove(&animation->link); @@ -717,11 +723,6 @@ wlsc_output_repaint(struct wlsc_output *output) &output->previous_damage_region); pixman_region32_copy(&output->previous_damage_region, &new_damage); - if (ec->state == WLSC_COMPOSITOR_SLEEPING) { - glClear(GL_COLOR_BUFFER_BIT); - return; - } - if (ec->focus) if (output->set_hardware_cursor(output, ec->input_device) < 0) using_hardware_cursor = 0; @@ -729,8 +730,7 @@ wlsc_output_repaint(struct wlsc_output *output) using_hardware_cursor = 0; es = container_of(ec->surface_list.next, struct wlsc_surface, link); - if (es->map_type == WLSC_SURFACE_MAP_FULLSCREEN && - es->fullscreen_output == output) { + if (es->fullscreen_output == output) { if (es->visual == &ec->compositor.rgb_visual && using_hardware_cursor) { if (output->prepare_scanout_surface(output, es) == 0) { @@ -827,7 +827,7 @@ repaint(void *data) return 1; } -void +WL_EXPORT void wlsc_compositor_schedule_repaint(struct wlsc_compositor *compositor) { struct wlsc_output *output; @@ -845,7 +845,7 @@ wlsc_compositor_schedule_repaint(struct wlsc_compositor *compositor) compositor->repaint_on_timeout = 1; } -void +WL_EXPORT void wlsc_compositor_fade(struct wlsc_compositor *compositor, float tint) { int done; @@ -856,7 +856,8 @@ wlsc_compositor_fade(struct wlsc_compositor *compositor, float tint) return; if (done) - compositor->fade.tweener.timestamp = get_time(); + compositor->fade.tweener.timestamp = + wlsc_compositor_get_time(); wlsc_compositor_damage_all(compositor); if (wl_list_empty(&compositor->fade.animation.link)) @@ -871,7 +872,7 @@ surface_destroy(struct wl_client *client, wl_resource_destroy(&surface->resource, client); } -void +WL_EXPORT void wlsc_surface_assign_output(struct wlsc_surface *es) { struct wlsc_compositor *ec = es->compositor; @@ -920,6 +921,8 @@ surface_attach(struct wl_client *client, if (x != 0 || y != 0) wlsc_surface_assign_output(es); wlsc_surface_update_matrix(es); + + es->compositor->shell->attach(es->compositor->shell, es); } static void @@ -1180,7 +1183,7 @@ static const struct wl_grab_interface motion_grab_interface = { motion_grab_end }; -void +WL_EXPORT void wlsc_compositor_wake(struct wlsc_compositor *compositor) { if (compositor->idle_inhibit) @@ -1294,7 +1297,7 @@ notify_motion(struct wl_input_device *device, uint32_t time, int x, int y) wlsc_surface_damage(wd->sprite); } -void +WL_EXPORT void wlsc_surface_activate(struct wlsc_surface *surface, struct wlsc_input_device *device, uint32_t time) { @@ -1367,7 +1370,7 @@ terminate_binding(struct wl_input_device *device, uint32_t time, wl_display_terminate(compositor->wl_display); } -struct wlsc_binding * +WL_EXPORT struct wlsc_binding * wlsc_compositor_add_binding(struct wlsc_compositor *compositor, uint32_t key, uint32_t button, uint32_t modifier, wlsc_binding_handler_t handler, void *data) @@ -1388,7 +1391,7 @@ wlsc_compositor_add_binding(struct wlsc_compositor *compositor, return binding; } -void +WL_EXPORT void wlsc_binding_destroy(struct wlsc_binding *binding) { wl_list_remove(&binding->link); @@ -1861,9 +1864,6 @@ wlsc_compositor_init(struct wlsc_compositor *ec, struct wl_display *display) ec->fade.animation.frame = fade_frame; wl_list_init(&ec->fade.animation.link); - wlsc_shell_init(ec); - wlsc_switcher_init(ec); - wlsc_compositor_add_binding(ec, KEY_BACKSPACE, 0, MODIFIER_CTRL | MODIFIER_ALT, terminate_binding, ec); @@ -1917,6 +1917,8 @@ int main(int argc, char *argv[]) GError *error = NULL; GOptionContext *context; int width, height; + void *shell_module; + int (*shell_init)(struct wlsc_compositor *ec); g_type_init(); /* GdkPixbuf needs this, it seems. */ @@ -1936,6 +1938,21 @@ int main(int argc, char *argv[]) ec = NULL; + shell_init = desktop_shell_init; + if (option_shell) { + shell_module = dlopen(option_shell, RTLD_LAZY); + if (!shell_module) { + fprintf(stderr, "failed to load shell module: %m\n"); + exit(EXIT_FAILURE); + } + shell_init = dlsym(shell_module, "shell_init"); + if (!shell_init) { + fprintf(stderr, + "failed to lookup shell init function: %m\n"); + exit(EXIT_FAILURE); + } + } + #if BUILD_WAYLAND_COMPOSITOR if (getenv("WAYLAND_DISPLAY")) ec = wayland_compositor_create(display, width, height); @@ -1961,6 +1978,9 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } + if (shell_init(ec) < 0) + exit(EXIT_FAILURE); + if (wl_display_add_socket(display, option_socket_name)) { fprintf(stderr, "failed to add socket: %m\n"); exit(EXIT_FAILURE); diff --git a/compositor/compositor.h b/compositor/compositor.h index 3c0d073..22095ff 100644 --- a/compositor/compositor.h +++ b/compositor/compositor.h @@ -112,6 +112,11 @@ struct wlsc_tweener { uint32_t timestamp; }; +struct wlsc_shell { + void (*lock)(struct wlsc_shell *shell); + void (*attach)(struct wlsc_shell *shell, struct wlsc_surface *surface); +}; + enum { WLSC_COMPOSITOR_ACTIVE, WLSC_COMPOSITOR_SLEEPING @@ -132,8 +137,7 @@ struct wlsc_compositor { struct wlsc_shader solid_shader; struct wl_display *wl_display; - /* We implement the shell interface. */ - struct wl_shell shell; + struct wlsc_shell *shell; /* There can be more than one, but not right now... */ struct wl_input_device *input_device; @@ -296,7 +300,7 @@ wlsc_selection_set_focus(struct wl_selection *selection, struct wl_surface *surface, uint32_t time); uint32_t -get_time(void); +wlsc_compositor_get_time(void); int wlsc_compositor_init(struct wlsc_compositor *ec, struct wl_display *display); @@ -313,7 +317,7 @@ wlsc_input_device_init(struct wlsc_input_device *device, struct wlsc_compositor *ec); int -wlsc_shell_init(struct wlsc_compositor *ec); +desktop_shell_init(struct wlsc_compositor *ec); void wlsc_switcher_init(struct wlsc_compositor *compositor); diff --git a/compositor/shell.c b/compositor/shell.c index c842b97..d3859ae 100644 --- a/compositor/shell.c +++ b/compositor/shell.c @@ -28,6 +28,11 @@ #include "wayland-server.h" #include "compositor.h" +struct wl_shell { + struct wl_object object; + struct wlsc_shell shell; +}; + struct wlsc_move_grab { struct wl_grab grab; struct wlsc_surface *surface; @@ -110,6 +115,7 @@ struct wlsc_resize_grab { uint32_t edges; int32_t dx, dy, width, height; struct wlsc_surface *surface; + struct wl_shell *shell; }; static void @@ -118,8 +124,6 @@ resize_grab_motion(struct wl_grab *grab, { struct wlsc_resize_grab *resize = (struct wlsc_resize_grab *) grab; struct wl_input_device *device = grab->input_device; - struct wlsc_compositor *ec = - (struct wlsc_compositor *) device->compositor; struct wl_surface *surface = &resize->surface->surface; int32_t width, height; @@ -139,7 +143,7 @@ resize_grab_motion(struct wl_grab *grab, height = resize->height; } - wl_client_post_event(surface->client, &ec->shell.object, + wl_client_post_event(surface->client, &resize->shell->object, WL_SHELL_CONFIGURE, time, resize->edges, surface, width, height); } @@ -195,6 +199,7 @@ shell_resize(struct wl_client *client, struct wl_shell *shell, resize->width = es->width; resize->height = es->height; resize->surface = es; + resize->shell = shell; if (edges == 0 || edges > 15 || (edges & 3) == 3 || (edges & 12) == 12) @@ -243,7 +248,8 @@ destroy_drag(struct wl_resource *resource, struct wl_client *client) wl_list_remove(&drag->drag_focus_listener.link); if (drag->grab.input_device) - wl_input_device_end_grab(drag->grab.input_device, get_time()); + wl_input_device_end_grab(drag->grab.input_device, + wlsc_compositor_get_time()); free(drag); } @@ -614,7 +620,8 @@ destroy_selection(struct wl_resource *resource, struct wl_client *client) if (wd && wd->selection == selection) { wd->selection = NULL; - wlsc_selection_set_focus(selection, NULL, get_time()); + wlsc_selection_set_focus(selection, NULL, + wlsc_compositor_get_time()); } wl_list_remove(&selection->selection_focus_listener.link); @@ -667,23 +674,21 @@ static void move_binding(struct wl_input_device *device, uint32_t time, uint32_t key, uint32_t button, uint32_t state, void *data) { - struct wlsc_compositor *compositor = data; + struct wl_shell *shell = data; struct wlsc_surface *surface = (struct wlsc_surface *) device->pointer_focus; if (surface == NULL) return; - shell_move(NULL, - (struct wl_shell *) &compositor->shell, - &surface->surface, device, time); + shell_move(NULL, shell, &surface->surface, device, time); } static void resize_binding(struct wl_input_device *device, uint32_t time, uint32_t key, uint32_t button, uint32_t state, void *data) { - struct wlsc_compositor *compositor = data; + struct wl_shell *shell = data; struct wlsc_surface *surface = (struct wlsc_surface *) device->pointer_focus; uint32_t edges = 0; @@ -709,15 +714,30 @@ resize_binding(struct wl_input_device *device, uint32_t time, else edges |= WL_SHELL_RESIZE_BOTTOM; - shell_resize(NULL, - (struct wl_shell *) &compositor->shell, - &surface->surface, device, time, edges); + shell_resize(NULL, shell, &surface->surface, device, time, edges); +} + +static void +lock(struct wlsc_shell *shell) +{ +} + +static void +attach(struct wlsc_shell *shell, struct wlsc_surface *surface) +{ } int -wlsc_shell_init(struct wlsc_compositor *ec) +desktop_shell_init(struct wlsc_compositor *ec) { - struct wl_shell *shell = &ec->shell; + struct wl_shell *shell; + + shell = malloc(sizeof *shell); + if (shell == NULL) + return -1; + + shell->shell.lock = lock; + shell->shell.attach = attach; shell->object.interface = &wl_shell_interface; shell->object.implementation = (void (**)(void)) &shell_interface; @@ -726,9 +746,11 @@ wlsc_shell_init(struct wlsc_compositor *ec) return -1; wlsc_compositor_add_binding(ec, 0, BTN_LEFT, MODIFIER_SUPER, - move_binding, ec); + move_binding, shell); wlsc_compositor_add_binding(ec, 0, BTN_MIDDLE, MODIFIER_SUPER, - resize_binding, ec); + resize_binding, shell); + + ec->shell = &shell->shell; return 0; } diff --git a/configure.ac b/configure.ac index 960f134..8873bd0 100644 --- a/configure.ac +++ b/configure.ac @@ -15,8 +15,16 @@ AM_SILENT_RULES([yes]) AC_PROG_CC AC_PROG_RANLIB +# Initialize libtool +LT_PREREQ([2.2]) +LT_INIT + PKG_PROG_PKG_CONFIG() +AC_CHECK_FUNC([dlopen], [], + AC_CHECK_LIB([dl], [dlopen], DLOPEN_LIBS="-ldl")) +AC_SUBST(DLOPEN_LIBS) + PKG_CHECK_MODULES(COMPOSITOR, [wayland-server wayland-client wayland-egl egl >= 7.10 glesv2 gdk-pixbuf-2.0 libudev >= 136 libdrm >= 2.4.23] pixman-1 x11 x11-xcb) PKG_CHECK_MODULES(SIMPLE_CLIENT, [egl >= 7.10 glesv2 wayland-client wayland-egl]) -- 2.7.4