[PATCH v2 0/2] new approach for Xephyr window placement (for multiseat purposes) (v2)

46 views
Skip to first unread message

Laércio de Sousa

unread,
Apr 30, 2014, 9:36:06 AM4/30/14
to xorg-...@lists.x.org, Laércio de Sousa
This is the v2 of patch series for providing window placement support
for Xephyr. In this version, there are some fixes in the second patch,
which provides -output option support to Xephyr:

- Fix error message format when the given output is invalid.
- When -output option is provided, set HostX.use_fullscreen to TRUE
and call hostx_set_fullscreen_hint(), in order to mimic fullscreen
mode, and prevent Xephyr from registering additional modes.

Laércio de Sousa (1):
ephyr: set screen size & origin from host X server output's CRTC
geometry

Loic Grenie (1):
ephyr: allow starting window at other than 0,0 location (via kdrive
-origin option)

configure.ac | 2 +-
hw/kdrive/ephyr/ephyr.c | 8 ++-
hw/kdrive/ephyr/ephyr.h | 2 +
hw/kdrive/ephyr/ephyrinit.c | 21 +++++-
hw/kdrive/ephyr/hostx.c | 151 ++++++++++++++++++++++++++++++++++++++++++--
hw/kdrive/ephyr/hostx.h | 10 ++-
6 files changed, 181 insertions(+), 13 deletions(-)

--
1.8.4.5

_______________________________________________
xorg-...@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Laércio de Sousa

unread,
Apr 30, 2014, 9:36:07 AM4/30/14
to xorg-...@lists.x.org, Laércio de Sousa, Loic Grenie
From: Loic Grenie <loic....@gmail.com>

The following patch sets the upper-left corner of the Xephyr window
to the coordinates specified with kdrive -origin option.

This option is overriden if Xephyr is started in a desktop environment
such as GNOME or KDE, but it does apply if Xephyr is started directly
from display manager, so it may be useful specially for single-card
multiseat setups.

This is based on original patch by Loic Grenie submitted to Debian
at August 06, 2008 (Debian bug #493963), and updated to current Xephyr
version by Laércio de Sousa.

Signed-off-by: Laércio de Sousa <lbso...@gmail.com>
---
hw/kdrive/ephyr/ephyr.c | 3 ++-
hw/kdrive/ephyr/hostx.c | 12 ++++++++----
hw/kdrive/ephyr/hostx.h | 1 +
3 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index def50d8..3e910ea 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->origin.x, screen->origin.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/hostx.c b/hw/kdrive/ephyr/hostx.c
index 435919e..5e79708 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -626,6 +626,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)
{
@@ -637,8 +638,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
@@ -711,8 +712,11 @@ hostx_screen_init(KdScreenInfo *screen,
}

{
- uint32_t mask = XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
- uint32_t values[2] = {width, height};
+ uint32_t mask = XCB_CONFIG_WINDOW_X
+ | XCB_CONFIG_WINDOW_Y
+ | XCB_CONFIG_WINDOW_WIDTH
+ | XCB_CONFIG_WINDOW_HEIGHT;
+ uint32_t values[4] = {x, y, width, height};
xcb_configure_window(HostX.conn, scrpriv->win, mask, values);
}

diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h
index e83323a..77b97ee 100644
--- a/hw/kdrive/ephyr/hostx.h
+++ b/hw/kdrive/ephyr/hostx.h
@@ -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);

Laércio de Sousa

unread,
Apr 30, 2014, 9:36:08 AM4/30/14
to xorg-...@lists.x.org, Laércio de Sousa
If a given output is passed via new -output option, Xephyr will query
host X server for its info. If the following conditions are met:

a. RandR extension is enabled in host X server;
b. supported RandR version in host X server is 1.2 or newer;
c. the given output name is valid;
d. the given output is connected;

then Xephyr will get output's CRTC geometry and use it to set its own
screen size and origin. It's just like starting Xephyr in fullscreen mode,
but restricted to the given output's CRTC geometry (fake "Zaphod mode").

This is the main feature needed for Xephyr-based single-card multiseat
setups where we don't have separate screens to start Xephyr in fullscreen
mode safely.
---
configure.ac | 2 +-
hw/kdrive/ephyr/ephyr.c | 5 +-
hw/kdrive/ephyr/ephyr.h | 2 +
hw/kdrive/ephyr/ephyrinit.c | 21 ++++++-
hw/kdrive/ephyr/hostx.c | 139 +++++++++++++++++++++++++++++++++++++++++++-
hw/kdrive/ephyr/hostx.h | 9 ++-
6 files changed, 170 insertions(+), 8 deletions(-)

