diff --git a/src/compositor.c b/src/compositor.c index bb0cb35c..1be1e100 100644 --- a/src/compositor.c +++ b/src/compositor.c @@ -229,7 +229,8 @@ weston_surface_create(struct weston_compositor *compositor) pixman_region32_init(&surface->transform.opaque); wl_list_init(&surface->frame_callback_list); - surface->buffer_destroy_listener.notify = surface_handle_buffer_destroy; + surface->buffer_destroy_listener.notify = + surface_handle_buffer_destroy; wl_list_init(&surface->geometry.transformation_list); wl_list_insert(&surface->geometry.transformation_list, @@ -908,7 +909,7 @@ fade_frame(struct weston_animation *animation, compositor->fade.surface = NULL; } else if (compositor->fade.spring.current > 0.999) { compositor->state = WESTON_COMPOSITOR_SLEEPING; - compositor->shell->lock(compositor->shell); + wl_signal_emit(&compositor->lock_signal, compositor); } } } @@ -1405,7 +1406,7 @@ weston_compositor_activity(struct weston_compositor *compositor) weston_compositor_wake(compositor); } else { weston_compositor_dpms_on(compositor); - compositor->shell->unlock(compositor->shell); + wl_signal_emit(&compositor->unlock_signal, compositor); } } @@ -1513,9 +1514,13 @@ WL_EXPORT void weston_surface_activate(struct weston_surface *surface, struct weston_input_device *device) { + struct weston_compositor *compositor = device->compositor; + wl_input_device_set_keyboard_focus(&device->input_device, &surface->surface); wl_data_device_set_keyboard_focus(&device->input_device); + + wl_signal_emit(&compositor->activate_signal, surface); } WL_EXPORT void @@ -2332,6 +2337,10 @@ weston_compositor_init(struct weston_compositor *ec, struct wl_display *display) const char *extensions; ec->wl_display = display; + wl_signal_init(&ec->destroy_signal); + wl_signal_init(&ec->activate_signal); + wl_signal_init(&ec->lock_signal); + wl_signal_init(&ec->unlock_signal); ec->launcher_sock = weston_environment_get_fd("WESTON_LAUNCHER_SOCK"); if (!wl_display_add_global(display, &wl_compositor_interface, @@ -2388,7 +2397,7 @@ weston_compositor_init(struct weston_compositor *ec, struct wl_display *display) weston_layer_init(&ec->fade_layer, &ec->layer_list); weston_layer_init(&ec->cursor_layer, &ec->fade_layer.link); - ec->screenshooter = screenshooter_create(ec); + screenshooter_create(ec); wl_data_device_manager_init(ec->wl_display); @@ -2421,9 +2430,6 @@ weston_compositor_shutdown(struct weston_compositor *ec) if (ec->input_loop_source) wl_event_source_remove(ec->input_loop_source); - if (ec->screenshooter) - screenshooter_destroy(ec->screenshooter); - /* Destroy all outputs associated with this compositor */ wl_list_for_each_safe(output, next, &ec->output_list, link) output->destroy(output); @@ -2615,12 +2621,7 @@ int main(int argc, char *argv[]) /* prevent further rendering while shutting down */ ec->state = WESTON_COMPOSITOR_SLEEPING; -#ifdef BUILD_XSERVER_LAUNCHER - if (xserver) - weston_xserver_destroy(ec); -#endif - - ec->shell->destroy(ec->shell); + wl_signal_emit(&ec->destroy_signal, ec); if (ec->has_bind_display) ec->unbind_display(ec->display, display); diff --git a/src/compositor.h b/src/compositor.h index 01e8d538..8fc5ab03 100644 --- a/src/compositor.h +++ b/src/compositor.h @@ -152,12 +152,6 @@ struct weston_spring { uint32_t timestamp; }; -struct weston_shell { - void (*lock)(struct weston_shell *shell); - void (*unlock)(struct weston_shell *shell); - void (*destroy)(struct weston_shell *shell); -}; - enum { WESTON_COMPOSITOR_ACTIVE, WESTON_COMPOSITOR_IDLE, /* shell->unlock called on activity */ @@ -173,7 +167,7 @@ struct weston_layer { struct weston_compositor { struct wl_shm *shm; - struct weston_xserver *wxs; + struct wl_signal destroy_signal; EGLDisplay display; EGLContext context; @@ -184,7 +178,9 @@ struct weston_compositor { struct weston_shader *current_shader; struct wl_display *wl_display; - struct weston_shell *shell; + struct wl_signal activate_signal; + struct wl_signal lock_signal; + struct wl_signal unlock_signal; struct wl_event_loop *input_loop; struct wl_event_source *input_loop_source; @@ -520,11 +516,8 @@ tty_destroy(struct tty *tty); int tty_activate_vt(struct tty *tty, int vt); -struct screenshooter * -screenshooter_create(struct weston_compositor *ec); - void -screenshooter_destroy(struct screenshooter *s); +screenshooter_create(struct weston_compositor *ec); struct weston_process; typedef void (*weston_process_cleanup_func_t)(struct weston_process *process, @@ -547,12 +540,6 @@ weston_watch_process(struct weston_process *process); int weston_xserver_init(struct weston_compositor *compositor); -void -weston_xserver_destroy(struct weston_compositor *compositor); -void -weston_xserver_surface_activate(struct weston_surface *surface); -void -weston_xserver_set_selection(struct weston_input_device *device); struct weston_zoom; typedef void (*weston_zoom_done_func_t)(struct weston_zoom *zoom, void *data); diff --git a/src/screenshooter.c b/src/screenshooter.c index 414bcea5..bd813513 100644 --- a/src/screenshooter.c +++ b/src/screenshooter.c @@ -33,6 +33,7 @@ struct screenshooter { struct wl_global *global; struct wl_client *client; struct weston_process process; + struct wl_listener destroy_listener; }; static void @@ -121,14 +122,24 @@ screenshooter_binding(struct wl_input_device *device, uint32_t time, screenshooter_exe, screenshooter_sigchld); } -struct screenshooter * +static void +screenshooter_destroy(struct wl_listener *listener, void *data) +{ + struct screenshooter *shooter = + container_of(listener, struct screenshooter, destroy_listener); + + wl_display_remove_global(shooter->ec->wl_display, shooter->global); + free(shooter); +} + +void screenshooter_create(struct weston_compositor *ec) { struct screenshooter *shooter; shooter = malloc(sizeof *shooter); if (shooter == NULL) - return NULL; + return; shooter->base.interface = &screenshooter_interface; shooter->base.implementation = @@ -142,12 +153,6 @@ screenshooter_create(struct weston_compositor *ec) weston_compositor_add_binding(ec, KEY_S, 0, 0, MODIFIER_SUPER, screenshooter_binding, shooter); - return shooter; -} - -void -screenshooter_destroy(struct screenshooter *shooter) -{ - wl_display_remove_global(shooter->ec->wl_display, shooter->global); - free(shooter); + shooter->destroy_listener.notify = screenshooter_destroy; + wl_signal_add(&ec->destroy_signal, &shooter->destroy_listener); } diff --git a/src/shell.c b/src/shell.c index b7bd4be1..6572ae3d 100644 --- a/src/shell.c +++ b/src/shell.c @@ -40,7 +40,10 @@ struct shell_surface; struct wl_shell { struct weston_compositor *compositor; - struct weston_shell shell; + + struct wl_listener lock_listener; + struct wl_listener unlock_listener; + struct wl_listener destroy_listener; struct weston_layer fullscreen_layer; struct weston_layer panel_layer; @@ -98,6 +101,7 @@ struct shell_surface { struct weston_surface *surface; struct wl_listener surface_destroy_listener; struct shell_surface *parent; + struct wl_shell *shell; enum shell_surface_type type; int32_t saved_x, saved_y; @@ -514,10 +518,7 @@ shell_surface_set_transient(struct wl_client *client, static struct wl_shell * shell_surface_get_shell(struct shell_surface *shsurf) { - struct weston_surface *es = shsurf->surface; - struct weston_shell *shell = es->compositor->shell; - - return (struct wl_shell *)container_of(shell, struct wl_shell, shell); + return shsurf->shell; } static int @@ -916,6 +917,7 @@ shell_get_shell_surface(struct wl_client *client, (void (**)(void)) &shell_surface_implementation; shsurf->resource.data = shsurf; + shsurf->shell = resource->data; shsurf->saved_position_valid = false; shsurf->surface = surface; shsurf->fullscreen.type = WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT; @@ -1469,18 +1471,13 @@ rotate_binding(struct wl_input_device *device, uint32_t time, } static void -activate(struct weston_shell *base, struct weston_surface *es, +activate(struct wl_shell *shell, struct weston_surface *es, struct weston_input_device *device) { - struct wl_shell *shell = container_of(base, struct wl_shell, shell); - struct weston_compositor *compositor = shell->compositor; struct weston_surface *surf, *prev; weston_surface_activate(es, device); - if (compositor->wxs) - weston_xserver_surface_activate(es); - switch (get_shell_surface_type(es)) { case SHELL_SURFACE_BACKGROUND: case SHELL_SURFACE_PANEL: @@ -1537,7 +1534,7 @@ click_to_activate_binding(struct wl_input_device *device, uint32_t button, uint32_t axis, int32_t state, void *data) { struct weston_input_device *wd = (struct weston_input_device *) device; - struct weston_compositor *compositor = data; + struct wl_shell *shell = data; struct weston_surface *focus; struct weston_surface *upper; @@ -1549,13 +1546,14 @@ click_to_activate_binding(struct wl_input_device *device, focus = upper; if (state && device->pointer_grab == &device->default_pointer_grab) - activate(compositor->shell, focus, wd); + activate(shell, focus, wd); } static void -lock(struct weston_shell *base) +lock(struct wl_listener *listener, void *data) { - struct wl_shell *shell = container_of(base, struct wl_shell, shell); + struct wl_shell *shell = + container_of(listener, struct wl_shell, lock_listener); struct weston_input_device *device; struct shell_surface *shsurf; struct weston_output *output; @@ -1606,9 +1604,10 @@ lock(struct weston_shell *base) } static void -unlock(struct weston_shell *base) +unlock(struct wl_listener *listener, void *data) { - struct wl_shell *shell = container_of(base, struct wl_shell, shell); + struct wl_shell *shell = + container_of(listener, struct wl_shell, unlock_listener); if (!shell->locked || shell->lock_surface) { weston_compositor_wake(shell->compositor); @@ -1639,10 +1638,9 @@ center_on_output(struct weston_surface *surface, struct weston_output *output) } static void -map(struct weston_shell *base, struct weston_surface *surface, +map(struct wl_shell *shell, struct weston_surface *surface, int32_t width, int32_t height, int32_t sx, int32_t sy) { - struct wl_shell *shell = container_of(base, struct wl_shell, shell); struct weston_compositor *compositor = shell->compositor; struct shell_surface *shsurf; enum shell_surface_type surface_type = SHELL_SURFACE_NONE; @@ -1743,7 +1741,7 @@ map(struct weston_shell *base, struct weston_surface *surface, case SHELL_SURFACE_FULLSCREEN: case SHELL_SURFACE_MAXIMIZED: if (!shell->locked) - activate(base, surface, + activate(shell, surface, (struct weston_input_device *) compositor->input_device); break; @@ -1756,10 +1754,9 @@ map(struct weston_shell *base, struct weston_surface *surface, } static void -configure(struct weston_shell *base, struct weston_surface *surface, +configure(struct wl_shell *shell, struct weston_surface *surface, GLfloat x, GLfloat y, int32_t width, int32_t height) { - struct wl_shell *shell = container_of(base, struct wl_shell, shell); enum shell_surface_type surface_type = SHELL_SURFACE_NONE; enum shell_surface_type prev_surface_type = SHELL_SURFACE_NONE; struct shell_surface *shsurf; @@ -1809,8 +1806,8 @@ configure(struct weston_shell *base, struct weston_surface *surface, static void shell_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy) { - struct weston_shell *shell = es->compositor->shell; struct shell_surface *shsurf = get_shell_surface(es); + struct wl_shell *shell = shsurf->shell; if (!weston_surface_is_mapped(es)) { map(shell, es, es->buffer->width, es->buffer->height, sx, sy); @@ -1974,7 +1971,7 @@ bind_screensaver(struct wl_client *client, } struct switcher { - struct weston_compositor *compositor; + struct wl_shell *shell; struct weston_surface *current; struct wl_listener listener; struct wl_keyboard_grab grab; @@ -1983,7 +1980,7 @@ struct switcher { static void switcher_next(struct switcher *switcher) { - struct weston_compositor *compositor = switcher->compositor; + struct weston_compositor *compositor = switcher->shell->compositor; struct weston_surface *surface; struct weston_surface *first = NULL, *prev = NULL, *next = NULL; struct shell_surface *shsurf; @@ -2043,7 +2040,7 @@ switcher_handle_surface_destroy(struct wl_listener *listener, void *data) static void switcher_destroy(struct switcher *switcher, uint32_t time) { - struct weston_compositor *compositor = switcher->compositor; + struct weston_compositor *compositor = switcher->shell->compositor; struct weston_surface *surface; struct weston_input_device *device = (struct weston_input_device *) switcher->grab.input_device; @@ -2054,7 +2051,7 @@ switcher_destroy(struct switcher *switcher, uint32_t time) } if (switcher->current) - activate(compositor->shell, switcher->current, device); + activate(switcher->shell, switcher->current, device); wl_list_remove(&switcher->listener.link); wl_input_device_end_keyboard_grab(&device->input_device); free(switcher); @@ -2084,11 +2081,11 @@ switcher_binding(struct wl_input_device *device, uint32_t time, uint32_t key, uint32_t button, uint32_t axis, int32_t state, void *data) { - struct weston_compositor *compositor = data; + struct wl_shell *shell = data; struct switcher *switcher; switcher = malloc(sizeof *switcher); - switcher->compositor = compositor; + switcher->shell = shell; switcher->current = NULL; switcher->listener.notify = switcher_handle_surface_destroy; wl_list_init(&switcher->listener.link); @@ -2136,9 +2133,8 @@ static void debug_repaint_binding(struct wl_input_device *device, uint32_t time, uint32_t key, uint32_t button, uint32_t axis, int32_t state, void *data) { - struct weston_compositor *compositor = data; - struct wl_shell *shell = - container_of(compositor->shell, struct wl_shell, shell); + struct wl_shell *shell = data; + struct weston_compositor *compositor = shell->compositor; struct weston_surface *surface; if (shell->debug_repaint_surface) { @@ -2168,9 +2164,10 @@ debug_repaint_binding(struct wl_input_device *device, uint32_t time, } static void -shell_destroy(struct weston_shell *base) +shell_destroy(struct wl_listener *listener, void *data) { - struct wl_shell *shell = container_of(base, struct wl_shell, shell); + struct wl_shell *shell = + container_of(listener, struct wl_shell, destroy_listener); if (shell->child.client) wl_client_destroy(shell->child.client); @@ -2193,9 +2190,13 @@ shell_init(struct weston_compositor *ec) memset(shell, 0, sizeof *shell); shell->compositor = ec; - shell->shell.lock = lock; - shell->shell.unlock = unlock; - shell->shell.destroy = shell_destroy; + + shell->destroy_listener.notify = shell_destroy; + wl_signal_add(&ec->destroy_signal, &shell->destroy_listener); + shell->lock_listener.notify = lock; + wl_signal_add(&ec->lock_signal, &shell->lock_listener); + shell->unlock_listener.notify = unlock; + wl_signal_add(&ec->unlock_signal, &shell->unlock_listener); wl_list_init(&shell->backgrounds); wl_list_init(&shell->panels); @@ -2235,7 +2236,7 @@ shell_init(struct weston_compositor *ec) MODIFIER_CTRL | MODIFIER_ALT, terminate_binding, ec); weston_compositor_add_binding(ec, 0, BTN_LEFT, 0, 0, - click_to_activate_binding, ec); + click_to_activate_binding, shell); weston_compositor_add_binding(ec, 0, 0, WL_INPUT_DEVICE_AXIS_VERTICAL_SCROLL, MODIFIER_SUPER | MODIFIER_ALT, surface_opacity_binding, NULL); @@ -2245,7 +2246,7 @@ shell_init(struct weston_compositor *ec) MODIFIER_SUPER | MODIFIER_ALT, rotate_binding, NULL); weston_compositor_add_binding(ec, KEY_TAB, 0, 0, MODIFIER_SUPER, - switcher_binding, ec); + switcher_binding, shell); /* brightness */ weston_compositor_add_binding(ec, KEY_F9, 0, 0, MODIFIER_CTRL, @@ -2258,9 +2259,7 @@ shell_init(struct weston_compositor *ec) backlight_binding, ec); weston_compositor_add_binding(ec, KEY_SPACE, 0, 0, MODIFIER_SUPER, - debug_repaint_binding, ec); - - ec->shell = &shell->shell; + debug_repaint_binding, shell); return 0; } diff --git a/src/tablet-shell.c b/src/tablet-shell.c index 0ec31ea1..1ead521a 100644 --- a/src/tablet-shell.c +++ b/src/tablet-shell.c @@ -46,7 +46,9 @@ enum { struct tablet_shell { struct wl_resource resource; - struct weston_shell shell; + struct wl_listener lock_listener; + struct wl_listener unlock_listener; + struct wl_listener destroy_listener; struct weston_compositor *compositor; struct weston_process process; @@ -80,6 +82,21 @@ struct tablet_client { char *name; }; +static void +tablet_shell_destroy(struct wl_listener *listener, void *data); + +static struct tablet_shell * +get_shell(struct weston_compositor *compositor) +{ + struct wl_listener *l; + + l = wl_signal_get(&compositor->destroy_signal, tablet_shell_destroy); + if (l) + return container_of(l, struct tablet_shell, destroy_listener); + + return NULL; +} + static void tablet_shell_sigchld(struct weston_process *process, int status) { @@ -109,9 +126,7 @@ static void tablet_shell_surface_configure(struct weston_surface *surface, int32_t sx, int32_t sy) { - struct tablet_shell *shell = - container_of(surface->compositor->shell, - struct tablet_shell, shell); + struct tablet_shell *shell = get_shell(surface->compositor); int32_t width, height; if (weston_surface_is_mapped(surface)) @@ -387,10 +402,10 @@ toggle_switcher(struct tablet_shell *shell) } static void -tablet_shell_lock(struct weston_shell *base) +tablet_shell_lock(struct wl_listener *listener, void *data) { struct tablet_shell *shell = - container_of(base, struct tablet_shell, shell); + container_of(listener, struct tablet_shell, lock_listener); if (shell->state == STATE_LOCKED) return; @@ -402,10 +417,10 @@ tablet_shell_lock(struct weston_shell *base) } static void -tablet_shell_unlock(struct weston_shell *base) +tablet_shell_unlock(struct wl_listener *listener, void *data) { struct tablet_shell *shell = - container_of(base, struct tablet_shell, shell); + container_of(listener, struct tablet_shell, lock_listener); weston_compositor_wake(shell->compositor); } @@ -505,10 +520,10 @@ bind_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id) } static void -tablet_shell_destroy(struct weston_shell *base) +tablet_shell_destroy(struct wl_listener *listener, void *data) { struct tablet_shell *shell = - container_of(base, struct tablet_shell, shell); + container_of(listener, struct tablet_shell, destroy_listener); if (shell->home_surface) shell->home_surface->configure = NULL; @@ -536,6 +551,13 @@ shell_init(struct weston_compositor *compositor) memset(shell, 0, sizeof *shell); shell->compositor = compositor; + shell->destroy_listener.notify = tablet_shell_destroy; + wl_signal_add(&compositor->destroy_signal, &shell->destroy_listener); + shell->lock_listener.notify = tablet_shell_lock; + wl_signal_add(&compositor->lock_signal, &shell->lock_listener); + shell->unlock_listener.notify = tablet_shell_unlock; + wl_signal_add(&compositor->unlock_signal, &shell->unlock_listener); + /* FIXME: This will make the object available to all clients. */ wl_display_add_global(compositor->wl_display, &tablet_shell_interface, shell, bind_shell); @@ -555,12 +577,6 @@ shell_init(struct weston_compositor *compositor) weston_compositor_add_binding(compositor, KEY_COMPOSE, 0, 0, 0, menu_key_binding, shell); - compositor->shell = &shell->shell; - - shell->shell.lock = tablet_shell_lock; - shell->shell.unlock = tablet_shell_unlock; - shell->shell.destroy = tablet_shell_destroy; - weston_layer_init(&shell->homescreen_layer, &compositor->cursor_layer.link); weston_layer_init(&shell->lockscreen_layer, diff --git a/src/xserver-launcher.c b/src/xserver-launcher.c index 36344ed1..7038999e 100644 --- a/src/xserver-launcher.c +++ b/src/xserver-launcher.c @@ -59,6 +59,8 @@ struct weston_xserver { struct wl_client *client; struct weston_compositor *compositor; struct weston_wm *wm; + struct wl_listener activate_listener; + struct wl_listener destroy_listener; }; struct weston_wm { @@ -555,11 +557,14 @@ weston_wm_activate(struct weston_wm *wm, XCB_INPUT_FOCUS_POINTER_ROOT, window->id, time); } -WL_EXPORT void -weston_xserver_surface_activate(struct weston_surface *surface) +static void +weston_xserver_surface_activate(struct wl_listener *listener, void *data) { + struct weston_surface *surface = data; struct weston_wm_window *window = get_wm_window(surface); - struct weston_xserver *wxs = surface->compositor->wxs; + struct weston_xserver *wxs = + container_of(listener, + struct weston_xserver, activate_listener); if (window) weston_wm_activate(wxs->wm, window, XCB_TIME_CURRENT_TIME); @@ -1681,6 +1686,21 @@ create_lockfile(int display, char *lockfile, size_t lsize) return 0; } +static void +weston_xserver_destroy(struct wl_listener *l, void *data) +{ + struct weston_xserver *wxs = + container_of(l, struct weston_xserver, destroy_listener); + + if (!wxs) + return; + + if (wxs->loop) + weston_xserver_shutdown(wxs); + + free(wxs); +} + int weston_xserver_init(struct weston_compositor *compositor) { @@ -1741,21 +1761,12 @@ weston_xserver_init(struct weston_compositor *compositor) wl_display_add_global(display, &xserver_interface, mxs, bind_xserver); - compositor->wxs = mxs; - - return 0; -} - -void -weston_xserver_destroy(struct weston_compositor *compositor) -{ - struct weston_xserver *wxs = compositor->wxs; + mxs->destroy_listener.notify = weston_xserver_destroy; + wl_signal_add(&compositor->destroy_signal, &mxs->destroy_listener); - if (!wxs) - return; - if (wxs->loop) - weston_xserver_shutdown(wxs); + mxs->activate_listener.notify = weston_xserver_surface_activate; + wl_signal_add(&compositor->activate_signal, &mxs->activate_listener); - free(wxs); + return 0; }