Replace commit/ack/frame protocol with simpler sync and frame callbacks
This commit is contained in:
parent
13b8ae4986
commit
9d69f8e796
|
@ -183,8 +183,8 @@ dnd_draw(struct dnd *dnd)
|
|||
cairo_destroy(cr);
|
||||
|
||||
window_copy_surface(dnd->window, &rectangle, surface);
|
||||
window_commit(dnd->window, dnd->key);
|
||||
cairo_surface_destroy(surface);
|
||||
window_flush(dnd->window);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -98,21 +98,22 @@ draw_stuff(cairo_surface_t *surface, int width, int height)
|
|||
}
|
||||
|
||||
struct flower {
|
||||
struct display *display;
|
||||
struct window *window;
|
||||
int x, y, width, height;
|
||||
int offset;
|
||||
};
|
||||
|
||||
static void
|
||||
handle_frame(struct window *window,
|
||||
uint32_t frame, uint32_t timestamp, void *data)
|
||||
frame_callback(void *data, uint32_t time)
|
||||
{
|
||||
struct flower *flower = data;
|
||||
|
||||
window_move(flower->window,
|
||||
flower->x + cos((flower->offset + timestamp) / 400.0) * 400 - flower->width / 2,
|
||||
flower->y + sin((flower->offset + timestamp) / 320.0) * 300 - flower->height / 2);
|
||||
window_commit(flower->window, 0);
|
||||
flower->x + cos((flower->offset + time) / 400.0) * 400 - flower->width / 2,
|
||||
flower->y + sin((flower->offset + time) / 320.0) * 300 - flower->height / 2);
|
||||
wl_display_frame_callback(display_get_display(flower->display),
|
||||
frame_callback, flower);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
@ -128,6 +129,7 @@ int main(int argc, char *argv[])
|
|||
flower.y = 384;
|
||||
flower.width = 200;
|
||||
flower.height = 200;
|
||||
flower.display = d;
|
||||
flower.window = window_create(d, "flower", flower.x, flower.y,
|
||||
flower.width, flower.height);
|
||||
|
||||
|
@ -145,10 +147,11 @@ int main(int argc, char *argv[])
|
|||
|
||||
draw_stuff(s, flower.width, flower.height);
|
||||
cairo_surface_flush(s);
|
||||
window_flush(flower.window);
|
||||
|
||||
window_set_user_data(flower.window, &flower);
|
||||
window_set_frame_handler(flower.window, handle_frame);
|
||||
window_commit(flower.window, 0);
|
||||
wl_display_frame_callback(display_get_display(d),
|
||||
frame_callback, &flower);
|
||||
|
||||
display_run(d);
|
||||
|
||||
|
|
|
@ -317,31 +317,21 @@ keyboard_focus_handler(struct window *window,
|
|||
}
|
||||
|
||||
static void
|
||||
acknowledge_handler(struct window *window,
|
||||
uint32_t key, uint32_t frame,
|
||||
void *data)
|
||||
{
|
||||
struct gears *gears = data;
|
||||
|
||||
if (key == 10) {
|
||||
if (gears->resized)
|
||||
resize_window(gears);
|
||||
|
||||
draw_gears(gears);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
frame_handler(struct window *window,
|
||||
uint32_t frame, uint32_t timestamp, void *data)
|
||||
frame_callback(void *data, uint32_t time)
|
||||
{
|
||||
struct gears *gears = data;
|
||||
|
||||
window_copy_image(gears->window, &gears->rectangle, gears->image);
|
||||
|
||||
window_commit(gears->window, 10);
|
||||
if (gears->resized)
|
||||
resize_window(gears);
|
||||
|
||||
gears->angle = (GLfloat) (timestamp % 8192) * 360 / 8192.0;
|
||||
draw_gears(gears);
|
||||
|
||||
gears->angle = (GLfloat) (time % 8192) * 360 / 8192.0;
|
||||
|
||||
wl_display_frame_callback(display_get_display(gears->d),
|
||||
frame_callback, gears);
|
||||
}
|
||||
|
||||
static struct gears *
|
||||
|
@ -417,13 +407,13 @@ gears_create(struct display *display)
|
|||
|
||||
resize_window(gears);
|
||||
draw_gears(gears);
|
||||
frame_handler(gears->window, 0, 0, gears);
|
||||
|
||||
window_set_user_data(gears->window, gears);
|
||||
window_set_resize_handler(gears->window, resize_handler);
|
||||
window_set_keyboard_focus_handler(gears->window, keyboard_focus_handler);
|
||||
window_set_acknowledge_handler(gears->window, acknowledge_handler);
|
||||
window_set_frame_handler(gears->window, frame_handler);
|
||||
|
||||
wl_display_frame_callback(display_get_display(gears->d),
|
||||
frame_callback, gears);
|
||||
|
||||
return gears;
|
||||
}
|
||||
|
|
|
@ -176,7 +176,7 @@ image_draw(struct image *image)
|
|||
g_object_unref(pb);
|
||||
|
||||
window_copy_surface(image->window, &rectangle, surface);
|
||||
window_commit(image->window, image->key);
|
||||
window_flush(image->window);
|
||||
cairo_surface_destroy(surface);
|
||||
}
|
||||
|
||||
|
|
|
@ -215,7 +215,7 @@ terminal_draw(struct terminal *terminal)
|
|||
|
||||
window_draw(terminal->window);
|
||||
terminal_draw_contents(terminal);
|
||||
window_commit(terminal->window, 0);
|
||||
window_flush(terminal->window);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -101,8 +101,7 @@ view_draw(struct view *view)
|
|||
poppler_page_render(page, cr);
|
||||
cairo_destroy(cr);
|
||||
g_object_unref(G_OBJECT(page));
|
||||
|
||||
window_commit(view->window, 0);
|
||||
window_flush(view->window);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -98,8 +98,6 @@ struct window {
|
|||
window_key_handler_t key_handler;
|
||||
window_button_handler_t button_handler;
|
||||
window_keyboard_focus_handler_t keyboard_focus_handler;
|
||||
window_acknowledge_handler_t acknowledge_handler;
|
||||
window_frame_handler_t frame_handler;
|
||||
window_motion_handler_t motion_handler;
|
||||
|
||||
void *user_data;
|
||||
|
@ -331,6 +329,21 @@ display_get_pointer_surface(struct display *display, int pointer,
|
|||
return cairo_surface_reference(surface);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
window_attach_surface(struct window *window);
|
||||
|
||||
static void
|
||||
free_surface(void *data)
|
||||
{
|
||||
struct window *window = data;
|
||||
|
||||
cairo_surface_destroy(window->pending_surface);
|
||||
window->pending_surface = NULL;
|
||||
if (window->cairo_surface)
|
||||
window_attach_surface(window);
|
||||
}
|
||||
|
||||
static void
|
||||
window_attach_surface(struct window *window)
|
||||
{
|
||||
|
@ -353,17 +366,14 @@ window_attach_surface(struct window *window)
|
|||
window->allocation.width,
|
||||
window->allocation.height);
|
||||
|
||||
wl_compositor_commit(window->display->compositor, 0);
|
||||
wl_display_sync_callback(display->display, free_surface, window);
|
||||
}
|
||||
|
||||
void
|
||||
window_commit(struct window *window, uint32_t key)
|
||||
window_flush(struct window *window)
|
||||
{
|
||||
if (window->cairo_surface) {
|
||||
if (window->cairo_surface)
|
||||
window_attach_surface(window);
|
||||
} else {
|
||||
wl_compositor_commit(window->display->compositor, key);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -848,6 +858,10 @@ window_copy_surface(struct window *window,
|
|||
|
||||
cairo_paint (cr);
|
||||
cairo_destroy (cr);
|
||||
|
||||
wl_surface_damage(window->surface,
|
||||
rectangle->x, rectangle->y,
|
||||
rectangle->width, rectangle->height);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -933,20 +947,6 @@ window_set_button_handler(struct window *window,
|
|||
window->button_handler = handler;
|
||||
}
|
||||
|
||||
void
|
||||
window_set_acknowledge_handler(struct window *window,
|
||||
window_acknowledge_handler_t handler)
|
||||
{
|
||||
window->acknowledge_handler = handler;
|
||||
}
|
||||
|
||||
void
|
||||
window_set_frame_handler(struct window *window,
|
||||
window_frame_handler_t handler)
|
||||
{
|
||||
window->frame_handler = handler;
|
||||
}
|
||||
|
||||
void
|
||||
window_set_motion_handler(struct window *window,
|
||||
window_motion_handler_t handler)
|
||||
|
@ -1022,48 +1022,6 @@ static const struct wl_drm_listener drm_listener = {
|
|||
drm_handle_authenticated
|
||||
};
|
||||
|
||||
static void
|
||||
display_handle_acknowledge(void *data,
|
||||
struct wl_compositor *compositor,
|
||||
uint32_t key, uint32_t frame)
|
||||
{
|
||||
struct display *d = data;
|
||||
struct window *window;
|
||||
|
||||
/* The acknowledge event means that the server processed our
|
||||
* last commit request and we can now safely free the old
|
||||
* window buffer if we resized and render the next frame into
|
||||
* our back buffer.. */
|
||||
wl_list_for_each(window, &d->window_list, link) {
|
||||
cairo_surface_destroy(window->pending_surface);
|
||||
window->pending_surface = NULL;
|
||||
if (window->cairo_surface)
|
||||
window_attach_surface(window);
|
||||
if (window->acknowledge_handler)
|
||||
(*window->acknowledge_handler)(window, key, frame, window->user_data);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
display_handle_frame(void *data,
|
||||
struct wl_compositor *compositor,
|
||||
uint32_t frame, uint32_t timestamp)
|
||||
{
|
||||
struct display *d = data;
|
||||
struct window *window;
|
||||
|
||||
wl_list_for_each(window, &d->window_list, link) {
|
||||
if (window->frame_handler)
|
||||
(*window->frame_handler)(window, frame,
|
||||
timestamp, window->user_data);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct wl_compositor_listener compositor_listener = {
|
||||
display_handle_acknowledge,
|
||||
display_handle_frame,
|
||||
};
|
||||
|
||||
static void
|
||||
display_handle_geometry(void *data,
|
||||
struct wl_output *output,
|
||||
|
@ -1111,8 +1069,6 @@ display_handle_global(struct wl_display *display, uint32_t id,
|
|||
|
||||
if (strcmp(interface, "compositor") == 0) {
|
||||
d->compositor = wl_compositor_create(display, id);
|
||||
wl_compositor_add_listener(d->compositor,
|
||||
&compositor_listener, d);
|
||||
} else if (strcmp(interface, "output") == 0) {
|
||||
d->output = wl_output_create(display, id);
|
||||
wl_output_add_listener(d->output, &output_listener, d);
|
||||
|
@ -1290,6 +1246,12 @@ display_create(int *argc, char **argv[], const GOptionEntry *option_entries)
|
|||
return d;
|
||||
}
|
||||
|
||||
struct wl_display *
|
||||
display_get_display(struct display *display)
|
||||
{
|
||||
return display->display;
|
||||
}
|
||||
|
||||
struct wl_compositor *
|
||||
display_get_compositor(struct display *display)
|
||||
{
|
||||
|
|
|
@ -38,6 +38,9 @@ struct input;
|
|||
struct display *
|
||||
display_create(int *argc, char **argv[], const GOptionEntry *option_entries);
|
||||
|
||||
struct wl_display *
|
||||
display_get_display(struct display *display);
|
||||
|
||||
struct wl_compositor *
|
||||
display_get_compositor(struct display *display);
|
||||
|
||||
|
@ -96,7 +99,6 @@ enum pointer_type {
|
|||
typedef void (*window_resize_handler_t)(struct window *window, void *data);
|
||||
typedef void (*window_redraw_handler_t)(struct window *window, void *data);
|
||||
typedef void (*window_frame_handler_t)(struct window *window, uint32_t frame, uint32_t timestamp, void *data);
|
||||
typedef void (*window_acknowledge_handler_t)(struct window *window, uint32_t key, uint32_t frame, void *data);
|
||||
typedef void (*window_key_handler_t)(struct window *window, uint32_t key, uint32_t unicode,
|
||||
uint32_t state, uint32_t modifiers, void *data);
|
||||
typedef void (*window_keyboard_focus_handler_t)(struct window *window,
|
||||
|
@ -121,8 +123,6 @@ window_create(struct display *display, const char *title,
|
|||
void
|
||||
window_draw(struct window *window);
|
||||
void
|
||||
window_commit(struct window *window, uint32_t key);
|
||||
void
|
||||
window_get_child_rectangle(struct window *window,
|
||||
struct rectangle *rectangle);
|
||||
void
|
||||
|
@ -146,6 +146,9 @@ window_copy_surface(struct window *window,
|
|||
struct rectangle *rectangle,
|
||||
cairo_surface_t *surface);
|
||||
|
||||
void
|
||||
window_flush(struct window *window);
|
||||
|
||||
void
|
||||
window_set_fullscreen(struct window *window, int fullscreen);
|
||||
|
||||
|
@ -168,9 +171,6 @@ window_set_resize_handler(struct window *window,
|
|||
void
|
||||
window_set_frame_handler(struct window *window,
|
||||
window_frame_handler_t handler);
|
||||
void
|
||||
window_set_acknowledge_handler(struct window *window,
|
||||
window_acknowledge_handler_t handler);
|
||||
|
||||
void
|
||||
window_set_key_handler(struct window *window,
|
||||
|
@ -188,10 +188,6 @@ void
|
|||
window_set_keyboard_focus_handler(struct window *window,
|
||||
window_keyboard_focus_handler_t handler);
|
||||
|
||||
void
|
||||
window_set_acknowledge_handler(struct window *window,
|
||||
window_acknowledge_handler_t handler);
|
||||
|
||||
void
|
||||
window_set_frame_handler(struct window *window,
|
||||
window_frame_handler_t handler);
|
||||
|
|
23
compositor.c
23
compositor.c
|
@ -349,12 +349,8 @@ wlsc_surface_update_matrix(struct wlsc_surface *es)
|
|||
void
|
||||
wlsc_compositor_finish_frame(struct wlsc_compositor *compositor, int msecs)
|
||||
{
|
||||
wl_display_post_frame(compositor->wl_display,
|
||||
&compositor->base,
|
||||
compositor->current_frame, msecs);
|
||||
|
||||
wl_display_post_frame(compositor->wl_display, msecs);
|
||||
wl_event_source_timer_update(compositor->timer_source, 5);
|
||||
compositor->current_frame++;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -426,6 +422,7 @@ surface_attach(struct wl_client *client,
|
|||
glBindTexture(GL_TEXTURE_2D, es->texture);
|
||||
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, buffer->image);
|
||||
es->visual = buffer->visual;
|
||||
wlsc_compositor_schedule_repaint(es->compositor);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -441,6 +438,7 @@ surface_map(struct wl_client *client,
|
|||
es->height = height;
|
||||
|
||||
wlsc_surface_update_matrix(es);
|
||||
wlsc_compositor_schedule_repaint(es->compositor);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -448,7 +446,9 @@ surface_damage(struct wl_client *client,
|
|||
struct wl_surface *surface,
|
||||
int32_t x, int32_t y, int32_t width, int32_t height)
|
||||
{
|
||||
/* FIXME: This need to take a damage region, of course. */
|
||||
struct wlsc_surface *es = (struct wlsc_surface *) surface;
|
||||
|
||||
wlsc_compositor_schedule_repaint(es->compositor);
|
||||
}
|
||||
|
||||
const static struct wl_surface_interface surface_interface = {
|
||||
|
@ -640,19 +640,8 @@ compositor_create_surface(struct wl_client *client,
|
|||
wl_client_add_resource(client, &surface->base.base);
|
||||
}
|
||||
|
||||
static void
|
||||
compositor_commit(struct wl_client *client,
|
||||
struct wl_compositor *compositor, uint32_t key)
|
||||
{
|
||||
struct wlsc_compositor *ec = (struct wlsc_compositor *) compositor;
|
||||
|
||||
wlsc_compositor_schedule_repaint(ec);
|
||||
wl_client_send_acknowledge(client, compositor, key, ec->current_frame);
|
||||
}
|
||||
|
||||
const static struct wl_compositor_interface compositor_interface = {
|
||||
compositor_create_surface,
|
||||
compositor_commit
|
||||
};
|
||||
|
||||
static void
|
||||
|
|
|
@ -154,7 +154,6 @@ struct wlsc_compositor {
|
|||
int repaint_needed;
|
||||
int repaint_on_timeout;
|
||||
struct timespec previous_swap;
|
||||
uint32_t current_frame;
|
||||
|
||||
uint32_t focus;
|
||||
|
||||
|
|
31
protocol.xml
31
protocol.xml
|
@ -1,6 +1,14 @@
|
|||
<protocol>
|
||||
|
||||
<interface name="display" version="1">
|
||||
<request name="sync">
|
||||
<arg name="key" type="uint"/>
|
||||
</request>
|
||||
|
||||
<request name="frame">
|
||||
<arg name="key" type="uint"/>
|
||||
</request>
|
||||
|
||||
<event name="invalid_object">
|
||||
<arg name="object_id" type="uint"/>
|
||||
</event>
|
||||
|
@ -21,26 +29,21 @@
|
|||
<event name="range">
|
||||
<arg name="base" type="uint"/>
|
||||
</event>
|
||||
|
||||
<event name="sync">
|
||||
<arg name="key" type="uint"/>
|
||||
</event>
|
||||
|
||||
<event name="frame">
|
||||
<arg name="key" type="uint"/>
|
||||
<arg name="time" type="uint"/>
|
||||
</event>
|
||||
</interface>
|
||||
|
||||
<interface name="compositor" version="1">
|
||||
<request name="create_surface">
|
||||
<arg name="id" type="new_id" interface="surface"/>
|
||||
</request>
|
||||
|
||||
<request name="commit">
|
||||
<arg name="key" type="uint"/>
|
||||
</request>
|
||||
|
||||
<event name="acknowledge">
|
||||
<arg name="key" type="uint"/>
|
||||
<arg name="frame" type="uint"/>
|
||||
</event>
|
||||
|
||||
<event name="frame">
|
||||
<arg name="frame" type="uint"/>
|
||||
<arg name="timestamp" type="uint"/>
|
||||
</event>
|
||||
</interface>
|
||||
|
||||
<interface name="drm" version="1">
|
||||
|
|
|
@ -59,6 +59,20 @@ struct wl_proxy {
|
|||
void *user_data;
|
||||
};
|
||||
|
||||
struct wl_sync_handler {
|
||||
wl_display_sync_func_t func;
|
||||
uint32_t key;
|
||||
void *data;
|
||||
struct wl_list link;
|
||||
};
|
||||
|
||||
struct wl_frame_handler {
|
||||
wl_display_frame_func_t func;
|
||||
uint32_t key;
|
||||
void *data;
|
||||
struct wl_list link;
|
||||
};
|
||||
|
||||
struct wl_display {
|
||||
struct wl_proxy proxy;
|
||||
struct wl_connection *connection;
|
||||
|
@ -78,6 +92,9 @@ struct wl_display {
|
|||
|
||||
wl_display_global_func_t global_handler;
|
||||
void *global_handler_data;
|
||||
|
||||
struct wl_list sync_list, frame_list;
|
||||
uint32_t key;
|
||||
};
|
||||
|
||||
static int
|
||||
|
@ -270,12 +287,49 @@ display_handle_range(void *data,
|
|||
display->next_range = range;
|
||||
}
|
||||
|
||||
static void
|
||||
display_handle_sync(void *data, struct wl_display *display, uint32_t key)
|
||||
{
|
||||
struct wl_sync_handler *handler;
|
||||
|
||||
handler = container_of(display->sync_list.next,
|
||||
struct wl_sync_handler, link);
|
||||
if (handler->key != key) {
|
||||
fprintf(stderr, "unsolicited sync event, client gone?\n");
|
||||
return;
|
||||
}
|
||||
|
||||
wl_list_remove(&handler->link);
|
||||
handler->func(handler->data);
|
||||
free(handler);
|
||||
}
|
||||
|
||||
static void
|
||||
display_handle_frame(void *data,
|
||||
struct wl_display *display, uint32_t key, uint32_t time)
|
||||
{
|
||||
struct wl_frame_handler *handler;
|
||||
|
||||
handler = container_of(display->frame_list. next,
|
||||
struct wl_frame_handler, link);
|
||||
if (handler->key != key) {
|
||||
fprintf(stderr, "unsolicited frame event, client gone?\n");
|
||||
return;
|
||||
}
|
||||
|
||||
wl_list_remove(&handler->link);
|
||||
handler->func(handler->data, time);
|
||||
free(handler);
|
||||
}
|
||||
|
||||
static const struct wl_display_listener display_listener = {
|
||||
display_handle_invalid_object,
|
||||
display_handle_invalid_method,
|
||||
display_handle_no_memory,
|
||||
display_handle_global,
|
||||
display_handle_range
|
||||
display_handle_range,
|
||||
display_handle_sync,
|
||||
display_handle_frame
|
||||
};
|
||||
|
||||
WL_EXPORT struct wl_display *
|
||||
|
@ -315,6 +369,9 @@ wl_display_create(const char *name, size_t name_size)
|
|||
display->proxy.display = display;
|
||||
wl_list_init(&display->proxy.listener_list);
|
||||
|
||||
wl_list_init(&display->sync_list);
|
||||
wl_list_init(&display->frame_list);
|
||||
|
||||
display->listener.implementation = (void(**)(void)) &display_listener;
|
||||
wl_list_insert(display->proxy.listener_list.prev, &display->listener.link);
|
||||
|
||||
|
@ -345,6 +402,46 @@ wl_display_get_fd(struct wl_display *display,
|
|||
return display->fd;
|
||||
}
|
||||
|
||||
WL_EXPORT int
|
||||
wl_display_sync_callback(struct wl_display *display,
|
||||
wl_display_sync_func_t func, void *data)
|
||||
{
|
||||
struct wl_sync_handler *handler;
|
||||
|
||||
handler = malloc(sizeof *handler);
|
||||
if (handler == NULL)
|
||||
return -1;
|
||||
|
||||
handler->func = func;
|
||||
handler->key = display->key++;
|
||||
handler->data = data;
|
||||
|
||||
wl_list_insert(display->sync_list.prev, &handler->link);
|
||||
wl_display_sync(display, handler->key);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
WL_EXPORT int
|
||||
wl_display_frame_callback(struct wl_display *display,
|
||||
wl_display_frame_func_t func, void *data)
|
||||
{
|
||||
struct wl_frame_handler *handler;
|
||||
|
||||
handler = malloc(sizeof *handler);
|
||||
if (handler == NULL)
|
||||
return -1;
|
||||
|
||||
handler->func = func;
|
||||
handler->key = display->key++;
|
||||
handler->data = data;
|
||||
|
||||
wl_list_insert(display->frame_list.prev, &handler->link);
|
||||
wl_display_frame(display, handler->key);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_event(struct wl_display *display,
|
||||
uint32_t id, uint32_t opcode, uint32_t size)
|
||||
|
|
|
@ -34,6 +34,8 @@ extern "C" {
|
|||
#define WL_DISPLAY_WRITABLE 0x02
|
||||
|
||||
typedef int (*wl_display_update_func_t)(uint32_t mask, void *data);
|
||||
typedef void (*wl_display_sync_func_t)(void *data);
|
||||
typedef void (*wl_display_frame_func_t)(void *data, uint32_t time);
|
||||
|
||||
struct wl_display *wl_display_create(const char *name, size_t name_size);
|
||||
void wl_display_destroy(struct wl_display *display);
|
||||
|
@ -41,6 +43,10 @@ int wl_display_get_fd(struct wl_display *display,
|
|||
wl_display_update_func_t update, void *data);
|
||||
uint32_t wl_display_allocate_id(struct wl_display *display);
|
||||
void wl_display_iterate(struct wl_display *display, uint32_t mask);
|
||||
int wl_display_sync_callback(struct wl_display *display,
|
||||
wl_display_sync_func_t func, void *data);
|
||||
int wl_display_frame_callback(struct wl_display *display,
|
||||
wl_display_frame_func_t func, void *data);
|
||||
|
||||
struct wl_global_listener;
|
||||
typedef void (*wl_display_global_func_t)(struct wl_display *display,
|
||||
|
|
|
@ -43,7 +43,6 @@ struct wl_client {
|
|||
struct wl_event_source *source;
|
||||
struct wl_display *display;
|
||||
struct wl_list resource_list;
|
||||
struct wl_list link;
|
||||
uint32_t id_count;
|
||||
};
|
||||
|
||||
|
@ -52,13 +51,20 @@ struct wl_display {
|
|||
struct wl_event_loop *loop;
|
||||
struct wl_hash_table *objects;
|
||||
|
||||
struct wl_list pending_frame_list;
|
||||
struct wl_list frame_list;
|
||||
uint32_t client_id_range;
|
||||
uint32_t id;
|
||||
|
||||
struct wl_list global_list;
|
||||
};
|
||||
|
||||
struct wl_frame_listener {
|
||||
struct wl_resource resource;
|
||||
struct wl_client *client;
|
||||
uint32_t key;
|
||||
struct wl_list link;
|
||||
};
|
||||
|
||||
struct wl_global {
|
||||
struct wl_object *object;
|
||||
wl_client_connect_func_t func;
|
||||
|
@ -200,7 +206,6 @@ wl_client_create(struct wl_display *display, int fd)
|
|||
wl_connection_create(fd, wl_client_connection_update, client);
|
||||
|
||||
wl_list_init(&client->resource_list);
|
||||
wl_list_init(&client->link);
|
||||
|
||||
wl_display_post_range(display, client);
|
||||
|
||||
|
@ -257,6 +262,7 @@ wl_resource_destroy(struct wl_resource *resource, struct wl_client *client)
|
|||
struct wl_display *display = client->display;
|
||||
|
||||
wl_list_remove(&resource->link);
|
||||
if (resource->base.id > 0)
|
||||
wl_hash_table_remove(display->objects, resource->base.id);
|
||||
resource->destroy(resource, client);
|
||||
}
|
||||
|
@ -268,30 +274,14 @@ wl_client_destroy(struct wl_client *client)
|
|||
|
||||
printf("disconnect from client %p\n", client);
|
||||
|
||||
wl_list_remove(&client->link);
|
||||
|
||||
wl_list_for_each_safe(resource, tmp, &client->resource_list, link) {
|
||||
wl_list_remove(&resource->link);
|
||||
resource->destroy(resource, client);
|
||||
}
|
||||
wl_list_for_each_safe(resource, tmp, &client->resource_list, link)
|
||||
wl_resource_destroy(resource, client);
|
||||
|
||||
wl_event_source_remove(client->source);
|
||||
wl_connection_destroy(client->connection);
|
||||
free(client);
|
||||
}
|
||||
|
||||
WL_EXPORT void
|
||||
wl_client_send_acknowledge(struct wl_client *client,
|
||||
struct wl_compositor *compositor,
|
||||
uint32_t key, uint32_t frame)
|
||||
{
|
||||
wl_list_remove(&client->link);
|
||||
wl_list_insert(client->display->pending_frame_list.prev,
|
||||
&client->link);
|
||||
wl_client_post_event(client, &compositor->base,
|
||||
WL_COMPOSITOR_ACKNOWLEDGE, key, frame);
|
||||
}
|
||||
|
||||
WL_EXPORT int
|
||||
wl_display_set_compositor(struct wl_display *display,
|
||||
struct wl_compositor *compositor,
|
||||
|
@ -307,6 +297,51 @@ wl_display_set_compositor(struct wl_display *display,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
display_sync(struct wl_client *client,
|
||||
struct wl_display *display, uint32_t key)
|
||||
{
|
||||
wl_client_post_event(client, &display->base, WL_DISPLAY_SYNC, key);
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_frame_listener(struct wl_resource *resource, struct wl_client *client)
|
||||
{
|
||||
struct wl_frame_listener *listener =
|
||||
container_of(resource, struct wl_frame_listener, resource);
|
||||
|
||||
wl_list_remove(&listener->link);
|
||||
free(listener);
|
||||
}
|
||||
|
||||
static void
|
||||
display_frame(struct wl_client *client,
|
||||
struct wl_display *display, uint32_t key)
|
||||
{
|
||||
struct wl_frame_listener *listener;
|
||||
|
||||
listener = malloc(sizeof *listener);
|
||||
if (listener == NULL) {
|
||||
wl_client_post_no_memory(client);
|
||||
return;
|
||||
}
|
||||
|
||||
/* The listener is a resource so we destroy it when the client
|
||||
* goes away. */
|
||||
listener->resource.destroy = destroy_frame_listener;
|
||||
listener->resource.base.id = 0;
|
||||
listener->client = client;
|
||||
listener->key = key;
|
||||
wl_list_insert(client->resource_list.prev, &listener->resource.link);
|
||||
wl_list_insert(display->frame_list.prev, &listener->link);
|
||||
}
|
||||
|
||||
struct wl_display_interface display_interface = {
|
||||
display_sync,
|
||||
display_frame
|
||||
};
|
||||
|
||||
|
||||
WL_EXPORT struct wl_display *
|
||||
wl_display_create(void)
|
||||
{
|
||||
|
@ -328,14 +363,14 @@ wl_display_create(void)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
wl_list_init(&display->pending_frame_list);
|
||||
wl_list_init(&display->frame_list);
|
||||
wl_list_init(&display->global_list);
|
||||
|
||||
display->client_id_range = 256; /* Gah, arbitrary... */
|
||||
|
||||
display->id = 1;
|
||||
display->base.interface = &wl_display_interface;
|
||||
display->base.implementation = NULL;
|
||||
display->base.implementation = (void (**)(void)) &display_interface;
|
||||
wl_display_add_object(display, &display->base);
|
||||
if (wl_display_add_global(display, &display->base, NULL)) {
|
||||
wl_event_loop_destroy(display->loop);
|
||||
|
@ -388,18 +423,15 @@ wl_surface_post_event(struct wl_surface *surface,
|
|||
}
|
||||
|
||||
WL_EXPORT void
|
||||
wl_display_post_frame(struct wl_display *display,
|
||||
struct wl_compositor *compositor,
|
||||
uint32_t frame, uint32_t msecs)
|
||||
wl_display_post_frame(struct wl_display *display, uint32_t time)
|
||||
{
|
||||
struct wl_client *client;
|
||||
struct wl_frame_listener *listener, *next;
|
||||
|
||||
wl_list_for_each(client, &display->pending_frame_list, link)
|
||||
wl_client_post_event(client, &compositor->base,
|
||||
WL_COMPOSITOR_FRAME, frame, msecs);
|
||||
|
||||
wl_list_remove(&display->pending_frame_list);
|
||||
wl_list_init(&display->pending_frame_list);
|
||||
wl_list_for_each_safe(listener, next, &display->frame_list, link) {
|
||||
wl_client_post_event(listener->client, &display->base,
|
||||
WL_DISPLAY_FRAME, listener->key, time);
|
||||
wl_resource_destroy(&listener->resource, listener->client);
|
||||
}
|
||||
}
|
||||
|
||||
WL_EXPORT struct wl_event_loop *
|
||||
|
|
|
@ -159,14 +159,7 @@ wl_display_set_compositor(struct wl_display *display,
|
|||
const struct wl_compositor_interface *implementation);
|
||||
|
||||
void
|
||||
wl_client_send_acknowledge(struct wl_client *client,
|
||||
struct wl_compositor *compositor,
|
||||
uint32_t key, uint32_t frame);
|
||||
|
||||
void
|
||||
wl_display_post_frame(struct wl_display *display,
|
||||
struct wl_compositor *compositor,
|
||||
uint32_t frame, uint32_t msecs);
|
||||
wl_display_post_frame(struct wl_display *display, uint32_t msecs);
|
||||
|
||||
void
|
||||
wl_client_add_resource(struct wl_client *client,
|
||||
|
|
Loading…
Reference in New Issue