commit 390414c

Michael Forney  ·  2018-05-26 18:36:07 +0000 UTC
parent 5b20050
Update to stable xdg-shell protocol

For now, xdg_positioner is just a stub.
10 files changed,  +450, -568
+2, -2
 1@@ -6,8 +6,8 @@ protocol/swc-protocol.c
 2 protocol/swc-server-protocol.h
 3 protocol/wayland-drm-protocol.c
 4 protocol/wayland-drm-server-protocol.h
 5-protocol/xdg-shell-unstable-v5-protocol.c
 6-protocol/xdg-shell-unstable-v5-server-protocol.h
 7+protocol/xdg-shell-protocol.c
 8+protocol/xdg-shell-server-protocol.h
 9 
10 /.deps/
11 /swc.pc
+2, -4
 1@@ -52,12 +52,10 @@ SWC_SOURCES =                       \
 2     libswc/view.c                   \
 3     libswc/wayland_buffer.c         \
 4     libswc/window.c                 \
 5-    libswc/xdg_popup.c              \
 6     libswc/xdg_shell.c              \
 7-    libswc/xdg_surface.c            \
 8     protocol/swc-protocol.c         \
 9     protocol/wayland-drm-protocol.c \
10-    protocol/xdg-shell-unstable-v5-protocol.c
11+    protocol/xdg-shell-protocol.c
12 
13 ifeq ($(ENABLE_LIBUDEV),1)
14 $(dir)_CFLAGS += -DENABLE_LIBUDEV
15@@ -80,7 +78,7 @@ SWC_SHARED_OBJECTS = $(SWC_SOURCES:%.c=%.lo)
16 objects = $(foreach obj,$(1),$(dir)/$(obj).o $(dir)/$(obj).lo)
17 $(call objects,compositor panel_manager panel screen): protocol/swc-server-protocol.h
18 $(call objects,drm drm_buffer): protocol/wayland-drm-server-protocol.h
19-$(call objects,xdg_shell xdg_surface xdg_popup): protocol/xdg-shell-unstable-v5-server-protocol.h
20+$(call objects,xdg_shell): protocol/xdg-shell-server-protocol.h
21 $(call objects,pointer): cursor/cursor_data.h
22 
23 $(dir)/libswc-internal.o: $(SWC_STATIC_OBJECTS)
+1, -1
1@@ -1,6 +1,6 @@
2 /* swc: libswc/swc.c
3  *
4- * Copyright (c) 2013, 2014 Michael Forney
5+ * Copyright (c) 2013, 2014, 2018 Michael Forney
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
+0, -104
  1@@ -1,104 +0,0 @@
  2-/* swc: libswc/xdg_popup.c
  3- *
  4- * Copyright (c) 2014 Michael Forney
  5- *
  6- * Permission is hereby granted, free of charge, to any person obtaining a copy
  7- * of this software and associated documentation files (the "Software"), to deal
  8- * in the Software without restriction, including without limitation the rights
  9- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 10- * copies of the Software, and to permit persons to whom the Software is
 11- * furnished to do so, subject to the following conditions:
 12- *
 13- * The above copyright notice and this permission notice shall be included in
 14- * all copies or substantial portions of the Software.
 15- *
 16- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 17- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 18- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 19- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 20- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 21- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 22- * SOFTWARE.
 23- */
 24-
 25-#include "xdg_popup.h"
 26-#include "compositor.h"
 27-#include "surface.h"
 28-#include "util.h"
 29-#include "window.h"
 30-
 31-#include <stdlib.h>
 32-#include "xdg-shell-unstable-v5-server-protocol.h"
 33-
 34-struct xdg_popup {
 35-	struct wl_resource *resource;
 36-	struct compositor_view *view;
 37-	struct wl_listener surface_destroy_listener;
 38-};
 39-
 40-static void
 41-destroy(struct wl_client *client, struct wl_resource *resource)
 42-{
 43-	wl_resource_destroy(resource);
 44-}
 45-
 46-static const struct xdg_popup_interface xdg_popup_implementation = {
 47-	.destroy = destroy,
 48-};
 49-
 50-static void
 51-handle_surface_destroy(struct wl_listener *listener, void *data)
 52-{
 53-	struct xdg_popup *popup = wl_container_of(listener, popup, surface_destroy_listener);
 54-	wl_resource_destroy(popup->resource);
 55-}
 56-
 57-static void
 58-destroy_popup(struct wl_resource *resource)
 59-{
 60-	struct xdg_popup *popup = wl_resource_get_user_data(resource);
 61-
 62-	wl_list_remove(&popup->surface_destroy_listener.link);
 63-	compositor_view_destroy(popup->view);
 64-	free(popup);
 65-}
 66-
 67-struct xdg_popup *
 68-xdg_popup_new(struct wl_client *client, uint32_t version,
 69-              uint32_t id, struct surface *surface, struct surface *parent_surface, int32_t x, int32_t y)
 70-{
 71-	struct xdg_popup *popup;
 72-	struct compositor_view *parent = compositor_view(parent_surface->view);
 73-
 74-	if (!parent)
 75-		goto error0;
 76-
 77-	popup = malloc(sizeof(*popup));
 78-
 79-	if (!popup)
 80-		goto error0;
 81-
 82-	popup->resource = wl_resource_create(client, &xdg_popup_interface, version, id);
 83-
 84-	if (!popup->resource)
 85-		goto error1;
 86-
 87-	popup->surface_destroy_listener.notify = &handle_surface_destroy;
 88-	wl_resource_add_destroy_listener(surface->resource, &popup->surface_destroy_listener);
 89-	wl_resource_set_implementation(popup->resource, &xdg_popup_implementation, popup, &destroy_popup);
 90-
 91-	if (!(popup->view = compositor_create_view(surface)))
 92-		goto error2;
 93-
 94-	view_move(&popup->view->base, parent->base.geometry.x + x, parent->base.geometry.y + y);
 95-	compositor_view_set_parent(popup->view, parent);
 96-
 97-	return popup;
 98-
 99-error2:
100-	wl_resource_destroy(popup->resource);
101-error1:
102-	free(popup);
103-error0:
104-	return NULL;
105-}
+0, -35
 1@@ -1,35 +0,0 @@
 2-/* swc: libswc/xdg_popup.h
 3- *
 4- * Copyright (c) 2014 Michael Forney
 5- *
 6- * Permission is hereby granted, free of charge, to any person obtaining a copy
 7- * of this software and associated documentation files (the "Software"), to deal
 8- * in the Software without restriction, including without limitation the rights
 9- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10- * copies of the Software, and to permit persons to whom the Software is
11- * furnished to do so, subject to the following conditions:
12- *
13- * The above copyright notice and this permission notice shall be included in
14- * all copies or substantial portions of the Software.
15- *
16- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22- * SOFTWARE.
23- */
24-
25-#ifndef SWC_XDG_POPUP_H
26-#define SWC_XDG_POPUP_H
27-
28-#include <stdint.h>
29-
30-struct surface;
31-struct wl_client;
32-
33-struct xdg_popup *xdg_popup_new(struct wl_client *client, uint32_t version, uint32_t id,
34-                                struct surface *surface, struct surface *parent, int32_t x, int32_t y);
35-
36-#endif
+443, -52
  1@@ -1,6 +1,6 @@
  2 /* swc: libswc/xdg_shell.c
  3  *
  4- * Copyright (c) 2014 Michael Forney
  5+ * Copyright (c) 2014, 2018 Michael Forney
  6  *
  7  * Permission is hereby granted, free of charge, to any person obtaining a copy
  8  * of this software and associated documentation files (the "Software"), to deal
  9@@ -23,21 +23,33 @@
 10 
 11 #include "xdg_shell.h"
 12 #include "internal.h"
 13-#include "xdg_popup.h"
 14-#include "xdg_surface.h"
 15+#include "seat.h"
 16+#include "surface.h"
 17+#include "util.h"
 18+#include "window.h"
 19 
 20 #include <assert.h>
 21+#include <stdlib.h>
 22 #include <wayland-server.h>
 23-#include "xdg-shell-unstable-v5-server-protocol.h"
 24+#include "xdg-shell-server-protocol.h"
 25 
 26-#define XDG_SHELL_VERSION 5
 27+struct xdg_surface {
 28+	struct wl_resource *resource, *role;
 29+	struct surface *surface;
 30+	struct wl_listener surface_destroy_listener;
 31+	uint32_t configure_serial;
 32+};
 33 
 34-static_assert(XDG_SHELL_VERSION == XDG_SHELL_VERSION_CURRENT,
 35-              "xdg_shell implementation does not match protocol version");
 36+struct xdg_positioner {
 37+	struct wl_resource *resource;
 38+};
 39 
 40-static struct {
 41-	struct wl_global *global;
 42-} shell;
 43+struct xdg_toplevel {
 44+	struct window window;
 45+	struct wl_resource *resource;
 46+	struct wl_array states;
 47+	struct xdg_surface *xdg_surface;
 48+};
 49 
 50 static void
 51 destroy(struct wl_client *client, struct wl_resource *resource)
 52@@ -45,90 +57,469 @@ destroy(struct wl_client *client, struct wl_resource *resource)
 53 	wl_resource_destroy(resource);
 54 }
 55 
 56+/* xdg_positioner */
 57 static void
 58-use_unstable_version(struct wl_client *client, struct wl_resource *resource, int32_t version)
 59+destroy_positioner(struct wl_resource *resource)
 60 {
 61+	struct xdg_positioner *positioner = wl_resource_get_user_data(resource);
 62+
 63+	free(positioner);
 64 }
 65 
 66 static void
 67-get_xdg_surface(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *surface_resource)
 68+set_size(struct wl_client *client, struct wl_resource *resource, int32_t width, int32_t height)
 69 {
 70-	struct surface *surface = wl_resource_get_user_data(surface_resource);
 71-	struct xdg_surface *xdg_surface;
 72-
 73-	xdg_surface = xdg_surface_new(client, wl_resource_get_version(resource), id, surface);
 74+}
 75 
 76-	if (!xdg_surface)
 77-		wl_resource_post_no_memory(resource);
 78+static void
 79+set_anchor_rect(struct wl_client *client, struct wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height)
 80+{
 81 }
 82 
 83 static void
 84-get_xdg_popup(struct wl_client *client, struct wl_resource *resource,
 85-              uint32_t id, struct wl_resource *surface_resource, struct wl_resource *parent_resource,
 86-              struct wl_resource *seat_resource, uint32_t serial, int32_t x, int32_t y)
 87+set_anchor(struct wl_client *client, struct wl_resource *resource, uint32_t anchor)
 88 {
 89-	struct surface *surface = wl_resource_get_user_data(surface_resource);
 90-	struct surface *parent = wl_resource_get_user_data(parent_resource);
 91-	struct xdg_popup *popup;
 92+}
 93 
 94-	popup = xdg_popup_new(client, wl_resource_get_version(resource), id, surface, parent, x, y);
 95+static void
 96+set_gravity(struct wl_client *client, struct wl_resource *resource, uint32_t gravity)
 97+{
 98+}
 99 
