The tablet-shell is unmaintained and unused. It is currently dead-weight and a burden when we make changes to weston. Let's drop it for now, we can pull it out of git if we find a need for it later.dev
parent
cae1f0ff2d
commit
873b515aee
@ -1,478 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright © 2011, 2012 Intel Corporation |
|
||||||
* |
|
||||||
* Permission to use, copy, modify, distribute, and sell this software and its |
|
||||||
* documentation for any purpose is hereby granted without fee, provided that |
|
||||||
* the above copyright notice appear in all copies and that both that copyright |
|
||||||
* notice and this permission notice appear in supporting documentation, and |
|
||||||
* that the name of the copyright holders not be used in advertising or |
|
||||||
* publicity pertaining to distribution of the software without specific, |
|
||||||
* written prior permission. The copyright holders make no representations |
|
||||||
* about the suitability of this software for any purpose. It is provided "as |
|
||||||
* is" without express or implied warranty. |
|
||||||
* |
|
||||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, |
|
||||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO |
|
||||||
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR |
|
||||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, |
|
||||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
|
||||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE |
|
||||||
* OF THIS SOFTWARE. |
|
||||||
*/ |
|
||||||
|
|
||||||
#include <stdint.h> |
|
||||||
#include <stdio.h> |
|
||||||
#include <stdlib.h> |
|
||||||
#include <string.h> |
|
||||||
#include <unistd.h> |
|
||||||
#include <sys/wait.h> |
|
||||||
|
|
||||||
#include "window.h" |
|
||||||
#include "../shared/cairo-util.h" |
|
||||||
#include "../shared/config-parser.h" |
|
||||||
|
|
||||||
#include "tablet-shell-client-protocol.h" |
|
||||||
|
|
||||||
struct tablet { |
|
||||||
struct display *display; |
|
||||||
struct tablet_shell *tablet_shell; |
|
||||||
struct rectangle allocation; |
|
||||||
struct window *switcher; |
|
||||||
|
|
||||||
struct homescreen *homescreen; |
|
||||||
struct lockscreen *lockscreen; |
|
||||||
}; |
|
||||||
|
|
||||||
struct homescreen { |
|
||||||
struct window *window; |
|
||||||
struct widget *widget; |
|
||||||
struct wl_list launcher_list; |
|
||||||
}; |
|
||||||
|
|
||||||
struct lockscreen { |
|
||||||
struct window *window; |
|
||||||
struct widget *widget; |
|
||||||
}; |
|
||||||
|
|
||||||
struct launcher { |
|
||||||
struct widget *widget; |
|
||||||
struct homescreen *homescreen; |
|
||||||
cairo_surface_t *icon; |
|
||||||
int focused, pressed; |
|
||||||
char *path; |
|
||||||
struct wl_list link; |
|
||||||
}; |
|
||||||
|
|
||||||
static char *key_lockscreen_icon; |
|
||||||
static char *key_lockscreen_background; |
|
||||||
static char *key_homescreen_background; |
|
||||||
|
|
||||||
static void |
|
||||||
sigchild_handler(int s) |
|
||||||
{ |
|
||||||
int status; |
|
||||||
pid_t pid; |
|
||||||
|
|
||||||
while (pid = waitpid(-1, &status, WNOHANG), pid > 0) |
|
||||||
fprintf(stderr, "child %d exited\n", pid); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
paint_background(cairo_t *cr, const char *path, struct rectangle *allocation) |
|
||||||
{ |
|
||||||
cairo_surface_t *image = NULL; |
|
||||||
cairo_pattern_t *pattern; |
|
||||||
cairo_matrix_t matrix; |
|
||||||
double sx, sy; |
|
||||||
|
|
||||||
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); |
|
||||||
if (path) |
|
||||||
image = load_cairo_surface(path); |
|
||||||
if (image) { |
|
||||||
pattern = cairo_pattern_create_for_surface(image); |
|
||||||
sx = (double) cairo_image_surface_get_width(image) / |
|
||||||
allocation->width; |
|
||||||
sy = (double) cairo_image_surface_get_height(image) / |
|
||||||
allocation->height; |
|
||||||
cairo_matrix_init_scale(&matrix, sx, sy); |
|
||||||
cairo_pattern_set_matrix(pattern, &matrix); |
|
||||||
cairo_set_source(cr, pattern); |
|
||||||
cairo_pattern_destroy (pattern); |
|
||||||
cairo_surface_destroy(image); |
|
||||||
cairo_paint(cr); |
|
||||||
} else { |
|
||||||
fprintf(stderr, "couldn't load background image: %s\n", path); |
|
||||||
cairo_set_source_rgb(cr, 0.2, 0, 0); |
|
||||||
cairo_paint(cr); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
homescreen_draw(struct widget *widget, void *data) |
|
||||||
{ |
|
||||||
struct homescreen *homescreen = data; |
|
||||||
cairo_surface_t *surface; |
|
||||||
struct rectangle allocation; |
|
||||||
cairo_t *cr; |
|
||||||
struct launcher *launcher; |
|
||||||
const int rows = 4, columns = 5, icon_width = 128, icon_height = 128; |
|
||||||
int x, y, i, width, height, vmargin, hmargin, vpadding, hpadding; |
|
||||||
|
|
||||||
surface = window_get_surface(homescreen->window); |
|
||||||
cr = cairo_create(surface); |
|
||||||
|
|
||||||
widget_get_allocation(widget, &allocation); |
|
||||||
paint_background(cr, key_homescreen_background, &allocation); |
|
||||||
|
|
||||||
cairo_set_operator(cr, CAIRO_OPERATOR_OVER); |
|
||||||
|
|
||||||
width = allocation.width - columns * icon_width; |
|
||||||
hpadding = width / (columns + 1); |
|
||||||
hmargin = (width - hpadding * (columns - 1)) / 2; |
|
||||||
|
|
||||||
height = allocation.height - rows * icon_height; |
|
||||||
vpadding = height / (rows + 1); |
|
||||||
vmargin = (height - vpadding * (rows - 1)) / 2; |
|
||||||
|
|
||||||
x = hmargin; |
|
||||||
y = vmargin; |
|
||||||
i = 0; |
|
||||||
|
|
||||||
wl_list_for_each(launcher, &homescreen->launcher_list, link) { |
|
||||||
widget_set_allocation(launcher->widget, |
|
||||||
x, y, icon_width, icon_height); |
|
||||||
x += icon_width + hpadding; |
|
||||||
i++; |
|
||||||
if (i == columns) { |
|
||||||
x = hmargin; |
|
||||||
y += icon_height + vpadding; |
|
||||||
i = 0; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
cairo_destroy(cr); |
|
||||||
cairo_surface_destroy(surface); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
lockscreen_draw(struct widget *widget, void *data) |
|
||||||
{ |
|
||||||
struct lockscreen *lockscreen = data; |
|
||||||
cairo_surface_t *surface; |
|
||||||
cairo_surface_t *icon; |
|
||||||
struct rectangle allocation; |
|
||||||
cairo_t *cr; |
|
||||||
int width, height; |
|
||||||
|
|
||||||
surface = window_get_surface(lockscreen->window); |
|
||||||
cr = cairo_create(surface); |
|
||||||
|
|
||||||
widget_get_allocation(widget, &allocation); |
|
||||||
paint_background(cr, key_lockscreen_background, &allocation); |
|
||||||
|
|
||||||
cairo_set_operator(cr, CAIRO_OPERATOR_OVER); |
|
||||||
icon = load_cairo_surface(key_lockscreen_icon); |
|
||||||
if (icon) { |
|
||||||
width = cairo_image_surface_get_width(icon); |
|
||||||
height = cairo_image_surface_get_height(icon); |
|
||||||
cairo_set_source_surface(cr, icon, |
|
||||||
allocation.x + (allocation.width - width) / 2, |
|
||||||
allocation.y + (allocation.height - height) / 2); |
|
||||||
} else { |
|
||||||
fprintf(stderr, "couldn't load lockscreen icon: %s\n", |
|
||||||
key_lockscreen_icon); |
|
||||||
cairo_set_source_rgb(cr, 0.2, 0, 0); |
|
||||||
} |
|
||||||
cairo_paint(cr); |
|
||||||
cairo_destroy(cr); |
|
||||||
cairo_surface_destroy(icon); |
|
||||||
cairo_surface_destroy(surface); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
lockscreen_button_handler(struct widget *widget, |
|
||||||
struct input *input, uint32_t time, |
|
||||||
uint32_t button, |
|
||||||
enum wl_pointer_button_state state, void *data) |
|
||||||
{ |
|
||||||
struct lockscreen *lockscreen = data; |
|
||||||
|
|
||||||
if (state == WL_POINTER_BUTTON_STATE_PRESSED && lockscreen->window) { |
|
||||||
window_destroy(lockscreen->window); |
|
||||||
lockscreen->window = NULL; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static struct homescreen * |
|
||||||
homescreen_create(struct tablet *tablet) |
|
||||||
{ |
|
||||||
struct homescreen *homescreen; |
|
||||||
|
|
||||||
homescreen = zalloc (sizeof *homescreen); |
|
||||||
homescreen->window = window_create_custom(tablet->display); |
|
||||||
homescreen->widget = |
|
||||||
window_add_widget(homescreen->window, homescreen); |
|
||||||
window_set_user_data(homescreen->window, homescreen); |
|
||||||
window_set_title(homescreen->window, "homescreen"); |
|
||||||
widget_set_redraw_handler(homescreen->widget, homescreen_draw); |
|
||||||
|
|
||||||
return homescreen; |
|
||||||
} |
|
||||||
|
|
||||||
static struct lockscreen * |
|
||||||
lockscreen_create(struct tablet *tablet) |
|
||||||
{ |
|
||||||
struct lockscreen *lockscreen; |
|
||||||
|
|
||||||
lockscreen = zalloc (sizeof *lockscreen); |
|
||||||
lockscreen->window = window_create_custom(tablet->display); |
|
||||||
lockscreen->widget = |
|
||||||
window_add_widget(lockscreen->window, lockscreen); |
|
||||||
window_set_user_data(lockscreen->window, lockscreen); |
|
||||||
window_set_title(lockscreen->window, "lockscreen"); |
|
||||||
widget_set_redraw_handler(lockscreen->widget, lockscreen_draw); |
|
||||||
widget_set_button_handler(lockscreen->widget, |
|
||||||
lockscreen_button_handler); |
|
||||||
|
|
||||||
return lockscreen; |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
show_lockscreen(void *data, struct tablet_shell *tablet_shell) |
|
||||||
{ |
|
||||||
struct tablet *tablet = data; |
|
||||||
|
|
||||||
tablet->lockscreen = lockscreen_create(tablet); |
|
||||||
tablet_shell_set_lockscreen(tablet->tablet_shell, |
|
||||||
window_get_wl_surface(tablet->lockscreen->window)); |
|
||||||
|
|
||||||
widget_schedule_resize(tablet->lockscreen->widget, |
|
||||||
tablet->allocation.width, |
|
||||||
tablet->allocation.height); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
show_switcher(void *data, struct tablet_shell *tablet_shell) |
|
||||||
{ |
|
||||||
struct tablet *tablet = data; |
|
||||||
|
|
||||||
tablet->switcher = window_create_custom(tablet->display); |
|
||||||
window_set_user_data(tablet->switcher, tablet); |
|
||||||
tablet_shell_set_switcher(tablet->tablet_shell, |
|
||||||
window_get_wl_surface(tablet->switcher)); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
hide_switcher(void *data, struct tablet_shell *tablet_shell) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
static const struct tablet_shell_listener tablet_shell_listener = { |
|
||||||
show_lockscreen, |
|
||||||
show_switcher, |
|
||||||
hide_switcher |
|
||||||
}; |
|
||||||
|
|
||||||
static int |
|
||||||
launcher_enter_handler(struct widget *widget, struct input *input, |
|
||||||
float x, float y, void *data) |
|
||||||
{ |
|
||||||
struct launcher *launcher = data; |
|
||||||
|
|
||||||
launcher->focused = 1; |
|
||||||
widget_schedule_redraw(widget); |
|
||||||
|
|
||||||
return CURSOR_LEFT_PTR; |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
launcher_leave_handler(struct widget *widget, |
|
||||||
struct input *input, void *data) |
|
||||||
{ |
|
||||||
struct launcher *launcher = data; |
|
||||||
|
|
||||||
launcher->focused = 0; |
|
||||||
widget_schedule_redraw(widget); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
launcher_activate(struct launcher *widget) |
|
||||||
{ |
|
||||||
pid_t pid; |
|
||||||
|
|
||||||
pid = fork(); |
|
||||||
if (pid < 0) { |
|
||||||
fprintf(stderr, "fork failed: %m\n"); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
if (pid) |
|
||||||
return; |
|
||||||
|
|
||||||
if (execl(widget->path, widget->path, NULL) < 0) { |
|
||||||
fprintf(stderr, "execl '%s' failed: %m\n", widget->path); |
|
||||||
exit(1); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
launcher_button_handler(struct widget *widget, |
|
||||||
struct input *input, uint32_t time, |
|
||||||
uint32_t button, |
|
||||||
enum wl_pointer_button_state state, void *data) |
|
||||||
{ |
|
||||||
struct launcher *launcher; |
|
||||||
|
|
||||||
launcher = widget_get_user_data(widget); |
|
||||||
widget_schedule_redraw(widget); |
|
||||||
if (state == WL_POINTER_BUTTON_STATE_RELEASED) { |
|
||||||
launcher_activate(launcher); |
|
||||||
launcher->pressed = 0; |
|
||||||
} else if (state == WL_POINTER_BUTTON_STATE_PRESSED)
|
|
||||||
launcher->pressed = 1; |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
launcher_redraw_handler(struct widget *widget, void *data) |
|
||||||
{ |
|
||||||
struct launcher *launcher = data; |
|
||||||
cairo_surface_t *surface; |
|
||||||
struct rectangle allocation; |
|
||||||
cairo_t *cr; |
|
||||||
|
|
||||||
surface = window_get_surface(launcher->homescreen->window); |
|
||||||
cr = cairo_create(surface); |
|
||||||
|
|
||||||
widget_get_allocation(widget, &allocation); |
|
||||||
if (launcher->pressed) { |
|
||||||
allocation.x++; |
|
||||||
allocation.y++; |
|
||||||
} |
|
||||||
|
|
||||||
cairo_set_source_surface(cr, launcher->icon, |
|
||||||
allocation.x, allocation.y); |
|
||||||
cairo_paint(cr); |
|
||||||
|
|
||||||
if (launcher->focused) { |
|
||||||
cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.4); |
|
||||||
cairo_mask_surface(cr, launcher->icon, |
|
||||||
allocation.x, allocation.y); |
|
||||||
} |
|
||||||
|
|
||||||
cairo_destroy(cr); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
tablet_shell_add_launcher(struct tablet *tablet, |
|
||||||
const char *icon, const char *path) |
|
||||||
{ |
|
||||||
struct launcher *launcher; |
|
||||||
struct homescreen *homescreen = tablet->homescreen; |
|
||||||
|
|
||||||
launcher = xmalloc(sizeof *launcher); |
|
||||||
launcher->icon = load_cairo_surface(icon); |
|
||||||
if ( !launcher->icon || |
|
||||||
cairo_surface_status (launcher->icon) != CAIRO_STATUS_SUCCESS) { |
|
||||||
fprintf(stderr, "couldn't load %s\n", icon); |
|
||||||
free(launcher); |
|
||||||
return; |
|
||||||
} |
|
||||||
launcher->path = strdup(path); |
|
||||||
|
|
||||||
launcher->homescreen = homescreen; |
|
||||||
launcher->widget = widget_add_widget(homescreen->widget, launcher); |
|
||||||
widget_set_enter_handler(launcher->widget, |
|
||||||
launcher_enter_handler); |
|
||||||
widget_set_leave_handler(launcher->widget, |
|
||||||
launcher_leave_handler); |
|
||||||
widget_set_button_handler(launcher->widget, |
|
||||||
launcher_button_handler); |
|
||||||
widget_set_redraw_handler(launcher->widget, |
|
||||||
launcher_redraw_handler); |
|
||||||
|
|
||||||
wl_list_insert(&homescreen->launcher_list, &launcher->link); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
global_handler(struct display *display, uint32_t name, |
|
||||||
const char *interface, uint32_t version, void *data) |
|
||||||
{ |
|
||||||
struct tablet *tablet = data; |
|
||||||
|
|
||||||
if (!strcmp(interface, "tablet_shell")) { |
|
||||||
tablet->tablet_shell = |
|
||||||
display_bind(display, name, |
|
||||||
&tablet_shell_interface, 1); |
|
||||||
tablet_shell_add_listener(tablet->tablet_shell, |
|
||||||
&tablet_shell_listener, tablet); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
int main(int argc, char *argv[]) |
|
||||||
{ |
|
||||||
struct tablet tablet = { 0 }; |
|
||||||
struct display *display; |
|
||||||
struct output *output; |
|
||||||
struct weston_config *config; |
|
||||||
struct weston_config_section *s; |
|
||||||
char *icon, *path; |
|
||||||
const char *name; |
|
||||||
|
|
||||||
display = display_create(&argc, argv); |
|
||||||
if (display == NULL) { |
|
||||||
fprintf(stderr, "failed to create display: %m\n"); |
|
||||||
return -1; |
|
||||||
} |
|
||||||
|
|
||||||
tablet.display = display; |
|
||||||
|
|
||||||
display_set_user_data(tablet.display, &tablet); |
|
||||||
display_set_global_handler(tablet.display, global_handler); |
|
||||||
|
|
||||||
tablet.homescreen = homescreen_create(&tablet); |
|
||||||
tablet_shell_set_homescreen(tablet.tablet_shell, |
|
||||||
window_get_wl_surface(tablet.homescreen->window)); |
|
||||||
|
|
||||||
wl_display_roundtrip (display_get_display(tablet.display)); |
|
||||||
|
|
||||||
wl_list_init(&tablet.homescreen->launcher_list); |
|
||||||
|
|
||||||
config = weston_config_parse("weston.ini"); |
|
||||||
s = weston_config_get_section(config, "shell", NULL, NULL); |
|
||||||
weston_config_section_get_string(s, "lockscreen-icon", |
|
||||||
&key_lockscreen_icon, NULL); |
|
||||||
weston_config_section_get_string(s, "lockscreen", |
|
||||||
&key_lockscreen_background, NULL); |
|
||||||
weston_config_section_get_string(s, "homescreen", |
|
||||||
&key_homescreen_background, NULL); |
|
||||||
|
|
||||||
s = NULL; |
|
||||||
while (weston_config_next_section(config, &s, &name)) { |
|
||||||
if (strcmp(name, "launcher") != 0) |
|
||||||
continue; |
|
||||||
|
|
||||||
weston_config_section_get_string(s, "icon", &icon, NULL); |
|
||||||
weston_config_section_get_string(s, "path", &path, NULL); |
|
||||||
|
|
||||||
if (icon != NULL && path != NULL) |
|
||||||
tablet_shell_add_launcher(&tablet, icon, path); |
|
||||||
else |
|
||||||
fprintf(stderr, "invalid launcher section\n"); |
|
||||||
|
|
||||||
free(icon); |
|
||||||
free(path); |
|
||||||
} |
|
||||||
|
|
||||||
weston_config_destroy(config); |
|
||||||
|
|
||||||
signal(SIGCHLD, sigchild_handler); |
|
||||||
|
|
||||||
output = display_get_output(tablet.display); |
|
||||||
output_get_allocation(output, &tablet.allocation); |
|
||||||
widget_schedule_resize(tablet.homescreen->widget, |
|
||||||
tablet.allocation.width, |
|
||||||
tablet.allocation.height); |
|
||||||
display_run(display); |
|
||||||
|
|
||||||
return 0; |
|
||||||
} |
|
@ -1,40 +0,0 @@ |
|||||||
<protocol name="tablet"> |
|
||||||
|
|
||||||
<interface name="tablet_shell" version="1"> |
|
||||||
<request name="set_lockscreen"> |
|
||||||
<arg name="surface" type="object" interface="wl_surface"/> |
|
||||||
</request> |
|
||||||
|
|
||||||
<request name="set_switcher"> |
|
||||||
<arg name="surface" type="object" interface="wl_surface"/> |
|
||||||
</request> |
|
||||||
|
|
||||||
<request name="set_homescreen"> |
|
||||||
<arg name="surface" type="object" interface="wl_surface"/> |
|
||||||
</request> |
|
||||||
|
|
||||||
<request name="show_grid"> |
|
||||||
<arg name="surface" type="object" interface="wl_surface"/> |
|
||||||
</request> |
|
||||||
|
|
||||||
<request name="show_panels"> |
|
||||||
<arg name="surface" type="object" interface="wl_surface"/> |
|
||||||
</request> |
|
||||||
|
|
||||||
<request name="create_client"> |
|
||||||
<arg name="id" type="new_id" interface="tablet_client"/> |
|
||||||
<arg name="name" type="string"/> |
|
||||||
<arg name="fd" type="fd"/> |
|
||||||
</request> |
|
||||||
|
|
||||||
<event name="show_lockscreen"/> |
|
||||||
<event name="show_switcher"/> |
|
||||||
<event name="hide_switcher"/> |
|
||||||
</interface> |
|
||||||
|
|
||||||
<interface name="tablet_client" version="1"> |
|
||||||
<request name="destroy" type="destructor"/> |
|
||||||
<request name="activate"/> |
|
||||||
</interface> |
|
||||||
|
|
||||||
</protocol> |
|
@ -1,603 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright © 2011 Intel Corporation |
|
||||||
* |
|
||||||
* Permission to use, copy, modify, distribute, and sell this software and |
|
||||||
* its documentation for any purpose is hereby granted without fee, provided |
|
||||||
* that the above copyright notice appear in all copies and that both that |
|
||||||
* copyright notice and this permission notice appear in supporting |
|
||||||
* documentation, and that the name of the copyright holders not be used in |
|
||||||
* advertising or publicity pertaining to distribution of the software |
|
||||||
* without specific, written prior permission. The copyright holders make |
|
||||||
* no representations about the suitability of this software for any |
|
||||||
* purpose. It is provided "as is" without express or implied warranty. |
|
||||||
* |
|
||||||
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS |
|
||||||
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND |
|
||||||
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY |
|
||||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER |
|
||||||
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF |
|
||||||
* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
|
||||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
||||||
*/ |
|
||||||
|
|
||||||
#include "config.h" |
|
||||||
|
|
||||||
#include <sys/wait.h> |
|
||||||
#include <unistd.h> |
|
||||||
#include <stdlib.h> |
|
||||||
#include <stdio.h> |
|
||||||
#include <string.h> |
|
||||||
#include <linux/input.h> |
|
||||||
#include <assert.h> |
|
||||||
|
|
||||||
#include "compositor.h" |
|
||||||
#include "tablet-shell-server-protocol.h" |
|
||||||
|
|
||||||
/*
|
|
||||||
* TODO: Don't fade back from black until we've received a lockscreen |
|
||||||
* attachment. |
|
||||||
*/ |
|
||||||
|
|
||||||
enum { |
|
||||||
STATE_STARTING, |
|
||||||
STATE_LOCKED, |
|
||||||
STATE_HOME, |
|
||||||
STATE_SWITCHER, |
|
||||||
STATE_TASK |
|
||||||
}; |
|
||||||
|
|
||||||
struct tablet_shell { |
|
||||||
struct wl_resource *resource; |
|
||||||
|
|
||||||
struct wl_listener lock_listener; |
|
||||||
struct wl_listener unlock_listener; |
|
||||||
struct wl_listener destroy_listener; |
|
||||||
|
|
||||||
struct weston_compositor *compositor; |
|
||||||
struct weston_process process; |
|
||||||
struct wl_client *client; |
|
||||||
|
|
||||||
struct weston_surface *surface; |
|
||||||
|
|
||||||
struct weston_surface *lockscreen_surface; |
|
||||||
struct wl_listener lockscreen_listener; |
|
||||||
struct weston_layer lockscreen_layer; |
|
||||||
|
|
||||||
struct weston_layer application_layer; |
|
||||||
|
|
||||||
struct weston_surface *home_surface; |
|
||||||
struct weston_layer homescreen_layer; |
|
||||||
|
|
||||||
struct weston_surface *switcher_surface; |
|
||||||
struct wl_listener switcher_listener; |
|
||||||
|
|
||||||
struct tablet_client *current_client; |
|
||||||
|
|
||||||
int state, previous_state; |
|
||||||
int long_press_active; |
|
||||||
struct wl_event_source *long_press_source; |
|
||||||
}; |
|
||||||
|
|
||||||
struct tablet_client { |
|
||||||
struct wl_resource *resource; |
|
||||||
struct tablet_shell *shell; |
|
||||||
struct wl_client *client; |
|
||||||
struct weston_surface *surface; |
|
||||||
char *name; |
|
||||||
}; |
|
||||||
|
|
||||||
static void |
|
||||||
tablet_shell_destroy(struct wl_listener *listener, void *data); |
|
||||||
|
|
||||||
static struct tablet_shell * |
|
||||||
get_shell(struct weston_compositor *compositor) |
|
||||||
{ |
|
||||||
struct wl_listener *l; |
|
||||||
|
|
||||||
l = wl_signal_get(&compositor->destroy_signal, tablet_shell_destroy); |
|
||||||
if (l) |
|
||||||
return container_of(l, struct tablet_shell, destroy_listener); |
|
||||||
|
|
||||||
return NULL; |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
tablet_shell_sigchld(struct weston_process *process, int status) |
|
||||||
{ |
|
||||||
struct tablet_shell *shell = |
|
||||||
container_of(process, struct tablet_shell, process); |
|
||||||
|
|
||||||
shell->process.pid = 0; |
|
||||||
|
|
||||||
weston_log("weston-tablet-shell crashed, exit code %d\n", status); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
tablet_shell_set_state(struct tablet_shell *shell, int state) |
|
||||||
{ |
|
||||||
static const char *states[] = { |
|
||||||
"STARTING", "LOCKED", "HOME", "SWITCHER", "TASK" |
|
||||||
}; |
|
||||||
|
|
||||||
weston_log("switching to state %s (from %s)\n", |
|
||||||
states[state], states[shell->state]); |
|
||||||
shell->previous_state = shell->state; |
|
||||||
shell->state = state; |
|
||||||
} |
|
||||||
|
|
||||||
static struct weston_view * |
|
||||||
get_surface_view(struct weston_surface *surface, int create) |
|
||||||
{ |
|
||||||
if (!surface) |
|
||||||
return NULL; |
|
||||||
|
|
||||||
if (wl_list_empty(&surface->views)) { |
|
||||||
if (create) |
|
||||||
return weston_view_create(surface); |
|
||||||
else |
|
||||||
return NULL; |
|
||||||
} |
|
||||||
|
|
||||||
return container_of(surface->views.next, struct weston_view, surface_link); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
tablet_shell_surface_configure(struct weston_surface *surface, |
|
||||||
int32_t sx, int32_t sy) |
|
||||||
{ |
|
||||||
struct tablet_shell *shell = get_shell(surface->compositor); |
|
||||||
struct weston_view *view = get_surface_view(surface, 0); |
|
||||||
assert(view); |
|
||||||
|
|
||||||
if (weston_surface_is_mapped(surface) || surface->width == 0) |
|
||||||
return; |
|
||||||
|
|
||||||
if (surface == shell->lockscreen_surface) { |
|
||||||
wl_list_insert(&shell->lockscreen_layer.view_list, |
|
||||||
&view->layer_link); |
|
||||||
} else if (surface == shell->switcher_surface) { |
|
||||||
/* */ |
|
||||||
} else if (surface == shell->home_surface) { |
|
||||||
if (shell->state == STATE_STARTING) { |
|
||||||
/* homescreen always visible, at the bottom */ |
|
||||||
wl_list_insert(&shell->homescreen_layer.view_list, |
|
||||||
&view->layer_link); |
|
||||||
|
|
||||||
tablet_shell_set_state(shell, STATE_LOCKED); |
|
||||||
shell->previous_state = STATE_HOME; |
|
||||||
tablet_shell_send_show_lockscreen(shell->resource); |
|
||||||
} |
|
||||||
} else if (shell->current_client && |
|
||||||
shell->current_client->surface != surface && |
|
||||||
shell->current_client->client == wl_resource_get_client(surface->resource)) { |
|
||||||
tablet_shell_set_state(shell, STATE_TASK); |
|
||||||
shell->current_client->surface = surface; |
|
||||||
weston_zoom_run(view, 0.3, 1.0, NULL, NULL); |
|
||||||
wl_list_insert(&shell->application_layer.view_list, |
|
||||||
&view->layer_link); |
|
||||||
} |
|
||||||
|
|
||||||
if (view) { |
|
||||||
weston_view_set_position(view, 0, 0); |
|
||||||
weston_view_update_transform(view); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
handle_lockscreen_surface_destroy(struct wl_listener *listener, void *data) |
|
||||||
{ |
|
||||||
struct tablet_shell *shell = |
|
||||||
container_of(listener, |
|
||||||
struct tablet_shell, lockscreen_listener); |
|
||||||
|
|
||||||
shell->lockscreen_surface = NULL; |
|
||||||
tablet_shell_set_state(shell, shell->previous_state); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
tablet_shell_set_lockscreen(struct wl_client *client, |
|
||||||
struct wl_resource *resource, |
|
||||||
struct wl_resource *surface_resource) |
|
||||||
{ |
|
||||||
struct tablet_shell *shell = wl_resource_get_user_data(resource); |
|
||||||
struct weston_surface *es = wl_resource_get_user_data(surface_resource); |
|
||||||
struct weston_view *view; |
|
||||||
|
|
||||||
view = weston_view_create(es); |
|
||||||
weston_view_set_position(view, 0, 0); |
|
||||||
shell->lockscreen_surface = es; |
|
||||||
es->configure = tablet_shell_surface_configure; |
|
||||||
shell->lockscreen_listener.notify = handle_lockscreen_surface_destroy; |
|
||||||
wl_signal_add(&es->destroy_signal, &shell->lockscreen_listener); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
handle_switcher_surface_destroy(struct wl_listener *listener, void *data) |
|
||||||
{ |
|
||||||
struct tablet_shell *shell = |
|
||||||
container_of(listener, |
|
||||||
struct tablet_shell, switcher_listener); |
|
||||||
|
|
||||||
shell->switcher_surface = NULL; |
|
||||||
if (shell->state != STATE_LOCKED) |
|
||||||
tablet_shell_set_state(shell, shell->previous_state); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
tablet_shell_set_switcher(struct wl_client *client, |
|
||||||
struct wl_resource *resource, |
|
||||||
struct wl_resource *surface_resource) |
|
||||||
{ |
|
||||||
struct tablet_shell *shell = wl_resource_get_user_data(resource); |
|
||||||
struct weston_surface *es = wl_resource_get_user_data(surface_resource); |
|
||||||
struct weston_view *view; |
|
||||||
|
|
||||||
/* FIXME: Switcher should be centered and the compositor
|
|
||||||
* should do the tinting of the background. With the cache |
|
||||||
* layer idea, we should be able to hit the framerate on the |
|
||||||
* fade/zoom in. */ |
|
||||||
view = weston_view_create(es); |
|
||||||
weston_view_set_position(view, 0, 0); |
|
||||||
|
|
||||||
shell->switcher_surface = es; |
|
||||||
shell->switcher_listener.notify = handle_switcher_surface_destroy; |
|
||||||
wl_signal_add(&es->destroy_signal, &shell->switcher_listener); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
tablet_shell_set_homescreen(struct wl_client *client, |
|
||||||
struct wl_resource *resource, |
|
||||||
struct wl_resource *surface_resource) |
|
||||||
{ |
|
||||||
struct tablet_shell *shell = wl_resource_get_user_data(resource); |
|
||||||
struct weston_surface *es = wl_resource_get_user_data(surface_resource); |
|
||||||
struct weston_view *view; |
|
||||||
|
|
||||||
view = weston_view_create(es); |
|
||||||
weston_view_set_position(view, 0, 0); |
|
||||||
|
|
||||||
shell->home_surface = es; |
|
||||||
es->configure = tablet_shell_surface_configure; |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
minimize_zoom_done(struct weston_view_animation *zoom, void *data) |
|
||||||
{ |
|
||||||
struct tablet_shell *shell = data; |
|
||||||
struct weston_compositor *compositor = shell->compositor; |
|
||||||
struct weston_seat *seat; |
|
||||||
|
|
||||||
wl_list_for_each(seat, &compositor->seat_list, link) |
|
||||||
weston_surface_activate(shell->home_surface, seat); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
tablet_shell_switch_to(struct tablet_shell *shell, |
|
||||||
struct weston_surface *surface) |
|
||||||
{ |
|
||||||
struct weston_compositor *compositor = shell->compositor; |
|
||||||
struct weston_seat *seat; |
|
||||||
struct weston_surface *current; |
|
||||||
struct weston_view *view = get_surface_view(surface, 1); |
|
||||||
|
|
||||||
if (shell->state == STATE_SWITCHER) { |
|
||||||
wl_list_remove(&shell->switcher_listener.link); |
|
||||||
shell->switcher_surface = NULL; |
|
||||||
}; |
|
||||||
|
|
||||||
if (surface == shell->home_surface) { |
|
||||||
tablet_shell_set_state(shell, STATE_HOME); |
|
||||||
|
|
||||||
if (shell->current_client && shell->current_client->surface) { |
|
||||||
current = shell->current_client->surface; |
|
||||||
weston_zoom_run(get_surface_view(current, 0), 1.0, 0.3, |
|
||||||
minimize_zoom_done, shell); |
|
||||||
} |
|
||||||
} else { |
|
||||||
fprintf(stderr, "switch to %p\n", view); |
|
||||||
wl_list_for_each(seat, &compositor->seat_list, link) |
|
||||||
weston_surface_activate(view->surface, seat); |
|
||||||
tablet_shell_set_state(shell, STATE_TASK); |
|
||||||
weston_zoom_run(view, 0.3, 1.0, NULL, NULL); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
tablet_shell_show_grid(struct wl_client *client, |
|
||||||
struct wl_resource *resource, |
|
||||||
struct wl_resource *surface_resource) |
|
||||||
{ |
|
||||||
struct tablet_shell *shell = wl_resource_get_user_data(resource); |
|
||||||
struct weston_surface *es = wl_resource_get_user_data(surface_resource); |
|
||||||
|
|
||||||
tablet_shell_switch_to(shell, es); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
tablet_shell_show_panels(struct wl_client *client, |
|
||||||
struct wl_resource *resource, |
|
||||||
struct wl_resource *surface_resource) |
|
||||||
{ |
|
||||||
struct tablet_shell *shell = wl_resource_get_user_data(resource); |
|
||||||
struct weston_surface *es = wl_resource_get_user_data(surface_resource); |
|
||||||
|
|
||||||
tablet_shell_switch_to(shell, es); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
destroy_tablet_client(struct wl_resource *resource) |
|
||||||
{ |
|
||||||
struct tablet_client *tablet_client = |
|
||||||
wl_resource_get_user_data(resource); |
|
||||||
|
|
||||||
free(tablet_client->name); |
|
||||||
free(tablet_client); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
tablet_client_destroy(struct wl_client *client, |
|
||||||
struct wl_resource *resource) |
|
||||||
{ |
|
||||||
wl_resource_destroy(resource); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
tablet_client_activate(struct wl_client *client, struct wl_resource *resource) |
|
||||||
{ |
|
||||||
struct tablet_client *tablet_client = wl_resource_get_user_data(resource); |
|
||||||
struct tablet_shell *shell = tablet_client->shell; |
|
||||||
|
|
||||||
shell->current_client = tablet_client; |
|
||||||
if (!tablet_client->surface) |
|
||||||
return; |
|
||||||
|
|
||||||
tablet_shell_switch_to(shell, tablet_client->surface); |
|
||||||
} |
|
||||||
|
|
||||||
static const struct tablet_client_interface tablet_client_implementation = { |
|
||||||
tablet_client_destroy, |
|
||||||
tablet_client_activate |
|
||||||
}; |
|
||||||
|
|
||||||
static void |
|
||||||
tablet_shell_create_client(struct wl_client *client, |
|
||||||
struct wl_resource *resource, |
|
||||||
uint32_t id, const char *name, int fd) |
|
||||||
{ |
|
||||||
struct tablet_shell *shell = wl_resource_get_user_data(resource); |
|
||||||
struct weston_compositor *compositor = shell->compositor; |
|
||||||
struct tablet_client *tablet_client; |
|
||||||
|
|
||||||
tablet_client = malloc(sizeof *tablet_client); |
|
||||||
if (tablet_client == NULL) { |
|
||||||
wl_resource_post_no_memory(resource); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
tablet_client->client = wl_client_create(compositor->wl_display, fd); |
|
||||||
tablet_client->shell = shell; |
|
||||||
tablet_client->name = strdup(name); |
|
||||||
|
|
||||||
tablet_client->resource = |
|
||||||
wl_resource_create(client, &tablet_client_interface, 1, id); |
|
||||||
wl_resource_set_implementation(tablet_client->resource, |
|
||||||
&tablet_client_implementation, |
|
||||||
tablet_client, destroy_tablet_client); |
|
||||||
|
|
||||||
tablet_client->surface = NULL; |
|
||||||
shell->current_client = tablet_client; |
|
||||||
|
|
||||||
weston_log("created client %p, id %d, name %s, fd %d\n", |
|
||||||
tablet_client->client, id, name, fd); |
|
||||||
} |
|
||||||
|
|
||||||
static const struct tablet_shell_interface tablet_shell_implementation = { |
|
||||||
tablet_shell_set_lockscreen, |
|
||||||
tablet_shell_set_switcher, |
|
||||||
tablet_shell_set_homescreen, |
|
||||||
tablet_shell_show_grid, |
|
||||||
tablet_shell_show_panels, |
|
||||||
tablet_shell_create_client |
|
||||||
}; |
|
||||||
|
|
||||||
static void |
|
||||||
launch_ux_daemon(struct tablet_shell *shell) |
|
||||||
{ |
|
||||||
const char *shell_exe = LIBEXECDIR "/weston-tablet-shell"; |
|
||||||
|
|
||||||
shell->client = weston_client_launch(shell->compositor, |
|
||||||
&shell->process, |
|
||||||
shell_exe, tablet_shell_sigchld); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
toggle_switcher(struct tablet_shell *shell) |
|
||||||
{ |
|
||||||
switch (shell->state) { |
|
||||||
case STATE_SWITCHER: |
|
||||||
tablet_shell_send_hide_switcher(shell->resource); |
|
||||||
break; |
|
||||||
default: |
|
||||||
tablet_shell_send_show_switcher(shell->resource); |
|
||||||
tablet_shell_set_state(shell, STATE_SWITCHER); |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
tablet_shell_lock(struct wl_listener *listener, void *data) |
|
||||||
{ |
|
||||||
struct tablet_shell *shell = |
|
||||||
container_of(listener, struct tablet_shell, lock_listener); |
|
||||||
|
|
||||||
if (shell->state == STATE_LOCKED) |
|
||||||
return; |
|
||||||
if (shell->state == STATE_SWITCHER) |
|
||||||
tablet_shell_send_hide_switcher(shell->resource); |
|
||||||
|
|
||||||
tablet_shell_send_show_lockscreen(shell->resource); |
|
||||||
tablet_shell_set_state(shell, STATE_LOCKED); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
tablet_shell_unlock(struct wl_listener *listener, void *data) |
|
||||||
{ |
|
||||||
struct tablet_shell *shell = |
|
||||||
container_of(listener, struct tablet_shell, unlock_listener); |
|
||||||
|
|
||||||
tablet_shell_set_state(shell, STATE_HOME); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
go_home(struct tablet_shell *shell, struct weston_seat *seat) |
|
||||||
{ |
|
||||||
if (shell->state == STATE_SWITCHER) |
|
||||||
tablet_shell_send_hide_switcher(shell->resource); |
|
||||||
|
|
||||||
weston_surface_activate(shell->home_surface, seat); |
|
||||||
|
|
||||||
tablet_shell_set_state(shell, STATE_HOME); |
|
||||||
} |
|
||||||
|
|
||||||
static int |
|
||||||
long_press_handler(void *data) |
|
||||||
{ |
|
||||||
struct tablet_shell *shell = data; |
|
||||||
|
|
||||||
shell->long_press_active = 0; |
|
||||||
toggle_switcher(shell); |
|
||||||
|
|
||||||
return 1; |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
menu_key_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *data) |
|
||||||
{ |
|
||||||
struct tablet_shell *shell = data; |
|
||||||
|
|
||||||
if (shell->state == STATE_LOCKED) |
|
||||||
return; |
|
||||||
|
|
||||||
toggle_switcher(shell); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
home_key_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *data) |
|
||||||
{ |
|
||||||
struct tablet_shell *shell = data; |
|
||||||
|
|
||||||
if (shell->state == STATE_LOCKED) |
|
||||||
return; |
|
||||||
|
|
||||||
if (1) { |
|
||||||
wl_event_source_timer_update(shell->long_press_source, 500); |
|
||||||
shell->long_press_active = 1; |
|
||||||
} else if (shell->long_press_active) { |
|
||||||
/* This code has never been run ... */ |
|
||||||
wl_event_source_timer_update(shell->long_press_source, 0); |
|
||||||
shell->long_press_active = 0; |
|
||||||
|
|
||||||
switch (shell->state) { |
|
||||||
case STATE_HOME: |
|
||||||
case STATE_SWITCHER: |
|
||||||
toggle_switcher(shell); |
|
||||||
break; |
|
||||||
default: |
|
||||||
go_home(shell, (struct weston_seat *) seat); |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
destroy_tablet_shell(struct wl_resource *resource) |
|
||||||
{ |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
bind_tablet_shell(struct wl_client *client, void *data, uint32_t version, |
|
||||||
uint32_t id) |
|
||||||
{ |
|
||||||
struct tablet_shell *shell = data; |
|
||||||
|
|
||||||
if (shell->client != client) |
|
||||||
/* Throw an error or just let the client fail when it
|
|
||||||
* tries to access the object?. */ |
|
||||||
return; |
|
||||||
|
|
||||||
shell->resource = |
|
||||||
wl_resource_create(client, &tablet_shell_interface, 1, id); |
|
||||||
wl_resource_set_implementation(shell->resource, |
|
||||||
&tablet_shell_implementation, |
|
||||||
shell, destroy_tablet_shell); |
|
||||||
} |
|
||||||
|
|
||||||
static void |
|
||||||
tablet_shell_destroy(struct wl_listener *listener, void *data) |
|
||||||
{ |
|
||||||
struct tablet_shell *shell = |
|
||||||
container_of(listener, struct tablet_shell, destroy_listener); |
|
||||||
|
|
||||||
if (shell->home_surface) |
|
||||||
shell->home_surface->configure = NULL; |
|
||||||
|
|
||||||
if (shell->lockscreen_surface) |
|
||||||
shell->lockscreen_surface->configure = NULL; |
|
||||||
|
|
||||||
wl_event_source_remove(shell->long_press_source); |
|
||||||
free(shell); |
|
||||||
} |
|
||||||
|
|
||||||
WL_EXPORT int |
|
||||||
module_init(struct weston_compositor *compositor, |
|
||||||
int *argc, char *argv[]) |
|
||||||
{ |
|
||||||
struct tablet_shell *shell; |
|
||||||
struct wl_event_loop *loop; |
|
||||||
|
|
||||||
shell = zalloc(sizeof *shell); |
|
||||||
if (shell == NULL) |
|
||||||
return -1; |
|
||||||
|
|
||||||
shell->compositor = compositor; |
|
||||||
|
|
||||||
shell->destroy_listener.notify = tablet_shell_destroy; |
|
||||||
wl_signal_add(&compositor->destroy_signal, &shell->destroy_listener); |
|
||||||
shell->lock_listener.notify = tablet_shell_lock; |
|
||||||
wl_signal_add(&compositor->idle_signal, &shell->lock_listener); |
|
||||||
shell->unlock_listener.notify = tablet_shell_unlock; |
|
||||||
wl_signal_add(&compositor->wake_signal, &shell->unlock_listener); |
|
||||||
|
|
||||||
/* FIXME: This will make the object available to all clients. */ |
|
||||||
wl_global_create(compositor->wl_display, &tablet_shell_interface, 1, |
|
||||||
shell, bind_tablet_shell); |
|
||||||
|
|
||||||
loop = wl_display_get_event_loop(compositor->wl_display); |
|
||||||
shell->long_press_source = |
|
||||||
wl_event_loop_add_timer(loop, long_press_handler, shell); |
|
||||||
|
|
||||||
weston_compositor_add_key_binding(compositor, KEY_LEFTMETA, 0, |
|
||||||
home_key_binding, shell); |
|
||||||
weston_compositor_add_key_binding(compositor, KEY_RIGHTMETA, 0, |
|
||||||
home_key_binding, shell); |
|
||||||
weston_compositor_add_key_binding(compositor, KEY_LEFTMETA, |
|
||||||
MODIFIER_SUPER, home_key_binding, |
|
||||||
shell); |
|
||||||
weston_compositor_add_key_binding(compositor, KEY_RIGHTMETA, |
|
||||||
MODIFIER_SUPER, home_key_binding, |
|
||||||
shell); |
|
||||||
weston_compositor_add_key_binding(compositor, KEY_COMPOSE, 0, |
|
||||||
menu_key_binding, shell); |
|
||||||
|
|
||||||
weston_layer_init(&shell->homescreen_layer, |
|
||||||
&compositor->cursor_layer.link); |
|
||||||
weston_layer_init(&shell->application_layer, |
|
||||||
&compositor->cursor_layer.link); |
|
||||||
weston_layer_init(&shell->lockscreen_layer, |
|
||||||
&compositor->cursor_layer.link); |
|
||||||
launch_ux_daemon(shell); |
|
||||||
|
|
||||||
tablet_shell_set_state(shell, STATE_STARTING); |
|
||||||
|
|
||||||
return 0; |
|
||||||
} |
|
Loading…
Reference in new issue