diff options
author | marha <marha@users.sourceforge.net> | 2014-08-30 13:45:43 +0200 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2014-08-30 13:45:43 +0200 |
commit | 3293021e6f582c7348667e7638941620134525e1 (patch) | |
tree | 5d8d3da8242ff7828fb6964bed19b13d74d48704 /xorg-server/hw/kdrive/ephyr | |
parent | 0a9ab140bb01b96888e313466a73e26e5156f22d (diff) | |
parent | e21655632e3fd40b7f6a5cc3c7f3c379d54557c4 (diff) | |
download | vcxsrv-3293021e6f582c7348667e7638941620134525e1.tar.gz vcxsrv-3293021e6f582c7348667e7638941620134525e1.tar.bz2 vcxsrv-3293021e6f582c7348667e7638941620134525e1.zip |
Merge remote-tracking branch 'origin/released'
Conflicts:
xorg-server/hw/kdrive/ephyr/ephyrinit.c
Diffstat (limited to 'xorg-server/hw/kdrive/ephyr')
-rw-r--r-- | xorg-server/hw/kdrive/ephyr/ephyr.c | 8 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/ephyr/ephyr.h | 3 | ||||
-rwxr-xr-x[-rw-r--r--] | xorg-server/hw/kdrive/ephyr/ephyrinit.c | 31 | ||||
-rwxr-xr-x | xorg-server/hw/kdrive/ephyr/hostx.c | 156 | ||||
-rw-r--r-- | xorg-server/hw/kdrive/ephyr/hostx.h | 10 |
5 files changed, 198 insertions, 10 deletions
diff --git a/xorg-server/hw/kdrive/ephyr/ephyr.c b/xorg-server/hw/kdrive/ephyr/ephyr.c index 76cc47efd..ae095c883 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyr.c +++ b/xorg-server/hw/kdrive/ephyr/ephyr.c @@ -114,13 +114,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->x = x; + screen->y = y; } if (EphyrWantGrayScale) @@ -245,7 +248,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/xorg-server/hw/kdrive/ephyr/ephyr.h b/xorg-server/hw/kdrive/ephyr/ephyr.h index 59e202095..ffe7db1c2 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyr.h +++ b/xorg-server/hw/kdrive/ephyr/ephyr.h @@ -75,8 +75,11 @@ 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_x, win_y; int win_width, win_height; int server_depth; + const 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/xorg-server/hw/kdrive/ephyr/ephyrinit.c b/xorg-server/hw/kdrive/ephyr/ephyrinit.c index 8fe45d575..dee15b530 100644..100755 --- a/xorg-server/hw/kdrive/ephyr/ephyrinit.c +++ b/xorg-server/hw/kdrive/ephyr/ephyrinit.c @@ -47,6 +47,8 @@ extern KdPointerDriver LinuxEvdevMouseDriver; extern KdKeyboardDriver LinuxEvdevKeyboardDriver; #endif +void processScreenOrOutputArg(const char *screen_size, const char *output, char *parent_id); +void processOutputArg(const char *output, char *parent_id); void processScreenArg(const char *screen_size, char *parent_id); void @@ -135,6 +137,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 @@ -156,7 +159,7 @@ ddxUseMsg(void) #endif void -processScreenArg(const char *screen_size, char *parent_id) +processScreenOrOutputArg(const char *screen_size, const char *output, char *parent_id) { KdCardInfo *card; @@ -166,6 +169,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); @@ -176,14 +180,28 @@ 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, output); } else { ErrorF("No matching card found!\n"); } } +void +processScreenArg(const char *screen_size, char *parent_id) +{ + processScreenOrOutputArg(screen_size, NULL, parent_id); +} + +void +processOutputArg(const char *output, char *parent_id) +{ + processScreenOrOutputArg("100x100+0+0", output, parent_id); +} + #ifndef _MSC_VER int ddxProcessArgument(int argc, char **argv, int i) @@ -226,6 +244,15 @@ ddxProcessArgument(int argc, char **argv, int i) UseMsg(); exit(1); } + else if (!strcmp(argv[i], "-output")) { + if (i + 1 < argc) { + processOutputArg(argv[i + 1], NULL); + return 2; + } + + UseMsg(); + exit(1); + } else if (!strcmp(argv[i], "-sw-cursor")) { hostx_use_sw_cursor(); return 1; diff --git a/xorg-server/hw/kdrive/ephyr/hostx.c b/xorg-server/hw/kdrive/ephyr/hostx.c index 3048cd087..4b69171a0 100755 --- a/xorg-server/hw/kdrive/ephyr/hostx.c +++ b/xorg-server/hw/kdrive/ephyr/hostx.c @@ -53,6 +53,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> @@ -106,12 +107,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; @@ -121,7 +125,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, const char *output) { EphyrScrPriv *scrpriv = screen->driver; int index = HostX.n_screens; @@ -133,6 +137,8 @@ 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; + scrpriv->output = output; } void @@ -216,6 +222,119 @@ hostx_want_preexisting_window(KdScreenInfo *screen) } void +hostx_get_output_geometry(const char *output, + int *x, int *y, + int *width, 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; @@ -364,6 +483,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; @@ -421,6 +542,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)) @@ -647,6 +779,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) { @@ -658,8 +791,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 @@ -758,10 +891,25 @@ __asm int 3; 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; scrpriv->win_height = height; + scrpriv->win_x = x; + scrpriv->win_y = y; #ifdef GLAMOR if (ephyr_glamor) { diff --git a/xorg-server/hw/kdrive/ephyr/hostx.h b/xorg-server/hw/kdrive/ephyr/hostx.h index f2350efba..d108d48be 100644 --- a/xorg-server/hw/kdrive/ephyr/hostx.h +++ b/xorg-server/hw/kdrive/ephyr/hostx.h @@ -78,7 +78,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); @@ -87,6 +87,11 @@ void hostx_use_sw_cursor(void); void + hostx_get_output_geometry(const char *output, + int *x, int *y, + int *width, int *height); + +void hostx_use_fullscreen(void); int @@ -111,7 +116,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, const char *output); void hostx_set_display_name(char *name); @@ -140,6 +145,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); |