2 * Copyright © 2011, 2012 Intel Corporation
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of the copyright holders not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission. The copyright holders make no representations
11 * about the suitability of this software for any purpose. It is provided "as
12 * is" without express or implied warranty.
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
31 #include "../shared/cairo-util.h"
32 #include "../shared/config-parser.h"
34 #include "tablet-shell-client-protocol.h"
37 struct display *display;
38 struct tablet_shell *tablet_shell;
39 struct rectangle allocation;
40 struct window *switcher;
42 struct homescreen *homescreen;
43 struct lockscreen *lockscreen;
47 struct window *window;
48 struct widget *widget;
49 struct wl_list launcher_list;
53 struct window *window;
54 struct widget *widget;
58 struct widget *widget;
59 struct homescreen *homescreen;
60 cairo_surface_t *icon;
66 static char *key_lockscreen_icon;
67 static char *key_lockscreen_background;
68 static char *key_homescreen_background;
69 static char *key_launcher_icon;
70 static char *key_launcher_path;
71 static void launcher_section_done(void *data);
73 static const struct config_key shell_config_keys[] = {
74 { "lockscreen-icon", CONFIG_KEY_STRING, &key_lockscreen_icon },
75 { "lockscreen", CONFIG_KEY_STRING, &key_lockscreen_background },
76 { "homescreen", CONFIG_KEY_STRING, &key_homescreen_background },
79 static const struct config_key launcher_config_keys[] = {
80 { "icon", CONFIG_KEY_STRING, &key_launcher_icon },
81 { "path", CONFIG_KEY_STRING, &key_launcher_path },
84 static const struct config_section config_sections[] = {
86 shell_config_keys, ARRAY_LENGTH(shell_config_keys) },
88 launcher_config_keys, ARRAY_LENGTH(launcher_config_keys),
89 launcher_section_done }
93 sigchild_handler(int s)
98 while (pid = waitpid(-1, &status, WNOHANG), pid > 0)
99 fprintf(stderr, "child %d exited\n", pid);
103 paint_background(cairo_t *cr, const char *path, struct rectangle *allocation)
105 cairo_surface_t *image = NULL;
106 cairo_pattern_t *pattern;
107 cairo_matrix_t matrix;
110 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
112 image = load_cairo_surface(path);
114 pattern = cairo_pattern_create_for_surface(image);
115 sx = (double) cairo_image_surface_get_width(image) /
117 sy = (double) cairo_image_surface_get_height(image) /
119 cairo_matrix_init_scale(&matrix, sx, sy);
120 cairo_pattern_set_matrix(pattern, &matrix);
121 cairo_set_source(cr, pattern);
122 cairo_pattern_destroy (pattern);
123 cairo_surface_destroy(image);
126 fprintf(stderr, "couldn't load background image: %s\n", path);
127 cairo_set_source_rgb(cr, 0.2, 0, 0);
133 homescreen_draw(struct widget *widget, void *data)
135 struct homescreen *homescreen = data;
136 cairo_surface_t *surface;
137 struct rectangle allocation;
139 struct launcher *launcher;
140 const int rows = 4, columns = 5, icon_width = 128, icon_height = 128;
141 int x, y, i, width, height, vmargin, hmargin, vpadding, hpadding;
143 surface = window_get_surface(homescreen->window);
144 cr = cairo_create(surface);
146 widget_get_allocation(widget, &allocation);
147 paint_background(cr, key_homescreen_background, &allocation);
149 cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
151 width = allocation.width - columns * icon_width;
152 hpadding = width / (columns + 1);
153 hmargin = (width - hpadding * (columns - 1)) / 2;
155 height = allocation.height - rows * icon_height;
156 vpadding = height / (rows + 1);
157 vmargin = (height - vpadding * (rows - 1)) / 2;
163 wl_list_for_each(launcher, &homescreen->launcher_list, link) {
164 widget_set_allocation(launcher->widget,
165 x, y, icon_width, icon_height);
166 x += icon_width + hpadding;
170 y += icon_height + vpadding;
176 cairo_surface_destroy(surface);
180 lockscreen_draw(struct widget *widget, void *data)
182 struct lockscreen *lockscreen = data;
183 cairo_surface_t *surface;
184 cairo_surface_t *icon;
185 struct rectangle allocation;
189 surface = window_get_surface(lockscreen->window);
190 cr = cairo_create(surface);
192 widget_get_allocation(widget, &allocation);
193 paint_background(cr, key_lockscreen_background, &allocation);
195 cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
196 icon = load_cairo_surface(key_lockscreen_icon);
198 width = cairo_image_surface_get_width(icon);
199 height = cairo_image_surface_get_height(icon);
200 cairo_set_source_surface(cr, icon,
201 allocation.x + (allocation.width - width) / 2,
202 allocation.y + (allocation.height - height) / 2);
204 fprintf(stderr, "couldn't load lockscreen icon: %s\n",
205 key_lockscreen_icon);
206 cairo_set_source_rgb(cr, 0.2, 0, 0);
210 cairo_surface_destroy(icon);
211 cairo_surface_destroy(surface);
215 lockscreen_button_handler(struct widget *widget,
216 struct input *input, uint32_t time,
218 enum wl_pointer_button_state state, void *data)
220 struct lockscreen *lockscreen = data;
222 if (state == WL_POINTER_BUTTON_STATE_PRESSED && lockscreen->window) {
223 window_destroy(lockscreen->window);
224 lockscreen->window = NULL;
228 static struct homescreen *
229 homescreen_create(struct tablet *tablet)
231 struct homescreen *homescreen;
233 homescreen = malloc (sizeof *homescreen);
234 memset(homescreen, 0, sizeof *homescreen);
236 homescreen->window = window_create_custom(tablet->display);
238 window_add_widget(homescreen->window, homescreen);
239 window_set_user_data(homescreen->window, homescreen);
240 window_set_title(homescreen->window, "homescreen");
241 widget_set_redraw_handler(homescreen->widget, homescreen_draw);
246 static struct lockscreen *
247 lockscreen_create(struct tablet *tablet)
249 struct lockscreen *lockscreen;
251 lockscreen = malloc (sizeof *lockscreen);
252 memset(lockscreen, 0, sizeof *lockscreen);
254 lockscreen->window = window_create_custom(tablet->display);
256 window_add_widget(lockscreen->window, lockscreen);
257 window_set_user_data(lockscreen->window, lockscreen);
258 window_set_title(lockscreen->window, "lockscreen");
259 widget_set_redraw_handler(lockscreen->widget, lockscreen_draw);
260 widget_set_button_handler(lockscreen->widget,
261 lockscreen_button_handler);
267 show_lockscreen(void *data, struct tablet_shell *tablet_shell)
269 struct tablet *tablet = data;
271 tablet->lockscreen = lockscreen_create(tablet);
272 tablet_shell_set_lockscreen(tablet->tablet_shell,
273 window_get_wl_surface(tablet->lockscreen->window));
275 widget_schedule_resize(tablet->lockscreen->widget,
276 tablet->allocation.width,
277 tablet->allocation.height);
281 show_switcher(void *data, struct tablet_shell *tablet_shell)
283 struct tablet *tablet = data;
285 tablet->switcher = window_create_custom(tablet->display);
286 window_set_user_data(tablet->switcher, tablet);
287 tablet_shell_set_switcher(tablet->tablet_shell,
288 window_get_wl_surface(tablet->switcher));
292 hide_switcher(void *data, struct tablet_shell *tablet_shell)
296 static const struct tablet_shell_listener tablet_shell_listener = {
303 launcher_enter_handler(struct widget *widget, struct input *input,
304 float x, float y, void *data)
306 struct launcher *launcher = data;
308 launcher->focused = 1;
309 widget_schedule_redraw(widget);
311 return CURSOR_LEFT_PTR;
315 launcher_leave_handler(struct widget *widget,
316 struct input *input, void *data)
318 struct launcher *launcher = data;
320 launcher->focused = 0;
321 widget_schedule_redraw(widget);
325 launcher_activate(struct launcher *widget)
331 fprintf(stderr, "fork failed: %m\n");
338 if (execl(widget->path, widget->path, NULL) < 0) {
339 fprintf(stderr, "execl '%s' failed: %m\n", widget->path);
345 launcher_button_handler(struct widget *widget,
346 struct input *input, uint32_t time,
348 enum wl_pointer_button_state state, void *data)
350 struct launcher *launcher;
352 launcher = widget_get_user_data(widget);
353 widget_schedule_redraw(widget);
354 if (state == WL_POINTER_BUTTON_STATE_RELEASED) {
355 launcher_activate(launcher);
356 launcher->pressed = 0;
357 } else if (state == WL_POINTER_BUTTON_STATE_PRESSED)
358 launcher->pressed = 1;
362 launcher_redraw_handler(struct widget *widget, void *data)
364 struct launcher *launcher = data;
365 cairo_surface_t *surface;
366 struct rectangle allocation;
369 surface = window_get_surface(launcher->homescreen->window);
370 cr = cairo_create(surface);
372 widget_get_allocation(widget, &allocation);
373 if (launcher->pressed) {
378 cairo_set_source_surface(cr, launcher->icon,
379 allocation.x, allocation.y);
382 if (launcher->focused) {
383 cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.4);
384 cairo_mask_surface(cr, launcher->icon,
385 allocation.x, allocation.y);
392 tablet_shell_add_launcher(struct tablet *tablet,
393 const char *icon, const char *path)
395 struct launcher *launcher;
396 struct homescreen *homescreen = tablet->homescreen;
398 launcher = malloc(sizeof *launcher);
399 launcher->path = strdup(path);
400 launcher->icon = load_cairo_surface(icon);
401 if ( !launcher->icon ||
402 cairo_surface_status (launcher->icon) != CAIRO_STATUS_SUCCESS) {
403 fprintf(stderr, "couldn't load %s\n", icon);
408 launcher->homescreen = homescreen;
409 launcher->widget = widget_add_widget(homescreen->widget, launcher);
410 widget_set_enter_handler(launcher->widget,
411 launcher_enter_handler);
412 widget_set_leave_handler(launcher->widget,
413 launcher_leave_handler);
414 widget_set_button_handler(launcher->widget,
415 launcher_button_handler);
416 widget_set_redraw_handler(launcher->widget,
417 launcher_redraw_handler);
419 wl_list_insert(&homescreen->launcher_list, &launcher->link);
423 launcher_section_done(void *data)
425 struct tablet *tablet = data;
427 if (key_launcher_icon == NULL || key_launcher_path == NULL) {
428 fprintf(stderr, "invalid launcher section\n");
432 tablet_shell_add_launcher(tablet, key_launcher_icon, key_launcher_path);
434 free(key_launcher_icon);
435 key_launcher_icon = NULL;
436 free(key_launcher_path);
437 key_launcher_path = NULL;
441 global_handler(struct display *display, uint32_t name,
442 const char *interface, uint32_t version, void *data)
444 struct tablet *tablet = data;
446 if (!strcmp(interface, "tablet_shell")) {
447 tablet->tablet_shell =
448 display_bind(display, name,
449 &tablet_shell_interface, 1);
450 tablet_shell_add_listener(tablet->tablet_shell,
451 &tablet_shell_listener, tablet);
455 int main(int argc, char *argv[])
457 struct tablet tablet = { 0 };
458 struct display *display;
460 struct output *output;
462 display = display_create(argc, argv);
463 if (display == NULL) {
464 fprintf(stderr, "failed to create display: %m\n");
468 tablet.display = display;
470 display_set_user_data(tablet.display, &tablet);
471 display_set_global_handler(tablet.display, global_handler);
473 tablet.homescreen = homescreen_create(&tablet);
474 tablet_shell_set_homescreen(tablet.tablet_shell,
475 window_get_wl_surface(tablet.homescreen->window));
476 wl_list_init(&tablet.homescreen->launcher_list);
478 config_file = config_file_path("weston.ini");
479 parse_config_file(config_file,
480 config_sections, ARRAY_LENGTH(config_sections),
484 signal(SIGCHLD, sigchild_handler);
486 output = display_get_output(tablet.display);
487 output_get_allocation(output, &tablet.allocation);
488 widget_schedule_resize(tablet.homescreen->widget,
489 tablet.allocation.width,
490 tablet.allocation.height);
491 display_run(display);