|  |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright © 2011 Collabora, Ltd.
 | 
					
						
							|  |  |  |  *
 | 
					
						
							|  |  |  |  * 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.
 | 
					
						
							|  |  |  |  */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												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>
											
										 
											14 years ago
										 |  |  | #include "../config.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "wscreensaver.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #include <sys/time.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <GL/gl.h>
 | 
					
						
							|  |  |  | #include <EGL/eglext.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <wayland-client.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												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>
											
										 
											14 years ago
										 |  |  | #include "desktop-shell-client-protocol.h"
 | 
					
						
							|  |  |  | #include "window.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | extern struct wscreensaver_plugin glmatrix_screensaver;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const struct wscreensaver_plugin * const plugins[] = {
 | 
					
						
							|  |  |  | 	&glmatrix_screensaver,
 | 
					
						
							|  |  |  | 	NULL
 | 
					
						
							|  |  |  | };
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const char *progname = 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>
											
										 
											14 years ago
										 |  |  | static int demo_mode;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct wscreensaver {
 | 
					
						
							| 
									
										
											  
											
												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>
											
										 
											14 years ago
										 |  |  | 	struct screensaver *interface;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	struct display *display;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	struct ModeInfo *demomode;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	struct {
 | 
					
						
							|  |  |  | 		EGLDisplay display;
 | 
					
						
							|  |  |  | 		EGLConfig config;
 | 
					
						
							|  |  |  | 	} egl;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const struct wscreensaver_plugin *plugin;
 | 
					
						
							|  |  |  | };
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void
 | 
					
						
							|  |  |  | frame_callback(void *data, struct wl_callback *callback, uint32_t time)
 | 
					
						
							|  |  |  | {
 | 
					
						
							|  |  |  | 	struct ModeInfo *mi = data;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	window_schedule_redraw(mi->window);
 | 
					
						
							|  |  |  | 	wl_callback_destroy(callback);
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const struct wl_callback_listener listener = {
 | 
					
						
							|  |  |  | 	frame_callback
 | 
					
						
							|  |  |  | };
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void
 | 
					
						
							|  |  |  | redraw_handler(struct widget *widget, void *data)
 | 
					
						
							|  |  |  | {
 | 
					
						
							|  |  |  | 	struct ModeInfo *mi = data;
 | 
					
						
							|  |  |  | 	struct wscreensaver *wscr = mi->priv;
 | 
					
						
							|  |  |  | 	struct rectangle drawarea;
 | 
					
						
							|  |  |  | 	struct rectangle winarea;
 | 
					
						
							|  |  |  | 	struct wl_callback *callback;
 | 
					
						
							|  |  |  | 	int bottom;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mi->swap_buffers = 0;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	widget_get_allocation(mi->widget, &drawarea);
 | 
					
						
							|  |  |  | 	window_get_allocation(mi->window, &winarea);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (display_acquire_window_surface(wscr->display,
 | 
					
						
							|  |  |  | 					   mi->window,
 | 
					
						
							|  |  |  | 					   mi->eglctx) < 0) {
 | 
					
						
							|  |  |  | 		fprintf(stderr, "%s: unable to acquire window surface",
 | 
					
						
							|  |  |  | 			progname);
 | 
					
						
							|  |  |  | 		return;
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bottom = winarea.height - (drawarea.height + drawarea.y);
 | 
					
						
							|  |  |  | 	glViewport(drawarea.x, bottom, drawarea.width, drawarea.height);
 | 
					
						
							|  |  |  | 	glScissor(drawarea.x, bottom, drawarea.width, drawarea.height);
 | 
					
						
							|  |  |  | 	glEnable(GL_SCISSOR_TEST);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (mi->width != drawarea.width || mi->height != drawarea.height) {
 | 
					
						
							|  |  |  | 		mi->width = drawarea.width;
 | 
					
						
							|  |  |  | 		mi->height = drawarea.height;
 | 
					
						
							|  |  |  | 		wscr->plugin->reshape(mi, mi->width, mi->height);
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	wscr->plugin->draw(mi);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (mi->swap_buffers == 0)
 | 
					
						
							|  |  |  | 		fprintf(stderr, "%s: swapBuffers not called\n", progname);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	display_release_window_surface(wscr->display, mi->window);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	callback = wl_surface_frame(window_get_wl_surface(mi->window));
 | 
					
						
							|  |  |  | 	wl_callback_add_listener(callback, &listener, mi);
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void
 | 
					
						
							|  |  |  | init_frand(void)
 | 
					
						
							|  |  |  | {
 | 
					
						
							|  |  |  | 	struct timeval tv;
 | 
					
						
							|  |  |  | 	gettimeofday(&tv, NULL);
 | 
					
						
							|  |  |  | 	srandom(tv.tv_sec * 100 + tv.tv_usec / 10000);
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | WL_EXPORT EGLContext *
 | 
					
						
							|  |  |  | init_GL(struct ModeInfo *mi)
 | 
					
						
							|  |  |  | {
 | 
					
						
							|  |  |  | 	struct wscreensaver *wscr = mi->priv;
 | 
					
						
							|  |  |  | 	EGLContext *pctx;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	pctx = malloc(sizeof *pctx);
 | 
					
						
							|  |  |  | 	if (!pctx)
 | 
					
						
							|  |  |  | 		return NULL;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (mi->eglctx != EGL_NO_CONTEXT) {
 | 
					
						
							|  |  |  | 		fprintf(stderr, "%s: multiple GL contexts are not supported",
 | 
					
						
							|  |  |  | 			progname);
 | 
					
						
							|  |  |  | 		goto errout;
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mi->eglctx = eglCreateContext(wscr->egl.display, wscr->egl.config,
 | 
					
						
							|  |  |  | 				      EGL_NO_CONTEXT, NULL);
 | 
					
						
							|  |  |  | 	if (mi->eglctx == EGL_NO_CONTEXT) {
 | 
					
						
							|  |  |  | 		fprintf(stderr, "%s: init_GL failed to create EGL context\n",
 | 
					
						
							|  |  |  | 			progname);
 | 
					
						
							|  |  |  | 		goto errout;
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!eglMakeCurrent(wscr->egl.display, NULL, NULL, mi->eglctx)) {
 | 
					
						
							|  |  |  | 		fprintf(stderr, "%s: init_GL failed on eglMakeCurrent\n",
 | 
					
						
							|  |  |  | 			progname);
 | 
					
						
							|  |  |  | 		goto errout;
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	glClearColor(0.0, 0.0, 0.0, 1.0);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	*pctx = mi->eglctx;
 | 
					
						
							|  |  |  | 	return pctx;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | errout:
 | 
					
						
							|  |  |  | 	free(pctx);
 | 
					
						
							|  |  |  | 	return NULL;
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct ModeInfo *
 | 
					
						
							|  |  |  | create_wscreensaver_instance(struct wscreensaver *screensaver,
 | 
					
						
							|  |  |  | 			     struct wl_output *output, int width, int height)
 | 
					
						
							|  |  |  | {
 | 
					
						
							|  |  |  | 	static int instance;
 | 
					
						
							|  |  |  | 	struct ModeInfo *mi;
 | 
					
						
							|  |  |  | 	struct rectangle drawarea;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mi = calloc(1, sizeof *mi);
 | 
					
						
							|  |  |  | 	if (!mi)
 | 
					
						
							|  |  |  | 		return NULL;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (demo_mode)
 | 
					
						
							|  |  |  | 		mi->window = window_create(screensaver->display);
 | 
					
						
							|  |  |  | 	else
 | 
					
						
							|  |  |  | 		mi->window = window_create_custom(screensaver->display);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!mi->window) {
 | 
					
						
							|  |  |  | 		fprintf(stderr, "%s: creating a window failed.\n", progname);
 | 
					
						
							|  |  |  | 		free(mi);
 | 
					
						
							|  |  |  | 		return NULL;
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	window_set_title(mi->window, progname);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (screensaver->interface && !demo_mode) {
 | 
					
						
							|  |  |  | 		mi->widget = window_add_widget(mi->window, mi);
 | 
					
						
							|  |  |  | 		screensaver_set_surface(screensaver->interface,
 | 
					
						
							|  |  |  | 					window_get_wl_surface(mi->window),
 | 
					
						
							|  |  |  | 					output);
 | 
					
						
							|  |  |  | 	} else {
 | 
					
						
							|  |  |  | 		mi->widget = frame_create(mi->window, mi);
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 	widget_set_redraw_handler(mi->widget, redraw_handler);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	mi->priv = screensaver;
 | 
					
						
							|  |  |  | 	mi->eglctx = EGL_NO_CONTEXT;
 | 
					
						
							|  |  |  | 	mi->instance_number = instance++; /* XXX */
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	widget_get_allocation(mi->widget, &drawarea);
 | 
					
						
							|  |  |  | 	mi->width = drawarea.width;
 | 
					
						
							|  |  |  | 	mi->height = drawarea.height;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	screensaver->plugin->init(mi);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	window_schedule_resize(mi->window, width, height);
 | 
					
						
							|  |  |  | 	return mi;
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void
 | 
					
						
							|  |  |  | handle_output_destroy(struct output *output, void *data)
 | 
					
						
							|  |  |  | {
 | 
					
						
							|  |  |  | 	/* struct ModeInfo *mi = data;
 | 
					
						
							|  |  |  | 	 * TODO */
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void
 | 
					
						
							|  |  |  | handle_output_configure(struct output *output, void *data)
 | 
					
						
							|  |  |  | {
 | 
					
						
							|  |  |  | 	struct wscreensaver *screensaver = data;
 | 
					
						
							|  |  |  | 	struct ModeInfo *mi;
 | 
					
						
							|  |  |  | 	struct rectangle area;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* skip existing outputs */
 | 
					
						
							|  |  |  | 	if (output_get_user_data(output))
 | 
					
						
							|  |  |  | 		return;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	output_get_allocation(output, &area);
 | 
					
						
							|  |  |  | 	mi = create_wscreensaver_instance(screensaver,
 | 
					
						
							|  |  |  | 					  output_get_wl_output(output),
 | 
					
						
							|  |  |  | 					  area.width, area.height);
 | 
					
						
							|  |  |  | 	output_set_user_data(output, mi);
 | 
					
						
							|  |  |  | 	output_set_destroy_handler(output, handle_output_destroy);
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int
 | 
					
						
							|  |  |  | init_wscreensaver(struct wscreensaver *wscr, struct display *display)
 | 
					
						
							|  |  |  | {
 | 
					
						
							|  |  |  | 	int size;
 | 
					
						
							|  |  |  | 	const char prefix[] = "wscreensaver::";
 | 
					
						
							|  |  |  | 	char *str;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	display_set_user_data(display, wscr);
 | 
					
						
							|  |  |  | 	wscr->display = display;
 | 
					
						
							|  |  |  | 	wscr->plugin = plugins[0];
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	size = sizeof(prefix) + strlen(wscr->plugin->name);
 | 
					
						
							|  |  |  | 	str = malloc(size);
 | 
					
						
							|  |  |  | 	if (!str) {
 | 
					
						
							|  |  |  | 		fprintf(stderr, "init: out of memory\n");
 | 
					
						
							|  |  |  | 		return -1;
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 	snprintf(str, size, "%s%s", prefix, wscr->plugin->name);
 | 
					
						
							|  |  |  | 	progname = str;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	wscr->egl.display = display_get_egl_display(wscr->display);
 | 
					
						
							|  |  |  | 	if (!wscr->egl.display) {
 | 
					
						
							|  |  |  | 		fprintf(stderr, "init: no EGL display\n");
 | 
					
						
							|  |  |  | 		return -1;
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	eglBindAPI(EGL_OPENGL_API);
 | 
					
						
							|  |  |  | 	wscr->egl.config = display_get_argb_egl_config(wscr->display);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (demo_mode) {
 | 
					
						
							|  |  |  | 		struct wl_output *o =
 | 
					
						
							|  |  |  | 			output_get_wl_output(display_get_output(display));
 | 
					
						
							|  |  |  | 		/* only one instance */
 | 
					
						
							|  |  |  | 		wscr->demomode =
 | 
					
						
							|  |  |  | 			create_wscreensaver_instance(wscr, o, 400, 300);
 | 
					
						
							|  |  |  | 		return 0;
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	display_set_output_configure_handler(display, handle_output_configure);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0;
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												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>
											
										 
											14 years ago
										 |  |  | static void
 | 
					
						
							|  |  |  | global_handler(struct display *display, uint32_t name,
 | 
					
						
							| 
									
										
											  
											
												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>
											
										 
											14 years ago
										 |  |  | 	       const char *interface, uint32_t version, void *data)
 | 
					
						
							|  |  |  | {
 | 
					
						
							|  |  |  | 	struct wscreensaver *screensaver = data;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!strcmp(interface, "screensaver")) {
 | 
					
						
							|  |  |  | 		screensaver->interface =
 | 
					
						
							|  |  |  | 			display_bind(display, name, &screensaver_interface, 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>
											
										 
											14 years ago
										 |  |  | 	}
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const struct weston_option wscreensaver_options[] = {
 | 
					
						
							|  |  |  | 	{ WESTON_OPTION_BOOLEAN, "demo", 0, &demo_mode },
 | 
					
						
							| 
									
										
											  
											
												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>
											
										 
											14 years ago
										 |  |  | };
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int main(int argc, char *argv[])
 | 
					
						
							|  |  |  | {
 | 
					
						
							|  |  |  | 	struct display *d;
 | 
					
						
							| 
									
										
											  
											
												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>
											
										 
											14 years ago
										 |  |  | 	struct wscreensaver screensaver = { 0 };
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	init_frand();
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	parse_options(wscreensaver_options,
 | 
					
						
							|  |  |  | 		      ARRAY_LENGTH(wscreensaver_options), &argc, argv);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	d = display_create(&argc, argv);
 | 
					
						
							|  |  |  | 	if (d == NULL) {
 | 
					
						
							|  |  |  | 		fprintf(stderr, "failed to create display: %m\n");
 | 
					
						
							|  |  |  | 		return EXIT_FAILURE;
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												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>
											
										 
											14 years ago
										 |  |  | 	if (!demo_mode) {
 | 
					
						
							|  |  |  | 		/* iterates already known globals immediately */
 | 
					
						
							|  |  |  | 		display_set_user_data(d, &screensaver);
 | 
					
						
							|  |  |  | 		display_set_global_handler(d, global_handler);
 | 
					
						
							| 
									
										
											  
											
												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>
											
										 
											14 years ago
										 |  |  | 		if (!screensaver.interface) {
 | 
					
						
							|  |  |  | 			fprintf(stderr,
 | 
					
						
							|  |  |  | 				"Server did not offer screensaver interface,"
 | 
					
						
							|  |  |  | 				" exiting.\n");
 | 
					
						
							|  |  |  | 			return EXIT_FAILURE;
 | 
					
						
							|  |  |  | 		}
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (init_wscreensaver(&screensaver, d) < 0) {
 | 
					
						
							|  |  |  | 		fprintf(stderr, "wscreensaver init failed.\n");
 | 
					
						
							|  |  |  | 		return EXIT_FAILURE;
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	display_run(d);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	free((void *)progname);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return EXIT_SUCCESS;
 | 
					
						
							|  |  |  | }
 |