From 84b02469ef97e6f85d074d220a517d752180045f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?La=C3=A9rcio=20de=20Sousa?= Date: Mon, 18 Aug 2014 08:45:42 -0300 Subject: [PATCH] ephyr: enable screen window placement following kdrive -screen option extended syntax MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. Signed-off-by: LaƩrcio de Sousa Reviewed-by: Keith Packard Signed-off-by: Keith Packard --- 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 d57e9f33c..b039c683f 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 dfd93c9bc..5c4936bb2 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 fc0001012..e04c8dc88 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 1c759743d..92a8ada96 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 e83323a0c..c554ca370 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);