blob: 89dfc3fe24c07fdf84588bfa642c45138ee2b4ae [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)
Kristian Høgsbergd6548762012-01-25 15:43:48 -050091 image = load_image(path);
Kristian Høgsbergf033a7b2011-11-26 23:38:41 -050092 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øgsbergbb977002012-01-10 19:11:42 -0500125 window_get_allocation(shell->homescreen, &allocation);
Kristian Høgsbergf033a7b2011-11-26 23:38:41 -0500126 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øgsbergbb977002012-01-10 19:11:42 -0500179 window_get_allocation(shell->lockscreen, &allocation);
Kristian Høgsbergf033a7b2011-11-26 23:38:41 -0500180 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
Kristian Høgsberg009ac0a2012-01-31 15:24:48 -0500216 shell->lockscreen = window_create(shell->display);
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500217 window_set_user_data(shell->lockscreen, shell);
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500218 window_set_custom(shell->lockscreen);
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500219
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500220 tablet_shell_set_lockscreen(shell->tablet_shell,
221 window_get_wl_surface(shell->lockscreen));
222 lockscreen_draw(shell);
223}
224
225static void
226show_switcher(void *data, struct tablet_shell *tablet_shell)
227{
228 struct tablet_shell *shell = data;
229
Kristian Høgsberg009ac0a2012-01-31 15:24:48 -0500230 shell->switcher = window_create(shell->display);
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500231 window_set_user_data(shell->switcher, shell);
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500232 window_set_custom(shell->switcher);
233 tablet_shell_set_switcher(shell->tablet_shell,
234 window_get_wl_surface(shell->switcher));
235}
236
237static void
238hide_switcher(void *data, struct tablet_shell *tablet_shell)
239{
240}
241
242static const struct tablet_shell_listener tablet_shell_listener = {
243 show_lockscreen,
244 show_switcher,
245 hide_switcher
246};
247
248static struct tablet_shell *
249tablet_shell_create(struct display *display, uint32_t id)
250{
251 struct tablet_shell *shell;
252 struct output *output;
253
254 shell = malloc(sizeof *shell);
255
256 shell->display = display;
257 shell->tablet_shell =
258 wl_display_bind(display_get_display(display),
259 id, &tablet_shell_interface);
260 tablet_shell_add_listener(shell->tablet_shell,
261 &tablet_shell_listener, shell);
262 output = display_get_output(display);
263 output_get_allocation(output, &shell->allocation);
264
Kristian Høgsberg009ac0a2012-01-31 15:24:48 -0500265 shell->homescreen = window_create(display);
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500266 window_set_user_data(shell->homescreen, shell);
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500267 window_set_custom(shell->homescreen);
268
269 tablet_shell_set_homescreen(shell->tablet_shell,
270 window_get_wl_surface(shell->homescreen));
Kristian Høgsbergf033a7b2011-11-26 23:38:41 -0500271 wl_list_init(&shell->launcher_list);
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500272
273 return shell;
274}
275
Kristian Høgsbergf033a7b2011-11-26 23:38:41 -0500276static void
277tablet_shell_add_launcher(struct tablet_shell *shell,
278 const char *icon, const char *path)
279{
280 struct launcher *launcher;
281
282 launcher = malloc(sizeof *launcher);
283 launcher->path = strdup(path);
284 launcher->icon = cairo_image_surface_create_from_png(icon);
285 if (cairo_surface_status (launcher->icon) != CAIRO_STATUS_SUCCESS) {
286 fprintf(stderr, "couldn't load %s\n", icon);
287 free(launcher);
288 return;
289 }
290
291 wl_list_insert(&shell->launcher_list, &launcher->link);
292}
293
294static void
295launcher_section_done(void *data)
296{
297 struct tablet_shell *shell = data;
298
299 if (key_launcher_icon == NULL || key_launcher_path == NULL) {
300 fprintf(stderr, "invalid launcher section\n");
301 return;
302 }
303
304 tablet_shell_add_launcher(shell, key_launcher_icon, key_launcher_path);
305
306 free(key_launcher_icon);
307 key_launcher_icon = NULL;
308 free(key_launcher_path);
309 key_launcher_path = NULL;
310}
311
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500312int main(int argc, char *argv[])
313{
314 struct display *display;
Kristian Høgsbergf033a7b2011-11-26 23:38:41 -0500315 char *config_file;
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500316 uint32_t id;
Kristian Høgsbergf033a7b2011-11-26 23:38:41 -0500317 struct tablet_shell *shell;
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500318
Kristian Høgsbergbcacef12012-03-11 21:05:57 -0400319 display = display_create(argc, argv);
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500320 if (display == NULL) {
321 fprintf(stderr, "failed to create display: %m\n");
322 return -1;
323 }
324
325 wl_display_roundtrip(display_get_display(display));
326 id = wl_display_get_global(display_get_display(display),
327 "tablet_shell", 1);
Kristian Høgsbergf033a7b2011-11-26 23:38:41 -0500328 shell = tablet_shell_create(display, id);
329
Kristian Høgsberg9724b512012-01-03 14:35:49 -0500330 config_file = config_file_path("weston-tablet-shell.ini");
Kristian Høgsbergf033a7b2011-11-26 23:38:41 -0500331 parse_config_file(config_file,
332 config_sections, ARRAY_LENGTH(config_sections),
333 shell);
334 free(config_file);
335
336 homescreen_draw(shell);
337
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500338 display_run(display);
339
340 return 0;
341}