struct display *display;
struct window *parent;
struct wl_surface *surface;
+ struct wl_shell_surface *shell_surface;
char *title;
struct rectangle allocation, saved_allocation, server_allocation;
int x, y;
static void
window_set_type(struct window *window)
{
- struct display *display = window->display;
-
switch (window->type) {
case TYPE_FULLSCREEN:
- wl_shell_set_fullscreen(display->shell, window->surface);
+ wl_shell_surface_set_fullscreen(window->shell_surface);
break;
case TYPE_TOPLEVEL:
- wl_shell_set_toplevel(display->shell, window->surface);
+ wl_shell_surface_set_toplevel(window->shell_surface);
break;
case TYPE_TRANSIENT:
- wl_shell_set_transient(display->shell, window->surface,
- window->parent->surface,
- window->x, window->y, 0);
+ wl_shell_surface_set_transient(window->shell_surface,
+ window->parent->shell_surface,
+ window->x, window->y, 0);
break;
case TYPE_CUSTOM:
break;
input->keyboard_focus = NULL;
}
+ wl_shell_surface_destroy(window->shell_surface);
wl_surface_destroy(window->surface);
wl_list_remove(&window->link);
free(window);
return window->surface;
}
+struct wl_shell_surface *
+window_get_wl_shell_surface(struct window *window)
+{
+ return window->shell_surface;
+}
+
static int
get_pointer_location(struct window *window, int32_t x, int32_t y)
{
button == BTN_LEFT && state == 1) {
switch (location) {
case WINDOW_TITLEBAR:
- wl_shell_move(window->display->shell,
- window->surface, input_device, time);
+ wl_shell_surface_move(window->shell_surface,
+ input_device, time);
break;
case WINDOW_RESIZING_TOP:
case WINDOW_RESIZING_BOTTOM:
case WINDOW_RESIZING_TOP_RIGHT:
case WINDOW_RESIZING_BOTTOM_LEFT:
case WINDOW_RESIZING_BOTTOM_RIGHT:
- wl_shell_resize(window->display->shell,
- window->surface, input_device, time,
- location);
+ wl_shell_surface_resize(window->shell_surface,
+ input_device, time,
+ location);
break;
case WINDOW_CLIENT_AREA:
if (window->button_handler)
void
window_move(struct window *window, struct input *input, uint32_t time)
{
- if (window->display->shell)
- wl_shell_move(window->display->shell,
- window->surface, input->input_device, time);
+ wl_shell_surface_move(window->shell_surface,
+ input->input_device, time);
}
static void
-handle_configure(void *data, struct wl_shell *shell,
+handle_configure(void *data, struct wl_shell_surface *shell_surface,
uint32_t time, uint32_t edges,
- struct wl_surface *surface, int32_t width, int32_t height)
+ int32_t width, int32_t height)
{
- struct window *window = wl_surface_get_user_data(surface);
+ struct window *window = data;
int32_t child_width, child_height;
/* FIXME: this is probably the wrong place to check for width
}
}
-static const struct wl_shell_listener shell_listener = {
+static const struct wl_shell_surface_listener shell_surface_listener = {
handle_configure,
};
window->display = display;
window->parent = parent;
window->surface = wl_compositor_create_surface(display->compositor);
+ window->shell_surface = wl_shell_get_shell_surface(display->shell,
+ window->surface);
window->allocation.x = 0;
window->allocation.y = 0;
window->allocation.width = width;
wl_surface_set_user_data(window->surface, window);
wl_list_insert(display->window_list.prev, &window->link);
+ wl_shell_surface_add_listener(window->shell_surface,
+ &shell_surface_listener, window);
+
return window;
}
display_add_input(d, id);
} else if (strcmp(interface, "wl_shell") == 0) {
d->shell = wl_display_bind(display, id, &wl_shell_interface);
- wl_shell_add_listener(d->shell, &shell_listener, d);
} else if (strcmp(interface, "wl_shm") == 0) {
d->shm = wl_display_bind(display, id, &wl_shm_interface);
} else if (strcmp(interface, "wl_data_device_manager") == 0) {
};
struct shell_surface {
+ struct wl_resource resource;
+
struct wlsc_surface *surface;
- struct wl_listener destroy_listener;
+ struct wl_listener surface_destroy_listener;
enum shell_surface_type type;
int32_t saved_x, saved_y;
int32_t dx, dy;
};
-static void
-destroy_shell_surface(struct shell_surface *priv)
-{
- wl_list_remove(&priv->destroy_listener.link);
- wl_list_remove(&priv->link);
- free(priv);
-}
-
-static void
-handle_shell_surface_destroy(struct wl_listener *listener,
- struct wl_resource *resource, uint32_t time)
-{
- struct shell_surface *priv =
- container_of(listener, struct shell_surface, destroy_listener);
- destroy_shell_surface(priv);
-}
-
static struct shell_surface *
get_shell_surface(struct wlsc_surface *surface)
{
- struct shell_surface *priv;
-
- if (surface->shell_priv)
- return surface->shell_priv;
-
- priv = calloc(1, sizeof *priv);
- if (!priv)
- return NULL;
-
- priv->destroy_listener.func = handle_shell_surface_destroy;
- wl_list_insert(surface->surface.resource.destroy_listener_list.prev,
- &priv->destroy_listener.link);
-
- surface->shell_priv = priv;
- priv->surface = surface;
- /* init link so its safe to always remove it in destroy_shell_surface */
- wl_list_init(&priv->link);
-
- priv->type = SHELL_SURFACE_NORMAL;
-
- return priv;
+ return surface->shell_priv;
}
static void
}
static void
-shell_move(struct wl_client *client, struct wl_resource *resource,
- struct wl_resource *surface_resource,
- struct wl_resource *input_resource, uint32_t time)
+shell_surface_move(struct wl_client *client, struct wl_resource *resource,
+ struct wl_resource *input_resource, uint32_t time)
{
struct wlsc_input_device *wd = input_resource->data;
- struct wlsc_surface *es = surface_resource->data;
+ struct shell_surface *shsurf = resource->data;
- if (wlsc_surface_move(es, wd, time) < 0)
+ if (wlsc_surface_move(shsurf->surface, wd, time) < 0)
wl_resource_post_no_memory(resource);
}
struct wl_grab grab;
uint32_t edges;
int32_t dx, dy, width, height;
- struct wlsc_surface *surface;
- struct wl_resource *resource;
+ struct shell_surface *shsurf;
};
static void
{
struct wlsc_resize_grab *resize = (struct wlsc_resize_grab *) grab;
struct wl_input_device *device = grab->input_device;
- struct wl_surface *surface = &resize->surface->surface;
int32_t width, height;
- if (resize->edges & WL_SHELL_RESIZE_LEFT) {
+ if (resize->edges & WL_SHELL_SURFACE_RESIZE_LEFT) {
width = device->grab_x - x + resize->width;
- } else if (resize->edges & WL_SHELL_RESIZE_RIGHT) {
+ } else if (resize->edges & WL_SHELL_SURFACE_RESIZE_RIGHT) {
width = x - device->grab_x + resize->width;
} else {
width = resize->width;
}
- if (resize->edges & WL_SHELL_RESIZE_TOP) {
+ if (resize->edges & WL_SHELL_SURFACE_RESIZE_TOP) {
height = device->grab_y - y + resize->height;
- } else if (resize->edges & WL_SHELL_RESIZE_BOTTOM) {
+ } else if (resize->edges & WL_SHELL_SURFACE_RESIZE_BOTTOM) {
height = y - device->grab_y + resize->height;
} else {
height = resize->height;
}
- wl_resource_post_event(resize->resource,
- WL_SHELL_CONFIGURE, time, resize->edges,
- surface, width, height);
+ wl_resource_post_event(&resize->shsurf->resource,
+ WL_SHELL_SURFACE_CONFIGURE, time, resize->edges,
+ width, height);
}
static void
};
static int
-wlsc_surface_resize(struct wlsc_surface *es,
+wlsc_surface_resize(struct shell_surface *shsurf,
struct wlsc_input_device *wd,
- uint32_t time, uint32_t edges,
- struct wl_resource *resource)
+ uint32_t time, uint32_t edges)
{
struct wlsc_resize_grab *resize;
+ struct wlsc_surface *es = shsurf->surface;
enum wlsc_pointer_type pointer = WLSC_POINTER_LEFT_PTR;
/* FIXME: Reject if fullscreen */
resize->dy = es->y - wd->input_device.grab_y;
resize->width = es->width;
resize->height = es->height;
- resize->surface = es;
- resize->resource = resource;
+ resize->shsurf = shsurf;
if (edges == 0 || edges > 15 ||
(edges & 3) == 3 || (edges & 12) == 12)
return 0;
switch (edges) {
- case WL_SHELL_RESIZE_TOP:
+ case WL_SHELL_SURFACE_RESIZE_TOP:
pointer = WLSC_POINTER_TOP;
break;
- case WL_SHELL_RESIZE_BOTTOM:
+ case WL_SHELL_SURFACE_RESIZE_BOTTOM:
pointer = WLSC_POINTER_BOTTOM;
break;
- case WL_SHELL_RESIZE_LEFT:
+ case WL_SHELL_SURFACE_RESIZE_LEFT:
pointer = WLSC_POINTER_LEFT;
break;
- case WL_SHELL_RESIZE_TOP_LEFT:
+ case WL_SHELL_SURFACE_RESIZE_TOP_LEFT:
pointer = WLSC_POINTER_TOP_LEFT;
break;
- case WL_SHELL_RESIZE_BOTTOM_LEFT:
+ case WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT:
pointer = WLSC_POINTER_BOTTOM_LEFT;
break;
- case WL_SHELL_RESIZE_RIGHT:
+ case WL_SHELL_SURFACE_RESIZE_RIGHT:
pointer = WLSC_POINTER_RIGHT;
break;
- case WL_SHELL_RESIZE_TOP_RIGHT:
+ case WL_SHELL_SURFACE_RESIZE_TOP_RIGHT:
pointer = WLSC_POINTER_TOP_RIGHT;
break;
- case WL_SHELL_RESIZE_BOTTOM_RIGHT:
+ case WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT:
pointer = WLSC_POINTER_BOTTOM_RIGHT;
break;
}
}
static void
-shell_resize(struct wl_client *client, struct wl_resource *resource,
- struct wl_resource *surface_resource,
- struct wl_resource *input_resource, uint32_t time, uint32_t edges)
+shell_surface_resize(struct wl_client *client, struct wl_resource *resource,
+ struct wl_resource *input_resource, uint32_t time,
+ uint32_t edges)
{
struct wlsc_input_device *wd = input_resource->data;
- struct wlsc_surface *es = surface_resource->data;
+ struct shell_surface *shsurf = resource->data;
/* FIXME: Reject if fullscreen */
- if (wlsc_surface_resize(es, wd, time, edges, resource) < 0)
+ if (wlsc_surface_resize(shsurf, wd, time, edges) < 0)
wl_resource_post_no_memory(resource);
}
static void
-shell_set_toplevel(struct wl_client *client,
- struct wl_resource *resource,
- struct wl_resource *surface_resource)
+shell_surface_set_toplevel(struct wl_client *client,
+ struct wl_resource *resource)
{
- struct wlsc_surface *es = surface_resource->data;
- struct shell_surface *priv;
+ struct shell_surface *shsurf = resource->data;
+ struct wlsc_surface *es = shsurf->surface;
- priv = get_shell_surface(es);
- if (priv->type == SHELL_SURFACE_FULLSCREEN) {
- es->x = priv->saved_x;
- es->y = priv->saved_y;
+ if (shsurf->type == SHELL_SURFACE_FULLSCREEN) {
+ es->x = shsurf->saved_x;
+ es->y = shsurf->saved_y;
}
wlsc_surface_damage(es);
- priv->type = SHELL_SURFACE_TOPLEVEL;
+ shsurf->type = SHELL_SURFACE_TOPLEVEL;
es->fullscreen_output = NULL;
}
static void
-shell_set_transient(struct wl_client *client,
- struct wl_resource *resource,
- struct wl_resource *surface_resource,
- struct wl_resource *parent_resource,
- int x, int y, uint32_t flags)
+shell_surface_set_transient(struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_resource *parent_resource,
+ int x, int y, uint32_t flags)
{
- struct wlsc_surface *es = surface_resource->data;
+ struct shell_surface *shsurf = resource->data;
+ struct wlsc_surface *es = shsurf->surface;
struct wlsc_surface *pes = parent_resource->data;
- struct shell_surface *priv;
-
- priv = get_shell_surface(es);
/* assign to parents output */
es->output = pes->output;
es->y = pes->y + y;
wlsc_surface_damage(es);
- priv->type = SHELL_SURFACE_TRANSIENT;
+ shsurf->type = SHELL_SURFACE_TRANSIENT;
}
static void
-shell_set_fullscreen(struct wl_client *client,
- struct wl_resource *resource,
- struct wl_resource *surface_resource)
+shell_surface_set_fullscreen(struct wl_client *client,
+ struct wl_resource *resource)
{
- struct wlsc_surface *es = surface_resource->data;
+ struct shell_surface *shsurf = resource->data;
+ struct wlsc_surface *es = shsurf->surface;
struct wlsc_output *output;
- struct shell_surface *priv;
-
- priv = get_shell_surface(es);
/* FIXME: Fullscreen on first output */
/* FIXME: Handle output going away */
struct wlsc_output, link);
es->output = output;
- priv->saved_x = es->x;
- priv->saved_y = es->y;
+ shsurf->saved_x = es->x;
+ shsurf->saved_y = es->y;
es->x = (output->current->width - es->width) / 2;
es->y = (output->current->height - es->height) / 2;
es->fullscreen_output = output;
wlsc_surface_damage(es);
- priv->type = SHELL_SURFACE_FULLSCREEN;
+ shsurf->type = SHELL_SURFACE_FULLSCREEN;
}
-static const struct wl_shell_interface shell_interface = {
- shell_move,
- shell_resize,
- shell_set_toplevel,
- shell_set_transient,
- shell_set_fullscreen
+static const struct wl_shell_surface_interface shell_surface_implementation = {
+ shell_surface_move,
+ shell_surface_resize,
+ shell_surface_set_toplevel,
+ shell_surface_set_transient,
+ shell_surface_set_fullscreen
+};
+
+static void
+destroy_shell_surface(struct wl_resource *resource)
+{
+ struct shell_surface *shsurf = resource->data;
+
+ /* in case cleaning up a dead client destroys shell_surface first */
+ if (shsurf->surface)
+ wl_list_remove(&shsurf->surface_destroy_listener.link);
+
+ wl_list_remove(&shsurf->link);
+ free(shsurf);
+}
+
+static void
+shell_handle_surface_destroy(struct wl_listener *listener,
+ struct wl_resource *resource, uint32_t time)
+{
+ struct shell_surface *shsurf = container_of(listener,
+ struct shell_surface,
+ surface_destroy_listener);
+
+ shsurf->surface = NULL;
+ wl_resource_destroy(&shsurf->resource, time);
+}
+
+static void
+shell_create_shell_surface(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t id,
+ struct wl_resource *surface_resource)
+{
+ struct wlsc_surface *surface = surface_resource->data;
+ struct shell_surface *shsurf;
+
+ shsurf = calloc(1, sizeof *shsurf);
+ if (!shsurf) {
+ wl_resource_post_no_memory(resource);
+ return;
+ }
+
+ shsurf->resource.destroy = destroy_shell_surface;
+ shsurf->resource.object.id = id;
+ shsurf->resource.object.interface = &wl_shell_surface_interface;
+ shsurf->resource.object.implementation =
+ (void (**)(void)) &shell_surface_implementation;
+ shsurf->resource.data = shsurf;
+
+ shsurf->surface = surface;
+ shsurf->surface_destroy_listener.func = shell_handle_surface_destroy;
+ wl_list_insert(surface->surface.resource.destroy_listener_list.prev,
+ &shsurf->surface_destroy_listener.link);
+
+ /* init link so its safe to always remove it in destroy_shell_surface */
+ wl_list_init(&shsurf->link);
+
+ shsurf->type = SHELL_SURFACE_NORMAL;
+
+ surface->shell_priv = shsurf;
+
+ wl_client_add_resource(client, &shsurf->resource);
+}
+
+static const struct wl_shell_interface shell_implementation = {
+ shell_create_shell_surface
};
static void
{
struct wlsc_surface *surface =
(struct wlsc_surface *) device->pointer_focus;
- struct shell_surface *priv;
+ struct shell_surface *shsurf;
if (surface == NULL)
return;
- priv = get_shell_surface(surface);
- switch (priv->type) {
+ shsurf = get_shell_surface(surface);
+ switch (shsurf->type) {
case SHELL_SURFACE_PANEL:
case SHELL_SURFACE_BACKGROUND:
case SHELL_SURFACE_FULLSCREEN:
{
struct wlsc_surface *surface =
(struct wlsc_surface *) device->pointer_focus;
- struct wl_resource *resource;
uint32_t edges = 0;
int32_t x, y;
- struct shell_surface *priv;
+ struct shell_surface *shsurf;
if (surface == NULL)
return;
- priv = get_shell_surface(surface);
- switch (priv->type) {
+ shsurf = get_shell_surface(surface);
+ switch (shsurf->type) {
case SHELL_SURFACE_PANEL:
case SHELL_SURFACE_BACKGROUND:
case SHELL_SURFACE_FULLSCREEN:
y = device->grab_y - surface->y;
if (x < surface->width / 3)
- edges |= WL_SHELL_RESIZE_LEFT;
+ edges |= WL_SHELL_SURFACE_RESIZE_LEFT;
else if (x < 2 * surface->width / 3)
edges |= 0;
else
- edges |= WL_SHELL_RESIZE_RIGHT;
+ edges |= WL_SHELL_SURFACE_RESIZE_RIGHT;
if (y < surface->height / 3)
- edges |= WL_SHELL_RESIZE_TOP;
+ edges |= WL_SHELL_SURFACE_RESIZE_TOP;
else if (y < 2 * surface->height / 3)
edges |= 0;
else
- edges |= WL_SHELL_RESIZE_BOTTOM;
-
- resource = /* Find shell resource for surface client */ 0;
-
- /* ... or use wl_shell_surface */
+ edges |= WL_SHELL_SURFACE_RESIZE_BOTTOM;
- wlsc_surface_resize(surface, (struct wlsc_input_device *) device,
- time, edges, resource);
+ wlsc_surface_resize(shsurf, (struct wlsc_input_device *) device,
+ time, edges);
}
static void
struct wl_shell *shell = data;
wl_client_add_object(client, &wl_shell_interface,
- &shell_interface, id, shell);
+ &shell_implementation, id, shell);
}
static void