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>
This commit is contained in:
parent
12c05b74ad
commit
6e16811e5e
@ -70,7 +70,12 @@ smoke_LDADD = $(toolkit_libs)
|
||||
resizor_SOURCES = resizor.c
|
||||
resizor_LDADD = $(toolkit_libs)
|
||||
|
||||
wscreensaver_SOURCES = wscreensaver.c wscreensaver-glue.c glmatrix.c
|
||||
wscreensaver_SOURCES = \
|
||||
wscreensaver.c \
|
||||
desktop-shell-client-protocol.h \
|
||||
desktop-shell-protocol.c \
|
||||
wscreensaver-glue.c \
|
||||
glmatrix.c
|
||||
wscreensaver_LDADD = $(toolkit_libs) -lGLU
|
||||
|
||||
eventdemo_SOURCES = eventdemo.c
|
||||
|
@ -20,7 +20,7 @@
|
||||
* OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "../config.h"
|
||||
|
||||
#include "wscreensaver.h"
|
||||
|
||||
@ -34,6 +34,7 @@
|
||||
|
||||
#include <wayland-client.h>
|
||||
|
||||
#include "desktop-shell-client-protocol.h"
|
||||
#include "window.h"
|
||||
|
||||
extern struct wscreensaver_plugin glmatrix_screensaver;
|
||||
@ -45,7 +46,11 @@ static const struct wscreensaver_plugin * const plugins[] = {
|
||||
|
||||
const char *progname = NULL;
|
||||
|
||||
static int demo_mode;
|
||||
|
||||
struct wscreensaver {
|
||||
struct screensaver *interface;
|
||||
|
||||
struct display *display;
|
||||
|
||||
/* per output, if fullscreen mode */
|
||||
@ -246,21 +251,51 @@ init_wscreensaver(struct wscreensaver *wscr, struct display *display)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
global_handler(struct wl_display *display, uint32_t id,
|
||||
const char *interface, uint32_t version, void *data)
|
||||
{
|
||||
struct wscreensaver *screensaver = data;
|
||||
|
||||
if (!strcmp(interface, "screensaver")) {
|
||||
screensaver->interface =
|
||||
wl_display_bind(display, id, &screensaver_interface);
|
||||
}
|
||||
}
|
||||
|
||||
static const GOptionEntry option_entries[] = {
|
||||
{ "demo", 0, 0, G_OPTION_ARG_NONE, &demo_mode,
|
||||
"Run as a regular application, not a screensaver.", NULL },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct display *d;
|
||||
struct wscreensaver wscr = { 0 };
|
||||
struct wscreensaver screensaver = { 0 };
|
||||
const char *msg;
|
||||
|
||||
init_frand();
|
||||
|
||||
d = display_create(&argc, &argv, NULL);
|
||||
d = display_create(&argc, &argv, option_entries);
|
||||
if (d == NULL) {
|
||||
fprintf(stderr, "failed to create display: %m\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
msg = init_wscreensaver(&wscr, d);
|
||||
if (!demo_mode) {
|
||||
wl_display_add_global_listener(display_get_display(d),
|
||||
global_handler, &screensaver);
|
||||
wl_display_roundtrip(display_get_display(d));
|
||||
if (!screensaver.interface) {
|
||||
fprintf(stderr,
|
||||
"Server did not offer screensaver interface,"
|
||||
" exiting.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
msg = init_wscreensaver(&screensaver, d);
|
||||
if (msg) {
|
||||
fprintf(stderr, "wscreensaver init failed: %s\n", msg);
|
||||
return EXIT_FAILURE;
|
||||
|
@ -54,6 +54,8 @@ struct wl_shell {
|
||||
|
||||
struct wl_list backgrounds;
|
||||
struct wl_list panels;
|
||||
|
||||
struct wl_resource *screensaver;
|
||||
};
|
||||
|
||||
enum shell_surface_type {
|
||||
@ -933,6 +935,54 @@ bind_desktop_shell(struct wl_client *client,
|
||||
wl_resource_destroy(resource, 0);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static const struct screensaver_interface screensaver_implementation = {
|
||||
screensaver_set_surface
|
||||
};
|
||||
|
||||
static void
|
||||
unbind_screensaver(struct wl_resource *resource)
|
||||
{
|
||||
struct wl_shell *shell = resource->data;
|
||||
|
||||
shell->screensaver = NULL;
|
||||
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);
|
||||
|
||||
if (shell->screensaver == NULL) {
|
||||
resource->destroy = unbind_screensaver;
|
||||
shell->screensaver = resource;
|
||||
return;
|
||||
}
|
||||
|
||||
wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||
"interface object already bound");
|
||||
wl_resource_destroy(resource, 0);
|
||||
}
|
||||
|
||||
int
|
||||
shell_init(struct wlsc_compositor *ec);
|
||||
|
||||
@ -966,6 +1016,10 @@ shell_init(struct wlsc_compositor *ec)
|
||||
shell, bind_desktop_shell) == NULL)
|
||||
return -1;
|
||||
|
||||
if (wl_display_add_global(ec->wl_display, &screensaver_interface,
|
||||
shell, bind_screensaver) == NULL)
|
||||
return -1;
|
||||
|
||||
if (launch_desktop_shell_process(shell) != 0)
|
||||
return -1;
|
||||
|
||||
|
@ -35,4 +35,17 @@
|
||||
<event name="prepare_lock_surface"/>
|
||||
</interface>
|
||||
|
||||
<!-- Only one client can bind this interface at a time. -->
|
||||
<interface name="screensaver" version="1">
|
||||
|
||||
<!-- Set the surface type as a screensaver for a particular output.
|
||||
A screensaver surface is normally hidden, and only visible after
|
||||
an idle timeout. -->
|
||||
<request name="set_surface">
|
||||
<arg name="surface" type="object" interface="wl_shell_surface"/>
|
||||
<arg name="output" type="object" interface="wl_output"/>
|
||||
</request>
|
||||
|
||||
</interface>
|
||||
|
||||
</protocol>
|
||||
|
Loading…
x
Reference in New Issue
Block a user