[vlc-commits] [Git][videolan/vlc][master] 6 commits: xdg/shell: report output device from done callback

Hugo Beauzée-Luyssen (@chouquette) gitlab at videolan.org
Tue May 3 07:46:41 UTC 2022



Hugo Beauzée-Luyssen pushed to branch master at VideoLAN / VLC


Commits:
a4467c49 by Rémi Denis-Courmont at 2022-05-03T07:31:32+00:00
xdg/shell: report output device from done callback

wl_output protocol versions 2 and larger involve more than one callback
to describe the outputs. The `done` callback indicates that all
callbacks have been invoked.

For backward compatibility with version 1, the `done` callback is
triggered manually, though I doubt that we can meaningfully support
version 1 going forward.

- - - - -
a9371890 by Rémi Denis-Courmont at 2022-05-03T07:31:32+00:00
xdg/shell: rationalise output functions

Separate look-up and destruction.

- - - - -
1bcfc025 by Rémi Denis-Courmont at 2022-05-03T07:31:32+00:00
xdg/shell: add output_find_by_name()

- - - - -
29688812 by Rémi Denis-Courmont at 2022-05-03T07:31:32+00:00
xdg/shell: look-up output for fullscreen mode

The existing code was blindly trusting that the provided object name
corresponded to a wl_output object and proxied it. This checks
that the ID corresponds to an already proxied object instead.

- - - - -
a2c23389 by Rémi Denis-Courmont at 2022-05-03T07:31:32+00:00
configure: bump wayland-client requirement

Get the protocol definition for wl_output version 4.

- - - - -
9c395de7 by Rémi Denis-Courmont at 2022-05-03T07:31:32+00:00
xdg/shell: get output name name description

Fixes #20571.

- - - - -


4 changed files:

- configure.ac
- modules/video_output/wayland/output.c
- modules/video_output/wayland/output.h
- modules/video_output/wayland/xdg-shell.c


Changes:

