summaryrefslogtreecommitdiff
path: root/overlay
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-08-27 14:25:38 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2013-08-27 14:26:22 +0100
commitddcd1b2ee5645475725a8e2f78917fa3e7d57c1b (patch)
treef53b5187e70899220d4e5803057d303d0f847c6d /overlay
parent87b66f4cf034c2e058f69d848763bb4bdc45bfbf (diff)
overlay: Add support for multi-monitor positioning
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'overlay')
-rw-r--r--overlay/Makefile.am8
-rw-r--r--overlay/kms/kms-overlay.c6
-rw-r--r--overlay/overlay.h1
-rw-r--r--overlay/x11/position.c75
-rw-r--r--overlay/x11/position.h2
-rw-r--r--overlay/x11/x11-overlay.c34
-rw-r--r--overlay/x11/x11-window.c32
7 files changed, 71 insertions, 87 deletions
diff --git a/overlay/Makefile.am b/overlay/Makefile.am
index 8f829fe4..395b8ed7 100644
--- a/overlay/Makefile.am
+++ b/overlay/Makefile.am
@@ -39,8 +39,8 @@ intel_gpu_overlay_SOURCES = \
if BUILD_OVERLAY_XLIB
both_x11_sources = x11/position.c x11/position.h
-AM_CFLAGS += $(OVERLAY_XLIB_CFLAGS)
-LDADD += $(OVERLAY_XLIB_LIBS)
+AM_CFLAGS += $(OVERLAY_XLIB_CFLAGS) $(XRANDR_CFLAGS)
+LDADD += $(OVERLAY_XLIB_LIBS) $(XRANDR_LIBS)
intel_gpu_overlay_SOURCES += \
x11/x11-window.c \
$(NULL)
@@ -48,8 +48,8 @@ endif
if BUILD_OVERLAY_XVLIB
both_x11_sources = x11/x11-position.c
-AM_CFLAGS += $(OVERLAY_XVLIB_CFLAGS)
-LDADD += $(OVERLAY_XVLIB_LIBS)
+AM_CFLAGS += $(OVERLAY_XVLIB_CFLAGS) $(XRANDR_CFLAGS)
+LDADD += $(OVERLAY_XVLIB_LIBS) $(XRANDR_LIBS)
intel_gpu_overlay_SOURCES += \
x11/dri2.c \
x11/dri2.h \
diff --git a/overlay/kms/kms-overlay.c b/overlay/kms/kms-overlay.c
index e49a495c..cfb3d5ae 100644
--- a/overlay/kms/kms-overlay.c
+++ b/overlay/kms/kms-overlay.c
@@ -124,11 +124,6 @@ static void kms_overlay_show(struct overlay *overlay)
}
}
-static void kms_overlay_position(struct overlay *overlay,
- enum position p)
-{
-}
-
static void kms_overlay_hide(struct overlay *overlay)
{
struct kms_overlay *priv = to_kms_overlay(overlay);
@@ -309,7 +304,6 @@ kms_overlay_create(struct config *config, int *width, int *height)
goto err_mem;
priv->base.show = kms_overlay_show;
- priv->base.position = kms_overlay_position;
priv->base.hide = kms_overlay_hide;
priv->visible = false;
diff --git a/overlay/overlay.h b/overlay/overlay.h
index 3733fce0..793816d2 100644
--- a/overlay/overlay.h
+++ b/overlay/overlay.h
@@ -58,7 +58,6 @@ enum position {
struct overlay {
cairo_surface_t *surface;
void (*show)(struct overlay *);
- void (*position)(struct overlay *, enum position);
void (*hide)(struct overlay *);
};
diff --git a/overlay/x11/position.c b/overlay/x11/position.c
index ebfc3afe..f4302813 100644
--- a/overlay/x11/position.c
+++ b/overlay/x11/position.c
@@ -22,9 +22,17 @@
*
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <X11/Xlib.h>
+#ifdef HAVE_XRANDR
+#include <X11/extensions/Xrandr.h>
+#endif
#include <string.h>
#include <stdio.h>
+#include <stdlib.h>
#include "position.h"
#include "../overlay.h"
@@ -65,8 +73,47 @@ static enum position get_position(struct config *config)
return POS_UNSET;
}
+static void screen_size(Display *dpy, struct config *config,
+ int *scr_x, int *scr_y, int *scr_width, int *scr_height)
+{
+ const char *crtc;
+ Screen *scr;
+
+#ifdef HAVE_XRANDR
+ crtc = config_get_value(config, "x11", "crtc");
+ if (crtc) {
+ XRRScreenResources *res;
+ int i = atoi(crtc);
+ int ok = 0;
+
+ res = XRRGetScreenResourcesCurrent(dpy, DefaultRootWindow(dpy));
+ if (res) {
+ if (i < res->ncrtc) {
+ XRRCrtcInfo *info = XRRGetCrtcInfo (dpy, res, res->crtcs[i]);
+ if (info) {
+ *scr_x = info->x;
+ *scr_y = info->y;
+ *scr_width = info->width;
+ *scr_height = info->height;
+ ok = 1;
+ XRRFreeCrtcInfo(info);
+ }
+ }
+ XRRFreeScreenResources(res);
+ }
+ if (ok)
+ return;
+ }
+#endif
+
+ scr = ScreenOfDisplay(dpy, DefaultScreen(dpy));
+ *scr_x = *scr_y = 0;
+ *scr_width = scr->width;
+ *scr_height = scr->height;
+}
+
enum position
-x11_position(Screen *scr, int width, int height,
+x11_position(Display *dpy, int width, int height,
struct config *config,
int *x, int *y, int *w, int *h)
{
@@ -85,11 +132,14 @@ x11_position(Screen *scr, int width, int height,
if (*h < height/2)
*h = height/2;
} else {
+ int scr_x, scr_y, scr_width, scr_height;
+
+ screen_size(dpy, config, &scr_x, &scr_y, &scr_width, &scr_height);
position = get_position(config);
if (position != POS_UNSET) {
if (width == -1) {
- *w = scr->width;
+ *w = scr_width;
switch (position & 7) {
default:
case 0:
@@ -98,7 +148,7 @@ x11_position(Screen *scr, int width, int height,
}
if (height == -1) {
- *h = scr->height;
+ *h = scr_height;
switch ((position >> 4) & 7) {
default:
case 0:
@@ -132,27 +182,30 @@ x11_position(Screen *scr, int width, int height,
*h = height/2;
}
- if ((unsigned)*w > scr->width)
- *w = scr->width;
+ if ((unsigned)*w > scr_width)
+ *w = scr_width;
- if ((unsigned)*h > scr->height)
- *h = scr->height;
+ if ((unsigned)*h > scr_height)
+ *h = scr_height;
if (position != POS_UNSET) {
switch (position & 7) {
default:
case 0: *x = 0; break;
- case 1: *x = (scr->width - *w)/2; break;
- case 2: *x = scr->width - *w; break;
+ case 1: *x = (scr_width - *w)/2; break;
+ case 2: *x = scr_width - *w; break;
}
switch ((position >> 4) & 7) {
default:
case 0: *y = 0; break;
- case 1: *y = (scr->height - *h)/2; break;
- case 2: *y = scr->height - *h; break;
+ case 1: *y = (scr_height - *h)/2; break;
+ case 2: *y = scr_height - *h; break;
}
}
+
+ *x += scr_x;
+ *y += scr_y;
}
return position;
diff --git a/overlay/x11/position.h b/overlay/x11/position.h
index 6221109f..c0713df6 100644
--- a/overlay/x11/position.h
+++ b/overlay/x11/position.h
@@ -31,7 +31,7 @@ struct config;
enum position;
enum position
-x11_position(Screen *scr, int width, int height,
+x11_position(Display *dpy, int width, int height,
struct config *config,
int *x, int *y, int *w, int *h);
diff --git a/overlay/x11/x11-overlay.c b/overlay/x11/x11-overlay.c
index f57bd55d..38d58b07 100644
--- a/overlay/x11/x11-overlay.c
+++ b/overlay/x11/x11-overlay.c
@@ -92,37 +92,6 @@ static void x11_overlay_show(struct overlay *overlay)
}
}
-static void x11_overlay_position(struct overlay *overlay,
- enum position p)
-{
- struct x11_overlay *priv = to_x11_overlay(overlay);
- Screen *scr = ScreenOfDisplay(priv->dpy, DefaultScreen(priv->dpy));
-
- switch (p & 7) {
- default:
- case 0: priv->x = 0; break;
- case 1: priv->x = (scr->width - priv->image->width)/2; break;
- case 2: priv->x = scr->width - priv->image->width; break;
- }
-
- switch ((p >> 4) & 7) {
- default:
- case 0: priv->y = 0; break;
- case 1: priv->y = (scr->height - priv->image->height)/2; break;
- case 2: priv->y = scr->height - priv->image->height; break;
- }
-
- if (priv->visible) {
- XvPutImage(priv->dpy, priv->port, DefaultRootWindow(priv->dpy),
- priv->gc, priv->image,
- 0, 0,
- priv->image->width, priv->image->height,
- priv->x, priv->y,
- priv->image->width, priv->image->height);
- XFlush(priv->dpy);
- }
-}
-
static void x11_overlay_hide(struct overlay *overlay)
{
struct x11_overlay *priv = to_x11_overlay(overlay);
@@ -197,7 +166,7 @@ x11_overlay_create(struct config *config, int *width, int *height)
XSetErrorHandler(noop);
- position = x11_position(scr, *width, *height, config, &x, &y, &w, &h);
+ position = x11_position(dpy, *width, *height, config, &x, &y, &w, &h);
image = XvCreateImage(dpy, port, FOURCC_RGB565, NULL, w, h);
if (image == NULL)
@@ -276,7 +245,6 @@ x11_overlay_create(struct config *config, int *width, int *height)
priv->base.surface = surface;
priv->base.show = x11_overlay_show;
- priv->base.position = x11_overlay_position;
priv->base.hide = x11_overlay_hide;
priv->dpy = dpy;
diff --git a/overlay/x11/x11-window.c b/overlay/x11/x11-window.c
index 89d5c738..6bdc48c2 100644
--- a/overlay/x11/x11-window.c
+++ b/overlay/x11/x11-window.c
@@ -74,33 +74,6 @@ static void x11_window_show(struct overlay *overlay)
XFlush(priv->dpy);
}
-static void x11_window_position(struct overlay *overlay,
- enum position p)
-{
- struct x11_window *priv = to_x11_window(overlay);
- Screen *scr = ScreenOfDisplay(priv->dpy, DefaultScreen(priv->dpy));
- int x, y;
-
- switch (p & 7) {
- default:
- case 0: x = 0; break;
- case 1: x = (scr->width - priv->width)/2; break;
- case 2: x = scr->width - priv->width; break;
- }
-
- switch ((p >> 4) & 7) {
- default:
- case 0: y = 0; break;
- case 1: y = (scr->height - priv->height)/2; break;
- case 2: y = scr->height - priv->height; break;
- }
-
- if (priv->visible) {
- XMoveWindow(priv->dpy, priv->win, x, y);
- XFlush(priv->dpy);
- }
-}
-
static void x11_window_hide(struct overlay *overlay)
{
struct x11_window *priv = to_x11_window(overlay);
@@ -136,7 +109,6 @@ cairo_surface_t *
x11_window_create(struct config *config, int *width, int *height)
{
Display *dpy;
- Screen *scr;
Window win;
int screen;
cairo_surface_t *surface;
@@ -149,11 +121,10 @@ x11_window_create(struct config *config, int *width, int *height)
return NULL;
screen = DefaultScreen(dpy);
- scr = XScreenOfDisplay(dpy, screen);
XSetErrorHandler(noop);
- x11_position(scr, *width, *height, config, &x, &y, &w, &h);
+ x11_position(dpy, *width, *height, config, &x, &y, &w, &h);
attr.override_redirect = True;
win = XCreateWindow(dpy, DefaultRootWindow(dpy),
@@ -179,7 +150,6 @@ x11_window_create(struct config *config, int *width, int *height)
goto err_priv;
priv->base.show = x11_window_show;
- priv->base.position = x11_window_position;
priv->base.hide = x11_window_hide;
priv->dpy = dpy;