diff --git a/configure.ac b/configure.ac
index e5387bf..1e318ac 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2359,7 +2359,7 @@ if test "$KDRIVE" = yes; then
AC_DEFINE(KDRIVE_MOUSE, 1, [Enable KDrive mouse driver])
fi

- XEPHYR_REQUIRED_LIBS="xau xdmcp xcb xcb-shape xcb-aux xcb-image xcb-icccm xcb-shm xcb-keysyms"
+ XEPHYR_REQUIRED_LIBS="xau xdmcp xcb xcb-shape xcb-aux xcb-image xcb-icccm xcb-shm xcb-keysyms xcb-randr"
if test "x$XV" = xyes; then
XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS xcb-xv"
fi
diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 3e910ea..eb3882e 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -111,13 +111,16 @@ Bool
ephyrScreenInitialize(KdScreenInfo *screen)
{
EphyrScrPriv *scrpriv = screen->driver;
+ int x = 0, y = 0;
int width = 640, height = 480;
CARD32 redMask, greenMask, blueMask;

- if (hostx_want_screen_size(screen, &width, &height)
+ if (hostx_want_screen_geometry(screen, &width, &height, &x, &y)
|| !screen->width || !screen->height) {
screen->width = width;
screen->height = height;
+ screen->origin.x = x;
+ screen->origin.y = y;
}

if (EphyrWantGrayScale)
diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h
index 34ce460..1296324 100644
--- a/hw/kdrive/ephyr/ephyr.h
+++ b/hw/kdrive/ephyr/ephyr.h
@@ -73,8 +73,10 @@ 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;
+ int win_x, win_y;
int win_width, win_height;
int server_depth;
+ char *output; /* Set via -output option */
unsigned char *fb_data; /* only used when host bpp != server bpp */
xcb_shm_segment_info_t shminfo;

diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c
index fac84cd..36900fe 100644
--- a/hw/kdrive/ephyr/ephyrinit.c
+++ b/hw/kdrive/ephyr/ephyrinit.c
@@ -47,6 +47,7 @@ extern KdPointerDriver LinuxEvdevMouseDriver;
extern KdKeyboardDriver LinuxEvdevKeyboardDriver;
#endif

+void processScreenArgWithOutput(const char *screen_size, char *parent_id, char *output);
void processScreenArg(const char *screen_size, char *parent_id);

void
@@ -134,6 +135,7 @@ ddxUseMsg(void)
ErrorF("-parent <XID> Use existing window as Xephyr root win\n");
ErrorF("-sw-cursor Render cursors in software in Xephyr\n");
ErrorF("-fullscreen Attempt to run Xephyr fullscreen\n");
+ ErrorF("-output <NAME> Attempt to run Xephyr fullscreen (restricted to given output geometry)\n");
ErrorF("-grayscale Simulate 8bit grayscale\n");
ErrorF("-resizeable Make Xephyr windows resizeable\n");
#ifdef GLAMOR
@@ -153,7 +155,7 @@ ddxUseMsg(void)
}

void
-processScreenArg(const char *screen_size, char *parent_id)
+processScreenArgWithOutput(const char *screen_size, char *parent_id, char *output)
{
KdCardInfo *card;

@@ -174,13 +176,19 @@ processScreenArg(const char *screen_size, char *parent_id)
p_id = strtol(parent_id, NULL, 0);
}
EPHYR_DBG("screen number:%d\n", screen->mynum);
- hostx_add_screen(screen, p_id, screen->mynum);
+ hostx_add_screen(screen, p_id, screen->mynum, output);
}
else {
ErrorF("No matching card found!\n");
}
}

