blob: 2331e6890f0932eda682c6aca6462d1734c6ac05 [file] [log] [blame]
Kristian Høgsberg6336e462011-11-26 17:36:23 -05001/*
2 * Copyright © 2011 Intel Corporation
3 *
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.
13 *
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
20 * OF THIS SOFTWARE.
21 */
22
23#include <stdint.h>
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27
28#include "window.h"
29#include "cairo-util.h"
Kristian Høgsberg9b935c82011-12-08 12:44:27 -050030#include "../shared/config-parser.h"
Kristian Høgsberg6336e462011-11-26 17:36:23 -050031
32#include "tablet-shell-client-protocol.h"
33
34struct tablet_shell {
35 struct display *display;
36 struct tablet_shell *tablet_shell;
37 struct rectangle allocation;
38 struct window *lockscreen;
39 struct window *switcher;
40 struct window *homescreen;
Kristian Høgsbergf033a7b2011-11-26 23:38:41 -050041 struct wl_list launcher_list;
42};
43
44struct launcher {
45 cairo_surface_t *icon;
46 char *path;
47 struct wl_list link;
48};
49
50static char *key_lockscreen_icon;
51static char *key_lockscreen_background;
52static char *key_homescreen_background;
53static char *key_launcher_icon;
54static char *key_launcher_path;
55static void launcher_section_done(void *data);
56
57static const struct config_key lockscreen_config_keys[] = {
58 { "icon", CONFIG_KEY_STRING, &key_lockscreen_icon },
59 { "background", CONFIG_KEY_STRING, &key_lockscreen_background },
60};
61
62static const struct config_key homescreen_config_keys[] = {
63 { "background", CONFIG_KEY_STRING, &key_homescreen_background },
64};
65
66static const struct config_key launcher_config_keys[] = {
67 { "icon", CONFIG_KEY_STRING, &key_launcher_icon },
68 { "path", CONFIG_KEY_STRING, &key_launcher_path },
69};
70
71static const struct config_section config_sections[] = {
72 { "lockscreen",
73 lockscreen_config_keys, ARRAY_LENGTH(lockscreen_config_keys) },
74 { "homescreen",
75 homescreen_config_keys, ARRAY_LENGTH(homescreen_config_keys) },
76 { "launcher",
77 launcher_config_keys, ARRAY_LENGTH(launcher_config_keys),
78 launcher_section_done }
Kristian Høgsberg6336e462011-11-26 17:36:23 -050079};
80
81static void
Kristian Høgsbergf033a7b2011-11-26 23:38:41 -050082paint_background(cairo_t *cr, const char *path, struct rectangle *allocation)
Kristian Høgsberg6336e462011-11-26 17:36:23 -050083{
Kristian Høgsbergf033a7b2011-11-26 23:38:41 -050084 cairo_surface_t *image = NULL;
85 cairo_pattern_t *pattern;
86 cairo_matrix_t matrix;
87 double sx, sy;
Kristian Høgsberg6336e462011-11-26 17:36:23 -050088
89 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
Kristian Høgsbergf033a7b2011-11-26 23:38:41 -050090 if (path)
91 image = load_jpeg(path);
92 if (image) {
93 pattern = cairo_pattern_create_for_surface(image);
94 sx = (double) cairo_image_surface_get_width(image) /
95 allocation->width;
96 sy = (double) cairo_image_surface_get_height(image) /
97 allocation->height;
98 cairo_matrix_init_scale(&matrix, sx, sy);
99 cairo_pattern_set_matrix(pattern, &matrix);
100 cairo_set_source(cr, pattern);
101 cairo_pattern_destroy (pattern);
102 cairo_surface_destroy(image);
103 cairo_paint(cr);
104 } else {
105 fprintf(stderr, "couldn't load backgrond image: %s\n",
106 key_lockscreen_background);
107 cairo_set_source_rgb(cr, 0.2, 0, 0);
108 cairo_paint(cr);
109 }
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500110}
111
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500112static void
113homescreen_draw(struct tablet_shell *shell)
114{
Kristian Høgsbergf033a7b2011-11-26 23:38:41 -0500115 cairo_surface_t *surface;
116 struct rectangle allocation;
117 cairo_pattern_t *pattern;
118 cairo_matrix_t matrix;
119 cairo_t *cr;
120 struct launcher *launcher;
121 const int rows = 4, columns = 5, icon_width = 128, icon_height = 128;
122 int x, y, i, width, height, vmargin, hmargin, vpadding, hpadding;
123
Kristian Høgsberg5d129902012-01-10 10:49:41 -0500124 window_create_surface(shell->homescreen);
Kristian Høgsbergf033a7b2011-11-26 23:38:41 -0500125 window_get_child_allocation(shell->homescreen, &allocation);
126 surface = window_get_surface(shell->homescreen);
127 cr = cairo_create(surface);
128
129 paint_background(cr, key_homescreen_background, &allocation);
130
131 cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
132
133 width = allocation.width - columns * icon_width;
134 hpadding = width / (columns + 1);
135 hmargin = (width - hpadding * (columns - 1)) / 2;
136
137 height = allocation.height - rows * icon_height;
138 vpadding = height / (rows + 1);
139 vmargin = (height - vpadding * (rows - 1)) / 2;
140
141 x = hmargin;
142 y = vmargin;
143 i = 0;
144
145 wl_list_for_each(launcher, &shell->launcher_list, link) {
146 pattern = cairo_pattern_create_for_surface(launcher->icon);
147 cairo_matrix_init_scale(&matrix, 2.0, 2.0);
148 cairo_matrix_translate(&matrix, -x, -y);
149 cairo_pattern_set_matrix(pattern, &matrix);
150 cairo_pattern_set_extend(pattern, CAIRO_EXTEND_NONE);
151 cairo_set_source(cr, pattern);
152 cairo_pattern_destroy(pattern);
153 cairo_paint(cr);
154 x += icon_width + hpadding;
155 i++;
156 if (i == columns) {
157 x = hmargin;
158 y += icon_height + vpadding;
159 i = 0;
160 }
161 }
162
163 cairo_surface_flush(surface);
164 cairo_surface_destroy(surface);
165 window_flush(shell->homescreen);
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500166}
167
168
169static void
170lockscreen_draw(struct tablet_shell *shell)
171{
Kristian Høgsbergf033a7b2011-11-26 23:38:41 -0500172 cairo_surface_t *surface;
173 cairo_surface_t *icon;
174 struct rectangle allocation;
175 cairo_t *cr;
176 int width, height;
177
Kristian Høgsberg5d129902012-01-10 10:49:41 -0500178 window_create_surface(shell->lockscreen);
Kristian Høgsbergf033a7b2011-11-26 23:38:41 -0500179 window_get_child_allocation(shell->lockscreen, &allocation);
180 surface = window_get_surface(shell->lockscreen);
181 cr = cairo_create(surface);
182
183 paint_background(cr, key_lockscreen_background, &allocation);
184
185 cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
186 icon = cairo_image_surface_create_from_png(key_lockscreen_icon);
187 width = cairo_image_surface_get_width(icon);
188 height = cairo_image_surface_get_height(icon);
189 cairo_set_source_surface(cr, icon,
190 allocation.x + (allocation.width - width) / 2,
191 allocation.y + (allocation.height - height) / 2);
192 cairo_paint(cr);
193 cairo_surface_destroy(icon);
194
195 cairo_surface_flush(surface);
196 cairo_surface_destroy(surface);
197 window_flush(shell->lockscreen);
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500198}
199
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500200static void
Kristian Høgsberga8a0db32012-01-09 11:12:05 -0500201lockscreen_button_handler(struct widget *widget,
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500202 struct input *input, uint32_t time,
203 int button, int state, void *data)
204{
Kristian Høgsbergb67e94b2012-01-10 12:23:19 -0500205 struct tablet_shell *shell = data;
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500206
207 window_destroy(shell->lockscreen);
208 shell->lockscreen = NULL;
209}
210
211static void
212show_lockscreen(void *data, struct tablet_shell *tablet_shell)
213{
214 struct tablet_shell *shell = data;
215
216 shell->lockscreen = window_create(shell->display,
217 shell->allocation.width,
218 shell->allocation.height);
219 window_set_user_data(shell->lockscreen, shell);
220 window_set_decoration(shell->lockscreen, 0);
221 window_set_custom(shell->lockscreen);
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500222
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500223 tablet_shell_set_lockscreen(shell->tablet_shell,
224 window_get_wl_surface(shell->lockscreen));
225 lockscreen_draw(shell);
226}
227
228static void
229show_switcher(void *data, struct tablet_shell *tablet_shell)
230{
231 struct tablet_shell *shell = data;
232
233 shell->switcher = window_create(shell->display, 0, 0);
234 window_set_user_data(shell->switcher, shell);
235 window_set_decoration(shell->switcher, 0);
236 window_set_custom(shell->switcher);
237 tablet_shell_set_switcher(shell->tablet_shell,
238 window_get_wl_surface(shell->switcher));
239}
240
241static void
242hide_switcher(void *data, struct tablet_shell *tablet_shell)
243{
244}
245
246static const struct tablet_shell_listener tablet_shell_listener = {
247 show_lockscreen,
248 show_switcher,
249 hide_switcher
250};
251
252static struct tablet_shell *
253tablet_shell_create(struct display *display, uint32_t id)
254{
255 struct tablet_shell *shell;
256 struct output *output;
257
258 shell = malloc(sizeof *shell);
259
260 shell->display = display;
261 shell->tablet_shell =
262 wl_display_bind(display_get_display(display),
263 id, &tablet_shell_interface);
264 tablet_shell_add_listener(shell->tablet_shell,
265 &tablet_shell_listener, shell);
266 output = display_get_output(display);
267 output_get_allocation(output, &shell->allocation);
268
269 shell->homescreen = window_create(display,
270 shell->allocation.width,
271 shell->allocation.height);
272 window_set_user_data(shell->homescreen, shell);
273 window_set_decoration(shell->homescreen, 0);
274 window_set_custom(shell->homescreen);
275
276 tablet_shell_set_homescreen(shell->tablet_shell,
277 window_get_wl_surface(shell->homescreen));
Kristian Høgsbergf033a7b2011-11-26 23:38:41 -0500278 wl_list_init(&shell->launcher_list);
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500279
280 return shell;
281}
282
Kristian Høgsbergf033a7b2011-11-26 23:38:41 -0500283static void
284tablet_shell_add_launcher(struct tablet_shell *shell,
285 const char *icon, const char *path)
286{
287 struct launcher *launcher;
288
289 launcher = malloc(sizeof *launcher);
290 launcher->path = strdup(path);
291 launcher->icon = cairo_image_surface_create_from_png(icon);
292 if (cairo_surface_status (launcher->icon) != CAIRO_STATUS_SUCCESS) {
293 fprintf(stderr, "couldn't load %s\n", icon);
294 free(launcher);
295 return;
296 }
297
298 wl_list_insert(&shell->launcher_list, &launcher->link);
299}
300
301static void
302launcher_section_done(void *data)
303{
304 struct tablet_shell *shell = data;
305
306 if (key_launcher_icon == NULL || key_launcher_path == NULL) {
307 fprintf(stderr, "invalid launcher section\n");
308 return;
309 }
310
311 tablet_shell_add_launcher(shell, key_launcher_icon, key_launcher_path);
312
313 free(key_launcher_icon);
314 key_launcher_icon = NULL;
315 free(key_launcher_path);
316 key_launcher_path = NULL;
317}
318
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500319int main(int argc, char *argv[])
320{
321 struct display *display;
Kristian Høgsbergf033a7b2011-11-26 23:38:41 -0500322 char *config_file;
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500323 uint32_t id;
Kristian Høgsbergf033a7b2011-11-26 23:38:41 -0500324 struct tablet_shell *shell;
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500325
326 display = display_create(&argc, &argv, NULL);
327 if (display == NULL) {
328 fprintf(stderr, "failed to create display: %m\n");
329 return -1;
330 }
331
332 wl_display_roundtrip(display_get_display(display));
333 id = wl_display_get_global(display_get_display(display),
334 "tablet_shell", 1);
Kristian Høgsbergf033a7b2011-11-26 23:38:41 -0500335 shell = tablet_shell_create(display, id);
336
Kristian Høgsberg9724b512012-01-03 14:35:49 -0500337 config_file = config_file_path("weston-tablet-shell.ini");
Kristian Høgsbergf033a7b2011-11-26 23:38:41 -0500338 parse_config_file(config_file,
339 config_sections, ARRAY_LENGTH(config_sections),
340 shell);
341 free(config_file);
342
343 homescreen_draw(shell);
344
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500345 display_run(display);
346
347 return 0;
348}