[PATCH v2 2/3] ephyr: enable screen window placement following kdrive -screen option extended syntax

Laércio de Sousa lbsousajr at gmail.com
Wed Aug 6 06:48:17 PDT 2014


With this patch, one can launch Xephyr with option "-screen WxH+X+Y"
to place its window origin at (X,Y). This patch relies on a previous
one that extends kdrive -screen option syntax to parse +X+Y substring
as expected.

If +X+Y is not passed in -screen argument string, let the WM place
the window for us, as before.
---
 hw/kdrive/ephyr/ephyr.c     |  3 ++-
 hw/kdrive/ephyr/ephyr.h     |  1 +
 hw/kdrive/ephyr/ephyrinit.c |  5 ++++-
 hw/kdrive/ephyr/hostx.c     | 21 ++++++++++++++++++---
 hw/kdrive/ephyr/hostx.h     |  3 ++-
 5 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index d57e9f3..b039c68 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -242,7 +242,8 @@ ephyrMapFramebuffer(KdScreenInfo * screen)
     buffer_height = ephyrBufferHeight(screen);
 
     priv->base =
-        hostx_screen_init(screen, screen->width, screen->height, buffer_height,
+        hostx_screen_init(screen, screen->x, screen->y,
+                          screen->width, screen->height, buffer_height,
                           &priv->bytes_per_line, &screen->fb.bitsPerPixel);
 
     if ((scrpriv->randr & RR_Rotate_0) && !(scrpriv->randr & RR_Reflect_All)) {
diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h
index dfd93c9..5c4936b 100644
--- a/hw/kdrive/ephyr/ephyr.h
+++ b/hw/kdrive/ephyr/ephyr.h
@@ -73,6 +73,7 @@ typedef struct _ephyrScrPriv {
     xcb_window_t win_pre_existing;    /* Set via -parent option like xnest */
     xcb_window_t peer_win;            /* Used for GL; should be at most one */
     xcb_image_t *ximg;
+    Bool win_explicit_position;
     int win_width, win_height;
     int server_depth;
     unsigned char *fb_data;     /* only used when host bpp != server bpp */
diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c
index fc00010..e04c8dc 100644
--- a/hw/kdrive/ephyr/ephyrinit.c
+++ b/hw/kdrive/ephyr/ephyrinit.c
@@ -164,6 +164,7 @@ processScreenArg(const char *screen_size, char *parent_id)
     if (card) {
         KdScreenInfo *screen;
         unsigned long p_id = 0;
+        Bool use_geometry;
 
         screen = KdScreenInfoAdd(card);
         KdParseScreen(screen, screen_size);
@@ -174,8 +175,10 @@ processScreenArg(const char *screen_size, char *parent_id)
         if (parent_id) {
             p_id = strtol(parent_id, NULL, 0);
         }
+
+        use_geometry = (strchr(screen_size, '+') != NULL);
         EPHYR_DBG("screen number:%d\n", screen->mynum);
-        hostx_add_screen(screen, p_id, screen->mynum);
+        hostx_add_screen(screen, p_id, screen->mynum, use_geometry);
     }
     else {
         ErrorF("No matching card found!\n");
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 1c75974..92a8ada 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -119,7 +119,7 @@ hostx_want_screen_size(KdScreenInfo *screen, int *width, int *height)
 }
 
 void
-hostx_add_screen(KdScreenInfo *screen, unsigned long win_id, int screen_num)
+hostx_add_screen(KdScreenInfo *screen, unsigned long win_id, int screen_num, Bool use_geometry)
 {
     EphyrScrPriv *scrpriv = screen->driver;
     int index = HostX.n_screens;
@@ -131,6 +131,7 @@ hostx_add_screen(KdScreenInfo *screen, unsigned long win_id, int screen_num)
 
     scrpriv->screen = screen;
     scrpriv->win_pre_existing = win_id;
+    scrpriv->win_explicit_position = use_geometry;
 }
 
 void
@@ -637,6 +638,7 @@ hostx_set_cmap_entry(unsigned char idx,
  */
 void *
 hostx_screen_init(KdScreenInfo *screen,
+                  int x, int y,
                   int width, int height, int buffer_height,
                   int *bytes_per_line, int *bits_per_pixel)
 {
@@ -648,8 +650,8 @@ hostx_screen_init(KdScreenInfo *screen,
         exit(1);
     }
 
-    EPHYR_DBG("host_screen=%p wxh=%dx%d, buffer_height=%d",
-              host_screen, width, height, buffer_height);
+    EPHYR_DBG("host_screen=%p x=%d, y=%d, wxh=%dx%d, buffer_height=%d",
+              host_screen, x, y, width, height, buffer_height);
 
     if (scrpriv->ximg != NULL) {
         /* Free up the image data if previously used
@@ -740,6 +742,19 @@ hostx_screen_init(KdScreenInfo *screen,
 
     xcb_map_window(HostX.conn, scrpriv->win);
 
+    /* Set explicit window position if it was informed in
+     * -screen option (WxH+X or WxH+X+Y). Otherwise, accept the
+     * position set by WM.
+     * The trick here is putting this code after xcb_map_window() call,
+     * so these values won't be overriden by WM. */
+    if (scrpriv->win_explicit_position)
+    {
+        uint32_t mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y;
+        uint32_t values[2] = {x, y};
+        xcb_configure_window(HostX.conn, scrpriv->win, mask, values);
+    }
+
+
     xcb_aux_sync(HostX.conn);
 
     scrpriv->win_width = width;
diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h
index e83323a..c554ca3 100644
--- a/hw/kdrive/ephyr/hostx.h
+++ b/hw/kdrive/ephyr/hostx.h
@@ -107,7 +107,7 @@ int
  hostx_init(void);
 
 void
-hostx_add_screen(KdScreenInfo *screen, unsigned long win_id, int screen_num);
+hostx_add_screen(KdScreenInfo *screen, unsigned long win_id, int screen_num, Bool use_geometry);
 
 void
  hostx_set_display_name(char *name);
@@ -136,6 +136,7 @@ hostx_set_cmap_entry(unsigned char idx,
                      unsigned char r, unsigned char g, unsigned char b);
 
 void *hostx_screen_init(KdScreenInfo *screen,
+                        int x, int y,
                         int width, int height, int buffer_height,
                         int *bytes_per_line, int *bits_per_pixel);
 
-- 
1.8.4.5



More information about the xorg-devel mailing list