+void
+processScreenArg(const char *screen_size, char *parent_id)
+{
+ processScreenArgWithOutput(screen_size, parent_id, NULL);
+}
+
int
ddxProcessArgument(int argc, char **argv, int i)
{
@@ -222,6 +230,15 @@ ddxProcessArgument(int argc, char **argv, int i)
UseMsg();
exit(1);
}
+ else if (!strcmp(argv[i], "-output")) {
+ if (i + 1 < argc) {
+ processScreenArgWithOutput("100x100", NULL, argv[i + 1]);
+ return 2;
+ }
+
+ UseMsg();
+ exit(1);
+ }
else if (!strcmp(argv[i], "-sw-cursor")) {
hostx_use_sw_cursor();
return 1;
diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 5e79708..cccb3f5 100644
--- a/hw/kdrive/ephyr/hostx.c
+++ b/hw/kdrive/ephyr/hostx.c
@@ -51,6 +51,7 @@
#include <xcb/xcb_image.h>
#include <xcb/shape.h>
#include <xcb/xcb_keysyms.h>
+#include <xcb/randr.h>
#ifdef XF86DRI
#include <xcb/xf86dri.h>
#include <xcb/glx.h>
@@ -104,12 +105,15 @@ static void
#define host_depth_matches_server(_vars) (HostX.depth == (_vars)->server_depth)

int
-hostx_want_screen_size(KdScreenInfo *screen, int *width, int *height)
+hostx_want_screen_geometry(KdScreenInfo *screen, int *width, int *height, int *x, int *y)
{
EphyrScrPriv *scrpriv = screen->driver;

if (scrpriv && (scrpriv->win_pre_existing != None ||
+ scrpriv->output != NULL ||
HostX.use_fullscreen == TRUE)) {
+ *x = scrpriv->win_x;
+ *y = scrpriv->win_y;
*width = scrpriv->win_width;
*height = scrpriv->win_height;
return 1;
@@ -119,7 +123,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, char *output)
{
EphyrScrPriv *scrpriv = screen->driver;
int index = HostX.n_screens;
@@ -131,6 +135,9 @@ hostx_add_screen(KdScreenInfo *screen, unsigned long win_id, int screen_num)

scrpriv->screen = screen;
scrpriv->win_pre_existing = win_id;
+
+ if (output != NULL)
+ scrpriv->output = output;
}

void
@@ -210,6 +217,119 @@ hostx_want_preexisting_window(KdScreenInfo *screen)
}

void
+hostx_get_output_geometry(char *output,
+ int *x, int *y,
+ unsigned int *width, unsigned int *height)
+{
+ int i, name_len = 0, output_found = FALSE;
+ char *name = NULL;
+ xcb_generic_error_t *error;
+ xcb_randr_query_version_cookie_t version_c;
+ xcb_randr_query_version_reply_t *version_r;
+ xcb_randr_get_screen_resources_cookie_t screen_resources_c;
+ xcb_randr_get_screen_resources_reply_t *screen_resources_r;
+ xcb_randr_output_t *randr_outputs;
+ xcb_randr_get_output_info_cookie_t output_info_c;
+ xcb_randr_get_output_info_reply_t *output_info_r;
+ xcb_randr_get_crtc_info_cookie_t crtc_info_c;
+ xcb_randr_get_crtc_info_reply_t *crtc_info_r;
+
+ /* First of all, check for extension */
+ if (!xcb_get_extension_data(HostX.conn, &xcb_randr_id)->present)
+ {
+ fprintf(stderr, "\nHost X server does not support RANDR extension (or it's disabled).\n");
+ exit(1);
+ }
+
+ /* Check RandR version */
+ version_c = xcb_randr_query_version(HostX.conn, 1, 2);
+ version_r = xcb_randr_query_version_reply(HostX.conn,
+ version_c,
+ &error);
+
+ if (error != NULL || version_r == NULL)
+ {
+ fprintf(stderr, "\nFailed to get RandR version supported by host X server.\n");
+ exit(1);
+ }
+ else if (version_r->major_version < 1 || version_r->minor_version < 2)
+ {
+ free(version_r);
+ fprintf(stderr, "\nHost X server doesn't support RandR 1.2, needed for -output usage.\n");
+ exit(1);
+ }
+
+ free(version_r);
+
+ /* Get list of outputs from screen resources */
+ screen_resources_c = xcb_randr_get_screen_resources(HostX.conn,
+ HostX.winroot);
+ screen_resources_r = xcb_randr_get_screen_resources_reply(HostX.conn,
+ screen_resources_c,
+ NULL);
+ randr_outputs = xcb_randr_get_screen_resources_outputs(screen_resources_r);
+
+ for (i = 0; !output_found && i < screen_resources_r->num_outputs; i++)
+ {
+ /* Get info on the output */
+ output_info_c = xcb_randr_get_output_info(HostX.conn,
+ randr_outputs[i],
+ XCB_CURRENT_TIME);
+ output_info_r = xcb_randr_get_output_info_reply(HostX.conn,
+ output_info_c,
+ NULL);
+
+ /* Get output name */
+ name_len = xcb_randr_get_output_info_name_length(output_info_r);
+ name = malloc(name_len + 1);
+ strncpy(name, (char*)xcb_randr_get_output_info_name(output_info_r), name_len);
+ name[name_len] = '\0';
+
+ if (!strcmp(name, output))
+ {
+ output_found = TRUE;
+
+ /* Check if output is connected */
+ if (output_info_r->crtc == XCB_NONE)
+ {
+ free(name);
+ free(output_info_r);
+ free(screen_resources_r);
+ fprintf(stderr, "\nOutput %s is currently disabled (or not connected).\n", output);
+ exit(1);
+ }
+
+ /* Get CRTC from output info */
+ crtc_info_c = xcb_randr_get_crtc_info(HostX.conn,
+ output_info_r->crtc,
+ XCB_CURRENT_TIME);
+ crtc_info_r = xcb_randr_get_crtc_info_reply(HostX.conn,
+ crtc_info_c,
+ NULL);
+
+ /* Get CRTC geometry */
+ *x = crtc_info_r->x;
+ *y = crtc_info_r->y;
+ *width = crtc_info_r->width;
+ *height = crtc_info_r->height;
+
+ free(crtc_info_r);
+ }
+
+ free(name);
+ free(output_info_r);
+ }
+
+ free(screen_resources_r);
+
+ if (!output_found)
+ {
+ fprintf(stderr, "\nOutput %s not available in host X server.\n", output);
+ exit(1);
+ }
+}
+
+void
hostx_use_fullscreen(void)
{
HostX.use_fullscreen = TRUE;
@@ -347,6 +467,8 @@ hostx_init(void)
scrpriv->win = xcb_generate_id(HostX.conn);
scrpriv->server_depth = HostX.depth;
scrpriv->ximg = NULL;
+ scrpriv->win_x = 0;
+ scrpriv->win_y = 0;

if (scrpriv->win_pre_existing != XCB_WINDOW_NONE) {
xcb_get_geometry_reply_t *prewin_geom;
@@ -404,6 +526,17 @@ hostx_init(void)

hostx_set_fullscreen_hint();
}
+ else if (scrpriv->output) {
+ hostx_get_output_geometry(scrpriv->output,
+ &scrpriv->win_x,
+ &scrpriv->win_y,
+ &scrpriv->win_width,
+ &scrpriv->win_height);
+
+ HostX.use_fullscreen = TRUE;
+ hostx_set_fullscreen_hint();
+ }
+

tmpstr = getenv("RESOURCE_NAME");
if (tmpstr && (!ephyrResNameFromCmd))
@@ -737,6 +870,8 @@ hostx_screen_init(KdScreenInfo *screen,

scrpriv->win_width = width;
scrpriv->win_height = height;
+ scrpriv->win_x = x;
+ scrpriv->win_y = y;

#ifdef GLAMOR
if (ephyr_glamor) {
diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h
index 77b97ee..8e2eafb 100644
--- a/hw/kdrive/ephyr/hostx.h
+++ b/hw/kdrive/ephyr/hostx.h
@@ -74,7 +74,7 @@ typedef struct {
} EphyrRect;

int
-hostx_want_screen_size(KdScreenInfo *screen, int *width, int *height);
+hostx_want_screen_geometry(KdScreenInfo *screen, int *width, int *height, int *x, int *y);

int
hostx_want_host_cursor(void);
@@ -83,6 +83,11 @@ void
hostx_use_sw_cursor(void);

void
+ hostx_get_output_geometry(char *output,
+ int *x, int *y,
+ unsigned int *width, unsigned int *height);
+
+void
hostx_use_fullscreen(void);

int
@@ -107,7 +112,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, char *output);

void
hostx_set_display_name(char *name);

Keith Packard

unread,
Apr 30, 2014, 1:04:05 PM4/30/14
to Laércio de Sousa, xorg-...@lists.x.org, Laércio de Sousa, Loic Grenie
Laércio de Sousa <lbso...@gmail.com> writes:

> From: Loic Grenie <loic....@gmail.com>
>
> The following patch sets the upper-left corner of the Xephyr window
> to the coordinates specified with kdrive -origin option.

The -origin option specifies where the screen appears in the cursor
address space when running multiple kdrive screens in Xinerama mode. If
you want an option to specify where the screen appears in the enclosing
window system, you'll need a new option.

Also, you probably want to make the configuration specify the X/Y
positions only if the user actually set them so that the window manager
will automatically position the window sensibly by default, and only
force the window position when directed by the user.

--
keith....@intel.com

Laércio de Sousa

unread,
Apr 30, 2014, 4:04:41 PM4/30/14
to Keith Packard, xorg-...@lists.x.org, Loic Grenie
2014-04-30 14:04 GMT-03:00 Keith Packard <kei...@keithp.com>:
The -origin option specifies where the screen appears in the cursor
address space when running multiple kdrive screens in Xinerama mode. If
you want an option to specify where the screen appears in the enclosing
window system, you'll need a new option.

OK, I'll take care about it.
 
Also, you probably want to make the configuration specify the X/Y
positions only if the user actually set them so that the window manager
will automatically position the window sensibly by default, and only
force the window position when directed by the user.

I dont' know if I understand what you mean, but I just realized I can force window position
by setting it after xcb_map_window() call. Example:

{
        uint32_t mask = XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
        uint32_t values[2] = {width, height};
        xcb_configure_window(HostX.conn, scrpriv->win, mask, values);
}

xcb_map_window(HostX.conn, scrpriv->win);

{
        uint32_t xy_mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y;
        uint32_t xy_values[2] = {x, y};
        xcb_configure_window(HostX.conn, scrpriv->win, xy_mask, xy_values);
}

Is this what you mean?

CANTATE DOMINO CANTICUM NOVUM
QUIA MIRABILIA FECIT

Laércio

Laércio de Sousa

unread,
May 2, 2014, 11:35:40 AM5/2/14
to Keith Packard, xorg-...@lists.x.org, Loic Grenie

Z


Em 30/04/2014 14:04, "Keith Packard" <kei...@keithp.com> escreveu:
>
> Laércio de Sousa <lbso...@gmail.com> writes:
>
> > From: Loic Grenie <loic....@gmail.com>
> >
> > The following patch sets the upper-left corner of the Xephyr window
> > to the coordinates specified with kdrive -origin option.
>
> The -origin option specifies where the screen appears in the cursor
> address space when running multiple kdrive screens in Xinerama mode. If
> you want an option to specify where the screen appears in the enclosing
> window system, you'll need a new option.
>

Some time ago I submitted another patch with the following approach: extend kdrive -screen option parsing to include strings like WxH+X+Y, and then place Xephyr window top-left corner at (X,Y). Do you think it's a good approach?

Keith Packard

unread,
May 2, 2014, 1:50:44 PM5/2/14
to Laércio de Sousa, xorg-...@lists.x.org, Loic Grenie
Yes, that sounds perfect.

--
keith....@intel.com

Laércio de Sousa

unread,
May 3, 2014, 11:10:37 AM5/3/14
to Keith Packard, xorg-...@lists.x.org, Loic Grenie

OK. One last question: for negative values, should it support WxH-X-Y syntax (harder to implement) or just WxH+-X+-Y syntax (easier to implement)?

Keith Packard

unread,
May 3, 2014, 1:02:46 PM5/3/14
to Laércio de Sousa, xorg-...@lists.x.org, Loic Grenie
Laércio de Sousa <lbso...@gmail.com> writes:

> OK. One last question: for negative values, should it support WxH-X-Y
> syntax (harder to implement) or just WxH+-X+-Y syntax (easier to
> implement)?

You should use XParseGeometry or even XWMGeometry. If you want to avoid
Xlib, you should hack those functions into something that could be
included in an xcb utility library (probably util-wm).

I couldn't find anything suitable in xcb yet, but I didn't do more than
a few simple greps; maybe there's already something to do this?

--
keith....@intel.com

Laércio de Sousa

unread,
May 3, 2014, 2:19:13 PM5/3/14
to Keith Packard, xorg-...@lists.x.org, Loic Grenie


Em 03/05/2014 14:02, "Keith Packard" <kei...@keithp.com> escreveu:
> You should use XParseGeometry or even XWMGeometry. If you want to avoid
> Xlib, you should hack those functions into something that could be
> included in an xcb utility library (probably util-wm).
>
> I couldn't find anything suitable in xcb yet, but I didn't do more than
> a few simple greps; maybe there's already something to do this?

Kdrive has its own "geometry" parsing algorithm, the function KdParseScreen() in file kdrive.c. I've extended it to include +X+Y parsing. See my previous patch at http://lists.x.org/archives/xorg-devel/2014-February/040606.html

This patch supports -X-Y syntax, but I could simplify it by supporting +-X+-Y only, so that the character + can be interpreted as the only delimiter for window placement.

Laércio de Sousa

unread,
May 6, 2014, 11:28:16 AM5/6/14
to Keith Packard, xorg-...@lists.x.org, Loic Grenie
Keith,

I've just submitted an updated series following your feedback. Please take a look:


CANTATE DOMINO CANTICUM NOVUM
QUIA MIRABILIA FECIT

Laércio


Reply all
Reply to author
Forward
0 new messages