From 0806922cd570868839a260866b5bc9b4239f5538 Mon Sep 17 00:00:00 2001
From: Philipp Zabel
Date: Thu, 19 Jan 2023 15:31:57 +0100
Subject: [PATCH] backend-rdp: extract weston_output_set_single_mode()
The ensure_single_mode() helper replaces an output's single mode.
Extract it into libweston so it can be reused by the VNC backend,
and rename it to weston_output_set_single_mode().
At the same time, set the the previously missing
WL_OUTPUT_MODE_CURRENT flag on the new mode.
Fixes #758
Signed-off-by: Philipp Zabel
(cherry picked from commit e58452d6be36dda204d034308fc3cc0f6b9ed9cc)
---
libweston/backend-rdp/rdp.c | 55 +---------------------------------
libweston/compositor.c | 39 ++++++++++++++++++++++++
libweston/libweston-internal.h | 4 +++
3 files changed, 44 insertions(+), 54 deletions(-)
diff --git a/libweston/backend-rdp/rdp.c b/libweston/backend-rdp/rdp.c
index 6bdc9abc8..849267459 100644
--- a/libweston/backend-rdp/rdp.c
+++ b/libweston/backend-rdp/rdp.c
@@ -338,72 +338,19 @@ finish_frame_handler(void *data)
return 1;
}
-static struct weston_mode *
-rdp_insert_new_mode(struct weston_output *output, int width, int height, int rate)
-{
- struct weston_mode *ret;
- ret = xzalloc(sizeof *ret);
- ret->width = width;
- ret->height = height;
- ret->refresh = rate;
- ret->flags = WL_OUTPUT_MODE_PREFERRED;
- wl_list_insert(&output->mode_list, &ret->link);
- return ret;
-}
-
-/* It doesn't make sense for RDP to have more than one mode, so
- * we make sure that we have only one.
- */
-static struct weston_mode *
-ensure_single_mode(struct weston_output *output, struct weston_mode *target)
-{
- struct rdp_output *rdpOutput = to_rdp_output(output);
- struct rdp_backend *b = rdpOutput->backend;
- struct weston_mode *iter, *local = NULL, *new_mode;
-
- wl_list_for_each(iter, &output->mode_list, link) {
- assert(!local);
-
- if ((iter->width == target->width) &&
- (iter->height == target->height) &&
- (iter->refresh == target->refresh)) {
- return iter;
- } else {
- local = iter;
- }
- }
- /* Make sure we create the new one before freeing the old one
- * because some mode switch code uses pointer comparisons! If
- * we freed the old mode first, malloc could theoretically give
- * us back the same pointer.
- */
- new_mode = rdp_insert_new_mode(output,
- target->width, target->height,
- b->rdp_monitor_refresh_rate);
- if (local) {
- wl_list_remove(&local->link);
- free(local);
- }
-
- return new_mode;
-}
-
static void
rdp_output_set_mode(struct weston_output *base, struct weston_mode *mode)
{
struct rdp_output *rdpOutput = container_of(base, struct rdp_output, base);
struct rdp_backend *b = rdpOutput->backend;
- struct weston_mode *cur;
struct weston_output *output = base;
struct rdp_peers_item *rdpPeer;
rdpSettings *settings;
struct weston_renderbuffer *new_renderbuffer;
mode->refresh = b->rdp_monitor_refresh_rate;
- cur = ensure_single_mode(base, mode);
+ weston_output_set_single_mode(base, mode);
- base->current_mode = cur;
- base->native_mode = cur;
if (base->enabled) {
const struct pixman_renderer_interface *pixman;
const struct pixel_format_info *pfmt;
diff --git a/libweston/compositor.c b/libweston/compositor.c
index 379cf3914..b806a0a85 100644
--- a/libweston/compositor.c
+++ b/libweston/compositor.c
@@ -7045,6 +7045,45 @@ weston_output_get_color_characteristics(struct weston_output *output)
return &output->color_characteristics;
}
+WL_EXPORT void
+weston_output_set_single_mode(struct weston_output *output,
+ struct weston_mode *target)
+{
+ struct weston_mode *iter, *local = NULL, *mode;
+
+ wl_list_for_each(iter, &output->mode_list, link) {
+ assert(!local);
+
+ if ((iter->width == target->width) &&
+ (iter->height == target->height) &&
+ (iter->refresh == target->refresh)) {
+ mode = iter;
+ goto out;
+ } else {
+ local = iter;
+ }
+ }
+ /* Make sure we create the new one before freeing the old one
+ * because some mode switch code uses pointer comparisons! If
+ * we freed the old mode first, malloc could theoretically give
+ * us back the same pointer.
+ */
+ mode = xzalloc(sizeof *mode);
+ mode->width = target->width;
+ mode->height = target->height;
+ mode->refresh = target->refresh;
+ mode->flags = WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
+ wl_list_insert(&output->mode_list, &mode->link);
+out:
+ output->current_mode = mode;
+ output->native_mode = mode;
+
+ if (local) {
+ wl_list_remove(&local->link);
+ free(local);
+ }
+}
+
/** Initializes a weston_output object with enough data so
** an output can be configured.
*
diff --git a/libweston/libweston-internal.h b/libweston/libweston-internal.h
index aaf943663..ddd39818f 100644
--- a/libweston/libweston-internal.h
+++ b/libweston/libweston-internal.h
@@ -260,6 +260,10 @@ weston_output_disable_planes_incr(struct weston_output *output);
void
weston_output_disable_planes_decr(struct weston_output *output);
+void
+weston_output_set_single_mode(struct weston_output *output,
+ struct weston_mode *target);
+
/* weston_plane */
void