2011-01-18 15:53:49 +03:00
|
|
|
/*
|
|
|
|
* Copyright © 2010 Intel Corporation
|
desktop-shell: screen locking protocol
Add protocol and functions for supporting screen locking, triggered by
activity timeout.
After activity timeout, compositor starts the fade to black, and then
enters SLEEPING state. At that point it calls lock() in the shell
plugin.
When input events trigger a wakeup, unlock() in the shell plugin is
called. This sends prepare_lock_surface event to the desktop-shell
client. The screen stays locked while the compositor starts fade-in.
At this point, desktop-shell client usually creates a surface for the
unlocking GUI (e.g. a password prompt), and sends it with the
set_lock_surface request. The compositor supposedly shows and allows
interaction only with the given lock surface (not yet implemented).
When desktop-shell has authenticated the user, or instead of issuing
set_lock_surface, it sends the unlock request. Upon receiving the unlock
request, the shell plugin unlocks the screen.
If desktop-shell client dies, the screen is unlocked automatically.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2011-11-15 15:34:48 +04:00
|
|
|
* Copyright © 2011 Collabora, Ltd.
|
2011-01-18 15:53:49 +03:00
|
|
|
*
|
|
|
|
* 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 <stdlib.h>
|
2011-09-06 21:48:16 +04:00
|
|
|
#include <stdio.h>
|
desktop-shell: screen locking protocol
Add protocol and functions for supporting screen locking, triggered by
activity timeout.
After activity timeout, compositor starts the fade to black, and then
enters SLEEPING state. At that point it calls lock() in the shell
plugin.
When input events trigger a wakeup, unlock() in the shell plugin is
called. This sends prepare_lock_surface event to the desktop-shell
client. The screen stays locked while the compositor starts fade-in.
At this point, desktop-shell client usually creates a surface for the
unlocking GUI (e.g. a password prompt), and sends it with the
set_lock_surface request. The compositor supposedly shows and allows
interaction only with the given lock surface (not yet implemented).
When desktop-shell has authenticated the user, or instead of issuing
set_lock_surface, it sends the unlock request. Upon receiving the unlock
request, the shell plugin unlocks the screen.
If desktop-shell client dies, the screen is unlocked automatically.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2011-11-15 15:34:48 +04:00
|
|
|
#include <stdbool.h>
|
2011-01-18 15:53:49 +03:00
|
|
|
#include <string.h>
|
|
|
|
#include <unistd.h>
|
2011-04-13 01:25:42 +04:00
|
|
|
#include <linux/input.h>
|
2011-11-15 15:34:54 +04:00
|
|
|
#include <assert.h>
|
2011-01-18 15:53:49 +03:00
|
|
|
|
2011-11-22 16:18:50 +04:00
|
|
|
#include <wayland-server.h>
|
2011-01-18 15:53:49 +03:00
|
|
|
#include "compositor.h"
|
2011-09-06 21:48:16 +04:00
|
|
|
#include "desktop-shell-server-protocol.h"
|
2011-01-18 15:53:49 +03:00
|
|
|
|
2011-11-28 16:11:15 +04:00
|
|
|
struct shell_surface;
|
|
|
|
|
2011-04-23 21:04:11 +04:00
|
|
|
struct wl_shell {
|
2011-09-06 21:48:16 +04:00
|
|
|
struct wlsc_compositor *compositor;
|
2011-04-23 21:04:11 +04:00
|
|
|
struct wlsc_shell shell;
|
2011-11-03 16:11:32 +04:00
|
|
|
|
|
|
|
struct {
|
|
|
|
struct wlsc_process process;
|
|
|
|
struct wl_client *client;
|
desktop-shell: screen locking protocol
Add protocol and functions for supporting screen locking, triggered by
activity timeout.
After activity timeout, compositor starts the fade to black, and then
enters SLEEPING state. At that point it calls lock() in the shell
plugin.
When input events trigger a wakeup, unlock() in the shell plugin is
called. This sends prepare_lock_surface event to the desktop-shell
client. The screen stays locked while the compositor starts fade-in.
At this point, desktop-shell client usually creates a surface for the
unlocking GUI (e.g. a password prompt), and sends it with the
set_lock_surface request. The compositor supposedly shows and allows
interaction only with the given lock surface (not yet implemented).
When desktop-shell has authenticated the user, or instead of issuing
set_lock_surface, it sends the unlock request. Upon receiving the unlock
request, the shell plugin unlocks the screen.
If desktop-shell client dies, the screen is unlocked automatically.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2011-11-15 15:34:48 +04:00
|
|
|
struct wl_resource *desktop_shell;
|
2011-11-03 16:11:32 +04:00
|
|
|
} child;
|
desktop-shell: screen locking protocol
Add protocol and functions for supporting screen locking, triggered by
activity timeout.
After activity timeout, compositor starts the fade to black, and then
enters SLEEPING state. At that point it calls lock() in the shell
plugin.
When input events trigger a wakeup, unlock() in the shell plugin is
called. This sends prepare_lock_surface event to the desktop-shell
client. The screen stays locked while the compositor starts fade-in.
At this point, desktop-shell client usually creates a surface for the
unlocking GUI (e.g. a password prompt), and sends it with the
set_lock_surface request. The compositor supposedly shows and allows
interaction only with the given lock surface (not yet implemented).
When desktop-shell has authenticated the user, or instead of issuing
set_lock_surface, it sends the unlock request. Upon receiving the unlock
request, the shell plugin unlocks the screen.
If desktop-shell client dies, the screen is unlocked automatically.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2011-11-15 15:34:48 +04:00
|
|
|
|
|
|
|
bool locked;
|
|
|
|
bool prepare_event_sent;
|
2011-11-15 15:34:54 +04:00
|
|
|
|
2011-11-28 16:11:15 +04:00
|
|
|
struct shell_surface *lock_surface;
|
2011-11-16 01:39:55 +04:00
|
|
|
struct wl_listener lock_surface_listener;
|
2011-11-15 15:34:54 +04:00
|
|
|
struct wl_list hidden_surface_list;
|
2011-11-22 15:43:52 +04:00
|
|
|
|
|
|
|
struct wl_list backgrounds;
|
|
|
|
struct wl_list panels;
|
protocol: add screensaver interface
Add the screensaver interface to the desktop-shell protocol file. Also
add stubs for it in the compositor, and make wscreensaver to bind to the
screensaver interface. Wscreensaver gets a new option --demo to retain
the current behaviour as a regular wayland client.
When a screensaver application starts, it should bind to the screensaver
interface, enumerate all outputs, create a surface per output, and
register those surfaces via screensaver::set_surface request. Then it
continues with the usual animation loop, waiting for frame events. The
compositor will decide, when the given screensaver surfaces are
displayed. A screensaver application should respond to outputs coming
and going away by creating and destroying surfaces.
The compositor is supposed to activate a screensaver by exec'ing it, and
stop the screensaver by killing the client process. Only one client may
be bound to the screensaver interface at a time. If there already is a
client, the compositor could either kill it first, or not exec a new
one.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2011-11-24 13:34:05 +04:00
|
|
|
|
2011-11-30 18:26:35 +04:00
|
|
|
struct {
|
|
|
|
struct wl_resource *binding;
|
|
|
|
struct wl_list surfaces;
|
|
|
|
} screensaver;
|
2011-11-15 15:34:54 +04:00
|
|
|
};
|
|
|
|
|
2011-11-23 19:52:40 +04:00
|
|
|
enum shell_surface_type {
|
2011-12-01 12:42:22 +04:00
|
|
|
SHELL_SURFACE_NONE,
|
2011-11-23 19:52:40 +04:00
|
|
|
|
2011-11-23 18:42:16 +04:00
|
|
|
SHELL_SURFACE_PANEL,
|
|
|
|
SHELL_SURFACE_BACKGROUND,
|
|
|
|
SHELL_SURFACE_LOCK,
|
2011-11-30 18:26:35 +04:00
|
|
|
SHELL_SURFACE_SCREENSAVER,
|
2011-11-23 19:52:40 +04:00
|
|
|
|
|
|
|
SHELL_SURFACE_TOPLEVEL,
|
|
|
|
SHELL_SURFACE_TRANSIENT,
|
|
|
|
SHELL_SURFACE_FULLSCREEN
|
2011-11-23 18:42:16 +04:00
|
|
|
};
|
|
|
|
|
2011-11-23 18:14:12 +04:00
|
|
|
struct shell_surface {
|
2011-11-25 14:09:16 +04:00
|
|
|
struct wl_resource resource;
|
|
|
|
|
2011-11-22 15:43:52 +04:00
|
|
|
struct wlsc_surface *surface;
|
2011-11-25 14:09:16 +04:00
|
|
|
struct wl_listener surface_destroy_listener;
|
2011-11-23 18:42:16 +04:00
|
|
|
|
2011-11-23 19:52:40 +04:00
|
|
|
enum shell_surface_type type;
|
|
|
|
int32_t saved_x, saved_y;
|
2011-11-22 15:43:52 +04:00
|
|
|
|
|
|
|
struct wlsc_output *output;
|
|
|
|
struct wl_list link;
|
2011-11-23 18:14:12 +04:00
|
|
|
};
|
|
|
|
|
2011-01-18 15:53:49 +03:00
|
|
|
struct wlsc_move_grab {
|
|
|
|
struct wl_grab grab;
|
2011-01-22 01:00:09 +03:00
|
|
|
struct wlsc_surface *surface;
|
2011-01-18 15:53:49 +03:00
|
|
|
int32_t dx, dy;
|
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
move_grab_motion(struct wl_grab *grab,
|
|
|
|
uint32_t time, int32_t x, int32_t y)
|
|
|
|
{
|
|
|
|
struct wlsc_move_grab *move = (struct wlsc_move_grab *) grab;
|
2011-01-22 01:00:09 +03:00
|
|
|
struct wlsc_surface *es = move->surface;
|
2011-01-18 15:53:49 +03:00
|
|
|
|
2011-06-24 05:43:50 +04:00
|
|
|
wlsc_surface_configure(es, x + move->dx, y + move->dy,
|
|
|
|
es->width, es->height);
|
2011-01-18 15:53:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
move_grab_button(struct wl_grab *grab,
|
|
|
|
uint32_t time, int32_t button, int32_t state)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
move_grab_end(struct wl_grab *grab, uint32_t time)
|
|
|
|
{
|
|
|
|
free(grab);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct wl_grab_interface move_grab_interface = {
|
|
|
|
move_grab_motion,
|
|
|
|
move_grab_button,
|
|
|
|
move_grab_end
|
|
|
|
};
|
|
|
|
|
2011-08-27 01:21:20 +04:00
|
|
|
static int
|
|
|
|
wlsc_surface_move(struct wlsc_surface *es,
|
|
|
|
struct wlsc_input_device *wd, uint32_t time)
|
2011-01-18 15:53:49 +03:00
|
|
|
{
|
|
|
|
struct wlsc_move_grab *move;
|
|
|
|
|
|
|
|
move = malloc(sizeof *move);
|
2011-08-27 01:21:20 +04:00
|
|
|
if (!move)
|
|
|
|
return -1;
|
2011-01-18 15:53:49 +03:00
|
|
|
|
|
|
|
move->grab.interface = &move_grab_interface;
|
|
|
|
move->dx = es->x - wd->input_device.grab_x;
|
|
|
|
move->dy = es->y - wd->input_device.grab_y;
|
2011-01-22 01:00:09 +03:00
|
|
|
move->surface = es;
|
2011-01-18 15:53:49 +03:00
|
|
|
|
|
|
|
if (wl_input_device_update_grab(&wd->input_device,
|
2011-08-27 01:21:20 +04:00
|
|
|
&move->grab, &es->surface, time) < 0)
|
|
|
|
return 0;
|
2011-01-18 15:53:49 +03:00
|
|
|
|
|
|
|
wlsc_input_device_set_pointer_image(wd, WLSC_POINTER_DRAGGING);
|
2011-08-27 01:21:20 +04:00
|
|
|
wl_input_device_set_pointer_focus(&wd->input_device,
|
|
|
|
NULL, time, 0, 0, 0, 0);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2011-11-25 14:09:16 +04:00
|
|
|
shell_surface_move(struct wl_client *client, struct wl_resource *resource,
|
|
|
|
struct wl_resource *input_resource, uint32_t time)
|
2011-08-27 01:21:20 +04:00
|
|
|
{
|
|
|
|
struct wlsc_input_device *wd = input_resource->data;
|
2011-11-25 14:09:16 +04:00
|
|
|
struct shell_surface *shsurf = resource->data;
|
2011-08-27 01:21:20 +04:00
|
|
|
|
2011-11-25 14:09:16 +04:00
|
|
|
if (wlsc_surface_move(shsurf->surface, wd, time) < 0)
|
2011-09-01 17:54:57 +04:00
|
|
|
wl_resource_post_no_memory(resource);
|
2011-01-18 15:53:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
struct wlsc_resize_grab {
|
|
|
|
struct wl_grab grab;
|
|
|
|
uint32_t edges;
|
|
|
|
int32_t dx, dy, width, height;
|
2011-11-25 14:09:16 +04:00
|
|
|
struct shell_surface *shsurf;
|
2011-01-18 15:53:49 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
resize_grab_motion(struct wl_grab *grab,
|
|
|
|
uint32_t time, int32_t x, int32_t y)
|
|
|
|
{
|
|
|
|
struct wlsc_resize_grab *resize = (struct wlsc_resize_grab *) grab;
|
|
|
|
struct wl_input_device *device = grab->input_device;
|
|
|
|
int32_t width, height;
|
|
|
|
|
2011-11-25 14:09:16 +04:00
|
|
|
if (resize->edges & WL_SHELL_SURFACE_RESIZE_LEFT) {
|
2011-01-18 15:53:49 +03:00
|
|
|
width = device->grab_x - x + resize->width;
|
2011-11-25 14:09:16 +04:00
|
|
|
} else if (resize->edges & WL_SHELL_SURFACE_RESIZE_RIGHT) {
|
2011-01-18 15:53:49 +03:00
|
|
|
width = x - device->grab_x + resize->width;
|
|
|
|
} else {
|
|
|
|
width = resize->width;
|
|
|
|
}
|
|
|
|
|
2011-11-25 14:09:16 +04:00
|
|
|
if (resize->edges & WL_SHELL_SURFACE_RESIZE_TOP) {
|
2011-01-18 15:53:49 +03:00
|
|
|
height = device->grab_y - y + resize->height;
|
2011-11-25 14:09:16 +04:00
|
|
|
} else if (resize->edges & WL_SHELL_SURFACE_RESIZE_BOTTOM) {
|
2011-01-18 15:53:49 +03:00
|
|
|
height = y - device->grab_y + resize->height;
|
|
|
|
} else {
|
|
|
|
height = resize->height;
|
|
|
|
}
|
|
|
|
|
2011-11-25 14:09:16 +04:00
|
|
|
wl_resource_post_event(&resize->shsurf->resource,
|
|
|
|
WL_SHELL_SURFACE_CONFIGURE, time, resize->edges,
|
|
|
|
width, height);
|
2011-01-18 15:53:49 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
resize_grab_button(struct wl_grab *grab,
|
|
|
|
uint32_t time, int32_t button, int32_t state)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
resize_grab_end(struct wl_grab *grab, uint32_t time)
|
|
|
|
{
|
|
|
|
free(grab);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct wl_grab_interface resize_grab_interface = {
|
|
|
|
resize_grab_motion,
|
|
|
|
resize_grab_button,
|
|
|
|
resize_grab_end
|
|
|
|
};
|
|
|
|
|
2011-08-27 01:21:20 +04:00
|
|
|
static int
|
2011-11-25 14:09:16 +04:00
|
|
|
wlsc_surface_resize(struct shell_surface *shsurf,
|
2011-08-27 01:21:20 +04:00
|
|
|
struct wlsc_input_device *wd,
|
2011-11-25 14:09:16 +04:00
|
|
|
uint32_t time, uint32_t edges)
|
2011-01-18 15:53:49 +03:00
|
|
|
{
|
|
|
|
struct wlsc_resize_grab *resize;
|
2011-11-25 14:09:16 +04:00
|
|
|
struct wlsc_surface *es = shsurf->surface;
|
2011-01-18 15:53:49 +03:00
|
|
|
enum wlsc_pointer_type pointer = WLSC_POINTER_LEFT_PTR;
|
|
|
|
|
2011-01-28 23:18:33 +03:00
|
|
|
/* FIXME: Reject if fullscreen */
|
|
|
|
|
2011-01-18 15:53:49 +03:00
|
|
|
resize = malloc(sizeof *resize);
|
2011-08-27 01:21:20 +04:00
|
|
|
if (!resize)
|
|
|
|
return -1;
|
2011-01-18 15:53:49 +03:00
|
|
|
|
|
|
|
resize->grab.interface = &resize_grab_interface;
|
|
|
|
resize->edges = edges;
|
|
|
|
resize->dx = es->x - wd->input_device.grab_x;
|
|
|
|
resize->dy = es->y - wd->input_device.grab_y;
|
|
|
|
resize->width = es->width;
|
|
|
|
resize->height = es->height;
|
2011-11-25 14:09:16 +04:00
|
|
|
resize->shsurf = shsurf;
|
2011-08-19 01:55:30 +04:00
|
|
|
|
2011-01-18 15:53:49 +03:00
|
|
|
if (edges == 0 || edges > 15 ||
|
|
|
|
(edges & 3) == 3 || (edges & 12) == 12)
|
2011-08-27 01:21:20 +04:00
|
|
|
return 0;
|
2011-01-18 15:53:49 +03:00
|
|
|
|
|
|
|
switch (edges) {
|
2011-11-25 14:09:16 +04:00
|
|
|
case WL_SHELL_SURFACE_RESIZE_TOP:
|
2011-01-18 15:53:49 +03:00
|
|
|
pointer = WLSC_POINTER_TOP;
|
|
|
|
break;
|
2011-11-25 14:09:16 +04:00
|
|
|
case WL_SHELL_SURFACE_RESIZE_BOTTOM:
|
2011-01-18 15:53:49 +03:00
|
|
|
pointer = WLSC_POINTER_BOTTOM;
|
|
|
|
break;
|
2011-11-25 14:09:16 +04:00
|
|
|
case WL_SHELL_SURFACE_RESIZE_LEFT:
|
2011-01-18 15:53:49 +03:00
|
|
|
pointer = WLSC_POINTER_LEFT;
|
|
|
|
break;
|
2011-11-25 14:09:16 +04:00
|
|
|
case WL_SHELL_SURFACE_RESIZE_TOP_LEFT:
|
2011-01-18 15:53:49 +03:00
|
|
|
pointer = WLSC_POINTER_TOP_LEFT;
|
|
|
|
break;
|
2011-11-25 14:09:16 +04:00
|
|
|
case WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT:
|
2011-01-18 15:53:49 +03:00
|
|
|
pointer = WLSC_POINTER_BOTTOM_LEFT;
|
|
|
|
break;
|
2011-11-25 14:09:16 +04:00
|
|
|
case WL_SHELL_SURFACE_RESIZE_RIGHT:
|
2011-01-18 15:53:49 +03:00
|
|
|
pointer = WLSC_POINTER_RIGHT;
|
|
|
|
break;
|
2011-11-25 14:09:16 +04:00
|
|
|
case WL_SHELL_SURFACE_RESIZE_TOP_RIGHT:
|
2011-01-18 15:53:49 +03:00
|
|
|
pointer = WLSC_POINTER_TOP_RIGHT;
|
|
|
|
break;
|
2011-11-25 14:09:16 +04:00
|
|
|
case WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT:
|
2011-01-18 15:53:49 +03:00
|
|
|
pointer = WLSC_POINTER_BOTTOM_RIGHT;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (wl_input_device_update_grab(&wd->input_device,
|
2011-08-27 01:21:20 +04:00
|
|
|
&resize->grab, &es->surface, time) < 0)
|
|
|
|
return 0;
|
2011-01-18 15:53:49 +03:00
|
|
|
|
|
|
|
wlsc_input_device_set_pointer_image(wd, pointer);
|
2011-08-27 01:21:20 +04:00
|
|
|
wl_input_device_set_pointer_focus(&wd->input_device,
|
|
|
|
NULL, time, 0, 0, 0, 0);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2011-11-25 14:09:16 +04:00
|
|
|
shell_surface_resize(struct wl_client *client, struct wl_resource *resource,
|
|
|
|
struct wl_resource *input_resource, uint32_t time,
|
|
|
|
uint32_t edges)
|
2011-08-27 01:21:20 +04:00
|
|
|
{
|
|
|
|
struct wlsc_input_device *wd = input_resource->data;
|
2011-11-25 14:09:16 +04:00
|
|
|
struct shell_surface *shsurf = resource->data;
|
2011-08-27 01:21:20 +04:00
|
|
|
|
|
|
|
/* FIXME: Reject if fullscreen */
|
|
|
|
|
2011-11-25 14:09:16 +04:00
|
|
|
if (wlsc_surface_resize(shsurf, wd, time, edges) < 0)
|
2011-09-01 17:54:57 +04:00
|
|
|
wl_resource_post_no_memory(resource);
|
2011-01-18 15:53:49 +03:00
|
|
|
}
|
|
|
|
|
2011-12-01 12:42:22 +04:00
|
|
|
static int
|
|
|
|
reset_shell_surface_type(struct shell_surface *surface)
|
|
|
|
{
|
|
|
|
switch (surface->type) {
|
|
|
|
case SHELL_SURFACE_FULLSCREEN:
|
|
|
|
surface->surface->x = surface->saved_x;
|
|
|
|
surface->surface->y = surface->saved_y;
|
|
|
|
surface->surface->fullscreen_output = NULL;
|
|
|
|
break;
|
|
|
|
case SHELL_SURFACE_PANEL:
|
|
|
|
case SHELL_SURFACE_BACKGROUND:
|
|
|
|
wl_list_remove(&surface->link);
|
|
|
|
wl_list_init(&surface->link);
|
|
|
|
break;
|
2011-11-30 18:26:35 +04:00
|
|
|
case SHELL_SURFACE_SCREENSAVER:
|
2011-12-01 12:42:22 +04:00
|
|
|
case SHELL_SURFACE_LOCK:
|
|
|
|
wl_resource_post_error(&surface->resource,
|
|
|
|
WL_DISPLAY_ERROR_INVALID_METHOD,
|
2011-11-30 18:26:35 +04:00
|
|
|
"cannot reassign surface type");
|
2011-12-01 12:42:22 +04:00
|
|
|
return -1;
|
|
|
|
case SHELL_SURFACE_NONE:
|
|
|
|
case SHELL_SURFACE_TOPLEVEL:
|
|
|
|
case SHELL_SURFACE_TRANSIENT:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
surface->type = SHELL_SURFACE_NONE;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-06-18 14:12:54 +04:00
|
|
|
static void
|
2011-11-25 14:09:16 +04:00
|
|
|
shell_surface_set_toplevel(struct wl_client *client,
|
|
|
|
struct wl_resource *resource)
|
2011-06-18 14:12:54 +04:00
|
|
|
|
|
|
|
{
|
2011-12-01 12:42:22 +04:00
|
|
|
struct shell_surface *surface = resource->data;
|
2011-06-18 14:12:54 +04:00
|
|
|
|
2011-12-01 12:42:22 +04:00
|
|
|
if (reset_shell_surface_type(surface))
|
|
|
|
return;
|
2011-06-18 14:12:54 +04:00
|
|
|
|
2011-12-01 12:42:22 +04:00
|
|
|
wlsc_surface_damage(surface->surface);
|
|
|
|
surface->type = SHELL_SURFACE_TOPLEVEL;
|
2011-06-18 14:12:54 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2011-11-25 14:09:16 +04:00
|
|
|
shell_surface_set_transient(struct wl_client *client,
|
|
|
|
struct wl_resource *resource,
|
|
|
|
struct wl_resource *parent_resource,
|
|
|
|
int x, int y, uint32_t flags)
|
2011-06-18 14:12:54 +04:00
|
|
|
{
|
2011-11-25 14:09:16 +04:00
|
|
|
struct shell_surface *shsurf = resource->data;
|
|
|
|
struct wlsc_surface *es = shsurf->surface;
|
2011-12-08 18:42:33 +04:00
|
|
|
struct shell_surface *pshsurf = parent_resource->data;
|
|
|
|
struct wlsc_surface *pes = pshsurf->surface;
|
2011-06-18 14:12:54 +04:00
|
|
|
|
2011-12-01 12:42:22 +04:00
|
|
|
if (reset_shell_surface_type(shsurf))
|
|
|
|
return;
|
|
|
|
|
2011-06-18 14:12:54 +04:00
|
|
|
/* assign to parents output */
|
|
|
|
es->output = pes->output;
|
|
|
|
|
|
|
|
es->x = pes->x + x;
|
|
|
|
es->y = pes->y + y;
|
|
|
|
|
|
|
|
wlsc_surface_damage(es);
|
2011-11-25 14:09:16 +04:00
|
|
|
shsurf->type = SHELL_SURFACE_TRANSIENT;
|
2011-06-18 14:12:54 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2011-11-25 14:09:16 +04:00
|
|
|
shell_surface_set_fullscreen(struct wl_client *client,
|
|
|
|
struct wl_resource *resource)
|
2011-06-18 14:12:54 +04:00
|
|
|
|
|
|
|
{
|
2011-11-25 14:09:16 +04:00
|
|
|
struct shell_surface *shsurf = resource->data;
|
|
|
|
struct wlsc_surface *es = shsurf->surface;
|
2011-06-18 14:12:54 +04:00
|
|
|
struct wlsc_output *output;
|
|
|
|
|
2011-12-01 12:42:22 +04:00
|
|
|
if (reset_shell_surface_type(shsurf))
|
|
|
|
return;
|
|
|
|
|
2011-06-18 14:12:54 +04:00
|
|
|
/* FIXME: Fullscreen on first output */
|
|
|
|
/* FIXME: Handle output going away */
|
|
|
|
output = container_of(es->compositor->output_list.next,
|
|
|
|
struct wlsc_output, link);
|
|
|
|
es->output = output;
|
|
|
|
|
2011-11-25 14:09:16 +04:00
|
|
|
shsurf->saved_x = es->x;
|
|
|
|
shsurf->saved_y = es->y;
|
2011-06-21 19:16:58 +04:00
|
|
|
es->x = (output->current->width - es->width) / 2;
|
|
|
|
es->y = (output->current->height - es->height) / 2;
|
2011-06-18 14:12:54 +04:00
|
|
|
es->fullscreen_output = output;
|
|
|
|
wlsc_surface_damage(es);
|
2011-11-25 14:09:16 +04:00
|
|
|
shsurf->type = SHELL_SURFACE_FULLSCREEN;
|
2011-06-18 14:12:54 +04:00
|
|
|
}
|
|
|
|
|
2011-11-25 14:09:16 +04:00
|
|
|
static const struct wl_shell_surface_interface shell_surface_implementation = {
|
|
|
|
shell_surface_move,
|
|
|
|
shell_surface_resize,
|
|
|
|
shell_surface_set_toplevel,
|
|
|
|
shell_surface_set_transient,
|
|
|
|
shell_surface_set_fullscreen
|
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
destroy_shell_surface(struct wl_resource *resource)
|
|
|
|
{
|
|
|
|
struct shell_surface *shsurf = resource->data;
|
|
|
|
|
|
|
|
/* in case cleaning up a dead client destroys shell_surface first */
|
|
|
|
if (shsurf->surface)
|
|
|
|
wl_list_remove(&shsurf->surface_destroy_listener.link);
|
|
|
|
|
|
|
|
wl_list_remove(&shsurf->link);
|
|
|
|
free(shsurf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
shell_handle_surface_destroy(struct wl_listener *listener,
|
|
|
|
struct wl_resource *resource, uint32_t time)
|
|
|
|
{
|
|
|
|
struct shell_surface *shsurf = container_of(listener,
|
|
|
|
struct shell_surface,
|
|
|
|
surface_destroy_listener);
|
|
|
|
|
|
|
|
shsurf->surface = NULL;
|
|
|
|
wl_resource_destroy(&shsurf->resource, time);
|
|
|
|
}
|
|
|
|
|
2011-11-28 17:12:34 +04:00
|
|
|
static struct shell_surface *
|
|
|
|
get_shell_surface(struct wlsc_surface *surface)
|
|
|
|
{
|
|
|
|
struct wl_list *lst = &surface->surface.resource.destroy_listener_list;
|
|
|
|
struct wl_listener *listener;
|
|
|
|
|
|
|
|
/* search the destroy listener list for our callback */
|
|
|
|
wl_list_for_each(listener, lst, link) {
|
|
|
|
if (listener->func == shell_handle_surface_destroy) {
|
|
|
|
return container_of(listener, struct shell_surface,
|
|
|
|
surface_destroy_listener);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-11-25 14:09:16 +04:00
|
|
|
static void
|
2011-11-29 17:49:31 +04:00
|
|
|
shell_get_shell_surface(struct wl_client *client,
|
|
|
|
struct wl_resource *resource,
|
|
|
|
uint32_t id,
|
|
|
|
struct wl_resource *surface_resource)
|
2011-11-25 14:09:16 +04:00
|
|
|
{
|
|
|
|
struct wlsc_surface *surface = surface_resource->data;
|
|
|
|
struct shell_surface *shsurf;
|
|
|
|
|
2011-11-29 18:05:28 +04:00
|
|
|
if (get_shell_surface(surface)) {
|
|
|
|
wl_resource_post_error(surface_resource,
|
|
|
|
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
|
|
|
"wl_shell::get_shell_surface already requested");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-11-25 14:09:16 +04:00
|
|
|
shsurf = calloc(1, sizeof *shsurf);
|
|
|
|
if (!shsurf) {
|
|
|
|
wl_resource_post_no_memory(resource);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
shsurf->resource.destroy = destroy_shell_surface;
|
|
|
|
shsurf->resource.object.id = id;
|
|
|
|
shsurf->resource.object.interface = &wl_shell_surface_interface;
|
|
|
|
shsurf->resource.object.implementation =
|
|
|
|
(void (**)(void)) &shell_surface_implementation;
|
|
|
|
shsurf->resource.data = shsurf;
|
|
|
|
|
|
|
|
shsurf->surface = surface;
|
|
|
|
shsurf->surface_destroy_listener.func = shell_handle_surface_destroy;
|
|
|
|
wl_list_insert(surface->surface.resource.destroy_listener_list.prev,
|
|
|
|
&shsurf->surface_destroy_listener.link);
|
|
|
|
|
|
|
|
/* init link so its safe to always remove it in destroy_shell_surface */
|
|
|
|
wl_list_init(&shsurf->link);
|
|
|
|
|
2011-12-01 12:42:22 +04:00
|
|
|
shsurf->type = SHELL_SURFACE_NONE;
|
2011-11-25 14:09:16 +04:00
|
|
|
|
|
|
|
wl_client_add_resource(client, &shsurf->resource);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct wl_shell_interface shell_implementation = {
|
2011-11-29 17:49:31 +04:00
|
|
|
shell_get_shell_surface
|
2011-01-18 15:53:49 +03:00
|
|
|
};
|
|
|
|
|
2011-11-30 18:26:35 +04:00
|
|
|
static void
|
|
|
|
launch_screensaver(struct wl_shell *shell)
|
|
|
|
{
|
|
|
|
if (shell->screensaver.binding)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* TODO: exec() the screensaver process */
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
terminate_screensaver(struct wl_shell *shell)
|
|
|
|
{
|
|
|
|
/* TODO */
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
show_screensaver(struct wl_shell *shell, struct shell_surface *surface)
|
|
|
|
{
|
|
|
|
struct wl_list *list;
|
|
|
|
|
|
|
|
if (shell->lock_surface)
|
|
|
|
list = &shell->lock_surface->surface->link;
|
|
|
|
else
|
|
|
|
list = &shell->compositor->surface_list;
|
|
|
|
|
|
|
|
wl_list_remove(&surface->surface->link);
|
|
|
|
wl_list_insert(list, &surface->surface->link);
|
|
|
|
wlsc_surface_configure(surface->surface,
|
|
|
|
surface->surface->x,
|
|
|
|
surface->surface->y,
|
|
|
|
surface->surface->width,
|
|
|
|
surface->surface->height);
|
|
|
|
surface->surface->output = surface->output;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
hide_screensaver(struct wl_shell *shell, struct shell_surface *surface)
|
|
|
|
{
|
|
|
|
wl_list_remove(&surface->surface->link);
|
|
|
|
wl_list_init(&surface->surface->link);
|
|
|
|
surface->surface->output = NULL;
|
|
|
|
}
|
|
|
|
|
2011-09-06 21:48:16 +04:00
|
|
|
static void
|
|
|
|
desktop_shell_set_background(struct wl_client *client,
|
|
|
|
struct wl_resource *resource,
|
2011-11-22 15:43:52 +04:00
|
|
|
struct wl_resource *output_resource,
|
2011-09-06 21:48:16 +04:00
|
|
|
struct wl_resource *surface_resource)
|
|
|
|
{
|
|
|
|
struct wl_shell *shell = resource->data;
|
2011-11-28 16:11:15 +04:00
|
|
|
struct shell_surface *shsurf = surface_resource->data;
|
|
|
|
struct wlsc_surface *surface = shsurf->surface;
|
2011-11-23 18:42:16 +04:00
|
|
|
struct shell_surface *priv;
|
2011-09-06 21:48:16 +04:00
|
|
|
|
2011-12-01 12:42:22 +04:00
|
|
|
if (reset_shell_surface_type(shsurf))
|
|
|
|
return;
|
|
|
|
|
2011-11-23 23:46:40 +04:00
|
|
|
wl_list_for_each(priv, &shell->backgrounds, link) {
|
|
|
|
if (priv->output == output_resource->data) {
|
|
|
|
priv->surface->output = NULL;
|
|
|
|
wl_list_remove(&priv->surface->link);
|
|
|
|
wl_list_remove(&priv->link);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-11-28 16:11:15 +04:00
|
|
|
shsurf->type = SHELL_SURFACE_BACKGROUND;
|
|
|
|
shsurf->output = output_resource->data;
|
2011-11-22 15:43:52 +04:00
|
|
|
|
2011-11-28 16:11:15 +04:00
|
|
|
wl_list_insert(&shell->backgrounds, &shsurf->link);
|
2011-11-22 15:43:52 +04:00
|
|
|
|
2011-11-28 16:11:15 +04:00
|
|
|
surface->x = shsurf->output->x;
|
|
|
|
surface->y = shsurf->output->y;
|
2011-11-23 18:42:16 +04:00
|
|
|
|
2011-09-06 21:48:16 +04:00
|
|
|
wl_resource_post_event(resource,
|
|
|
|
DESKTOP_SHELL_CONFIGURE,
|
2011-11-28 16:11:15 +04:00
|
|
|
wlsc_compositor_get_time(), 0, surface_resource,
|
|
|
|
shsurf->output->current->width,
|
|
|
|
shsurf->output->current->height);
|
2011-09-06 21:48:16 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
desktop_shell_set_panel(struct wl_client *client,
|
|
|
|
struct wl_resource *resource,
|
2011-11-22 15:43:52 +04:00
|
|
|
struct wl_resource *output_resource,
|
2011-09-06 21:48:16 +04:00
|
|
|
struct wl_resource *surface_resource)
|
|
|
|
{
|
|
|
|
struct wl_shell *shell = resource->data;
|
2011-11-28 16:11:15 +04:00
|
|
|
struct shell_surface *shsurf = surface_resource->data;
|
|
|
|
struct wlsc_surface *surface = shsurf->surface;
|
2011-11-23 18:42:16 +04:00
|
|
|
struct shell_surface *priv;
|
2011-09-06 21:48:16 +04:00
|
|
|
|
2011-12-01 12:42:22 +04:00
|
|
|
if (reset_shell_surface_type(shsurf))
|
|
|
|
return;
|
|
|
|
|
2011-11-23 23:46:40 +04:00
|
|
|
wl_list_for_each(priv, &shell->panels, link) {
|
|
|
|
if (priv->output == output_resource->data) {
|
|
|
|
priv->surface->output = NULL;
|
|
|
|
wl_list_remove(&priv->surface->link);
|
|
|
|
wl_list_remove(&priv->link);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-11-28 16:11:15 +04:00
|
|
|
shsurf->type = SHELL_SURFACE_PANEL;
|
|
|
|
shsurf->output = output_resource->data;
|
2011-09-06 21:48:16 +04:00
|
|
|
|
2011-11-28 16:11:15 +04:00
|
|
|
wl_list_insert(&shell->panels, &shsurf->link);
|
2011-09-06 21:48:16 +04:00
|
|
|
|
2011-11-28 16:11:15 +04:00
|
|
|
surface->x = shsurf->output->x;
|
|
|
|
surface->y = shsurf->output->y;
|
2011-11-23 18:42:16 +04:00
|
|
|
|
2011-09-06 21:48:16 +04:00
|
|
|
wl_resource_post_event(resource,
|
|
|
|
DESKTOP_SHELL_CONFIGURE,
|
|
|
|
wlsc_compositor_get_time(), 0, surface_resource,
|
2011-11-28 16:11:15 +04:00
|
|
|
shsurf->output->current->width,
|
|
|
|
shsurf->output->current->height);
|
2011-09-06 21:48:16 +04:00
|
|
|
}
|
|
|
|
|
2011-11-16 01:39:55 +04:00
|
|
|
static void
|
|
|
|
handle_lock_surface_destroy(struct wl_listener *listener,
|
|
|
|
struct wl_resource *resource, uint32_t time)
|
|
|
|
{
|
|
|
|
struct wl_shell *shell =
|
2011-11-16 15:47:35 +04:00
|
|
|
container_of(listener, struct wl_shell, lock_surface_listener);
|
2011-11-16 01:39:55 +04:00
|
|
|
|
|
|
|
fprintf(stderr, "lock surface gone\n");
|
|
|
|
shell->lock_surface = NULL;
|
|
|
|
}
|
|
|
|
|
desktop-shell: screen locking protocol
Add protocol and functions for supporting screen locking, triggered by
activity timeout.
After activity timeout, compositor starts the fade to black, and then
enters SLEEPING state. At that point it calls lock() in the shell
plugin.
When input events trigger a wakeup, unlock() in the shell plugin is
called. This sends prepare_lock_surface event to the desktop-shell
client. The screen stays locked while the compositor starts fade-in.
At this point, desktop-shell client usually creates a surface for the
unlocking GUI (e.g. a password prompt), and sends it with the
set_lock_surface request. The compositor supposedly shows and allows
interaction only with the given lock surface (not yet implemented).
When desktop-shell has authenticated the user, or instead of issuing
set_lock_surface, it sends the unlock request. Upon receiving the unlock
request, the shell plugin unlocks the screen.
If desktop-shell client dies, the screen is unlocked automatically.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2011-11-15 15:34:48 +04:00
|
|
|
static void
|
|
|
|
desktop_shell_set_lock_surface(struct wl_client *client,
|
|
|
|
struct wl_resource *resource,
|
|
|
|
struct wl_resource *surface_resource)
|
|
|
|
{
|
2011-11-15 15:34:49 +04:00
|
|
|
struct wl_shell *shell = resource->data;
|
2011-12-01 12:42:22 +04:00
|
|
|
struct shell_surface *surface = surface_resource->data;
|
|
|
|
|
|
|
|
if (reset_shell_surface_type(surface))
|
|
|
|
return;
|
2011-11-15 15:34:54 +04:00
|
|
|
|
|
|
|
shell->prepare_event_sent = false;
|
|
|
|
|
|
|
|
if (!shell->locked)
|
|
|
|
return;
|
2011-11-15 15:34:49 +04:00
|
|
|
|
2011-12-01 12:42:22 +04:00
|
|
|
shell->lock_surface = surface;
|
2011-11-15 15:34:49 +04:00
|
|
|
|
2011-11-16 01:39:55 +04:00
|
|
|
shell->lock_surface_listener.func = handle_lock_surface_destroy;
|
|
|
|
wl_list_insert(&surface_resource->destroy_listener_list,
|
|
|
|
&shell->lock_surface_listener.link);
|
2011-11-23 18:42:16 +04:00
|
|
|
|
2011-11-28 16:11:15 +04:00
|
|
|
shell->lock_surface->type = SHELL_SURFACE_LOCK;
|
2011-11-15 15:34:54 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
resume_desktop(struct wl_shell *shell)
|
|
|
|
{
|
2011-11-16 01:39:55 +04:00
|
|
|
struct wlsc_surface *surface;
|
2011-11-25 18:07:52 +04:00
|
|
|
struct wl_list *list;
|
2011-11-30 18:26:35 +04:00
|
|
|
struct shell_surface *tmp;
|
|
|
|
|
|
|
|
wl_list_for_each(tmp, &shell->screensaver.surfaces, link)
|
|
|
|
hide_screensaver(shell, tmp);
|
|
|
|
|
|
|
|
terminate_screensaver(shell);
|
2011-11-15 15:34:54 +04:00
|
|
|
|
2011-11-16 01:39:55 +04:00
|
|
|
wl_list_for_each(surface, &shell->hidden_surface_list, link)
|
|
|
|
wlsc_surface_configure(surface, surface->x, surface->y,
|
|
|
|
surface->width, surface->height);
|
|
|
|
|
2011-11-25 18:07:52 +04:00
|
|
|
if (wl_list_empty(&shell->backgrounds)) {
|
|
|
|
list = &shell->compositor->surface_list;
|
|
|
|
} else {
|
|
|
|
struct shell_surface *background;
|
|
|
|
background = container_of(shell->backgrounds.prev,
|
|
|
|
struct shell_surface, link);
|
|
|
|
list = background->surface->link.prev;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!wl_list_empty(&shell->hidden_surface_list))
|
|
|
|
wl_list_insert_list(list, &shell->hidden_surface_list);
|
2011-11-16 01:39:55 +04:00
|
|
|
wl_list_init(&shell->hidden_surface_list);
|
2011-11-15 15:34:54 +04:00
|
|
|
|
|
|
|
shell->locked = false;
|
|
|
|
wlsc_compositor_repick(shell->compositor);
|
2011-11-15 15:34:49 +04:00
|
|
|
wlsc_compositor_wake(shell->compositor);
|
desktop-shell: screen locking protocol
Add protocol and functions for supporting screen locking, triggered by
activity timeout.
After activity timeout, compositor starts the fade to black, and then
enters SLEEPING state. At that point it calls lock() in the shell
plugin.
When input events trigger a wakeup, unlock() in the shell plugin is
called. This sends prepare_lock_surface event to the desktop-shell
client. The screen stays locked while the compositor starts fade-in.
At this point, desktop-shell client usually creates a surface for the
unlocking GUI (e.g. a password prompt), and sends it with the
set_lock_surface request. The compositor supposedly shows and allows
interaction only with the given lock surface (not yet implemented).
When desktop-shell has authenticated the user, or instead of issuing
set_lock_surface, it sends the unlock request. Upon receiving the unlock
request, the shell plugin unlocks the screen.
If desktop-shell client dies, the screen is unlocked automatically.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2011-11-15 15:34:48 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
desktop_shell_unlock(struct wl_client *client,
|
|
|
|
struct wl_resource *resource)
|
|
|
|
{
|
|
|
|
struct wl_shell *shell = resource->data;
|
|
|
|
|
|
|
|
shell->prepare_event_sent = false;
|
2011-11-15 15:34:54 +04:00
|
|
|
|
|
|
|
if (shell->locked)
|
|
|
|
resume_desktop(shell);
|
desktop-shell: screen locking protocol
Add protocol and functions for supporting screen locking, triggered by
activity timeout.
After activity timeout, compositor starts the fade to black, and then
enters SLEEPING state. At that point it calls lock() in the shell
plugin.
When input events trigger a wakeup, unlock() in the shell plugin is
called. This sends prepare_lock_surface event to the desktop-shell
client. The screen stays locked while the compositor starts fade-in.
At this point, desktop-shell client usually creates a surface for the
unlocking GUI (e.g. a password prompt), and sends it with the
set_lock_surface request. The compositor supposedly shows and allows
interaction only with the given lock surface (not yet implemented).
When desktop-shell has authenticated the user, or instead of issuing
set_lock_surface, it sends the unlock request. Upon receiving the unlock
request, the shell plugin unlocks the screen.
If desktop-shell client dies, the screen is unlocked automatically.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2011-11-15 15:34:48 +04:00
|
|
|
}
|
|
|
|
|
2011-09-06 21:48:16 +04:00
|
|
|
static const struct desktop_shell_interface desktop_shell_implementation = {
|
|
|
|
desktop_shell_set_background,
|
desktop-shell: screen locking protocol
Add protocol and functions for supporting screen locking, triggered by
activity timeout.
After activity timeout, compositor starts the fade to black, and then
enters SLEEPING state. At that point it calls lock() in the shell
plugin.
When input events trigger a wakeup, unlock() in the shell plugin is
called. This sends prepare_lock_surface event to the desktop-shell
client. The screen stays locked while the compositor starts fade-in.
At this point, desktop-shell client usually creates a surface for the
unlocking GUI (e.g. a password prompt), and sends it with the
set_lock_surface request. The compositor supposedly shows and allows
interaction only with the given lock surface (not yet implemented).
When desktop-shell has authenticated the user, or instead of issuing
set_lock_surface, it sends the unlock request. Upon receiving the unlock
request, the shell plugin unlocks the screen.
If desktop-shell client dies, the screen is unlocked automatically.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2011-11-15 15:34:48 +04:00
|
|
|
desktop_shell_set_panel,
|
|
|
|
desktop_shell_set_lock_surface,
|
|
|
|
desktop_shell_unlock
|
2011-09-06 21:48:16 +04:00
|
|
|
};
|
|
|
|
|
2011-11-28 17:34:13 +04:00
|
|
|
static enum shell_surface_type
|
|
|
|
get_shell_surface_type(struct wlsc_surface *surface)
|
|
|
|
{
|
|
|
|
struct shell_surface *shsurf;
|
|
|
|
|
|
|
|
shsurf = get_shell_surface(surface);
|
|
|
|
if (!shsurf)
|
2011-12-01 12:42:22 +04:00
|
|
|
return SHELL_SURFACE_NONE;
|
2011-11-28 17:34:13 +04:00
|
|
|
return shsurf->type;
|
|
|
|
}
|
|
|
|
|
2011-04-13 01:25:42 +04:00
|
|
|
static void
|
|
|
|
move_binding(struct wl_input_device *device, uint32_t time,
|
|
|
|
uint32_t key, uint32_t button, uint32_t state, void *data)
|
|
|
|
{
|
|
|
|
struct wlsc_surface *surface =
|
|
|
|
(struct wlsc_surface *) device->pointer_focus;
|
2011-11-23 19:52:40 +04:00
|
|
|
|
2011-11-22 15:43:52 +04:00
|
|
|
if (surface == NULL)
|
2011-09-06 21:48:16 +04:00
|
|
|
return;
|
2011-04-13 19:52:54 +04:00
|
|
|
|
2011-11-28 17:34:13 +04:00
|
|
|
switch (get_shell_surface_type(surface)) {
|
2011-11-22 15:43:52 +04:00
|
|
|
case SHELL_SURFACE_PANEL:
|
|
|
|
case SHELL_SURFACE_BACKGROUND:
|
|
|
|
case SHELL_SURFACE_FULLSCREEN:
|
2011-11-30 18:26:35 +04:00
|
|
|
case SHELL_SURFACE_SCREENSAVER:
|
2011-11-22 15:43:52 +04:00
|
|
|
return;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2011-08-27 01:21:20 +04:00
|
|
|
wlsc_surface_move(surface, (struct wlsc_input_device *) device, time);
|
2011-04-13 01:25:42 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
resize_binding(struct wl_input_device *device, uint32_t time,
|
|
|
|
uint32_t key, uint32_t button, uint32_t state, void *data)
|
|
|
|
{
|
|
|
|
struct wlsc_surface *surface =
|
|
|
|
(struct wlsc_surface *) device->pointer_focus;
|
|
|
|
uint32_t edges = 0;
|
|
|
|
int32_t x, y;
|
2011-11-25 14:09:16 +04:00
|
|
|
struct shell_surface *shsurf;
|
2011-11-23 19:52:40 +04:00
|
|
|
|
2011-11-22 15:43:52 +04:00
|
|
|
if (surface == NULL)
|
2011-09-06 21:48:16 +04:00
|
|
|
return;
|
2011-11-28 17:34:13 +04:00
|
|
|
|
2011-11-25 14:09:16 +04:00
|
|
|
shsurf = get_shell_surface(surface);
|
2011-11-28 17:34:13 +04:00
|
|
|
if (!shsurf)
|
|
|
|
return;
|
|
|
|
|
2011-11-25 14:09:16 +04:00
|
|
|
switch (shsurf->type) {
|
2011-11-22 15:43:52 +04:00
|
|
|
case SHELL_SURFACE_PANEL:
|
|
|
|
case SHELL_SURFACE_BACKGROUND:
|
|
|
|
case SHELL_SURFACE_FULLSCREEN:
|
2011-11-30 18:26:35 +04:00
|
|
|
case SHELL_SURFACE_SCREENSAVER:
|
2011-11-22 15:43:52 +04:00
|
|
|
return;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2011-04-13 19:52:54 +04:00
|
|
|
|
2011-04-13 01:25:42 +04:00
|
|
|
x = device->grab_x - surface->x;
|
|
|
|
y = device->grab_y - surface->y;
|
|
|
|
|
|
|
|
if (x < surface->width / 3)
|
2011-11-25 14:09:16 +04:00
|
|
|
edges |= WL_SHELL_SURFACE_RESIZE_LEFT;
|
2011-04-13 01:25:42 +04:00
|
|
|
else if (x < 2 * surface->width / 3)
|
|
|
|
edges |= 0;
|
|
|
|
else
|
2011-11-25 14:09:16 +04:00
|
|
|
edges |= WL_SHELL_SURFACE_RESIZE_RIGHT;
|
2011-04-13 01:25:42 +04:00
|
|
|
|
|
|
|
if (y < surface->height / 3)
|
2011-11-25 14:09:16 +04:00
|
|
|
edges |= WL_SHELL_SURFACE_RESIZE_TOP;
|
2011-04-13 01:25:42 +04:00
|
|
|
else if (y < 2 * surface->height / 3)
|
|
|
|
edges |= 0;
|
|
|
|
else
|
2011-11-25 14:09:16 +04:00
|
|
|
edges |= WL_SHELL_SURFACE_RESIZE_BOTTOM;
|
2011-08-27 01:21:20 +04:00
|
|
|
|
2011-11-25 14:09:16 +04:00
|
|
|
wlsc_surface_resize(shsurf, (struct wlsc_input_device *) device,
|
|
|
|
time, edges);
|
2011-04-23 21:04:11 +04:00
|
|
|
}
|
|
|
|
|
2011-09-06 21:48:16 +04:00
|
|
|
static void
|
|
|
|
activate(struct wlsc_shell *base, struct wlsc_surface *es,
|
|
|
|
struct wlsc_input_device *device, uint32_t time)
|
|
|
|
{
|
|
|
|
struct wl_shell *shell = container_of(base, struct wl_shell, shell);
|
|
|
|
struct wlsc_compositor *compositor = shell->compositor;
|
|
|
|
|
|
|
|
wlsc_surface_activate(es, device, time);
|
|
|
|
|
2011-10-12 07:41:17 +04:00
|
|
|
if (compositor->wxs)
|
|
|
|
wlsc_xserver_surface_activate(es);
|
|
|
|
|
2011-11-28 17:34:13 +04:00
|
|
|
switch (get_shell_surface_type(es)) {
|
2011-11-23 18:42:16 +04:00
|
|
|
case SHELL_SURFACE_BACKGROUND:
|
|
|
|
/* put background back to bottom */
|
2011-09-06 21:48:16 +04:00
|
|
|
wl_list_remove(&es->link);
|
|
|
|
wl_list_insert(compositor->surface_list.prev, &es->link);
|
2011-11-23 18:42:16 +04:00
|
|
|
break;
|
|
|
|
case SHELL_SURFACE_PANEL:
|
|
|
|
/* already put on top */
|
|
|
|
break;
|
2011-11-30 18:26:35 +04:00
|
|
|
case SHELL_SURFACE_SCREENSAVER:
|
|
|
|
/* always below lock surface */
|
|
|
|
if (shell->lock_surface) {
|
|
|
|
wl_list_remove(&es->link);
|
|
|
|
wl_list_insert(&shell->lock_surface->surface->link,
|
|
|
|
&es->link);
|
|
|
|
}
|
|
|
|
break;
|
2011-11-23 18:42:16 +04:00
|
|
|
default:
|
2011-11-22 15:43:52 +04:00
|
|
|
if (!shell->locked) {
|
2011-11-23 18:42:16 +04:00
|
|
|
/* bring panel back to top */
|
2011-11-22 15:43:52 +04:00
|
|
|
struct shell_surface *panel;
|
|
|
|
wl_list_for_each(panel, &shell->panels, link) {
|
|
|
|
wl_list_remove(&panel->surface->link);
|
|
|
|
wl_list_insert(&compositor->surface_list,
|
|
|
|
&panel->surface->link);
|
|
|
|
}
|
2011-11-23 18:42:16 +04:00
|
|
|
}
|
2011-09-06 21:48:16 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-04-23 21:04:11 +04:00
|
|
|
static void
|
desktop-shell: screen locking protocol
Add protocol and functions for supporting screen locking, triggered by
activity timeout.
After activity timeout, compositor starts the fade to black, and then
enters SLEEPING state. At that point it calls lock() in the shell
plugin.
When input events trigger a wakeup, unlock() in the shell plugin is
called. This sends prepare_lock_surface event to the desktop-shell
client. The screen stays locked while the compositor starts fade-in.
At this point, desktop-shell client usually creates a surface for the
unlocking GUI (e.g. a password prompt), and sends it with the
set_lock_surface request. The compositor supposedly shows and allows
interaction only with the given lock surface (not yet implemented).
When desktop-shell has authenticated the user, or instead of issuing
set_lock_surface, it sends the unlock request. Upon receiving the unlock
request, the shell plugin unlocks the screen.
If desktop-shell client dies, the screen is unlocked automatically.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2011-11-15 15:34:48 +04:00
|
|
|
lock(struct wlsc_shell *base)
|
2011-04-23 21:04:11 +04:00
|
|
|
{
|
desktop-shell: screen locking protocol
Add protocol and functions for supporting screen locking, triggered by
activity timeout.
After activity timeout, compositor starts the fade to black, and then
enters SLEEPING state. At that point it calls lock() in the shell
plugin.
When input events trigger a wakeup, unlock() in the shell plugin is
called. This sends prepare_lock_surface event to the desktop-shell
client. The screen stays locked while the compositor starts fade-in.
At this point, desktop-shell client usually creates a surface for the
unlocking GUI (e.g. a password prompt), and sends it with the
set_lock_surface request. The compositor supposedly shows and allows
interaction only with the given lock surface (not yet implemented).
When desktop-shell has authenticated the user, or instead of issuing
set_lock_surface, it sends the unlock request. Upon receiving the unlock
request, the shell plugin unlocks the screen.
If desktop-shell client dies, the screen is unlocked automatically.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2011-11-15 15:34:48 +04:00
|
|
|
struct wl_shell *shell = container_of(base, struct wl_shell, shell);
|
2011-11-15 15:34:54 +04:00
|
|
|
struct wl_list *surface_list = &shell->compositor->surface_list;
|
|
|
|
struct wlsc_surface *cur;
|
|
|
|
struct wlsc_surface *tmp;
|
|
|
|
struct wlsc_input_device *device;
|
2011-11-30 18:26:35 +04:00
|
|
|
struct shell_surface *shsurf;
|
2011-11-15 15:34:54 +04:00
|
|
|
uint32_t time;
|
|
|
|
|
|
|
|
if (shell->locked)
|
|
|
|
return;
|
desktop-shell: screen locking protocol
Add protocol and functions for supporting screen locking, triggered by
activity timeout.
After activity timeout, compositor starts the fade to black, and then
enters SLEEPING state. At that point it calls lock() in the shell
plugin.
When input events trigger a wakeup, unlock() in the shell plugin is
called. This sends prepare_lock_surface event to the desktop-shell
client. The screen stays locked while the compositor starts fade-in.
At this point, desktop-shell client usually creates a surface for the
unlocking GUI (e.g. a password prompt), and sends it with the
set_lock_surface request. The compositor supposedly shows and allows
interaction only with the given lock surface (not yet implemented).
When desktop-shell has authenticated the user, or instead of issuing
set_lock_surface, it sends the unlock request. Upon receiving the unlock
request, the shell plugin unlocks the screen.
If desktop-shell client dies, the screen is unlocked automatically.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2011-11-15 15:34:48 +04:00
|
|
|
|
|
|
|
shell->locked = true;
|
2011-11-15 15:34:54 +04:00
|
|
|
|
|
|
|
/* Move all surfaces from compositor's list to our hidden list,
|
|
|
|
* except the background. This way nothing else can show or
|
|
|
|
* receive input events while we are locked. */
|
|
|
|
|
|
|
|
if (!wl_list_empty(&shell->hidden_surface_list)) {
|
|
|
|
fprintf(stderr,
|
|
|
|
"%s: Assertion failed: hidden_surface_list is not empty.\n",
|
|
|
|
__func__);
|
|
|
|
}
|
|
|
|
|
|
|
|
wl_list_for_each_safe(cur, tmp, surface_list, link) {
|
|
|
|
/* skip input device sprites, cur->surface is uninitialised */
|
|
|
|
if (cur->surface.resource.client == NULL)
|
|
|
|
continue;
|
|
|
|
|
2011-11-28 17:34:13 +04:00
|
|
|
if (get_shell_surface_type(cur) == SHELL_SURFACE_BACKGROUND)
|
2011-11-15 15:34:54 +04:00
|
|
|
continue;
|
|
|
|
|
2011-11-16 01:39:55 +04:00
|
|
|
cur->output = NULL;
|
2011-11-15 15:34:54 +04:00
|
|
|
wl_list_remove(&cur->link);
|
2011-11-16 01:39:55 +04:00
|
|
|
wl_list_insert(shell->hidden_surface_list.prev, &cur->link);
|
2011-11-15 15:34:54 +04:00
|
|
|
}
|
|
|
|
|
2011-11-30 18:26:35 +04:00
|
|
|
launch_screensaver(shell);
|
|
|
|
|
|
|
|
wl_list_for_each(shsurf, &shell->screensaver.surfaces, link)
|
|
|
|
show_screensaver(shell, shsurf);
|
|
|
|
|
2011-12-01 18:23:57 +04:00
|
|
|
if (!wl_list_empty(&shell->screensaver.surfaces))
|
|
|
|
wlsc_compositor_wake(shell->compositor);
|
|
|
|
|
2011-11-15 15:34:54 +04:00
|
|
|
/* reset pointer foci */
|
|
|
|
wlsc_compositor_repick(shell->compositor);
|
|
|
|
|
|
|
|
/* reset keyboard foci */
|
|
|
|
time = wlsc_compositor_get_time();
|
|
|
|
wl_list_for_each(device, &shell->compositor->input_device_list, link) {
|
|
|
|
wl_input_device_set_keyboard_focus(&device->input_device,
|
|
|
|
NULL, time);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* TODO: disable bindings that should not work while locked. */
|
|
|
|
|
|
|
|
/* All this must be undone in resume_desktop(). */
|
desktop-shell: screen locking protocol
Add protocol and functions for supporting screen locking, triggered by
activity timeout.
After activity timeout, compositor starts the fade to black, and then
enters SLEEPING state. At that point it calls lock() in the shell
plugin.
When input events trigger a wakeup, unlock() in the shell plugin is
called. This sends prepare_lock_surface event to the desktop-shell
client. The screen stays locked while the compositor starts fade-in.
At this point, desktop-shell client usually creates a surface for the
unlocking GUI (e.g. a password prompt), and sends it with the
set_lock_surface request. The compositor supposedly shows and allows
interaction only with the given lock surface (not yet implemented).
When desktop-shell has authenticated the user, or instead of issuing
set_lock_surface, it sends the unlock request. Upon receiving the unlock
request, the shell plugin unlocks the screen.
If desktop-shell client dies, the screen is unlocked automatically.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2011-11-15 15:34:48 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
unlock(struct wlsc_shell *base)
|
|
|
|
{
|
|
|
|
struct wl_shell *shell = container_of(base, struct wl_shell, shell);
|
|
|
|
|
2011-11-16 15:47:34 +04:00
|
|
|
if (!shell->locked || shell->lock_surface) {
|
desktop-shell: screen locking protocol
Add protocol and functions for supporting screen locking, triggered by
activity timeout.
After activity timeout, compositor starts the fade to black, and then
enters SLEEPING state. At that point it calls lock() in the shell
plugin.
When input events trigger a wakeup, unlock() in the shell plugin is
called. This sends prepare_lock_surface event to the desktop-shell
client. The screen stays locked while the compositor starts fade-in.
At this point, desktop-shell client usually creates a surface for the
unlocking GUI (e.g. a password prompt), and sends it with the
set_lock_surface request. The compositor supposedly shows and allows
interaction only with the given lock surface (not yet implemented).
When desktop-shell has authenticated the user, or instead of issuing
set_lock_surface, it sends the unlock request. Upon receiving the unlock
request, the shell plugin unlocks the screen.
If desktop-shell client dies, the screen is unlocked automatically.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2011-11-15 15:34:48 +04:00
|
|
|
wlsc_compositor_wake(shell->compositor);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If desktop-shell client has gone away, unlock immediately. */
|
|
|
|
if (!shell->child.desktop_shell) {
|
2011-11-15 15:34:54 +04:00
|
|
|
resume_desktop(shell);
|
desktop-shell: screen locking protocol
Add protocol and functions for supporting screen locking, triggered by
activity timeout.
After activity timeout, compositor starts the fade to black, and then
enters SLEEPING state. At that point it calls lock() in the shell
plugin.
When input events trigger a wakeup, unlock() in the shell plugin is
called. This sends prepare_lock_surface event to the desktop-shell
client. The screen stays locked while the compositor starts fade-in.
At this point, desktop-shell client usually creates a surface for the
unlocking GUI (e.g. a password prompt), and sends it with the
set_lock_surface request. The compositor supposedly shows and allows
interaction only with the given lock surface (not yet implemented).
When desktop-shell has authenticated the user, or instead of issuing
set_lock_surface, it sends the unlock request. Upon receiving the unlock
request, the shell plugin unlocks the screen.
If desktop-shell client dies, the screen is unlocked automatically.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2011-11-15 15:34:48 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (shell->prepare_event_sent)
|
|
|
|
return;
|
|
|
|
|
|
|
|
wl_resource_post_event(shell->child.desktop_shell,
|
|
|
|
DESKTOP_SHELL_PREPARE_LOCK_SURFACE);
|
|
|
|
shell->prepare_event_sent = true;
|
2011-04-23 21:04:11 +04:00
|
|
|
}
|
|
|
|
|
2011-11-30 18:26:35 +04:00
|
|
|
static void
|
|
|
|
center_on_output(struct wlsc_surface *surface, struct wlsc_output *output)
|
|
|
|
{
|
|
|
|
struct wlsc_mode *mode = output->current;
|
|
|
|
|
|
|
|
surface->x = output->x + (mode->width - surface->width) / 2;
|
|
|
|
surface->y = output->y + (mode->height - surface->height) / 2;
|
|
|
|
}
|
|
|
|
|
2011-04-23 21:04:11 +04:00
|
|
|
static void
|
2011-11-09 21:07:35 +04:00
|
|
|
map(struct wlsc_shell *base,
|
|
|
|
struct wlsc_surface *surface, int32_t width, int32_t height)
|
2011-04-23 21:04:11 +04:00
|
|
|
{
|
2011-09-06 21:48:16 +04:00
|
|
|
struct wl_shell *shell = container_of(base, struct wl_shell, shell);
|
|
|
|
struct wlsc_compositor *compositor = shell->compositor;
|
2011-11-16 01:39:55 +04:00
|
|
|
struct wl_list *list;
|
2011-11-30 18:26:35 +04:00
|
|
|
struct shell_surface *shsurf;
|
|
|
|
enum shell_surface_type surface_type = SHELL_SURFACE_NONE;
|
|
|
|
int do_configure;
|
2011-11-23 18:42:16 +04:00
|
|
|
|
2011-11-30 18:26:35 +04:00
|
|
|
shsurf = get_shell_surface(surface);
|
|
|
|
if (shsurf)
|
|
|
|
surface_type = shsurf->type;
|
2011-11-16 01:39:55 +04:00
|
|
|
|
2011-11-30 18:26:35 +04:00
|
|
|
if (shell->locked) {
|
2011-11-16 01:39:55 +04:00
|
|
|
list = &shell->hidden_surface_list;
|
2011-11-30 18:26:35 +04:00
|
|
|
do_configure = 0;
|
|
|
|
} else {
|
2011-11-16 01:39:55 +04:00
|
|
|
list = &compositor->surface_list;
|
2011-11-30 18:26:35 +04:00
|
|
|
do_configure = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
surface->width = width;
|
|
|
|
surface->height = height;
|
|
|
|
|
|
|
|
/* initial positioning, see also configure() */
|
|
|
|
switch (surface_type) {
|
|
|
|
case SHELL_SURFACE_TOPLEVEL:
|
|
|
|
surface->x = 10 + random() % 400;
|
|
|
|
surface->y = 10 + random() % 400;
|
|
|
|
break;
|
|
|
|
case SHELL_SURFACE_SCREENSAVER:
|
|
|
|
case SHELL_SURFACE_FULLSCREEN:
|
|
|
|
center_on_output(surface, surface->fullscreen_output);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
;
|
|
|
|
}
|
2011-09-06 21:48:16 +04:00
|
|
|
|
2011-11-16 15:47:33 +04:00
|
|
|
/* surface stacking order, see also activate() */
|
2011-11-28 17:34:13 +04:00
|
|
|
switch (surface_type) {
|
2011-11-23 18:42:16 +04:00
|
|
|
case SHELL_SURFACE_BACKGROUND:
|
2011-11-16 15:47:33 +04:00
|
|
|
/* background always visible, at the bottom */
|
2011-11-09 21:07:35 +04:00
|
|
|
wl_list_insert(compositor->surface_list.prev, &surface->link);
|
2011-11-30 18:26:35 +04:00
|
|
|
do_configure = 1;
|
2011-11-23 18:42:16 +04:00
|
|
|
break;
|
|
|
|
case SHELL_SURFACE_PANEL:
|
2011-11-16 15:47:33 +04:00
|
|
|
/* panel always on top, hidden while locked */
|
2011-11-16 01:39:55 +04:00
|
|
|
wl_list_insert(list, &surface->link);
|
2011-11-23 18:42:16 +04:00
|
|
|
break;
|
|
|
|
case SHELL_SURFACE_LOCK:
|
2011-11-16 15:47:33 +04:00
|
|
|
/* lock surface always visible, on top */
|
2011-11-16 01:39:55 +04:00
|
|
|
wl_list_insert(&compositor->surface_list, &surface->link);
|
2011-11-16 15:47:33 +04:00
|
|
|
|
2011-11-16 01:39:55 +04:00
|
|
|
wlsc_compositor_repick(compositor);
|
2011-11-23 18:42:16 +04:00
|
|
|
wlsc_compositor_wake(compositor);
|
2011-11-30 18:26:35 +04:00
|
|
|
do_configure = 1;
|
|
|
|
break;
|
|
|
|
case SHELL_SURFACE_SCREENSAVER:
|
|
|
|
/* If locked, show it. */
|
2011-12-01 18:23:57 +04:00
|
|
|
if (shell->locked) {
|
2011-11-30 18:26:35 +04:00
|
|
|
show_screensaver(shell, shsurf);
|
2011-12-01 18:23:57 +04:00
|
|
|
wlsc_compositor_wake(compositor);
|
|
|
|
}
|
2011-11-30 18:26:35 +04:00
|
|
|
do_configure = 0;
|
2011-11-23 18:42:16 +04:00
|
|
|
break;
|
|
|
|
default:
|
2011-11-16 15:47:33 +04:00
|
|
|
/* everything else just below the panel */
|
2011-11-22 15:43:52 +04:00
|
|
|
if (!wl_list_empty(&shell->panels)) {
|
|
|
|
struct shell_surface *panel =
|
|
|
|
container_of(shell->panels.prev,
|
|
|
|
struct shell_surface, link);
|
|
|
|
wl_list_insert(&panel->surface->link, &surface->link);
|
|
|
|
} else {
|
2011-11-23 18:42:16 +04:00
|
|
|
wl_list_insert(list, &surface->link);
|
2011-11-22 15:43:52 +04:00
|
|
|
}
|
2011-11-15 15:34:54 +04:00
|
|
|
}
|
|
|
|
|
2011-11-30 18:26:35 +04:00
|
|
|
if (do_configure)
|
2011-11-16 01:39:55 +04:00
|
|
|
wlsc_surface_configure(surface,
|
|
|
|
surface->x, surface->y, width, height);
|
2011-12-05 00:32:59 +04:00
|
|
|
|
|
|
|
if (surface_type == SHELL_SURFACE_TOPLEVEL)
|
|
|
|
wlsc_zoom_run(surface, 0.8, 1.0, NULL, NULL);
|
2011-11-09 21:07:35 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2011-11-30 18:26:35 +04:00
|
|
|
configure(struct wlsc_shell *base, struct wlsc_surface *surface,
|
2011-11-09 21:07:35 +04:00
|
|
|
int32_t x, int32_t y, int32_t width, int32_t height)
|
|
|
|
{
|
2011-11-30 18:26:35 +04:00
|
|
|
struct wl_shell *shell = container_of(base, struct wl_shell, shell);
|
|
|
|
int do_configure = !shell->locked;
|
|
|
|
enum shell_surface_type surface_type = SHELL_SURFACE_NONE;
|
|
|
|
struct shell_surface *shsurf;
|
2011-11-09 21:07:35 +04:00
|
|
|
|
2011-11-30 18:26:35 +04:00
|
|
|
shsurf = get_shell_surface(surface);
|
|
|
|
if (shsurf)
|
|
|
|
surface_type = shsurf->type;
|
|
|
|
|
|
|
|
surface->width = width;
|
|
|
|
surface->height = height;
|
|
|
|
|
|
|
|
switch (surface_type) {
|
|
|
|
case SHELL_SURFACE_SCREENSAVER:
|
|
|
|
do_configure = !do_configure;
|
|
|
|
/* fall through */
|
2011-11-23 19:52:40 +04:00
|
|
|
case SHELL_SURFACE_FULLSCREEN:
|
2011-11-30 18:26:35 +04:00
|
|
|
center_on_output(surface, surface->fullscreen_output);
|
2011-11-23 19:52:40 +04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2011-06-18 14:12:54 +04:00
|
|
|
}
|
2011-11-09 21:07:35 +04:00
|
|
|
|
2011-11-30 18:26:35 +04:00
|
|
|
/*
|
|
|
|
* wlsc_surface_configure() will assign an output, which means
|
|
|
|
* the surface is supposed to be in compositor->surface_list.
|
|
|
|
* Be careful with that, and make sure we stay on the right output.
|
|
|
|
* XXX: would a fullscreen surface need the same handling?
|
|
|
|
*/
|
|
|
|
if (do_configure) {
|
|
|
|
wlsc_surface_configure(surface, x, y, width, height);
|
|
|
|
|
|
|
|
if (surface_type == SHELL_SURFACE_SCREENSAVER)
|
|
|
|
surface->output = shsurf->output;
|
|
|
|
}
|
2011-04-13 01:25:42 +04:00
|
|
|
}
|
|
|
|
|
2011-11-03 16:11:32 +04:00
|
|
|
static void
|
|
|
|
desktop_shell_sigchld(struct wlsc_process *process, int status)
|
|
|
|
{
|
|
|
|
struct wl_shell *shell =
|
|
|
|
container_of(process, struct wl_shell, child.process);
|
|
|
|
|
|
|
|
shell->child.process.pid = 0;
|
|
|
|
shell->child.client = NULL; /* already destroyed by wayland */
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
launch_desktop_shell_process(struct wl_shell *shell)
|
|
|
|
{
|
2011-11-14 23:57:17 +04:00
|
|
|
const char *shell_exe = LIBEXECDIR "/wayland-desktop-shell";
|
2011-11-03 16:11:32 +04:00
|
|
|
|
2011-12-02 17:30:21 +04:00
|
|
|
shell->child.client = wlsc_client_launch(shell->compositor,
|
|
|
|
&shell->child.process,
|
|
|
|
shell_exe,
|
|
|
|
desktop_shell_sigchld);
|
2011-11-03 16:11:32 +04:00
|
|
|
|
2011-12-02 17:30:21 +04:00
|
|
|
if (!shell->child.client)
|
2011-11-03 16:11:32 +04:00
|
|
|
return -1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-08-27 01:21:20 +04:00
|
|
|
static void
|
|
|
|
bind_shell(struct wl_client *client, void *data, uint32_t version, uint32_t id)
|
|
|
|
{
|
|
|
|
struct wl_shell *shell = data;
|
|
|
|
|
|
|
|
wl_client_add_object(client, &wl_shell_interface,
|
2011-11-25 14:09:16 +04:00
|
|
|
&shell_implementation, id, shell);
|
2011-08-27 01:21:20 +04:00
|
|
|
}
|
|
|
|
|
desktop-shell: screen locking protocol
Add protocol and functions for supporting screen locking, triggered by
activity timeout.
After activity timeout, compositor starts the fade to black, and then
enters SLEEPING state. At that point it calls lock() in the shell
plugin.
When input events trigger a wakeup, unlock() in the shell plugin is
called. This sends prepare_lock_surface event to the desktop-shell
client. The screen stays locked while the compositor starts fade-in.
At this point, desktop-shell client usually creates a surface for the
unlocking GUI (e.g. a password prompt), and sends it with the
set_lock_surface request. The compositor supposedly shows and allows
interaction only with the given lock surface (not yet implemented).
When desktop-shell has authenticated the user, or instead of issuing
set_lock_surface, it sends the unlock request. Upon receiving the unlock
request, the shell plugin unlocks the screen.
If desktop-shell client dies, the screen is unlocked automatically.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2011-11-15 15:34:48 +04:00
|
|
|
static void
|
|
|
|
unbind_desktop_shell(struct wl_resource *resource)
|
|
|
|
{
|
|
|
|
struct wl_shell *shell = resource->data;
|
2011-11-16 01:39:55 +04:00
|
|
|
|
|
|
|
if (shell->locked)
|
|
|
|
resume_desktop(shell);
|
|
|
|
|
desktop-shell: screen locking protocol
Add protocol and functions for supporting screen locking, triggered by
activity timeout.
After activity timeout, compositor starts the fade to black, and then
enters SLEEPING state. At that point it calls lock() in the shell
plugin.
When input events trigger a wakeup, unlock() in the shell plugin is
called. This sends prepare_lock_surface event to the desktop-shell
client. The screen stays locked while the compositor starts fade-in.
At this point, desktop-shell client usually creates a surface for the
unlocking GUI (e.g. a password prompt), and sends it with the
set_lock_surface request. The compositor supposedly shows and allows
interaction only with the given lock surface (not yet implemented).
When desktop-shell has authenticated the user, or instead of issuing
set_lock_surface, it sends the unlock request. Upon receiving the unlock
request, the shell plugin unlocks the screen.
If desktop-shell client dies, the screen is unlocked automatically.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2011-11-15 15:34:48 +04:00
|
|
|
shell->child.desktop_shell = NULL;
|
|
|
|
shell->prepare_event_sent = false;
|
|
|
|
free(resource);
|
|
|
|
}
|
|
|
|
|
2011-09-06 21:48:16 +04:00
|
|
|
static void
|
|
|
|
bind_desktop_shell(struct wl_client *client,
|
|
|
|
void *data, uint32_t version, uint32_t id)
|
|
|
|
{
|
|
|
|
struct wl_shell *shell = data;
|
2011-11-03 16:11:33 +04:00
|
|
|
struct wl_resource *resource;
|
|
|
|
|
|
|
|
resource = wl_client_add_object(client, &desktop_shell_interface,
|
|
|
|
&desktop_shell_implementation,
|
|
|
|
id, shell);
|
|
|
|
|
desktop-shell: screen locking protocol
Add protocol and functions for supporting screen locking, triggered by
activity timeout.
After activity timeout, compositor starts the fade to black, and then
enters SLEEPING state. At that point it calls lock() in the shell
plugin.
When input events trigger a wakeup, unlock() in the shell plugin is
called. This sends prepare_lock_surface event to the desktop-shell
client. The screen stays locked while the compositor starts fade-in.
At this point, desktop-shell client usually creates a surface for the
unlocking GUI (e.g. a password prompt), and sends it with the
set_lock_surface request. The compositor supposedly shows and allows
interaction only with the given lock surface (not yet implemented).
When desktop-shell has authenticated the user, or instead of issuing
set_lock_surface, it sends the unlock request. Upon receiving the unlock
request, the shell plugin unlocks the screen.
If desktop-shell client dies, the screen is unlocked automatically.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2011-11-15 15:34:48 +04:00
|
|
|
if (client == shell->child.client) {
|
|
|
|
resource->destroy = unbind_desktop_shell;
|
|
|
|
shell->child.desktop_shell = resource;
|
2011-11-03 16:11:33 +04:00
|
|
|
return;
|
desktop-shell: screen locking protocol
Add protocol and functions for supporting screen locking, triggered by
activity timeout.
After activity timeout, compositor starts the fade to black, and then
enters SLEEPING state. At that point it calls lock() in the shell
plugin.
When input events trigger a wakeup, unlock() in the shell plugin is
called. This sends prepare_lock_surface event to the desktop-shell
client. The screen stays locked while the compositor starts fade-in.
At this point, desktop-shell client usually creates a surface for the
unlocking GUI (e.g. a password prompt), and sends it with the
set_lock_surface request. The compositor supposedly shows and allows
interaction only with the given lock surface (not yet implemented).
When desktop-shell has authenticated the user, or instead of issuing
set_lock_surface, it sends the unlock request. Upon receiving the unlock
request, the shell plugin unlocks the screen.
If desktop-shell client dies, the screen is unlocked automatically.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2011-11-15 15:34:48 +04:00
|
|
|
}
|
2011-09-06 21:48:16 +04:00
|
|
|
|
2011-11-03 16:11:33 +04:00
|
|
|
wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
|
|
|
|
"permission to bind desktop_shell denied");
|
|
|
|
wl_resource_destroy(resource, 0);
|
2011-09-06 21:48:16 +04:00
|
|
|
}
|
|
|
|
|
protocol: add screensaver interface
Add the screensaver interface to the desktop-shell protocol file. Also
add stubs for it in the compositor, and make wscreensaver to bind to the
screensaver interface. Wscreensaver gets a new option --demo to retain
the current behaviour as a regular wayland client.
When a screensaver application starts, it should bind to the screensaver
interface, enumerate all outputs, create a surface per output, and
register those surfaces via screensaver::set_surface request. Then it
continues with the usual animation loop, waiting for frame events. The
compositor will decide, when the given screensaver surfaces are
displayed. A screensaver application should respond to outputs coming
and going away by creating and destroying surfaces.
The compositor is supposed to activate a screensaver by exec'ing it, and
stop the screensaver by killing the client process. Only one client may
be bound to the screensaver interface at a time. If there already is a
client, the compositor could either kill it first, or not exec a new
one.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2011-11-24 13:34:05 +04:00
|
|
|
static void
|
|
|
|
screensaver_set_surface(struct wl_client *client,
|
|
|
|
struct wl_resource *resource,
|
|
|
|
struct wl_resource *shell_surface_resource,
|
|
|
|
struct wl_resource *output_resource)
|
|
|
|
{
|
|
|
|
struct wl_shell *shell = resource->data;
|
|
|
|
struct shell_surface *surface = shell_surface_resource->data;
|
|
|
|
struct wlsc_output *output = output_resource->data;
|
|
|
|
|
2011-12-01 12:42:22 +04:00
|
|
|
if (reset_shell_surface_type(surface))
|
|
|
|
return;
|
|
|
|
|
2011-11-30 18:26:35 +04:00
|
|
|
surface->type = SHELL_SURFACE_SCREENSAVER;
|
|
|
|
|
|
|
|
surface->surface->fullscreen_output = output;
|
|
|
|
surface->output = output;
|
|
|
|
wl_list_insert(shell->screensaver.surfaces.prev, &surface->link);
|
protocol: add screensaver interface
Add the screensaver interface to the desktop-shell protocol file. Also
add stubs for it in the compositor, and make wscreensaver to bind to the
screensaver interface. Wscreensaver gets a new option --demo to retain
the current behaviour as a regular wayland client.
When a screensaver application starts, it should bind to the screensaver
interface, enumerate all outputs, create a surface per output, and
register those surfaces via screensaver::set_surface request. Then it
continues with the usual animation loop, waiting for frame events. The
compositor will decide, when the given screensaver surfaces are
displayed. A screensaver application should respond to outputs coming
and going away by creating and destroying surfaces.
The compositor is supposed to activate a screensaver by exec'ing it, and
stop the screensaver by killing the client process. Only one client may
be bound to the screensaver interface at a time. If there already is a
client, the compositor could either kill it first, or not exec a new
one.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2011-11-24 13:34:05 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static const struct screensaver_interface screensaver_implementation = {
|
|
|
|
screensaver_set_surface
|
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
unbind_screensaver(struct wl_resource *resource)
|
|
|
|
{
|
|
|
|
struct wl_shell *shell = resource->data;
|
|
|
|
|
2011-11-30 18:26:35 +04:00
|
|
|
shell->screensaver.binding = NULL;
|
protocol: add screensaver interface
Add the screensaver interface to the desktop-shell protocol file. Also
add stubs for it in the compositor, and make wscreensaver to bind to the
screensaver interface. Wscreensaver gets a new option --demo to retain
the current behaviour as a regular wayland client.
When a screensaver application starts, it should bind to the screensaver
interface, enumerate all outputs, create a surface per output, and
register those surfaces via screensaver::set_surface request. Then it
continues with the usual animation loop, waiting for frame events. The
compositor will decide, when the given screensaver surfaces are
displayed. A screensaver application should respond to outputs coming
and going away by creating and destroying surfaces.
The compositor is supposed to activate a screensaver by exec'ing it, and
stop the screensaver by killing the client process. Only one client may
be bound to the screensaver interface at a time. If there already is a
client, the compositor could either kill it first, or not exec a new
one.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2011-11-24 13:34:05 +04:00
|
|
|
free(resource);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
bind_screensaver(struct wl_client *client,
|
|
|
|
void *data, uint32_t version, uint32_t id)
|
|
|
|
{
|
|
|
|
struct wl_shell *shell = data;
|
|
|
|
struct wl_resource *resource;
|
|
|
|
|
|
|
|
resource = wl_client_add_object(client, &screensaver_interface,
|
|
|
|
&screensaver_implementation,
|
|
|
|
id, shell);
|
|
|
|
|
2011-11-30 18:26:35 +04:00
|
|
|
if (shell->screensaver.binding == NULL) {
|
protocol: add screensaver interface
Add the screensaver interface to the desktop-shell protocol file. Also
add stubs for it in the compositor, and make wscreensaver to bind to the
screensaver interface. Wscreensaver gets a new option --demo to retain
the current behaviour as a regular wayland client.
When a screensaver application starts, it should bind to the screensaver
interface, enumerate all outputs, create a surface per output, and
register those surfaces via screensaver::set_surface request. Then it
continues with the usual animation loop, waiting for frame events. The
compositor will decide, when the given screensaver surfaces are
displayed. A screensaver application should respond to outputs coming
and going away by creating and destroying surfaces.
The compositor is supposed to activate a screensaver by exec'ing it, and
stop the screensaver by killing the client process. Only one client may
be bound to the screensaver interface at a time. If there already is a
client, the compositor could either kill it first, or not exec a new
one.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2011-11-24 13:34:05 +04:00
|
|
|
resource->destroy = unbind_screensaver;
|
2011-11-30 18:26:35 +04:00
|
|
|
shell->screensaver.binding = resource;
|
protocol: add screensaver interface
Add the screensaver interface to the desktop-shell protocol file. Also
add stubs for it in the compositor, and make wscreensaver to bind to the
screensaver interface. Wscreensaver gets a new option --demo to retain
the current behaviour as a regular wayland client.
When a screensaver application starts, it should bind to the screensaver
interface, enumerate all outputs, create a surface per output, and
register those surfaces via screensaver::set_surface request. Then it
continues with the usual animation loop, waiting for frame events. The
compositor will decide, when the given screensaver surfaces are
displayed. A screensaver application should respond to outputs coming
and going away by creating and destroying surfaces.
The compositor is supposed to activate a screensaver by exec'ing it, and
stop the screensaver by killing the client process. Only one client may
be bound to the screensaver interface at a time. If there already is a
client, the compositor could either kill it first, or not exec a new
one.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2011-11-24 13:34:05 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
|
|
|
|
"interface object already bound");
|
|
|
|
wl_resource_destroy(resource, 0);
|
|
|
|
}
|
|
|
|
|
2011-05-06 22:52:41 +04:00
|
|
|
int
|
|
|
|
shell_init(struct wlsc_compositor *ec);
|
|
|
|
|
2011-05-03 06:09:20 +04:00
|
|
|
WL_EXPORT int
|
|
|
|
shell_init(struct wlsc_compositor *ec)
|
2011-01-18 15:53:49 +03:00
|
|
|
{
|
2011-04-23 21:04:11 +04:00
|
|
|
struct wl_shell *shell;
|
|
|
|
|
|
|
|
shell = malloc(sizeof *shell);
|
|
|
|
if (shell == NULL)
|
|
|
|
return -1;
|
|
|
|
|
2011-10-12 06:44:23 +04:00
|
|
|
memset(shell, 0, sizeof *shell);
|
2011-09-06 21:48:16 +04:00
|
|
|
shell->compositor = ec;
|
|
|
|
shell->shell.activate = activate;
|
2011-04-23 21:04:11 +04:00
|
|
|
shell->shell.lock = lock;
|
desktop-shell: screen locking protocol
Add protocol and functions for supporting screen locking, triggered by
activity timeout.
After activity timeout, compositor starts the fade to black, and then
enters SLEEPING state. At that point it calls lock() in the shell
plugin.
When input events trigger a wakeup, unlock() in the shell plugin is
called. This sends prepare_lock_surface event to the desktop-shell
client. The screen stays locked while the compositor starts fade-in.
At this point, desktop-shell client usually creates a surface for the
unlocking GUI (e.g. a password prompt), and sends it with the
set_lock_surface request. The compositor supposedly shows and allows
interaction only with the given lock surface (not yet implemented).
When desktop-shell has authenticated the user, or instead of issuing
set_lock_surface, it sends the unlock request. Upon receiving the unlock
request, the shell plugin unlocks the screen.
If desktop-shell client dies, the screen is unlocked automatically.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2011-11-15 15:34:48 +04:00
|
|
|
shell->shell.unlock = unlock;
|
2011-11-09 21:07:35 +04:00
|
|
|
shell->shell.map = map;
|
|
|
|
shell->shell.configure = configure;
|
2011-01-18 15:53:49 +03:00
|
|
|
|
2011-11-15 15:34:54 +04:00
|
|
|
wl_list_init(&shell->hidden_surface_list);
|
2011-11-22 15:43:52 +04:00
|
|
|
wl_list_init(&shell->backgrounds);
|
|
|
|
wl_list_init(&shell->panels);
|
2011-11-30 18:26:35 +04:00
|
|
|
wl_list_init(&shell->screensaver.surfaces);
|
2011-11-15 15:34:54 +04:00
|
|
|
|
2011-08-27 01:21:20 +04:00
|
|
|
if (wl_display_add_global(ec->wl_display, &wl_shell_interface,
|
|
|
|
shell, bind_shell) == NULL)
|
2011-01-18 15:53:49 +03:00
|
|
|
return -1;
|
|
|
|
|
2011-09-06 21:48:16 +04:00
|
|
|
if (wl_display_add_global(ec->wl_display,
|
|
|
|
&desktop_shell_interface,
|
|
|
|
shell, bind_desktop_shell) == NULL)
|
|
|
|
return -1;
|
|
|
|
|
protocol: add screensaver interface
Add the screensaver interface to the desktop-shell protocol file. Also
add stubs for it in the compositor, and make wscreensaver to bind to the
screensaver interface. Wscreensaver gets a new option --demo to retain
the current behaviour as a regular wayland client.
When a screensaver application starts, it should bind to the screensaver
interface, enumerate all outputs, create a surface per output, and
register those surfaces via screensaver::set_surface request. Then it
continues with the usual animation loop, waiting for frame events. The
compositor will decide, when the given screensaver surfaces are
displayed. A screensaver application should respond to outputs coming
and going away by creating and destroying surfaces.
The compositor is supposed to activate a screensaver by exec'ing it, and
stop the screensaver by killing the client process. Only one client may
be bound to the screensaver interface at a time. If there already is a
client, the compositor could either kill it first, or not exec a new
one.
Signed-off-by: Pekka Paalanen <ppaalanen@gmail.com>
2011-11-24 13:34:05 +04:00
|
|
|
if (wl_display_add_global(ec->wl_display, &screensaver_interface,
|
|
|
|
shell, bind_screensaver) == NULL)
|
|
|
|
return -1;
|
|
|
|
|
2011-11-03 16:11:32 +04:00
|
|
|
if (launch_desktop_shell_process(shell) != 0)
|
|
|
|
return -1;
|
|
|
|
|
2011-04-13 01:25:42 +04:00
|
|
|
wlsc_compositor_add_binding(ec, 0, BTN_LEFT, MODIFIER_SUPER,
|
2011-04-23 21:04:11 +04:00
|
|
|
move_binding, shell);
|
2011-04-13 01:25:42 +04:00
|
|
|
wlsc_compositor_add_binding(ec, 0, BTN_MIDDLE, MODIFIER_SUPER,
|
2011-04-23 21:04:11 +04:00
|
|
|
resize_binding, shell);
|
|
|
|
|
|
|
|
ec->shell = &shell->shell;
|
2011-04-13 01:25:42 +04:00
|
|
|
|
2011-01-18 15:53:49 +03:00
|
|
|
return 0;
|
|
|
|
}
|