summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--wayland-client.c27
-rw-r--r--wayland-client.h3
-rw-r--r--wayland-protocol.c11
-rw-r--r--wayland-protocol.h5
-rw-r--r--wayland-system-compositor.c29
-rw-r--r--wayland.c61
-rw-r--r--wayland.h10
7 files changed, 124 insertions, 22 deletions
diff --git a/wayland-client.c b/wayland-client.c
index f3358b4..2760706 100644
--- a/wayland-client.c
+++ b/wayland-client.c
@@ -67,6 +67,9 @@ struct wl_display {
wl_display_event_func_t event_handler;
void *event_handler_data;
+
+ uint32_t output_id;
+ int32_t width, height;
};
struct wl_compositor {
@@ -96,6 +99,13 @@ connection_update(struct wl_connection *connection,
return 0;
}
+WL_EXPORT void
+wl_display_get_geometry(struct wl_display *display, int32_t *width, int32_t *height)
+{
+ *width = display->width;
+ *height = display->height;
+}
+
static void
add_visual(struct wl_display *display, struct wl_global *global)
{
@@ -258,6 +268,9 @@ handle_display_event(struct wl_display *display,
if (strcmp(global->interface, "visual") == 0)
add_visual(display, global);
+ else if (strcmp(global->interface, "output") == 0) {
+ display->output_id = p[0];
+ }
break;
case WL_DISPLAY_RANGE:
@@ -267,6 +280,18 @@ handle_display_event(struct wl_display *display,
}
static void
+handle_output_event(struct wl_display *display,
+ uint32_t opcode, uint32_t *p, uint32_t size)
+{
+ switch (opcode) {
+ case WL_OUTPUT_PRESENCE:
+ display->width = p[0];
+ display->height = p[1];
+ break;
+ }
+}
+
+static void
handle_event(struct wl_display *display,
uint32_t object, uint32_t opcode, uint32_t size)
{
@@ -275,6 +300,8 @@ handle_event(struct wl_display *display,
wl_connection_copy(display->connection, p, size);
if (object == 1) {
handle_display_event(display, opcode, p + 2, size);
+ } if (object == display->output_id) {
+ handle_output_event(display, opcode, p + 2, size);
} else if (display->event_handler != NULL)
display->event_handler(display, object, opcode, size, p + 2,
display->event_handler_data);
diff --git a/wayland-client.h b/wayland-client.h
index 1a41217..fd15839 100644
--- a/wayland-client.h
+++ b/wayland-client.h
@@ -57,6 +57,9 @@ void wl_display_set_event_handler(struct wl_display *display,
wl_display_event_func_t handler,
void *data);
+void
+wl_display_get_geometry(struct wl_display *display,
+ int32_t *width, int32_t *height);
struct wl_compositor *
wl_display_get_compositor(struct wl_display *display);
struct wl_visual *
diff --git a/wayland-protocol.c b/wayland-protocol.c
index 4c61810..4ec40ab 100644
--- a/wayland-protocol.c
+++ b/wayland-protocol.c
@@ -83,3 +83,14 @@ WL_EXPORT const struct wl_interface wl_input_device_interface = {
0, NULL,
ARRAY_LENGTH(input_device_events), input_device_events,
};
+
+
+static const struct wl_message output_events[] = {
+ { "presence", "uu" },
+};
+
+WL_EXPORT const struct wl_interface wl_output_interface = {
+ "output", 1,
+ 0, NULL,
+ ARRAY_LENGTH(output_events), output_events,
+};
diff --git a/wayland-protocol.h b/wayland-protocol.h
index c71cfdc..76a80c5 100644
--- a/wayland-protocol.h
+++ b/wayland-protocol.h
@@ -78,4 +78,9 @@ extern const struct wl_interface wl_surface_interface;
extern const struct wl_interface wl_input_device_interface;
+
+#define WL_OUTPUT_PRESENCE 0
+
+extern const struct wl_interface wl_output_interface;
+
#endif
diff --git a/wayland-system-compositor.c b/wayland-system-compositor.c
index 69f785c..f3ff5b0 100644
--- a/wayland-system-compositor.c
+++ b/wayland-system-compositor.c
@@ -56,6 +56,10 @@ struct wl_visual {
struct wl_object base;
};
+struct wl_output {
+ struct wl_object base;
+};
+
struct wlsc_input_device {
struct wl_object base;
int32_t x, y;
@@ -70,6 +74,7 @@ struct wlsc_input_device {
struct egl_compositor {
struct wl_compositor base;
+ struct wl_output output;
struct wl_visual argb_visual, premultiplied_argb_visual, rgb_visual;
EGLDisplay display;
@@ -825,19 +830,29 @@ add_visuals(struct egl_compositor *ec)
ec->argb_visual.base.interface = &visual_interface;
ec->argb_visual.base.implementation = NULL;
wl_display_add_object(ec->wl_display, &ec->argb_visual.base);
- wl_display_add_global(ec->wl_display, &ec->argb_visual.base);
+ wl_display_add_global(ec->wl_display, &ec->argb_visual.base, NULL);
ec->premultiplied_argb_visual.base.interface = &visual_interface;
ec->premultiplied_argb_visual.base.implementation = NULL;
wl_display_add_object(ec->wl_display,
&ec->premultiplied_argb_visual.base);
wl_display_add_global(ec->wl_display,
- &ec->premultiplied_argb_visual.base);
+ &ec->premultiplied_argb_visual.base, NULL);
ec->rgb_visual.base.interface = &visual_interface;
ec->rgb_visual.base.implementation = NULL;
wl_display_add_object(ec->wl_display, &ec->rgb_visual.base);
- wl_display_add_global(ec->wl_display, &ec->rgb_visual.base);
+ wl_display_add_global(ec->wl_display, &ec->rgb_visual.base, NULL);
+}
+
+static void
+post_output_presence(struct wl_client *client, struct wl_object *global)
+{
+ struct egl_compositor *ec =
+ container_of(global, struct egl_compositor, output.base);
+
+ wl_client_post_event(client, global,
+ WL_OUTPUT_PRESENCE, ec->width, ec->height);
}
static const char gem_device[] = "/dev/dri/card0";
@@ -1021,6 +1036,12 @@ egl_compositor_create(struct wl_display *display)
glClearColor(0, 0, 0.2, 1);
wl_display_set_compositor(display, &ec->base, &compositor_interface);
+
+ /* FIXME: This needs to be much more expressive... something like randr 1.2. */
+ ec->output.base.interface = &wl_output_interface;
+ wl_display_add_object(display, &ec->output.base);
+ wl_display_add_global(display, &ec->output.base, post_output_presence);
+
add_visuals(ec);
wl_list_init(&ec->input_device_list);
@@ -1033,7 +1054,7 @@ egl_compositor_create(struct wl_display *display)
shooter = screenshooter_create(ec);
wl_display_add_object(display, &shooter->base);
- wl_display_add_global(display, &shooter->base);
+ wl_display_add_global(display, &shooter->base, NULL);
loop = wl_display_get_event_loop(ec->wl_display);
diff --git a/wayland.c b/wayland.c
index 6ad1887..0fe2a8d 100644
--- a/wayland.c
+++ b/wayland.c
@@ -64,6 +64,12 @@ struct wl_object_ref {
struct wl_list link;
};
+struct wl_global {
+ struct wl_object *object;
+ wl_client_connect_func_t func;
+ struct wl_list link;
+};
+
void
wl_client_destroy(struct wl_client *client);
@@ -122,6 +128,17 @@ wl_client_marshal(struct wl_client *client, struct wl_object *sender,
va_end(ap);
}
+WL_EXPORT void
+wl_client_post_event(struct wl_client *client, struct wl_object *sender,
+ uint32_t opcode, ...)
+{
+ va_list ap;
+
+ va_start(ap, opcode);
+ wl_client_vmarshal(client, sender, opcode, ap);
+ va_end(ap);
+}
+
static void
wl_client_demarshal(struct wl_client *client, struct wl_object *target,
uint32_t opcode, size_t size)
@@ -284,7 +301,7 @@ static struct wl_client *
wl_client_create(struct wl_display *display, int fd)
{
struct wl_client *client;
- struct wl_object_ref *ref;
+ struct wl_global *global;
client = malloc(sizeof *client);
if (client == NULL)
@@ -303,17 +320,25 @@ wl_client_create(struct wl_display *display, int fd)
wl_display_post_range(display, client);
- ref = container_of(display->global_list.next,
- struct wl_object_ref, link);
- while (&ref->link != &display->global_list) {
+ global = container_of(display->global_list.next,
+ struct wl_global, link);
+ while (&global->link != &display->global_list) {
wl_client_marshal(client, &client->display->base,
WL_DISPLAY_GLOBAL,
- ref->object,
- ref->object->interface->name,
- ref->object->interface->version);
+ global->object,
+ global->object->interface->name,
+ global->object->interface->version);
+ global = container_of(global->link.next,
+ struct wl_global, link);
+ }
- ref = container_of(ref->link.next,
- struct wl_object_ref, link);
+ global = container_of(display->global_list.next,
+ struct wl_global, link);
+ while (&global->link != &display->global_list) {
+ if (global->func)
+ global->func(client, global->object);
+ global = container_of(global->link.next,
+ struct wl_global, link);
}
return client;
@@ -403,7 +428,7 @@ wl_display_set_compositor(struct wl_display *display,
compositor->base.implementation = (void (**)(void)) implementation;
wl_display_add_object(display, &compositor->base);
- if (wl_display_add_global(display, &compositor->base))
+ if (wl_display_add_global(display, &compositor->base, NULL))
return -1;
return 0;
@@ -439,7 +464,7 @@ wl_display_create(void)
display->base.interface = &wl_display_interface;
display->base.implementation = NULL;
wl_display_add_object(display, &display->base);
- if (wl_display_add_global(display, &display->base)) {
+ if (wl_display_add_global(display, &display->base, NULL)) {
wl_event_loop_destroy(display->loop);
free(display);
return NULL;
@@ -456,16 +481,18 @@ wl_display_add_object(struct wl_display *display, struct wl_object *object)
}
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, wl_client_connect_func_t func)
{
- struct wl_object_ref *ref;
+ struct wl_global *global;
- ref = malloc(sizeof *ref);
- if (ref == NULL)
+ global = malloc(sizeof *global);
+ if (global == NULL)
return -1;
- ref->object = object;
- wl_list_insert(display->global_list.prev, &ref->link);
+ global->object = object;
+ global->func = func;
+ wl_list_insert(display->global_list.prev, &global->link);
return 0;
}
diff --git a/wayland.h b/wayland.h
index ff43572..09567e0 100644
--- a/wayland.h
+++ b/wayland.h
@@ -85,7 +85,10 @@ int wl_display_add_socket(struct wl_display *display, const char *name, size_t n
void wl_display_run(struct wl_display *display);
void wl_display_add_object(struct wl_display *display, struct wl_object *object);
-int wl_display_add_global(struct wl_display *display, struct wl_object *object);
+
+typedef void (*wl_client_connect_func_t)(struct wl_client *client, struct wl_object *global);
+
+int wl_display_add_global(struct wl_display *display, struct wl_object *object, wl_client_connect_func_t func);
struct wl_compositor {
struct wl_object base;
@@ -121,6 +124,11 @@ struct wl_surface_interface {
};
void
+wl_client_post_event(struct wl_client *client,
+ struct wl_object *sender,
+ uint32_t event, ...);
+
+void
wl_surface_post_event(struct wl_surface *surface,
struct wl_object *sender,
uint32_t event, ...);