#include <gdk-pixbuf/gdk-pixbuf.h>
#include <math.h>
#include <linux/input.h>
+#include <dlfcn.h>
#include "wayland-server.h"
#include "compositor.h"
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;
&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 }
};
*v = t;
}
-void
+WL_EXPORT void
wlsc_tweener_init(struct wlsc_tweener *tweener,
double k, double current, double target)
{
tweener->target = target;
}
-void
+WL_EXPORT void
wlsc_tweener_update(struct wlsc_tweener *tweener, uint32_t msec)
{
double force, current, step;
}
}
-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)
{
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)
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;
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);
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);
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;
wlsc_output_damage(output);
}
-void
+WL_EXPORT void
wlsc_output_finish_frame(struct wlsc_output *output, int msecs)
{
struct wlsc_compositor *compositor = output->compositor;
animation->frame(animation, output, msecs);
}
-void
+WL_EXPORT void
wlsc_output_damage(struct wlsc_output *output)
{
struct wlsc_compositor *compositor = output->compositor;
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);
&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;
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) {
return 1;
}
-void
+WL_EXPORT void
wlsc_compositor_schedule_repaint(struct wlsc_compositor *compositor)
{
struct wlsc_output *output;
compositor->repaint_on_timeout = 1;
}
-void
+WL_EXPORT void
wlsc_compositor_fade(struct wlsc_compositor *compositor, float tint)
{
int done;
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))
wl_resource_destroy(&surface->resource, client);
}
-void
+WL_EXPORT void
wlsc_surface_assign_output(struct wlsc_surface *es)
{
struct wlsc_compositor *ec = es->compositor;
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
motion_grab_end
};
-void
+WL_EXPORT void
wlsc_compositor_wake(struct wlsc_compositor *compositor)
{
if (compositor->idle_inhibit)
wlsc_surface_damage(wd->sprite);
}
-void
+WL_EXPORT void
wlsc_surface_activate(struct wlsc_surface *surface,
struct wlsc_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)
return binding;
}
-void
+WL_EXPORT void
wlsc_binding_destroy(struct wlsc_binding *binding)
{
wl_list_remove(&binding->link);
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);
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. */
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);
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);
#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;
uint32_t edges;
int32_t dx, dy, width, height;
struct wlsc_surface *surface;
+ struct wl_shell *shell;
};
static void
{
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;
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);
}
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)
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);
}
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);
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;
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;
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;
}