blob: e313b9907a7d1e65e089f1422c05dfd2fbbb80dc [file] [log] [blame]
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -04001/*
2 * Copyright © 2011 Kristian Høgsberg
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +02003 * Copyright © 2011 Collabora, Ltd.
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -04004 *
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that copyright
8 * notice and this permission notice appear in supporting documentation, and
9 * that the name of the copyright holders not be used in advertising or
10 * publicity pertaining to distribution of the software without specific,
11 * written prior permission. The copyright holders make no representations
12 * about the suitability of this software for any purpose. It is provided "as
13 * is" without express or implied warranty.
14 *
15 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
21 * OF THIS SOFTWARE.
22 */
23
24#include <stdint.h>
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <fcntl.h>
29#include <unistd.h>
30#include <math.h>
31#include <cairo.h>
32#include <sys/wait.h>
33#include <linux/input.h>
34
Pekka Paalanen50719bc2011-11-22 14:18:50 +020035#include <wayland-client.h>
Kristian Høgsberg27d38662011-10-20 13:11:12 -040036#include "cairo-util.h"
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -040037#include "window.h"
38
Pekka Paalanen50719bc2011-11-22 14:18:50 +020039#include "desktop-shell-client-protocol.h"
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -040040
41struct desktop {
42 struct display *display;
43 struct desktop_shell *shell;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -040044 const char *background_path;
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +020045 struct unlock_dialog *unlock_dialog;
46 struct task unlock_task;
Benjamin Franzked0f79ab2011-11-22 12:43:52 +010047 struct wl_list outputs;
48};
49
50struct surface {
51 void (*configure)(void *data,
52 struct desktop_shell *desktop_shell,
53 uint32_t time, uint32_t edges,
54 struct wl_surface *surface,
55 int32_t width, int32_t height);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -040056};
57
58struct panel {
Benjamin Franzked0f79ab2011-11-22 12:43:52 +010059 struct surface base;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -040060 struct window *window;
Kristian Høgsbergbcee9a42011-10-12 00:36:16 -040061 struct window *menu;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -040062};
63
Benjamin Franzked0f79ab2011-11-22 12:43:52 +010064struct background {
65 struct surface base;
66 struct window *window;
67};
68
69struct output {
70 struct wl_output *output;
71 struct wl_list link;
72
73 struct panel *panel;
74 struct background *background;
75};
76
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -040077struct panel_item {
Kristian Høgsberge28d05b2011-09-20 21:43:54 -040078 struct item *item;
79 struct panel *panel;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -040080 cairo_surface_t *icon;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -040081 int pressed;
82 const char *path;
83};
84
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +020085struct unlock_dialog {
86 struct window *window;
87 struct item *button;
88 int closing;
89
90 struct desktop *desktop;
91};
92
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -050093static char *key_background_image;
94static uint32_t key_panel_color;
95static char *key_launcher_icon;
96static char *key_launcher_path;
97static void launcher_section_done(void *data);
98
99static const struct config_key shell_config_keys[] = {
100 { "background-image", CONFIG_KEY_STRING, &key_background_image },
101 { "panel-color", CONFIG_KEY_INTEGER, &key_panel_color },
102};
103
104static const struct config_key launcher_config_keys[] = {
105 { "icon", CONFIG_KEY_STRING, &key_launcher_icon },
106 { "path", CONFIG_KEY_STRING, &key_launcher_path },
107};
108
109static const struct config_section config_sections[] = {
110 { "wayland-desktop-shell",
111 shell_config_keys, ARRAY_LENGTH(shell_config_keys) },
112 { "launcher",
113 launcher_config_keys, ARRAY_LENGTH(launcher_config_keys),
114 launcher_section_done }
115};
116
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400117static void
118sigchild_handler(int s)
119{
120 int status;
121 pid_t pid;
122
123 while (pid = waitpid(-1, &status, WNOHANG), pid > 0)
124 fprintf(stderr, "child %d exited\n", pid);
125}
126
127static void
Kristian Høgsbergbcee9a42011-10-12 00:36:16 -0400128show_menu(struct panel *panel, struct input *input)
129{
130 int32_t x, y, width = 200, height = 200;
131 struct display *display;
132
133 input_get_position(input, &x, &y);
134 display = window_get_display(panel->window);
135 panel->menu = window_create_transient(display, panel->window,
136 x - 10, y - 10, width, height);
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100137 window_set_user_data(panel->menu, panel);
Kristian Høgsbergbcee9a42011-10-12 00:36:16 -0400138
139 window_draw(panel->menu);
140 window_flush(panel->menu);
141}
142
143static void
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400144panel_activate_item(struct panel *panel, struct panel_item *item)
145{
146 pid_t pid;
147
148 pid = fork();
149 if (pid < 0) {
150 fprintf(stderr, "fork failed: %m\n");
151 return;
152 }
153
154 if (pid)
155 return;
Benjamin Franzked7759712011-11-22 12:38:48 +0100156
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400157 if (execl(item->path, item->path, NULL) < 0) {
158 fprintf(stderr, "execl failed: %m\n");
159 exit(1);
160 }
161}
162
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400163static void
Kristian Høgsberge28d05b2011-09-20 21:43:54 -0400164panel_draw_item(struct item *item, void *data)
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400165{
Kristian Høgsberge28d05b2011-09-20 21:43:54 -0400166 cairo_t *cr = data;
167 struct panel_item *pi;
168 int x, y, width, height;
169 double dx, dy;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400170
Kristian Høgsberge28d05b2011-09-20 21:43:54 -0400171 pi = item_get_user_data(item);
172 width = cairo_image_surface_get_width(pi->icon);
173 height = cairo_image_surface_get_height(pi->icon);
174 x = 0;
175 y = -height / 2;
176 if (pi->pressed) {
177 x++;
178 y++;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400179 }
180
Kristian Høgsberge28d05b2011-09-20 21:43:54 -0400181 dx = x;
182 dy = y;
183 cairo_user_to_device(cr, &dx, &dy);
184 item_set_allocation(item, dx, dy, width, height);
185
186 cairo_set_source_surface(cr, pi->icon, x, y);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400187 cairo_paint(cr);
188
Kristian Høgsberge28d05b2011-09-20 21:43:54 -0400189 if (window_get_focus_item(pi->panel->window) == item) {
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400190 cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.4);
Kristian Høgsberge28d05b2011-09-20 21:43:54 -0400191 cairo_mask_surface(cr, pi->icon, x, y);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400192 }
Kristian Høgsberge28d05b2011-09-20 21:43:54 -0400193
194 cairo_translate(cr, width + 10, 0);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400195}
196
197static void
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500198set_hex_color(cairo_t *cr, uint32_t color)
199{
200 cairo_set_source_rgba(cr,
201 ((color >> 16) & 0xff) / 255.0,
202 ((color >> 8) & 0xff) / 255.0,
203 ((color >> 0) & 0xff) / 255.0,
204 ((color >> 24) & 0xff) / 255.0);
205}
206
207static void
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400208panel_redraw_handler(struct window *window, void *data)
209{
210 cairo_surface_t *surface;
211 cairo_t *cr;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400212
213 window_draw(window);
214 surface = window_get_surface(window);
215 cr = cairo_create(surface);
216 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500217 set_hex_color(cr, key_panel_color);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400218 cairo_paint(cr);
219
220 cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
Kristian Høgsberge28d05b2011-09-20 21:43:54 -0400221 cairo_translate(cr, 10, 32 / 2);
222 window_for_each_item(window, panel_draw_item, cr);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400223
224 cairo_destroy(cr);
225 cairo_surface_destroy(surface);
226 window_flush(window);
227}
228
229static void
Kristian Høgsberge28d05b2011-09-20 21:43:54 -0400230panel_item_focus_handler(struct window *window,
231 struct item *focus, void *data)
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400232{
Kristian Høgsberge28d05b2011-09-20 21:43:54 -0400233 window_schedule_redraw(window);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400234}
235
236static void
237panel_button_handler(struct window *window,
238 struct input *input, uint32_t time,
239 int button, int state, void *data)
240{
241 struct panel *panel = data;
Kristian Høgsberge28d05b2011-09-20 21:43:54 -0400242 struct panel_item *pi;
243 struct item *focus;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400244
Kristian Høgsberge28d05b2011-09-20 21:43:54 -0400245 focus = window_get_focus_item(panel->window);
246 if (focus && button == BTN_LEFT) {
247 pi = item_get_user_data(focus);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400248 window_schedule_redraw(panel->window);
Kristian Høgsberge28d05b2011-09-20 21:43:54 -0400249 if (state == 0)
250 panel_activate_item(panel, pi);
Kristian Høgsbergbcee9a42011-10-12 00:36:16 -0400251 } else if (button == BTN_RIGHT) {
252 if (state)
253 show_menu(panel, input);
254 else
255 window_destroy(panel->menu);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400256 }
257}
258
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100259static void
260panel_configure(void *data,
261 struct desktop_shell *desktop_shell,
262 uint32_t time, uint32_t edges,
263 struct wl_surface *surface,
264 int32_t width, int32_t height)
265{
266 struct panel *panel =
267 window_get_user_data(wl_surface_get_user_data(surface));
268
269 window_set_child_size(panel->window, width, 32);
270 window_schedule_redraw(panel->window);
271}
272
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400273static struct panel *
274panel_create(struct display *display)
275{
276 struct panel *panel;
277
278 panel = malloc(sizeof *panel);
279 memset(panel, 0, sizeof *panel);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400280
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100281 panel->base.configure = panel_configure;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400282 panel->window = window_create(display, 0, 0);
283
284 window_set_title(panel->window, "panel");
285 window_set_decoration(panel->window, 0);
286 window_set_redraw_handler(panel->window, panel_redraw_handler);
287 window_set_custom(panel->window);
288 window_set_user_data(panel->window, panel);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400289 window_set_button_handler(panel->window, panel_button_handler);
Kristian Høgsberge28d05b2011-09-20 21:43:54 -0400290 window_set_item_focus_handler(panel->window, panel_item_focus_handler);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400291
292 return panel;
293}
294
295static void
296panel_add_item(struct panel *panel, const char *icon, const char *path)
297{
298 struct panel_item *item;
299
300 item = malloc(sizeof *item);
301 memset(item, 0, sizeof *item);
302 item->icon = cairo_image_surface_create_from_png(icon);
303 item->path = strdup(path);
Kristian Høgsberge28d05b2011-09-20 21:43:54 -0400304 item->panel = panel;
305 window_add_item(panel->window, item);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400306}
307
308static void
309background_draw(struct window *window, int width, int height, const char *path)
310{
311 cairo_surface_t *surface, *image;
Kristian Høgsberg7e690002011-09-08 18:18:02 -0400312 cairo_pattern_t *pattern;
313 cairo_matrix_t matrix;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400314 cairo_t *cr;
Kristian Høgsberg7e690002011-09-08 18:18:02 -0400315 double sx, sy;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400316
317 window_set_child_size(window, width, height);
318 window_draw(window);
319 surface = window_get_surface(window);
320
321 cr = cairo_create(surface);
322 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
323 cairo_set_source_rgba(cr, 0.0, 0.0, 0.2, 1.0);
324 cairo_paint(cr);
325
326 if (path) {
Kristian Høgsberg27d38662011-10-20 13:11:12 -0400327 image = load_jpeg(path);
Kristian Høgsberg7e690002011-09-08 18:18:02 -0400328 pattern = cairo_pattern_create_for_surface(image);
329 sx = (double) cairo_image_surface_get_width(image) / width;
330 sy = (double) cairo_image_surface_get_height(image) / height;
331 cairo_matrix_init_scale(&matrix, sx, sy);
332 cairo_pattern_set_matrix(pattern, &matrix);
333 cairo_set_source(cr, pattern);
334 cairo_pattern_destroy (pattern);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400335 cairo_paint(cr);
Kristian Høgsberg27d38662011-10-20 13:11:12 -0400336 cairo_surface_destroy(image);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400337 }
338
339 cairo_destroy(cr);
340 cairo_surface_destroy(surface);
341 window_flush(window);
342}
343
344static void
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100345background_configure(void *data,
346 struct desktop_shell *desktop_shell,
347 uint32_t time, uint32_t edges,
348 struct wl_surface *surface,
349 int32_t width, int32_t height)
350{
351 struct desktop *desktop = data;
352 struct background *background =
353 window_get_user_data(wl_surface_get_user_data(surface));
354
355 background_draw(background->window,
356 width, height, desktop->background_path);
357}
358
359static void
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200360unlock_dialog_draw(struct unlock_dialog *dialog)
361{
362 struct rectangle allocation;
363 cairo_t *cr;
364 cairo_surface_t *surface;
365 cairo_pattern_t *pat;
366 double cx, cy, r, f;
367
368 window_draw(dialog->window);
369
370 surface = window_get_surface(dialog->window);
371 cr = cairo_create(surface);
372 window_get_child_allocation(dialog->window, &allocation);
373 cairo_rectangle(cr, allocation.x, allocation.y,
374 allocation.width, allocation.height);
375 cairo_clip(cr);
376 cairo_push_group(cr);
377 cairo_translate(cr, allocation.x, allocation.y);
378
379 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
380 cairo_set_source_rgba(cr, 0, 0, 0, 0.6);
381 cairo_paint(cr);
382
383 if (window_get_focus_item(dialog->window) == dialog->button)
384 f = 1.0;
385 else
386 f = 0.7;
387
388 cx = allocation.width / 2.0;
389 cy = allocation.height / 2.0;
390 r = (cx < cy ? cx : cy) * 0.4;
391 pat = cairo_pattern_create_radial(cx, cy, r * 0.7, cx, cy, r);
392 cairo_pattern_add_color_stop_rgb(pat, 0.0, 0, 0.86 * f, 0);
393 cairo_pattern_add_color_stop_rgb(pat, 0.85, 0.2 * f, f, 0.2 * f);
394 cairo_pattern_add_color_stop_rgb(pat, 1.0, 0, 0.86 * f, 0);
395 cairo_set_source(cr, pat);
396 cairo_arc(cr, cx, cy, r, 0.0, 2.0 * M_PI);
397 cairo_fill(cr);
398
399 item_set_allocation(dialog->button,
400 allocation.x + cx - r,
401 allocation.y + cy - r, 2 * r, 2 * r);
402 cairo_pattern_destroy(pat);
403
404 cairo_pop_group_to_source(cr);
405 cairo_paint(cr);
406 cairo_destroy(cr);
407
408 window_flush(dialog->window);
409 cairo_surface_destroy(surface);
410}
411
412static void
413unlock_dialog_button_handler(struct window *window,
414 struct input *input, uint32_t time,
415 int button, int state, void *data)
416{
417 struct unlock_dialog *dialog = data;
418 struct desktop *desktop = dialog->desktop;
419 struct item *focus;
420
421 focus = window_get_focus_item(dialog->window);
422 if (focus && button == BTN_LEFT) {
423 if (state == 0 && !dialog->closing) {
424 display_defer(desktop->display, &desktop->unlock_task);
425 dialog->closing = 1;
426 }
427 }
428}
429
430static void
431unlock_dialog_redraw_handler(struct window *window, void *data)
432{
433 struct unlock_dialog *dialog = data;
434
435 unlock_dialog_draw(dialog);
436}
437
438static void
439unlock_dialog_keyboard_focus_handler(struct window *window,
440 struct input *device, void *data)
441{
442 window_schedule_redraw(window);
443}
444
445static void
446unlock_dialog_item_focus_handler(struct window *window,
Benjamin Franzked7759712011-11-22 12:38:48 +0100447 struct item *focus, void *data)
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200448{
449 window_schedule_redraw(window);
450}
451
452static struct unlock_dialog *
Kristian Høgsberg1ec0c312011-11-15 16:39:55 -0500453unlock_dialog_create(struct desktop *desktop)
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200454{
Kristian Høgsberg1ec0c312011-11-15 16:39:55 -0500455 struct display *display = desktop->display;
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200456 struct unlock_dialog *dialog;
457
458 dialog = malloc(sizeof *dialog);
459 if (!dialog)
460 return NULL;
461 memset(dialog, 0, sizeof *dialog);
462
463 dialog->window = window_create(display, 260, 230);
464 window_set_title(dialog->window, "Unlock your desktop");
Benjamin Franzke8193bc12011-11-23 19:35:07 +0100465 window_set_custom(dialog->window);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200466
467 window_set_user_data(dialog->window, dialog);
468 window_set_redraw_handler(dialog->window, unlock_dialog_redraw_handler);
469 window_set_keyboard_focus_handler(dialog->window,
470 unlock_dialog_keyboard_focus_handler);
471 window_set_button_handler(dialog->window, unlock_dialog_button_handler);
472 window_set_item_focus_handler(dialog->window,
473 unlock_dialog_item_focus_handler);
474 dialog->button = window_add_item(dialog->window, NULL);
475
Kristian Høgsberg1ec0c312011-11-15 16:39:55 -0500476 desktop_shell_set_lock_surface(desktop->shell,
477 window_get_wl_surface(dialog->window));
478
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200479 unlock_dialog_draw(dialog);
480
481 return dialog;
482}
483
484static void
485unlock_dialog_destroy(struct unlock_dialog *dialog)
486{
487 window_destroy(dialog->window);
488 free(dialog);
489}
490
491static void
492unlock_dialog_finish(struct task *task, uint32_t events)
493{
494 struct desktop *desktop =
Benjamin Franzked7759712011-11-22 12:38:48 +0100495 container_of(task, struct desktop, unlock_task);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200496
497 desktop_shell_unlock(desktop->shell);
498 unlock_dialog_destroy(desktop->unlock_dialog);
499 desktop->unlock_dialog = NULL;
500}
501
502static void
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400503desktop_shell_configure(void *data,
504 struct desktop_shell *desktop_shell,
505 uint32_t time, uint32_t edges,
506 struct wl_surface *surface,
507 int32_t width, int32_t height)
508{
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100509 struct surface *s =
510 window_get_user_data(wl_surface_get_user_data(surface));
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400511
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100512 s->configure(data, desktop_shell, time, edges, surface, width, height);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400513}
514
Pekka Paalanen9ef3e012011-11-15 13:34:48 +0200515static void
516desktop_shell_prepare_lock_surface(void *data,
517 struct desktop_shell *desktop_shell)
518{
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200519 struct desktop *desktop = data;
520
521 if (!desktop->unlock_dialog) {
Kristian Høgsberg1ec0c312011-11-15 16:39:55 -0500522 desktop->unlock_dialog = unlock_dialog_create(desktop);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200523 desktop->unlock_dialog->desktop = desktop;
524 }
Pekka Paalanen9ef3e012011-11-15 13:34:48 +0200525}
526
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400527static const struct desktop_shell_listener listener = {
Pekka Paalanen9ef3e012011-11-15 13:34:48 +0200528 desktop_shell_configure,
529 desktop_shell_prepare_lock_surface
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400530};
531
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100532static struct background *
533background_create(struct desktop *desktop)
534{
535 struct background *background;
536
537 background = malloc(sizeof *background);
538 memset(background, 0, sizeof *background);
539
540 background->base.configure = background_configure;
541 background->window = window_create(desktop->display, 0, 0);
542 window_set_decoration(background->window, 0);
543 window_set_custom(background->window);
544 window_set_user_data(background->window, background);
545
546 return background;
547}
548
549static void
550create_output(struct desktop *desktop, uint32_t id)
551{
552 struct output *output;
553
554 output = calloc(1, sizeof *output);
555 if (!output)
556 return;
557
558 output->output = wl_display_bind(display_get_display(desktop->display),
559 id, &wl_output_interface);
560
561 wl_list_insert(&desktop->outputs, &output->link);
562}
563
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400564static void
565global_handler(struct wl_display *display, uint32_t id,
566 const char *interface, uint32_t version, void *data)
567{
568 struct desktop *desktop = data;
569
570 if (!strcmp(interface, "desktop_shell")) {
571 desktop->shell =
572 wl_display_bind(display, id, &desktop_shell_interface);
573 desktop_shell_add_listener(desktop->shell, &listener, desktop);
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100574 } else if (!strcmp(interface, "wl_output")) {
575 create_output(desktop, id);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400576 }
577}
578
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500579static void
580launcher_section_done(void *data)
581{
582 struct desktop *desktop = data;
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100583 struct output *output;
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500584
585 if (key_launcher_icon == NULL || key_launcher_path == NULL) {
586 fprintf(stderr, "invalid launcher section\n");
587 return;
588 }
589
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100590 wl_list_for_each(output, &desktop->outputs, link)
591 panel_add_item(output->panel,
592 key_launcher_icon, key_launcher_path);
593
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500594 free(key_launcher_icon);
595 key_launcher_icon = NULL;
596 free(key_launcher_path);
597 key_launcher_path = NULL;
598}
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400599
600int main(int argc, char *argv[])
601{
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200602 struct desktop desktop = { 0 };
Pekka Paalanen668dd562011-11-15 11:45:40 +0200603 char *config_file;
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100604 struct output *output;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400605
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200606 desktop.unlock_task.run = unlock_dialog_finish;
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100607 wl_list_init(&desktop.outputs);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200608
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400609 desktop.display = display_create(&argc, &argv, NULL);
610 if (desktop.display == NULL) {
611 fprintf(stderr, "failed to create display: %m\n");
612 return -1;
613 }
614
Pekka Paalanen6cd281a2011-11-03 14:11:32 +0200615 /* The fd is our private, do not confuse our children with it. */
616 unsetenv("WAYLAND_SOCKET");
617
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400618 wl_display_add_global_listener(display_get_display(desktop.display),
619 global_handler, &desktop);
620
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100621 wl_list_for_each(output, &desktop.outputs, link) {
622 struct wl_surface *surface;
623
624 output->panel = panel_create(desktop.display);
625 surface = window_get_wl_surface(output->panel->window);
626 desktop_shell_set_panel(desktop.shell, output->output, surface);
627
628 output->background = background_create(&desktop);
629 surface = window_get_wl_surface(output->background->window);
630 desktop_shell_set_background(desktop.shell,
631 output->output, surface);
632 }
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400633
Pekka Paalanen668dd562011-11-15 11:45:40 +0200634 config_file = config_file_path("wayland-desktop-shell.ini");
635 parse_config_file(config_file,
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500636 config_sections, ARRAY_LENGTH(config_sections),
637 &desktop);
Pekka Paalanen668dd562011-11-15 11:45:40 +0200638 free(config_file);
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500639
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500640 desktop.background_path = key_background_image;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400641
642 signal(SIGCHLD, sigchild_handler);
643
644 display_run(desktop.display);
645
646 return 0;
647}