Introduce wl_signal

This is mostly renaming and consolidating the listener_list pattern
into something more concise and reusable.
This commit is contained in:
Kristian Høgsberg 2012-04-12 15:29:48 -04:00
parent 5535f155d8
commit 6802eaa68a
3 changed files with 82 additions and 69 deletions

View file

@ -77,8 +77,7 @@ static const struct wl_data_offer_interface data_offer_interface = {
}; };
static void static void
destroy_offer_data_source(struct wl_listener *listener, destroy_offer_data_source(struct wl_listener *listener, void *data)
struct wl_resource *resource)
{ {
struct wl_data_offer *offer; struct wl_data_offer *offer;
@ -111,12 +110,12 @@ wl_data_source_send_offer(struct wl_data_source *source,
offer->resource.object.implementation = offer->resource.object.implementation =
(void (**)(void)) source->offer_interface; (void (**)(void)) source->offer_interface;
offer->resource.data = offer; offer->resource.data = offer;
wl_list_init(&offer->resource.destroy_listener_list); wl_signal_init(&offer->resource.destroy_signal);
offer->source = source; offer->source = source;
offer->source_destroy_listener.func = destroy_offer_data_source; offer->source_destroy_listener.notify = destroy_offer_data_source;
wl_list_insert(&source->resource.destroy_listener_list, wl_signal_add(&source->resource.destroy_signal,
&offer->source_destroy_listener.link); &offer->source_destroy_listener);
wl_client_add_resource(target->client, &offer->resource); wl_client_add_resource(target->client, &offer->resource);
@ -168,8 +167,7 @@ find_resource(struct wl_list *list, struct wl_client *client)
} }
static void static void
destroy_drag_focus(struct wl_listener *listener, destroy_drag_focus(struct wl_listener *listener, void *data)
struct wl_resource *resource)
{ {
struct wl_input_device *device = struct wl_input_device *device =
container_of(listener, struct wl_input_device, container_of(listener, struct wl_input_device,
@ -209,9 +207,9 @@ drag_grab_focus(struct wl_pointer_grab *grab,
x, y, offer); x, y, offer);
device->drag_focus = surface; device->drag_focus = surface;
device->drag_focus_listener.func = destroy_drag_focus; device->drag_focus_listener.notify = destroy_drag_focus;
wl_list_insert(resource->destroy_listener_list.prev, wl_signal_add(&resource->destroy_signal,
&device->drag_focus_listener.link); &device->drag_focus_listener);
device->drag_focus_resource = resource; device->drag_focus_resource = resource;
grab->focus = surface; grab->focus = surface;
} }
@ -275,8 +273,7 @@ static const struct wl_pointer_grab_interface drag_grab_interface = {
}; };
static void static void
destroy_data_device_source(struct wl_listener *listener, destroy_data_device_source(struct wl_listener *listener, void *data)
struct wl_resource *resource)
{ {
struct wl_input_device *device; struct wl_input_device *device;
@ -287,8 +284,7 @@ destroy_data_device_source(struct wl_listener *listener,
} }
static void static void
destroy_data_device_icon(struct wl_listener *listener, destroy_data_device_icon(struct wl_listener *listener, void *data)
struct wl_resource *resource)
{ {
struct wl_input_device *device; struct wl_input_device *device;
@ -305,7 +301,6 @@ data_device_start_drag(struct wl_client *client, struct wl_resource *resource,
struct wl_resource *icon_resource, uint32_t serial) struct wl_resource *icon_resource, uint32_t serial)
{ {
struct wl_input_device *device = resource->data; struct wl_input_device *device = resource->data;
struct wl_listener *listener, *tmp;
/* FIXME: Check that client has implicit grab on the origin /* FIXME: Check that client has implicit grab on the origin
* surface that matches the given time. */ * surface that matches the given time. */
@ -315,27 +310,23 @@ data_device_start_drag(struct wl_client *client, struct wl_resource *resource,
device->drag_grab.interface = &drag_grab_interface; device->drag_grab.interface = &drag_grab_interface;
device->drag_data_source = source_resource->data; device->drag_data_source = source_resource->data;
device->drag_data_source_listener.func = destroy_data_device_source; device->drag_data_source_listener.notify = destroy_data_device_source;
wl_list_insert(source_resource->destroy_listener_list.prev, wl_signal_add(&source_resource->destroy_signal,
&device->drag_data_source_listener.link); &device->drag_data_source_listener);
if (icon_resource) { if (icon_resource) {
device->drag_surface = icon_resource->data; device->drag_surface = icon_resource->data;
device->drag_icon_listener.func = destroy_data_device_icon; device->drag_icon_listener.notify = destroy_data_device_icon;
wl_list_insert(icon_resource->destroy_listener_list.prev, wl_signal_add(&icon_resource->destroy_signal,
&device->drag_icon_listener.link); &device->drag_icon_listener);
wl_signal_emit(&device->drag_icon_signal, icon_resource);
wl_list_for_each_safe(listener, tmp,
&device->drag_icon_listener_list, link)
listener->func(listener, icon_resource);
} }
wl_input_device_start_pointer_grab(device, &device->drag_grab); wl_input_device_start_pointer_grab(device, &device->drag_grab);
} }
static void static void
destroy_selection_data_source(struct wl_listener *listener, destroy_selection_data_source(struct wl_listener *listener, void *data)
struct wl_resource *resource)
{ {
struct wl_input_device *device = struct wl_input_device *device =
container_of(listener, struct wl_input_device, container_of(listener, struct wl_input_device,
@ -357,7 +348,6 @@ wl_input_device_set_selection(struct wl_input_device *device,
struct wl_data_source *source) struct wl_data_source *source)
{ {
struct wl_resource *data_device, *focus, *offer; struct wl_resource *data_device, *focus, *offer;
struct wl_selection_listener *listener, *next;
if (device->selection_data_source) { if (device->selection_data_source) {
device->selection_data_source->cancel(device->selection_data_source); device->selection_data_source->cancel(device->selection_data_source);
@ -378,14 +368,12 @@ wl_input_device_set_selection(struct wl_input_device *device,
} }
} }
wl_list_for_each_safe(listener, next, wl_signal_emit(&device->selection_signal, device);
&device->selection_listener_list, link)
listener->func(listener, device);
device->selection_data_source_listener.func = device->selection_data_source_listener.notify =
destroy_selection_data_source; destroy_selection_data_source;
wl_list_insert(source->resource.destroy_listener_list.prev, wl_signal_add(&source->resource.destroy_signal,
&device->selection_data_source_listener.link); &device->selection_data_source_listener);
} }
static void static void
@ -438,7 +426,7 @@ create_data_source(struct wl_client *client,
source->resource.object.implementation = source->resource.object.implementation =
(void (**)(void)) &data_source_interface; (void (**)(void)) &data_source_interface;
source->resource.data = source; source->resource.data = source;
wl_list_init(&source->resource.destroy_listener_list); wl_signal_init(&source->resource.destroy_signal);
source->offer_interface = &data_offer_interface; source->offer_interface = &data_offer_interface;
source->cancel = data_source_cancel; source->cancel = data_source_cancel;

View file

@ -368,7 +368,7 @@ wl_client_add_resource(struct wl_client *client,
resource->object.id, resource); resource->object.id, resource);
resource->client = client; resource->client = client;
wl_list_init(&resource->destroy_listener_list); wl_signal_init(&resource->destroy_signal);
} }
WL_EXPORT void WL_EXPORT void
@ -382,10 +382,8 @@ static void
destroy_resource(void *element, void *data) destroy_resource(void *element, void *data)
{ {
struct wl_resource *resource = element; struct wl_resource *resource = element;
struct wl_listener *l, *next;
wl_list_for_each_safe(l, next, &resource->destroy_listener_list, link) wl_signal_emit(&resource->destroy_signal, resource);
l->func(l, resource);
if (resource->destroy) if (resource->destroy)
resource->destroy(resource); resource->destroy(resource);
@ -428,8 +426,7 @@ wl_client_destroy(struct wl_client *client)
} }
static void static void
lose_pointer_focus(struct wl_listener *listener, lose_pointer_focus(struct wl_listener *listener, void *data)
struct wl_resource *resource)
{ {
struct wl_input_device *device = struct wl_input_device *device =
container_of(listener, struct wl_input_device, container_of(listener, struct wl_input_device,
@ -439,8 +436,7 @@ lose_pointer_focus(struct wl_listener *listener,
} }
static void static void
lose_keyboard_focus(struct wl_listener *listener, lose_keyboard_focus(struct wl_listener *listener, void *data)
struct wl_resource *resource)
{ {
struct wl_input_device *device = struct wl_input_device *device =
container_of(listener, struct wl_input_device, container_of(listener, struct wl_input_device,
@ -527,8 +523,8 @@ wl_input_device_init(struct wl_input_device *device)
memset(device, 0, sizeof *device); memset(device, 0, sizeof *device);
wl_list_init(&device->resource_list); wl_list_init(&device->resource_list);
wl_array_init(&device->keys); wl_array_init(&device->keys);
device->pointer_focus_listener.func = lose_pointer_focus; device->pointer_focus_listener.notify = lose_pointer_focus;
device->keyboard_focus_listener.func = lose_keyboard_focus; device->keyboard_focus_listener.notify = lose_keyboard_focus;
device->default_pointer_grab.interface = &default_pointer_grab_interface; device->default_pointer_grab.interface = &default_pointer_grab_interface;
device->default_pointer_grab.input_device = device; device->default_pointer_grab.input_device = device;
@ -540,9 +536,8 @@ wl_input_device_init(struct wl_input_device *device)
wl_list_init(&device->drag_resource_list); wl_list_init(&device->drag_resource_list);
device->selection_data_source = NULL; device->selection_data_source = NULL;
wl_list_init(&device->selection_listener_list); wl_signal_init(&device->selection_signal);
wl_signal_init(&device->drag_icon_signal);
wl_list_init(&device->drag_icon_listener_list);
device->x = 100; device->x = 100;
device->y = 100; device->y = 100;
@ -604,8 +599,8 @@ wl_input_device_set_pointer_focus(struct wl_input_device *device,
wl_input_device_send_pointer_enter(resource, serial, wl_input_device_send_pointer_enter(resource, serial,
&surface->resource, &surface->resource,
sx, sy); sx, sy);
wl_list_insert(resource->destroy_listener_list.prev, wl_signal_add(&resource->destroy_signal,
&device->pointer_focus_listener.link); &device->pointer_focus_listener);
device->pointer_focus_serial = serial; device->pointer_focus_serial = serial;
} }
@ -638,8 +633,8 @@ wl_input_device_set_keyboard_focus(struct wl_input_device *device,
wl_input_device_send_keyboard_enter(resource, serial, wl_input_device_send_keyboard_enter(resource, serial,
&surface->resource, &surface->resource,
&device->keys); &device->keys);
wl_list_insert(resource->destroy_listener_list.prev, wl_signal_add(&resource->destroy_signal,
&device->keyboard_focus_listener.link); &device->keyboard_focus_listener);
device->keyboard_focus_serial = serial; device->keyboard_focus_serial = serial;
} }
@ -1036,7 +1031,7 @@ wl_client_add_object(struct wl_client *client,
resource->client = client; resource->client = client;
resource->data = data; resource->data = data;
resource->destroy = (void *) free; resource->destroy = (void *) free;
wl_list_init(&resource->destroy_listener_list); wl_signal_init(&resource->destroy_signal);
if (wl_map_insert_at(&client->objects, resource->object.id, resource) < 0) { if (wl_map_insert_at(&client->objects, resource->object.id, resource) < 0) {
wl_resource_post_no_memory(client->display_resource); wl_resource_post_no_memory(client->display_resource);

View file

@ -114,11 +114,53 @@ wl_client_new_object(struct wl_client *client,
const struct wl_interface *interface, const struct wl_interface *interface,
const void *implementation, void *data); const void *implementation, void *data);
struct wl_listener {
struct wl_list link;
void (*notify)(struct wl_listener *listener, void *data);
};
struct wl_signal {
struct wl_list listener_list;
};
static inline void
wl_signal_init(struct wl_signal *signal)
{
wl_list_init(&signal->listener_list);
}
static inline void
wl_signal_add(struct wl_signal *signal, struct wl_listener *listener)
{
wl_list_insert(signal->listener_list.prev, &listener->link);
}
static inline struct wl_listener *
wl_signal_get(struct wl_signal *signal, void *notify)
{
struct wl_listener *l;
wl_list_for_each(l, &signal->listener_list, link)
if (l->notify == notify)
return l;
return NULL;
}
static inline void
wl_signal_emit(struct wl_signal *signal, void *data)
{
struct wl_listener *l, *next;
wl_list_for_each_safe(l, next, &signal->listener_list, link)
l->notify(l, data);
}
struct wl_resource { struct wl_resource {
struct wl_object object; struct wl_object object;
void (*destroy)(struct wl_resource *resource); void (*destroy)(struct wl_resource *resource);
struct wl_list link; struct wl_list link;
struct wl_list destroy_listener_list; struct wl_signal destroy_signal;
struct wl_client *client; struct wl_client *client;
void *data; void *data;
}; };
@ -129,12 +171,6 @@ struct wl_buffer {
uint32_t busy_count; uint32_t busy_count;
}; };
struct wl_listener {
struct wl_list link;
void (*func)(struct wl_listener *listener,
struct wl_resource *resource);
};
struct wl_surface { struct wl_surface {
struct wl_resource resource; struct wl_resource resource;
}; };
@ -183,12 +219,6 @@ struct wl_data_source {
void (*cancel)(struct wl_data_source *source); void (*cancel)(struct wl_data_source *source);
}; };
struct wl_selection_listener {
void (*func)(struct wl_selection_listener *listener,
struct wl_input_device *device);
struct wl_list link;
};
struct wl_input_device { struct wl_input_device {
struct wl_list resource_list; struct wl_list resource_list;
struct wl_resource *pointer_focus_resource; struct wl_resource *pointer_focus_resource;
@ -226,11 +256,11 @@ struct wl_input_device {
struct wl_pointer_grab drag_grab; struct wl_pointer_grab drag_grab;
struct wl_surface *drag_surface; struct wl_surface *drag_surface;
struct wl_listener drag_icon_listener; struct wl_listener drag_icon_listener;
struct wl_list drag_icon_listener_list; struct wl_signal drag_icon_signal;
struct wl_data_source *selection_data_source; struct wl_data_source *selection_data_source;
struct wl_listener selection_data_source_listener; struct wl_listener selection_data_source_listener;
struct wl_list selection_listener_list; struct wl_signal selection_signal;
}; };