blob: fc908ab0f3da1cb6eb81cb059a442f39e91325b9 [file] [log] [blame]
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -04001/*
2 * Copyright © 2011 Intel Corporation
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and
5 * its documentation for any purpose is hereby granted without fee, provided
6 * that the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of the copyright holders not be used in
9 * advertising or publicity pertaining to distribution of the software
10 * without specific, written prior permission. The copyright holders make
11 * no representations about the suitability of this software for any
12 * purpose. It is provided "as is" without express or implied warranty.
13 *
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
15 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
17 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
18 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 */
22
23#include <sys/wait.h>
24#include <unistd.h>
25#include <stdlib.h>
26#include <stdio.h>
27#include <string.h>
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -040028#include <linux/input.h>
29
30#include "compositor.h"
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -050031#include "tablet-shell-server-protocol.h"
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -040032
33/*
34 * TODO: Don't fade back from black until we've received a lockscreen
35 * attachment.
36 */
37
Kristian Høgsberg1258a4a2011-05-04 11:35:02 -040038enum {
39 STATE_STARTING,
40 STATE_LOCKED,
41 STATE_HOME,
42 STATE_SWITCHER,
43 STATE_TASK
44};
45
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -050046struct tablet_shell {
Kristian Høgsberg904055a2011-08-18 17:55:30 -040047 struct wl_resource resource;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -040048
Kristian Høgsberg8334bc12012-01-03 10:29:47 -050049 struct weston_shell shell;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -040050
Kristian Høgsberg8334bc12012-01-03 10:29:47 -050051 struct weston_compositor *compositor;
52 struct weston_process process;
53 struct weston_input_device *device;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -040054 struct wl_client *client;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -040055
Kristian Høgsberg8334bc12012-01-03 10:29:47 -050056 struct weston_surface *surface;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -040057
Kristian Høgsberg8334bc12012-01-03 10:29:47 -050058 struct weston_surface *lockscreen_surface;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -040059 struct wl_listener lockscreen_listener;
Tiago Vignatti0a386112012-03-28 13:04:02 +030060 struct weston_layer lockscreen_layer;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -040061
Kristian Høgsberg8334bc12012-01-03 10:29:47 -050062 struct weston_surface *home_surface;
Tiago Vignatti0a386112012-03-28 13:04:02 +030063 struct weston_layer homescreen_layer;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -040064
Kristian Høgsberg8334bc12012-01-03 10:29:47 -050065 struct weston_surface *switcher_surface;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -040066 struct wl_listener switcher_listener;
67
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -050068 struct tablet_client *current_client;
Kristian Høgsberg1258a4a2011-05-04 11:35:02 -040069
70 int state, previous_state;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -040071 int long_press_active;
72 struct wl_event_source *long_press_source;
73};
74
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -050075struct tablet_client {
Kristian Høgsberg3a53efe2011-05-02 14:21:03 -040076 struct wl_resource resource;
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -050077 struct tablet_shell *shell;
Kristian Høgsberg3a53efe2011-05-02 14:21:03 -040078 struct wl_client *client;
Kristian Høgsberg8334bc12012-01-03 10:29:47 -050079 struct weston_surface *surface;
Kristian Høgsberg3a53efe2011-05-02 14:21:03 -040080 char *name;
81};
82
Kristian Høgsbergd4af3202011-06-21 17:43:31 -040083static void
Kristian Høgsberg8334bc12012-01-03 10:29:47 -050084tablet_shell_sigchld(struct weston_process *process, int status)
Kristian Høgsbergd4af3202011-06-21 17:43:31 -040085{
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -050086 struct tablet_shell *shell =
87 container_of(process, struct tablet_shell, process);
Kristian Høgsbergd4af3202011-06-21 17:43:31 -040088
89 shell->process.pid = 0;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -040090
Kristian Høgsberg6336e462011-11-26 17:36:23 -050091 fprintf(stderr,
Kristian Høgsberg9724b512012-01-03 14:35:49 -050092 "weston-tablet-shell crashed, exit code %d\n", status);
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -040093}
94
95static void
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -050096tablet_shell_set_state(struct tablet_shell *shell, int state)
Kristian Høgsberg1258a4a2011-05-04 11:35:02 -040097{
98 static const char *states[] = {
99 "STARTING", "LOCKED", "HOME", "SWITCHER", "TASK"
100 };
101
102 fprintf(stderr, "switching to state %s (from %s)\n",
103 states[state], states[shell->state]);
104 shell->previous_state = shell->state;
105 shell->state = state;
106}
107
108static void
Kristian Høgsberg34486162012-03-29 13:08:32 -0400109tablet_shell_surface_configure(struct weston_surface *surface,
110 int32_t sx, int32_t sy)
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400111{
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500112 struct tablet_shell *shell =
Kristian Høgsberg34486162012-03-29 13:08:32 -0400113 container_of(surface->compositor->shell,
114 struct tablet_shell, shell);
115 int32_t width, height;
116
117 if (weston_surface_is_mapped(surface))
118 return;
119
120 width = surface->buffer->width;
121 height = surface->buffer->height;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400122
Pekka Paalanen8fb8d3b2012-02-13 13:03:59 +0200123 weston_surface_configure(surface, 0, 0, width, height);
Kristian Høgsbergbfcf07c2011-05-05 15:25:28 -0400124
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400125 if (surface == shell->lockscreen_surface) {
Tiago Vignatti0a386112012-03-28 13:04:02 +0300126 wl_list_insert(&shell->lockscreen_layer.surface_list,
127 &surface->layer_link);
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400128 } else if (surface == shell->switcher_surface) {
Kristian Høgsberg1258a4a2011-05-04 11:35:02 -0400129 /* */
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400130 } else if (surface == shell->home_surface) {
Kristian Høgsbergb79216e2011-05-08 21:28:45 -0400131 if (shell->state == STATE_STARTING) {
Tiago Vignatti0a386112012-03-28 13:04:02 +0300132 /* homescreen always visible, at the bottom */
133 wl_list_insert(&shell->homescreen_layer.surface_list,
134 &surface->layer_link);
135
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500136 tablet_shell_set_state(shell, STATE_LOCKED);
Kristian Høgsbergb79216e2011-05-08 21:28:45 -0400137 shell->previous_state = STATE_HOME;
Kristian Høgsberg0b5cd0c2012-03-04 21:57:37 -0500138 tablet_shell_send_show_lockscreen(&shell->resource);
Kristian Høgsbergb79216e2011-05-08 21:28:45 -0400139 }
Kristian Høgsbergbfcf07c2011-05-05 15:25:28 -0400140 } else if (shell->current_client &&
141 shell->current_client->surface != surface &&
Kristian Høgsberg904055a2011-08-18 17:55:30 -0400142 shell->current_client->client == surface->surface.resource.client) {
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500143 tablet_shell_set_state(shell, STATE_TASK);
Kristian Høgsberg1258a4a2011-05-04 11:35:02 -0400144 shell->current_client->surface = surface;
Kristian Høgsberg8334bc12012-01-03 10:29:47 -0500145 weston_zoom_run(surface, 0.3, 1.0, NULL, NULL);
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400146 }
Kristian Høgsberg32e24cc2011-11-09 12:07:35 -0500147
148 wl_list_insert(&shell->compositor->surface_list, &surface->link);
Pekka Paalanenf07cb5d2012-02-10 13:34:36 +0200149 weston_surface_assign_output(surface);
Kristian Høgsberg32e24cc2011-11-09 12:07:35 -0500150}
151
152static void
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400153handle_lockscreen_surface_destroy(struct wl_listener *listener,
Kristian Høgsbergeae5de72012-04-11 22:42:15 -0400154 struct wl_resource *resource)
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400155{
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500156 struct tablet_shell *shell =
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400157 container_of(listener,
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500158 struct tablet_shell, lockscreen_listener);
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400159
160 shell->lockscreen_surface = NULL;
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500161 tablet_shell_set_state(shell, shell->previous_state);
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400162}
163
164static void
165tablet_shell_set_lockscreen(struct wl_client *client,
Kristian Høgsberg904055a2011-08-18 17:55:30 -0400166 struct wl_resource *resource,
Kristian Høgsberg97d44aa2011-08-26 17:21:20 -0400167 struct wl_resource *surface_resource)
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400168{
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500169 struct tablet_shell *shell = resource->data;
Kristian Høgsberg8334bc12012-01-03 10:29:47 -0500170 struct weston_surface *es = surface_resource->data;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400171
Pekka Paalanen8fb8d3b2012-02-13 13:03:59 +0200172 weston_surface_set_position(es, 0, 0);
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400173 shell->lockscreen_surface = es;
Tiago Vignatti0a386112012-03-28 13:04:02 +0300174 shell->lockscreen_surface->configure = tablet_shell_surface_configure;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400175 shell->lockscreen_listener.func = handle_lockscreen_surface_destroy;
Benjamin Franzke4721a3c2011-05-06 17:13:17 +0200176 wl_list_insert(es->surface.resource.destroy_listener_list.prev,
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400177 &shell->lockscreen_listener.link);
178}
179
180static void
181handle_switcher_surface_destroy(struct wl_listener *listener,
Kristian Høgsbergeae5de72012-04-11 22:42:15 -0400182 struct wl_resource *resource)
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400183{
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500184 struct tablet_shell *shell =
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400185 container_of(listener,
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500186 struct tablet_shell, switcher_listener);
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400187
188 shell->switcher_surface = NULL;
Kristian Høgsberg1258a4a2011-05-04 11:35:02 -0400189 if (shell->state != STATE_LOCKED)
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500190 tablet_shell_set_state(shell, shell->previous_state);
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400191}
192
193static void
194tablet_shell_set_switcher(struct wl_client *client,
Kristian Høgsberg904055a2011-08-18 17:55:30 -0400195 struct wl_resource *resource,
Kristian Høgsberg97d44aa2011-08-26 17:21:20 -0400196 struct wl_resource *surface_resource)
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400197{
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500198 struct tablet_shell *shell = resource->data;
Kristian Høgsberg8334bc12012-01-03 10:29:47 -0500199 struct weston_surface *es = surface_resource->data;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400200
201 /* FIXME: Switcher should be centered and the compositor
202 * should do the tinting of the background. With the cache
203 * layer idea, we should be able to hit the framerate on the
204 * fade/zoom in. */
205 shell->switcher_surface = es;
Pekka Paalanen8fb8d3b2012-02-13 13:03:59 +0200206 weston_surface_set_position(shell->switcher_surface, 0, 0);
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400207
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400208 shell->switcher_listener.func = handle_switcher_surface_destroy;
Benjamin Franzke4721a3c2011-05-06 17:13:17 +0200209 wl_list_insert(es->surface.resource.destroy_listener_list.prev,
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400210 &shell->switcher_listener.link);
211}
212
213static void
214tablet_shell_set_homescreen(struct wl_client *client,
Kristian Høgsberg904055a2011-08-18 17:55:30 -0400215 struct wl_resource *resource,
Kristian Høgsberg97d44aa2011-08-26 17:21:20 -0400216 struct wl_resource *surface_resource)
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400217{
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500218 struct tablet_shell *shell = resource->data;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400219
Kristian Høgsberg97d44aa2011-08-26 17:21:20 -0400220 shell->home_surface = surface_resource->data;
Tiago Vignatti0a386112012-03-28 13:04:02 +0300221 shell->home_surface->configure = tablet_shell_surface_configure;
222
Pekka Paalanen8fb8d3b2012-02-13 13:03:59 +0200223 weston_surface_set_position(shell->home_surface, 0, 0);
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400224}
225
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400226static void
Kristian Høgsberg8334bc12012-01-03 10:29:47 -0500227minimize_zoom_done(struct weston_zoom *zoom, void *data)
Kristian Høgsberg57eca742011-06-21 16:40:56 -0400228{
Kristian Høgsberg698c0582011-12-04 15:20:19 -0500229 struct tablet_shell *shell = data;
Kristian Høgsberg8334bc12012-01-03 10:29:47 -0500230 struct weston_compositor *compositor = shell->compositor;
231 struct weston_input_device *device =
232 (struct weston_input_device *) compositor->input_device;
Kristian Høgsberg57eca742011-06-21 16:40:56 -0400233
Kristian Høgsbergeae5de72012-04-11 22:42:15 -0400234 weston_surface_activate(shell->home_surface, device);
Kristian Høgsberg57eca742011-06-21 16:40:56 -0400235}
236
237static void
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500238tablet_shell_switch_to(struct tablet_shell *shell,
Kristian Høgsberg8334bc12012-01-03 10:29:47 -0500239 struct weston_surface *surface)
Kristian Høgsbergbfcf07c2011-05-05 15:25:28 -0400240{
Kristian Høgsberg8334bc12012-01-03 10:29:47 -0500241 struct weston_compositor *compositor = shell->compositor;
242 struct weston_input_device *device =
243 (struct weston_input_device *) compositor->input_device;
244 struct weston_surface *current;
Kristian Høgsbergbfcf07c2011-05-05 15:25:28 -0400245
246 if (shell->state == STATE_SWITCHER) {
247 wl_list_remove(&shell->switcher_listener.link);
248 shell->switcher_surface = NULL;
249 };
250
Kristian Høgsberg57eca742011-06-21 16:40:56 -0400251 if (surface == shell->home_surface) {
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500252 tablet_shell_set_state(shell, STATE_HOME);
Kristian Høgsberg57eca742011-06-21 16:40:56 -0400253
254 if (shell->current_client && shell->current_client->surface) {
255 current = shell->current_client->surface;
Kristian Høgsberg8334bc12012-01-03 10:29:47 -0500256 weston_zoom_run(current, 1.0, 0.3,
Kristian Høgsberg698c0582011-12-04 15:20:19 -0500257 minimize_zoom_done, shell);
Kristian Høgsberg57eca742011-06-21 16:40:56 -0400258 }
259 } else {
260 fprintf(stderr, "switch to %p\n", surface);
Kristian Høgsbergeae5de72012-04-11 22:42:15 -0400261 weston_surface_activate(surface, device);
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500262 tablet_shell_set_state(shell, STATE_TASK);
Kristian Høgsberg8334bc12012-01-03 10:29:47 -0500263 weston_zoom_run(surface, 0.3, 1.0, NULL, NULL);
Kristian Høgsberg57eca742011-06-21 16:40:56 -0400264 }
Kristian Høgsbergbfcf07c2011-05-05 15:25:28 -0400265}
266
267static void
Kristian Høgsberg92fb0e92011-05-04 16:16:43 -0400268tablet_shell_show_grid(struct wl_client *client,
Kristian Høgsberg904055a2011-08-18 17:55:30 -0400269 struct wl_resource *resource,
Kristian Høgsberg97d44aa2011-08-26 17:21:20 -0400270 struct wl_resource *surface_resource)
Kristian Høgsberg92fb0e92011-05-04 16:16:43 -0400271{
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500272 struct tablet_shell *shell = resource->data;
Kristian Høgsberg8334bc12012-01-03 10:29:47 -0500273 struct weston_surface *es = surface_resource->data;
Kristian Høgsberg904055a2011-08-18 17:55:30 -0400274
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500275 tablet_shell_switch_to(shell, es);
Kristian Høgsberg92fb0e92011-05-04 16:16:43 -0400276}
277
278static void
279tablet_shell_show_panels(struct wl_client *client,
Kristian Høgsberg904055a2011-08-18 17:55:30 -0400280 struct wl_resource *resource,
Kristian Høgsberg97d44aa2011-08-26 17:21:20 -0400281 struct wl_resource *surface_resource)
Kristian Høgsberg92fb0e92011-05-04 16:16:43 -0400282{
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500283 struct tablet_shell *shell = resource->data;
Kristian Høgsberg8334bc12012-01-03 10:29:47 -0500284 struct weston_surface *es = surface_resource->data;
Kristian Høgsberg904055a2011-08-18 17:55:30 -0400285
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500286 tablet_shell_switch_to(shell, es);
Kristian Høgsberg92fb0e92011-05-04 16:16:43 -0400287}
288
289static void
Kristian Høgsberg904055a2011-08-18 17:55:30 -0400290destroy_tablet_client(struct wl_resource *resource)
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400291{
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500292 struct tablet_client *tablet_client =
293 container_of(resource, struct tablet_client, resource);
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400294
295 free(tablet_client->name);
296 free(tablet_client);
297}
298
299static void
Kristian Høgsberg97d44aa2011-08-26 17:21:20 -0400300tablet_client_destroy(struct wl_client *client,
301 struct wl_resource *resource)
Kristian Høgsberg81e8c262011-05-04 16:17:20 -0400302{
Kristian Høgsbergeae5de72012-04-11 22:42:15 -0400303 wl_resource_destroy(resource);
Kristian Høgsberg81e8c262011-05-04 16:17:20 -0400304}
305
306static void
Kristian Høgsberg904055a2011-08-18 17:55:30 -0400307tablet_client_activate(struct wl_client *client, struct wl_resource *resource)
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400308{
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500309 struct tablet_client *tablet_client = resource->data;
310 struct tablet_shell *shell = tablet_client->shell;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400311
Kristian Høgsberg1258a4a2011-05-04 11:35:02 -0400312 shell->current_client = tablet_client;
Kristian Høgsberg81e8c262011-05-04 16:17:20 -0400313 if (!tablet_client->surface)
314 return;
315
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500316 tablet_shell_switch_to(shell, tablet_client->surface);
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400317}
318
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500319static const struct tablet_client_interface tablet_client_implementation = {
Kristian Høgsberg81e8c262011-05-04 16:17:20 -0400320 tablet_client_destroy,
321 tablet_client_activate
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400322};
323
324static void
325tablet_shell_create_client(struct wl_client *client,
Kristian Høgsberg904055a2011-08-18 17:55:30 -0400326 struct wl_resource *resource,
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400327 uint32_t id, const char *name, int fd)
328{
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500329 struct tablet_shell *shell = resource->data;
Kristian Høgsberg8334bc12012-01-03 10:29:47 -0500330 struct weston_compositor *compositor = shell->compositor;
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500331 struct tablet_client *tablet_client;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400332
333 tablet_client = malloc(sizeof *tablet_client);
334 if (tablet_client == NULL) {
Kristian Høgsberg9ebcf942011-09-01 09:54:57 -0400335 wl_resource_post_no_memory(resource);
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400336 return;
337 }
338
339 tablet_client->client = wl_client_create(compositor->wl_display, fd);
340 tablet_client->shell = shell;
341 tablet_client->name = strdup(name);
342
343 tablet_client->resource.destroy = destroy_tablet_client;
344 tablet_client->resource.object.id = id;
345 tablet_client->resource.object.interface =
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500346 &tablet_client_interface;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400347 tablet_client->resource.object.implementation =
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500348 (void (**)(void)) &tablet_client_implementation;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400349
350 wl_client_add_resource(client, &tablet_client->resource);
Kristian Høgsberg1258a4a2011-05-04 11:35:02 -0400351 tablet_client->surface = NULL;
352 shell->current_client = tablet_client;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400353
354 fprintf(stderr, "created client %p, id %d, name %s, fd %d\n",
355 tablet_client->client, id, name, fd);
356}
357
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500358static const struct tablet_shell_interface tablet_shell_implementation = {
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400359 tablet_shell_set_lockscreen,
360 tablet_shell_set_switcher,
361 tablet_shell_set_homescreen,
Kristian Høgsberg92fb0e92011-05-04 16:16:43 -0400362 tablet_shell_show_grid,
363 tablet_shell_show_panels,
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400364 tablet_shell_create_client
365};
366
367static void
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500368launch_ux_daemon(struct tablet_shell *shell)
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400369{
Kristian Høgsberg9724b512012-01-03 14:35:49 -0500370 const char *shell_exe = LIBEXECDIR "/weston-tablet-shell";
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400371
Kristian Høgsberg8334bc12012-01-03 10:29:47 -0500372 shell->client = weston_client_launch(shell->compositor,
Pekka Paalanen409ef0a2011-12-02 15:30:21 +0200373 &shell->process,
374 shell_exe, tablet_shell_sigchld);
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400375}
376
377static void
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500378toggle_switcher(struct tablet_shell *shell)
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400379{
Kristian Høgsberg1258a4a2011-05-04 11:35:02 -0400380 switch (shell->state) {
381 case STATE_SWITCHER:
Kristian Høgsberg0b5cd0c2012-03-04 21:57:37 -0500382 tablet_shell_send_hide_switcher(&shell->resource);
Kristian Høgsberg1258a4a2011-05-04 11:35:02 -0400383 break;
384 default:
Kristian Høgsberg0b5cd0c2012-03-04 21:57:37 -0500385 tablet_shell_send_show_switcher(&shell->resource);
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500386 tablet_shell_set_state(shell, STATE_SWITCHER);
Kristian Høgsberg1258a4a2011-05-04 11:35:02 -0400387 break;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400388 }
389}
390
391static void
Kristian Høgsberg8334bc12012-01-03 10:29:47 -0500392tablet_shell_lock(struct weston_shell *base)
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400393{
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500394 struct tablet_shell *shell =
395 container_of(base, struct tablet_shell, shell);
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400396
Kristian Høgsberg1258a4a2011-05-04 11:35:02 -0400397 if (shell->state == STATE_LOCKED)
398 return;
399 if (shell->state == STATE_SWITCHER)
Kristian Høgsberg0b5cd0c2012-03-04 21:57:37 -0500400 tablet_shell_send_hide_switcher(&shell->resource);
Kristian Høgsberg1258a4a2011-05-04 11:35:02 -0400401
Kristian Høgsberg0b5cd0c2012-03-04 21:57:37 -0500402 tablet_shell_send_show_lockscreen(&shell->resource);
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500403 tablet_shell_set_state(shell, STATE_LOCKED);
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400404}
405
406static void
Kristian Høgsberg8334bc12012-01-03 10:29:47 -0500407tablet_shell_unlock(struct weston_shell *base)
Pekka Paalanen9ef3e012011-11-15 13:34:48 +0200408{
Kristian Høgsbergaf867cc2011-11-15 13:34:49 +0200409 struct tablet_shell *shell =
410 container_of(base, struct tablet_shell, shell);
411
Kristian Høgsberg8334bc12012-01-03 10:29:47 -0500412 weston_compositor_wake(shell->compositor);
Pekka Paalanen9ef3e012011-11-15 13:34:48 +0200413}
414
415static void
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500416go_home(struct tablet_shell *shell)
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400417{
Kristian Høgsberg8334bc12012-01-03 10:29:47 -0500418 struct weston_input_device *device =
419 (struct weston_input_device *) shell->compositor->input_device;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400420
Kristian Høgsberg1258a4a2011-05-04 11:35:02 -0400421 if (shell->state == STATE_SWITCHER)
Kristian Høgsberg0b5cd0c2012-03-04 21:57:37 -0500422 tablet_shell_send_hide_switcher(&shell->resource);
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400423
Kristian Høgsbergeae5de72012-04-11 22:42:15 -0400424 weston_surface_activate(shell->home_surface, device);
Kristian Høgsberg1258a4a2011-05-04 11:35:02 -0400425
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500426 tablet_shell_set_state(shell, STATE_HOME);
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400427}
428
429static int
430long_press_handler(void *data)
431{
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500432 struct tablet_shell *shell = data;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400433
434 shell->long_press_active = 0;
435 toggle_switcher(shell);
436
437 return 1;
438}
439
440static void
441menu_key_binding(struct wl_input_device *device, uint32_t time,
Scott Moreau6a3633d2012-03-20 08:47:59 -0600442 uint32_t key, uint32_t button, uint32_t axis, int32_t state, void *data)
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400443{
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500444 struct tablet_shell *shell = data;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400445
Kristian Høgsberg1258a4a2011-05-04 11:35:02 -0400446 if (shell->state == STATE_LOCKED)
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400447 return;
448
449 if (state)
450 toggle_switcher(shell);
451}
452
453static void
454home_key_binding(struct wl_input_device *device, uint32_t time,
Scott Moreau6a3633d2012-03-20 08:47:59 -0600455 uint32_t key, uint32_t button, uint32_t axis, int32_t state, void *data)
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400456{
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500457 struct tablet_shell *shell = data;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400458
Kristian Høgsberg1258a4a2011-05-04 11:35:02 -0400459 if (shell->state == STATE_LOCKED)
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400460 return;
461
Kristian Høgsberg8334bc12012-01-03 10:29:47 -0500462 shell->device = (struct weston_input_device *) device;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400463
464 if (state) {
465 wl_event_source_timer_update(shell->long_press_source, 500);
466 shell->long_press_active = 1;
467 } else if (shell->long_press_active) {
468 wl_event_source_timer_update(shell->long_press_source, 0);
469 shell->long_press_active = 0;
470
Kristian Høgsberg1258a4a2011-05-04 11:35:02 -0400471 switch (shell->state) {
472 case STATE_HOME:
473 case STATE_SWITCHER:
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400474 toggle_switcher(shell);
Kristian Høgsberg1258a4a2011-05-04 11:35:02 -0400475 break;
476 default:
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400477 go_home(shell);
Kristian Høgsberg1258a4a2011-05-04 11:35:02 -0400478 break;
479 }
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400480 }
481}
482
483static void
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500484destroy_tablet_shell(struct wl_resource *resource)
485{
486}
487
488static void
Kristian Høgsberg97d44aa2011-08-26 17:21:20 -0400489bind_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id)
Kristian Høgsberg904055a2011-08-18 17:55:30 -0400490{
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500491 struct tablet_shell *shell = data;
Kristian Høgsberg904055a2011-08-18 17:55:30 -0400492
493 if (shell->client != client)
494 /* Throw an error or just let the client fail when it
495 * tries to access the object?. */
496 return;
497
Kristian Høgsbergf790c792011-08-19 14:41:57 -0400498 shell->resource.object.id = id;
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500499 shell->resource.object.interface = &tablet_shell_interface;
500 shell->resource.object.implementation =
501 (void (**)(void)) &tablet_shell_implementation;
502 shell->resource.client = client;
503 shell->resource.data = shell;
504 shell->resource.destroy = destroy_tablet_shell;
505
506 wl_client_add_resource(client, &shell->resource);
Kristian Høgsberg904055a2011-08-18 17:55:30 -0400507}
508
Pekka Paalanen3c647232011-12-22 13:43:43 +0200509static void
Kristian Høgsberg3466bc82012-01-03 11:29:15 -0500510tablet_shell_destroy(struct weston_shell *base)
Pekka Paalanen3c647232011-12-22 13:43:43 +0200511{
512 struct tablet_shell *shell =
513 container_of(base, struct tablet_shell, shell);
514
Tiago Vignatti0a386112012-03-28 13:04:02 +0300515 if (shell->home_surface)
516 shell->home_surface->configure = NULL;
517
518 if (shell->lockscreen_surface)
519 shell->lockscreen_surface->configure = NULL;
520
Pekka Paalanen3c647232011-12-22 13:43:43 +0200521 wl_event_source_remove(shell->long_press_source);
522 free(shell);
523}
524
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400525void
Kristian Høgsberg8334bc12012-01-03 10:29:47 -0500526shell_init(struct weston_compositor *compositor);
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400527
528WL_EXPORT void
Kristian Høgsberg8334bc12012-01-03 10:29:47 -0500529shell_init(struct weston_compositor *compositor)
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400530{
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500531 struct tablet_shell *shell;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400532 struct wl_event_loop *loop;
533
534 shell = malloc(sizeof *shell);
535 if (shell == NULL)
536 return;
537
538 memset(shell, 0, sizeof *shell);
539 shell->compositor = compositor;
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400540
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400541 /* FIXME: This will make the object available to all clients. */
Kristian Høgsberg904055a2011-08-18 17:55:30 -0400542 wl_display_add_global(compositor->wl_display,
Kristian Høgsberg6336e462011-11-26 17:36:23 -0500543 &tablet_shell_interface, shell, bind_shell);
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400544
545 loop = wl_display_get_event_loop(compositor->wl_display);
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400546 shell->long_press_source =
547 wl_event_loop_add_timer(loop, long_press_handler, shell);
548
Scott Moreau6a3633d2012-03-20 08:47:59 -0600549 weston_compositor_add_binding(compositor, KEY_LEFTMETA, 0, 0, 0,
550 home_key_binding, shell);
551 weston_compositor_add_binding(compositor, KEY_RIGHTMETA, 0, 0, 0,
552 home_key_binding, shell);
Kristian Høgsberg8334bc12012-01-03 10:29:47 -0500553 weston_compositor_add_binding(compositor, KEY_LEFTMETA, 0, 0,
Scott Moreau6a3633d2012-03-20 08:47:59 -0600554 MODIFIER_SUPER, home_key_binding, shell);
Kristian Høgsberg8334bc12012-01-03 10:29:47 -0500555 weston_compositor_add_binding(compositor, KEY_RIGHTMETA, 0, 0,
Kristian Høgsbergf77ce462011-05-03 13:11:43 -0400556 MODIFIER_SUPER, home_key_binding, shell);
Scott Moreau6a3633d2012-03-20 08:47:59 -0600557 weston_compositor_add_binding(compositor, KEY_COMPOSE, 0, 0, 0,
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400558 menu_key_binding, shell);
559
560 compositor->shell = &shell->shell;
561
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500562 shell->shell.lock = tablet_shell_lock;
Pekka Paalanen9ef3e012011-11-15 13:34:48 +0200563 shell->shell.unlock = tablet_shell_unlock;
Pekka Paalanen3c647232011-12-22 13:43:43 +0200564 shell->shell.destroy = tablet_shell_destroy;
Kristian Høgsberg47fe08a2011-10-28 12:26:06 -0400565
Tiago Vignatti0a386112012-03-28 13:04:02 +0300566 weston_layer_init(&shell->homescreen_layer,
567 &compositor->cursor_layer.link);
568 weston_layer_init(&shell->lockscreen_layer,
569 &compositor->cursor_layer.link);
Kristian Høgsberg1258a4a2011-05-04 11:35:02 -0400570 launch_ux_daemon(shell);
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400571
Kristian Høgsberg64f1c3f2011-11-14 15:50:03 -0500572 tablet_shell_set_state(shell, STATE_STARTING);
Kristian Høgsbergeb7e12c2011-04-23 13:17:43 -0400573}