blob: 9a1b502fc4feda0c1525120d0ab29513503c64f4 [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;
Martin Minarik1e51a872012-06-08 00:39:11 +020098 struct task clock_task;
99 int clock_fd;
100};
101
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200102struct unlock_dialog {
103 struct window *window;
Kristian Høgsberg75bc6672012-01-10 09:43:58 -0500104 struct widget *widget;
Kristian Høgsbergc51f7992012-01-08 15:09:53 -0500105 struct widget *button;
Kristian Høgsbergb6323512012-01-11 00:04:42 -0500106 int button_focused;
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200107 int closing;
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200108 struct desktop *desktop;
109};
110
Kristian Høgsberg6af8eb92012-01-25 16:57:11 -0500111static char *key_background_image = DATADIR "/weston/pattern.png";
112static char *key_background_type = "tile";
113static uint32_t key_panel_color = 0xaa000000;
114static uint32_t key_background_color = 0xff002244;
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500115static char *key_launcher_icon;
116static char *key_launcher_path;
117static void launcher_section_done(void *data);
Pekka Paalanenfd83b6d2011-12-08 10:06:53 +0200118static int key_locking = 1;
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500119
120static const struct config_key shell_config_keys[] = {
121 { "background-image", CONFIG_KEY_STRING, &key_background_image },
Kristian Høgsberg07f72942012-01-25 16:34:36 -0500122 { "background-type", CONFIG_KEY_STRING, &key_background_type },
Scott Moreaufa1de692012-01-27 13:25:49 -0700123 { "panel-color", CONFIG_KEY_UNSIGNED_INTEGER, &key_panel_color },
124 { "background-color", CONFIG_KEY_UNSIGNED_INTEGER, &key_background_color },
Pekka Paalanenfd83b6d2011-12-08 10:06:53 +0200125 { "locking", CONFIG_KEY_BOOLEAN, &key_locking },
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500126};
127
128static const struct config_key launcher_config_keys[] = {
129 { "icon", CONFIG_KEY_STRING, &key_launcher_icon },
130 { "path", CONFIG_KEY_STRING, &key_launcher_path },
131};
132
133static const struct config_section config_sections[] = {
Tiago Vignatti9a206c42012-03-21 19:49:18 +0200134 { "shell",
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500135 shell_config_keys, ARRAY_LENGTH(shell_config_keys) },
136 { "launcher",
137 launcher_config_keys, ARRAY_LENGTH(launcher_config_keys),
138 launcher_section_done }
139};
140
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400141static void
142sigchild_handler(int s)
143{
144 int status;
145 pid_t pid;
146
147 while (pid = waitpid(-1, &status, WNOHANG), pid > 0)
148 fprintf(stderr, "child %d exited\n", pid);
149}
150
151static void
Pekka Paalanen9e30a822012-01-19 16:40:28 +0200152menu_func(struct window *window, int index, void *data)
153{
154 printf("Selected index %d from a panel menu.\n", index);
155}
156
157static void
Kristian Høgsbergb3cca0a2012-01-04 22:19:14 -0500158show_menu(struct panel *panel, struct input *input, uint32_t time)
Kristian Høgsbergbcee9a42011-10-12 00:36:16 -0400159{
Kristian Høgsbergb3cca0a2012-01-04 22:19:14 -0500160 int32_t x, y;
161 static const char *entries[] = {
162 "Roy", "Pris", "Leon", "Zhora"
163 };
Kristian Høgsbergbcee9a42011-10-12 00:36:16 -0400164
165 input_get_position(input, &x, &y);
Pekka Paalanen6d174cf2012-01-19 15:17:59 +0200166 window_show_menu(window_get_display(panel->window),
167 input, time, panel->window,
Pekka Paalanen9e30a822012-01-19 16:40:28 +0200168 x - 10, y - 10, menu_func, entries, 4);
Kristian Høgsbergbcee9a42011-10-12 00:36:16 -0400169}
170
171static void
Kristian Høgsberg53880802012-01-09 11:16:50 -0500172panel_launcher_activate(struct panel_launcher *widget)
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400173{
174 pid_t pid;
175
176 pid = fork();
177 if (pid < 0) {
178 fprintf(stderr, "fork failed: %m\n");
179 return;
180 }
181
182 if (pid)
183 return;
Benjamin Franzked7759712011-11-22 12:38:48 +0100184
Kristian Høgsbergc51f7992012-01-08 15:09:53 -0500185 if (execl(widget->path, widget->path, NULL) < 0) {
Pekka Paalanena291ae52012-01-27 09:50:02 +0200186 fprintf(stderr, "execl '%s' failed: %m\n", widget->path);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400187 exit(1);
188 }
189}
190
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400191static void
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500192panel_launcher_redraw_handler(struct widget *widget, void *data)
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400193{
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500194 struct panel_launcher *launcher = data;
195 cairo_surface_t *surface;
196 struct rectangle allocation;
197 cairo_t *cr;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400198
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500199 surface = window_get_surface(launcher->panel->window);
200 cr = cairo_create(surface);
201
202 widget_get_allocation(widget, &allocation);
Kristian Høgsberg75bc6672012-01-10 09:43:58 -0500203 if (launcher->pressed) {
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500204 allocation.x++;
205 allocation.y++;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400206 }
207
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500208 cairo_set_source_surface(cr, launcher->icon,
209 allocation.x, allocation.y);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400210 cairo_paint(cr);
211
Kristian Høgsbergb6323512012-01-11 00:04:42 -0500212 if (launcher->focused) {
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400213 cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.4);
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500214 cairo_mask_surface(cr, launcher->icon,
215 allocation.x, allocation.y);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400216 }
Kristian Høgsberge28d05b2011-09-20 21:43:54 -0400217
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500218 cairo_destroy(cr);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400219}
220
Tiago Vignatti61500722012-05-23 22:06:28 +0300221static int
222panel_launcher_motion_handler(struct widget *widget, struct input *input,
223 uint32_t time, float x, float y, void *data)
224{
225 struct panel_launcher *launcher = data;
226
227 widget_set_tooltip(widget, basename((char *)launcher->path), x, y);
228
Ander Conselvan de Oliveiradc8c8fc2012-05-25 16:01:41 +0300229 return CURSOR_LEFT_PTR;
Tiago Vignatti61500722012-05-23 22:06:28 +0300230}
231
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400232static void
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500233set_hex_color(cairo_t *cr, uint32_t color)
234{
235 cairo_set_source_rgba(cr,
236 ((color >> 16) & 0xff) / 255.0,
237 ((color >> 8) & 0xff) / 255.0,
238 ((color >> 0) & 0xff) / 255.0,
239 ((color >> 24) & 0xff) / 255.0);
240}
241
242static void
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500243panel_redraw_handler(struct widget *widget, void *data)
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400244{
245 cairo_surface_t *surface;
246 cairo_t *cr;
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500247 struct panel *panel = data;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400248
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500249 surface = window_get_surface(panel->window);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400250 cr = cairo_create(surface);
251 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500252 set_hex_color(cr, key_panel_color);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400253 cairo_paint(cr);
254
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400255 cairo_destroy(cr);
256 cairo_surface_destroy(surface);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400257}
258
Kristian Høgsbergbb901fa2012-01-09 11:22:32 -0500259static int
Kristian Høgsberg53880802012-01-09 11:16:50 -0500260panel_launcher_enter_handler(struct widget *widget, struct input *input,
Kristian Høgsberg80680c72012-05-10 12:21:37 -0400261 float x, float y, void *data)
Kristian Høgsbergee143232012-01-09 08:42:24 -0500262{
Kristian Høgsbergb6323512012-01-11 00:04:42 -0500263 struct panel_launcher *launcher = data;
264
265 launcher->focused = 1;
Kristian Høgsbergee143232012-01-09 08:42:24 -0500266 widget_schedule_redraw(widget);
Kristian Høgsbergbb901fa2012-01-09 11:22:32 -0500267
Ander Conselvan de Oliveiradc8c8fc2012-05-25 16:01:41 +0300268 return CURSOR_LEFT_PTR;
Kristian Høgsbergee143232012-01-09 08:42:24 -0500269}
270
271static void
Kristian Høgsberg53880802012-01-09 11:16:50 -0500272panel_launcher_leave_handler(struct widget *widget,
273 struct input *input, void *data)
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400274{
Kristian Høgsbergb6323512012-01-11 00:04:42 -0500275 struct panel_launcher *launcher = data;
276
277 launcher->focused = 0;
Tiago Vignatti61500722012-05-23 22:06:28 +0300278 widget_destroy_tooltip(widget);
Kristian Høgsberg9a13dab2012-01-08 15:18:19 -0500279 widget_schedule_redraw(widget);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400280}
281
282static void
Kristian Høgsberg53880802012-01-09 11:16:50 -0500283panel_launcher_button_handler(struct widget *widget,
284 struct input *input, uint32_t time,
Daniel Stone4dbadb12012-05-30 16:31:51 +0100285 uint32_t button,
286 enum wl_pointer_button_state state, void *data)
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400287{
Kristian Høgsberg53880802012-01-09 11:16:50 -0500288 struct panel_launcher *launcher;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400289
Kristian Høgsberg53880802012-01-09 11:16:50 -0500290 launcher = widget_get_user_data(widget);
Kristian Høgsberga8a0db32012-01-09 11:12:05 -0500291 widget_schedule_redraw(widget);
Daniel Stone4dbadb12012-05-30 16:31:51 +0100292 if (state == WL_POINTER_BUTTON_STATE_RELEASED)
Kristian Høgsberg53880802012-01-09 11:16:50 -0500293 panel_launcher_activate(launcher);
Kristian Høgsberga8a0db32012-01-09 11:12:05 -0500294}
295
Martin Minarik1e51a872012-06-08 00:39:11 +0200296static void
297clock_func(struct task *task, uint32_t events)
298{
299 struct panel_clock *clock =
Kristian Høgsbergbb262cf2012-06-11 11:03:03 -0400300 container_of(task, struct panel_clock, clock_task);
Kristian Høgsberg70226bb2012-06-08 16:54:52 -0400301 uint64_t exp;
Martin Minarik1e51a872012-06-08 00:39:11 +0200302
Kristian Høgsberg70226bb2012-06-08 16:54:52 -0400303 read(clock->clock_fd, &exp, sizeof exp);
Kristian Høgsberg92a984a2012-06-11 11:10:57 -0400304 widget_schedule_redraw(clock->widget);
Martin Minarik1e51a872012-06-08 00:39:11 +0200305}
306
307static void
308panel_clock_redraw_handler(struct widget *widget, void *data)
309{
310 cairo_surface_t *surface;
311 struct panel_clock *clock = data;
312 cairo_t *cr;
313 struct rectangle allocation;
314 cairo_text_extents_t extents;
315 cairo_font_extents_t font_extents;
Martin Minarik1e51a872012-06-08 00:39:11 +0200316 time_t rawtime;
317 struct tm * timeinfo;
Kristian Høgsberg92a984a2012-06-11 11:10:57 -0400318 char string[128];
Martin Minarik1e51a872012-06-08 00:39:11 +0200319
Kristian Høgsbergbb262cf2012-06-11 11:03:03 -0400320 time(&rawtime);
321 timeinfo = localtime(&rawtime);
Kristian Høgsberge9f68f62012-06-11 12:24:12 -0400322 strftime(string, sizeof string, "%a %b %d, %I:%M %p", timeinfo);
Martin Minarik1e51a872012-06-08 00:39:11 +0200323
324 widget_get_allocation(widget, &allocation);
Kristian Høgsbergbb262cf2012-06-11 11:03:03 -0400325 if (allocation.width == 0)
326 return;
Martin Minarik1e51a872012-06-08 00:39:11 +0200327
328 surface = window_get_surface(clock->panel->window);
329 cr = cairo_create(surface);
Martin Minarik1e51a872012-06-08 00:39:11 +0200330 cairo_select_font_face(cr, "sans",
331 CAIRO_FONT_SLANT_NORMAL,
332 CAIRO_FONT_WEIGHT_NORMAL);
333 cairo_set_font_size(cr, 14);
Kristian Høgsberg92a984a2012-06-11 11:10:57 -0400334 cairo_text_extents(cr, string, &extents);
Martin Minarik1e51a872012-06-08 00:39:11 +0200335 cairo_font_extents (cr, &font_extents);
Kristian Høgsbergbb262cf2012-06-11 11:03:03 -0400336 cairo_move_to(cr, allocation.x + 5,
337 allocation.y + 3 * (allocation.height >> 2) + 1);
338 cairo_set_source_rgb(cr, 0, 0, 0);
Kristian Høgsberg92a984a2012-06-11 11:10:57 -0400339 cairo_show_text(cr, string);
Kristian Høgsbergbb262cf2012-06-11 11:03:03 -0400340 cairo_move_to(cr, allocation.x + 4,
341 allocation.y + 3 * (allocation.height >> 2));
342 cairo_set_source_rgb(cr, 1, 1, 1);
Kristian Høgsberg92a984a2012-06-11 11:10:57 -0400343 cairo_show_text(cr, string);
Martin Minarik1e51a872012-06-08 00:39:11 +0200344 cairo_destroy(cr);
345}
346
347static int
348clock_timer_reset(struct panel_clock *clock)
349{
350 struct itimerspec its;
Kristian Høgsbergbb262cf2012-06-11 11:03:03 -0400351
Kristian Høgsberge9f68f62012-06-11 12:24:12 -0400352 its.it_interval.tv_sec = 60;
Martin Minarik1e51a872012-06-08 00:39:11 +0200353 its.it_interval.tv_nsec = 0;
Kristian Høgsberge9f68f62012-06-11 12:24:12 -0400354 its.it_value.tv_sec = 60;
Martin Minarik1e51a872012-06-08 00:39:11 +0200355 its.it_value.tv_nsec = 0;
356 if (timerfd_settime(clock->clock_fd, 0, &its, NULL) < 0) {
357 fprintf(stderr, "could not set timerfd\n: %m");
358 return -1;
359 }
360
361 return 0;
362}
363
364static void
365panel_add_clock(struct panel *panel)
366{
367 struct panel_clock *clock;
368 int timerfd;
369
370 timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
371 if (timerfd < 0) {
372 fprintf(stderr, "could not create timerfd\n: %m");
373 return;
374 }
375
376 clock = malloc(sizeof *clock);
377 memset(clock, 0, sizeof *clock);
378 clock->panel = panel;
379 panel->clock = clock;
380 clock->clock_fd = timerfd;
381
382 clock->clock_task.run = clock_func;
Kristian Høgsbergbb262cf2012-06-11 11:03:03 -0400383 display_watch_fd(window_get_display(panel->window), clock->clock_fd,
384 EPOLLIN, &clock->clock_task);
Martin Minarik1e51a872012-06-08 00:39:11 +0200385 clock_timer_reset(clock);
386
387 clock->widget = widget_add_widget(panel->widget, clock);
Kristian Høgsbergbb262cf2012-06-11 11:03:03 -0400388 widget_set_redraw_handler(clock->widget, panel_clock_redraw_handler);
Martin Minarik1e51a872012-06-08 00:39:11 +0200389}
390
Kristian Høgsberga8a0db32012-01-09 11:12:05 -0500391static void
392panel_button_handler(struct widget *widget,
393 struct input *input, uint32_t time,
Daniel Stone4dbadb12012-05-30 16:31:51 +0100394 uint32_t button,
395 enum wl_pointer_button_state state, void *data)
Kristian Høgsberga8a0db32012-01-09 11:12:05 -0500396{
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500397 struct panel *panel = data;
Kristian Høgsberga8a0db32012-01-09 11:12:05 -0500398
Daniel Stone4dbadb12012-05-30 16:31:51 +0100399 if (button == BTN_RIGHT && state == WL_POINTER_BUTTON_STATE_PRESSED)
Kristian Høgsberga8a0db32012-01-09 11:12:05 -0500400 show_menu(panel, input, time);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400401}
402
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100403static void
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500404panel_resize_handler(struct widget *widget,
405 int32_t width, int32_t height, void *data)
406{
407 struct panel_launcher *launcher;
408 struct panel *panel = data;
409 int x, y, w, h;
410
411 x = 10;
412 y = 16;
413 wl_list_for_each(launcher, &panel->launcher_list, link) {
414 w = cairo_image_surface_get_width(launcher->icon);
415 h = cairo_image_surface_get_height(launcher->icon);
416 widget_set_allocation(launcher->widget,
417 x, y - h / 2, w + 1, h + 1);
418 x += w + 10;
419 }
Martin Minarik1e51a872012-06-08 00:39:11 +0200420 h=20;
421 w=170;
422 widget_set_allocation(panel->clock->widget, width - w - 8, y - h / 2, w + 1, h + 1);
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500423}
424
425static void
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100426panel_configure(void *data,
427 struct desktop_shell *desktop_shell,
Kristian Høgsbergeae5de72012-04-11 22:42:15 -0400428 uint32_t edges, struct window *window,
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100429 int32_t width, int32_t height)
430{
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500431 struct surface *surface = window_get_user_data(window);
432 struct panel *panel = container_of(surface, struct panel, base);
433
434 window_schedule_resize(panel->window, width, 32);
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100435}
436
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400437static struct panel *
438panel_create(struct display *display)
439{
440 struct panel *panel;
441
442 panel = malloc(sizeof *panel);
443 memset(panel, 0, sizeof *panel);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400444
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100445 panel->base.configure = panel_configure;
Kristian Høgsberg009ac0a2012-01-31 15:24:48 -0500446 panel->window = window_create(display);
Kristian Høgsberg75bc6672012-01-10 09:43:58 -0500447 panel->widget = window_add_widget(panel->window, panel);
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500448 wl_list_init(&panel->launcher_list);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400449
450 window_set_title(panel->window, "panel");
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400451 window_set_custom(panel->window);
452 window_set_user_data(panel->window, panel);
Kristian Høgsberga8a0db32012-01-09 11:12:05 -0500453
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500454 widget_set_redraw_handler(panel->widget, panel_redraw_handler);
455 widget_set_resize_handler(panel->widget, panel_resize_handler);
Kristian Høgsberg75bc6672012-01-10 09:43:58 -0500456 widget_set_button_handler(panel->widget, panel_button_handler);
Rafal Mielniczukb9e513c2012-06-09 20:33:29 +0200457
458 panel_add_clock(panel);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400459
460 return panel;
461}
462
463static void
Kristian Høgsberg53880802012-01-09 11:16:50 -0500464panel_add_launcher(struct panel *panel, const char *icon, const char *path)
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400465{
Kristian Høgsberg53880802012-01-09 11:16:50 -0500466 struct panel_launcher *launcher;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400467
Kristian Høgsberg53880802012-01-09 11:16:50 -0500468 launcher = malloc(sizeof *launcher);
469 memset(launcher, 0, sizeof *launcher);
470 launcher->icon = cairo_image_surface_create_from_png(icon);
471 launcher->path = strdup(path);
472 launcher->panel = panel;
Kristian Høgsberg75bc6672012-01-10 09:43:58 -0500473 wl_list_insert(panel->launcher_list.prev, &launcher->link);
474
Kristian Høgsberg441338c2012-01-10 13:52:34 -0500475 launcher->widget = widget_add_widget(panel->widget, launcher);
Kristian Høgsberg53880802012-01-09 11:16:50 -0500476 widget_set_enter_handler(launcher->widget,
477 panel_launcher_enter_handler);
478 widget_set_leave_handler(launcher->widget,
479 panel_launcher_leave_handler);
480 widget_set_button_handler(launcher->widget,
481 panel_launcher_button_handler);
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500482 widget_set_redraw_handler(launcher->widget,
483 panel_launcher_redraw_handler);
Tiago Vignatti61500722012-05-23 22:06:28 +0300484 widget_set_motion_handler(launcher->widget,
485 panel_launcher_motion_handler);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400486}
487
Kristian Høgsberg07f72942012-01-25 16:34:36 -0500488enum {
489 BACKGROUND_SCALE,
490 BACKGROUND_TILE
491};
492
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400493static void
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500494background_draw(struct widget *widget, void *data)
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400495{
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500496 struct background *background = data;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400497 cairo_surface_t *surface, *image;
Kristian Høgsberg7e690002011-09-08 18:18:02 -0400498 cairo_pattern_t *pattern;
499 cairo_matrix_t matrix;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400500 cairo_t *cr;
Kristian Høgsberg7e690002011-09-08 18:18:02 -0400501 double sx, sy;
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500502 struct rectangle allocation;
Kristian Høgsberg07f72942012-01-25 16:34:36 -0500503 int type = -1;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400504
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500505 surface = window_get_surface(background->window);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400506
507 cr = cairo_create(surface);
508 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
509 cairo_set_source_rgba(cr, 0.0, 0.0, 0.2, 1.0);
510 cairo_paint(cr);
511
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500512 widget_get_allocation(widget, &allocation);
Kristian Høgsberg8129bc02012-01-25 14:55:33 -0500513 image = NULL;
514 if (key_background_image)
Kristian Høgsbergf02a6492012-03-12 01:05:25 -0400515 image = load_cairo_surface(key_background_image);
Kristian Høgsberg07f72942012-01-25 16:34:36 -0500516
517 if (strcmp(key_background_type, "scale") == 0)
518 type = BACKGROUND_SCALE;
519 else if (strcmp(key_background_type, "tile") == 0)
520 type = BACKGROUND_TILE;
521 else
522 fprintf(stderr, "invalid background-type: %s\n",
523 key_background_type);
524
525 if (image && type != -1) {
Kristian Høgsberg7e690002011-09-08 18:18:02 -0400526 pattern = cairo_pattern_create_for_surface(image);
Kristian Høgsberg07f72942012-01-25 16:34:36 -0500527 switch (type) {
528 case BACKGROUND_SCALE:
529 sx = (double) cairo_image_surface_get_width(image) /
530 allocation.width;
531 sy = (double) cairo_image_surface_get_height(image) /
532 allocation.height;
533 cairo_matrix_init_scale(&matrix, sx, sy);
534 cairo_pattern_set_matrix(pattern, &matrix);
535 break;
536 case BACKGROUND_TILE:
537 cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
538 break;
539 }
Kristian Høgsberg7e690002011-09-08 18:18:02 -0400540 cairo_set_source(cr, pattern);
541 cairo_pattern_destroy (pattern);
Kristian Høgsberg27d38662011-10-20 13:11:12 -0400542 cairo_surface_destroy(image);
Kristian Høgsberg8129bc02012-01-25 14:55:33 -0500543 } else {
544 set_hex_color(cr, key_background_color);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400545 }
546
Kristian Høgsberg8129bc02012-01-25 14:55:33 -0500547 cairo_paint(cr);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400548 cairo_destroy(cr);
549 cairo_surface_destroy(surface);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400550}
551
552static void
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100553background_configure(void *data,
554 struct desktop_shell *desktop_shell,
Kristian Høgsbergeae5de72012-04-11 22:42:15 -0400555 uint32_t edges, struct window *window,
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100556 int32_t width, int32_t height)
557{
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500558 struct background *background =
559 (struct background *) window_get_user_data(window);
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100560
Kristian Høgsbergbb977002012-01-10 19:11:42 -0500561 widget_schedule_resize(background->widget, width, height);
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100562}
563
564static void
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500565unlock_dialog_redraw_handler(struct widget *widget, void *data)
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200566{
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500567 struct unlock_dialog *dialog = data;
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200568 struct rectangle allocation;
569 cairo_t *cr;
570 cairo_surface_t *surface;
571 cairo_pattern_t *pat;
572 double cx, cy, r, f;
573
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200574 surface = window_get_surface(dialog->window);
575 cr = cairo_create(surface);
Kristian Høgsberg41c5c4e2012-03-05 20:37:51 -0500576
Kristian Høgsbergbb977002012-01-10 19:11:42 -0500577 widget_get_allocation(dialog->widget, &allocation);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200578 cairo_rectangle(cr, allocation.x, allocation.y,
579 allocation.width, allocation.height);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200580 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
581 cairo_set_source_rgba(cr, 0, 0, 0, 0.6);
Kristian Høgsberg41c5c4e2012-03-05 20:37:51 -0500582 cairo_fill(cr);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200583
Kristian Høgsberg41c5c4e2012-03-05 20:37:51 -0500584 cairo_translate(cr, allocation.x, allocation.y);
Kristian Høgsbergb6323512012-01-11 00:04:42 -0500585 if (dialog->button_focused)
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200586 f = 1.0;
587 else
588 f = 0.7;
589
590 cx = allocation.width / 2.0;
591 cy = allocation.height / 2.0;
592 r = (cx < cy ? cx : cy) * 0.4;
593 pat = cairo_pattern_create_radial(cx, cy, r * 0.7, cx, cy, r);
594 cairo_pattern_add_color_stop_rgb(pat, 0.0, 0, 0.86 * f, 0);
595 cairo_pattern_add_color_stop_rgb(pat, 0.85, 0.2 * f, f, 0.2 * f);
596 cairo_pattern_add_color_stop_rgb(pat, 1.0, 0, 0.86 * f, 0);
597 cairo_set_source(cr, pat);
Kristian Høgsberg41c5c4e2012-03-05 20:37:51 -0500598 cairo_pattern_destroy(pat);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200599 cairo_arc(cr, cx, cy, r, 0.0, 2.0 * M_PI);
600 cairo_fill(cr);
601
Kristian Høgsbergc51f7992012-01-08 15:09:53 -0500602 widget_set_allocation(dialog->button,
Kristian Høgsberg41c5c4e2012-03-05 20:37:51 -0500603 allocation.x + cx - r,
604 allocation.y + cy - r, 2 * r, 2 * r);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200605
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200606 cairo_destroy(cr);
607
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200608 cairo_surface_destroy(surface);
609}
610
611static void
Kristian Høgsberga8a0db32012-01-09 11:12:05 -0500612unlock_dialog_button_handler(struct widget *widget,
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200613 struct input *input, uint32_t time,
Daniel Stone4dbadb12012-05-30 16:31:51 +0100614 uint32_t button,
615 enum wl_pointer_button_state state, void *data)
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200616{
617 struct unlock_dialog *dialog = data;
618 struct desktop *desktop = dialog->desktop;
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200619
Kristian Høgsberga8a0db32012-01-09 11:12:05 -0500620 if (button == BTN_LEFT) {
Daniel Stone4dbadb12012-05-30 16:31:51 +0100621 if (state == WL_POINTER_BUTTON_STATE_RELEASED &&
622 !dialog->closing) {
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200623 display_defer(desktop->display, &desktop->unlock_task);
624 dialog->closing = 1;
625 }
626 }
627}
628
629static void
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200630unlock_dialog_keyboard_focus_handler(struct window *window,
631 struct input *device, void *data)
632{
633 window_schedule_redraw(window);
634}
635
Kristian Høgsbergbb901fa2012-01-09 11:22:32 -0500636static int
Kristian Høgsbergee143232012-01-09 08:42:24 -0500637unlock_dialog_widget_enter_handler(struct widget *widget,
Kristian Høgsbergeae5de72012-04-11 22:42:15 -0400638 struct input *input,
Kristian Høgsberg80680c72012-05-10 12:21:37 -0400639 float x, float y, void *data)
Kristian Høgsbergee143232012-01-09 08:42:24 -0500640{
Kristian Høgsbergb6323512012-01-11 00:04:42 -0500641 struct unlock_dialog *dialog = data;
642
643 dialog->button_focused = 1;
Kristian Høgsbergee143232012-01-09 08:42:24 -0500644 widget_schedule_redraw(widget);
Kristian Høgsbergbb901fa2012-01-09 11:22:32 -0500645
Ander Conselvan de Oliveiradc8c8fc2012-05-25 16:01:41 +0300646 return CURSOR_LEFT_PTR;
Kristian Høgsbergee143232012-01-09 08:42:24 -0500647}
648
649static void
650unlock_dialog_widget_leave_handler(struct widget *widget,
651 struct input *input, void *data)
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200652{
Kristian Høgsbergb6323512012-01-11 00:04:42 -0500653 struct unlock_dialog *dialog = data;
654
655 dialog->button_focused = 0;
Kristian Høgsberg9a13dab2012-01-08 15:18:19 -0500656 widget_schedule_redraw(widget);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200657}
658
659static struct unlock_dialog *
Kristian Høgsberg1ec0c312011-11-15 16:39:55 -0500660unlock_dialog_create(struct desktop *desktop)
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200661{
Kristian Høgsberg1ec0c312011-11-15 16:39:55 -0500662 struct display *display = desktop->display;
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200663 struct unlock_dialog *dialog;
664
665 dialog = malloc(sizeof *dialog);
666 if (!dialog)
667 return NULL;
668 memset(dialog, 0, sizeof *dialog);
669
Kristian Høgsberg009ac0a2012-01-31 15:24:48 -0500670 dialog->window = window_create(display);
Kristian Høgsberg29af3eb2012-01-10 22:41:05 -0500671 dialog->widget = frame_create(dialog->window, dialog);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200672 window_set_title(dialog->window, "Unlock your desktop");
Benjamin Franzke8193bc12011-11-23 19:35:07 +0100673 window_set_custom(dialog->window);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200674
675 window_set_user_data(dialog->window, dialog);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200676 window_set_keyboard_focus_handler(dialog->window,
677 unlock_dialog_keyboard_focus_handler);
Kristian Høgsberg441338c2012-01-10 13:52:34 -0500678 dialog->button = widget_add_widget(dialog->widget, dialog);
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500679 widget_set_redraw_handler(dialog->widget,
680 unlock_dialog_redraw_handler);
Kristian Høgsbergee143232012-01-09 08:42:24 -0500681 widget_set_enter_handler(dialog->button,
682 unlock_dialog_widget_enter_handler);
683 widget_set_leave_handler(dialog->button,
684 unlock_dialog_widget_leave_handler);
Kristian Høgsberga8a0db32012-01-09 11:12:05 -0500685 widget_set_button_handler(dialog->button,
686 unlock_dialog_button_handler);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200687
Kristian Høgsberg1ec0c312011-11-15 16:39:55 -0500688 desktop_shell_set_lock_surface(desktop->shell,
Pekka Paalanen068ae942011-11-28 14:11:15 +0200689 window_get_wl_shell_surface(dialog->window));
Kristian Høgsberg1ec0c312011-11-15 16:39:55 -0500690
Pekka Paalanen40e49ac2012-01-18 16:51:30 +0200691 window_schedule_resize(dialog->window, 260, 230);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200692
693 return dialog;
694}
695
696static void
697unlock_dialog_destroy(struct unlock_dialog *dialog)
698{
699 window_destroy(dialog->window);
700 free(dialog);
701}
702
703static void
704unlock_dialog_finish(struct task *task, uint32_t events)
705{
706 struct desktop *desktop =
Benjamin Franzked7759712011-11-22 12:38:48 +0100707 container_of(task, struct desktop, unlock_task);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200708
709 desktop_shell_unlock(desktop->shell);
710 unlock_dialog_destroy(desktop->unlock_dialog);
711 desktop->unlock_dialog = NULL;
712}
713
714static void
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400715desktop_shell_configure(void *data,
716 struct desktop_shell *desktop_shell,
Kristian Høgsbergeae5de72012-04-11 22:42:15 -0400717 uint32_t edges,
Pekka Paalanen068ae942011-11-28 14:11:15 +0200718 struct wl_shell_surface *shell_surface,
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400719 int32_t width, int32_t height)
720{
Pekka Paalanen068ae942011-11-28 14:11:15 +0200721 struct window *window = wl_shell_surface_get_user_data(shell_surface);
722 struct surface *s = window_get_user_data(window);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400723
Kristian Høgsbergeae5de72012-04-11 22:42:15 -0400724 s->configure(data, desktop_shell, edges, window, width, height);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400725}
726
Pekka Paalanen9ef3e012011-11-15 13:34:48 +0200727static void
728desktop_shell_prepare_lock_surface(void *data,
729 struct desktop_shell *desktop_shell)
730{
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200731 struct desktop *desktop = data;
732
Pekka Paalanenfd83b6d2011-12-08 10:06:53 +0200733 if (!key_locking) {
734 desktop_shell_unlock(desktop->shell);
735 return;
736 }
737
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200738 if (!desktop->unlock_dialog) {
Kristian Høgsberg1ec0c312011-11-15 16:39:55 -0500739 desktop->unlock_dialog = unlock_dialog_create(desktop);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200740 desktop->unlock_dialog->desktop = desktop;
741 }
Pekka Paalanen9ef3e012011-11-15 13:34:48 +0200742}
743
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400744static const struct desktop_shell_listener listener = {
Pekka Paalanen9ef3e012011-11-15 13:34:48 +0200745 desktop_shell_configure,
746 desktop_shell_prepare_lock_surface
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400747};
748
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100749static struct background *
750background_create(struct desktop *desktop)
751{
752 struct background *background;
753
754 background = malloc(sizeof *background);
755 memset(background, 0, sizeof *background);
756
757 background->base.configure = background_configure;
Kristian Høgsberg009ac0a2012-01-31 15:24:48 -0500758 background->window = window_create(desktop->display);
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500759 background->widget = window_add_widget(background->window, background);
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100760 window_set_custom(background->window);
761 window_set_user_data(background->window, background);
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500762 widget_set_redraw_handler(background->widget, background_draw);
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100763
764 return background;
765}
766
Kristian Høgsbergd56bd902012-06-05 09:58:51 -0400767static const struct wl_callback_listener busy_cursor_listener;
768
769static void
770busy_cursor_frame_callback(void *data,
771 struct wl_callback *callback, uint32_t time)
772{
773 struct input *input = data;
774 struct display *display = input_get_display(input);
775 struct desktop *desktop = display_get_user_data(display);
776 struct wl_surface *surface;
777 int index;
778
779 if (callback)
780 wl_callback_destroy(callback);
781 if (input_get_focus_widget(input) != desktop->busy_widget)
782 return;
783
784 /* FIXME: Get frame duration and number of frames from cursor. */
785 index = (time / 100) % 8;
786 input_set_pointer_image_index(input, CURSOR_WATCH, index);
787
788 surface = window_get_wl_surface(desktop->busy_window);
789 callback = wl_surface_frame(surface);
790 wl_callback_add_listener(callback, &busy_cursor_listener, input);
791}
792
793static const struct wl_callback_listener busy_cursor_listener = {
794 busy_cursor_frame_callback
795};
796
797static int
798busy_surface_enter_handler(struct widget *widget, struct input *input,
799 float x, float y, void *data)
800{
801 busy_cursor_frame_callback(input, NULL, 0);
802
803 return CURSOR_WATCH;
804}
805
806static void
807busy_surface_create(struct desktop *desktop)
808{
809 struct wl_surface *s;
810
811 desktop->busy_window = window_create(desktop->display);
812 s = window_get_wl_surface(desktop->busy_window);
813 desktop_shell_set_busy_surface(desktop->shell, s);
814
815 desktop->busy_widget =
816 window_add_widget(desktop->busy_window, desktop);
817 /* We set the allocation to 1x1 at 0,0 so the fake enter event
818 * at 0,0 will go to this widget. */
819 widget_set_allocation(desktop->busy_widget, 0, 0, 1, 1);
820
821 widget_set_enter_handler(desktop->busy_widget,
822 busy_surface_enter_handler);
823}
824
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100825static void
826create_output(struct desktop *desktop, uint32_t id)
827{
828 struct output *output;
829
830 output = calloc(1, sizeof *output);
831 if (!output)
832 return;
833
834 output->output = wl_display_bind(display_get_display(desktop->display),
835 id, &wl_output_interface);
836
837 wl_list_insert(&desktop->outputs, &output->link);
838}
839
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400840static void
841global_handler(struct wl_display *display, uint32_t id,
842 const char *interface, uint32_t version, void *data)
843{
844 struct desktop *desktop = data;
845
846 if (!strcmp(interface, "desktop_shell")) {
847 desktop->shell =
848 wl_display_bind(display, id, &desktop_shell_interface);
849 desktop_shell_add_listener(desktop->shell, &listener, desktop);
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100850 } else if (!strcmp(interface, "wl_output")) {
851 create_output(desktop, id);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400852 }
853}
854
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500855static void
856launcher_section_done(void *data)
857{
858 struct desktop *desktop = data;
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100859 struct output *output;
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500860
861 if (key_launcher_icon == NULL || key_launcher_path == NULL) {
862 fprintf(stderr, "invalid launcher section\n");
863 return;
864 }
865
Martin Minarik1e51a872012-06-08 00:39:11 +0200866 wl_list_for_each(output, &desktop->outputs, link) {
Kristian Høgsberg53880802012-01-09 11:16:50 -0500867 panel_add_launcher(output->panel,
868 key_launcher_icon, key_launcher_path);
Martin Minarik1e51a872012-06-08 00:39:11 +0200869 }
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100870
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500871 free(key_launcher_icon);
872 key_launcher_icon = NULL;
873 free(key_launcher_path);
874 key_launcher_path = NULL;
875}
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400876
Kristian Høgsberg6af8eb92012-01-25 16:57:11 -0500877static void
878add_default_launcher(struct desktop *desktop)
879{
880 struct output *output;
881
882 wl_list_for_each(output, &desktop->outputs, link)
883 panel_add_launcher(output->panel,
884 DATADIR "/weston/terminal.png",
Rodney Lorrimar99ff01b2012-02-29 17:31:03 +0100885 BINDIR "/weston-terminal");
Kristian Høgsberg6af8eb92012-01-25 16:57:11 -0500886}
887
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400888int main(int argc, char *argv[])
889{
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200890 struct desktop desktop = { 0 };
Pekka Paalanen668dd562011-11-15 11:45:40 +0200891 char *config_file;
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100892 struct output *output;
Kristian Høgsberg6af8eb92012-01-25 16:57:11 -0500893 int ret;
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400894
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200895 desktop.unlock_task.run = unlock_dialog_finish;
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100896 wl_list_init(&desktop.outputs);
Pekka Paalanenbfbb26b2011-11-15 13:34:56 +0200897
Kristian Høgsbergbcacef12012-03-11 21:05:57 -0400898 desktop.display = display_create(argc, argv);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400899 if (desktop.display == NULL) {
900 fprintf(stderr, "failed to create display: %m\n");
901 return -1;
902 }
903
Kristian Høgsbergd56bd902012-06-05 09:58:51 -0400904 display_set_user_data(desktop.display, &desktop);
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400905 wl_display_add_global_listener(display_get_display(desktop.display),
906 global_handler, &desktop);
907
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100908 wl_list_for_each(output, &desktop.outputs, link) {
Pekka Paalanen068ae942011-11-28 14:11:15 +0200909 struct wl_shell_surface *s;
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100910
911 output->panel = panel_create(desktop.display);
Pekka Paalanen068ae942011-11-28 14:11:15 +0200912 s = window_get_wl_shell_surface(output->panel->window);
913 desktop_shell_set_panel(desktop.shell, output->output, s);
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100914
915 output->background = background_create(&desktop);
Pekka Paalanen068ae942011-11-28 14:11:15 +0200916 s = window_get_wl_shell_surface(output->background->window);
917 desktop_shell_set_background(desktop.shell, output->output, s);
Benjamin Franzked0f79ab2011-11-22 12:43:52 +0100918 }
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400919
Kristian Høgsbergd56bd902012-06-05 09:58:51 -0400920 busy_surface_create(&desktop);
921
Tiago Vignatti9a206c42012-03-21 19:49:18 +0200922 config_file = config_file_path("weston.ini");
Kristian Høgsberg6af8eb92012-01-25 16:57:11 -0500923 ret = parse_config_file(config_file,
924 config_sections, ARRAY_LENGTH(config_sections),
925 &desktop);
Pekka Paalanen668dd562011-11-15 11:45:40 +0200926 free(config_file);
Kristian Høgsberg6af8eb92012-01-25 16:57:11 -0500927 if (ret < 0)
928 add_default_launcher(&desktop);
Kristian Høgsbergac3a59a2011-11-14 22:43:37 -0500929
Kristian Høgsberg0c29eb22011-09-06 18:02:34 -0400930 signal(SIGCHLD, sigchild_handler);
931
932 display_run(desktop.display);
933
934 return 0;
935}