[PATCH v2 1/3] Store desktop dimensions in screenInfo.

Peter Hutterer peter.hutterer at who-t.net
Wed Oct 12 18:39:38 PDT 2011


For Zaphod mode screen crossing handling we need to know the size of all
screens together (i.e. the whole desktop size). Store that in the screenInfo to
have it readily available in events.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
Changes to v1:
- store x/y as well as width/height

 dix/dispatch.c                 |    2 +
 dix/inpututils.c               |   24 +++++++++
 hw/xfree86/common/xf86Cursor.c |    2 +
 hw/xfree86/common/xf86RandR.c  |    3 +
 hw/xfree86/modes/xf86RandR12.c |    2 +
 include/input.h                |    1 +
 include/scrnintstr.h           |    4 ++
 test/misc.c                    |  104 ++++++++++++++++++++++++++++++++++++++++
 8 files changed, 142 insertions(+), 0 deletions(-)

diff --git a/dix/dispatch.c b/dix/dispatch.c
index 43cb4d1..4a4481a 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -3898,6 +3898,8 @@ AddScreen(
 	return -1;
     }
 
+    update_desktop_dimensions();
+
     dixRegisterScreenPrivateKey(&cursorScreenDevPriv, pScreen, PRIVATE_CURSOR, 0);
 
     return i;
diff --git a/dix/inpututils.c b/dix/inpututils.c
index eeae2a7..8a83444 100644
--- a/dix/inpututils.c
+++ b/dix/inpututils.c
@@ -628,6 +628,30 @@ point_on_screen(ScreenPtr pScreen, int x, int y)
 }
 
 /**
+ * Update desktop dimensions on the screenInfo struct.
+ */
+void
+update_desktop_dimensions(void)
+{
+    int i;
+    int x1 = INT_MAX, y1 = INT_MAX; /* top-left */
+    int x2 = INT_MIN, y2 = INT_MIN; /* bottom-right */
+
+    for (i = 0; i < screenInfo.numScreens; i++) {
+        ScreenPtr screen = screenInfo.screens[i];
+        x1 = min(x1, screen->x);
+        y1 = min(y1, screen->y);
+        x2 = max(x2, screen->x + screen->width);
+        y2 = max(y2, screen->y + screen->height);
+    }
+
+    screenInfo.x = x1;
+    screenInfo.y = y1;
+    screenInfo.width = x2 - x1;
+    screenInfo.height = y2 - y1;
+}
+
+/*
  * Delete the element with the key from the list, freeing all memory
  * associated with the element..
  */
diff --git a/hw/xfree86/common/xf86Cursor.c b/hw/xfree86/common/xf86Cursor.c
index 929f047..6f5d726 100644
--- a/hw/xfree86/common/xf86Cursor.c
+++ b/hw/xfree86/common/xf86Cursor.c
@@ -838,6 +838,8 @@ xf86InitOrigins(void)
 		FillOutEdge(pLayout->down, pScreen->width);
 	}
     }
+
+    update_desktop_dimensions();
 }
 
 void
diff --git a/hw/xfree86/common/xf86RandR.c b/hw/xfree86/common/xf86RandR.c
index 4663d03..d0e4784 100644
--- a/hw/xfree86/common/xf86RandR.c
+++ b/hw/xfree86/common/xf86RandR.c
@@ -313,6 +313,9 @@ xf86RandRSetConfig (ScreenPtr		pScreen,
 	return FALSE;
     }
 
+
+    update_desktop_dimensions();
+
     /*
      * Move the cursor back where it belongs; SwitchMode repositions it
      * FIXME: duplicated code, see modes/xf86RandR12.c
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index cb20d1c..d5031a2 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -736,6 +736,8 @@ xf86RandR12ScreenSetSize (ScreenPtr	pScreen,
     xf86SetViewport (pScreen, 0, 0);
 
 finish:
+    update_desktop_dimensions();
+
     if (pRoot && pScrn->vtSema)
 	(*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE);
 #if RANDR_12_INTERFACE
diff --git a/include/input.h b/include/input.h
index b7de5ca..2544996 100644
--- a/include/input.h
+++ b/include/input.h
@@ -609,5 +609,6 @@ extern _X_EXPORT void input_option_set_key(InputOption *opt, const char* key);
 extern _X_EXPORT void input_option_set_value(InputOption *opt, const char* value);
 
 extern _X_HIDDEN Bool point_on_screen(ScreenPtr pScreen, int x, int y);
+extern _X_HIDDEN void update_desktop_dimensions(void);
 
 #endif /* INPUT_H */
