1
From ad2c48ab05d9415aa384eda6be52576525a3abcf Mon Sep 17 00:00:00 2001
1
From 14f1112bec18ccece8e732fe6c200a56546230c7 Mon Sep 17 00:00:00 2001
2
2
From: Adam Jackson <ajax@redhat.com>
3
3
Date: Thu, 17 Mar 2011 13:56:17 -0400
4
4
Subject: [PATCH] CRTC confine and pointer barriers
8
dix/getevents.c | 12 +-
7
10
include/protocol-versions.h | 2 +-
8
xfixes/cursor.c | 408 ++++++++++++++++++++++++++++++++++++++++++-
11
mi/mipointer.c | 16 ++-
14
randr/randrstr.h | 4 +
15
randr/rrcrtc.c | 155 ++++++++++++++++
16
xfixes/cursor.c | 399 ++++++++++++++++++++++++++++++++++++++++++-
9
17
xfixes/xfixes.c | 24 ++-
10
18
xfixes/xfixes.h | 17 ++
11
19
xfixes/xfixesint.h | 16 ++
12
6 files changed, 458 insertions(+), 12 deletions(-)
20
14 files changed, 658 insertions(+), 16 deletions(-)
22
diff --git a/dix/events.c b/dix/events.c
23
index 07f8b05..d2be84f 100644
26
@@ -328,6 +328,13 @@ IsMaster(DeviceIntPtr dev)
27
return dev->type == MASTER_POINTER || dev->type == MASTER_KEYBOARD;
31
+IsFloating(DeviceIntPtr dev)
33
+ return GetMaster(dev, MASTER_KEYBOARD) == NULL;
40
diff --git a/dix/getevents.c b/dix/getevents.c
41
index 794df42..c66e516 100644
44
@@ -812,7 +812,11 @@ accelPointer(DeviceIntPtr dev, int first, int num, int *valuators, CARD32 ms)
45
* miPointerSetPosition() and then scale back into device coordinates (if
46
* needed). miPSP will change x/y if the screen was crossed.
48
+ * The coordinates provided are always absolute. The parameter mode whether
49
+ * it was relative or absolute movement that landed us at those coordinates.
51
* @param dev The device to be moved.
52
+ * @param mode Movement mode (Absolute or Relative)
53
* @param x Pointer to current x-axis value, may be modified.
54
* @param y Pointer to current y-axis value, may be modified.
55
* @param x_frac Fractional part of current x-axis value, may be modified.
56
@@ -824,7 +828,8 @@ accelPointer(DeviceIntPtr dev, int first, int num, int *valuators, CARD32 ms)
57
* @param screeny_frac Fractional part of screen y coordinate, as above.
60
-positionSprite(DeviceIntPtr dev, int *x, int *y, float x_frac, float y_frac,
61
+positionSprite(DeviceIntPtr dev, int mode,
62
+ int *x, int *y, float x_frac, float y_frac,
63
ScreenPtr scr, int *screenx, int *screeny, float *screenx_frac, float *screeny_frac)
65
int old_screenx, old_screeny;
66
@@ -863,7 +868,7 @@ positionSprite(DeviceIntPtr dev, int *x, int *y, float x_frac, float y_frac,
67
old_screeny = *screeny;
68
/* This takes care of crossing screens for us, as well as clipping
69
* to the current screen. */
70
- miPointerSetPosition(dev, screenx, screeny);
71
+ _miPointerSetPosition(dev, mode, screenx, screeny);
74
dev->u.master->last.valuators[0] = *screenx;
75
@@ -1193,7 +1198,8 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
77
set_raw_valuators(raw, &mask, raw->valuators.data);
79
- positionSprite(pDev, &x, &y, x_frac, y_frac, scr, &cx, &cy, &cx_frac, &cy_frac);
80
+ positionSprite(pDev, (flags & POINTER_ABSOLUTE) ? Absolute : Relative,
81
+ &x, &y, x_frac, y_frac, scr, &cx, &cy, &cx_frac, &cy_frac);
82
updateHistory(pDev, &mask, ms);
84
/* Update the valuators with the true value sent to the client*/
85
diff --git a/include/dix.h b/include/dix.h
86
index 12e4b59..3f99098 100644
89
@@ -570,6 +570,7 @@ extern Bool _X_EXPORT IsPointerDevice( DeviceIntPtr dev);
90
extern Bool _X_EXPORT IsKeyboardDevice(DeviceIntPtr dev);
91
extern Bool IsPointerEvent(InternalEvent *event);
92
extern _X_EXPORT Bool IsMaster(DeviceIntPtr dev);
93
+extern _X_EXPORT Bool IsFloating(DeviceIntPtr dev);
95
extern _X_HIDDEN void CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master);
96
extern _X_HIDDEN int CorePointerProc(DeviceIntPtr dev, int what);
14
97
diff --git a/include/protocol-versions.h b/include/protocol-versions.h
15
index 8692ded..7b7a9f5 100644
98
index 1d33bdd..1dc66ad 100644
16
99
--- a/include/protocol-versions.h
17
100
+++ b/include/protocol-versions.h
19
102
#define SERVER_XF86VIDMODE_MINOR_VERSION 2
24
107
#define SERVER_XFIXES_MINOR_VERSION 0
110
diff --git a/mi/mipointer.c b/mi/mipointer.c
111
index 554397a..85f1949 100644
114
@@ -229,6 +229,10 @@ miPointerSetCursorPosition(DeviceIntPtr pDev, ScreenPtr pScreen,
115
SetupScreen (pScreen);
117
GenerateEvent = generateEvent;
119
+ if (pScreen->ConstrainCursorHarder)
120
+ pScreen->ConstrainCursorHarder(pDev, pScreen, Absolute, &x, &y);
122
/* device dependent - must pend signal and call miPointerWarpCursor */
123
(*pScreenPriv->screenFuncs->WarpCursor) (pDev, pScreen, x, y);
125
@@ -484,7 +488,7 @@ miPointerMoveNoEvent (DeviceIntPtr pDev, ScreenPtr pScreen,
129
-miPointerSetPosition(DeviceIntPtr pDev, int *x, int *y)
130
+_miPointerSetPosition(DeviceIntPtr pDev, int mode, int *x, int *y)
132
miPointerScreenPtr pScreenPriv;
134
@@ -529,6 +533,9 @@ miPointerSetPosition(DeviceIntPtr pDev, int *x, int *y)
135
if (*y >= pPointer->limits.y2)
136
*y = pPointer->limits.y2 - 1;
138
+ if (pScreen->ConstrainCursorHarder)
139
+ pScreen->ConstrainCursorHarder(pDev, pScreen, mode, x, y);
141
if (pPointer->x == *x && pPointer->y == *y &&
142
pPointer->pScreen == pScreen)
144
@@ -536,6 +543,13 @@ miPointerSetPosition(DeviceIntPtr pDev, int *x, int *y)
145
miPointerMoveNoEvent(pDev, pScreen, *x, *y);
150
+miPointerSetPosition(DeviceIntPtr pDev, int *x, int *y)
152
+ _miPointerSetPosition(pDev, Absolute, x, y);
156
miPointerGetPosition(DeviceIntPtr pDev, int *x, int *y)
158
diff --git a/mi/mipointer.h b/mi/mipointer.h
159
index 3c86110..6b6010c 100644
162
@@ -131,6 +131,12 @@ extern _X_EXPORT void miPointerGetPosition(
164
/* Moves the cursor to the specified position. May clip the co-ordinates:
165
* x and y are modified in-place. */
166
+extern _X_EXPORT void _miPointerSetPosition(
172
extern _X_EXPORT void miPointerSetPosition(
175
diff --git a/randr/randr.c b/randr/randr.c
176
index 6077705..d337129 100644
179
@@ -270,6 +270,8 @@ Bool RRScreenInit(ScreenPtr pScreen)
181
wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen);
183
+ pScreen->ConstrainCursorHarder = RRConstrainCursorHarder;
185
pScrPriv->numOutputs = 0;
186
pScrPriv->outputs = NULL;
187
pScrPriv->numCrtcs = 0;
188
diff --git a/randr/randrstr.h b/randr/randrstr.h
189
index 7ea6080..d8dd37d 100644
190
--- a/randr/randrstr.h
191
+++ b/randr/randrstr.h
192
@@ -297,6 +297,7 @@ typedef struct _rrScrPriv {
196
+ Bool discontiguous;
197
} rrScrPrivRec, *rrScrPrivPtr;
199
extern _X_EXPORT DevPrivateKeyRec rrPrivKeyRec;
200
@@ -700,6 +701,9 @@ ProcRRGetPanning (ClientPtr client);
202
ProcRRSetPanning (ClientPtr client);
205
+RRConstrainCursorHarder (DeviceIntPtr, ScreenPtr, int, int *, int *);
208
extern _X_EXPORT Bool
209
RRClientKnowsRates (ClientPtr pClient);
210
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
211
index 98206a2..d4d8f2a 100644
216
* Copyright © 2006 Keith Packard
217
+ * Copyright 2010 Red Hat, Inc
219
* Permission to use, copy, modify, distribute, and sell this software and its
220
* documentation for any purpose is hereby granted without fee, provided that
223
#include "randrstr.h"
225
+#include "mipointer.h"
229
@@ -292,6 +294,92 @@ RRCrtcPendingProperties (RRCrtcPtr crtc)
234
+crtc_bounds(RRCrtcPtr crtc, int *left, int *right, int *top, int *bottom)
239
+ switch (crtc->rotation) {
241
+ case RR_Rotate_180:
243
+ *right = crtc->x + crtc->mode->mode.width;
244
+ *bottom = crtc->y + crtc->mode->mode.height;
247
+ case RR_Rotate_270:
248
+ *right = crtc->x + crtc->mode->mode.height;
249
+ *bottom = crtc->y + crtc->mode->mode.width;
254
+/* overlapping counts as adjacent */
256
+crtcs_adjacent(const RRCrtcPtr a, const RRCrtcPtr b)
258
+ /* left, right, top, bottom... */
259
+ int al, ar, at, ab;
260
+ int bl, br, bt, bb;
261
+ int cl, cr, ct, cb; /* the overlap, if any */
263
+ crtc_bounds(a, &al, &ar, &at, &ab);
264
+ crtc_bounds(b, &bl, &br, &bt, &bb);
271
+ return (cl <= cr) && (ct <= cb);
274
+/* Depth-first search and mark all CRTCs reachable from cur */
276
+mark_crtcs (rrScrPrivPtr pScrPriv, int *reachable, int cur)
279
+ reachable[cur] = TRUE;
280
+ for (i = 0; i < pScrPriv->numCrtcs; ++i) {
281
+ if (reachable[i] || !pScrPriv->crtcs[i]->mode)
283
+ if (crtcs_adjacent(pScrPriv->crtcs[cur], pScrPriv->crtcs[i]))
284
+ mark_crtcs(pScrPriv, reachable, i);
289
+RRComputeContiguity (ScreenPtr pScreen)
291
+ rrScrPriv(pScreen);
292
+ Bool discontiguous = TRUE;
293
+ int i, n = pScrPriv->numCrtcs;
295
+ int *reachable = calloc(n, sizeof(int));
299
+ /* Find first enabled CRTC and start search for reachable CRTCs from it */
300
+ for (i = 0; i < n; ++i) {
301
+ if (pScrPriv->crtcs[i]->mode) {
302
+ mark_crtcs(pScrPriv, reachable, i);
307
+ /* Check that all enabled CRTCs were marked as reachable */
308
+ for (i = 0; i < n; ++i)
309
+ if (pScrPriv->crtcs[i]->mode && !reachable[i])
312
+ discontiguous = FALSE;
316
+ pScrPriv->discontiguous = discontiguous;
320
* Request that the Crtc be reconfigured
322
@@ -306,6 +394,7 @@ RRCrtcSet (RRCrtcPtr crtc,
324
ScreenPtr pScreen = crtc->pScreen;
326
+ Bool recompute = TRUE;
329
/* See if nothing changed */
330
@@ -318,6 +407,7 @@ RRCrtcSet (RRCrtcPtr crtc,
331
!RRCrtcPendingProperties (crtc) &&
332
!RRCrtcPendingTransform (crtc))
338
@@ -381,6 +471,10 @@ RRCrtcSet (RRCrtcPtr crtc,
339
RRPostPendingProperties (outputs[o]);
344
+ RRComputeContiguity(pScreen);
349
@@ -1349,3 +1443,64 @@ ProcRRGetCrtcTransform (ClientPtr client)
355
+RRConstrainCursorHarder(DeviceIntPtr pDev, ScreenPtr pScreen, int mode, int *x, int *y)
357
+ rrScrPriv (pScreen);
360
+ /* intentional dead space -> let it float */
361
+ if (pScrPriv->discontiguous)
364
+ /* if we're moving inside a crtc, we're fine */
365
+ for (i = 0; i < pScrPriv->numCrtcs; i++) {
366
+ RRCrtcPtr crtc = pScrPriv->crtcs[i];
368
+ int left, right, top, bottom;
373
+ crtc_bounds(crtc, &left, &right, &top, &bottom);
375
+ if ((*x >= left) && (*x <= right) && (*y >= top) && (*y <= bottom))
379
+ /* if we're trying to escape, clamp to the CRTC we're coming from */
380
+ for (i = 0; i < pScrPriv->numCrtcs; i++) {
381
+ RRCrtcPtr crtc = pScrPriv->crtcs[i];
383
+ int left, right, top, bottom;
388
+ crtc_bounds(crtc, &left, &right, &top, &bottom);
389
+ miPointerGetPosition(pDev, &nx, &ny);
391
+ if ((nx >= left) && (nx <= right) && (ny >= top) && (ny <= bottom)) {
392
+ if ((*x <= left) || (*x >= right)) {
401
+ if ((*y <= top) || (*y >= bottom)) {
27
414
diff --git a/xfixes/cursor.c b/xfixes/cursor.c
28
415
index fb608f6..5c55c95 100644
29
416
--- a/xfixes/cursor.c