main neuswc / libswc / swc.c
  1/* swc: libswc/swc.c
  2 *
  3 * Copyright (c) 2013-2020 Michael Forney
  4 *
  5 * Permission is hereby granted, free of charge, to any person obtaining a copy
  6 * of this software and associated documentation files (the "Software"), to deal
  7 * in the Software without restriction, including without limitation the rights
  8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9 * copies of the Software, and to permit persons to whom the Software is
 10 * furnished to do so, subject to the following conditions:
 11 *
 12 * The above copyright notice and this permission notice shall be included in
 13 * all copies or substantial portions of the Software.
 14 *
 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 21 * SOFTWARE.
 22 */
 23
 24#include "swc.h"
 25#include "bindings.h"
 26#include "compositor.h"
 27#include "data_device_manager.h"
 28#include "drm.h"
 29#include "event.h"
 30#include "internal.h"
 31#include "kde_decoration.h"
 32#include "keyboard.h"
 33#include "launch.h"
 34#include "layer_shell.h"
 35#include "panel_manager.h"
 36#include "pointer.h"
 37#include "screen.h"
 38#include "seat.h"
 39#include "select.h"
 40#include "shell.h"
 41#include "shm.h"
 42#include "snap.h"
 43#include "subcompositor.h"
 44#include "util.h"
 45#include "window.h"
 46#include "xdg_decoration.h"
 47#include "xdg_output.h"
 48#include "xdg_shell.h"
 49#ifdef ENABLE_XWAYLAND
 50#include "xserver.h"
 51#endif
 52
 53extern struct swc_launch swc_launch;
 54extern const struct swc_bindings swc_bindings;
 55extern struct swc_compositor swc_compositor;
 56extern struct swc_drm swc_drm;
 57#ifdef ENABLE_XWAYLAND
 58extern struct swc_xserver swc_xserver;
 59#endif
 60
 61extern struct pointer_handler screens_pointer_handler;
 62
 63struct swc swc = {
 64    .bindings = &swc_bindings,
 65    .compositor = &swc_compositor,
 66    .drm = &swc_drm,
 67#ifdef ENABLE_XWAYLAND
 68    .xserver = &swc_xserver,
 69#endif
 70};
 71
 72static void
 73setup_compositor(void)
 74{
 75	pixman_region32_t pointer_region;
 76	struct screen *screen;
 77	struct swc_rectangle *geom;
 78
 79	wl_list_insert(&swc.seat->keyboard->handlers,
 80	               &swc.bindings->keyboard_handler->link);
 81	wl_list_insert(&swc.seat->pointer->handlers,
 82	               &swc.bindings->pointer_handler->link);
 83	wl_list_insert(&swc.seat->pointer->handlers,
 84	               &swc.compositor->pointer_handler->link);
 85	wl_list_insert(&swc.seat->pointer->handlers, &screens_pointer_handler.link);
 86	wl_signal_add(&swc.seat->pointer->focus.event_signal,
 87	              &window_enter_listener);
 88
 89	/* Calculate pointer region */
 90	pixman_region32_init(&pointer_region);
 91
 92	wl_list_for_each(screen, &swc.screens, link)
 93	{
 94		geom = &screen->base.geometry;
 95		pixman_region32_union_rect(&pointer_region, &pointer_region, geom->x,
 96		                           geom->y, geom->width, geom->height);
 97	}
 98
 99	pointer_set_region(swc.seat->pointer, &pointer_region);
100	pixman_region32_fini(&pointer_region);
101}
102
103void
104swc_activate(void)
105{
106	swc.active = true;
107	send_event(&swc.event_signal, SWC_EVENT_ACTIVATED, NULL);
108	if (swc.manager->activate) {
109		swc.manager->activate();
110	}
111}
112
113void
114swc_deactivate(void)
115{
116	swc.active = false;
117	send_event(&swc.event_signal, SWC_EVENT_DEACTIVATED, NULL);
118	if (swc.manager->deactivate) {
119		swc.manager->deactivate();
120	}
121}
122
123EXPORT bool
124swc_cursor_position(int32_t *x, int32_t *y)
125{
126	if (x) {
127		*x = 0;
128	}
129	if (y) {
130		*y = 0;
131	}
132
133	if (!swc.seat || !swc.seat->pointer) {
134		return false;
135	}
136
137	if (x) {
138		*x = swc.seat->pointer->x;
139	}
140	if (y) {
141		*y = swc.seat->pointer->y;
142	}
143
144	return true;
145}
146
147EXPORT bool
148swc_initialize(struct wl_display *display, struct wl_event_loop *event_loop,
149               const struct swc_manager *manager)
150{
151	swc.display = display;
152	swc.event_loop =
153	    event_loop ? event_loop : wl_display_get_event_loop(display);
154	swc.manager = manager;
155	const char *default_seat = "seat0";
156	wl_signal_init(&swc.event_signal);
157
158	if (!launch_initialize()) {
159		ERROR("Could not connect to swc-launch\n");
160		goto error0;
161	}
162
163	if (!drm_initialize()) {
164		ERROR("Could not initialize DRM\n");
165		goto error1;
166	}
167
168	swc.shm = shm_create(display);
169	if (!swc.shm) {
170		ERROR("Could not initialize SHM\n");
171		goto error2;
172	}
173
174	if (!bindings_initialize()) {
175		ERROR("Could not initialize bindings\n");
176		goto error3;
177	}
178
179	swc.subcompositor = subcompositor_create(display);
180	if (!swc.subcompositor) {
181		ERROR("Could not initialize subcompositor\n");
182		goto error4;
183	}
184
185	if (!screens_initialize()) {
186		ERROR("Could not initialize screens\n");
187		goto error5;
188	}
189
190	if (!compositor_initialize()) {
191		ERROR("Could not initialize compositor\n");
192		goto error6;
193	}
194
195	swc.data_device_manager = data_device_manager_create(display);
196	if (!swc.data_device_manager) {
197		ERROR("Could not initialize data device manager\n");
198		goto error7;
199	}
200
201	swc.seat = seat_create(display, default_seat);
202	if (!swc.seat) {
203		ERROR("Could not initialize seat\n");
204		goto error8;
205	}
206
207	swc.shell = shell_create(display);
208	if (!swc.shell) {
209		ERROR("Could not initialize shell\n");
210		goto error9;
211	}
212
213	swc.xdg_shell = xdg_shell_create(display);
214	if (!swc.xdg_shell) {
215		ERROR("Could not initialize XDG shell\n");
216		goto error10;
217	}
218
219	swc.xdg_decoration_manager = xdg_decoration_manager_create(display);
220	if (!swc.xdg_decoration_manager) {
221		ERROR("Could not initialize XDG decoration manager\n");
222		goto error11;
223	}
224
225	swc.kde_decoration_manager = kde_decoration_manager_create(display);
226	if (!swc.kde_decoration_manager) {
227		ERROR("Could not initialize KDE decoration manager\n");
228		goto error12;
229	}
230
231	swc.layer_shell = layer_shell_create(display);
232	if (!swc.layer_shell) {
233		ERROR("Could not initialize layer shell\n");
234		goto error13;
235	}
236
237	swc.panel_manager = panel_manager_create(display);
238	if (!swc.panel_manager) {
239		ERROR("Could not initialize panel manager\n");
240		goto error14;
241	}
242
243	swc.snap_manager = snap_manager_create(display);
244	if (!swc.snap_manager) {
245		ERROR("Could not initialize snap manager\n");
246		goto error15;
247	}
248
249#ifdef ENABLE_XWAYLAND
250	if (!xserver_initialize()) {
251		ERROR("Could not initialize xwayland\n");
252		goto error16;
253	}
254#endif
255
256	swc.select_manager = select_manager_create(display);
257	if (!swc.select_manager) {
258		ERROR("Could not initialize select manager\n");
259		goto error17;
260	}
261
262	swc.xdg_output_manager = xdg_output_manager_create(display);
263	if (!swc.xdg_output_manager) {
264		ERROR("Could not initialize XDG output manager\n");
265		goto error17;
266	}
267
268	setup_compositor();
269
270	return true;
271
272error17:
273	wl_global_destroy(swc.select_manager);
274#ifdef ENABLE_XWAYLAND
275error16:
276#endif
277	wl_global_destroy(swc.snap_manager);
278error15:
279	wl_global_destroy(swc.panel_manager);
280error14:
281	wl_global_destroy(swc.layer_shell);
282error13:
283	wl_global_destroy(swc.kde_decoration_manager);
284error12:
285	wl_global_destroy(swc.xdg_decoration_manager);
286error11:
287	wl_global_destroy(swc.xdg_shell);
288error10:
289	wl_global_destroy(swc.shell);
290error9:
291	seat_destroy(swc.seat);
292error8:
293	wl_global_destroy(swc.data_device_manager);
294error7:
295	compositor_finalize();
296error6:
297	screens_finalize();
298error5:
299	wl_global_destroy(swc.subcompositor);
300error4:
301	bindings_finalize();
302error3:
303	shm_destroy(swc.shm);
304error2:
305	drm_finalize();
306error1:
307	launch_finalize();
308error0:
309	return false;
310}
311
312EXPORT void
313swc_finalize(void)
314{
315#ifdef ENABLE_XWAYLAND
316	xserver_finalize();
317#endif
318	wl_global_destroy(swc.xdg_output_manager);
319	wl_global_destroy(swc.snap_manager);
320	wl_global_destroy(swc.select_manager);
321	wl_global_destroy(swc.panel_manager);
322	wl_global_destroy(swc.layer_shell);
323	wl_global_destroy(swc.xdg_decoration_manager);
324	wl_global_destroy(swc.xdg_shell);
325	wl_global_destroy(swc.shell);
326	seat_destroy(swc.seat);
327	wl_global_destroy(swc.data_device_manager);
328	compositor_finalize();
329	screens_finalize();
330	bindings_finalize();
331	shm_destroy(swc.shm);
332	drm_finalize();
333	launch_finalize();
334}