commit ec48a73
Michael Forney
·
2014-01-23 01:29:14 +0000 UTC
parent f743751
Implement panels
10 files changed,
+489,
-2
M
Makefile
+1,
-1
1@@ -48,7 +48,7 @@ pkgconfig = $(sort $(foreach pkg,$(1),$(if $($(pkg)_$(3)),$($(pkg)_$(3)), \
2
3 include $(SUBDIRS:%=%/local.mk)
4
5-$(foreach dir,BIN LIB INCLUDE PKGCONFIG,$(DESTDIR)$($(dir)DIR)):
6+$(foreach dir,BIN LIB INCLUDE PKGCONFIG,$(DESTDIR)$($(dir)DIR)) $(DESTDIR)$(DATADIR)/swc:
7 mkdir -p "$@"
8
9 .PHONY: check-dependencies
+1,
-0
1@@ -4,6 +4,7 @@ PREFIX = /usr/local
2 BINDIR = $(PREFIX)/bin
3 LIBDIR = $(PREFIX)/lib
4 INCLUDEDIR = $(PREFIX)/include
5+DATADIR = $(PREFIX)/share
6 PKGCONFIGDIR = $(LIBDIR)/pkgconfig
7
8 CC = gcc
+4,
-0
1@@ -44,6 +44,8 @@ SWC_SOURCES = \
2 libswc/launch.c \
3 libswc/mode.c \
4 libswc/output.c \
5+ libswc/panel.c \
6+ libswc/panel_manager.c \
7 libswc/pointer.c \
8 libswc/region.c \
9 libswc/screen.c \
10@@ -58,6 +60,7 @@ SWC_SOURCES = \
11 libswc/wayland_buffer.c \
12 libswc/window.c \
13 libswc/xkb.c \
14+ protocol/swc-protocol.c \
15 protocol/wayland-drm-protocol.c
16
17 ifeq ($(ENABLE_HOTPLUGGING),1)
18@@ -85,6 +88,7 @@ SWC_SHARED_OBJECTS = $(SWC_SOURCES:%.c=%.lo)
19 objects = $(foreach obj,$(1),$(dir)/$(obj).o $(dir)/$(obj).lo)
20 $(call objects,drm drm_buffer): protocol/wayland-drm-server-protocol.h
21 $(call objects,xserver): protocol/xserver-server-protocol.h
22+$(call objects,panel_manager panel): protocol/swc-server-protocol.h
23 $(call objects,pointer): cursor/cursor_data.h
24
25 $(dir)/libswc.a: $(SWC_STATIC_OBJECTS)
+261,
-0
1@@ -0,0 +1,261 @@
2+/* swc: libswc/panel.c
3+ *
4+ * Copyright (c) 2013, 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 "panel.h"
26+#include "compositor.h"
27+#include "internal.h"
28+#include "keyboard.h"
29+#include "output.h"
30+#include "screen.h"
31+#include "seat.h"
32+#include "surface.h"
33+#include "util.h"
34+#include "view.h"
35+#include "protocol/swc-server-protocol.h"
36+
37+#include <assert.h>
38+#include <stdlib.h>
39+
40+static void update_position(struct swc_panel * panel)
41+{
42+ int32_t x, y;
43+ struct swc_rectangle * screen = &panel->screen->base.geometry,
44+ * view = &panel->surface->view->geometry;
45+
46+ switch (panel->edge)
47+ {
48+ case SWC_PANEL_EDGE_TOP:
49+ x = screen->x + panel->offset;
50+ y = screen->y;
51+ break;
52+ case SWC_PANEL_EDGE_BOTTOM:
53+ x = screen->x + panel->offset;
54+ y = screen->y + screen->height - view->height;
55+ break;
56+ case SWC_PANEL_EDGE_LEFT:
57+ x = screen->x;
58+ y = screen->y + screen->height - view->height - panel->offset;
59+ break;
60+ case SWC_PANEL_EDGE_RIGHT:
61+ x = screen->x + screen->width - view->width;
62+ y = screen->y + panel->offset;
63+ break;
64+ }
65+
66+ swc_view_move(panel->surface->view, x, y);
67+}
68+
69+static void dock(struct wl_client * client, struct wl_resource * resource,
70+ uint32_t edge, struct wl_resource * output_resource,
71+ uint32_t focus)
72+{
73+ struct swc_panel * panel = wl_resource_get_user_data(resource);
74+ struct swc_output * output = output_resource
75+ ? wl_resource_get_user_data(output_resource) : NULL;
76+ struct swc_screen_internal * screen = output
77+ ? output->screen : CONTAINER_OF(swc.screens.next,
78+ struct swc_screen_internal, link);
79+ bool screen_changed = screen != panel->screen;
80+ uint32_t length;
81+
82+ if (panel->docked)
83+ wl_list_remove(&panel->view_listener.link);
84+
85+ if (panel->screen && screen_changed)
86+ {
87+ wl_list_remove(&panel->modifier.link);
88+ swc_screen_update_usable_geometry(panel->screen);
89+ }
90+
91+ panel->screen = screen;
92+ panel->edge = edge;
93+ panel->docked = true;
94+
95+ switch (edge)
96+ {
97+ case SWC_PANEL_EDGE_TOP:
98+ case SWC_PANEL_EDGE_BOTTOM:
99+ length = panel->screen->base.geometry.width;
100+ break;
101+ case SWC_PANEL_EDGE_LEFT:
102+ case SWC_PANEL_EDGE_RIGHT:
103+ length = panel->screen->base.geometry.height;
104+ break;
105+ }
106+
107+ swc_compositor_add_surface(panel->surface);
108+ update_position(panel);
109+ swc_compositor_surface_show(panel->surface);
110+ wl_signal_add(&panel->surface->view->event_signal, &panel->view_listener);
111+ wl_list_insert(&screen->modifiers, &panel->modifier.link);
112+
113+ if (focus)
114+ swc_keyboard_set_focus(swc.seat->keyboard, panel->surface);
115+
116+ swc_panel_send_docked(resource, length);
117+}
118+
119+static void set_offset(struct wl_client * client, struct wl_resource * resource,
120+ uint32_t offset)
121+{
122+ struct swc_panel * panel = wl_resource_get_user_data(resource);
123+
124+ panel->offset = offset;
125+
126+ if (panel->docked)
127+ update_position(panel);
128+}
129+
130+static void set_strut(struct wl_client * client, struct wl_resource * resource,
131+ uint32_t size, uint32_t begin, uint32_t end)
132+{
133+ struct swc_panel * panel = wl_resource_get_user_data(resource);
134+
135+ panel->strut_size = size;
136+
137+ if (panel->docked)
138+ swc_screen_update_usable_geometry(panel->screen);
139+}
140+
141+static const struct swc_panel_interface panel_implementation = {
142+ .dock = &dock,
143+ .set_offset = &set_offset,
144+ .set_strut = &set_strut
145+};
146+
147+static void modify(struct swc_screen_modifier * modifier,
148+ const struct swc_rectangle * geometry,
149+ pixman_region32_t * usable)
150+{
151+ struct swc_panel * panel = CONTAINER_OF(modifier, typeof(*panel), modifier);
152+ pixman_box32_t box = {
153+ .x1 = geometry->x, .y1 = geometry->y,
154+ .x2 = geometry->x + geometry->width,
155+ .y2 = geometry->y + geometry->height
156+ };
157+
158+ assert(panel->docked);
159+
160+ DEBUG("Original geometry { x1: %d, y1: %d, x2: %d, y2: %d }\n",
161+ box.x1, box.y1, box.x2, box.y2);
162+
163+ switch (panel->edge)
164+ {
165+ case SWC_PANEL_EDGE_TOP:
166+ box.y1 = MAX(box.y1, geometry->y + panel->strut_size);
167+ break;
168+ case SWC_PANEL_EDGE_BOTTOM:
169+ box.y2 = MIN(box.y2, geometry->y + geometry->height
170+ - panel->strut_size);
171+ break;
172+ case SWC_PANEL_EDGE_LEFT:
173+ box.x1 = MAX(box.x1, geometry->x + panel->strut_size);
174+ break;
175+ case SWC_PANEL_EDGE_RIGHT:
176+ box.x2 = MIN(box.x2, geometry->x + geometry->width
177+ - panel->strut_size);
178+ break;
179+ }
180+
181+ DEBUG("Usable region { x1: %d, y1: %d, x2: %d, y2: %d }\n",
182+ box.x1, box.y1, box.x2, box.y2);
183+
184+ pixman_region32_reset(usable, &box);
185+}
186+
187+static void destroy_panel(struct wl_resource * resource)
188+{
189+ struct swc_panel * panel = wl_resource_get_user_data(resource);
190+
191+ if (panel->docked)
192+ {
193+ wl_list_remove(&panel->view_listener.link);
194+ wl_list_remove(&panel->modifier.link);
195+ swc_screen_update_usable_geometry(panel->screen);
196+ swc_compositor_remove_surface(panel->surface);
197+ }
198+
199+ free(panel);
200+}
201+
202+static void handle_view_event(struct wl_listener * listener, void * data)
203+{
204+ struct swc_panel * panel;
205+ struct swc_event * event = data;
206+
207+ panel = CONTAINER_OF(listener, typeof(*panel), view_listener);
208+
209+ switch (event->type)
210+ {
211+ case SWC_VIEW_EVENT_RESIZED:
212+ update_position(panel);
213+ break;
214+ }
215+}
216+
217+static void handle_surface_destroy(struct wl_listener * listener, void * data)
218+{
219+ struct swc_panel * panel;
220+
221+ panel = CONTAINER_OF(listener, typeof(*panel), surface_destroy_listener);
222+ wl_resource_destroy(panel->resource);
223+}
224+
225+struct swc_panel * swc_panel_new(struct wl_client * client, uint32_t id,
226+ struct swc_surface * surface)
227+{
228+ struct swc_panel * panel;
229+
230+ panel = malloc(sizeof *panel);
231+
232+ if (!panel)
233+ goto error0;
234+
235+ panel->resource = wl_resource_create(client, &swc_panel_interface, 1, id);
236+
237+ if (!panel->resource)
238+ goto error1;
239+
240+ wl_resource_set_implementation(panel->resource, &panel_implementation,
241+ panel, &destroy_panel);
242+
243+ panel->surface = surface;
244+ panel->surface_destroy_listener.notify = &handle_surface_destroy;
245+ panel->view_listener.notify = &handle_view_event;
246+ panel->modifier.modify = &modify;
247+ panel->screen = NULL;
248+ panel->offset = 0;
249+ panel->strut_size = 0;
250+ panel->docked = false;
251+
252+ wl_resource_add_destroy_listener(surface->resource,
253+ &panel->surface_destroy_listener);
254+
255+ return panel;
256+
257+ error1:
258+ free(panel);
259+ error0:
260+ return NULL;
261+}
262+
+50,
-0
1@@ -0,0 +1,50 @@
2+/* swc: libswc/panel.h
3+ *
4+ * Copyright (c) 2013, 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_PANEL_H
26+#define SWC_PANEL_H
27+
28+#include "screen.h"
29+
30+#include <stdbool.h>
31+#include <wayland-server.h>
32+
33+struct swc_panel
34+{
35+ struct wl_resource * resource;
36+
37+ struct swc_surface * surface;
38+ struct wl_listener surface_destroy_listener;
39+ struct wl_listener view_listener;
40+ struct swc_screen_internal * screen;
41+ struct swc_screen_modifier modifier;
42+ uint32_t edge;
43+ uint32_t offset, strut_size;
44+ bool docked;
45+};
46+
47+struct swc_panel * swc_panel_new(struct wl_client * client, uint32_t id,
48+ struct swc_surface * surface);
49+
50+#endif
51+
+82,
-0
1@@ -0,0 +1,82 @@
2+/* swc: libswc/panel_manager.c
3+ *
4+ * Copyright (c) 2013, 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 "panel_manager.h"
26+#include "internal.h"
27+#include "panel.h"
28+
29+#include <wayland-server.h>
30+#include "protocol/swc-server-protocol.h"
31+
32+static struct
33+{
34+ struct wl_global * global;
35+ struct wl_resource * resource;
36+} panel_manager;
37+
38+static void create_panel(struct wl_client * client,
39+ struct wl_resource * resource, uint32_t id,
40+ struct wl_resource * surface_resource)
41+{
42+ struct swc_surface * surface = wl_resource_get_user_data(surface_resource);
43+ struct swc_panel * panel;
44+
45+ panel = swc_panel_new(client, id, surface);
46+
47+ if (!panel)
48+ wl_client_post_no_memory(client);
49+}
50+
51+static const struct swc_panel_manager_interface panel_manager_implementation = {
52+ .create_panel = &create_panel
53+};
54+
55+static void bind_panel_manager(struct wl_client * client, void * data,
56+ uint32_t version, uint32_t id)
57+{
58+ struct wl_resource * resource;
59+
60+ resource = wl_resource_create(client, &swc_panel_manager_interface, 1, id);
61+ wl_resource_set_implementation(resource, &panel_manager_implementation,
62+ NULL, NULL);
63+}
64+
65+bool swc_panel_manager_initialize()
66+{
67+ panel_manager.global = wl_global_create(swc.display,
68+ &swc_panel_manager_interface, 1,
69+ NULL, &bind_panel_manager);
70+
71+ if (!panel_manager.global)
72+ return false;
73+
74+ return true;
75+}
76+
77+void swc_panel_manager_finalize()
78+{
79+ wl_global_destroy(panel_manager.global);
80+}
81+
82+// vim: fdm=syntax fo=croql et sw=4 sts=4 ts=8
83+
+33,
-0
1@@ -0,0 +1,33 @@
2+/* swc: libswc/panel_manager.h
3+ *
4+ * Copyright (c) 2013 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_PANEL_MANAGER_H
26+#define SWC_PANEL_MANAGER_H
27+
28+#include <stdbool.h>
29+
30+bool swc_panel_manager_initialize();
31+void swc_panel_manager_finalize();
32+
33+#endif
34+
+13,
-1
1@@ -29,6 +29,7 @@
2 #include "internal.h"
3 #include "launch.h"
4 #include "keyboard.h"
5+#include "panel_manager.h"
6 #include "pointer.h"
7 #include "screen.h"
8 #include "seat.h"
9@@ -147,11 +148,17 @@ bool swc_initialize(struct wl_display * display,
10 goto error8;
11 }
12
13+ if (!swc_panel_manager_initialize())
14+ {
15+ ERROR("Could not initialize panel manager\n");
16+ goto error9;
17+ }
18+
19 #ifdef ENABLE_XWAYLAND
20 if (!swc_xserver_initialize())
21 {
22 ERROR("Could not initialize xwayland\n");
23- goto error9;
24+ goto error10;
25 }
26 #endif
27
28@@ -159,6 +166,10 @@ bool swc_initialize(struct wl_display * display,
29
30 return true;
31
32+#ifdef ENABLE_XWAYLAND
33+ error10:
34+ swc_panel_manager_finalize();
35+#endif
36 error9:
37 swc_shell_finalize();
38 error8:
39@@ -187,6 +198,7 @@ void swc_finalize()
40 #ifdef ENABLE_XWAYLAND
41 swc_xserver_finalize();
42 #endif
43+ swc_panel_manager_finalize();
44 swc_shell_finalize();
45 swc_seat_finalize();
46 swc_data_device_manager_finalize();
+4,
-0
1@@ -3,6 +3,7 @@
2 dir := protocol
3
4 PROTOCOL_EXTENSIONS = \
5+ $(dir)/swc.xml \
6 $(dir)/wayland-drm.xml \
7 $(dir)/xserver.xml
8
9@@ -15,5 +16,8 @@ $(dir)/%-protocol.c: $(dir)/%.xml
10 $(dir)/%-server-protocol.h: $(dir)/%.xml
11 $(call quiet,GEN,$(WAYLAND_SCANNER)) server-header < $< > $@
12
13+install-protocol: | $(DESTDIR)$(DATADIR)/swc
14+ install -m0644 protocol/swc.xml "$(DESTDIR)$(DATADIR)/swc"
15+
16 include common.mk
17
+40,
-0
1@@ -0,0 +1,40 @@
2+<?xml version="1.0" encoding="UTF-8"?>
3+<protocol name="swc">
4+ <interface name="swc_panel_manager" version="1">
5+ <request name="create_panel">
6+ <arg name="id" type="new_id" interface="swc_panel" />
7+ <arg name="surface" type="object" interface="wl_surface" />
8+ </request>
9+ </interface>
10+
11+ <interface name="swc_panel" version="1">
12+ <enum name="edge">
13+ <entry name="top" value="0" />
14+ <entry name="bottom" value="1" />
15+ <entry name="left" value="2" />
16+ <entry name="right" value="3" />
17+ </enum>
18+
19+ <request name="dock">
20+ <arg name="edge" type="uint" />
21+ <arg name="output" type="object" interface="wl_output"
22+ allow-null="true" />
23+ <arg name="focus" type="uint" />
24+ </request>
25+
26+ <request name="set_offset">
27+ <arg name="offset" type="uint" />
28+ </request>
29+
30+ <request name="set_strut">
31+ <arg name="size" type="uint" />
32+ <arg name="begin" type="uint" />
33+ <arg name="end" type="uint" />
34+ </request>
35+
36+ <event name="docked">
37+ <arg name="length" type="uint" />
38+ </event>
39+ </interface>
40+</protocol>
41+