diff --git a/configure.ac b/configure.ac
index f3d9654a41c5df7a624ee7ca2428e5b49ef43350..cba7d24ea09f6bddd4f92e80b562fc9855a8b35d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2364,7 +2364,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 b039c683f9f7b40a32d5baff8153ec0de0b297ac..85d41937660b219a9364db6107b91c88d91283b1 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->x = x;
+        screen->y = y;
     }
 
     if (EphyrWantGrayScale)
diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h
index 5c4936bb22832973cf5e2a1b9e44f4c759c949d1..4e753f1586cf4746d461fc130059dfc8aeed4b23 100644
--- a/hw/kdrive/ephyr/ephyr.h
+++ b/hw/kdrive/ephyr/ephyr.h
@@ -74,8 +74,10 @@ typedef struct _ephyrScrPriv {
     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/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c
index e04c8dc889452f7e716737a0e330ba0ddfa9c041..38acc52a60f0c230179aa9b4fd79a7e4e8de27c2 100644
--- a/hw/kdrive/ephyr/ephyrinit.c
+++ b/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
@@ -134,6 +136,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
@@ -154,7 +157,7 @@ ddxUseMsg(void)
 }
 
 void
-processScreenArg(const char *screen_size, char *parent_id)
+processScreenOrOutputArg(const char *screen_size, const char *output, char *parent_id)
 {
     KdCardInfo *card;
 
@@ -178,13 +181,25 @@ processScreenArg(const char *screen_size, char *parent_id)
 
         use_geometry = (strchr(screen_size, '+') != NULL);
         EPHYR_DBG("screen number:%d\n", screen->mynum);
-        hostx_add_screen(screen, p_id, screen->mynum, use_geometry);
+        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);
+}
+
 int
 ddxProcessArgument(int argc, char **argv, int i)
 {
@@ -226,6 +241,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/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c
index 92a8ada96a45fd0acf64fde69b0e19abf32473ec..2161ad5509427d88c0cf47c0cc64f671242933b2 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, Bool use_geometry)
+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;
@@ -132,6 +136,7 @@ hostx_add_screen(KdScreenInfo *screen, unsigned long win_id, int screen_num, Boo
     scrpriv->screen = screen;
     scrpriv->win_pre_existing = win_id;
     scrpriv->win_explicit_position = use_geometry;
+    scrpriv->output = output;
 }
 
 void
@@ -210,6 +215,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)
 {
@@ -359,6 +477,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;
@@ -416,6 +536,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))
@@ -759,6 +890,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 c554ca370cc90dbc2d2a5d778b10cadc70d0decd..80894c8c0e42198ada36aac8e1715faaa9d81c33 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);
@@ -82,6 +82,11 @@ int
 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);
 
@@ -107,7 +112,7 @@ int
  hostx_init(void);
 
 void
-hostx_add_screen(KdScreenInfo *screen, unsigned long win_id, int screen_num, Bool use_geometry);
+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);