This lets us boot strap the client side state cache. This commit also adds the first user
of this feature, an output object that represents the current output. Very simple
at this point, but will grow to something more like RandR 1.2.
wl_display_event_func_t event_handler;
void *event_handler_data;
+
+ uint32_t output_id;
+ int32_t width, height;
};
struct wl_compositor {
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)
{
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:
}
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)
{
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);
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 *
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,
+};
extern const struct wl_interface wl_input_device_interface;
+
+#define WL_OUTPUT_PRESENCE 0
+
+extern const struct wl_interface wl_output_interface;
+
#endif
struct wl_object base;
};
+struct wl_output {
+ struct wl_object base;
+};
+
struct wlsc_input_device {
struct wl_object base;
int32_t x, y;
struct egl_compositor {
struct wl_compositor base;
+ struct wl_output output;
struct wl_visual argb_visual, premultiplied_argb_visual, rgb_visual;
EGLDisplay display;
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";
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);
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);
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);
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)
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)
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;
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;
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;
}
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;
}
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;
};
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, ...);