diff --git a/include/scrnintstr.h b/include/scrnintstr.h
index a9357e8..132a671 100644
--- a/include/scrnintstr.h
+++ b/include/scrnintstr.h
@@ -561,6 +561,10 @@ typedef struct _ScreenInfo {
 		formats[MAXFORMATS];
     int		numScreens;
     ScreenPtr	screens[MAXSCREENS];
+    int         x;      /* origin */
+    int         y;      /* origin */
+    int		width;  /* total width of all screens together */
+    int		height; /* total height of all screens together */
 } ScreenInfo;
 
 extern _X_EXPORT ScreenInfo screenInfo;
diff --git a/test/misc.c b/test/misc.c
index 3d3b1a1..d98449b 100644
--- a/test/misc.c
+++ b/test/misc.c
@@ -27,6 +27,9 @@
 
 #include <stdint.h>
 #include "misc.h"
+#include "scrnintstr.h"
+
+ScreenInfo screenInfo;
 
 static void dix_version_compare(void)
 {
@@ -54,9 +57,110 @@ static void dix_version_compare(void)
     assert(rc < 0);
 }
 
+static void dix_update_desktop_dimensions(void)
+{
+    int i;
+    int x, y, w, h;
+    int w2, h2;
+    ScreenRec screens[MAXSCREENS];
+
+    for (i = 0; i < MAXSCREENS; i++)
+        screenInfo.screens[i] = &screens[i];
+
+    x = 0;
+    y = 0;
+    w = 10;
+    h = 5;
+    w2 = 35;
+    h2 = 25;
+
+#define assert_dimensions(_x, _y, _w, _h) \
+    update_desktop_dimensions();          \
+    printf("%d %d %d %d\n", screenInfo.x, screenInfo.y, screenInfo.width, screenInfo.height); \
+    assert(screenInfo.x == _x);           \
+    assert(screenInfo.y == _y);           \
+    assert(screenInfo.width == _w);       \
+    assert(screenInfo.height == _h);
+
+#define set_screen(idx, _x, _y, _w, _h)   \
+    screenInfo.screens[idx]->x = _x;      \
+    screenInfo.screens[idx]->y = _y;      \
+    screenInfo.screens[idx]->width = _w;  \
+    screenInfo.screens[idx]->height = _h; \
+
+    printf("Testing\n");
+
+    /* single screen */
+    screenInfo.numScreens = 1;
+    set_screen(0, x, y, w, h);
+    assert_dimensions(x, y, w, h);
+
+    /* dualhead rightof */
+    screenInfo.numScreens = 2;
+    set_screen(1, w, 0, w2, h2);
+    assert_dimensions(x, y, w + w2, h2);
+
+    /* dualhead belowof */
+    screenInfo.numScreens = 2;
+    set_screen(1, 0, h, w2, h2);
+    assert_dimensions(x, y, w2, h + h2);
+
+    /* triplehead L shape */
+    screenInfo.numScreens = 3;
+    set_screen(1, 0, h, w2, h2);
+    set_screen(2, w2, h2, w, h);
+    assert_dimensions(x, y, w + w2, h + h2);
+
+    /* quadhead 2x2 */
+    screenInfo.numScreens = 4;
+    set_screen(1, 0, h, w, h);
+    set_screen(2, w, h, w, h2);
+    set_screen(3, w, 0, w2, h);
+    assert_dimensions(x, y, w + w2, h + h2);
+
+    /* quadhead horiz line */
+    screenInfo.numScreens = 4;
+    set_screen(1, w, 0, w, h);
+    set_screen(2, 2 * w, 0, w, h);
+    set_screen(3, 3 * w, 0, w, h);
+    assert_dimensions(x, y, 4 * w, h);
+
+    /* quadhead vert line */
+    screenInfo.numScreens = 4;
+    set_screen(1, 0, h, w, h);
+    set_screen(2, 0, 2 * h, w, h);
+    set_screen(3, 0, 3 * h, w, h);
+    assert_dimensions(x, y, w, 4 * h);
+
+
+    /* x overlap */
+    screenInfo.numScreens = 2;
+    set_screen(0, 0, 0, w2, h2);
+    set_screen(1, w, 0, w2, h2);
+    assert_dimensions(x, y, w2 + w, h2);
+
+    /* y overlap */
+    screenInfo.numScreens = 2;
+    set_screen(0, 0, 0, w2, h2);
+    set_screen(1, 0, h, w2, h2);
+    assert_dimensions(x, y, w2, h2 + h);
+
+    /* negative origin */
+    screenInfo.numScreens = 1;
+    set_screen(0, -w2, -h2, w, h);
+    assert_dimensions(-w2, -h2, w, h);
+
+    /* dualhead negative origin, overlap */
+    screenInfo.numScreens = 2;
+    set_screen(0, -w2, -h2, w2, h2);
+    set_screen(1, -w, -h, w, h);
+    assert_dimensions(-w2, -h2, w2, h2);
+}
+
 int main(int argc, char** argv)
 {
     dix_version_compare();
+    dix_update_desktop_dimensions();
 
     return 0;
 }
-- 
1.7.6.4



More information about the xorg-devel mailing list