blob: 3e014cc47e4976270c786edacf312b1df81a1375 [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>
Martin Minarik1e51a872012-06-08 00:39:11 +020033#include <sys/timerfd.h>
34#include <sys/epoll.h>
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -040035#include <linux/input.h>
Tiago Vignatti61500722012-05-23 22:06:28 +030036#include <libgen.h>
Martin Minarik1e51a872012-06-08 00:39:11 +020037#include <time.h>
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -040038
Pekka Paalanen50719bc2011-11-22 14:18:50 +020039#include <wayland-client.h>
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -040040#include "window.h"
Kristian Høgsberg5a315bc2012-05-15 22:33:43 -040041#include "../shared/cairo-util.h"
Kristian Høgsberg9b935c82011-12-08 12:44:27 -050042#include "../shared/config-parser.h"
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -040043
Pekka Paalanen50719bc2011-11-22 14:18:50 +020044#include "desktop-shell-client-protocol.h"
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -040045
46struct desktop {
47 struct display *display;
48 struct desktop_shell *shell;
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +020049 struct unlock_dialog *unlock_dialog;
50 struct task unlock_task;
Benjamin Franzked0f79ab2011-11-22 12:43:52 +010051 struct wl_list outputs;
Kristian Høgsbergd56bd902012-06-05 09:58:51 -040052
53 struct window *busy_window;
54 struct widget *busy_widget;
Benjamin Franzked0f79ab2011-11-22 12:43:52 +010055};
56
57struct surface {
58 void (*configure)(void *data,
59 struct desktop_shell *desktop_shell,
Kristian Høgsbergeae5de72012-04-11 22:42:15 -040060 uint32_t edges, struct window *window,
Benjamin Franzked0f79ab2011-11-22 12:43:52 +010061 int32_t width, int32_t height);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -040062};
63
64struct panel {
Benjamin Franzked0f79ab2011-11-22 12:43:52 +010065 struct surface base;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -040066 struct window *window;
Kristian Høgsberg75bc6672012-01-10 09:43:58 -050067 struct widget *widget;
Kristian Høgsberg75bc6672012-01-10 09:43:58 -050068 struct wl_list launcher_list;
Martin Minarik1e51a872012-06-08 00:39:11 +020069 struct panel_clock *clock;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -040070};
71
Benjamin Franzked0f79ab2011-11-22 12:43:52 +010072struct background {
73 struct surface base;
74 struct window *window;
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -050075 struct widget *widget;
Benjamin Franzked0f79ab2011-11-22 12:43:52 +010076};
77
78struct output {
79 struct wl_output *output;
80 struct wl_list link;
81
82 struct panel *panel;
83 struct background *background;
84};
85
Kristian Høgsberg53880802012-01-09 11:16:50 -050086struct panel_launcher {
Kristian Høgsbergc51f7992012-01-08 15:09:53 -050087 struct widget *widget;
Kristian Høgsberge28d05b2011-09-20 21:43:54 -040088 struct panel *panel;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -040089 cairo_surface_t *icon;
Kristian Høgsbergb6323512012-01-11 00:04:42 -050090 int focused, pressed;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -040091 const char *path;
Kristian Høgsberg75bc6672012-01-10 09:43:58 -050092 struct wl_list link;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -040093};
94
Martin Minarik1e51a872012-06-08 00:39:11 +020095struct panel_clock {
96 struct widget *widget;
97 struct panel *panel;
98 char string[128];
99 struct task clock_task;
100 int clock_fd;
101};
102
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200103struct unlock_dialog {
104 struct window *window;
Kristian Høgsberg75bc6672012-01-10 09:43:58 -0500105 struct widget *widget;
Kristian Høgsbergc51f7992012-01-08 15:09:53 -0500106 struct widget *button;
Kristian Høgsbergb6323512012-01-11 00:04:42 -0500107 int button_focused;
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200108 int closing;
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200109 struct desktop *desktop;
110};
111
Kristian Høgsberg6af8eb92012-01-25 16:57:11 -0500112static char *key_background_image = DATADIR "/weston/pattern.png";
113static char *key_background_type = "tile";
114static uint32_t key_panel_color = 0xaa000000;
115static uint32_t key_background_color = 0xff002244;
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500116static char *key_launcher_icon;
117static char *key_launcher_path;
118static void launcher_section_done(void *data);
Pekka Paalanenfd83b6d2011-12-08 10:06:53 +0200119static int key_locking = 1;
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500120
121static const struct config_key shell_config_keys[] = {
122 { "background-image", CONFIG_KEY_STRING, &key_background_image },
Kristian Høgsberg07f72942012-01-25 16:34:36 -0500123 { "background-type", CONFIG_KEY_STRING, &key_background_type },
Scott Moreaufa1de692012-01-27 13:25:49 -0700124 { "panel-color", CONFIG_KEY_UNSIGNED_INTEGER, &key_panel_color },
125 { "background-color", CONFIG_KEY_UNSIGNED_INTEGER, &key_background_color },
Pekka Paalanenfd83b6d2011-12-08 10:06:53 +0200126 { "locking", CONFIG_KEY_BOOLEAN, &key_locking },
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500127};
128
129static const struct config_key launcher_config_keys[] = {
130 { "icon", CONFIG_KEY_STRING, &key_launcher_icon },
131 { "path", CONFIG_KEY_STRING, &key_launcher_path },
132};
133
134static const struct config_section config_sections[] = {
Tiago Vignatti9a206c42012-03-21 19:49:18 +0200135 { "shell",
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500136 shell_config_keys, ARRAY_LENGTH(shell_config_keys) },
137 { "launcher",
138 launcher_config_keys, ARRAY_LENGTH(launcher_config_keys),
139 launcher_section_done }
140};
141
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400142static void
143sigchild_handler(int s)
144{
145 int status;
146 pid_t pid;
147
148 while (pid = waitpid(-1, &status, WNOHANG), pid > 0)
149 fprintf(stderr, "child %d exited\n", pid);
150}
151
152static void
Pekka Paalanen9e30a822012-01-19 16:40:28 +0200153menu_func(struct window *window, int index, void *data)
154{
155 printf("Selected index %d from a panel menu.\n", index);
156}
157
158static void
Kristian Høgsbergb3cca0a2012-01-04 22:19:14 -0500159show_menu(struct panel *panel, struct input *input, uint32_t time)
Kristian Høgsbergbcee9a42011-10-12 00:36:16 -0400160{
Kristian Høgsbergb3cca0a2012-01-04 22:19:14 -0500161 int32_t x, y;
162 static const char *entries[] = {
163 "Roy", "Pris", "Leon", "Zhora"
164 };
Kristian Høgsbergbcee9a42011-10-12 00:36:16 -0400165
166 input_get_position(input, &x, &y);
Pekka Paalanen6d174cf2012-01-19 15:17:59 +0200167 window_show_menu(window_get_display(panel->window),
168 input, time, panel->window,
Pekka Paalanen9e30a822012-01-19 16:40:28 +0200169 x - 10, y - 10, menu_func, entries, 4);
Kristian Høgsbergbcee9a42011-10-12 00:36:16 -0400170}
171
172static void
Kristian Høgsberg53880802012-01-09 11:16:50 -0500173panel_launcher_activate(struct panel_launcher *widget)
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400174{
175 pid_t pid;
176
177 pid = fork();
178 if (pid < 0) {
179 fprintf(stderr, "fork failed: %m\n");
180 return;
181 }
182
183 if (pid)
184 return;
Benjamin Franzked7759712011-11-22 12:38:48 +0100185
Kristian Høgsbergc51f7992012-01-08 15:09:53 -0500186 if (execl(widget->path, widget->path, NULL) < 0) {
Pekka Paalanena291ae52012-01-27 09:50:02 +0200187 fprintf(stderr, "execl '%s' failed: %m\n", widget->path);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400188 exit(1);
189 }
190}
191
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400192static void
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500193panel_launcher_redraw_handler(struct widget *widget, void *data)
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400194{
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500195 struct panel_launcher *launcher = data;
196 cairo_surface_t *surface;
197 struct rectangle allocation;
198 cairo_t *cr;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400199
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500200 surface = window_get_surface(launcher->panel->window);
201 cr = cairo_create(surface);
202
203 widget_get_allocation(widget, &allocation);
Kristian Høgsberg75bc6672012-01-10 09:43:58 -0500204 if (launcher->pressed) {
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500205 allocation.x++;
206 allocation.y++;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400207 }
208
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500209 cairo_set_source_surface(cr, launcher->icon,
210 allocation.x, allocation.y);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400211 cairo_paint(cr);
212
Kristian Høgsbergb6323512012-01-11 00:04:42 -0500213 if (launcher->focused) {
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400214 cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.4);
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500215 cairo_mask_surface(cr, launcher->icon,
216 allocation.x, allocation.y);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400217 }
Kristian Høgsberge28d05b2011-09-20 21:43:54 -0400218
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500219 cairo_destroy(cr);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400220}
221
Tiago Vignatti61500722012-05-23 22:06:28 +0300222static int
223panel_launcher_motion_handler(struct widget *widget, struct input *input,
224 uint32_t time, float x, float y, void *data)
225{
226 struct panel_launcher *launcher = data;
227
228 widget_set_tooltip(widget, basename((char *)launcher->path), x, y);
229
Ander Conselvan de Oliveiradc8c8fc2012-05-25 16:01:41 +0300230 return CURSOR_LEFT_PTR;
Tiago Vignatti61500722012-05-23 22:06:28 +0300231}
232
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400233static void
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500234set_hex_color(cairo_t *cr, uint32_t color)
235{
236 cairo_set_source_rgba(cr,
237 ((color >> 16) & 0xff) / 255.0,
238 ((color >> 8) & 0xff) / 255.0,
239 ((color >> 0) & 0xff) / 255.0,
240 ((color >> 24) & 0xff) / 255.0);
241}
242
243static void
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500244panel_redraw_handler(struct widget *widget, void *data)
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400245{
246 cairo_surface_t *surface;
247 cairo_t *cr;
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500248 struct panel *panel = data;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400249
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500250 surface = window_get_surface(panel->window);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400251 cr = cairo_create(surface);
252 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500253 set_hex_color(cr, key_panel_color);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400254 cairo_paint(cr);
255
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400256 cairo_destroy(cr);
257 cairo_surface_destroy(surface);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400258}
259
Kristian Høgsbergbb901fa2012-01-09 11:22:32 -0500260static int
Kristian Høgsberg53880802012-01-09 11:16:50 -0500261panel_launcher_enter_handler(struct widget *widget, struct input *input,
Kristian Høgsberg80680c72012-05-10 12:21:37 -0400262 float x, float y, void *data)
Kristian Høgsbergee143232012-01-09 08:42:24 -0500263{
Kristian Høgsbergb6323512012-01-11 00:04:42 -0500264 struct panel_launcher *launcher = data;
265
266 launcher->focused = 1;
Kristian Høgsbergee143232012-01-09 08:42:24 -0500267 widget_schedule_redraw(widget);
Kristian Høgsbergbb901fa2012-01-09 11:22:32 -0500268
Ander Conselvan de Oliveiradc8c8fc2012-05-25 16:01:41 +0300269 return CURSOR_LEFT_PTR;
Kristian Høgsbergee143232012-01-09 08:42:24 -0500270}
271
272static void
Kristian Høgsberg53880802012-01-09 11:16:50 -0500273panel_launcher_leave_handler(struct widget *widget,
274 struct input *input, void *data)
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400275{
Kristian Høgsbergb6323512012-01-11 00:04:42 -0500276 struct panel_launcher *launcher = data;
277
278 launcher->focused = 0;
Tiago Vignatti61500722012-05-23 22:06:28 +0300279 widget_destroy_tooltip(widget);
Kristian Høgsberg9a13dab2012-01-08 15:18:19 -0500280 widget_schedule_redraw(widget);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400281}
282
283static void
Kristian Høgsberg53880802012-01-09 11:16:50 -0500284panel_launcher_button_handler(struct widget *widget,
285 struct input *input, uint32_t time,
Daniel Stone4dbadb12012-05-30 16:31:51 +0100286 uint32_t button,
287 enum wl_pointer_button_state state, void *data)
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400288{
Kristian Høgsberg53880802012-01-09 11:16:50 -0500289 struct panel_launcher *launcher;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400290
Kristian Høgsberg53880802012-01-09 11:16:50 -0500291 launcher = widget_get_user_data(widget);
Kristian Høgsberga8a0db32012-01-09 11:12:05 -0500292 widget_schedule_redraw(widget);
Daniel Stone4dbadb12012-05-30 16:31:51 +0100293 if (state == WL_POINTER_BUTTON_STATE_RELEASED)
Kristian Høgsberg53880802012-01-09 11:16:50 -0500294 panel_launcher_activate(launcher);
Kristian Høgsberga8a0db32012-01-09 11:12:05 -0500295}
296
Martin Minarik1e51a872012-06-08 00:39:11 +0200297
298static int
299panel_clock_tick(struct panel_clock *clock)
300{
301 time_t rawtime;
302 struct tm * timeinfo;
303 char string[128];
304
305 time ( &rawtime );
306 timeinfo = localtime ( &rawtime );
307 strftime (string,124,"%a %b %d, %I:%M:%S %p",timeinfo);
308
309 if (0 == strcmp(string, clock->string))
310 return 0;
311
312 strncpy (clock->string, string, 126 );
313 return 1;
314}
315
316static void
317clock_func(struct task *task, uint32_t events)
318{
319 struct panel_clock *clock =
320 container_of(task, struct panel_clock, clock_task);
321
322 if (panel_clock_tick(clock))
323 widget_schedule_redraw(clock->widget);
324}
325
326static void
327panel_clock_redraw_handler(struct widget *widget, void *data)
328{
329 cairo_surface_t *surface;
330 struct panel_clock *clock = data;
331 cairo_t *cr;
332 struct rectangle allocation;
333 cairo_text_extents_t extents;
334 cairo_font_extents_t font_extents;
335
336 time_t rawtime;
337 struct tm * timeinfo;
338
339 time ( &rawtime );
340 timeinfo = localtime ( &rawtime );
341 strftime (clock->string,126,"%a %b %d, %I:%M:%S %p",timeinfo);
342
343 widget_get_allocation(widget, &allocation);
344
345 if (allocation.width == 0) return;
346
347 surface = window_get_surface(clock->panel->window);
348 cr = cairo_create(surface);
349 cairo_rectangle(cr, allocation.x, allocation.y,
350 allocation.width, allocation.height);
351 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
352 cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.1);
353 cairo_rectangle (cr, allocation.x, allocation.y, 3, 3);
354 cairo_fill(cr);
355
356 cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
357 cairo_select_font_face(cr, "sans",
358 CAIRO_FONT_SLANT_NORMAL,
359 CAIRO_FONT_WEIGHT_NORMAL);
360 cairo_set_font_size(cr, 14);
361 cairo_text_extents(cr, clock->string, &extents);
362 cairo_font_extents (cr, &font_extents);
363 cairo_move_to(cr, allocation.x + 5, allocation.y + 3*(allocation.height>>2) + 1);
364 cairo_set_source_rgb(cr, 0, 0, 0);
365 cairo_show_text(cr, clock->string);
366 cairo_move_to(cr, allocation.x + 4, allocation.y + 3*(allocation.height>>2));
367 cairo_set_source_rgb(cr, 1, 1, 1);
368 cairo_show_text(cr, clock->string);
369 cairo_destroy(cr);
370}
371
372static int
373clock_timer_reset(struct panel_clock *clock)
374{
375 struct itimerspec its;
376 its.it_interval.tv_sec = 1;
377 its.it_interval.tv_nsec = 0;
378
379 its.it_value.tv_sec = 1;
380 its.it_value.tv_nsec = 0;
381 if (timerfd_settime(clock->clock_fd, 0, &its, NULL) < 0) {
382 fprintf(stderr, "could not set timerfd\n: %m");
383 return -1;
384 }
385
386 return 0;
387}
388
389static void
390panel_add_clock(struct panel *panel)
391{
392 struct panel_clock *clock;
393 int timerfd;
394
395 timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
396 if (timerfd < 0) {
397 fprintf(stderr, "could not create timerfd\n: %m");
398 return;
399 }
400
401 clock = malloc(sizeof *clock);
402 memset(clock, 0, sizeof *clock);
403 clock->panel = panel;
404 panel->clock = clock;
405 clock->clock_fd = timerfd;
406
407 clock->clock_task.run = clock_func;
408 display_watch_fd(
409 window_get_display(panel->window),
410 clock->clock_fd,
411 EPOLLIN,
412 &clock->clock_task);
413 clock_timer_reset(clock);
414
415 clock->widget = widget_add_widget(panel->widget, clock);
416 widget_set_redraw_handler(clock->widget,
417 panel_clock_redraw_handler);
418}
419
Kristian Høgsberga8a0db32012-01-09 11:12:05 -0500420static void
421panel_button_handler(struct widget *widget,
422 struct input *input, uint32_t time,
Daniel Stone4dbadb12012-05-30 16:31:51 +0100423 uint32_t button,
424 enum wl_pointer_button_state state, void *data)
Kristian Høgsberga8a0db32012-01-09 11:12:05 -0500425{
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500426 struct panel *panel = data;
Kristian Høgsberga8a0db32012-01-09 11:12:05 -0500427
Daniel Stone4dbadb12012-05-30 16:31:51 +0100428 if (button == BTN_RIGHT && state == WL_POINTER_BUTTON_STATE_PRESSED)
Kristian Høgsberga8a0db32012-01-09 11:12:05 -0500429 show_menu(panel, input, time);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400430}
431
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100432static void
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500433panel_resize_handler(struct widget *widget,
434 int32_t width, int32_t height, void *data)
435{
436 struct panel_launcher *launcher;
437 struct panel *panel = data;
438 int x, y, w, h;
439
440 x = 10;
441 y = 16;
442 wl_list_for_each(launcher, &panel->launcher_list, link) {
443 w = cairo_image_surface_get_width(launcher->icon);
444 h = cairo_image_surface_get_height(launcher->icon);
445 widget_set_allocation(launcher->widget,
446 x, y - h / 2, w + 1, h + 1);
447 x += w + 10;
448 }
Martin Minarik1e51a872012-06-08 00:39:11 +0200449 h=20;
450 w=170;
451 widget_set_allocation(panel->clock->widget, width - w - 8, y - h / 2, w + 1, h + 1);
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500452}
453
454static void
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100455panel_configure(void *data,
456 struct desktop_shell *desktop_shell,
Kristian Høgsbergeae5de72012-04-11 22:42:15 -0400457 uint32_t edges, struct window *window,
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100458 int32_t width, int32_t height)
459{
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500460 struct surface *surface = window_get_user_data(window);
461 struct panel *panel = container_of(surface, struct panel, base);
462
463 window_schedule_resize(panel->window, width, 32);
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100464}
465
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400466static struct panel *
467panel_create(struct display *display)
468{
469 struct panel *panel;
470
471 panel = malloc(sizeof *panel);
472 memset(panel, 0, sizeof *panel);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400473
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100474 panel->base.configure = panel_configure;
Kristian Høgsberg009ac0a2012-01-31 15:24:48 -0500475 panel->window = window_create(display);
Kristian Høgsberg75bc6672012-01-10 09:43:58 -0500476 panel->widget = window_add_widget(panel->window, panel);
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500477 wl_list_init(&panel->launcher_list);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400478
479 window_set_title(panel->window, "panel");
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400480 window_set_custom(panel->window);
481 window_set_user_data(panel->window, panel);
Kristian Høgsberga8a0db32012-01-09 11:12:05 -0500482
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500483 widget_set_redraw_handler(panel->widget, panel_redraw_handler);
484 widget_set_resize_handler(panel->widget, panel_resize_handler);
Kristian Høgsberg75bc6672012-01-10 09:43:58 -0500485 widget_set_button_handler(panel->widget, panel_button_handler);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400486
487 return panel;
488}
489
490static void
Kristian Høgsberg53880802012-01-09 11:16:50 -0500491panel_add_launcher(struct panel *panel, const char *icon, const char *path)
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400492{
Kristian Høgsberg53880802012-01-09 11:16:50 -0500493 struct panel_launcher *launcher;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400494
Kristian Høgsberg53880802012-01-09 11:16:50 -0500495 launcher = malloc(sizeof *launcher);
496 memset(launcher, 0, sizeof *launcher);
497 launcher->icon = cairo_image_surface_create_from_png(icon);
498 launcher->path = strdup(path);
499 launcher->panel = panel;
Kristian Høgsberg75bc6672012-01-10 09:43:58 -0500500 wl_list_insert(panel->launcher_list.prev, &launcher->link);
501
Kristian Høgsberg441338c2012-01-10 13:52:34 -0500502 launcher->widget = widget_add_widget(panel->widget, launcher);
Kristian Høgsberg53880802012-01-09 11:16:50 -0500503 widget_set_enter_handler(launcher->widget,
504 panel_launcher_enter_handler);
505 widget_set_leave_handler(launcher->widget,
506 panel_launcher_leave_handler);
507 widget_set_button_handler(launcher->widget,
508 panel_launcher_button_handler);
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500509 widget_set_redraw_handler(launcher->widget,
510 panel_launcher_redraw_handler);
Tiago Vignatti61500722012-05-23 22:06:28 +0300511 widget_set_motion_handler(launcher->widget,
512 panel_launcher_motion_handler);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400513}
514
Kristian Høgsberg07f72942012-01-25 16:34:36 -0500515enum {
516 BACKGROUND_SCALE,
517 BACKGROUND_TILE
518};
519
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400520static void
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500521background_draw(struct widget *widget, void *data)
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400522{
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500523 struct background *background = data;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400524 cairo_surface_t *surface, *image;
Kristian Høgsberg7e690002011-09-08 18:18:02 -0400525 cairo_pattern_t *pattern;
526 cairo_matrix_t matrix;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400527 cairo_t *cr;
Kristian Høgsberg7e690002011-09-08 18:18:02 -0400528 double sx, sy;
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500529 struct rectangle allocation;
Kristian Høgsberg07f72942012-01-25 16:34:36 -0500530 int type = -1;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400531
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500532 surface = window_get_surface(background->window);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400533
534 cr = cairo_create(surface);
535 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
536 cairo_set_source_rgba(cr, 0.0, 0.0, 0.2, 1.0);
537 cairo_paint(cr);
538
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500539 widget_get_allocation(widget, &allocation);
Kristian Høgsberg8129bc02012-01-25 14:55:33 -0500540 image = NULL;
541 if (key_background_image)
Kristian Høgsbergf02a6492012-03-12 01:05:25 -0400542 image = load_cairo_surface(key_background_image);
Kristian Høgsberg07f72942012-01-25 16:34:36 -0500543
544 if (strcmp(key_background_type, "scale") == 0)
545 type = BACKGROUND_SCALE;
546 else if (strcmp(key_background_type, "tile") == 0)
547 type = BACKGROUND_TILE;
548 else
549 fprintf(stderr, "invalid background-type: %s\n",
550 key_background_type);
551
552 if (image && type != -1) {
Kristian Høgsberg7e690002011-09-08 18:18:02 -0400553 pattern = cairo_pattern_create_for_surface(image);
Kristian Høgsberg07f72942012-01-25 16:34:36 -0500554 switch (type) {
555 case BACKGROUND_SCALE:
556 sx = (double) cairo_image_surface_get_width(image) /
557 allocation.width;
558 sy = (double) cairo_image_surface_get_height(image) /
559 allocation.height;
560 cairo_matrix_init_scale(&matrix, sx, sy);
561 cairo_pattern_set_matrix(pattern, &matrix);
562 break;
563 case BACKGROUND_TILE:
564 cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
565 break;
566 }
Kristian Høgsberg7e690002011-09-08 18:18:02 -0400567 cairo_set_source(cr, pattern);
568 cairo_pattern_destroy (pattern);
Kristian Høgsberg27d38662011-10-20 13:11:12 -0400569 cairo_surface_destroy(image);
Kristian Høgsberg8129bc02012-01-25 14:55:33 -0500570 } else {
571 set_hex_color(cr, key_background_color);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400572 }
573
Kristian Høgsberg8129bc02012-01-25 14:55:33 -0500574 cairo_paint(cr);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400575 cairo_destroy(cr);
576 cairo_surface_destroy(surface);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400577}
578
579static void
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100580background_configure(void *data,
581 struct desktop_shell *desktop_shell,
Kristian Høgsbergeae5de72012-04-11 22:42:15 -0400582 uint32_t edges, struct window *window,
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100583 int32_t width, int32_t height)
584{
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500585 struct background *background =
586 (struct background *) window_get_user_data(window);
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100587
Kristian Høgsbergbb977002012-01-10 19:11:42 -0500588 widget_schedule_resize(background->widget, width, height);
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100589}
590
591static void
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500592unlock_dialog_redraw_handler(struct widget *widget, void *data)
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200593{
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500594 struct unlock_dialog *dialog = data;
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200595 struct rectangle allocation;
596 cairo_t *cr;
597 cairo_surface_t *surface;
598 cairo_pattern_t *pat;
599 double cx, cy, r, f;
600
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200601 surface = window_get_surface(dialog->window);
602 cr = cairo_create(surface);
Kristian Høgsberg41c5c4e2012-03-05 20:37:51 -0500603
Kristian Høgsbergbb977002012-01-10 19:11:42 -0500604 widget_get_allocation(dialog->widget, &allocation);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200605 cairo_rectangle(cr, allocation.x, allocation.y,
606 allocation.width, allocation.height);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200607 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
608 cairo_set_source_rgba(cr, 0, 0, 0, 0.6);
Kristian Høgsberg41c5c4e2012-03-05 20:37:51 -0500609 cairo_fill(cr);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200610
Kristian Høgsberg41c5c4e2012-03-05 20:37:51 -0500611 cairo_translate(cr, allocation.x, allocation.y);
Kristian Høgsbergb6323512012-01-11 00:04:42 -0500612 if (dialog->button_focused)
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200613 f = 1.0;
614 else
615 f = 0.7;
616
617 cx = allocation.width / 2.0;
618 cy = allocation.height / 2.0;
619 r = (cx < cy ? cx : cy) * 0.4;
620 pat = cairo_pattern_create_radial(cx, cy, r * 0.7, cx, cy, r);
621 cairo_pattern_add_color_stop_rgb(pat, 0.0, 0, 0.86 * f, 0);
622 cairo_pattern_add_color_stop_rgb(pat, 0.85, 0.2 * f, f, 0.2 * f);
623 cairo_pattern_add_color_stop_rgb(pat, 1.0, 0, 0.86 * f, 0);
624 cairo_set_source(cr, pat);
Kristian Høgsberg41c5c4e2012-03-05 20:37:51 -0500625 cairo_pattern_destroy(pat);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200626 cairo_arc(cr, cx, cy, r, 0.0, 2.0 * M_PI);
627 cairo_fill(cr);
628
Kristian Høgsbergc51f7992012-01-08 15:09:53 -0500629 widget_set_allocation(dialog->button,
Kristian Høgsberg41c5c4e2012-03-05 20:37:51 -0500630 allocation.x + cx - r,
631 allocation.y + cy - r, 2 * r, 2 * r);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200632
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200633 cairo_destroy(cr);
634
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200635 cairo_surface_destroy(surface);
636}
637
638static void
Kristian Høgsberga8a0db32012-01-09 11:12:05 -0500639unlock_dialog_button_handler(struct widget *widget,
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200640 struct input *input, uint32_t time,
Daniel Stone4dbadb12012-05-30 16:31:51 +0100641 uint32_t button,
642 enum wl_pointer_button_state state, void *data)
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200643{
644 struct unlock_dialog *dialog = data;
645 struct desktop *desktop = dialog->desktop;
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200646
Kristian Høgsberga8a0db32012-01-09 11:12:05 -0500647 if (button == BTN_LEFT) {
Daniel Stone4dbadb12012-05-30 16:31:51 +0100648 if (state == WL_POINTER_BUTTON_STATE_RELEASED &&
649 !dialog->closing) {
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200650 display_defer(desktop->display, &desktop->unlock_task);
651 dialog->closing = 1;
652 }
653 }
654}
655
656static void
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200657unlock_dialog_keyboard_focus_handler(struct window *window,
658 struct input *device, void *data)
659{
660 window_schedule_redraw(window);
661}
662
Kristian Høgsbergbb901fa2012-01-09 11:22:32 -0500663static int
Kristian Høgsbergee143232012-01-09 08:42:24 -0500664unlock_dialog_widget_enter_handler(struct widget *widget,
Kristian Høgsbergeae5de72012-04-11 22:42:15 -0400665 struct input *input,
Kristian Høgsberg80680c72012-05-10 12:21:37 -0400666 float x, float y, void *data)
Kristian Høgsbergee143232012-01-09 08:42:24 -0500667{
Kristian Høgsbergb6323512012-01-11 00:04:42 -0500668 struct unlock_dialog *dialog = data;
669
670 dialog->button_focused = 1;
Kristian Høgsbergee143232012-01-09 08:42:24 -0500671 widget_schedule_redraw(widget);
Kristian Høgsbergbb901fa2012-01-09 11:22:32 -0500672
Ander Conselvan de Oliveiradc8c8fc2012-05-25 16:01:41 +0300673 return CURSOR_LEFT_PTR;
Kristian Høgsbergee143232012-01-09 08:42:24 -0500674}
675
676static void
677unlock_dialog_widget_leave_handler(struct widget *widget,
678 struct input *input, void *data)
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200679{
Kristian Høgsbergb6323512012-01-11 00:04:42 -0500680 struct unlock_dialog *dialog = data;
681
682 dialog->button_focused = 0;
Kristian Høgsberg9a13dab2012-01-08 15:18:19 -0500683 widget_schedule_redraw(widget);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200684}
685
686static struct unlock_dialog *
Kristian Høgsberg1ec0c312011-11-15 16:39:55 -0500687unlock_dialog_create(struct desktop *desktop)
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200688{
Kristian Høgsberg1ec0c312011-11-15 16:39:55 -0500689 struct display *display = desktop->display;
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200690 struct unlock_dialog *dialog;
691
692 dialog = malloc(sizeof *dialog);
693 if (!dialog)
694 return NULL;
695 memset(dialog, 0, sizeof *dialog);
696
Kristian Høgsberg009ac0a2012-01-31 15:24:48 -0500697 dialog->window = window_create(display);
Kristian Høgsberg29af3eb2012-01-10 22:41:05 -0500698 dialog->widget = frame_create(dialog->window, dialog);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200699 window_set_title(dialog->window, "Unlock your desktop");
Benjamin Franzke8193bc12011-11-23 19:35:07 +0100700 window_set_custom(dialog->window);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200701
702 window_set_user_data(dialog->window, dialog);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200703 window_set_keyboard_focus_handler(dialog->window,
704 unlock_dialog_keyboard_focus_handler);
Kristian Høgsberg441338c2012-01-10 13:52:34 -0500705 dialog->button = widget_add_widget(dialog->widget, dialog);
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500706 widget_set_redraw_handler(dialog->widget,
707 unlock_dialog_redraw_handler);
Kristian Høgsbergee143232012-01-09 08:42:24 -0500708 widget_set_enter_handler(dialog->button,
709 unlock_dialog_widget_enter_handler);
710 widget_set_leave_handler(dialog->button,
711 unlock_dialog_widget_leave_handler);
Kristian Høgsberga8a0db32012-01-09 11:12:05 -0500712 widget_set_button_handler(dialog->button,
713 unlock_dialog_button_handler);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200714
Kristian Høgsberg1ec0c312011-11-15 16:39:55 -0500715 desktop_shell_set_lock_surface(desktop->shell,
Pekka Paalanen068ae942011-11-28 14:11:15 +0200716 window_get_wl_shell_surface(dialog->window));
Kristian Høgsberg1ec0c312011-11-15 16:39:55 -0500717
Pekka Paalanen40e49ac2012-01-18 16:51:30 +0200718 window_schedule_resize(dialog->window, 260, 230);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200719
720 return dialog;
721}
722
723static void
724unlock_dialog_destroy(struct unlock_dialog *dialog)
725{
726 window_destroy(dialog->window);
727 free(dialog);
728}
729
730static void
731unlock_dialog_finish(struct task *task, uint32_t events)
732{
733 struct desktop *desktop =
Benjamin Franzked7759712011-11-22 12:38:48 +0100734 container_of(task, struct desktop, unlock_task);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200735
736 desktop_shell_unlock(desktop->shell);
737 unlock_dialog_destroy(desktop->unlock_dialog);
738 desktop->unlock_dialog = NULL;
739}
740
741static void
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400742desktop_shell_configure(void *data,
743 struct desktop_shell *desktop_shell,
Kristian Høgsbergeae5de72012-04-11 22:42:15 -0400744 uint32_t edges,
Pekka Paalanen068ae942011-11-28 14:11:15 +0200745 struct wl_shell_surface *shell_surface,
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400746 int32_t width, int32_t height)
747{
Pekka Paalanen068ae942011-11-28 14:11:15 +0200748 struct window *window = wl_shell_surface_get_user_data(shell_surface);
749 struct surface *s = window_get_user_data(window);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400750
Kristian Høgsbergeae5de72012-04-11 22:42:15 -0400751 s->configure(data, desktop_shell, edges, window, width, height);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400752}
753
Pekka Paalanen9ef3e012011-11-15 13:34:48 +0200754static void
755desktop_shell_prepare_lock_surface(void *data,
756 struct desktop_shell *desktop_shell)
757{
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200758 struct desktop *desktop = data;
759
Pekka Paalanenfd83b6d2011-12-08 10:06:53 +0200760 if (!key_locking) {
761 desktop_shell_unlock(desktop->shell);
762 return;
763 }
764
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200765 if (!desktop->unlock_dialog) {
Kristian Høgsberg1ec0c312011-11-15 16:39:55 -0500766 desktop->unlock_dialog = unlock_dialog_create(desktop);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200767 desktop->unlock_dialog->desktop = desktop;
768 }
Pekka Paalanen9ef3e012011-11-15 13:34:48 +0200769}
770
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400771static const struct desktop_shell_listener listener = {
Pekka Paalanen9ef3e012011-11-15 13:34:48 +0200772 desktop_shell_configure,
773 desktop_shell_prepare_lock_surface
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400774};
775
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100776static struct background *
777background_create(struct desktop *desktop)
778{
779 struct background *background;
780
781 background = malloc(sizeof *background);
782 memset(background, 0, sizeof *background);
783
784 background->base.configure = background_configure;
Kristian Høgsberg009ac0a2012-01-31 15:24:48 -0500785 background->window = window_create(desktop->display);
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500786 background->widget = window_add_widget(background->window, background);
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100787 window_set_custom(background->window);
788 window_set_user_data(background->window, background);
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500789 widget_set_redraw_handler(background->widget, background_draw);
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100790
791 return background;
792}
793
Kristian Høgsbergd56bd902012-06-05 09:58:51 -0400794static const struct wl_callback_listener busy_cursor_listener;
795
796static void
797busy_cursor_frame_callback(void *data,
798 struct wl_callback *callback, uint32_t time)
799{
800 struct input *input = data;
801 struct display *display = input_get_display(input);
802 struct desktop *desktop = display_get_user_data(display);
803 struct wl_surface *surface;
804 int index;
805
806 if (callback)
807 wl_callback_destroy(callback);
808 if (input_get_focus_widget(input) != desktop->busy_widget)
809 return;
810
811 /* FIXME: Get frame duration and number of frames from cursor. */
812 index = (time / 100) % 8;
813 input_set_pointer_image_index(input, CURSOR_WATCH, index);
814
815 surface = window_get_wl_surface(desktop->busy_window);
816 callback = wl_surface_frame(surface);
817 wl_callback_add_listener(callback, &busy_cursor_listener, input);
818}
819
820static const struct wl_callback_listener busy_cursor_listener = {
821 busy_cursor_frame_callback
822};
823
824static int
825busy_surface_enter_handler(struct widget *widget, struct input *input,
826 float x, float y, void *data)
827{
828 busy_cursor_frame_callback(input, NULL, 0);
829
830 return CURSOR_WATCH;
831}
832
833static void
834busy_surface_create(struct desktop *desktop)
835{
836 struct wl_surface *s;
837
838 desktop->busy_window = window_create(desktop->display);
839 s = window_get_wl_surface(desktop->busy_window);
840 desktop_shell_set_busy_surface(desktop->shell, s);
841
842 desktop->busy_widget =
843 window_add_widget(desktop->busy_window, desktop);
844 /* We set the allocation to 1x1 at 0,0 so the fake enter event
845 * at 0,0 will go to this widget. */
846 widget_set_allocation(desktop->busy_widget, 0, 0, 1, 1);
847
848 widget_set_enter_handler(desktop->busy_widget,
849 busy_surface_enter_handler);
850}
851
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100852static void
853create_output(struct desktop *desktop, uint32_t id)
854{
855 struct output *output;
856
857 output = calloc(1, sizeof *output);
858 if (!output)
859 return;
860
861 output->output = wl_display_bind(display_get_display(desktop->display),
862 id, &wl_output_interface);
863
864 wl_list_insert(&desktop->outputs, &output->link);
865}
866
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400867static void
868global_handler(struct wl_display *display, uint32_t id,
869 const char *interface, uint32_t version, void *data)
870{
871 struct desktop *desktop = data;
872
873 if (!strcmp(interface, "desktop_shell")) {
874 desktop->shell =
875 wl_display_bind(display, id, &desktop_shell_interface);
876 desktop_shell_add_listener(desktop->shell, &listener, desktop);
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100877 } else if (!strcmp(interface, "wl_output")) {
878 create_output(desktop, id);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400879 }
880}
881
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500882static void
883launcher_section_done(void *data)
884{
885 struct desktop *desktop = data;
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100886 struct output *output;
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500887
888 if (key_launcher_icon == NULL || key_launcher_path == NULL) {
889 fprintf(stderr, "invalid launcher section\n");
890 return;
891 }
892
Martin Minarik1e51a872012-06-08 00:39:11 +0200893 wl_list_for_each(output, &desktop->outputs, link) {
Kristian Høgsberg53880802012-01-09 11:16:50 -0500894 panel_add_launcher(output->panel,
895 key_launcher_icon, key_launcher_path);
Martin Minarik1e51a872012-06-08 00:39:11 +0200896 panel_add_clock(output->panel);
897 }
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100898
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500899 free(key_launcher_icon);
900 key_launcher_icon = NULL;
901 free(key_launcher_path);
902 key_launcher_path = NULL;
903}
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400904
Kristian Høgsberg6af8eb92012-01-25 16:57:11 -0500905static void
906add_default_launcher(struct desktop *desktop)
907{
908 struct output *output;
909
910 wl_list_for_each(output, &desktop->outputs, link)
911 panel_add_launcher(output->panel,
912 DATADIR "/weston/terminal.png",
Rodney Lorrimar99ff01b2012-02-29 17:31:03 +0100913 BINDIR "/weston-terminal");
Kristian Høgsberg6af8eb92012-01-25 16:57:11 -0500914}
915
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400916int main(int argc, char *argv[])
917{
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200918 struct desktop desktop = { 0 };
Pekka Paalanen668dd562011-11-15 11:45:40 +0200919 char *config_file;
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100920 struct output *output;
Kristian Høgsberg6af8eb92012-01-25 16:57:11 -0500921 int ret;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400922
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200923 desktop.unlock_task.run = unlock_dialog_finish;
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100924 wl_list_init(&desktop.outputs);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200925
Kristian Høgsbergbcacef12012-03-11 21:05:57 -0400926 desktop.display = display_create(argc, argv);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400927 if (desktop.display == NULL) {
928 fprintf(stderr, "failed to create display: %m\n");
929 return -1;
930 }
931
Kristian Høgsbergd56bd902012-06-05 09:58:51 -0400932 display_set_user_data(desktop.display, &desktop);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400933 wl_display_add_global_listener(display_get_display(desktop.display),
934 global_handler, &desktop);
935
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100936 wl_list_for_each(output, &desktop.outputs, link) {
Pekka Paalanen068ae942011-11-28 14:11:15 +0200937 struct wl_shell_surface *s;
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100938
939 output->panel = panel_create(desktop.display);
Pekka Paalanen068ae942011-11-28 14:11:15 +0200940 s = window_get_wl_shell_surface(output->panel->window);
941 desktop_shell_set_panel(desktop.shell, output->output, s);
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100942
943 output->background = background_create(&desktop);
Pekka Paalanen068ae942011-11-28 14:11:15 +0200944 s = window_get_wl_shell_surface(output->background->window);
945 desktop_shell_set_background(desktop.shell, output->output, s);
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100946 }
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400947
Kristian Høgsbergd56bd902012-06-05 09:58:51 -0400948 busy_surface_create(&desktop);
949
Tiago Vignatti9a206c42012-03-21 19:49:18 +0200950 config_file = config_file_path("weston.ini");
Kristian Høgsberg6af8eb92012-01-25 16:57:11 -0500951 ret = parse_config_file(config_file,
952 config_sections, ARRAY_LENGTH(config_sections),
953 &desktop);
Pekka Paalanen668dd562011-11-15 11:45:40 +0200954 free(config_file);
Kristian Høgsberg6af8eb92012-01-25 16:57:11 -0500955 if (ret < 0)
956 add_default_launcher(&desktop);
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500957
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400958 signal(SIGCHLD, sigchild_handler);
959
960 display_run(desktop.display);
961
962 return 0;
963}