100-	if (!popup)
101-		wl_resource_post_no_memory(resource);
102+static void
103+set_constraint_adjustment(struct wl_client *client, struct wl_resource *resource, uint32_t adjustment)
104+{
105 }
106 
107 static void
108-pong(struct wl_client *client, struct wl_resource *resource, uint32_t serial)
109+set_offset(struct wl_client *client, struct wl_resource *resource, int32_t x, int32_t y)
110 {
111 }
112 
113-static const struct xdg_shell_interface shell_implementation = {
114+static const struct xdg_positioner_interface positioner_implementation = {
115 	.destroy = destroy,
116-	.use_unstable_version = use_unstable_version,
117-	.get_xdg_surface = get_xdg_surface,
118-	.get_xdg_popup = get_xdg_popup,
119-	.pong = pong,
120+	.set_size = set_size,
121+	.set_anchor_rect = set_anchor_rect,
122+	.set_anchor = set_anchor,
123+	.set_gravity = set_gravity,
124+	.set_constraint_adjustment = set_constraint_adjustment,
125+	.set_offset = set_offset,
126 };
127 
128-static int
129-unversioned_dispatch(const void *implementation, void *target,
130-                     uint32_t opcode, const struct wl_message *message, union wl_argument *arguments)
131+/* xdg_toplevel */
132+static void
133+destroy_toplevel(struct wl_resource *resource)
134+{
135+	struct xdg_toplevel *toplevel = wl_resource_get_user_data(resource);
136+
137+	window_finalize(&toplevel->window);
138+	free(toplevel);
139+}
140+
141+static bool
142+add_state(struct xdg_toplevel *toplevel, uint32_t state)
143+{
144+	uint32_t *current_state;
145+
146+	wl_array_for_each (current_state, &toplevel->states) {
147+		if (*current_state == state)
148+			return false;
149+	}
150+
151+	if (!(current_state = wl_array_add(&toplevel->states, sizeof(state)))) {
152+		WARNING("xdg_toplevel: Failed to allocate new state\n");
153+		return false;
154+	}
155+
156+	*current_state = state;
157+	return true;
158+}
159+
160+static bool
161+remove_state(struct xdg_toplevel *toplevel, uint32_t state)
162+{
163+	uint32_t *current_state;
164+
165+	wl_array_for_each (current_state, &toplevel->states) {
166+		if (*current_state == state) {
167+			array_remove(&toplevel->states, current_state, sizeof(state));
168+			return true;
169+		}
170+	}
171+
172+	return false;
173+}
174+
175+static uint32_t
176+send_configure(struct xdg_toplevel *toplevel, int32_t width, int32_t height) {
177+	uint32_t serial = wl_display_next_serial(swc.display);
178+
179+	if (width < 0)
180+		width = toplevel->window.configure.width;
181+	if (height < 0)
182+		height = toplevel->window.configure.height;
183+
184+	xdg_toplevel_send_configure(toplevel->resource, width, height, &toplevel->states);
185+	xdg_surface_send_configure(toplevel->xdg_surface->resource, serial);
186+
187+	return serial;
188+}
189+
190+static void
191+configure(struct window *window, uint32_t width, uint32_t height)
192+{
193+	struct xdg_toplevel *toplevel = wl_container_of(window, toplevel, window);
194+
195+	window->configure.acknowledged = false;
196+	toplevel->xdg_surface->configure_serial = send_configure(toplevel, width, height);
197+}
198+
199+static void
200+focus(struct window *window)
201+{
202+	struct xdg_toplevel *toplevel = wl_container_of(window, toplevel, window);
203+
204+	add_state(toplevel, XDG_TOPLEVEL_STATE_ACTIVATED);
205+	send_configure(toplevel, -1, -1);
206+}
207+
208+static void
209+unfocus(struct window *window)
210 {
211-	struct wl_resource *resource = target;
212+	struct xdg_toplevel *toplevel = wl_container_of(window, toplevel, window);
213 
214-	if (opcode != 1) {
215-		wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
216-		                       "use_unstable_version must be called first");
217-		return 0;
218+	remove_state(toplevel, XDG_TOPLEVEL_STATE_ACTIVATED);
219+	send_configure(toplevel, -1, -1);
220+}
221+
222+static void
223+close(struct window *window)
224+{
225+	struct xdg_toplevel *toplevel = wl_container_of(window, toplevel, window);
226+
227+	xdg_toplevel_send_close(toplevel->resource);
228+}
229+
230+static void
231+set_mode(struct window *window, unsigned mode)
232+{
233+	struct xdg_toplevel *toplevel = wl_container_of(window, toplevel, window);
234+
235+	switch (window->mode) {
236+	case WINDOW_MODE_TILED:
237+		remove_state(toplevel, XDG_TOPLEVEL_STATE_MAXIMIZED);
238+		break;
239+	case WINDOW_MODE_FULLSCREEN:
240+		remove_state(toplevel, XDG_TOPLEVEL_STATE_FULLSCREEN);
241+		break;
242 	}
243 
244-	if (arguments[0].i != XDG_SHELL_VERSION) {
245-		wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
246-		                       "incompatible xdg_shell versions, server: %d, client: %d",
247-		                       XDG_SHELL_VERSION, arguments[0].i);
248-		return 0;
249+	switch (mode) {
250+	case WINDOW_MODE_TILED:
251+		add_state(toplevel, XDG_TOPLEVEL_STATE_MAXIMIZED);
252+		break;
253+	case WINDOW_MODE_FULLSCREEN:
254+		add_state(toplevel, XDG_TOPLEVEL_STATE_FULLSCREEN);
255+		break;
256 	}
257 
258-	wl_resource_set_implementation(resource, &shell_implementation, NULL, NULL);
259-	return 1;
260+	send_configure(toplevel, -1, -1);
261 }
262 
263+static const struct window_impl toplevel_window_impl = {
264+	.configure = configure,
265+	.focus = focus,
266+	.unfocus = unfocus,
267+	.close = close,
268+	.set_mode = set_mode,
269+};
270+
271 static void
272-bind_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id)
273+set_parent(struct wl_client *client, struct wl_resource *resource, struct wl_resource *parent_resource)
274+{
275+	struct xdg_toplevel *toplevel = wl_resource_get_user_data(resource), *parent = NULL;
276+
277+	if (parent_resource)
278+		parent = wl_resource_get_user_data(parent_resource);
279+	window_set_parent(&toplevel->window, parent ? &parent->window : NULL);
280+}
281+
282+static void
283+set_title(struct wl_client *client, struct wl_resource *resource, const char *title)
284+{
285+	struct xdg_toplevel *toplevel = wl_resource_get_user_data(resource);
286+	window_set_title(&toplevel->window, title, -1);
287+}
288+
289+static void
290+set_app_id(struct wl_client *client, struct wl_resource *resource, const char *app_id)
291+{
292+	struct xdg_toplevel *toplevel = wl_resource_get_user_data(resource);
293+	window_set_app_id(&toplevel->window, app_id);
294+}
295+
296+static void
297+show_window_menu(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat, uint32_t serial, int32_t x, int32_t y)
298+{
299+}
300+
301+static void
302+move(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat, uint32_t serial)
303+{
304+	struct xdg_toplevel *toplevel = wl_resource_get_user_data(resource);
305+	struct button *button;
306+
307+	button = pointer_get_button(swc.seat->pointer, serial);
308+	if (button)
309+		window_begin_move(&toplevel->window, button);
310+}
311+
312+static void
313+resize(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat, uint32_t serial, uint32_t edges)
314+{
315+	struct xdg_toplevel *toplevel = wl_resource_get_user_data(resource);
316+	struct button *button;
317+
318+	button = pointer_get_button(swc.seat->pointer, serial);
319+	if (button)
320+		window_begin_resize(&toplevel->window, edges, button);
321+}
322+
323+static void
324+set_max_size(struct wl_client *client, struct wl_resource *resource, int32_t width, int32_t height)
325+{
326+}
327+
328+static void
329+set_min_size(struct wl_client *client, struct wl_resource *resource, int32_t width, int32_t height)
330+{
331+}
332+
333+static void
334+set_maximized(struct wl_client *client, struct wl_resource *resource)
335+{
336+}
337+
338+static void
339+unset_maximized(struct wl_client *client, struct wl_resource *resource)
340+{
341+}
342+
343+static void
344+set_fullscreen(struct wl_client *client, struct wl_resource *resource, struct wl_resource *output)
345+{
346+}
347+
348+static void
349+unset_fullscreen(struct wl_client *client, struct wl_resource *resource)
350+{
351+}
352+
353+static void
354+set_minimized(struct wl_client *client, struct wl_resource *resource)
355+{
356+}
357+
358+static const struct xdg_toplevel_interface toplevel_impl = {
359+	.destroy = destroy,
360+	.set_parent = set_parent,
361+	.set_title = set_title,
362+	.set_app_id = set_app_id,
363+	.show_window_menu = show_window_menu,
364+	.move = move,
365+	.resize = resize,
366+	.set_max_size = set_max_size,
367+	.set_min_size = set_min_size,
368+	.set_maximized = set_maximized,
369+	.unset_maximized = unset_maximized,
370+	.set_fullscreen = set_fullscreen,
371+	.unset_fullscreen = unset_fullscreen,
372+	.set_minimized = set_minimized,
373+};
374+
375+static struct xdg_toplevel *
376+xdg_toplevel_new(struct wl_client *client, uint32_t version, uint32_t id, struct xdg_surface *xdg_surface)
377+{
378+	struct xdg_toplevel *toplevel;
379+
380+	toplevel = malloc(sizeof(*toplevel));
381+	if (!toplevel)
382+		goto error0;
383+	toplevel->xdg_surface = xdg_surface;
384+	toplevel->resource = wl_resource_create(client, &xdg_toplevel_interface, version, id);
385+	if (!toplevel->resource)
386+		goto error1;
387+	window_initialize(&toplevel->window, &toplevel_window_impl, xdg_surface->surface);
388+	wl_array_init(&toplevel->states);
389+	wl_resource_set_implementation(toplevel->resource, &toplevel_impl, toplevel, &destroy_toplevel);
390+	window_manage(&toplevel->window);
391+
392+	return toplevel;
393+
394+error1:
395+	free(toplevel);
396+error0:
397+	return NULL;
398+}
399+
400+/* xdg_surface */
401+static void
402+get_toplevel(struct wl_client *client, struct wl_resource *resource, uint32_t id)
403+{
404+	struct xdg_surface *xdg_surface = wl_resource_get_user_data(resource);
405+	struct xdg_toplevel *toplevel;
406+
407+	toplevel = xdg_toplevel_new(client, wl_resource_get_version(resource), id, xdg_surface);
408+	if (!toplevel) {
409+		wl_client_post_no_memory(client);
410+		return;
411+	}
412+	xdg_surface->role = toplevel->resource;
413+}
414+
415+static void
416+get_popup(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *parent, struct wl_resource *positioner)
417+{
418+}
419+
420+static void
421+ack_configure(struct wl_client *client, struct wl_resource *resource, uint32_t serial)
422+{
423+	struct xdg_surface *xdg_surface = wl_resource_get_user_data(resource);
424+	struct window *window;
425+
426+	if (!xdg_surface->role)
427+		return;
428+	window = wl_resource_get_user_data(xdg_surface->role);
429+	if (window && serial == xdg_surface->configure_serial)
430+		window->configure.acknowledged = true;
431+}
432+
433+static void
434+set_window_geometry(struct wl_client *client, struct wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height)
435+{
436+}
437+
438+static const struct xdg_surface_interface xdg_surface_impl = {
439+	.destroy = destroy,
440+	.get_toplevel = get_toplevel,
441+	.get_popup = get_popup,
442+	.ack_configure = ack_configure,
443+	.set_window_geometry = set_window_geometry,
444+};
445+
446+static void
447+handle_surface_destroy(struct wl_listener *listener, void *data)
448+{
449+	struct xdg_surface *xdg_surface = wl_container_of(listener, xdg_surface, surface_destroy_listener);
450+
451+	wl_resource_destroy(xdg_surface->resource);
452+}
453+
454+static void
455+destroy_xdg_surface(struct wl_resource *resource)
456+{
457+	struct xdg_surface *xdg_surface = wl_resource_get_user_data(resource);
458+
459+	wl_list_remove(&xdg_surface->surface_destroy_listener.link);
460+	wl_resource_destroy(xdg_surface->role);
461+	free(xdg_surface);
462+}
463+
464+static struct xdg_surface *
465+xdg_surface_new(struct wl_client *client, uint32_t version, uint32_t id, struct surface *surface)
466+{
467+	struct xdg_surface *xdg_surface;
468+
469+	xdg_surface = malloc(sizeof(*xdg_surface));
470+	if (!xdg_surface)
471+		goto error0;
472+	xdg_surface->resource = wl_resource_create(client, &xdg_surface_interface, version, id);
473+	if (!xdg_surface->resource)
474+		goto error1;
475+	xdg_surface->surface = surface;
476+	xdg_surface->surface_destroy_listener.notify = &handle_surface_destroy;
477+	wl_resource_add_destroy_listener(surface->resource, &xdg_surface->surface_destroy_listener);
478+	wl_resource_set_implementation(xdg_surface->resource, &xdg_surface_impl, xdg_surface, destroy_xdg_surface);
479+
480+	return xdg_surface;
481+
482+error1:
483+	free(xdg_surface);
484+error0:
485+	return NULL;
486+}
487+
488+/* xdg_shell */
489+static struct {
490+	struct wl_global *global;
491+} shell;
492+
493+static void
494+create_positioner(struct wl_client *client, struct wl_resource *resource, uint32_t id)
495+{
496+	struct xdg_positioner *positioner;
497+	uint32_t version;
498+
499+	positioner = malloc(sizeof(*positioner));
500+	if (!positioner)
501+		goto error0;
502+	version = wl_resource_get_version(resource);
503+	positioner->resource = wl_resource_create(client, &xdg_positioner_interface, version, id);
504+	if (!positioner->resource)
505+		goto error1;
506+	wl_resource_set_implementation(positioner->resource, &positioner_implementation, positioner, &destroy_positioner);
507+	return;
508+
509+error1:
510+	free(positioner);
511+error0:
512+	wl_resource_post_no_memory(resource);
513+}
514+
515+static void
516+get_xdg_surface(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *surface_resource)
517+{
518+	struct xdg_surface *xdg_surface;
519+	struct surface *surface = wl_resource_get_user_data(surface_resource);
520+
521+	xdg_surface = xdg_surface_new(client, wl_resource_get_version(resource), id, surface);
522+	if (!xdg_surface)
523+		wl_client_post_no_memory(client);
524+}
525+
526+static void
527+pong(struct wl_client *client, struct wl_resource *resource, uint32_t serial)
528+{
529+}
530+
531+static const struct xdg_wm_base_interface wm_base_impl = {
532+	.destroy = destroy,
533+	.create_positioner = create_positioner,
534+	.get_xdg_surface = get_xdg_surface,
535+	.pong = pong,
536+};
537+
538+static void
539+bind_wm_base(struct wl_client *client, void *data, uint32_t version, uint32_t id)
540 {
541 	struct wl_resource *resource;
542 
543 	if (version > 1)
544 		version = 1;
545 
546-	resource = wl_resource_create(client, &xdg_shell_interface, version, id);
547-	wl_resource_set_dispatcher(resource, &unversioned_dispatch, NULL, NULL, NULL);
548+	resource = wl_resource_create(client, &xdg_wm_base_interface, version, id);
549+	if (!resource) {
550+		wl_client_post_no_memory(client);
551+		return;
552+	}
553+	wl_resource_set_implementation(resource, &wm_base_impl, NULL, NULL);
554 }
555 
556 bool
557 xdg_shell_initialize(void)
558 {
559-	shell.global = wl_global_create(swc.display, &xdg_shell_interface, 1, NULL, &bind_shell);
560+	shell.global = wl_global_create(swc.display, &xdg_wm_base_interface, 1, NULL, &bind_wm_base);
561 	return shell.global;
562 }
563 
+1, -1
1@@ -1,6 +1,6 @@
2 /* swc: libswc/xdg_shell.h
3  *
4- * Copyright (c) 2014 Michael Forney
5+ * Copyright (c) 2018 Michael Forney
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
+0, -334
  1@@ -1,334 +0,0 @@
  2-/* swc: libswc/xdg_surface.c
  3- *
  4- * Copyright (c) 2014 Michael Forney
  5- *
  6- * Permission is hereby granted, free of charge, to any person obtaining a copy
  7- * of this software and associated documentation files (the "Software"), to deal
  8- * in the Software without restriction, including without limitation the rights
  9- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 10- * copies of the Software, and to permit persons to whom the Software is
 11- * furnished to do so, subject to the following conditions:
 12- *
 13- * The above copyright notice and this permission notice shall be included in
 14- * all copies or substantial portions of the Software.
 15- *
 16- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 17- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 18- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 19- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 20- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 21- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 22- * SOFTWARE.
 23- */
 24-
 25-#include "xdg_surface.h"
 26-#include "compositor.h"
 27-#include "internal.h"
 28-#include "seat.h"
 29-#include "surface.h"
 30-#include "util.h"
 31-#include "view.h"
 32-#include "window.h"
 33-
 34-#include <stdlib.h>
 35-#include "xdg-shell-unstable-v5-server-protocol.h"
 36-
 37-struct xdg_surface {
 38-	struct window window;
 39-	struct wl_resource *resource;
 40-	struct wl_listener surface_destroy_listener;
 41-	struct wl_array states;
 42-	uint32_t configure_serial;
 43-};
 44-
 45-static bool
 46-add_state(struct xdg_surface *xdg_surface, uint32_t state)
 47-{
 48-	uint32_t *current_state;
 49-
 50-	wl_array_for_each (current_state, &xdg_surface->states) {
 51-		if (*current_state == state)
 52-			return false;
 53-	}
 54-
 55-	if (!(current_state = wl_array_add(&xdg_surface->states, sizeof(state)))) {
 56-		WARNING("xdg_surface: Failed to allocate new state\n");
 57-		return false;
 58-	}
 59-
 60-	*current_state = state;
 61-	return true;
 62-}
 63-
 64-static bool
 65-remove_state(struct xdg_surface *xdg_surface, uint32_t state)
 66-{
 67-	uint32_t *current_state;
 68-
 69-	wl_array_for_each (current_state, &xdg_surface->states) {
 70-		if (*current_state == state) {
 71-			array_remove(&xdg_surface->states, current_state, sizeof(state));
 72-			return true;
 73-		}
 74-	}
 75-
 76-	return false;
 77-}
 78-
 79-static uint32_t
 80-send_configure(struct xdg_surface *xdg_surface, int32_t width, int32_t height) {
 81-	uint32_t serial = wl_display_next_serial(swc.display);
 82-
 83-	if (width < 0)
 84-		width = xdg_surface->window.configure.width;
 85-	if (height < 0)
 86-		height = xdg_surface->window.configure.height;
 87-
 88-	xdg_surface_send_configure(xdg_surface->resource, width, height, &xdg_surface->states, serial);
 89-
 90-	return serial;
 91-}
 92-
 93-static void
 94-configure(struct window *window, uint32_t width, uint32_t height)
 95-{
 96-	struct xdg_surface *xdg_surface = wl_container_of(window, xdg_surface, window);
 97-
 98-	window->configure.acknowledged = false;
 99-	xdg_surface->configure_serial = send_configure(xdg_surface, width, height);
100-}
101-
102-static void
103-focus(struct window *window)
104-{
105-	struct xdg_surface *xdg_surface = wl_container_of(window, xdg_surface, window);
106-
107-	add_state(xdg_surface, XDG_SURFACE_STATE_ACTIVATED);
108-	send_configure(xdg_surface, -1, -1);
109-}
110-
111-static void
112-unfocus(struct window *window)
113-{
114-	struct xdg_surface *xdg_surface = wl_container_of(window, xdg_surface, window);
115-
116-	remove_state(xdg_surface, XDG_SURFACE_STATE_ACTIVATED);
117-	send_configure(xdg_surface, -1, -1);
118-}
119-
120-static void
121-close(struct window *window)
122-{
123-	struct xdg_surface *xdg_surface = wl_container_of(window, xdg_surface, window);
124-
125-	xdg_surface_send_close(xdg_surface->resource);
126-}
127-
128-static void
129-set_mode(struct window *window, unsigned mode)
130-{
131-	struct xdg_surface *xdg_surface = wl_container_of(window, xdg_surface, window);
132-
133-	switch (window->mode) {
134-	case WINDOW_MODE_TILED:
135-		remove_state(xdg_surface, XDG_SURFACE_STATE_MAXIMIZED);
136-		break;
137-	case WINDOW_MODE_FULLSCREEN:
138-		remove_state(xdg_surface, XDG_SURFACE_STATE_FULLSCREEN);
139-		break;
140-	}
141-
142-	switch (mode) {
143-	case WINDOW_MODE_TILED:
144-		add_state(xdg_surface, XDG_SURFACE_STATE_MAXIMIZED);
145-		break;
146-	case WINDOW_MODE_FULLSCREEN:
147-		add_state(xdg_surface, XDG_SURFACE_STATE_FULLSCREEN);
148-		break;
149-	}
150-
151-	send_configure(xdg_surface, -1, -1);
152-}
153-
154-static const struct window_impl xdg_surface_window_impl = {
155-	.configure = &configure,
156-	.focus = &focus,
157-	.unfocus = &unfocus,
158-	.close = &close,
159-	.set_mode = &set_mode,
160-};
161-
162-static void
163-destroy(struct wl_client *client, struct wl_resource *resource)
164-{
165-	wl_resource_destroy(resource);
166-}
167-
168-static void
169-set_parent(struct wl_client *client, struct wl_resource *resource, struct wl_resource *parent_resource)
170-{
171-	struct xdg_surface *xdg_surface = wl_resource_get_user_data(resource), *parent_surface;
172-	struct window *parent_window = NULL;
173-
174-	if (parent_resource) {
175-		parent_surface = wl_resource_get_user_data(parent_resource);
176-		parent_window = &parent_surface->window;
177-	}
178-
179-	window_set_parent(&xdg_surface->window, parent_window);
180-}
181-
182-static void
183-set_title(struct wl_client *client, struct wl_resource *resource, const char *title)
184-{
185-	struct xdg_surface *xdg_surface = wl_resource_get_user_data(resource);
186-	window_set_title(&xdg_surface->window, title, -1);
187-}
188-
189-static void
190-set_app_id(struct wl_client *client, struct wl_resource *resource, const char *app_id)
191-{
192-	struct xdg_surface *surface = wl_resource_get_user_data(resource);
193-	window_set_app_id(&surface->window, app_id);
194-}
195-
196-static void
197-show_window_menu(struct wl_client *client, struct wl_resource *resource,
198-                 struct wl_resource *seat_resource, uint32_t serial, int32_t x, int32_t y)
199-{
200-}
201-
202-static void
203-move(struct wl_client *client, struct wl_resource *resource, struct wl_resource *seat_resource, uint32_t serial)
204-{
205-	struct xdg_surface *xdg_surface = wl_resource_get_user_data(resource);
206-	struct button *button;
207-
208-	if (!(button = pointer_get_button(swc.seat->pointer, serial)))
209-		return;
210-
211-	window_begin_move(&xdg_surface->window, button);
212-}
213-
214-static void
215-resize(struct wl_client *client, struct wl_resource *resource,
216-       struct wl_resource *seat_resource, uint32_t serial, uint32_t edges)
217-{
218-	struct xdg_surface *xdg_surface = wl_resource_get_user_data(resource);
219-	struct button *button;
220-
221-	if (!(button = pointer_get_button(swc.seat->pointer, serial)))
222-		return;
223-
224-	window_begin_resize(&xdg_surface->window, edges, button);
225-}
226-
227-static void
228-ack_configure(struct wl_client *client, struct wl_resource *resource, uint32_t serial)
229-{
230-	struct xdg_surface *xdg_surface = wl_resource_get_user_data(resource);
231-
232-	if (serial == xdg_surface->configure_serial)
233-		xdg_surface->window.configure.acknowledged = true;
234-}
235-
236-static void
237-set_window_geometry(struct wl_client *client, struct wl_resource *resource,
238-                    int32_t x, int32_t y, int32_t width, int32_t height)
239-{
240-	/* TODO: Implement set_window_geometry. */
241-}
242-
243-static void
244-set_maximized(struct wl_client *client, struct wl_resource *resource)
245-{
246-	/* TODO: Implement set_maximized. */
247-}
248-
249-static void
250-unset_maximized(struct wl_client *client, struct wl_resource *resource)
251-{
252-	/* TODO: Implement unset_maximized. */
253-}
254-
255-static void
256-set_fullscreen(struct wl_client *client, struct wl_resource *resource, struct wl_resource *output_resource)
257-{
258-	/* TODO: Implement set_fullscreen. */
259-}
260-
261-static void
262-unset_fullscreen(struct wl_client *client, struct wl_resource *resource)
263-{
264-	/* TODO: Implement unset_fullscreen. */
265-}
266-
267-static void
268-set_minimized(struct wl_client *client, struct wl_resource *resource)
269-{
270-	/* TODO: Implement set_minimized. */
271-}
272-
273-static const struct xdg_surface_interface xdg_surface_implementation = {
274-	.destroy = destroy,
275-	.set_parent = set_parent,
276-	.set_title = set_title,
277-	.set_app_id = set_app_id,
278-	.show_window_menu = show_window_menu,
279-	.move = move,
280-	.resize = resize,
281-	.ack_configure = ack_configure,
282-	.set_window_geometry = set_window_geometry,
283-	.set_maximized = set_maximized,
284-	.unset_maximized = unset_maximized,
285-	.set_fullscreen = set_fullscreen,
286-	.unset_fullscreen = unset_fullscreen,
287-	.set_minimized = set_minimized,
288-};
289-
290-static void
291-handle_surface_destroy(struct wl_listener *listener, void *data)
292-{
293-	struct xdg_surface *xdg_surface = wl_container_of(listener, xdg_surface, surface_destroy_listener);
294-	wl_resource_destroy(xdg_surface->resource);
295-}
296-
297-static void
298-destroy_xdg_surface(struct wl_resource *resource)
299-{
300-	struct xdg_surface *xdg_surface = wl_resource_get_user_data(resource);
301-
302-	wl_list_remove(&xdg_surface->surface_destroy_listener.link);
303-	window_finalize(&xdg_surface->window);
304-	free(xdg_surface);
305-}
306-
307-struct xdg_surface *
308-xdg_surface_new(struct wl_client *client, uint32_t version, uint32_t id, struct surface *surface)
309-{
310-	struct xdg_surface *xdg_surface;
311-
312-	xdg_surface = malloc(sizeof(*xdg_surface));
313-
314-	if (!xdg_surface)
315-		goto error0;
316-
317-	xdg_surface->resource = wl_resource_create(client, &xdg_surface_interface, version, id);
318-
319-	if (!xdg_surface->resource)
320-		goto error1;
321-
322-	window_initialize(&xdg_surface->window, &xdg_surface_window_impl, surface);
323-	xdg_surface->surface_destroy_listener.notify = &handle_surface_destroy;
324-	wl_array_init(&xdg_surface->states);
325-	wl_resource_add_destroy_listener(surface->resource, &xdg_surface->surface_destroy_listener);
326-	wl_resource_set_implementation(xdg_surface->resource, &xdg_surface_implementation, xdg_surface, &destroy_xdg_surface);
327-	window_manage(&xdg_surface->window);
328-
329-	return xdg_surface;
330-
331-error1:
332-	free(xdg_surface);
333-error0:
334-	return NULL;
335-}
+0, -34
 1@@ -1,34 +0,0 @@
 2-/* swc: libswc/xdg_surface.h
 3- *
 4- * Copyright (c) 2014 Michael Forney
 5- *
 6- * Permission is hereby granted, free of charge, to any person obtaining a copy
 7- * of this software and associated documentation files (the "Software"), to deal
 8- * in the Software without restriction, including without limitation the rights
 9- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10- * copies of the Software, and to permit persons to whom the Software is
11- * furnished to do so, subject to the following conditions:
12- *
13- * The above copyright notice and this permission notice shall be included in
14- * all copies or substantial portions of the Software.
15- *
16- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22- * SOFTWARE.
23- */
24-
25-#ifndef SWC_XDG_SURFACE_H
26-#define SWC_XDG_SURFACE_H
27-
28-#include <stdint.h>
29-
30-struct surface;
31-struct wl_client;
32-
33-struct xdg_surface *xdg_surface_new(struct wl_client *client, uint32_t version, uint32_t id, struct surface *surface);
34-
35-#endif
+1, -1
1@@ -6,7 +6,7 @@ wayland_protocols := $(call pkgconfig,wayland-protocols,variable=pkgdatadir,DATA
2 PROTOCOL_EXTENSIONS =           \
3     $(dir)/swc.xml              \
4     $(dir)/wayland-drm.xml      \
5-    $(wayland_protocols)/unstable/xdg-shell/xdg-shell-unstable-v5.xml
6+    $(wayland_protocols)/stable/xdg-shell/xdg-shell.xml
7 
8 $(dir)_PACKAGES := wayland-server
9