|
| 1 | +From 6bd9aec85f329def9ed97956d13f990bb8fbd7eb Mon Sep 17 00:00:00 2001 |
| 2 | +From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= |
| 3 | + <marmarek@invisiblethingslab.com> |
| 4 | +Date: Wed, 17 Jun 2026 20:22:20 +0200 |
| 5 | +Subject: [PATCH] Xephyr: fix setting physical output size |
| 6 | +MIME-Version: 1.0 |
| 7 | +Content-Type: text/plain; charset=UTF-8 |
| 8 | +Content-Transfer-Encoding: 8bit |
| 9 | + |
| 10 | +Providing physical size via RRRegisterSize() is not enough - physical |
| 11 | +size is a property of the output, not resolution and needs to be set |
| 12 | +separately. Furhermore, get the physical output size using RandR if |
| 13 | +-output is used, to match specific output, not the whole screen. |
| 14 | + |
| 15 | +With this, `Xephyr -output OUTPUT_NAME` properly copies not only |
| 16 | +resolution but also physical size of the named output. |
| 17 | + |
| 18 | +Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com> |
| 19 | +--- |
| 20 | + hw/kdrive/ephyr/ephyr.c | 8 ++++++++ |
| 21 | + hw/kdrive/ephyr/ephyr.h | 1 + |
| 22 | + hw/kdrive/ephyr/hostx.c | 15 +++++++++++---- |
| 23 | + hw/kdrive/ephyr/hostx.h | 3 ++- |
| 24 | + 4 files changed, 22 insertions(+), 5 deletions(-) |
| 25 | + |
| 26 | +diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c |
| 27 | +index 069270219..e62c46912 100644 |
| 28 | +--- a/hw/kdrive/ephyr/ephyr.c |
| 29 | ++++ b/hw/kdrive/ephyr/ephyr.c |
| 30 | +@@ -453,6 +453,14 @@ ephyrRandRGetInfo(ScreenPtr pScreen, Rotation * rotations) |
| 31 | + screen->width, |
| 32 | + screen->height, screen->width_mm, screen->height_mm); |
| 33 | + |
| 34 | ++ if (hostx_want_fullscreen()) { |
| 35 | ++ RROutputPtr pOutput = RRFirstOutput(pScreen); |
| 36 | ++ if (pOutput) |
| 37 | ++ RROutputSetPhysicalSize(pOutput, |
| 38 | ++ scrpriv->win_width_mm, |
| 39 | ++ scrpriv->win_height_mm); |
| 40 | ++ } |
| 41 | ++ |
| 42 | + randr = KdSubRotation(scrpriv->randr, screen->randr); |
| 43 | + |
| 44 | + RRSetCurrentConfig(pScreen, randr, 0, pSize); |
| 45 | +diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h |
| 46 | +index 8833de8a9..67e24b3e8 100644 |
| 47 | +--- a/hw/kdrive/ephyr/ephyr.h |
| 48 | ++++ b/hw/kdrive/ephyr/ephyr.h |
| 49 | +@@ -76,6 +76,7 @@ typedef struct _ephyrScrPriv { |
| 50 | + Bool win_explicit_position; |
| 51 | + int win_x, win_y; |
| 52 | + int win_width, win_height; |
| 53 | ++ int win_width_mm, win_height_mm; |
| 54 | + int server_depth; |
| 55 | + const char *output; /* Set via -output option */ |
| 56 | + unsigned char *fb_data; /* only used when host bpp != server bpp */ |
| 57 | +diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c |
| 58 | +index b7ac56d50..78e957176 100644 |
| 59 | +--- a/hw/kdrive/ephyr/hostx.c |
| 60 | ++++ b/hw/kdrive/ephyr/hostx.c |
| 61 | +@@ -238,7 +238,8 @@ hostx_want_preexisting_window(KdScreenInfo *screen) |
| 62 | + void |
| 63 | + hostx_get_output_geometry(const char *output, |
| 64 | + int *x, int *y, |
| 65 | +- int *width, int *height) |
| 66 | ++ int *width, int *height, |
| 67 | ++ int *width_mm, int *height_mm) |
| 68 | + { |
| 69 | + int i, name_len = 0, output_found = FALSE; |
| 70 | + char *name = NULL; |
| 71 | +@@ -331,6 +332,8 @@ hostx_get_output_geometry(const char *output, |
| 72 | + *y = crtc_info_r->y; |
| 73 | + *width = crtc_info_r->width; |
| 74 | + *height = crtc_info_r->height; |
| 75 | ++ *width_mm = output_info_r->mm_width; |
| 76 | ++ *height_mm = output_info_r->mm_height; |
| 77 | + |
| 78 | + free(crtc_info_r); |
| 79 | + } |
| 80 | +@@ -628,8 +631,10 @@ hostx_init(void) |
| 81 | + "(ctrl+shift grabs mouse and keyboard)"); |
| 82 | + |
| 83 | + if (HostX.use_fullscreen) { |
| 84 | +- scrpriv->win_width = xscreen->width_in_pixels; |
| 85 | +- scrpriv->win_height = xscreen->height_in_pixels; |
| 86 | ++ scrpriv->win_width = xscreen->width_in_pixels; |
| 87 | ++ scrpriv->win_height = xscreen->height_in_pixels; |
| 88 | ++ scrpriv->win_width_mm = xscreen->width_in_millimeters; |
| 89 | ++ scrpriv->win_height_mm = xscreen->height_in_millimeters; |
| 90 | + |
| 91 | + hostx_set_fullscreen_hint(); |
| 92 | + } |
| 93 | +@@ -638,7 +643,9 @@ hostx_init(void) |
| 94 | + &scrpriv->win_x, |
| 95 | + &scrpriv->win_y, |
| 96 | + &scrpriv->win_width, |
| 97 | +- &scrpriv->win_height); |
| 98 | ++ &scrpriv->win_height, |
| 99 | ++ &scrpriv->win_width_mm, |
| 100 | ++ &scrpriv->win_height_mm); |
| 101 | + |
| 102 | + HostX.use_fullscreen = TRUE; |
| 103 | + hostx_set_fullscreen_hint(); |
| 104 | +diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h |
| 105 | +index 8b3caf245..00891a07a 100644 |
| 106 | +--- a/hw/kdrive/ephyr/hostx.h |
| 107 | ++++ b/hw/kdrive/ephyr/hostx.h |
| 108 | +@@ -84,7 +84,8 @@ xcb_cursor_t |
| 109 | + void |
| 110 | + hostx_get_output_geometry(const char *output, |
| 111 | + int *x, int *y, |
| 112 | +- int *width, int *height); |
| 113 | ++ int *width, int *height, |
| 114 | ++ int *width_mm, int *height_mm); |
| 115 | + |
| 116 | + void |
| 117 | + hostx_use_fullscreen(void); |
| 118 | +-- |
| 119 | +2.54.0 |
| 120 | + |
0 commit comments