mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2025-11-03 09:01:42 -05:00
Expose screenshooting as an interface, drop SIGUSR hack.
This pulls in a bit of extra infrastructure for discovering adertised objects on the client side.
This commit is contained in:
parent
14fcff7726
commit
1e4b86af1a
10 changed files with 295 additions and 94 deletions
9
Makefile
9
Makefile
|
|
@ -5,7 +5,7 @@ PKG_CONFIG_PATH ?= $(HOME)/install/lib/pkgconfig
|
||||||
EAGLE_CFLAGS = $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --cflags eagle)
|
EAGLE_CFLAGS = $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --cflags eagle)
|
||||||
EAGLE_LDLIBS = $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs eagle)
|
EAGLE_LDLIBS = $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) pkg-config --libs eagle)
|
||||||
|
|
||||||
clients = flower pointer background window
|
clients = flower pointer background window screenshot
|
||||||
compositors = egl-compositor.so glx-compositor.so
|
compositors = egl-compositor.so glx-compositor.so
|
||||||
|
|
||||||
all : wayland libwayland.so $(compositors) $(clients)
|
all : wayland libwayland.so $(compositors) $(clients)
|
||||||
|
|
@ -14,8 +14,8 @@ wayland_objs = \
|
||||||
wayland.o \
|
wayland.o \
|
||||||
event-loop.o \
|
event-loop.o \
|
||||||
connection.o \
|
connection.o \
|
||||||
hash.o \
|
input.o \
|
||||||
input.o
|
wayland-util.o
|
||||||
|
|
||||||
wayland : CFLAGS += $(shell pkg-config --cflags libffi)
|
wayland : CFLAGS += $(shell pkg-config --cflags libffi)
|
||||||
wayland : LDLIBS += $(shell pkg-config --libs libffi) -ldl -rdynamic
|
wayland : LDLIBS += $(shell pkg-config --libs libffi) -ldl -rdynamic
|
||||||
|
|
@ -23,7 +23,7 @@ wayland : LDLIBS += $(shell pkg-config --libs libffi) -ldl -rdynamic
|
||||||
wayland : $(wayland_objs)
|
wayland : $(wayland_objs)
|
||||||
gcc -o $@ $(LDLIBS) $(wayland_objs)
|
gcc -o $@ $(LDLIBS) $(wayland_objs)
|
||||||
|
|
||||||
libwayland_objs = wayland-client.o connection.o
|
libwayland_objs = wayland-client.o connection.o wayland-util.o
|
||||||
|
|
||||||
libwayland.so : $(libwayland_objs)
|
libwayland.so : $(libwayland_objs)
|
||||||
|
|
||||||
|
|
@ -48,6 +48,7 @@ flower_objs = flower.o wayland-glib.o
|
||||||
pointer_objs = pointer.o wayland-glib.o cairo-util.o
|
pointer_objs = pointer.o wayland-glib.o cairo-util.o
|
||||||
background_objs = background.o wayland-glib.o
|
background_objs = background.o wayland-glib.o
|
||||||
window_objs = window.o gears.o wayland-glib.o cairo-util.o
|
window_objs = window.o gears.o wayland-glib.o cairo-util.o
|
||||||
|
screenshot_objs = screenshot.o wayland-glib.o
|
||||||
|
|
||||||
$(clients) : CFLAGS += $(shell pkg-config --cflags cairo glib-2.0)
|
$(clients) : CFLAGS += $(shell pkg-config --cflags cairo glib-2.0)
|
||||||
$(clients) : LDLIBS += $(shell pkg-config --libs cairo glib-2.0) -lrt
|
$(clients) : LDLIBS += $(shell pkg-config --libs cairo glib-2.0) -lrt
|
||||||
|
|
|
||||||
|
|
@ -43,14 +43,6 @@ struct egl_surface {
|
||||||
EGLSurface surface;
|
EGLSurface surface;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int do_screenshot;
|
|
||||||
|
|
||||||
static void
|
|
||||||
handle_sigusr1(int s)
|
|
||||||
{
|
|
||||||
do_screenshot = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
die(const char *msg, ...)
|
die(const char *msg, ...)
|
||||||
{
|
{
|
||||||
|
|
@ -115,9 +107,15 @@ convert_pixels(png_structp png, png_row_infop row_info, png_bytep data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct screenshooter {
|
||||||
|
struct wl_object base;
|
||||||
|
struct egl_compositor *ec;
|
||||||
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
screenshot(struct egl_compositor *ec)
|
screenshooter_shoot(struct wl_client *client, struct screenshooter *shooter)
|
||||||
{
|
{
|
||||||
|
struct egl_compositor *ec = shooter->ec;
|
||||||
png_struct *png;
|
png_struct *png;
|
||||||
png_info *info;
|
png_info *info;
|
||||||
png_byte **volatile rows = NULL;
|
png_byte **volatile rows = NULL;
|
||||||
|
|
@ -179,6 +177,31 @@ screenshot(struct egl_compositor *ec)
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct wl_method screenshooter_methods[] = {
|
||||||
|
{ "shoot", screenshooter_shoot, 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_interface screenshooter_interface = {
|
||||||
|
"screenshooter", 1,
|
||||||
|
ARRAY_LENGTH(screenshooter_methods),
|
||||||
|
screenshooter_methods,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct screenshooter *
|
||||||
|
screenshooter_create(struct egl_compositor *ec)
|
||||||
|
{
|
||||||
|
struct screenshooter *shooter;
|
||||||
|
|
||||||
|
shooter = malloc(sizeof *shooter);
|
||||||
|
if (shooter == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
shooter->base.interface = &screenshooter_interface;
|
||||||
|
shooter->ec = ec;
|
||||||
|
|
||||||
|
return shooter;
|
||||||
|
};
|
||||||
|
|
||||||
static struct egl_surface *
|
static struct egl_surface *
|
||||||
egl_surface_create_from_cairo_surface(cairo_surface_t *surface,
|
egl_surface_create_from_cairo_surface(cairo_surface_t *surface,
|
||||||
int x, int y, int width, int height)
|
int x, int y, int width, int height)
|
||||||
|
|
@ -387,7 +410,7 @@ overlay_create(int x, int y, int width, int height)
|
||||||
width, height);
|
width, height);
|
||||||
|
|
||||||
cr = cairo_create(surface);
|
cr = cairo_create(surface);
|
||||||
cairo_set_source_rgba(cr, 0.1, 0.1, 0.1, 0.7);
|
cairo_set_source_rgba(cr, 0.1, 0.1, 0.1, 0.8);
|
||||||
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
|
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
|
||||||
cairo_paint(cr);
|
cairo_paint(cr);
|
||||||
|
|
||||||
|
|
@ -469,17 +492,6 @@ repaint(void *data)
|
||||||
draw_surface(ec->pointer);
|
draw_surface(ec->pointer);
|
||||||
|
|
||||||
eglSwapBuffers(ec->display, ec->surface);
|
eglSwapBuffers(ec->display, ec->surface);
|
||||||
|
|
||||||
if (do_screenshot) {
|
|
||||||
glFinish();
|
|
||||||
/* FIXME: There's a bug somewhere so that glFinish()
|
|
||||||
* doesn't actually wait for all rendering to finish.
|
|
||||||
* I *think* it's fixed in upstream drm, but for my
|
|
||||||
* kernel I need this sleep now... */
|
|
||||||
sleep(1);
|
|
||||||
screenshot(ec);
|
|
||||||
do_screenshot = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -637,6 +649,7 @@ wl_compositor_create(struct wl_display *display)
|
||||||
EGLint major, minor, count;
|
EGLint major, minor, count;
|
||||||
struct egl_compositor *ec;
|
struct egl_compositor *ec;
|
||||||
const char *filename;
|
const char *filename;
|
||||||
|
struct screenshooter *shooter;
|
||||||
|
|
||||||
ec = malloc(sizeof *ec);
|
ec = malloc(sizeof *ec);
|
||||||
if (ec == NULL)
|
if (ec == NULL)
|
||||||
|
|
@ -703,7 +716,9 @@ wl_compositor_create(struct wl_display *display)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
signal(SIGUSR1, handle_sigusr1);
|
shooter = screenshooter_create(ec);
|
||||||
|
wl_display_add_object(display, &shooter->base);
|
||||||
|
wl_display_add_global(display, &shooter->base);
|
||||||
|
|
||||||
schedule_repaint(ec);
|
schedule_repaint(ec);
|
||||||
|
|
||||||
|
|
|
||||||
1
input.c
1
input.c
|
|
@ -126,7 +126,6 @@ wl_input_device_create(struct wl_display *display,
|
||||||
if (device == NULL)
|
if (device == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
device->base.id = id;
|
|
||||||
device->base.interface = &input_device_interface;
|
device->base.interface = &input_device_interface;
|
||||||
device->display = display;
|
device->display = display;
|
||||||
device->tool = 1;
|
device->tool = 1;
|
||||||
|
|
|
||||||
84
screenshot.c
Normal file
84
screenshot.c
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include "wayland-client.h"
|
||||||
|
#include "wayland-glib.h"
|
||||||
|
|
||||||
|
/* The screenshooter is a good example of a custom object exposed by
|
||||||
|
* the compositor and serves as a test bed for implementing client
|
||||||
|
* side marshalling outside libwayland.so */
|
||||||
|
|
||||||
|
static const char socket_name[] = "\0wayland";
|
||||||
|
|
||||||
|
struct screenshooter {
|
||||||
|
uint32_t id;
|
||||||
|
struct wl_display *display;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct screenshooter *
|
||||||
|
screenshooter_create(struct wl_display *display)
|
||||||
|
{
|
||||||
|
struct screenshooter *screenshooter;
|
||||||
|
uint32_t id;
|
||||||
|
|
||||||
|
id = wl_display_get_object_id(display, "screenshooter");
|
||||||
|
if (id == 0) {
|
||||||
|
fprintf(stderr, "server doesn't support screenshooter interface\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
screenshooter = malloc(sizeof screenshooter);
|
||||||
|
if (screenshooter == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
screenshooter->id = id;
|
||||||
|
screenshooter->display = display;
|
||||||
|
|
||||||
|
return screenshooter;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SCREENSHOOTER_SHOOT 0
|
||||||
|
|
||||||
|
static void
|
||||||
|
screenshooter_shoot(struct screenshooter *screenshooter)
|
||||||
|
{
|
||||||
|
uint32_t request[2];
|
||||||
|
|
||||||
|
request[0] = screenshooter->id;
|
||||||
|
request[1] = SCREENSHOOTER_SHOOT | ((sizeof request) << 16);
|
||||||
|
|
||||||
|
wl_display_write(screenshooter->display,
|
||||||
|
request, sizeof request);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
struct wl_display *display;
|
||||||
|
GMainLoop *loop;
|
||||||
|
GSource *source;
|
||||||
|
struct screenshooter *s;
|
||||||
|
|
||||||
|
display = wl_display_create(socket_name);
|
||||||
|
if (display == NULL) {
|
||||||
|
fprintf(stderr, "failed to create display: %m\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
loop = g_main_loop_new(NULL, FALSE);
|
||||||
|
source = wayland_source_new(display);
|
||||||
|
g_source_attach(source, NULL);
|
||||||
|
|
||||||
|
s = screenshooter_create(display);
|
||||||
|
if (s == NULL)
|
||||||
|
exit(-1);
|
||||||
|
|
||||||
|
screenshooter_shoot(s);
|
||||||
|
|
||||||
|
g_main_loop_run(loop);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -11,10 +11,17 @@
|
||||||
#include <sys/poll.h>
|
#include <sys/poll.h>
|
||||||
|
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
|
#include "wayland-util.h"
|
||||||
#include "wayland-client.h"
|
#include "wayland-client.h"
|
||||||
|
|
||||||
static const char socket_name[] = "\0wayland";
|
static const char socket_name[] = "\0wayland";
|
||||||
|
|
||||||
|
struct wl_global {
|
||||||
|
uint32_t id;
|
||||||
|
char *interface;
|
||||||
|
struct wl_list link;
|
||||||
|
};
|
||||||
|
|
||||||
struct wl_proxy {
|
struct wl_proxy {
|
||||||
struct wl_display *display;
|
struct wl_display *display;
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
|
|
@ -26,6 +33,7 @@ struct wl_display {
|
||||||
int fd;
|
int fd;
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
uint32_t mask;
|
uint32_t mask;
|
||||||
|
struct wl_list global_list;
|
||||||
|
|
||||||
wl_display_update_func_t update;
|
wl_display_update_func_t update;
|
||||||
void *update_data;
|
void *update_data;
|
||||||
|
|
@ -56,10 +64,11 @@ WL_EXPORT struct wl_display *
|
||||||
wl_display_create(const char *address)
|
wl_display_create(const char *address)
|
||||||
{
|
{
|
||||||
struct wl_display *display;
|
struct wl_display *display;
|
||||||
|
struct wl_global *global;
|
||||||
struct sockaddr_un name;
|
struct sockaddr_un name;
|
||||||
socklen_t size;
|
socklen_t size;
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
uint32_t id, length;
|
uint32_t id, length, count, i;
|
||||||
|
|
||||||
display = malloc(sizeof *display);
|
display = malloc(sizeof *display);
|
||||||
if (display == NULL)
|
if (display == NULL)
|
||||||
|
|
@ -87,13 +96,28 @@ wl_display_create(const char *address)
|
||||||
* guess... */
|
* guess... */
|
||||||
read(display->fd, &display->id, sizeof display->id);
|
read(display->fd, &display->id, sizeof display->id);
|
||||||
|
|
||||||
/* FIXME: actually discover advertised objects here. */
|
read(display->fd, &count, sizeof count);
|
||||||
read(display->fd, &id, sizeof id);
|
|
||||||
read(display->fd, &length, sizeof length);
|
wl_list_init(&display->global_list);
|
||||||
read(display->fd, buffer, (length + 3) & ~3);
|
for (i = 0; i < count; i++) {
|
||||||
|
/* FIXME: actually discover advertised objects here. */
|
||||||
|
read(display->fd, &id, sizeof id);
|
||||||
|
read(display->fd, &length, sizeof length);
|
||||||
|
read(display->fd, buffer, (length + 3) & ~3);
|
||||||
|
|
||||||
|
global = malloc(sizeof *global);
|
||||||
|
if (global == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
global->id = id;
|
||||||
|
global->interface = malloc(length + 1);
|
||||||
|
memcpy(global->interface, buffer, length);
|
||||||
|
global->interface[length] = '\0';
|
||||||
|
wl_list_insert(display->global_list.prev, &global->link);
|
||||||
|
}
|
||||||
|
|
||||||
display->proxy.display = display;
|
display->proxy.display = display;
|
||||||
display->proxy.id = id;
|
display->proxy.id = wl_display_get_object_id(display, "display");
|
||||||
|
|
||||||
display->connection = wl_connection_create(display->fd,
|
display->connection = wl_connection_create(display->fd,
|
||||||
connection_update,
|
connection_update,
|
||||||
|
|
@ -110,6 +134,24 @@ wl_display_destroy(struct wl_display *display)
|
||||||
free(display);
|
free(display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WL_EXPORT uint32_t
|
||||||
|
wl_display_get_object_id(struct wl_display *display, const char *interface)
|
||||||
|
{
|
||||||
|
struct wl_global *global;
|
||||||
|
|
||||||
|
global = container_of(display->global_list.next,
|
||||||
|
struct wl_global, link);
|
||||||
|
while (&global->link != &display->global_list) {
|
||||||
|
if (strcmp(global->interface, interface) == 0)
|
||||||
|
return global->id;
|
||||||
|
|
||||||
|
global = container_of(global->link.next,
|
||||||
|
struct wl_global, link);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
WL_EXPORT int
|
WL_EXPORT int
|
||||||
wl_display_get_fd(struct wl_display *display,
|
wl_display_get_fd(struct wl_display *display,
|
||||||
wl_display_update_func_t update, void *data)
|
wl_display_update_func_t update, void *data)
|
||||||
|
|
@ -171,6 +213,18 @@ wl_display_set_event_handler(struct wl_display *display,
|
||||||
display->event_handler_data = data;
|
display->event_handler_data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WL_EXPORT uint32_t
|
||||||
|
wl_display_allocate_id(struct wl_display *display)
|
||||||
|
{
|
||||||
|
return display->id++;
|
||||||
|
}
|
||||||
|
|
||||||
|
WL_EXPORT void
|
||||||
|
wl_display_write(struct wl_display *display, const void *data, size_t count)
|
||||||
|
{
|
||||||
|
wl_connection_write(display->connection, data, count);
|
||||||
|
}
|
||||||
|
|
||||||
#define WL_DISPLAY_CREATE_SURFACE 0
|
#define WL_DISPLAY_CREATE_SURFACE 0
|
||||||
|
|
||||||
WL_EXPORT struct wl_surface *
|
WL_EXPORT struct wl_surface *
|
||||||
|
|
@ -183,7 +237,7 @@ wl_display_create_surface(struct wl_display *display)
|
||||||
if (surface == NULL)
|
if (surface == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
surface->proxy.id = display->id++;
|
surface->proxy.id = wl_display_allocate_id(display);
|
||||||
surface->proxy.display = display;
|
surface->proxy.display = display;
|
||||||
|
|
||||||
request[0] = display->proxy.id;
|
request[0] = display->proxy.id;
|
||||||
|
|
@ -284,4 +338,3 @@ wl_surface_damage(struct wl_surface *surface,
|
||||||
wl_connection_write(surface->proxy.display->connection,
|
wl_connection_write(surface->proxy.display->connection,
|
||||||
request, sizeof request);
|
request, sizeof request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@ void wl_display_set_event_handler(struct wl_display *display,
|
||||||
wl_display_event_func_t handler,
|
wl_display_event_func_t handler,
|
||||||
void *data);
|
void *data);
|
||||||
|
|
||||||
|
|
||||||
struct wl_surface *
|
struct wl_surface *
|
||||||
wl_display_create_surface(struct wl_display *display);
|
wl_display_create_surface(struct wl_display *display);
|
||||||
|
|
||||||
|
|
@ -47,4 +46,15 @@ void wl_surface_copy(struct wl_surface *surface, int32_t dst_x, int32_t dst_y,
|
||||||
void wl_surface_damage(struct wl_surface *surface,
|
void wl_surface_damage(struct wl_surface *surface,
|
||||||
int32_t x, int32_t y, int32_t width, int32_t height);
|
int32_t x, int32_t y, int32_t width, int32_t height);
|
||||||
|
|
||||||
|
|
||||||
|
/* These entry points are for client side implementation of custom
|
||||||
|
* objects. */
|
||||||
|
|
||||||
|
uint32_t wl_display_get_object_id(struct wl_display *display,
|
||||||
|
const char *interface);
|
||||||
|
uint32_t wl_display_allocate_id(struct wl_display *display);
|
||||||
|
void wl_display_write(struct wl_display *display,
|
||||||
|
const void *data,
|
||||||
|
size_t count);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -43,3 +43,41 @@ wl_hash_delete(struct wl_hash *hash, struct wl_object *object)
|
||||||
{
|
{
|
||||||
/* writeme */
|
/* writeme */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void wl_list_init(struct wl_list *list)
|
||||||
|
{
|
||||||
|
list->prev = list;
|
||||||
|
list->next = list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wl_list_insert(struct wl_list *list, struct wl_list *elm)
|
||||||
|
{
|
||||||
|
elm->prev = list;
|
||||||
|
elm->next = list->next;
|
||||||
|
list->next = elm;
|
||||||
|
elm->next->prev = elm;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wl_list_remove(struct wl_list *elm)
|
||||||
|
{
|
||||||
|
elm->prev->next = elm->next;
|
||||||
|
elm->next->prev = elm->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
wl_list_length(struct wl_list *list)
|
||||||
|
{
|
||||||
|
struct wl_list *e;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
e = list->next;
|
||||||
|
while (e != list) {
|
||||||
|
e = e->next;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
37
wayland-util.h
Normal file
37
wayland-util.h
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
#ifndef WAYLAND_UTIL_H
|
||||||
|
#define WAYLAND_UTIL_H
|
||||||
|
|
||||||
|
/* GCC visibility */
|
||||||
|
#if defined(__GNUC__) && __GNUC__ >= 4
|
||||||
|
#define WL_EXPORT __attribute__ ((visibility("default")))
|
||||||
|
#else
|
||||||
|
#define WL_EXPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
|
||||||
|
|
||||||
|
#define container_of(ptr, type, member) ({ \
|
||||||
|
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
||||||
|
(type *)( (char *)__mptr - offsetof(type,member) );})
|
||||||
|
|
||||||
|
struct wl_hash {
|
||||||
|
struct wl_object **objects;
|
||||||
|
uint32_t count, alloc, id;
|
||||||
|
};
|
||||||
|
|
||||||
|
int wl_hash_insert(struct wl_hash *hash, struct wl_object *object);
|
||||||
|
struct wl_object *wl_hash_lookup(struct wl_hash *hash, uint32_t id);
|
||||||
|
void wl_hash_delete(struct wl_hash *hash, struct wl_object *object);
|
||||||
|
|
||||||
|
struct wl_list {
|
||||||
|
struct wl_list *prev;
|
||||||
|
struct wl_list *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
void wl_list_init(struct wl_list *list);
|
||||||
|
void wl_list_insert(struct wl_list *list, struct wl_list *elm);
|
||||||
|
void wl_list_remove(struct wl_list *elm);
|
||||||
|
int wl_list_length(struct wl_list *list);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
45
wayland.c
45
wayland.c
|
|
@ -13,28 +13,6 @@
|
||||||
#include "wayland.h"
|
#include "wayland.h"
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
|
|
||||||
void wl_list_init(struct wl_list *list)
|
|
||||||
{
|
|
||||||
list->prev = list;
|
|
||||||
list->next = list;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
wl_list_insert(struct wl_list *list, struct wl_list *elm)
|
|
||||||
{
|
|
||||||
elm->prev = list;
|
|
||||||
elm->next = list->next;
|
|
||||||
list->next = elm;
|
|
||||||
elm->next->prev = elm;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
wl_list_remove(struct wl_list *elm)
|
|
||||||
{
|
|
||||||
elm->prev->next = elm->next;
|
|
||||||
elm->next->prev = elm->prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct wl_client {
|
struct wl_client {
|
||||||
struct wl_connection *connection;
|
struct wl_connection *connection;
|
||||||
struct wl_event_source *source;
|
struct wl_event_source *source;
|
||||||
|
|
@ -56,6 +34,7 @@ struct wl_display {
|
||||||
struct wl_list surface_list;
|
struct wl_list surface_list;
|
||||||
struct wl_list client_list;
|
struct wl_list client_list;
|
||||||
uint32_t client_id_range;
|
uint32_t client_id_range;
|
||||||
|
uint32_t id;
|
||||||
|
|
||||||
struct wl_list global_list;
|
struct wl_list global_list;
|
||||||
|
|
||||||
|
|
@ -359,7 +338,7 @@ wl_client_connection_data(int fd, uint32_t mask, void *data)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (len > sizeof p) {
|
while (len >= sizeof p) {
|
||||||
wl_connection_copy(connection, p, sizeof p);
|
wl_connection_copy(connection, p, sizeof p);
|
||||||
opcode = p[1] & 0xffff;
|
opcode = p[1] & 0xffff;
|
||||||
size = p[1] >> 16;
|
size = p[1] >> 16;
|
||||||
|
|
@ -428,6 +407,7 @@ wl_client_create(struct wl_display *display, int fd)
|
||||||
{
|
{
|
||||||
struct wl_client *client;
|
struct wl_client *client;
|
||||||
struct wl_object_ref *ref;
|
struct wl_object_ref *ref;
|
||||||
|
uint32_t count;
|
||||||
|
|
||||||
client = malloc(sizeof *client);
|
client = malloc(sizeof *client);
|
||||||
if (client == NULL)
|
if (client == NULL)
|
||||||
|
|
@ -448,6 +428,10 @@ wl_client_create(struct wl_display *display, int fd)
|
||||||
sizeof display->client_id_range);
|
sizeof display->client_id_range);
|
||||||
display->client_id_range += 256;
|
display->client_id_range += 256;
|
||||||
|
|
||||||
|
/* Write list of global objects to client. */
|
||||||
|
count = wl_list_length(&display->global_list);
|
||||||
|
wl_connection_write(client->connection, &count, sizeof count);
|
||||||
|
|
||||||
ref = container_of(display->global_list.next,
|
ref = container_of(display->global_list.next,
|
||||||
struct wl_object_ref, link);
|
struct wl_object_ref, link);
|
||||||
while (&ref->link != &display->global_list) {
|
while (&ref->link != &display->global_list) {
|
||||||
|
|
@ -542,7 +526,7 @@ wl_display_create_input_devices(struct wl_display *display)
|
||||||
display->pointer = wl_input_device_create(display, path, 1);
|
display->pointer = wl_input_device_create(display, path, 1);
|
||||||
|
|
||||||
if (display->pointer != NULL)
|
if (display->pointer != NULL)
|
||||||
wl_hash_insert(&display->objects, display->pointer);
|
wl_display_add_object(display, display->pointer);
|
||||||
|
|
||||||
display->pointer_x = 100;
|
display->pointer_x = 100;
|
||||||
display->pointer_y = 100;
|
display->pointer_y = 100;
|
||||||
|
|
@ -563,9 +547,6 @@ wl_display_create(void)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
display->base.id = 0;
|
|
||||||
display->base.interface = &display_interface;
|
|
||||||
wl_hash_insert(&display->objects, &display->base);
|
|
||||||
wl_list_init(&display->surface_list);
|
wl_list_init(&display->surface_list);
|
||||||
wl_list_init(&display->client_list);
|
wl_list_init(&display->client_list);
|
||||||
wl_list_init(&display->global_list);
|
wl_list_init(&display->global_list);
|
||||||
|
|
@ -574,6 +555,9 @@ wl_display_create(void)
|
||||||
|
|
||||||
display->client_id_range = 256; /* Gah, arbitrary... */
|
display->client_id_range = 256; /* Gah, arbitrary... */
|
||||||
|
|
||||||
|
display->id = 1;
|
||||||
|
display->base.interface = &display_interface;
|
||||||
|
wl_display_add_object(display, &display->base);
|
||||||
if (wl_display_add_global(display, &display->base)) {
|
if (wl_display_add_global(display, &display->base)) {
|
||||||
wl_event_loop_destroy(display->loop);
|
wl_event_loop_destroy(display->loop);
|
||||||
free(display);
|
free(display);
|
||||||
|
|
@ -583,6 +567,13 @@ wl_display_create(void)
|
||||||
return display;
|
return display;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WL_EXPORT void
|
||||||
|
wl_display_add_object(struct wl_display *display, struct wl_object *object)
|
||||||
|
{
|
||||||
|
object->id = display->id++;
|
||||||
|
wl_hash_insert(&display->objects, object);
|
||||||
|
}
|
||||||
|
|
||||||
WL_EXPORT int
|
WL_EXPORT int
|
||||||
wl_display_add_global(struct wl_display *display, struct wl_object *object)
|
wl_display_add_global(struct wl_display *display, struct wl_object *object)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
35
wayland.h
35
wayland.h
|
|
@ -2,28 +2,7 @@
|
||||||
#define WAYLAND_H
|
#define WAYLAND_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "wayland-util.h"
|
||||||
/* GCC visibility */
|
|
||||||
#if defined(__GNUC__) && __GNUC__ >= 4
|
|
||||||
#define WL_EXPORT __attribute__ ((visibility("default")))
|
|
||||||
#else
|
|
||||||
#define WL_EXPORT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
|
|
||||||
|
|
||||||
#define container_of(ptr, type, member) ({ \
|
|
||||||
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
|
||||||
(type *)( (char *)__mptr - offsetof(type,member) );})
|
|
||||||
|
|
||||||
struct wl_list {
|
|
||||||
struct wl_list *prev;
|
|
||||||
struct wl_list *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
void wl_list_init(struct wl_list *list);
|
|
||||||
void wl_list_insert(struct wl_list *list, struct wl_list *elm);
|
|
||||||
void wl_list_remove(struct wl_list *elm);
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
WL_EVENT_READABLE = 0x01,
|
WL_EVENT_READABLE = 0x01,
|
||||||
|
|
@ -52,15 +31,6 @@ struct wl_event_source *wl_event_loop_add_idle(struct wl_event_loop *loop,
|
||||||
wl_event_loop_idle_func_t func,
|
wl_event_loop_idle_func_t func,
|
||||||
void *data);
|
void *data);
|
||||||
|
|
||||||
struct wl_hash {
|
|
||||||
struct wl_object **objects;
|
|
||||||
uint32_t count, alloc, id;
|
|
||||||
};
|
|
||||||
|
|
||||||
int wl_hash_insert(struct wl_hash *hash, struct wl_object *object);
|
|
||||||
struct wl_object *wl_hash_lookup(struct wl_hash *hash, uint32_t id);
|
|
||||||
void wl_hash_delete(struct wl_hash *hash, struct wl_object *object);
|
|
||||||
|
|
||||||
struct wl_client;
|
struct wl_client;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
@ -122,8 +92,11 @@ void wl_surface_iterator_destroy(struct wl_surface_iterator *iterator);
|
||||||
struct wl_object *
|
struct wl_object *
|
||||||
wl_input_device_create(struct wl_display *display,
|
wl_input_device_create(struct wl_display *display,
|
||||||
const char *path, uint32_t id);
|
const char *path, uint32_t id);
|
||||||
|
void
|
||||||
|
wl_display_add_object(struct wl_display *display, struct wl_object *object);
|
||||||
int
|
int
|
||||||
wl_display_add_global(struct wl_display *display, struct wl_object *object);
|
wl_display_add_global(struct wl_display *display, struct wl_object *object);
|
||||||
|
|
||||||
void
|
void
|
||||||
wl_display_post_relative_event(struct wl_display *display,
|
wl_display_post_relative_event(struct wl_display *display,
|
||||||
struct wl_object *source, int dx, int dy);
|
struct wl_object *source, int dx, int dy);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue