blob: 69573c27133815d6fd895c833718cfe52971141c [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,
Pekka Paalanen068ae942011-11-28 14:11:15 +020054 struct window *window,
Benjamin Franzked0f79ab2011-11-22 12:43:52 +010055 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,
Pekka Paalanen068ae942011-11-28 14:11:15 +0200263 struct window *window,
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100264 int32_t width, int32_t height)
265{
Pekka Paalanen068ae942011-11-28 14:11:15 +0200266 window_set_child_size(window, width, 32);
267 window_schedule_redraw(window);
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100268}
269
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400270static struct panel *
271panel_create(struct display *display)
272{
273 struct panel *panel;
274
275 panel = malloc(sizeof *panel);
276 memset(panel, 0, sizeof *panel);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400277
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100278 panel->base.configure = panel_configure;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400279 panel->window = window_create(display, 0, 0);
280
281 window_set_title(panel->window, "panel");
282 window_set_decoration(panel->window, 0);
283 window_set_redraw_handler(panel->window, panel_redraw_handler);
284 window_set_custom(panel->window);
285 window_set_user_data(panel->window, panel);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400286 window_set_button_handler(panel->window, panel_button_handler);
Kristian Høgsberge28d05b2011-09-20 21:43:54 -0400287 window_set_item_focus_handler(panel->window, panel_item_focus_handler);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400288
289 return panel;
290}
291
292static void
293panel_add_item(struct panel *panel, const char *icon, const char *path)
294{
295 struct panel_item *item;
296
297 item = malloc(sizeof *item);
298 memset(item, 0, sizeof *item);
299 item->icon = cairo_image_surface_create_from_png(icon);
300 item->path = strdup(path);
Kristian Høgsberge28d05b2011-09-20 21:43:54 -0400301 item->panel = panel;
302 window_add_item(panel->window, item);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400303}
304
305static void
306background_draw(struct window *window, int width, int height, const char *path)
307{
308 cairo_surface_t *surface, *image;
Kristian Høgsberg7e690002011-09-08 18:18:02 -0400309 cairo_pattern_t *pattern;
310 cairo_matrix_t matrix;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400311 cairo_t *cr;
Kristian Høgsberg7e690002011-09-08 18:18:02 -0400312 double sx, sy;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400313
314 window_set_child_size(window, width, height);
315 window_draw(window);
316 surface = window_get_surface(window);
317
318 cr = cairo_create(surface);
319 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
320 cairo_set_source_rgba(cr, 0.0, 0.0, 0.2, 1.0);
321 cairo_paint(cr);
322
323 if (path) {
Kristian Høgsberg27d38662011-10-20 13:11:12 -0400324 image = load_jpeg(path);
Kristian Høgsberg7e690002011-09-08 18:18:02 -0400325 pattern = cairo_pattern_create_for_surface(image);
326 sx = (double) cairo_image_surface_get_width(image) / width;
327 sy = (double) cairo_image_surface_get_height(image) / height;
328 cairo_matrix_init_scale(&matrix, sx, sy);
329 cairo_pattern_set_matrix(pattern, &matrix);
330 cairo_set_source(cr, pattern);
331 cairo_pattern_destroy (pattern);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400332 cairo_paint(cr);
Kristian Høgsberg27d38662011-10-20 13:11:12 -0400333 cairo_surface_destroy(image);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400334 }
335
336 cairo_destroy(cr);
337 cairo_surface_destroy(surface);
338 window_flush(window);
339}
340
341static void
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100342background_configure(void *data,
343 struct desktop_shell *desktop_shell,
344 uint32_t time, uint32_t edges,
Pekka Paalanen068ae942011-11-28 14:11:15 +0200345 struct window *window,
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100346 int32_t width, int32_t height)
347{
348 struct desktop *desktop = data;
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100349
Pekka Paalanen068ae942011-11-28 14:11:15 +0200350 background_draw(window, width, height, desktop->background_path);
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100351}
352
353static void
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200354unlock_dialog_draw(struct unlock_dialog *dialog)
355{
356 struct rectangle allocation;
357 cairo_t *cr;
358 cairo_surface_t *surface;
359 cairo_pattern_t *pat;
360 double cx, cy, r, f;
361
362 window_draw(dialog->window);
363
364 surface = window_get_surface(dialog->window);
365 cr = cairo_create(surface);
366 window_get_child_allocation(dialog->window, &allocation);
367 cairo_rectangle(cr, allocation.x, allocation.y,
368 allocation.width, allocation.height);
369 cairo_clip(cr);
370 cairo_push_group(cr);
371 cairo_translate(cr, allocation.x, allocation.y);
372
373 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
374 cairo_set_source_rgba(cr, 0, 0, 0, 0.6);
375 cairo_paint(cr);
376
377 if (window_get_focus_item(dialog->window) == dialog->button)
378 f = 1.0;
379 else
380 f = 0.7;
381
382 cx = allocation.width / 2.0;
383 cy = allocation.height / 2.0;
384 r = (cx < cy ? cx : cy) * 0.4;
385 pat = cairo_pattern_create_radial(cx, cy, r * 0.7, cx, cy, r);
386 cairo_pattern_add_color_stop_rgb(pat, 0.0, 0, 0.86 * f, 0);
387 cairo_pattern_add_color_stop_rgb(pat, 0.85, 0.2 * f, f, 0.2 * f);
388 cairo_pattern_add_color_stop_rgb(pat, 1.0, 0, 0.86 * f, 0);
389 cairo_set_source(cr, pat);
390 cairo_arc(cr, cx, cy, r, 0.0, 2.0 * M_PI);
391 cairo_fill(cr);
392
393 item_set_allocation(dialog->button,
394 allocation.x + cx - r,
395 allocation.y + cy - r, 2 * r, 2 * r);
396 cairo_pattern_destroy(pat);
397
398 cairo_pop_group_to_source(cr);
399 cairo_paint(cr);
400 cairo_destroy(cr);
401
402 window_flush(dialog->window);
403 cairo_surface_destroy(surface);
404}
405
406static void
407unlock_dialog_button_handler(struct window *window,
408 struct input *input, uint32_t time,
409 int button, int state, void *data)
410{
411 struct unlock_dialog *dialog = data;
412 struct desktop *desktop = dialog->desktop;
413 struct item *focus;
414
415 focus = window_get_focus_item(dialog->window);
416 if (focus && button == BTN_LEFT) {
417 if (state == 0 && !dialog->closing) {
418 display_defer(desktop->display, &desktop->unlock_task);
419 dialog->closing = 1;
420 }
421 }
422}
423
424static void
425unlock_dialog_redraw_handler(struct window *window, void *data)
426{
427 struct unlock_dialog *dialog = data;
428
429 unlock_dialog_draw(dialog);
430}
431
432static void
433unlock_dialog_keyboard_focus_handler(struct window *window,
434 struct input *device, void *data)
435{
436 window_schedule_redraw(window);
437}
438
439static void
440unlock_dialog_item_focus_handler(struct window *window,
Benjamin Franzked7759712011-11-22 12:38:48 +0100441 struct item *focus, void *data)
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200442{
443 window_schedule_redraw(window);
444}
445
446static struct unlock_dialog *
Kristian Høgsberg1ec0c312011-11-15 16:39:55 -0500447unlock_dialog_create(struct desktop *desktop)
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200448{
Kristian Høgsberg1ec0c312011-11-15 16:39:55 -0500449 struct display *display = desktop->display;
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200450 struct unlock_dialog *dialog;
451
452 dialog = malloc(sizeof *dialog);
453 if (!dialog)
454 return NULL;
455 memset(dialog, 0, sizeof *dialog);
456
457 dialog->window = window_create(display, 260, 230);
458 window_set_title(dialog->window, "Unlock your desktop");
Benjamin Franzke8193bc12011-11-23 19:35:07 +0100459 window_set_custom(dialog->window);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200460
461 window_set_user_data(dialog->window, dialog);
462 window_set_redraw_handler(dialog->window, unlock_dialog_redraw_handler);
463 window_set_keyboard_focus_handler(dialog->window,
464 unlock_dialog_keyboard_focus_handler);
465 window_set_button_handler(dialog->window, unlock_dialog_button_handler);
466 window_set_item_focus_handler(dialog->window,
467 unlock_dialog_item_focus_handler);
468 dialog->button = window_add_item(dialog->window, NULL);
469
Kristian Høgsberg1ec0c312011-11-15 16:39:55 -0500470 desktop_shell_set_lock_surface(desktop->shell,
Pekka Paalanen068ae942011-11-28 14:11:15 +0200471 window_get_wl_shell_surface(dialog->window));
Kristian Høgsberg1ec0c312011-11-15 16:39:55 -0500472
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200473 unlock_dialog_draw(dialog);
474
475 return dialog;
476}
477
478static void
479unlock_dialog_destroy(struct unlock_dialog *dialog)
480{
481 window_destroy(dialog->window);
482 free(dialog);
483}
484
485static void
486unlock_dialog_finish(struct task *task, uint32_t events)
487{
488 struct desktop *desktop =
Benjamin Franzked7759712011-11-22 12:38:48 +0100489 container_of(task, struct desktop, unlock_task);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200490
491 desktop_shell_unlock(desktop->shell);
492 unlock_dialog_destroy(desktop->unlock_dialog);
493 desktop->unlock_dialog = NULL;
494}
495
496static void
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400497desktop_shell_configure(void *data,
498 struct desktop_shell *desktop_shell,
499 uint32_t time, uint32_t edges,
Pekka Paalanen068ae942011-11-28 14:11:15 +0200500 struct wl_shell_surface *shell_surface,
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400501 int32_t width, int32_t height)
502{
Pekka Paalanen068ae942011-11-28 14:11:15 +0200503 struct window *window = wl_shell_surface_get_user_data(shell_surface);
504 struct surface *s = window_get_user_data(window);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400505
Pekka Paalanen068ae942011-11-28 14:11:15 +0200506 s->configure(data, desktop_shell, time, edges, window, width, height);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400507}
508
Pekka Paalanen9ef3e012011-11-15 13:34:48 +0200509static void
510desktop_shell_prepare_lock_surface(void *data,
511 struct desktop_shell *desktop_shell)
512{
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200513 struct desktop *desktop = data;
514
515 if (!desktop->unlock_dialog) {
Kristian Høgsberg1ec0c312011-11-15 16:39:55 -0500516 desktop->unlock_dialog = unlock_dialog_create(desktop);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200517 desktop->unlock_dialog->desktop = desktop;
518 }
Pekka Paalanen9ef3e012011-11-15 13:34:48 +0200519}
520
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400521static const struct desktop_shell_listener listener = {
Pekka Paalanen9ef3e012011-11-15 13:34:48 +0200522 desktop_shell_configure,
523 desktop_shell_prepare_lock_surface
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400524};
525
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100526static struct background *
527background_create(struct desktop *desktop)
528{
529 struct background *background;
530
531 background = malloc(sizeof *background);
532 memset(background, 0, sizeof *background);
533
534 background->base.configure = background_configure;
535 background->window = window_create(desktop->display, 0, 0);
536 window_set_decoration(background->window, 0);
537 window_set_custom(background->window);
538 window_set_user_data(background->window, background);
539
540 return background;
541}
542
543static void
544create_output(struct desktop *desktop, uint32_t id)
545{
546 struct output *output;
547
548 output = calloc(1, sizeof *output);
549 if (!output)
550 return;
551
552 output->output = wl_display_bind(display_get_display(desktop->display),
553 id, &wl_output_interface);
554
555 wl_list_insert(&desktop->outputs, &output->link);
556}
557
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400558static void
559global_handler(struct wl_display *display, uint32_t id,
560 const char *interface, uint32_t version, void *data)
561{
562 struct desktop *desktop = data;
563
564 if (!strcmp(interface, "desktop_shell")) {
565 desktop->shell =
566 wl_display_bind(display, id, &desktop_shell_interface);
567 desktop_shell_add_listener(desktop->shell, &listener, desktop);
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100568 } else if (!strcmp(interface, "wl_output")) {
569 create_output(desktop, id);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400570 }
571}
572
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500573static void
574launcher_section_done(void *data)
575{
576 struct desktop *desktop = data;
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100577 struct output *output;
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500578
579 if (key_launcher_icon == NULL || key_launcher_path == NULL) {
580 fprintf(stderr, "invalid launcher section\n");
581 return;
582 }
583
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100584 wl_list_for_each(output, &desktop->outputs, link)
585 panel_add_item(output->panel,
586 key_launcher_icon, key_launcher_path);
587
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500588 free(key_launcher_icon);
589 key_launcher_icon = NULL;
590 free(key_launcher_path);
591 key_launcher_path = NULL;
592}
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400593
594int main(int argc, char *argv[])
595{
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200596 struct desktop desktop = { 0 };
Pekka Paalanen668dd562011-11-15 11:45:40 +0200597 char *config_file;
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100598 struct output *output;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400599
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200600 desktop.unlock_task.run = unlock_dialog_finish;
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100601 wl_list_init(&desktop.outputs);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200602
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400603 desktop.display = display_create(&argc, &argv, NULL);
604 if (desktop.display == NULL) {
605 fprintf(stderr, "failed to create display: %m\n");
606 return -1;
607 }
608
Pekka Paalanen6cd281a2011-11-03 14:11:32 +0200609 /* The fd is our private, do not confuse our children with it. */
610 unsetenv("WAYLAND_SOCKET");
611
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400612 wl_display_add_global_listener(display_get_display(desktop.display),
613 global_handler, &desktop);
614
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100615 wl_list_for_each(output, &desktop.outputs, link) {
Pekka Paalanen068ae942011-11-28 14:11:15 +0200616 struct wl_shell_surface *s;
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100617
618 output->panel = panel_create(desktop.display);
Pekka Paalanen068ae942011-11-28 14:11:15 +0200619 s = window_get_wl_shell_surface(output->panel->window);
620 desktop_shell_set_panel(desktop.shell, output->output, s);
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100621
622 output->background = background_create(&desktop);
Pekka Paalanen068ae942011-11-28 14:11:15 +0200623 s = window_get_wl_shell_surface(output->background->window);
624 desktop_shell_set_background(desktop.shell, output->output, s);
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100625 }
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400626
Pekka Paalanen668dd562011-11-15 11:45:40 +0200627 config_file = config_file_path("wayland-desktop-shell.ini");
628 parse_config_file(config_file,
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500629 config_sections, ARRAY_LENGTH(config_sections),
630 &desktop);
Pekka Paalanen668dd562011-11-15 11:45:40 +0200631 free(config_file);
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500632
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500633 desktop.background_path = key_background_image;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400634
635 signal(SIGCHLD, sigchild_handler);
636
637 display_run(desktop.display);
638
639 return 0;
640}