compositor: Support xdg_output_unstable_v1

The xdg-output resources are listed in each head struct. They become idle when
the respective weston_output has been removed again. The client is supposed to
destroy them explicitly afterwards.

After starting an XWayland client xrandr displays the logical size as expected.

Signed-off-by: Roman Gilg <subdiff@gmail.com>
dev
Roman Gilg 6 years ago committed by Daniel Stone
parent 29beeafde9
commit e97391c49f
  1. 2
      include/libweston/libweston.h
  2. 118
      libweston/compositor.c
  3. 2
      libweston/meson.build

@ -187,6 +187,8 @@ struct weston_head {
struct wl_list resource_list; /**< wl_output protocol objects */
struct wl_global *global; /**< wl_output global */
struct wl_list xdg_output_resource_list; /**< xdg_output protocol objects */
int32_t mm_width; /**< physical image width in mm */
int32_t mm_height; /**< physical image height in mm */
char *make; /**< monitor manufacturer (PNP ID) */

@ -60,6 +60,7 @@
#include "linux-dmabuf.h"
#include "viewporter-server-protocol.h"
#include "presentation-time-server-protocol.h"
#include "xdg-output-unstable-v1-server-protocol.h"
#include "linux-explicit-synchronization-unstable-v1-server-protocol.h"
#include "linux-explicit-synchronization.h"
#include "shared/fd-util.h"
@ -123,6 +124,15 @@ weston_mode_switch_send_events(struct weston_head *head,
if (version >= WL_OUTPUT_DONE_SINCE_VERSION)
wl_output_send_done(resource);
}
wl_resource_for_each(resource, &head->xdg_output_resource_list) {
zxdg_output_v1_send_logical_position(resource,
output->x,
output->y);
zxdg_output_v1_send_logical_size(resource,
output->width,
output->height);
zxdg_output_v1_send_done(resource);
}
}
static void
@ -4705,6 +4715,14 @@ weston_head_remove_global(struct weston_head *head)
wl_resource_set_destructor(resource, NULL);
wl_resource_set_user_data(resource, NULL);
}
wl_resource_for_each(resource, &head->xdg_output_resource_list) {
/* It's sufficient to unset the destructor, then the list elements
* won't be accessed.
*/
wl_resource_set_destructor(resource, NULL);
}
wl_list_init(&head->xdg_output_resource_list);
}
/** Get the backing object of wl_output
@ -4749,6 +4767,7 @@ weston_head_init(struct weston_head *head, const char *name)
wl_signal_init(&head->destroy_signal);
wl_list_init(&head->output_link);
wl_list_init(&head->resource_list);
wl_list_init(&head->xdg_output_resource_list);
head->name = strdup(name);
}
@ -5572,6 +5591,13 @@ weston_output_move(struct weston_output *output, int x, int y)
if (ver >= WL_OUTPUT_DONE_SINCE_VERSION)
wl_output_send_done(resource);
}
wl_resource_for_each(resource, &head->xdg_output_resource_list) {
zxdg_output_v1_send_logical_position(resource,
output->x,
output->y);
zxdg_output_v1_send_done(resource);
}
}
}
@ -5790,6 +5816,15 @@ weston_output_set_transform(struct weston_output *output,
if (ver >= WL_OUTPUT_DONE_SINCE_VERSION)
wl_output_send_done(resource);
}
wl_resource_for_each(resource, &head->xdg_output_resource_list) {
zxdg_output_v1_send_logical_position(resource,
output->x,
output->y);
zxdg_output_v1_send_logical_size(resource,
output->width,
output->height);
zxdg_output_v1_send_done(resource);
}
}
/* we must ensure that pointers are inside output, otherwise they disappear */
@ -6291,6 +6326,85 @@ weston_output_get_first_head(struct weston_output *output)
struct weston_head, output_link);
}
static void
xdg_output_unlist(struct wl_resource *resource)
{
wl_list_remove(wl_resource_get_link(resource));
}
static void
xdg_output_destroy(struct wl_client *client, struct wl_resource *resource)
{
wl_resource_destroy(resource);
}
static const struct zxdg_output_v1_interface xdg_output_interface = {
xdg_output_destroy
};
static void
xdg_output_manager_destroy(struct wl_client *client,
struct wl_resource *resource)
{
wl_resource_destroy(resource);
}
static void
xdg_output_manager_get_xdg_output(struct wl_client *client,
struct wl_resource *manager,
uint32_t id,
struct wl_resource *output_resource)
{
int version = wl_resource_get_version(manager);
struct weston_head *head = wl_resource_get_user_data(output_resource);
struct weston_output *output = head->output;
struct wl_resource *resource;
resource = wl_resource_create(client, &zxdg_output_v1_interface,
version, id);
if (resource == NULL) {
wl_client_post_no_memory(client);
return;
}
wl_list_insert(&head->xdg_output_resource_list,
wl_resource_get_link(resource));
wl_resource_set_implementation(resource, &xdg_output_interface,
NULL, xdg_output_unlist);
zxdg_output_v1_send_logical_position(resource, output->x, output->y);
zxdg_output_v1_send_logical_size(resource,
output->width,
output->height);
if (version >= ZXDG_OUTPUT_V1_NAME_SINCE_VERSION)
zxdg_output_v1_send_name(resource, head->name);
zxdg_output_v1_send_done(resource);
}
static const struct zxdg_output_manager_v1_interface xdg_output_manager_interface = {
xdg_output_manager_destroy,
xdg_output_manager_get_xdg_output
};
static void
bind_xdg_output_manager(struct wl_client *client,
void *data, uint32_t version, uint32_t id)
{
struct wl_resource *resource;
resource = wl_resource_create(client, &zxdg_output_manager_v1_interface,
version, id);
if (resource == NULL) {
wl_client_post_no_memory(client);
return;
}
wl_resource_set_implementation(resource, &xdg_output_manager_interface,
NULL, NULL);
}
static void
destroy_viewport(struct wl_resource *resource)
{
@ -6916,6 +7030,10 @@ weston_compositor_create(struct wl_display *display,
ec, bind_viewporter))
goto fail;
if (!wl_global_create(ec->wl_display, &zxdg_output_manager_v1_interface, 2,
ec, bind_xdg_output_manager))
goto fail;
if (!wl_global_create(ec->wl_display, &wp_presentation_interface, 1,
ec, bind_presentation))
goto fail;

@ -52,6 +52,8 @@ srcs_libweston = [
weston_touch_calibration_server_protocol_h,
viewporter_protocol_c,
viewporter_server_protocol_h,
xdg_output_unstable_v1_protocol_c,
xdg_output_unstable_v1_server_protocol_h,
weston_debug_protocol_c,
weston_debug_server_protocol_h,
]

Loading…
Cancel
Save