commit bf972a9
Michael Forney
·
2014-10-01 04:40:18 +0000 UTC
parent 8e1d3bf
Implement xdg-shell Fixes #2
12 files changed,
+1140,
-6
+2,
-0
1@@ -6,6 +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-protocol.c
6+protocol/xdg-shell-server-protocol.h
7
8 /.deps/
9 /swc.pc
+6,
-1
1@@ -56,9 +56,13 @@ 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 libswc/xkb.c \
9 protocol/swc-protocol.c \
10- protocol/wayland-drm-protocol.c
11+ protocol/wayland-drm-protocol.c \
12+ protocol/xdg-shell-protocol.c
13
14 ifeq ($(ENABLE_LIBINPUT),1)
15 $(dir)_CFLAGS += -DENABLE_LIBINPUT
16@@ -87,6 +91,7 @@ SWC_SHARED_OBJECTS = $(SWC_SOURCES:%.c=%.lo)
17 objects = $(foreach obj,$(1),$(dir)/$(obj).o $(dir)/$(obj).lo)
18 $(call objects,compositor panel_manager panel screen): protocol/swc-server-protocol.h
19 $(call objects,drm drm_buffer): protocol/wayland-drm-server-protocol.h
20+$(call objects,xdg_shell xdg_surface xdg_popup): protocol/xdg-shell-server-protocol.h
21 $(call objects,pointer): cursor/cursor_data.h
22
23 $(dir)/libswc.a: $(SWC_STATIC_OBJECTS)
+12,
-3
1@@ -37,6 +37,7 @@
2 #include "shm.h"
3 #include "util.h"
4 #include "window.h"
5+#include "xdg_shell.h"
6 #ifdef ENABLE_XWAYLAND
7 # include "xserver.h"
8 #endif
9@@ -161,17 +162,23 @@ bool swc_initialize(struct wl_display * display,
10 goto error8;
11 }
12
13+ if (!xdg_shell_initialize())
14+ {
15+ ERROR("Could not initialize XDG shell\n");
16+ goto error9;
17+ }
18+
19 if (!panel_manager_initialize())
20 {
21 ERROR("Could not initialize panel manager\n");
22- goto error9;
23+ goto error10;
24 }
25
26 #ifdef ENABLE_XWAYLAND
27 if (!xserver_initialize())
28 {
29 ERROR("Could not initialize xwayland\n");
30- goto error10;
31+ goto error11;
32 }
33 #endif
34
35@@ -180,9 +187,11 @@ bool swc_initialize(struct wl_display * display,
36 return true;
37
38 #ifdef ENABLE_XWAYLAND
39- error10:
40+ error11:
41 panel_manager_finalize();
42 #endif
43+ error10:
44+ xdg_shell_finalize();
45 error9:
46 swc_shell_finalize();
47 error8:
+1,
-1
1@@ -54,7 +54,7 @@ struct window
2 struct compositor_view * view;
3 struct view_handler view_handler;
4 bool managed;
5- enum window_mode mode;
6+ unsigned mode;
7
8 struct
9 {
+111,
-0
1@@ -0,0 +1,111 @@
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+#include "protocol/xdg-shell-server-protocol.h"
31+
32+#include <stdlib.h>
33+
34+struct xdg_popup
35+{
36+ struct wl_resource * resource;
37+ struct compositor_view * view;
38+ struct wl_listener surface_destroy_listener;
39+};
40+
41+static void 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 handle_surface_destroy(struct wl_listener * listener, void * data)
51+{
52+ struct xdg_popup * popup
53+ = wl_container_of(listener, popup, surface_destroy_listener);
54+
55+ wl_resource_destroy(popup->resource);
56+}
57+
58+static void 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 * xdg_popup_new(struct wl_client * client,
68+ uint32_t version, uint32_t id,
69+ struct swc_surface * surface,
70+ struct swc_surface * parent_surface,
71+ int32_t x, int32_t y)
72+{
73+ struct xdg_popup * popup;
74+ struct compositor_view * parent = compositor_view(parent_surface->view);
75+
76+ if (!parent)
77+ goto error0;
78+
79+ popup = malloc(sizeof *popup);
80+
81+ if (!popup)
82+ goto error0;
83+
84+ popup->resource = wl_resource_create(client, &xdg_popup_interface,
85+ version, id);
86+
87+ if (!popup->resource)
88+ goto error1;
89+
90+ popup->surface_destroy_listener.notify = &handle_surface_destroy;
91+ wl_resource_add_destroy_listener(surface->resource,
92+ &popup->surface_destroy_listener);
93+ wl_resource_set_implementation(popup->resource, &xdg_popup_implementation,
94+ popup, &destroy_popup);
95+
96+ if (!(popup->view = swc_compositor_create_view(surface)))
97+ goto error2;
98+
99+ view_move(&popup->view->base,
100+ parent->base.geometry.x + x, parent->base.geometry.y + y);
101+ compositor_view_set_parent(popup->view, parent);
102+
103+ return popup;
104+
105+ error2:
106+ wl_resource_destroy(popup->resource);
107+ error1:
108+ free(popup);
109+ error0:
110+ return NULL;
111+}
112+
+39,
-0
1@@ -0,0 +1,39 @@
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 swc_surface;
31+struct wl_client;
32+
33+struct xdg_popup * xdg_popup_new(struct wl_client * client,
34+ uint32_t version, uint32_t id,
35+ struct swc_surface * surface,
36+ struct swc_surface * parent,
37+ int32_t x, int32_t y);
38+
39+#endif
40+
+144,
-0
1@@ -0,0 +1,144 @@
2+/* swc: libswc/xdg_shell.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_shell.h"
26+#include "internal.h"
27+#include "xdg_popup.h"
28+#include "xdg_surface.h"
29+
30+#include <assert.h>
31+#include <wayland-server.h>
32+#include "protocol/xdg-shell-server-protocol.h"
33+
34+#define XDG_SHELL_VERSION 4
35+
36+static_assert(XDG_SHELL_VERSION == XDG_SHELL_VERSION_CURRENT,
37+ "xdg_shell implementation does not match protocol version");
38+
39+static struct
40+{
41+ struct wl_global * global;
42+} shell;
43+
44+static void use_unstable_version(struct wl_client * client,
45+ struct wl_resource * resource, int32_t version)
46+{
47+}
48+
49+static void get_xdg_surface(struct wl_client * client,
50+ struct wl_resource * resource, uint32_t id,
51+ struct wl_resource * surface_resource)
52+{
53+ struct swc_surface * surface = wl_resource_get_user_data(surface_resource);
54+ struct xdg_surface * xdg_surface;
55+
56+ xdg_surface = xdg_surface_new(client, wl_resource_get_version(resource), id,
57+ surface);
58+
59+ if (!xdg_surface)
60+ wl_resource_post_no_memory(resource);
61+}
62+
63+static void get_xdg_popup(struct wl_client * client,
64+ struct wl_resource * resource, uint32_t id,
65+ struct wl_resource * surface_resource,
66+ struct wl_resource * parent_resource,
67+ struct wl_resource * seat_resource,
68+ uint32_t serial, int32_t x, int32_t y, uint32_t flags)
69+{
70+ struct swc_surface * surface = wl_resource_get_user_data(surface_resource);
71+ struct swc_surface * parent = wl_resource_get_user_data(parent_resource);
72+ struct xdg_popup * popup;
73+
74+ popup = xdg_popup_new(client, wl_resource_get_version(resource), id,
75+ surface, parent, x, y);
76+
77+ if (!popup)
78+ wl_resource_post_no_memory(resource);
79+}
80+
81+static void pong(struct wl_client * client, struct wl_resource * resource,
82+ uint32_t serial)
83+{
84+}
85+
86+static const struct xdg_shell_interface shell_implementation = {
87+ .use_unstable_version = &use_unstable_version,
88+ .get_xdg_surface = &get_xdg_surface,
89+ .get_xdg_popup = &get_xdg_popup,
90+ .pong = &pong
91+};
92+
93+static int unversioned_dispatch(const void * implementation, void * target,
94+ uint32_t opcode,
95+ const struct wl_message * message,
96+ union wl_argument * arguments)
97+{
98+ struct wl_resource * resource = target;
99+
100+ if (opcode != 0)
101+ {
102+ wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
103+ "use_unstable_version must be called first");
104+ return 0;
105+ }
106+
107+ if (arguments[0].i != XDG_SHELL_VERSION)
108+ {
109+ wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
110+ "incompatible xdg_shell versions, "
111+ "server: %d, client: %d",
112+ XDG_SHELL_VERSION, arguments[0].i);
113+ return 0;
114+ }
115+
116+ wl_resource_set_implementation(resource, &shell_implementation, NULL, NULL);
117+ return 1;
118+}
119+
120+static void bind_shell(struct wl_client * client, void * data,
121+ uint32_t version, uint32_t id)
122+{
123+ struct wl_resource * resource;
124+
125+ if (version >= 1)
126+ version = 1;
127+
128+ resource = wl_resource_create(client, &xdg_shell_interface, version, id);
129+ wl_resource_set_dispatcher(resource, &unversioned_dispatch,
130+ NULL, NULL, NULL);
131+}
132+
133+bool xdg_shell_initialize()
134+{
135+ shell.global = wl_global_create(swc.display, &xdg_shell_interface, 1,
136+ NULL, &bind_shell);
137+
138+ return shell.global;
139+}
140+
141+void xdg_shell_finalize()
142+{
143+ wl_global_destroy(shell.global);
144+}
145+
+33,
-0
1@@ -0,0 +1,33 @@
2+/* swc: libswc/xdg_shell.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_SHELL_H
26+#define SWC_XDG_SHELL_H
27+
28+#include <stdbool.h>
29+
30+bool xdg_shell_initialize();
31+void xdg_shell_finalize();
32+
33+#endif
34+
+340,
-0
1@@ -0,0 +1,340 @@
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+#include "protocol/xdg-shell-server-protocol.h"
34+
35+#include <stdlib.h>
36+
37+struct xdg_surface
38+{
39+ struct window window;
40+ struct wl_resource * resource;
41+ struct wl_listener surface_destroy_listener;
42+ struct wl_array states;
43+ uint32_t configure_serial;
44+};
45+
46+static bool 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+ {
52+ if (*current_state == state)
53+ return false;
54+ }
55+
56+ if (!(current_state = wl_array_add(&xdg_surface->states, sizeof state)))
57+ {
58+ WARNING("xdg_surface: Failed to allocate new state\n");
59+ return false;
60+ }
61+
62+ *current_state = state;
63+ return true;
64+}
65+
66+static bool remove_state(struct xdg_surface * xdg_surface, uint32_t state)
67+{
68+ uint32_t * current_state;
69+
70+ wl_array_for_each(current_state, &xdg_surface->states)
71+ {
72+ if (*current_state == state)
73+ {
74+ swc_array_remove(&xdg_surface->states, current_state, sizeof state);
75+ return true;
76+ }
77+ }
78+
79+ return false;
80+}
81+
82+static void configure(struct window * window, uint32_t width, uint32_t height)
83+{
84+ struct xdg_surface * xdg_surface
85+ = wl_container_of(window, xdg_surface, window);
86+
87+ window->configure.acknowledged = false;
88+ xdg_surface->configure_serial = wl_display_next_serial(swc.display);
89+ xdg_surface_send_configure(xdg_surface->resource, width, height,
90+ &xdg_surface->states,
91+ xdg_surface->configure_serial);
92+}
93+
94+static void focus(struct window * window)
95+{
96+ struct xdg_surface * xdg_surface
97+ = wl_container_of(window, xdg_surface, window);
98+
99+ add_state(xdg_surface, XDG_SURFACE_STATE_ACTIVATED);
100+ configure(window, window->configure.width, window->configure.height);
101+}
102+
103+static void unfocus(struct window * window)
104+{
105+ struct xdg_surface * xdg_surface
106+ = wl_container_of(window, xdg_surface, window);
107+
108+ remove_state(xdg_surface, XDG_SURFACE_STATE_ACTIVATED);
109+ configure(window, window->configure.width, window->configure.height);
110+}
111+
112+static void close(struct window * window)
113+{
114+ struct xdg_surface * xdg_surface
115+ = wl_container_of(window, xdg_surface, window);
116+
117+ xdg_surface_send_close(xdg_surface->resource);
118+}
119+
120+static void set_mode(struct window * window, unsigned mode)
121+{
122+ struct xdg_surface * xdg_surface
123+ = wl_container_of(window, xdg_surface, window);
124+
125+ switch (window->mode)
126+ {
127+ case WINDOW_MODE_TILED:
128+ remove_state(xdg_surface, XDG_SURFACE_STATE_MAXIMIZED);
129+ break;
130+ case WINDOW_MODE_FULLSCREEN:
131+ remove_state(xdg_surface, XDG_SURFACE_STATE_FULLSCREEN);
132+ break;
133+ }
134+
135+ switch (mode)
136+ {
137+ case WINDOW_MODE_TILED:
138+ add_state(xdg_surface, XDG_SURFACE_STATE_MAXIMIZED);
139+ break;
140+ case WINDOW_MODE_FULLSCREEN:
141+ add_state(xdg_surface, XDG_SURFACE_STATE_FULLSCREEN);
142+ break;
143+ }
144+}
145+
146+static const struct window_impl xdg_surface_window_impl = {
147+ .configure = &configure,
148+ .focus = &focus,
149+ .unfocus = &unfocus,
150+ .close = &close,
151+ .set_mode = &set_mode,
152+};
153+
154+static void destroy(struct wl_client * client, struct wl_resource * resource)
155+{
156+ wl_resource_destroy(resource);
157+}
158+
159+static void set_parent(struct wl_client * client, struct wl_resource * resource,
160+ struct wl_resource * parent_resource)
161+{
162+ struct xdg_surface * xdg_surface = wl_resource_get_user_data(resource);
163+ struct swc_surface * parent_surface;
164+ struct compositor_view * parent_view;
165+ struct window * parent_window = NULL;
166+
167+ if (parent_resource)
168+ {
169+ parent_surface = wl_resource_get_user_data(parent_resource);
170+ parent_view = compositor_view(parent_surface->view);
171+ parent_window = parent_view->window;
172+ }
173+
174+ window_set_parent(&xdg_surface->window, parent_window);
175+}
176+
177+static void set_title(struct wl_client * client, struct wl_resource * resource,
178+ const char * title)
179+{
180+ struct xdg_surface * xdg_surface = wl_resource_get_user_data(resource);
181+
182+ window_set_title(&xdg_surface->window, title, -1);
183+}
184+
185+static void set_app_id(struct wl_client * client, struct wl_resource * resource,
186+ const char * app_id)
187+{
188+ struct xdg_surface * surface = wl_resource_get_user_data(resource);
189+
190+ window_set_class(&surface->window, app_id);
191+}
192+
193+static void show_window_menu(struct wl_client * client,
194+ struct wl_resource * resource,
195+ struct wl_resource * seat_resource,
196+ uint32_t serial, int32_t x, int32_t y)
197+{
198+}
199+
200+static void move(struct wl_client * client, struct wl_resource * resource,
201+ struct wl_resource * seat_resource, uint32_t serial)
202+{
203+ struct xdg_surface * xdg_surface = wl_resource_get_user_data(resource);
204+ struct button * button;
205+
206+ if (!(button = pointer_get_button(swc.seat->pointer, serial)))
207+ return;
208+
209+ window_begin_move(&xdg_surface->window, button);
210+}
211+
212+static void resize(struct wl_client * client, struct wl_resource * resource,
213+ struct wl_resource * seat_resource, uint32_t serial,
214+ uint32_t edges)
215+{
216+ struct xdg_surface * xdg_surface = wl_resource_get_user_data(resource);
217+ struct button * button;
218+
219+ if (!(button = pointer_get_button(swc.seat->pointer, serial)))
220+ return;
221+
222+ window_begin_resize(&xdg_surface->window, edges, button);
223+}
224+
225+static void ack_configure(struct wl_client * client,
226+ struct wl_resource * resource, uint32_t serial)
227+{
228+ struct xdg_surface * xdg_surface = wl_resource_get_user_data(resource);
229+
230+ if (serial == xdg_surface->configure_serial)
231+ xdg_surface->window.configure.acknowledged = true;
232+}
233+
234+static void set_window_geometry(struct wl_client * client,
235+ struct wl_resource * resource,
236+ int32_t x, int32_t y,
237+ int32_t width, int32_t height)
238+{
239+ /* TODO: Implement set_window_geometry. */
240+}
241+
242+static void set_maximized(struct wl_client * client,
243+ struct wl_resource * resource)
244+{
245+ /* TODO: Implement set_maximized. */
246+}
247+
248+static void unset_maximized(struct wl_client * client,
249+ struct wl_resource * resource)
250+{
251+ /* TODO: Implement unset_maximized. */
252+}
253+
254+static void set_fullscreen(struct wl_client * client,
255+ struct wl_resource * resource,
256+ struct wl_resource * output_resource)
257+{
258+ /* TODO: Implement set_fullscreen. */
259+}
260+
261+static void unset_fullscreen(struct wl_client * client,
262+ struct wl_resource * resource)
263+{
264+ /* TODO: Implement unset_fullscreen. */
265+}
266+
267+static void set_minimized(struct wl_client * client,
268+ 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 handle_surface_destroy(struct wl_listener * listener, void * data)
291+{
292+ struct xdg_surface * xdg_surface
293+ = wl_container_of (listener, xdg_surface, surface_destroy_listener);
294+
295+ wl_resource_destroy(xdg_surface->resource);
296+}
297+
298+static void 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 * xdg_surface_new(struct wl_client * client,
308+ uint32_t version, uint32_t id,
309+ struct swc_surface * surface)
310+{
311+ struct xdg_surface * xdg_surface;
312+
313+ xdg_surface = malloc(sizeof *xdg_surface);
314+
315+ if (!xdg_surface)
316+ goto error0;
317+
318+ xdg_surface->resource = wl_resource_create(client, &xdg_surface_interface,
319+ version, id);
320+
321+ if (!xdg_surface->resource)
322+ goto error1;
323+
324+ window_initialize(&xdg_surface->window, &xdg_surface_window_impl, surface);
325+ xdg_surface->surface_destroy_listener.notify = &handle_surface_destroy;
326+ wl_array_init(&xdg_surface->states);
327+ wl_resource_add_destroy_listener(surface->resource,
328+ &xdg_surface->surface_destroy_listener);
329+ wl_resource_set_implementation(xdg_surface->resource,
330+ &xdg_surface_implementation,
331+ xdg_surface, &destroy_xdg_surface);
332+ window_manage(&xdg_surface->window);
333+
334+ return xdg_surface;
335+
336+ error1:
337+ free(xdg_surface);
338+ error0:
339+ return NULL;
340+}
341+
+37,
-0
1@@ -0,0 +1,37 @@
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 swc_surface;
31+struct wl_client;
32+
33+struct xdg_surface * xdg_surface_new(struct wl_client * client,
34+ uint32_t version, uint32_t id,
35+ struct swc_surface * surface);
36+
37+#endif
38+
+2,
-1
1@@ -4,7 +4,8 @@ dir := protocol
2
3 PROTOCOL_EXTENSIONS = \
4 $(dir)/swc.xml \
5- $(dir)/wayland-drm.xml
6+ $(dir)/wayland-drm.xml \
7+ $(dir)/xdg-shell.xml
8
9 $(dir)_TARGETS := $(PROTOCOL_EXTENSIONS:%.xml=%-protocol.c) \
10 $(PROTOCOL_EXTENSIONS:%.xml=%-server-protocol.h)
+413,
-0
1@@ -0,0 +1,413 @@
2+<?xml version="1.0" encoding="UTF-8"?>
3+<protocol name="xdg_shell">
4+
5+ <copyright>
6+ Copyright © 2008-2013 Kristian Høgsberg
7+ Copyright © 2013 Rafael Antognolli
8+ Copyright © 2013 Jasper St. Pierre
9+ Copyright © 2010-2013 Intel Corporation
10+
11+ Permission to use, copy, modify, distribute, and sell this
12+ software and its documentation for any purpose is hereby granted
13+ without fee, provided that the above copyright notice appear in
14+ all copies and that both that copyright notice and this permission
15+ notice appear in supporting documentation, and that the name of
16+ the copyright holders not be used in advertising or publicity
17+ pertaining to distribution of the software without specific,
18+ written prior permission. The copyright holders make no
19+ representations about the suitability of this software for any
20+ purpose. It is provided "as is" without express or implied
21+ warranty.
22+
23+ THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
24+ SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
25+ FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
26+ SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
27+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
28+ AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
29+ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
30+ THIS SOFTWARE.
31+ </copyright>
32+
33+ <interface name="xdg_shell" version="1">
34+ <description summary="create desktop-style surfaces">
35+ This interface is implemented by servers that provide
36+ desktop-style user interfaces.
37+
38+ It allows clients to associate a xdg_surface with
39+ a basic surface.
40+ </description>
41+
42+ <enum name="version">
43+ <description summary="latest protocol version">
44+ The 'current' member of this enum gives the version of the
45+ protocol. Implementations can compare this to the version
46+ they implement using static_assert to ensure the protocol and
47+ implementation versions match.
48+ </description>
49+ <entry name="current" value="4" summary="Always the latest version"/>
50+ </enum>
51+
52+
53+ <request name="use_unstable_version">
54+ <description summary="enable use of this unstable version">
55+ Negotiate the unstable version of the interface. This
56+ mechanism is in place to ensure client and server agree on the
57+ unstable versions of the protocol that they speak or exit
58+ cleanly if they don't agree. This request will go away once
59+ the xdg-shell protocol is stable.
60+ </description>
61+ <arg name="version" type="int"/>
62+ </request>
63+
64+ <request name="get_xdg_surface">
65+ <description summary="create a shell surface from a surface">
66+ Create a shell surface for an existing surface.
67+
68+ Only one shell or popup surface can be associated with a given
69+ surface.
70+ </description>
71+ <arg name="id" type="new_id" interface="xdg_surface"/>
72+ <arg name="surface" type="object" interface="wl_surface"/>
73+ </request>
74+
75+ <request name="get_xdg_popup">
76+ <description summary="create a shell surface from a surface">
77+ Create a popup surface for an existing surface.
78+
79+ Only one shell or popup surface can be associated with a given
80+ surface.
81+ </description>
82+ <arg name="id" type="new_id" interface="xdg_popup"/>
83+ <arg name="surface" type="object" interface="wl_surface"/>
84+ <arg name="parent" type="object" interface="wl_surface"/>
85+ <arg name="seat" type="object" interface="wl_seat" summary="the wl_seat whose pointer is used"/>
86+ <arg name="serial" type="uint" summary="serial of the implicit grab on the pointer"/>
87+ <arg name="x" type="int"/>
88+ <arg name="y" type="int"/>
89+ <arg name="flags" type="uint"/>
90+ </request>
91+
92+ <event name="ping">
93+ <description summary="check if the client is alive">
94+ The ping event asks the client if it's still alive. Pass the
95+ serial specified in the event back to the compositor by sending
96+ a "pong" request back with the specified serial.
97+
98+ Compositors can use this to determine if the client is still
99+ alive. It's unspecified what will happen if the client doesn't
100+ respond to the ping request, or in what timeframe. Clients should
101+ try to respond in a reasonable amount of time.
102+ </description>
103+ <arg name="serial" type="uint" summary="pass this to the callback"/>
104+ </event>
105+
106+ <request name="pong">
107+ <description summary="respond to a ping event">
108+ A client must respond to a ping event with a pong request or
109+ the client may be deemed unresponsive.
110+ </description>
111+ <arg name="serial" type="uint" summary="serial of the ping event"/>
112+ </request>
113+ </interface>
114+
115+ <interface name="xdg_surface" version="1">
116+
117+ <description summary="desktop-style metadata interface">
118+ An interface that may be implemented by a wl_surface, for
119+ implementations that provide a desktop-style user interface.
120+
121+ It provides requests to treat surfaces like windows, allowing to set
122+ properties like maximized, fullscreen, minimized, and to move and resize
123+ them, and associate metadata like title and app id.
124+
125+ On the server side the object is automatically destroyed when
126+ the related wl_surface is destroyed. On client side,
127+ xdg_surface.destroy() must be called before destroying
128+ the wl_surface object.
129+ </description>
130+
131+ <request name="destroy" type="destructor">
132+ <description summary="remove xdg_surface interface">
133+ The xdg_surface interface is removed from the wl_surface object
134+ that was turned into a xdg_surface with
135+ xdg_shell.get_xdg_surface request. The xdg_surface properties,
136+ like maximized and fullscreen, are lost. The wl_surface loses
137+ its role as a xdg_surface. The wl_surface is unmapped.
138+ </description>
139+ </request>
140+
141+ <request name="set_parent">
142+ <description summary="surface is a child of another surface">
143+ Child surfaces are stacked above their parents, and will be
144+ unmapped if the parent is unmapped too. They should not appear
145+ on task bars and alt+tab.
146+ </description>
147+ <arg name="parent" type="object" interface="wl_surface" allow-null="true"/>
148+ </request>
149+
150+ <request name="set_title">
151+ <description summary="set surface title">
152+ Set a short title for the surface.
153+
154+ This string may be used to identify the surface in a task bar,
155+ window list, or other user interface elements provided by the
156+ compositor.
157+
158+ The string must be encoded in UTF-8.
159+ </description>
160+ <arg name="title" type="string"/>
161+ </request>
162+
163+ <request name="set_app_id">
164+ <description summary="set surface class">
165+ Set an id for the surface.
166+
167+ The app id identifies the general class of applications to which
168+ the surface belongs.
169+
170+ It should be the ID that appears in the new desktop entry
171+ specification, the interface name.
172+ </description>
173+ <arg name="app_id" type="string"/>
174+ </request>
175+
176+ <request name="show_window_menu">
177+ <description summary="show the window menu">
178+ Clients implementing client-side decorations might want to show
179+ a context menu when right-clicking on the decorations, giving the
180+ user a menu that they can use to maximize or minimize the window.
181+
182+ This request asks the compositor to pop up such a window menu at
183+ the given position, relative to the parent surface. There are
184+ no guarantees as to what the window menu contains.
185+
186+ Your surface must have focus on the seat passed in to pop up the
187+ window menu.
188+ </description>
189+
190+ <arg name="seat" type="object" interface="wl_seat" summary="the seat to pop the window up on"/>
191+ <arg name="serial" type="uint" summary="serial of the event to pop up the window for"/>
192+ <arg name="x" type="int" summary="the x position to pop up the window menu at"/>
193+ <arg name="y" type="int" summary="the y position to pop up the window menu at"/>
194+ </request>
195+
196+ <request name="move">
197+ <description summary="start an interactive move">
198+ Start a pointer-driven move of the surface.
199+
200+ This request must be used in response to a button press event.
201+ The server may ignore move requests depending on the state of
202+ the surface (e.g. fullscreen or maximized).
203+ </description>
204+ <arg name="seat" type="object" interface="wl_seat" summary="the wl_seat whose pointer is used"/>
205+ <arg name="serial" type="uint" summary="serial of the implicit grab on the pointer"/>
206+ </request>
207+
208+ <enum name="resize_edge">
209+ <description summary="edge values for resizing">
210+ These values are used to indicate which edge of a surface
211+ is being dragged in a resize operation. The server may
212+ use this information to adapt its behavior, e.g. choose
213+ an appropriate cursor image.
214+ </description>
215+ <entry name="none" value="0"/>
216+ <entry name="top" value="1"/>
217+ <entry name="bottom" value="2"/>
218+ <entry name="left" value="4"/>
219+ <entry name="top_left" value="5"/>
220+ <entry name="bottom_left" value="6"/>
221+ <entry name="right" value="8"/>
222+ <entry name="top_right" value="9"/>
223+ <entry name="bottom_right" value="10"/>
224+ </enum>
225+
226+ <request name="resize">
227+ <description summary="start an interactive resize">
228+ Start a pointer-driven resizing of the surface.
229+
230+ This request must be used in response to a button press event.
231+ The server may ignore resize requests depending on the state of
232+ the surface (e.g. fullscreen or maximized).
233+ </description>
234+ <arg name="seat" type="object" interface="wl_seat" summary="the wl_seat whose pointer is used"/>
235+ <arg name="serial" type="uint" summary="serial of the implicit grab on the pointer"/>
236+ <arg name="edges" type="uint" summary="which edge or corner is being dragged"/>
237+ </request>
238+
239+ <enum name="state">
240+ <description summary="types of state on the surface">
241+ The different state values used on the surface. This is designed for
242+ state values like maximized, fullscreen. It is paired with the
243+ configure event to ensure that both the client and the compositor
244+ setting the state can be synchronized.
245+
246+ States set in this way are double-buffered. They will get applied on
247+ the next commit.
248+
249+ Desktop environments may extend this enum by taking up a range of
250+ values and documenting the range they chose in this description.
251+ They are not required to document the values for the range that they
252+ chose. Ideally, any good extensions from a desktop environment should
253+ make its way into standardization into this enum.
254+
255+ The current reserved ranges are:
256+
257+ 0x0000 - 0x0FFF: xdg-shell core values, documented below.
258+ 0x1000 - 0x1FFF: GNOME
259+ </description>
260+ <entry name="maximized" value="1" summary="the surface is maximized">
261+ The surface is maximized. The window geometry specified in the configure
262+ event must be obeyed by the client.
263+ </entry>
264+ <entry name="fullscreen" value="2" summary="the surface is fullscreen">
265+ The surface is fullscreen. The window geometry specified in the configure
266+ event must be obeyed by the client.
267+ </entry>
268+ <entry name="resizing" value="3">
269+ The surface is being resized. The window geometry specified in the
270+ configure event is a maximum; the client cannot resize beyond it.
271+ Clients that have aspect ratio or cell sizing configuration can use
272+ a smaller size, however.
273+ </entry>
274+ <entry name="activated" value="4">
275+ Client window decorations should be painted as if the window is
276+ active. Do not assume this means that the window actually has
277+ keyboard or pointer focus.
278+ </entry>
279+ </enum>
280+
281+ <event name="configure">
282+ <description summary="suggest a surface change">
283+ The configure event asks the client to resize its surface.
284+
285+ The width and height arguments specify a hint to the window
286+ about how its surface should be resized in window geometry
287+ coordinates. The states listed in the event specify how the
288+ width/height arguments should be interpreted.
289+
290+ A client should arrange a new surface, and then send a
291+ ack_configure request with the serial sent in this configure
292+ event before attaching a new surface.
293+
294+ If the client receives multiple configure events before it
295+ can respond to one, it is free to discard all but the last
296+ event it received.
297+ </description>
298+
299+ <arg name="width" type="int"/>
300+ <arg name="height" type="int"/>
301+ <arg name="states" type="array"/>
302+ <arg name="serial" type="uint"/>
303+ </event>
304+
305+ <request name="ack_configure">
306+ <description summary="ack a configure event">
307+ When a configure event is received, a client should then ack it
308+ using the ack_configure request to ensure that the compositor
309+ knows the client has seen the event.
310+
311+ By this point, the state is confirmed, and the next attach should
312+ contain the buffer drawn for the configure event you are acking.
313+ </description>
314+ <arg name="serial" type="uint" summary="a serial to configure for"/>
315+ </request>
316+
317+ <request name="set_window_geometry">
318+ <description summary="set the new window geometry">
319+ The window geometry of a window is its "visible bounds" from the
320+ user's perspective. Client-side decorations often have invisible
321+ portions like drop-shadows which should be ignored for the
322+ purposes of aligning, placing and constraining windows.
323+
324+ The default value is the full bounds of the surface, including any
325+ subsurfaces. Once the window geometry of the surface is set once,
326+ it is not possible to unset it, and it will remain the same until
327+ set_window_geometry is called again, even if a new subsurface or
328+ buffer is attached.
329+
330+ If responding to a configure event, the window geometry in here
331+ must respect the sizing negotiations specified by the states in
332+ the configure event.
333+ </description>
334+ <arg name="x" type="int"/>
335+ <arg name="y" type="int"/>
336+ <arg name="width" type="int"/>
337+ <arg name="height" type="int"/>
338+ </request>
339+
340+ <request name="set_maximized" />
341+ <request name="unset_maximized" />
342+
343+ <request name="set_fullscreen">
344+ <description summary="set the window as fullscreen on a monitor">
345+ Make the surface fullscreen.
346+
347+ You can specify an output that you would prefer to be fullscreen.
348+ If this value is NULL, it's up to the compositor to choose which
349+ display will be used to map this surface.
350+ </description>
351+ <arg name="output" type="object" interface="wl_output" allow-null="true"/>
352+ </request>
353+ <request name="unset_fullscreen" />
354+
355+ <request name="set_minimized" />
356+
357+ <event name="close">
358+ <description summary="surface wants to be closed">
359+ The close event is sent by the compositor when the user
360+ wants the surface to be closed. This should be equivalent to
361+ the user clicking the close button in client-side decorations,
362+ if your application has any...
363+
364+ This is only a request that the user intends to close your
365+ window. The client may choose to ignore this request, or show
366+ a dialog to ask the user to save their data...
367+ </description>
368+ </event>
369+ </interface>
370+
371+ <interface name="xdg_popup" version="1">
372+ <description summary="desktop-style metadata interface">
373+ An interface that may be implemented by a wl_surface, for
374+ implementations that provide a desktop-style popups/menus. A popup
375+ surface is a transient surface with an added pointer grab.
376+
377+ An existing implicit grab will be changed to owner-events mode,
378+ and the popup grab will continue after the implicit grab ends
379+ (i.e. releasing the mouse button does not cause the popup to be
380+ unmapped).
381+
382+ The popup grab continues until the window is destroyed or a mouse
383+ button is pressed in any other clients window. A click in any of
384+ the clients surfaces is reported as normal, however, clicks in
385+ other clients surfaces will be discarded and trigger the callback.
386+
387+ The x and y arguments specify the locations of the upper left
388+ corner of the surface relative to the upper left corner of the
389+ parent surface, in surface local coordinates.
390+
391+ xdg_popup surfaces are always transient for another surface.
392+ </description>
393+
394+ <request name="destroy" type="destructor">
395+ <description summary="remove xdg_surface interface">
396+ The xdg_surface interface is removed from the wl_surface object
397+ that was turned into a xdg_surface with
398+ xdg_shell.get_xdg_surface request. The xdg_surface properties,
399+ like maximized and fullscreen, are lost. The wl_surface loses
400+ its role as a xdg_surface. The wl_surface is unmapped.
401+ </description>
402+ </request>
403+
404+ <event name="popup_done">
405+ <description summary="popup interaction is done">
406+ The popup_done event is sent out when a popup grab is broken,
407+ that is, when the users clicks a surface that doesn't belong
408+ to the client owning the popup surface.
409+ </description>
410+ <arg name="serial" type="uint" summary="serial of the implicit grab on the pointer"/>
411+ </event>
412+
413+ </interface>
414+</protocol>