diff options
author | Marius Vlad <marius.vlad@collabora.com> | 2022-08-18 18:07:29 +0300 |
---|---|---|
committer | Marius Vlad <marius.vlad@collabora.com> | 2022-08-30 13:06:56 +0300 |
commit | 9f39c12f709fc9f59b06b0ebbc6b1d9065846f98 (patch) | |
tree | 64039629cb43c0fb972d55d38e848619ffee15be | |
parent | 0b21156c3b4f049325dbc7937aabb1f689ed945d (diff) |
main: Add support for binding to wl_output version 4
This allows the ability to specify which output to activate the
surface/application.
Note that this requires a libweston update to include support for this
new interface update, but it still fallbacks to to version 3 and uses
the first available output if uses that older interface.
Bug-AGL: SPEC-4530
Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
Change-Id: I151368720093422565746a01048fc2802c55c553
-rw-r--r-- | src/main.c | 67 |
1 files changed, 55 insertions, 12 deletions
@@ -1,5 +1,5 @@ /* - * Copyright 2021 Collabora, Ltd. + * Copyright 2021, 2022 Collabora, Ltd. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -33,6 +33,13 @@ #include <wayland-util.h> #include "agl-shell-desktop-client-protocol.h" +#ifndef MIN +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif +#ifndef MAX +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif + static int running = 1; const char *app_id_to_activate = NULL; @@ -40,8 +47,9 @@ struct display; struct window_output { struct display *display; - struct wl_output *output; - struct wl_list link; /** display::output_list */ + struct wl_output *output; + char *name; + struct wl_list link; /** display::output_list */ }; struct display { @@ -78,6 +86,10 @@ display_handle_scale(void *data, struct wl_output *wl_output, int32_t factor) static void display_handle_name(void *data, struct wl_output *wl_output, const char *name) { + struct window_output *woutput = data; + woutput->name = strdup(name); + + fprintf(stderr, "Adding output '%s'\n", name); } static void @@ -96,23 +108,28 @@ static const struct wl_output_listener output_listener = { static void -display_add_output(struct display *display, uint32_t id) +display_add_output(struct display *display, uint32_t id, uint32_t version) { struct window_output *w_output; w_output = calloc(1, sizeof(*w_output)); w_output->display = display; - w_output->output = - wl_registry_bind(display->registry, id, &wl_output_interface, 2); - wl_list_insert(&display->output_list, &w_output->link); + if (version < 4) + w_output->output = + wl_registry_bind(display->registry, id, &wl_output_interface, MAX(version, 3)); + else + w_output->output = + wl_registry_bind(display->registry, id, &wl_output_interface, MIN(version, 4)); - wl_output_add_listener(w_output->output, &output_listener, display); + wl_list_insert(&display->output_list, &w_output->link); + wl_output_add_listener(w_output->output, &output_listener, w_output); } static void destroy_output(struct window_output *w_output) { + free(w_output->name); wl_list_remove(&w_output->link); free(w_output); } @@ -150,7 +167,10 @@ registry_handle_global(void *data, struct wl_registry *registry, agl_shell_desktop_add_listener(d->agl_shell_desktop, &desktop_shell_listener, d); } else if (strcmp(interface, "wl_output") == 0) { - display_add_output(d, id); + if (version < 4) + fprintf(stderr, "Failed to bind to version 4. " + "Current version %d\n", version); + display_add_output(d, id, version); } } @@ -213,13 +233,18 @@ destroy_display(struct display *display) int main(int argc, char *argv[]) { struct display *display; - struct window_output *w_output; + struct window_output *w_output = NULL; + char *output_name = NULL; int ret = 0; if (argc < 2) { exit(EXIT_FAILURE); } + if (argc == 3) { + output_name = argv[2]; + } + display = create_display(); /* the app has to be already started, or not already active */ @@ -227,8 +252,26 @@ int main(int argc, char *argv[]) if (app_id_to_activate && strlen(app_id_to_activate) == 0) exit(EXIT_FAILURE); - /* pick the first one available */ - w_output = wl_container_of(display->output_list.prev, w_output, link); + if (output_name) { + struct window_output *woutput; + + wl_list_for_each(woutput, &display->output_list, link) { + if (woutput->name && !strcmp(woutput->name, output_name)) { + w_output = woutput; + break; + } + } + } else { + w_output = wl_container_of(display->output_list.prev, w_output, link); + } + + /* maybe that output doesn't exit, still allow a fallback */ + if (!w_output) + w_output = wl_container_of(display->output_list.prev, w_output, link); + + fprintf(stderr, "Activating application '%s' on output '%s'\n", + app_id_to_activate, w_output->name ? + w_output->name : "first default output"); agl_shell_desktop_activate_app(display->agl_shell_desktop, app_id_to_activate, NULL, w_output->output); |