[vlc-commits] xdg-shell: move output handling to separate file
Rémi Denis-Courmont
git at videolan.org
Thu May 24 19:33:13 CEST 2018
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Thu May 24 19:10:56 2018 +0300| [21047ec421f4bdfb1345284ebe285965b7aee237] | committer: Rémi Denis-Courmont
xdg-shell: move output handling to separate file
This follows the model already used for seats (i.e. inputs).
This avoids one race-prone round-trip at start-up.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=21047ec421f4bdfb1345284ebe285965b7aee237
---
modules/video_output/Makefile.am | 1 +
modules/video_output/wayland/output.c | 162 +++++++++++++++++++++++++++++++
modules/video_output/wayland/output.h | 28 ++++++
modules/video_output/wayland/xdg-shell.c | 96 ++----------------
4 files changed, 201 insertions(+), 86 deletions(-)
diff --git a/modules/video_output/Makefile.am b/modules/video_output/Makefile.am
index 279f461efd..89b71a4dc6 100644
--- a/modules/video_output/Makefile.am
+++ b/modules/video_output/Makefile.am
@@ -212,6 +212,7 @@ libwl_shell_plugin_la_CFLAGS = $(libxdg_shell_plugin_la_CFLAGS)
libwl_shell_plugin_la_LIBADD = $(libxdg_shell_plugin_la_LIBADD)
libxdg_shell_plugin_la_SOURCES = \
+ video_output/wayland/output.h video_output/wayland/output.c \
video_output/wayland/input.h video_output/wayland/input.c \
video_output/xcb/vlc_xkb.h video_output/xcb/xkb.c \
video_output/wayland/xdg-shell.c
diff --git a/modules/video_output/wayland/output.c b/modules/video_output/wayland/output.c
new file mode 100644
index 0000000000..dc85aac7c7
--- /dev/null
+++ b/modules/video_output/wayland/output.c
@@ -0,0 +1,162 @@
+/**
+ * @file input.c
+ * @brief Wayland input events for VLC media player
+ */
+/*****************************************************************************
+ * Copyright © 2018 Rémi Denis-Courmont
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <stdlib.h>
+#include <wayland-client.h>
+#include <vlc_common.h>
+#include <vlc_vout_window.h>
+
+#include "output.h"
+
+/* TODO: xdg_output protocol */
+
+struct output_data
+{
+ vout_window_t *owner;
+ struct wl_output *wl_output;
+
+ uint32_t name;
+ struct wl_list node;
+};
+
+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,
+ int32_t transform)
+{
+ 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);
+
+ sprintf(idstr, "%"PRIu32, od->name);
+ if (likely(asprintf(&name, "%s - %s", make, model) >= 0))
+ {
+ vout_window_ReportOutputDevice(wnd, idstr, name);
+ free(name);
+ }
+ (void) output;
+}
+
+static void output_mode_cb(void *data, struct wl_output *output,
+ uint32_t flags, int32_t w, int32_t h, int32_t vr)
+{
+ struct output_data *od = data;
+ vout_window_t *wnd = od->owner;
+ 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);
+ (void) output;
+}
+
+static void output_done_cb(void *data, struct wl_output *output)
+{
+ (void) data; (void) output;
+}
+
+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);
+ (void) output;
+}
+
+static const struct wl_output_listener wl_output_cbs =
+{
+ output_geometry_cb,
+ output_mode_cb,
+ output_done_cb,
+ output_scale_cb,
+};
+
+int output_create(vout_window_t *wnd, struct wl_registry *registry,
+ uint32_t name, uint32_t version, struct wl_list *list)
+{
+ struct output_data *od = malloc(sizeof (*od));
+ if (unlikely(od == NULL))
+ return -1;
+
+ if (version > 2)
+ version = 2;
+
+ od->wl_output = wl_registry_bind(registry, name, &wl_output_interface,
+ version);
+ if (unlikely(od->wl_output == NULL))
+ {
+ free(od);
+ return -1;
+ }
+
+ od->owner = wnd;
+ od->name = name;
+
+ wl_output_add_listener(od->wl_output, &wl_output_cbs, od);
+ wl_list_insert(list, &od->node);
+ return 0;
+}
+
+static void output_destroy(struct output_data *od)
+{
+ char idstr[11];
+
+ sprintf(idstr, "%"PRIu32, od->name);
+ vout_window_ReportOutputDevice(od->owner, idstr, NULL);
+
+ wl_list_remove(&od->node);
+ wl_output_destroy(od->wl_output);
+ free(od);
+}
+
+int output_destroy_one(struct wl_list *list, uint32_t name)
+{
+ struct output_data *od;
+
+ wl_list_for_each(od, list, node)
+ {
+ if (od->name == name)
+ {
+ output_destroy(od);
+ /* Note: return here so no needs for safe walk variant */
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+void output_destroy_all(struct wl_list *list)
+{
+ while (!wl_list_empty(list))
+ output_destroy(container_of(list->next, struct output_data, node));
+}
diff --git a/modules/video_output/wayland/output.h b/modules/video_output/wayland/output.h
new file mode 100644
index 0000000000..7d6710d90e
--- /dev/null
+++ b/modules/video_output/wayland/output.h
@@ -0,0 +1,28 @@
+/*****************************************************************************
+ * Copyright © 2018 Rémi Denis-Courmont
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#include <stdint.h>
+
+struct vout_window_t;
+struct wl_registry;
+struct wl_list;
+
+int output_create(struct vout_window_t *wnd, struct wl_registry *,
+ uint32_t name, uint32_t version, struct wl_list *list);
+int output_destroy_one(struct wl_list *list, uint32_t name);
+void output_destroy_all(struct wl_list *list);
diff --git a/modules/video_output/wayland/xdg-shell.c b/modules/video_output/wayland/xdg-shell.c
index 40dca03738..06d3a286a5 100644
--- a/modules/video_output/wayland/xdg-shell.c
+++ b/modules/video_output/wayland/xdg-shell.c
@@ -65,6 +65,7 @@
#include <vlc_vout_window.h>
#include "input.h"
+#include "output.h"
struct vout_window_sys_t
{
@@ -85,6 +86,7 @@ struct vout_window_sys_t
bool unstable;
#endif
+ struct wl_list outputs;
struct wl_list seats;
vlc_thread_t thread;
@@ -130,12 +132,6 @@ static void *Thread(void *data)
//return NULL;
}
-struct device_data
-{
- uint32_t name;
- struct vout_window_t *window;
-};
-
static int Control(vout_window_t *wnd, int cmd, va_list ap)
{
vout_window_sys_t *sys = wnd->sys;
@@ -321,64 +317,6 @@ static const struct wl_shell_surface_listener wl_shell_surface_cbs =
#define xdg_surface_cbs wl_shell_surface_cbs
#endif
-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,
- int32_t transform)
-{
- struct device_data *dd = data;
- struct vout_window_t *wnd = dd->window;
- char idstr[11];
- char *name;
-
- msg_Dbg(wnd, "output %"PRIu32" geometry: %"PRId32"x%"PRId32"mm"
- "+%"PRId32"+%"PRId32", subpixel %"PRId32", transform %"PRId32,
- dd->name, w, h, x, y, sp, transform);
-
- sprintf(idstr, "%"PRIu32, dd->name);
- if (likely(asprintf(&name, "%s - %s", make, model) >= 0))
- {
- vout_window_ReportOutputDevice(wnd, idstr, name);
- free(name);
- }
- (void) output;
-}
-
-static void output_mode_cb(void *data, struct wl_output *output,
- uint32_t flags, int32_t w, int32_t h, int32_t vr)
-{
- struct device_data *dd = data;
- struct vout_window_t *wnd = dd->window;
- div_t d = div(vr, 1000);
-
- msg_Dbg(wnd, "output %"PRIu32" mode: 0x%"PRIx32" %"PRId32"x%"PRId32
- ", %d.%03d Hz", dd->name, flags, w, h, d.quot, d.rem);
- (void) output;
-}
-
-static void output_done_cb(void *data, struct wl_output *output)
-{
- wl_output_destroy(output);
- free(data);
-}
-
-static void output_scale_cb(void *data, struct wl_output *output, int32_t f)
-{
- struct device_data *dd = data;
- struct vout_window_t *wnd = dd->window;
-
- msg_Dbg(wnd, "output %"PRIu32" scale: %"PRId32, dd->name, f);
- (void) output;
-}
-
-static const struct wl_output_listener output_cbs =
-{
- output_geometry_cb,
- output_mode_cb,
- output_done_cb,
- output_scale_cb,
-};
-
static void registry_global_cb(void *data, struct wl_registry *registry,
uint32_t name, const char *iface, uint32_t vers)
{
@@ -392,22 +330,6 @@ static void registry_global_cb(void *data, struct wl_registry *registry,
&wl_compositor_interface,
(vers < 2) ? vers : 2);
else
- if (!strcmp(iface, "wl_output") && vers >= 2)
- {
- struct device_data *dd = malloc(sizeof (*dd));
- if (unlikely(dd == NULL))
- return;
-
- struct wl_output *output = wl_registry_bind(registry, name,
- &wl_output_interface, 2);
- if (unlikely(output == NULL))
- return;
-
- dd->name = name;
- dd->window = wnd;
- wl_output_add_listener(output, &output_cbs, dd);
- }
- else
#ifdef XDG_SHELL
# ifdef XDG_SHELL_UNSTABLE
if (!strcmp(iface, "zxdg_shell_v6") && sys->wm_base == NULL)
@@ -436,6 +358,9 @@ static void registry_global_cb(void *data, struct wl_registry *registry,
if (!strcmp(iface, "wl_seat"))
seat_create(wnd, registry, name, vers, &sys->seats);
else
+ if (!strcmp(iface, "wl_output"))
+ output_create(wnd, registry, name, vers, &sys->outputs);
+ else
if (!strcmp(iface, "org_kde_kwin_server_decoration_manager"))
sys->deco_manager = wl_registry_bind(registry, name,
&org_kde_kwin_server_decoration_manager_interface, 1);
@@ -446,16 +371,13 @@ static void registry_global_remove_cb(void *data, struct wl_registry *registry,
{
vout_window_t *wnd = data;
vout_window_sys_t *sys = wnd->sys;
- char idstr[11];
msg_Dbg(wnd, "global remove %3"PRIu32, name);
if (seat_destroy_one(&sys->seats, name) == 0)
return;
-
- /* If the global was an output, this will remove it. Otherwise, no-op. */
- sprintf(idstr, "%"PRIu32, name);
- vout_window_ReportOutputDevice(wnd, idstr, NULL);
+ if (output_destroy_one(&sys->outputs, name) == 0)
+ return;
(void) registry;
}
@@ -485,6 +407,7 @@ static int Open(vout_window_t *wnd, const vout_window_cfg_t *cfg)
sys->width = cfg->width;
sys->height = cfg->height;
sys->fullscreen = false;
+ wl_list_init(&sys->outputs);
wl_list_init(&sys->seats);
wnd->sys = sys;
wnd->handle.wl = NULL;
@@ -511,7 +434,6 @@ static int Open(vout_window_t *wnd, const vout_window_cfg_t *cfg)
#endif
wl_registry_add_listener(sys->registry, ®istry_cbs, wnd);
wl_display_roundtrip(display); /* complete registry enumeration */
- wl_display_roundtrip(display); /* complete devices enumeration */
if (sys->compositor == NULL || sys->wm_base == NULL)
goto error;
@@ -601,6 +523,7 @@ static int Open(vout_window_t *wnd, const vout_window_cfg_t *cfg)
error:
seat_destroy_all(&sys->seats);
+ output_destroy_all(&sys->outputs);
if (sys->deco != NULL)
org_kde_kwin_server_decoration_destroy(sys->deco);
if (sys->deco_manager != NULL)
@@ -633,6 +556,7 @@ static void Close(vout_window_t *wnd)
vlc_join(sys->thread, NULL);
seat_destroy_all(&sys->seats);
+ output_destroy_all(&sys->outputs);
if (sys->deco != NULL)
org_kde_kwin_server_decoration_destroy(sys->deco);
if (sys->deco_manager != NULL)
More information about the vlc-commits
mailing list