=====================================
configure.ac
=====================================
@@ -3328,7 +3328,7 @@ AS_IF([test "${enable_wayland}" != "no"], [
   wl_err=""
 
   dnl wayland
-  PKG_CHECK_MODULES([WAYLAND_CLIENT], [wayland-client >= 1.5.91],, [
+  PKG_CHECK_MODULES([WAYLAND_CLIENT], [wayland-client >= 1.19.91],, [
     wl_err="$wl_err ${WAYLAND_CLIENT_PKG_ERRORS}."
   ])
   PKG_CHECK_MODULES([WAYLAND_CURSOR], [wayland-cursor],, [


=====================================
modules/video_output/wayland/output.c
=====================================
@@ -24,6 +24,7 @@
 # include <config.h>
 #endif
 
+#include <assert.h>
 #include <inttypes.h>
 #include <stdlib.h>
 #include <wayland-client.h>
@@ -32,8 +33,6 @@
 
 #include "output.h"
 
-/* TODO: xdg_output protocol */
-
 struct output_list
 {
     vout_window_t *owner;
@@ -45,11 +44,16 @@ struct output_data
     vout_window_t *owner;
     struct wl_output *wl_output;
 
-    uint32_t name;
+    uint32_t id;
     uint32_t version;
+    char *name;
+    char *description;
+
     struct wl_list node;
 };
 
+static void output_done_cb(void *data, struct wl_output *output);
+
 static void output_geometry_cb(void *data, struct wl_output *output,
                                int32_t x, int32_t y, int32_t w, int32_t h,
                                int32_t sp, const char *make, const char *model,
@@ -57,19 +61,25 @@ static void output_geometry_cb(void *data, struct wl_output *output,
 {
     struct output_data *od = data;
     vout_window_t *wnd = od->owner;
-    char idstr[11];
-    char *name;
 
     msg_Dbg(wnd, "output %"PRIu32" geometry: %"PRId32"x%"PRId32"mm"
             "+%"PRId32"+%"PRId32", subpixel %"PRId32", transform %"PRId32,
-            od->name, w, h, x, y, sp, transform);
+            od->id, w, h, x, y, sp, transform);
 
-    sprintf(idstr, "%"PRIu32, od->name);
-    if (likely(asprintf(&name, "%s - %s", make, model) >= 0))
+    if (od->version < WL_OUTPUT_NAME_SINCE_VERSION)
     {
-        vout_window_ReportOutputDevice(wnd, idstr, name);
-        free(name);
+        free(od->name);
+        if (unlikely(asprintf(&od->name, "%"PRIu32, od->id) < 0))
+            od->name = NULL;
     }
+
+    if (od->version < WL_OUTPUT_DESCRIPTION_SINCE_VERSION)
+    {
+        free(od->description);
+        if (unlikely(asprintf(&od->description, "%s - %s", make, model) < 0))
+            od->description = NULL;
+    }
+
     (void) output;
 }
 
@@ -81,13 +91,27 @@ static void output_mode_cb(void *data, struct wl_output *output,
     div_t d = div(vr, 1000);
 
     msg_Dbg(wnd, "output %"PRIu32" mode: 0x%"PRIx32" %"PRId32"x%"PRId32
-            ", %d.%03d Hz", od->name, flags, w, h, d.quot, d.rem);
+            ", %d.%03d Hz", od->id, flags, w, h, d.quot, d.rem);
+
+    if (od->version < WL_OUTPUT_DONE_SINCE_VERSION)
+        output_done_cb(data, output); /* Ancient display server */
+
     (void) output;
 }
 
 static void output_done_cb(void *data, struct wl_output *output)
 {
-    (void) data; (void) output;
+    struct output_data *od = data;
+    vout_window_t *wnd = od->owner;
+    const char *name = od->name;
+    const char *description = od->description;
+
+    if (unlikely(description == NULL))
+        description = name;
+    if (likely(name != NULL))
+        vout_window_ReportOutputDevice(wnd, name, description);
+
+    (void) output;
 }
 
 static void output_scale_cb(void *data, struct wl_output *output, int32_t f)
@@ -95,16 +119,39 @@ static void output_scale_cb(void *data, struct wl_output *output, int32_t f)
     struct output_data *od = data;
     vout_window_t *wnd = od->owner;
 
-    msg_Dbg(wnd, "output %"PRIu32" scale: %"PRId32, od->name, f);
+    msg_Dbg(wnd, "output %"PRIu32" scale: %"PRId32, od->id, f);
     (void) output;
 }
 
+static void output_name_cb(void *data, struct wl_output *output,
+                           const char *name)
+{
+    struct output_data *od = data;
+
+    free(od->name);
+    od->name = strdup(name);
+    (void) output;
+}
+
+static void output_description_cb(void *data, struct wl_output *output,
+                                  const char *description)
+{
+    struct output_data *od = data;
+
+    free(od->description);
+    od->description = strdup(description);
+    (void) output;
+}
+
+
 static const struct wl_output_listener wl_output_cbs =
 {
     output_geometry_cb,
     output_mode_cb,
     output_done_cb,
     output_scale_cb,
+    output_name_cb,
+    output_description_cb,
 };
 
 struct output_list *output_list_create(vout_window_t *wnd)
@@ -118,42 +165,53 @@ struct output_list *output_list_create(vout_window_t *wnd)
     return ol;
 }
 
-int output_create(struct output_list *ol, struct wl_registry *registry,
-                  uint32_t name, uint32_t version)
+struct wl_output *output_create(struct output_list *ol,
+                                struct wl_registry *registry,
+                                uint32_t id, uint32_t version)
 {
     if (unlikely(ol == NULL))
-        return -1;
+        return NULL;
 
     struct output_data *od = malloc(sizeof (*od));
     if (unlikely(od == NULL))
-        return -1;
+        return NULL;
 
     if (version > 3)
         version = 3;
 
-    od->wl_output = wl_registry_bind(registry, name, &wl_output_interface,
-                                     version);
-    if (unlikely(od->wl_output == NULL))
+    struct wl_output *wo = wl_registry_bind(registry, id,
+                                            &wl_output_interface, version);
+    if (unlikely(wo == NULL))
     {
         free(od);
-        return -1;
+        return NULL;
     }
 
+    od->wl_output = wo;
     od->owner = ol->owner;
-    od->name = name;
+    od->id = id;
     od->version = version;
+    od->name = NULL;
+    od->description = NULL;
 
-    wl_output_add_listener(od->wl_output, &wl_output_cbs, od);
+    wl_output_add_listener(wo, &wl_output_cbs, od);
     wl_list_insert(&ol->outputs, &od->node);
-    return 0;
+    return wo;
 }
 
-static void output_destroy(struct output_list *ol, struct output_data *od)
+void output_destroy(struct output_list *ol, struct wl_output *wo)
 {
-    char idstr[11];
+    assert(ol != NULL);
+    assert(wo != NULL);
+
+    struct output_data *od = wl_output_get_user_data(wo);
 
-    sprintf(idstr, "%"PRIu32, od->name);
-    vout_window_ReportOutputDevice(ol->owner, idstr, NULL);
+    free(od->description);
+
+    if (od->name != NULL) {
+        vout_window_ReportOutputDevice(ol->owner, od->name, NULL);
+        free(od->name);
+    }
 
     wl_list_remove(&od->node);
 
@@ -164,25 +222,35 @@ static void output_destroy(struct output_list *ol, struct output_data *od)
     free(od);
 }
 
-int output_destroy_by_name(struct output_list *ol, uint32_t name)
+struct wl_output *output_find_by_id(struct output_list *ol, uint32_t id)
 {
     if (unlikely(ol == NULL))
-        return -1;
+        return NULL;
 
     struct wl_list *list = &ol->outputs;
     struct output_data *od;
 
     wl_list_for_each(od, list, node)
-    {
-        if (od->name == name)
-        {
-            output_destroy(ol, od);
-            /* Note: return here so no needs for safe walk variant */
-            return 0;
-        }
-    }
+        if (od->id == id)
+            return od->wl_output;
+
+    return NULL;
+}
+
+struct wl_output *output_find_by_name(struct output_list *ol, const char *name)
+{
+    if (unlikely(ol == NULL))
+        return NULL;
+
+    struct wl_list *list = &ol->outputs;
+    struct output_data *od;
+
+    wl_list_for_each(od, list, node)
+        if (strcmp(od->name, name) == 0)
+            return od->wl_output;
+
+    return NULL;
 
-    return -1;
 }
 
 void output_list_destroy(struct output_list *ol)
@@ -192,8 +260,11 @@ void output_list_destroy(struct output_list *ol)
 
     struct wl_list *list = &ol->outputs;
 
-    while (!wl_list_empty(list))
-        output_destroy(ol, container_of(list->next, struct output_data, node));
+    while (!wl_list_empty(list)) {
+        struct output_data *od = container_of(list->next, struct output_data,
+                                              node);
+        output_destroy(ol, od->wl_output);
+    }
 
     free(ol);
 }


=====================================
modules/video_output/wayland/output.h
=====================================
@@ -23,7 +23,10 @@ struct wl_registry;
 struct output_list;
 
 struct output_list *output_list_create(struct vout_window_t *wnd);
-int output_create(struct output_list *, struct wl_registry *,
-                  uint32_t name, uint32_t version);
-int output_destroy_by_name(struct output_list *, uint32_t name);
 void output_list_destroy(struct output_list *);
+
+struct wl_output *output_create(struct output_list *, struct wl_registry *,
+                                uint32_t id, uint32_t version);
+struct wl_output *output_find_by_id(struct output_list *, uint32_t id);
+struct wl_output *output_find_by_name(struct output_list *, const char *name);
+void output_destroy(struct output_list *, struct wl_output *);


=====================================
modules/video_output/wayland/xdg-shell.c
=====================================
@@ -219,24 +219,12 @@ static void SetFullscreen(vout_window_t *wnd, const char *idstr)
     struct wl_output *output = NULL;
 
     if (idstr != NULL)
-    {
-        char *end;
-        unsigned long name = strtoul(idstr, &end, 10);
-
-        assert(*end == '\0' && name <= UINT32_MAX);
-        output = wl_registry_bind(sys->registry, name,
-                                  &wl_output_interface, 1);
-    }
+        output = output_find_by_name(sys->outputs, idstr);
     else
     if (sys->default_output != 0)
-        output = wl_registry_bind(sys->registry, sys->default_output,
-                                  &wl_output_interface, 1);
+        output = output_find_by_id(sys->outputs, sys->default_output);
 
     xdg_toplevel_set_fullscreen(sys->toplevel, output);
-
-    if (output != NULL)
-        wl_output_destroy(output);
-
     wl_display_flush(wnd->display.wl);
 }
 
@@ -509,7 +497,7 @@ struct registry_handler
 static const struct registry_handler global_handlers[] =
 {
      { "wl_compositor", register_wl_compositor, 2 },
-     { "wl_output", register_wl_output, 1},
+     { "wl_output", register_wl_output, 4 },
      { "wl_seat", register_wl_seat, UINT32_C(-1) },
 #ifndef XDG_SHELL
      { "wl_shell", register_wl_shell, 1 },
@@ -557,8 +545,12 @@ static void registry_global_remove_cb(void *data, struct wl_registry *registry,
 
     if (seat_destroy_one(&sys->seats, name) == 0)
         return;
-    if (output_destroy_by_name(sys->outputs, name) == 0)
+
+    struct wl_output *output = output_find_by_id(sys->outputs, name);
+    if (output != NULL) {
+        output_destroy(sys->outputs, output);
         return;
+    }
 
     (void) registry;
 }



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/a9f4fdd77251de7f348ee6722346acfebecb9306...9c395de77cde9b6dd54d10f526f97048ff43d0fe

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/a9f4fdd77251de7f348ee6722346acfebecb9306...9c395de77cde9b6dd54d10f526f97048ff43d0fe
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list