diff --git a/include/wlr/types/wlr_xdg_output.h b/include/wlr/types/wlr_xdg_output.h index 27dad2b8..5e6a0780 100644 --- a/include/wlr/types/wlr_xdg_output.h +++ b/include/wlr/types/wlr_xdg_output.h @@ -4,10 +4,10 @@ #include struct wlr_xdg_output { - struct wl_list link; - struct wl_list resources; - struct wlr_xdg_output_manager *manager; + struct wl_list resources; + struct wl_list link; + struct wlr_output_layout_output *layout_output; struct wl_listener destroy; @@ -15,7 +15,7 @@ struct wlr_xdg_output { struct wlr_xdg_output_manager { struct wl_global *global; - + struct wl_list resources; struct wlr_output_layout *layout; struct wl_list outputs; diff --git a/types/wlr_xdg_output.c b/types/wlr_xdg_output.c index 182c5c37..20df24ba 100644 --- a/types/wlr_xdg_output.c +++ b/types/wlr_xdg_output.c @@ -6,23 +6,22 @@ #include #include "xdg-output-unstable-v1-protocol.h" -static void xdg_output_destroy(struct wl_client *client, +#define OUTPUT_MANAGER_VERSION 1 + +static void output_handle_destroy(struct wl_client *client, struct wl_resource *resource) { wl_resource_destroy(resource); } -static const struct zxdg_output_v1_interface xdg_output_implementation = { - .destroy = xdg_output_destroy, +static const struct zxdg_output_v1_interface output_implementation = { + .destroy = output_handle_destroy, }; -static void xdg_output_manager_destroy(struct wl_client *client, - struct wl_resource *resource) { - wl_resource_destroy(resource); +static void output_handle_resource_destroy(struct wl_resource *resource) { + wl_list_remove(wl_resource_get_link(resource)); } -static const struct zxdg_output_manager_v1_interface xdg_output_manager_implementation; - -static void xdg_output_send_details(struct wl_resource *resource, +static void output_send_details(struct wl_resource *resource, struct wlr_output_layout_output *layout_output) { zxdg_output_v1_send_logical_position(resource, layout_output->x, layout_output->y); @@ -32,18 +31,39 @@ static void xdg_output_send_details(struct wl_resource *resource, zxdg_output_v1_send_done(resource); } -static void xdg_output_manager_get_xdg_output(struct wl_client *client, - struct wl_resource *resource, uint32_t id, struct wl_resource *output) { +static void output_destroy(struct wlr_xdg_output *output) { + struct wl_resource *resource, *tmp; + wl_resource_for_each_safe(resource, tmp, &output->resources) { + wl_list_remove(wl_resource_get_link(resource)); + wl_list_init(wl_resource_get_link(resource)); + } + wl_list_remove(&output->destroy.link); + wl_list_remove(&output->link); + free(output); +} + + +static void output_manager_handle_destroy(struct wl_client *client, + struct wl_resource *resource) { + wl_resource_destroy(resource); +} + +static const struct zxdg_output_manager_v1_interface + output_manager_implementation; + +static void output_manager_handle_get_xdg_output(struct wl_client *client, + struct wl_resource *resource, uint32_t id, + struct wl_resource *output_resource) { assert(wl_resource_instance_of(resource, &zxdg_output_manager_v1_interface, - &xdg_output_manager_implementation)); + &output_manager_implementation)); struct wlr_xdg_output_manager *manager = wl_resource_get_user_data(resource); struct wlr_output_layout *layout = manager->layout; - struct wlr_output *wlr_output = wlr_output_from_resource(output); + struct wlr_output *output = wlr_output_from_resource(output_resource); struct wlr_output_layout_output *layout_output = - wlr_output_layout_get(layout, wlr_output); + wlr_output_layout_get(layout, output); assert(layout_output); struct wlr_xdg_output *_xdg_output, *xdg_output = NULL; @@ -55,58 +75,56 @@ static void xdg_output_manager_get_xdg_output(struct wl_client *client, } assert(xdg_output); - struct wl_resource *output_resource = wl_resource_create(client, + struct wl_resource *xdg_output_resource = wl_resource_create(client, &zxdg_output_v1_interface, wl_resource_get_version(resource), id); - if (!output_resource) { + if (!xdg_output_resource) { wl_client_post_no_memory(client); return; } - wl_resource_set_implementation(output_resource, - &xdg_output_implementation, NULL, NULL); - xdg_output_send_details(output_resource, layout_output); + wl_resource_set_implementation(xdg_output_resource, &output_implementation, + NULL, output_handle_resource_destroy); + output_send_details(xdg_output_resource, layout_output); wl_list_insert(&xdg_output->resources, - wl_resource_get_link(output_resource)); + wl_resource_get_link(xdg_output_resource)); } -static const struct zxdg_output_manager_v1_interface xdg_output_manager_implementation = { - .destroy = xdg_output_manager_destroy, - .get_xdg_output = xdg_output_manager_get_xdg_output, +static const struct zxdg_output_manager_v1_interface + output_manager_implementation = { + .destroy = output_manager_handle_destroy, + .get_xdg_output = output_manager_handle_get_xdg_output, }; +static void output_manager_handle_resource_destroy( + struct wl_resource *resource) { + wl_list_remove(wl_resource_get_link(resource)); +} + static void output_manager_bind(struct wl_client *wl_client, void *data, uint32_t version, uint32_t id) { struct wlr_xdg_output_manager *manager = data; - assert(wl_client && manager); - struct wl_resource *wl_resource = wl_resource_create(wl_client, + struct wl_resource *resource = wl_resource_create(wl_client, &zxdg_output_manager_v1_interface, version, id); - if (wl_resource == NULL) { + if (resource == NULL) { wl_client_post_no_memory(wl_client); return; } - wl_resource_set_implementation(wl_resource, - &xdg_output_manager_implementation, manager, NULL); -} - -static void destroy_output(struct wlr_xdg_output *output) { - struct wl_resource *resource, *tmp; - wl_resource_for_each_safe(resource, tmp, &output->resources) { - wl_list_remove(wl_resource_get_link(resource)); - wl_list_init(wl_resource_get_link(resource)); - } - wl_list_remove(&output->destroy.link); - wl_list_remove(&output->link); - free(output); + wl_resource_set_implementation(resource, &output_manager_implementation, + manager, output_manager_handle_resource_destroy); + wl_list_insert(&manager->resources, wl_resource_get_link(resource)); } static void handle_output_destroy(struct wl_listener *listener, void *data) { struct wlr_xdg_output *output = wl_container_of(listener, output, destroy); - destroy_output(output); + output_destroy(output); } static void add_output(struct wlr_xdg_output_manager *manager, struct wlr_output_layout_output *layout_output) { struct wlr_xdg_output *output = calloc(1, sizeof(struct wlr_xdg_output)); + if (output == NULL) { + return; + } wl_list_init(&output->resources); output->manager = manager; output->layout_output = layout_output; @@ -115,13 +133,13 @@ static void add_output(struct wlr_xdg_output_manager *manager, wl_list_insert(&manager->outputs, &output->link); } -static void xdg_output_manager_send_details( +static void output_manager_send_details( struct wlr_xdg_output_manager *manager) { struct wlr_xdg_output *output; wl_list_for_each(output, &manager->outputs, link) { struct wl_resource *resource; wl_resource_for_each(resource, &output->resources) { - xdg_output_send_details(resource, output->layout_output); + output_send_details(resource, output->layout_output); } } } @@ -136,7 +154,7 @@ static void handle_layout_add(struct wl_listener *listener, void *data) { static void handle_layout_change(struct wl_listener *listener, void *data) { struct wlr_xdg_output_manager *manager = wl_container_of(listener, manager, layout_change); - xdg_output_manager_send_details(manager); + output_manager_send_details(manager); } static void handle_layout_destroy(struct wl_listener *listener, void *data) { @@ -156,12 +174,14 @@ struct wlr_xdg_output_manager *wlr_xdg_output_manager_create( manager->layout = layout; manager->global = wl_global_create(display, &zxdg_output_manager_v1_interface, - 1, manager, output_manager_bind); + OUTPUT_MANAGER_VERSION, manager, output_manager_bind); if (!manager->global) { free(manager); return NULL; + } + wl_list_init(&manager->resources); wl_list_init(&manager->outputs); struct wlr_output_layout_output *layout_output; wl_list_for_each(layout_output, &layout->outputs, link) { @@ -178,9 +198,13 @@ struct wlr_xdg_output_manager *wlr_xdg_output_manager_create( } void wlr_xdg_output_manager_destroy(struct wlr_xdg_output_manager *manager) { - struct wlr_xdg_output *output, *tmp; - wl_list_for_each_safe(output, tmp, &manager->outputs, link) { - destroy_output(output); + struct wlr_xdg_output *output, *output_tmp; + wl_list_for_each_safe(output, output_tmp, &manager->outputs, link) { + output_destroy(output); + } + struct wl_resource *resource, *resource_tmp; + wl_resource_for_each_safe(resource, resource_tmp, &manager->resources) { + wl_resource_destroy(resource); } wl_list_remove(&manager->layout_add.link); wl_list_remove(&manager->layout_change.link);