aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikhil Devshatwar2013-06-10 08:58:41 -0500
committerNikhil Devshatwar2013-06-10 08:58:41 -0500
commit1680ed87f202cedafa8e80239a825c2694172de2 (patch)
tree8be2642cd461c4b8e350790e185f23f405e8f561
parentd57f3032216f67daf49b532cdbb9231a0c2827b2 (diff)
downloadxserver-1680ed87f202cedafa8e80239a825c2694172de2.tar.gz
xserver-1680ed87f202cedafa8e80239a825c2694172de2.tar.xz
xserver-1680ed87f202cedafa8e80239a825c2694172de2.zip
Removing debian/patches directoryHEADmaster
-rw-r--r--debian/patches/0001-add-dri2video.patch1182
-rw-r--r--debian/patches/001_fedora_extramodes.patch83
-rw-r--r--debian/patches/02_Add-libnettle-as-option-for-sha1.diff90
-rw-r--r--debian/patches/07-xfree86-fix-build-with-xv-disabled.diff50
-rw-r--r--debian/patches/1001-xfree86-modes-Let-the-driver-handle-the-transform.patch333
-rw-r--r--debian/patches/1002-xfree86-modes-Make-cursor-position-transform-a-helpe.patch117
-rw-r--r--debian/patches/100_rethrow_signals.patch375
-rw-r--r--debian/patches/105_nvidia_fglrx_autodetect.patch83
-rw-r--r--debian/patches/111_armel-drv-fallbacks.patch62
-rw-r--r--debian/patches/122_xext_fix_card32_overflow_in_xauth.patch38
-rw-r--r--debian/patches/13_debian_add_xkbpath_env_variable.diff27
-rw-r--r--debian/patches/15-nouveau.diff68
-rw-r--r--debian/patches/157_check_null_modes.patch14
-rw-r--r--debian/patches/162_null_crtc_in_rotation.patch14
-rw-r--r--debian/patches/165_man_xorg_conf_no_device_ident.patch26
-rw-r--r--debian/patches/166_nullptr_xinerama_keyrepeat.patch27
-rw-r--r--debian/patches/167_nullptr_xisbread.patch14
-rw-r--r--debian/patches/168_glibc_trace_to_stderr.patch17
-rw-r--r--debian/patches/172_cwgetbackingpicture_nullptr_check.patch35
-rw-r--r--debian/patches/188_default_primary_to_first_busid.patch20
-rw-r--r--debian/patches/190_cache-xkbcomp_output_for_fast_start_up.patch343
-rw-r--r--debian/patches/191-Xorg-add-an-extra-module-path.patch99
-rw-r--r--debian/patches/198_nohwaccess.patch55
-rw-r--r--debian/patches/200_randr-null.patch14
-rw-r--r--debian/patches/201_report-real-dpi.patch46
-rw-r--r--debian/patches/208_switch_on_release.diff109
-rw-r--r--debian/patches/209_add_legacy_bgnone_option.patch21
-rw-r--r--debian/patches/214_glx_dri_searchdirs.patch240
-rw-r--r--debian/patches/217_revert_bgnonevisitwindow.patch43
-rw-r--r--debian/patches/219_fedora-pointer-barriers.diff1020
-rw-r--r--debian/patches/224_return_BadWindow_not_BadMatch.diff47
-rw-r--r--debian/patches/225_non-root_config_paths.patch247
-rw-r--r--debian/patches/226_fall_back_to_autoconfiguration.patch105
-rw-r--r--debian/patches/227_null_ptr_midispcur.patch14
-rw-r--r--debian/patches/228_log-format-fix.patch441
-rw-r--r--debian/patches/229_randr_first_check_pScrPriv_before_using_the_pointer.patch30
-rw-r--r--debian/patches/230_randr_catch_two_more_potential_unset_rrScrPriv_uses.patch52
-rw-r--r--debian/patches/233-xf86events-valgrind.patch19
-rw-r--r--debian/patches/235-composite-tracking.diff63
-rw-r--r--debian/patches/238-xrandr-fix-panning.patch129
-rw-r--r--debian/patches/500_pointer_barrier_thresholds.diff1694
-rw-r--r--debian/patches/505_query_pointer_touchscreen.patch32
-rw-r--r--debian/patches/506_touchscreen_pointer_emulation_checks.patch159
-rw-r--r--debian/patches/507_touchscreen_fixes.patch540
-rw-r--r--debian/patches/508_device_off_release_buttons.patch37
-rw-r--r--debian/patches/510-dix-return-early-from-DisableDevice-if-the-device-is.patch29
-rw-r--r--debian/patches/511-dix-move-freeing-the-sprite-into-a-function.patch62
-rw-r--r--debian/patches/512-dix-free-the-sprite-when-disabling-the-device.patch31
-rw-r--r--debian/patches/513-dix-disable-non-sprite-owners-first-when-disabling-p.patch41
-rw-r--r--debian/patches/514-Xi-drop-forced-unpairing-when-changing-the-hierarchy.patch33
-rw-r--r--debian/patches/515-dix-disable-all-devices-before-shutdown.patch85
-rw-r--r--debian/patches/516-dix-dont-emulate-scroll-events-for-non-existing-axes.patch39
-rw-r--r--debian/patches/516-randr-first-check-pScrPriv-before-using-the-pointer.patch30
-rw-r--r--debian/patches/517-randr-Catch-two-more-potential-unset-rrScrPriv-uses.patch52
-rw-r--r--debian/patches/series62
55 files changed, 0 insertions, 8738 deletions
diff --git a/debian/patches/0001-add-dri2video.patch b/debian/patches/0001-add-dri2video.patch
deleted file mode 100644
index 7922f66..0000000
--- a/debian/patches/0001-add-dri2video.patch
+++ /dev/null
@@ -1,1182 +0,0 @@
1From 1301542b17a9ea3cc185e24a3e40d33daa66e8ce Mon Sep 17 00:00:00 2001
2From: Rob Clark <rob@ti.com>
3Date: Tue, 15 Nov 2011 14:28:06 -0600
4Subject: [PATCH] add dri2video
5
6TODO:
7 + implement OSD support.. core should register damage and automatically
8 re-call ScheduleSwapVid..
9 + automatically re-call ScheduleSwapVid on dri2 drawable resize...
10---
11 hw/xfree86/dri2/dri2.c | 364 +++++++++++++++++++++++++++++++++++++--------
12 hw/xfree86/dri2/dri2.h | 127 ++++++++++++++++-
13 hw/xfree86/dri2/dri2ext.c | 214 +++++++++++++++++++++++++-
14 3 files changed, 632 insertions(+), 73 deletions(-)
15
16Index: xserver/hw/xfree86/dri2/dri2.c
17===================================================================
18--- xserver.orig/hw/xfree86/dri2/dri2.c 2012-02-22 11:04:26.000000000 +0100
19+++ xserver/hw/xfree86/dri2/dri2.c 2012-02-22 16:32:28.000000000 +0100
20@@ -91,6 +91,8 @@
21 int refcnt;
22 unsigned int numDrivers;
23 const char **driverNames;
24+ unsigned int numFormats;
25+ unsigned int *formats;
26 const char *deviceName;
27 int fd;
28 unsigned int lastSequence;
29@@ -102,12 +104,29 @@
30 DRI2GetMSCProcPtr GetMSC;
31 DRI2ScheduleWaitMSCProcPtr ScheduleWaitMSC;
32 DRI2AuthMagicProcPtr AuthMagic;
33+ DRI2ReuseBufferNotifyProcPtr ReuseBufferNotify;
34+ DRI2SwapLimitValidateProcPtr SwapLimitValidate;
35+ DRI2GetExtraBufferNamesProcPtr GetExtraBufferNames;
36+ DRI2CreateBufferVidProcPtr CreateBufferVid;
37+ DRI2ScheduleSwapVidProcPtr ScheduleSwapVid;
38+ DRI2SetAttributeProcPtr SetAttribute;
39+ DRI2GetAttributeProcPtr GetAttribute;
40
41 HandleExposuresProcPtr HandleExposures;
42
43 ConfigNotifyProcPtr ConfigNotify;
44 } DRI2ScreenRec;
45
46+static Bool
47+supports_video(DRI2ScreenPtr ds)
48+{
49+ /* it would be easier if we had a way to track the driverType in the
50+ * DRI2DrawablePtr.. but the DRI2DrawablePtr isn't created at the
51+ * time of DRI2Connect()..
52+ */
53+ return ds && ds->numFormats && ds->CreateBufferVid && ds->ScheduleSwapVid;
54+}
55+
56 static DRI2ScreenPtr
57 DRI2GetScreen(ScreenPtr pScreen)
58 {
59@@ -179,6 +198,7 @@
60 pPriv->last_swap_ust = 0;
61 list_init(&pPriv->reference_list);
62 pPriv->serialNumber = DRI2DrawableSerial(pDraw);
63+ pPriv->needInvalidate = FALSE;
64
65 if (pDraw->type == DRAWABLE_WINDOW) {
66 pWin = (WindowPtr) pDraw;
67@@ -191,6 +211,35 @@
68 return pPriv;
69 }
70
71+Bool
72+DRI2SwapLimit(DrawablePtr pDraw, int swap_limit)
73+{
74+ DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw);
75+ DRI2ScreenPtr ds;
76+ if (!pPriv)
77+ return FALSE;
78+
79+ ds = pPriv->dri2_screen;
80+
81+ if (!ds->SwapLimitValidate
82+ || !ds->SwapLimitValidate(pDraw, swap_limit))
83+ return FALSE;
84+
85+ pPriv->swap_limit = swap_limit;
86+
87+ /* Check throttling */
88+ if (pPriv->swapsPending >= pPriv->swap_limit)
89+ return TRUE;
90+
91+ if (pPriv->target_sbc == -1 && !pPriv->blockedOnMsc) {
92+ if (pPriv->blockedClient) {
93+ AttendClient(pPriv->blockedClient);
94+ pPriv->blockedClient = NULL;
95+ }
96+ }
97+
98+ return TRUE;
99+}
100 typedef struct DRI2DrawableRefRec {
101 XID id;
102 XID dri2_id;
103@@ -264,15 +313,26 @@
104 return Success;
105 }
106
107+static void destroy_buffers(DrawablePtr pDraw, DRI2BufferPtr *buffers, int count)
108+{
109+ if (buffers != NULL) {
110+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
111+ int i;
112+ for (i = 0; i < count; i++)
113+ if (buffers[i])
114+ (*ds->DestroyBuffer)(pDraw, buffers[i]);
115+
116+ free(buffers);
117+ }
118+}
119+
120 static int DRI2DrawableGone(pointer p, XID id)
121 {
122 DRI2DrawablePtr pPriv = p;
123- DRI2ScreenPtr ds = pPriv->dri2_screen;
124 DRI2DrawableRefPtr ref, next;
125 WindowPtr pWin;
126 PixmapPtr pPixmap;
127 DrawablePtr pDraw;
128- int i;
129
130 list_for_each_entry_safe(ref, next, &pPriv->reference_list, link) {
131 if (ref->dri2_id == id) {
132@@ -304,12 +364,7 @@
133 dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, NULL);
134 }
135
136- if (pPriv->buffers != NULL) {
137- for (i = 0; i < pPriv->bufferCount; i++)
138- (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
139-
140- free(pPriv->buffers);
141- }
142+ destroy_buffers(pDraw, pPriv->buffers, pPriv->bufferCount);
143
144 free(pPriv);
145
146@@ -317,7 +372,7 @@
147 }
148
149 static int
150-find_attachment(DRI2DrawablePtr pPriv, unsigned attachment)
151+find_attachment(DRI2DrawablePtr pPriv, unsigned attachment, DRI2BufferPtr *buf)
152 {
153 int i;
154
155@@ -328,6 +383,8 @@
156 for (i = 0; i < pPriv->bufferCount; i++) {
157 if ((pPriv->buffers[i] != NULL)
158 && (pPriv->buffers[i]->attachment == attachment)) {
159+ if (buf)
160+ *buf = pPriv->buffers[i];
161 return i;
162 }
163 }
164@@ -336,14 +393,27 @@
165 }
166
167 static Bool
168+valid_format(DRI2ScreenPtr ds, unsigned int format)
169+{
170+ int i;
171+ for (i = 0; i < ds->numFormats; i++) {
172+ if (format == ds->formats[i]) {
173+ return TRUE;
174+ }
175+ }
176+ return FALSE;
177+}
178+
179+static Bool
180 allocate_or_reuse_buffer(DrawablePtr pDraw, DRI2ScreenPtr ds,
181 DRI2DrawablePtr pPriv,
182 unsigned int attachment, unsigned int format,
183 int dimensions_match, DRI2BufferPtr *buffer)
184 {
185- int old_buf = find_attachment(pPriv, attachment);
186+ int old_buf = find_attachment(pPriv, attachment, NULL);
187
188 if ((old_buf < 0)
189+ || attachment == DRI2BufferFrontLeft
190 || !dimensions_match
191 || (pPriv->buffers[old_buf]->format != format)) {
192 *buffer = (*ds->CreateBuffer)(pDraw, attachment, format);
193@@ -352,6 +422,8 @@
194
195 } else {
196 *buffer = pPriv->buffers[old_buf];
197+ if (ds->ReuseBufferNotify)
198+ (*ds->ReuseBufferNotify)(pDraw, *buffer);
199 pPriv->buffers[old_buf] = NULL;
200 return FALSE;
201 }
202@@ -361,18 +433,7 @@
203 update_dri2_drawable_buffers(DRI2DrawablePtr pPriv, DrawablePtr pDraw,
204 DRI2BufferPtr *buffers, int out_count, int *width, int *height)
205 {
206- DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
207- int i;
208-
209- if (pPriv->buffers != NULL) {
210- for (i = 0; i < pPriv->bufferCount; i++) {
211- if (pPriv->buffers[i] != NULL) {
212- (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
213- }
214- }
215-
216- free(pPriv->buffers);
217- }
218+ destroy_buffers(pDraw, pPriv->buffers, pPriv->bufferCount);
219
220 pPriv->buffers = buffers;
221 pPriv->bufferCount = out_count;
222@@ -417,6 +478,15 @@
223 const unsigned attachment = *(attachments++);
224 const unsigned format = (has_format) ? *(attachments++) : 0;
225
226+ /* note: don't require a valid format for old drivers which don't
227+ * register their supported formats..
228+ */
229+ if (has_format && (ds->numFormats > 0) && !valid_format(ds, format)) {
230+ xf86DrvMsg(pDraw->pScreen->myNum, X_ERROR,
231+ "[DRI2] %s: bad format: %d\n", __func__, format);
232+ goto err_out;
233+ }
234+
235 if (allocate_or_reuse_buffer(pDraw, ds, pPriv, attachment,
236 format, dimensions_match,
237 &buffers[i]))
238@@ -506,19 +576,11 @@
239
240 *out_count = 0;
241
242- if (buffers) {
243- for (i = 0; i < count; i++) {
244- if (buffers[i] != NULL)
245- (*ds->DestroyBuffer)(pDraw, buffers[i]);
246- }
247+ destroy_buffers(pDraw, buffers, count);
248
249- free(buffers);
250- buffers = NULL;
251- }
252+ update_dri2_drawable_buffers(pPriv, pDraw, NULL, *out_count, width, height);
253
254- update_dri2_drawable_buffers(pPriv, pDraw, buffers, *out_count, width, height);
255-
256- return buffers;
257+ return NULL;
258 }
259
260 DRI2BufferPtr *
261@@ -537,6 +599,95 @@
262 out_count, TRUE);
263 }
264
265+DRI2BufferPtr *
266+DRI2GetBuffersVid(DrawablePtr pDraw, int width, int height,
267+ unsigned int *attachments, int count, int *out_count)
268+{
269+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
270+ DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw);
271+ DRI2BufferPtr *buffers;
272+ int i, n = 0;
273+
274+ if (!pPriv || !supports_video(ds)) {
275+ *out_count = 0;
276+ return NULL;
277+ }
278+
279+ buffers = calloc(count, sizeof(buffers[0]));
280+ if (!buffers)
281+ goto err_out;
282+
283+ for (i = 0; i < count; i++) {
284+ DRI2BufferPtr buf;
285+ const unsigned attachment = *(attachments++);
286+ const unsigned format = *(attachments++);
287+
288+ /* grow array of stored buffers if needed: */
289+ if (attachment >= pPriv->bufferCount) {
290+ int n = attachment + 1;
291+ DRI2BufferPtr *newBuffers = realloc(pPriv->buffers,
292+ sizeof(pPriv->buffers[0]) * n);
293+ if (!newBuffers) {
294+ xf86DrvMsg(pDraw->pScreen->myNum, X_ERROR,
295+ "[DRI2] %s: allocation failed for buffer: %d\n",
296+ __func__, attachment);
297+ goto err_out;
298+ }
299+ pPriv->buffers = newBuffers;
300+ memset(&pPriv->buffers[pPriv->bufferCount], 0,
301+ (n - pPriv->bufferCount) * sizeof(pPriv->buffers[0]));
302+ pPriv->bufferCount = n;
303+ }
304+
305+ /* destroy any previous buffer at this attachment slot */
306+ if (pPriv->buffers[attachment]) {
307+ (*ds->DestroyBuffer)(pDraw, pPriv->buffers[attachment]);
308+ pPriv->buffers[attachment] = NULL;
309+ }
310+
311+ if ((width == 0) && (height == 0)) {
312+ /* client just wanted us to delete the buffer */
313+ continue;
314+ }
315+
316+ if (!valid_format(ds, format)) {
317+ xf86DrvMsg(pDraw->pScreen->myNum, X_ERROR,
318+ "[DRI2] %s: bad format: %d\n", __func__, format);
319+ goto err_out;
320+ }
321+
322+ if (attachment == DRI2BufferFrontLeft) {
323+ buf = (*ds->CreateBuffer)(pDraw, attachment, format);
324+ /* note: don't expose front buffer to client */
325+ } else {
326+ buf = (*ds->CreateBufferVid)(pDraw, attachment, format, width, height);
327+ buffers[n++] = buf;
328+ }
329+
330+ if (! buf) {
331+ goto err_out;
332+ }
333+
334+ pPriv->buffers[attachment] = buf;
335+ }
336+
337+ *out_count = n;
338+
339+ return buffers;
340+
341+err_out:
342+
343+ *out_count = 0;
344+
345+ for (i = 0; i < n; i++)
346+ if (buffers[i])
347+ pPriv->buffers[buffers[i]->attachment] = NULL;
348+
349+ destroy_buffers(pDraw, buffers, n);
350+
351+ return NULL;
352+}
353+
354 static void
355 DRI2InvalidateDrawable(DrawablePtr pDraw)
356 {
357@@ -549,7 +700,7 @@
358 pPriv->needInvalidate = FALSE;
359
360 list_for_each_entry(ref, &pPriv->reference_list, link)
361- ref->invalidate(pDraw, ref->priv);
362+ ref->invalidate(pDraw, ref->priv, ref->id);
363 }
364
365 /*
366@@ -609,22 +760,14 @@
367 {
368 DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
369 DRI2DrawablePtr pPriv;
370- DRI2BufferPtr pDestBuffer, pSrcBuffer;
371- int i;
372+ DRI2BufferPtr pDestBuffer = NULL, pSrcBuffer = NULL;
373
374 pPriv = DRI2GetDrawable(pDraw);
375 if (pPriv == NULL)
376 return BadDrawable;
377
378- pDestBuffer = NULL;
379- pSrcBuffer = NULL;
380- for (i = 0; i < pPriv->bufferCount; i++)
381- {
382- if (pPriv->buffers[i]->attachment == dest)
383- pDestBuffer = (DRI2BufferPtr) pPriv->buffers[i];
384- if (pPriv->buffers[i]->attachment == src)
385- pSrcBuffer = (DRI2BufferPtr) pPriv->buffers[i];
386- }
387+ find_attachment(pPriv, dest, &pDestBuffer);
388+ find_attachment(pPriv, src, &pSrcBuffer);
389 if (pSrcBuffer == NULL || pDestBuffer == NULL)
390 return BadValue;
391
392@@ -792,31 +935,41 @@
393 return FALSE;
394 }
395
396-int
397-DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
398- CARD64 divisor, CARD64 remainder, CARD64 *swap_target,
399- DRI2SwapEventPtr func, void *data)
400+/*
401+ * A TraverseTree callback to invalidate all windows using the same
402+ * pixmap
403+ */
404+static int
405+DRI2InvalidateWalk(WindowPtr pWin, pointer data)
406+{
407+ if (pWin->drawable.pScreen->GetWindowPixmap(pWin) != data)
408+ return WT_DONTWALKCHILDREN;
409+ DRI2InvalidateDrawable(&pWin->drawable);
410+ return WT_WALKCHILDREN;
411+}
412+
413+static int
414+swap_buffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
415+ CARD64 divisor, CARD64 remainder, CARD64 *swap_target,
416+ DRI2SwapEventPtr func, void *data,
417+ Bool vid, unsigned int source, BoxPtr b)
418 {
419 ScreenPtr pScreen = pDraw->pScreen;
420 DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
421- DRI2DrawablePtr pPriv;
422+ DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw);
423 DRI2BufferPtr pDestBuffer = NULL, pSrcBuffer = NULL;
424- int ret, i;
425+ int ret;
426 CARD64 ust, current_msc;
427
428- pPriv = DRI2GetDrawable(pDraw);
429- if (pPriv == NULL) {
430+ if ((pPriv == NULL) || (vid && !supports_video(ds))) {
431 xf86DrvMsg(pScreen->myNum, X_ERROR,
432 "[DRI2] %s: bad drawable\n", __func__);
433 return BadDrawable;
434 }
435
436- for (i = 0; i < pPriv->bufferCount; i++) {
437- if (pPriv->buffers[i]->attachment == DRI2BufferFrontLeft)
438- pDestBuffer = (DRI2BufferPtr) pPriv->buffers[i];
439- if (pPriv->buffers[i]->attachment == DRI2BufferBackLeft)
440- pSrcBuffer = (DRI2BufferPtr) pPriv->buffers[i];
441- }
442+ find_attachment(pPriv, DRI2BufferFrontLeft, &pDestBuffer);
443+ find_attachment(pPriv, source, &pSrcBuffer);
444+
445 if (pSrcBuffer == NULL || pDestBuffer == NULL) {
446 xf86DrvMsg(pScreen->myNum, X_ERROR,
447 "[DRI2] %s: drawable has no back or front?\n", __func__);
448@@ -824,7 +977,7 @@
449 }
450
451 /* Old DDX or no swap interval, just blit */
452- if (!ds->ScheduleSwap || !pPriv->swap_interval) {
453+ if ((!ds->ScheduleSwap || !pPriv->swap_interval) && !vid) {
454 BoxRec box;
455 RegionRec region;
456
457@@ -860,7 +1013,6 @@
458
459 if (current_msc < pPriv->last_swap_target)
460 pPriv->last_swap_target = current_msc;
461-
462 }
463
464 /*
465@@ -876,8 +1028,14 @@
466 }
467
468 pPriv->swapsPending++;
469- ret = (*ds->ScheduleSwap)(client, pDraw, pDestBuffer, pSrcBuffer,
470- swap_target, divisor, remainder, func, data);
471+ if (vid) {
472+ DrawablePtr osd = NULL; // TODO
473+ ret = (*ds->ScheduleSwapVid)(client, pDraw, pDestBuffer, pSrcBuffer,
474+ b, osd, swap_target, divisor, remainder, func, data);
475+ } else {
476+ ret = (*ds->ScheduleSwap)(client, pDraw, pDestBuffer, pSrcBuffer,
477+ swap_target, divisor, remainder, func, data);
478+ }
479 if (!ret) {
480 pPriv->swapsPending--; /* didn't schedule */
481 xf86DrvMsg(pScreen->myNum, X_ERROR,
482@@ -892,11 +1050,50 @@
483 */
484 *swap_target = pPriv->swap_count + pPriv->swapsPending;
485
486+ if (vid) {
487+ return Success;
488+ }
489+
490+ if (pDraw->type == DRAWABLE_WINDOW) {
491+ WindowPtr pWin = (WindowPtr) pDraw;
492+ PixmapPtr pPixmap = pScreen->GetWindowPixmap(pWin);
493+
494+ /*
495+ * Find the top-most window using this pixmap
496+ */
497+ while (pWin->parent && pScreen->GetWindowPixmap(pWin->parent) == pPixmap)
498+ pWin = pWin->parent;
499+
500+ /*
501+ * Walk the sub-tree to invalidate all of the
502+ * windows using the same pixmap
503+ */
504+ TraverseTree(pWin, DRI2InvalidateWalk, pPixmap);
505+ DRI2InvalidateDrawable(&pPixmap->drawable);
506+ } else
507 DRI2InvalidateDrawable(pDraw);
508
509 return Success;
510 }
511
512+int
513+DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
514+ CARD64 divisor, CARD64 remainder, CARD64 *swap_target,
515+ DRI2SwapEventPtr func, void *data)
516+{
517+ return swap_buffers(client, pDraw, target_msc, divisor, remainder,
518+ swap_target, func, data, FALSE, DRI2BufferBackLeft, NULL);
519+}
520+
521+int
522+DRI2SwapBuffersVid(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
523+ CARD64 divisor, CARD64 remainder, CARD64 *swap_target,
524+ unsigned int source, BoxPtr b, DRI2SwapEventPtr func, void *data)
525+{
526+ return swap_buffers(client, pDraw, target_msc, divisor, remainder,
527+ swap_target, func, data, TRUE, source, b);
528+}
529+
530 void
531 DRI2SwapInterval(DrawablePtr pDrawable, int interval)
532 {
533@@ -1014,6 +1211,77 @@
534 return ds->ScheduleSwap && ds->GetMSC;
535 }
536
537+#define ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
538+
539+/* length in multiple of CARD32's, passed in value should be copied by
540+ * receiver
541+ */
542+int
543+DRI2SetAttribute(DrawablePtr pDraw, Atom attribute, int len, const CARD32 *val)
544+{
545+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
546+ int ret = BadMatch;
547+
548+ if (!supports_video(ds)) {
549+ return BadDrawable;
550+ }
551+
552+ if (attribute == ATOM("XV_OSD")) {
553+ } else if (ds->SetAttribute) {
554+ ret = (*ds->SetAttribute)(pDraw, attribute, len, val);
555+ }
556+
557+ return ret;
558+}
559+
560+/* length in multiple of CARD32's, returned val should *not* be free'd
561+ * (unlike similar function on client side) to avoid temporary allocation
562+ * and extra copy.
563+ */
564+int
565+DRI2GetAttribute(DrawablePtr pDraw, Atom attribute, int *len, const CARD32 **val)
566+{
567+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
568+ int ret = BadMatch;
569+
570+ if (!supports_video(ds)) {
571+ return BadDrawable;
572+ }
573+
574+ if (attribute == ATOM("XV_OSD")) {
575+ } else if (ds->GetAttribute) {
576+ ret = (*ds->GetAttribute)(pDraw, attribute, len, val);
577+ }
578+
579+ return ret;
580+}
581+
582+int
583+DRI2GetFormats(ScreenPtr pScreen, unsigned int *nformats, unsigned int **formats)
584+{
585+ DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
586+
587+ if (! supports_video(ds)) {
588+ return BadDrawable;
589+ }
590+
591+ *nformats = ds->numFormats;
592+ *formats = ds->formats;
593+
594+ return Success;
595+}
596+
597+unsigned int
598+DRI2GetExtraBufferNames(DrawablePtr pDraw, DRI2BufferPtr buf,
599+ unsigned int **names, unsigned int **pitches)
600+{
601+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
602+ if (ds->GetExtraBufferNames) {
603+ return (*ds->GetExtraBufferNames)(pDraw, buf, names, pitches);
604+ }
605+ return 0;
606+}
607+
608 Bool
609 DRI2Connect(ScreenPtr pScreen, unsigned int driverType, int *fd,
610 const char **driverName, const char **deviceName)
611@@ -1081,9 +1349,10 @@
612 const char* driverTypeNames[] = {
613 "DRI", /* DRI2DriverDRI */
614 "VDPAU", /* DRI2DriverVDPAU */
615+ "XV", /* DRI2DriverXV */
616 };
617 unsigned int i;
618- CARD8 cur_minor;
619+ CARD8 cur_minor = 1;
620
621 if (info->version < 3)
622 return FALSE;
623@@ -1121,14 +1390,45 @@
624 ds->ScheduleWaitMSC = info->ScheduleWaitMSC;
625 ds->GetMSC = info->GetMSC;
626 cur_minor = 3;
627- } else {
628- cur_minor = 1;
629 }
630
631 if (info->version >= 5) {
632 ds->AuthMagic = info->AuthMagic;
633 }
634
635+ if (info->version >= 6) {
636+ ds->ReuseBufferNotify = info->ReuseBufferNotify;
637+ ds->SwapLimitValidate = info->SwapLimitValidate;
638+ }
639+
640+ if (info->version >= 7) {
641+ if ((info->numDrivers > DRI2DriverXV) &&
642+ info->driverNames[DRI2DriverXV]) {
643+ /* if driver claims to support DRI2DriverXV, then ensure
644+ * it provides the required fxn ptrs:
645+ */
646+ if (!info->CreateBufferVid || !info->ScheduleSwapVid) {
647+ xf86DrvMsg(pScreen->myNum, X_WARNING,
648+ "[DRI2] DRI2DriverXV must implement "
649+ "CreateBuffersVid and ScheduleSwapVid.\n");
650+ goto err_out;
651+ }
652+ }
653+ ds->numFormats = info->numFormats;
654+ ds->formats = malloc(info->numFormats * sizeof(*ds->formats));
655+ if (!ds->formats)
656+ goto err_out;
657+ memcpy(ds->formats, info->formats,
658+ info->numFormats * sizeof(*ds->formats));
659+ ds->GetExtraBufferNames = info->GetExtraBufferNames;
660+ ds->CreateBufferVid = info->CreateBufferVid;
661+ ds->ScheduleSwapVid = info->ScheduleSwapVid;
662+ ds->SetAttribute = info->SetAttribute;
663+ ds->GetAttribute = info->GetAttribute;
664+
665+ cur_minor = 4;
666+ }
667+
668 /*
669 * if the driver doesn't provide an AuthMagic function or the info struct
670 * version is too low, it relies on the old method (using libdrm) or fail
671@@ -1178,6 +1478,10 @@
672 err_out:
673 xf86DrvMsg(pScreen->myNum, X_WARNING,
674 "[DRI2] Initialization failed for info version %d.\n", info->version);
675+ if (ds) {
676+ free(ds->formats);
677+ free(ds->driverNames);
678+ }
679 free(ds);
680 return FALSE;
681 }
682Index: xserver/hw/xfree86/dri2/dri2.h
683===================================================================
684--- xserver.orig/hw/xfree86/dri2/dri2.h 2012-02-22 11:04:26.000000000 +0100
685+++ xserver/hw/xfree86/dri2/dri2.h 2012-02-22 16:31:43.000000000 +0100
686@@ -104,12 +104,73 @@
687 CARD64 remainder,
688 DRI2SwapEventPtr func,
689 void *data);
690+
691+/**
692+ * Schedule a video buffer swap
693+ *
694+ * Drivers should queue an event for the frame count that satisfies the
695+ * parameters passed in. If the event is in the future (i.e. the conditions
696+ * aren't currently satisfied), the server may block the client at the next
697+ * GLX request using DRI2WaitSwap. When the event arrives, drivers should call
698+ * \c DRI2SwapComplete, which will handle waking the client and returning
699+ * the appropriate data.
700+ *
701+ * The DDX is responsible for doing an overlay buffer flip/exchange, or
702+ * scaling/colorconvert blit when the corresponding event arrives.
703+ *
704+ * If the target drawable is resized/damaged, or the osd pixmap is changed/
705+ * damaged, ScheduleSwapVid can be re-invoked by the core with the same
706+ * source buffer to repair the dri2 video drawable.
707+ * XXX TODO this part isn't implemented in core yet..
708+ *
709+ * \param client client pointer (used for block/unblock)
710+ * \param pDraw drawable whose count we want
711+ * \param pDestBuffer current front buffer
712+ * \param pSrcBuffer current back buffer
713+ * \param b the crop box
714+ * \param osd the on-screen-display overlay pixmap, should be an ARGB pixmap
715+ * that is blended on top of the video as part of swap. Multiple layers
716+ * to blend over the video should be flattened into a single layer by the
717+ * client
718+ * \param target_msc frame count to wait for
719+ * \param divisor divisor for condition equation
720+ * \param remainder remainder for division equation
721+ * \param func function to call when the swap completes
722+ * \param data data for the callback \p func.
723+ */
724+typedef int (*DRI2ScheduleSwapVidProcPtr)(ClientPtr client,
725+ DrawablePtr pDraw,
726+ DRI2BufferPtr pDestBuffer,
727+ DRI2BufferPtr pSrcBuffer,
728+ BoxPtr b,
729+ DrawablePtr osd,
730+ CARD64 *target_msc,
731+ CARD64 divisor,
732+ CARD64 remainder,
733+ DRI2SwapEventPtr func,
734+ void *data);
735+
736 typedef DRI2BufferPtr (*DRI2CreateBufferProcPtr)(DrawablePtr pDraw,
737 unsigned int attachment,
738 unsigned int format);
739+typedef DRI2BufferPtr (*DRI2CreateBufferVidProcPtr)(DrawablePtr pDraw,
740+ unsigned int attachment,
741+ unsigned int format,
742+ unsigned int width,
743+ unsigned int height);
744 typedef void (*DRI2DestroyBufferProcPtr)(DrawablePtr pDraw,
745 DRI2BufferPtr buffer);
746 /**
747+ * Notifies driver when DRI2GetBuffers reuses a dri2 buffer.
748+ *
749+ * Driver may rename the dri2 buffer in this notify if it is required.
750+ *
751+ * \param pDraw drawable whose count we want
752+ * \param buffer buffer that will be returned to client
753+ */
754+typedef void (*DRI2ReuseBufferNotifyProcPtr)(DrawablePtr pDraw,
755+ DRI2BufferPtr buffer);
756+/**
757 * Get current media stamp counter values
758 *
759 * This callback is used to support the SGI_video_sync and OML_sync_control
760@@ -156,12 +217,62 @@
761 CARD64 remainder);
762
763 typedef void (*DRI2InvalidateProcPtr)(DrawablePtr pDraw,
764- void *data);
765+ void *data,
766+ XID id);
767+
768+/**
769+ * DRI2 calls this hook when ever swap_limit is going to be changed. Default
770+ * implementation for the hook only accepts one as swap_limit. If driver can
771+ * support other swap_limits it has to implement supported limits with this
772+ * callback.
773+ *
774+ * \param pDraw drawable whos swap_limit is going to be changed
775+ * \param swap_limit new swap_limit that going to be set
776+ * \return TRUE if limit is support, FALSE if not.
777+ */
778+typedef Bool (*DRI2SwapLimitValidateProcPtr)(DrawablePtr pDraw,
779+ int swap_limit);
780+
781+
782+/**
783+ * An ugly approach to avoid changing DRI2BufferPtr and cause ABI breakage
784+ * between driver and xserver. This only needs to be implemented by drivers
785+ * supporting planar formats with one buffer per plane.
786+ *
787+ * This might be a good argument for having drivers in-tree ;-)
788+ *
789+ * \param pDraw drawable that the buffer belongs to
790+ * \param buf the DRI2 buffer
791+ * \param names array of buffer names
792+ * \param pitches array of buffer pitches
793+ * \return the number of additional buffers, ie. for I420 tri-planar buffer,
794+ * if represented as multiple buffer names, the Y buffer name would be in
795+ * buf->name, this function would return 2, and return the U and V buffer
796+ * names by reference.
797+ */
798+typedef unsigned int (*DRI2GetExtraBufferNamesProcPtr)(DrawablePtr pDraw,
799+ DRI2BufferPtr buf, unsigned int **names, unsigned int **pitches);
800+
801+/**
802+ * Length in multiple of CARD32's, passed in value should be copied by
803+ * receiver
804+ */
805+typedef int (*DRI2SetAttributeProcPtr)(DrawablePtr pDraw, Atom attribute,
806+ int len, const CARD32 *val);
807+
808+/**
809+ * Length in multiple of CARD32's, returned val should *not* be free'd
810+ * (unlike similar function on client side) to avoid temporary allocation
811+ * and extra copy.
812+ */
813+typedef int (*DRI2GetAttributeProcPtr)(DrawablePtr pDraw, Atom attribute,
814+ int *len, const CARD32 **val);
815+
816
817 /**
818 * Version of the DRI2InfoRec structure defined in this header
819 */
820-#define DRI2INFOREC_VERSION 5
821+#define DRI2INFOREC_VERSION 7
822
823 typedef struct {
824 unsigned int version; /**< Version of this struct */
825@@ -189,6 +300,20 @@
826 /* added in version 5 */
827
828 DRI2AuthMagicProcPtr AuthMagic;
829+ /* added in version 6 */
830+
831+ DRI2ReuseBufferNotifyProcPtr ReuseBufferNotify;
832+ DRI2SwapLimitValidateProcPtr SwapLimitValidate;
833+
834+ /* added in version 7 */
835+
836+ unsigned int numFormats;
837+ const unsigned int *formats;
838+ DRI2GetExtraBufferNamesProcPtr GetExtraBufferNames;
839+ DRI2CreateBufferVidProcPtr CreateBufferVid;
840+ DRI2ScheduleSwapVidProcPtr ScheduleSwapVid;
841+ DRI2SetAttributeProcPtr SetAttribute;
842+ DRI2GetAttributeProcPtr GetAttribute;
843 } DRI2InfoRec, *DRI2InfoPtr;
844
845 extern _X_EXPORT int DRI2EventBase;
846@@ -250,11 +375,19 @@
847 int *width, int *height, unsigned int *attachments, int count,
848 int *out_count);
849
850+extern _X_EXPORT DRI2BufferPtr * DRI2GetBuffersVid(DrawablePtr pDraw,
851+ int width, int height, unsigned int *attachments, int count,
852+ int *out_count);
853+
854 extern _X_EXPORT void DRI2SwapInterval(DrawablePtr pDrawable, int interval);
855+extern _X_EXPORT Bool DRI2SwapLimit(DrawablePtr pDraw, int swap_limit);
856 extern _X_EXPORT int DRI2SwapBuffers(ClientPtr client, DrawablePtr pDrawable,
857 CARD64 target_msc, CARD64 divisor,
858 CARD64 remainder, CARD64 *swap_target,
859 DRI2SwapEventPtr func, void *data);
860+extern _X_EXPORT int DRI2SwapBuffersVid(ClientPtr client, DrawablePtr pDraw,
861+ CARD64 target_msc, CARD64 divisor, CARD64 remainder, CARD64 *swap_target,
862+ unsigned int source, BoxPtr b, DRI2SwapEventPtr func, void *data);
863 extern _X_EXPORT Bool DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable);
864
865 extern _X_EXPORT int DRI2GetMSC(DrawablePtr pDrawable, CARD64 *ust,
866@@ -284,4 +417,22 @@
867 int frame, unsigned int tv_sec,
868 unsigned int tv_usec);
869
870+extern _X_EXPORT int DRI2SetAttribute(DrawablePtr pDraw, Atom attribute,
871+ int len, const CARD32 *val);
872+extern _X_EXPORT int DRI2GetAttribute(DrawablePtr pDraw, Atom attribute,
873+ int *len, const CARD32 **val);
874+extern _X_EXPORT int DRI2GetFormats(ScreenPtr pScreen,
875+ unsigned int *nformats, unsigned int **formats);
876+
877+extern _X_EXPORT unsigned int DRI2GetExtraBufferNames(DrawablePtr pDraw,
878+ DRI2BufferPtr buf, unsigned int **names, unsigned int **pitches);
879+
880+
881+/* some utility macros.. maybe could go elsewhere? */
882+#define FOURCC(a, b, c, d) (((uint32_t)(uint8_t)(a) | ((uint32_t)(uint8_t)(b) << 8) | ((uint32_t)(uint8_t)(c) << 16) | ((uint32_t)(uint8_t)(d) << 24 )))
883+#define FOURCC_STR(str) FOURCC(str[0], str[1], str[2], str[3])
884+#ifndef ARRAY_SIZE
885+# define ARRAY_SIZE(_a) (sizeof((_a)) / sizeof((_a)[0]))
886+#endif
887+
888 #endif
889Index: xserver/hw/xfree86/dri2/dri2ext.c
890===================================================================
891--- xserver.orig/hw/xfree86/dri2/dri2ext.c 2012-02-22 11:04:26.000000000 +0100
892+++ xserver/hw/xfree86/dri2/dri2ext.c 2012-02-22 16:37:21.000000000 +0100
893@@ -78,6 +78,7 @@
894 swaps(&stuff->length, n);
895
896 REQUEST_SIZE_MATCH(xDRI2QueryVersionReq);
897+
898 rep.type = X_Reply;
899 rep.length = 0;
900 rep.sequenceNumber = client->sequence;
901@@ -157,7 +158,7 @@
902 }
903
904 static void
905-DRI2InvalidateBuffersEvent(DrawablePtr pDraw, void *priv)
906+DRI2InvalidateBuffersEvent(DrawablePtr pDraw, void *priv, XID id)
907 {
908 xDRI2InvalidateBuffers event;
909 ClientPtr client = priv;
910@@ -206,12 +207,13 @@
911
912
913 static int
914-send_buffers_reply(ClientPtr client, DrawablePtr pDrawable,
915+send_buffers_reply(ClientPtr client, DrawablePtr pDrawable, int vid,
916 DRI2BufferPtr *buffers, int count, int width, int height)
917 {
918 xDRI2GetBuffersReply rep;
919- int skip = 0;
920- int i;
921+ int skip = 0, extra = 0;
922+ unsigned int *names, *pitches;
923+ int i, j;
924
925 if (buffers == NULL)
926 return BadAlloc;
927@@ -227,8 +229,24 @@
928 }
929 }
930
931+ if (vid) {
932+ extra = 4 * (count - skip);
933+
934+ for (i = 0; i < count; i++) {
935+ /* Do not send the real front buffer of a window to the client.
936+ */
937+ if ((pDrawable->type == DRAWABLE_WINDOW)
938+ && (buffers[i]->attachment == DRI2BufferFrontLeft)) {
939+ continue;
940+ }
941+
942+ extra += 8 * DRI2GetExtraBufferNames(pDrawable, buffers[i],
943+ &names, &pitches);
944+ }
945+ }
946+
947 rep.type = X_Reply;
948- rep.length = (count - skip) * sizeof(xDRI2Buffer) / 4;
949+ rep.length = ((count - skip) * sizeof(xDRI2Buffer) + extra) / 4;
950 rep.sequenceNumber = client->sequence;
951 rep.width = width;
952 rep.height = height;
953@@ -251,6 +269,17 @@
954 buffer.cpp = buffers[i]->cpp;
955 buffer.flags = buffers[i]->flags;
956 WriteToClient(client, sizeof(xDRI2Buffer), &buffer);
957+
958+ if (vid) {
959+ CARD32 n = DRI2GetExtraBufferNames(pDrawable, buffers[i],
960+ &names, &pitches);
961+ WriteToClient(client, sizeof(n), &n);
962+ for (j = 0; j < n; j++) {
963+ CARD32 name = names[j], pitch = pitches[j];
964+ WriteToClient(client, sizeof(name), &name);
965+ WriteToClient(client, sizeof(pitch), &pitch);
966+ }
967+ }
968 }
969 return Success;
970 }
971@@ -278,8 +307,8 @@
972 attachments, stuff->count, &count);
973
974
975- return send_buffers_reply(client, pDrawable, buffers, count, width, height);
976-
977+ return send_buffers_reply(client, pDrawable, FALSE,
978+ buffers, count, width, height);
979 }
980
981 static int
982@@ -303,7 +332,40 @@
983 buffers = DRI2GetBuffersWithFormat(pDrawable, &width, &height,
984 attachments, stuff->count, &count);
985
986- return send_buffers_reply(client, pDrawable, buffers, count, width, height);
987+ return send_buffers_reply(client, pDrawable, FALSE,
988+ buffers, count, width, height);
989+}
990+
991+static int
992+ProcDRI2GetBuffersVid(ClientPtr client)
993+{
994+ REQUEST(xDRI2GetBuffersVidReq);
995+ DrawablePtr pDrawable;
996+ DRI2BufferPtr *buffers;
997+ int status, count;
998+ unsigned int *attachments;
999+
1000+ REQUEST_FIXED_SIZE(xDRI2GetBuffersVidReq, stuff->count * (2 * 4));
1001+ if (!validDrawable(client, stuff->drawable, DixReadAccess | DixWriteAccess,
1002+ &pDrawable, &status))
1003+ return status;
1004+
1005+ if (DRI2ThrottleClient(client, pDrawable))
1006+ return Success;
1007+
1008+ attachments = (unsigned int *) &stuff[1];
1009+ buffers = DRI2GetBuffersVid(pDrawable, stuff->width, stuff->height,
1010+ attachments, stuff->count, &count);
1011+
1012+ status = send_buffers_reply(client, pDrawable, TRUE, buffers, count, 0, 0);
1013+
1014+ /* note, unlike other DRI2GetBuffers variants, we allow requesting/
1015+ * returning just a subset of buffers.. so array that is returned is
1016+ * not the one held in pPriv, so must be free'd
1017+ */
1018+ free(buffers);
1019+
1020+ return status;
1021 }
1022
1023 static int
1024@@ -416,6 +478,53 @@
1025 return Success;
1026 }
1027
1028+static int
1029+ProcDRI2SwapBuffersVid(ClientPtr client)
1030+{
1031+ REQUEST(xDRI2SwapBuffersVidReq);
1032+ xDRI2SwapBuffersReply rep;
1033+ DrawablePtr pDrawable;
1034+ CARD64 target_msc, divisor, remainder, swap_target;
1035+ BoxRec b;
1036+ int status;
1037+
1038+ REQUEST_SIZE_MATCH(xDRI2SwapBuffersVidReq);
1039+
1040+ if (!validDrawable(client, stuff->drawable,
1041+ DixReadAccess | DixWriteAccess, &pDrawable, &status))
1042+ return status;
1043+
1044+ /*
1045+ * Ensures an out of control client can't exhaust our swap queue, and
1046+ * also orders swaps.
1047+ */
1048+ if (DRI2ThrottleClient(client, pDrawable))
1049+ return Success;
1050+
1051+ target_msc = vals_to_card64(stuff->target_msc_lo, stuff->target_msc_hi);
1052+ divisor = vals_to_card64(stuff->divisor_lo, stuff->divisor_hi);
1053+ remainder = vals_to_card64(stuff->remainder_lo, stuff->remainder_hi);
1054+
1055+ b.x1 = stuff->x1;
1056+ b.y1 = stuff->y1;
1057+ b.x2 = stuff->x2;
1058+ b.y2 = stuff->y2;
1059+
1060+ status = DRI2SwapBuffersVid(client, pDrawable, target_msc, divisor, remainder,
1061+ &swap_target, stuff->source, &b, DRI2SwapEvent, pDrawable);
1062+ if (status != Success)
1063+ return BadDrawable;
1064+
1065+ rep.type = X_Reply;
1066+ rep.length = 0;
1067+ rep.sequenceNumber = client->sequence;
1068+ load_swap_reply(&rep, swap_target);
1069+
1070+ WriteToClient(client, sizeof(xDRI2SwapBuffersReply), &rep);
1071+
1072+ return Success;
1073+}
1074+
1075 static void
1076 load_msc_reply(xDRI2MSCReply *rep, CARD64 ust, CARD64 msc, CARD64 sbc)
1077 {
1078@@ -539,6 +648,87 @@
1079 }
1080
1081 static int
1082+ProcDRI2SetAttribute(ClientPtr client)
1083+{
1084+ REQUEST(xDRI2SetAttributeReq);
1085+ DrawablePtr pDrawable;
1086+ int status;
1087+ int len = (stuff->length * 4 - sizeof(xDRI2SetAttributeReq)) / 4;
1088+
1089+ REQUEST_FIXED_SIZE(xDRI2SetAttributeReq, len * 4);
1090+
1091+ if (!validDrawable(client, stuff->drawable,
1092+ DixReadAccess | DixWriteAccess, &pDrawable, &status))
1093+ return status;
1094+
1095+ status = DRI2SetAttribute(pDrawable, stuff->attribute, len,
1096+ (const CARD32 *)&stuff[1]);
1097+ if (status != Success)
1098+ return status;
1099+
1100+ return Success;
1101+}
1102+
1103+static int
1104+ProcDRI2GetAttribute(ClientPtr client)
1105+{
1106+ REQUEST(xDRI2GetAttributeReq);
1107+ xDRI2GetAttributeReply rep;
1108+ DrawablePtr pDrawable;
1109+ const CARD32 *val;
1110+ int status, len;
1111+
1112+ REQUEST_SIZE_MATCH(xDRI2GetAttributeReq);
1113+
1114+ if (!validDrawable(client, stuff->drawable, DixReadAccess, &pDrawable,
1115+ &status))
1116+ return status;
1117+
1118+ status = DRI2GetAttribute(pDrawable, stuff->attribute, &len, &val);
1119+ if (status != Success)
1120+ return status;
1121+
1122+ rep.type = X_Reply;
1123+ rep.length = len;
1124+ rep.sequenceNumber = client->sequence;
1125+ WriteToClient(client, sizeof(xDRI2GetAttributeReply), &rep);
1126+ WriteToClient(client, len * 4, val);
1127+
1128+ return Success;
1129+}
1130+
1131+static int
1132+ProcDRI2GetFormats(ClientPtr client)
1133+{
1134+ REQUEST(xDRI2GetFormatsReq);
1135+ xDRI2GetFormatsReply rep;
1136+ DrawablePtr pDrawable;
1137+ unsigned int i, nformats, *formats;
1138+ int status;
1139+
1140+ REQUEST_SIZE_MATCH(xDRI2GetFormatsReq);
1141+
1142+ if (!validDrawable(client, stuff->drawable, DixReadAccess, &pDrawable,
1143+ &status))
1144+ return status;
1145+
1146+ status = DRI2GetFormats(pDrawable->pScreen, &nformats, &formats);
1147+ if (status != Success)
1148+ return status;
1149+
1150+ rep.type = X_Reply;
1151+ rep.length = nformats * sizeof(*formats) / 4;
1152+ rep.sequenceNumber = client->sequence;
1153+ WriteToClient(client, sizeof(xDRI2GetFormatsReply), &rep);
1154+
1155+ for (i = 0; i < nformats; i++) {
1156+ WriteToClient(client, sizeof(formats[i]), &formats[i]);
1157+ }
1158+
1159+ return Success;
1160+}
1161+
1162+static int
1163 ProcDRI2Dispatch (ClientPtr client)
1164 {
1165 REQUEST(xReq);
1166@@ -576,6 +766,16 @@
1167 return ProcDRI2WaitSBC(client);
1168 case X_DRI2SwapInterval:
1169 return ProcDRI2SwapInterval(client);
1170+ case X_DRI2GetBuffersVid:
1171+ return ProcDRI2GetBuffersVid(client);
1172+ case X_DRI2SwapBuffersVid:
1173+ return ProcDRI2SwapBuffersVid(client);
1174+ case X_DRI2SetAttribute:
1175+ return ProcDRI2SetAttribute(client);
1176+ case X_DRI2GetAttribute:
1177+ return ProcDRI2GetAttribute(client);
1178+ case X_DRI2GetFormats:
1179+ return ProcDRI2GetFormats(client);
1180 default:
1181 return BadRequest;
1182 }
diff --git a/debian/patches/001_fedora_extramodes.patch b/debian/patches/001_fedora_extramodes.patch
deleted file mode 100644
index 77005b2..0000000
--- a/debian/patches/001_fedora_extramodes.patch
+++ /dev/null
@@ -1,83 +0,0 @@
1From: Adam Jackson <ajax@redhat.com>
2Date: Sun, 28 Oct 2007 09:37:52 +0100
3Subject: [PATCH] Fedora extra modes list
4
5---
6--- a/hw/xfree86/common/extramodes
7+++ b/hw/xfree86/common/extramodes
8@@ -3,16 +3,75 @@
9 //
10 // $XFree86: xc/programs/Xserver/hw/xfree86/etc/extramodes,v 1.5 2002/06/05 19:43:05 dawes Exp $
11 //
12+// NOTE: Please keep all video modes sorted in order of X res, then Y res for
13+// ease of maintenance and readability.
14
15 # 832x624 @ 75Hz (74.55Hz) (fix if the official/Apple spec is different) hsync: 49.725kHz
16 ModeLine "832x624" 57.284 832 864 928 1152 624 625 628 667 -Hsync -Vsync
17
18+# 1152x864 @ 60.00 Hz (GTF) hsync: 53.70 kHz; pclk: 81.62 MHz
19+Modeline "1152x864" 81.62 1152 1216 1336 1520 864 865 868 895 -HSync +Vsync
20+
21+# 1152x864 @ 70.00 Hz (GTF) hsync: 63.00 kHz; pclk: 96.77 MHz
22+Modeline "1152x864" 96.77 1152 1224 1344 1536 864 865 868 900 -HSync +Vsync
23+
24+# 1152x864 @ 75.00 Hz (GTF) hsync: 67.65 kHz; pclk: 104.99 MHz
25+Modeline "1152x864" 104.99 1152 1224 1352 1552 864 865 868 902 -HSync +Vsync
26+
27+# 1152x864 @ 85.00 Hz (GTF) hsync: 77.10 kHz; pclk: 119.65 MHz
28+Modeline "1152x864" 119.65 1152 1224 1352 1552 864 865 868 907 -HSync +Vsync
29+
30+# 1152x864 @ 85Hz (Red Hat custom modeline)
31+ModeLine "1152x864" 121.5 1152 1216 1344 1568 864 865 868 911 +hsync -vsync
32+
33+# 1152x864 @ 100.00 Hz (GTF) hsync: 91.50 kHz; pclk: 143.47 MHz
34+Modeline "1152x864" 143.47 1152 1232 1360 1568 864 865 868 915 -HSync +Vsync
35+
36+# 1360x768 59.96 Hz (CVT) hsync: 47.37 kHz; pclk: 72.00 MHz
37+Modeline "1360x768" 72.00 1360 1408 1440 1520 768 771 781 790 +hsync -vsync
38+
39+# 1360x768 59.80 Hz (CVT) hsync: 47.72 kHz; pclk: 84.75 MHz
40+Modeline "1360x768" 84.75 1360 1432 1568 1776 768 771 781 798 -hsync +vsync
41+
42 # 1400x1050 @ 60Hz (VESA GTF) hsync: 65.5kHz
43 ModeLine "1400x1050" 122.0 1400 1488 1640 1880 1050 1052 1064 1082 +hsync +vsync
44
45+# 1400x1050 @ 70.00 Hz (GTF) hsync: 76.51 kHz; pclk: 145.06 MHz
46+Modeline "1400x1050" 145.06 1400 1496 1648 1896 1050 1051 1054 1093 -HSync +Vsync
47+
48 # 1400x1050 @ 75Hz (VESA GTF) hsync: 82.2kHz
49 ModeLine "1400x1050" 155.8 1400 1464 1784 1912 1050 1052 1064 1090 +hsync +vsync
50
51+# 1400x1050 @ 85.00 Hz (GTF) hsync: 93.76 kHz; pclk: 179.26 MHz
52+Modeline "1400x1050" 179.26 1400 1504 1656 1912 1050 1051 1054 1103 -HSync +Vsync
53+
54+# 1440x900 @ 60.00 Hz (CVT) field rate 59.89 Hz; hsync: 55.93 kHz; pclk: 106.50 MHz
55+Modeline "1440x900" 106.50 1440 1520 1672 1904 900 903 909 934 -HSync +Vsync
56+
57+# 1600x1024 for SGI 1600 SW
58+ModeLine "1600x1024" 103.125 1600 1600 1656 1664 1024 1024 1029 1030 +Hsync +Vsync
59+
60+# 1680x1050 59.88 Hz (CVT 1.76MA-R) hsync: 64.67 kHz; pclk: 119.00 MHz
61+Modeline "1680x1050" 119.00 1680 1728 1760 1840 1050 1053 1059 1080 +hsync -vsync
62+
63+# 1680x1050 59.95 Hz (CVT 1.76MA) hsync: 65.29 kHz; pclk: 146.25 MHz
64+Modeline "1680x1050" 146.25 1680 1784 1960 2240 1050 1053 1059 1089 -hsync +vsync
65+
66+# 1680x1050 69.88 Hz (CVT) hsync: 76.58 kHz; pclk: 174.00 MHz
67+Modeline "1680x1050" 174.00 1680 1800 1976 2272 1050 1053 1059 1096 -hsync +vsync
68+
69+# 1680x1050 74.89 Hz (CVT 1.76MA) hsync: 82.31 kHz; pclk: 187.00 MHz
70+Modeline "1680x1050" 187.00 1680 1800 1976 2272 1050 1053 1059 1099 -hsync +vsync
71+
72+# 1680x1050 84.94 Hz (CVT 1.76MA) hsync: 93.86 kHz; pclk: 214.75 MHz
73+Modeline "1680x1050" 214.75 1680 1808 1984 2288 1050 1053 1059 1105 -hsync +vsync
74+
75+# 1920x1080 59.93 Hz (CVT 2.07M9-R) hsync: 66.59 kHz; pclk: 138.50 MHz
76+Modeline "1920x1080" 138.50 1920 1968 2000 2080 1080 1083 1088 1111 +hsync -vsync
77+
78+# 1920x1200 59.95 Hz (CVT 2.30MA-R) hsync: 74.04 kHz; pclk: 154.00 MHz
79+Modeline "1920x1200" 154.00 1920 1968 2000 2080 1200 1203 1209 1235 +hsync -vsync
80+
81 # 1920x1440 @ 85Hz (VESA GTF) hsync: 128.5kHz
82 Modeline "1920x1440" 341.35 1920 2072 2288 2656 1440 1441 1444 1512 -hsync +vsync
83
diff --git a/debian/patches/02_Add-libnettle-as-option-for-sha1.diff b/debian/patches/02_Add-libnettle-as-option-for-sha1.diff
deleted file mode 100644
index bb0c338..0000000
--- a/debian/patches/02_Add-libnettle-as-option-for-sha1.diff
+++ /dev/null
@@ -1,90 +0,0 @@
1From a6119f6cd7e47041044fcc9c15a6e3f9f189b3ed Mon Sep 17 00:00:00 2001
2From: Cyril Brulebois <kibi@debian.org>
3Date: Sun, 14 Mar 2010 22:01:47 +0100
4Subject: [PATCH] Add libnettle as option for sha1.
5
6Signed-off-by: Cyril Brulebois <kibi@debian.org>
7
8[jcristau: forward-ported from 1.7 to 1.8]
9Signed-off-by: Julien Cristau <jcristau@debian.org>
10---
11Index: xorg-server/configure.ac
12===================================================================
13--- xorg-server.orig/configure.ac
14+++ xorg-server/configure.ac
15@@ -1315,7 +1315,7 @@ CORE_INCS='-I$(top_srcdir)/include -I$(t
16
17 # SHA1 hashing
18 AC_ARG_WITH([sha1],
19- [AS_HELP_STRING([--with-sha1=libc|libmd|libgcrypt|libcrypto|libsha1|CommonCrypto],
20+ [AS_HELP_STRING([--with-sha1=libc|libmd|libgcrypt|libcrypto|libsha1|CommonCrypto|nettle],
21 [choose SHA1 implementation])])
22 AC_CHECK_FUNC([SHA1Init], [HAVE_SHA1_IN_LIBC=yes])
23 if test "x$with_sha1" = x && test "x$HAVE_SHA1_IN_LIBC" = xyes; then
24@@ -1398,6 +1398,16 @@ if test "x$with_sha1" = xlibcrypto; then
25 SHA1_CFLAGS="$OPENSSL_CFLAGS"
26 fi
27 fi
28+AC_CHECK_LIB([nettle], [nettle_sha1_init], [HAVE_LIBNETTLE=yes])
29+if test "x$with_sha1" = x && test "x$HAVE_LIBNETTLE" = xyes; then
30+ with_sha1=nettle
31+fi
32+if test "x$with_sha1" = xnettle; then
33+ AC_DEFINE([HAVE_SHA1_IN_LIBNETTLE], [1],
34+ [Use libnettle SHA1 functions])
35+ # XXX hack for d-i: use the static lib
36+ SHA1_LIBS=-l:libnettle.a
37+fi
38 AC_MSG_CHECKING([for SHA1 implementation])
39 if test "x$with_sha1" = x; then
40 AC_MSG_ERROR([No suitable SHA1 implementation found])
41Index: xorg-server/include/dix-config.h.in
42===================================================================
43--- xorg-server.orig/include/dix-config.h.in
44+++ xorg-server/include/dix-config.h.in
45@@ -175,6 +175,9 @@
46 /* Define to use libsha1 for SHA1 */
47 #undef HAVE_SHA1_IN_LIBSHA1
48
49+/* Define to use libnettle SHA1 */
50+#undef HAVE_SHA1_IN_LIBNETTLE
51+
52 /* Define to 1 if you have the `shmctl64' function. */
53 #undef HAVE_SHMCTL64
54
55Index: xorg-server/os/xsha1.c
56===================================================================
57--- xorg-server.orig/os/xsha1.c
58+++ xorg-server/os/xsha1.c
59@@ -127,6 +127,31 @@ int x_sha1_final(void *ctx, unsigned cha
60 return 1;
61 }
62
63+#elif defined(HAVE_SHA1_IN_LIBNETTLE)
64+
65+# include <nettle/sha.h>
66+
67+void *x_sha1_init(void)
68+{
69+ struct sha1_ctx *ctx = xalloc(sizeof(*ctx));
70+ if (!ctx)
71+ return NULL;
72+ sha1_init(ctx);
73+ return ctx;
74+}
75+
76+int x_sha1_update(void *ctx, void *data, int size)
77+{
78+ sha1_update(ctx, size, data);
79+ return 1;
80+}
81+
82+int x_sha1_final(void *ctx, unsigned char result[20])
83+{
84+ sha1_digest(ctx, 20, result);
85+ return 1;
86+}
87+
88 #else /* Use OpenSSL's libcrypto */
89
90 # include <stddef.h> /* buggy openssl/sha.h wants size_t */
diff --git a/debian/patches/07-xfree86-fix-build-with-xv-disabled.diff b/debian/patches/07-xfree86-fix-build-with-xv-disabled.diff
deleted file mode 100644
index 1bd6b70..0000000
--- a/debian/patches/07-xfree86-fix-build-with-xv-disabled.diff
+++ /dev/null
@@ -1,50 +0,0 @@
1From fe7575e929d65e8c798104ec2f72b879051694d3 Mon Sep 17 00:00:00 2001
2From: Julien Cristau <jcristau@debian.org>
3Date: Mon, 8 Feb 2010 02:04:33 +0100
4Subject: [PATCH] xfree86: fix build with xv disabled
5
6---
7 hw/xfree86/modes/xf86Crtc.c | 2 ++
8 hw/xfree86/modes/xf86Crtc.h | 2 ++
9 2 files changed, 4 insertions(+), 0 deletions(-)
10
11Index: xorg-server/hw/xfree86/modes/xf86Crtc.c
12===================================================================
13--- xorg-server.orig/hw/xfree86/modes/xf86Crtc.c
14+++ xorg-server/hw/xfree86/modes/xf86Crtc.c
15@@ -3089,6 +3089,7 @@ xf86_crtc_box_area(BoxPtr box)
16 return (int) (box->x2 - box->x1) * (int) (box->y2 - box->y1);
17 }
18
19+#ifdef XV
20 /*
21 * Return the crtc covering 'box'. If two crtcs cover a portion of
22 * 'box', then prefer 'desired'. If 'desired' is NULL, then prefer the crtc
23@@ -3177,6 +3178,7 @@ xf86_crtc_clip_video_helper(ScrnInfoPtr
24
25 return ret;
26 }
27+#endif
28
29 xf86_crtc_notify_proc_ptr
30 xf86_wrap_crtc_notify (ScreenPtr screen, xf86_crtc_notify_proc_ptr new)
31Index: xorg-server/hw/xfree86/modes/xf86Crtc.h
32===================================================================
33--- xorg-server.orig/hw/xfree86/modes/xf86Crtc.h
34+++ xorg-server/hw/xfree86/modes/xf86Crtc.h
35@@ -934,6 +934,7 @@ xf86_hide_cursors (ScrnInfoPtr scrn);
36 extern _X_EXPORT void
37 xf86_cursors_fini (ScreenPtr screen);
38
39+#ifdef XV
40 /*
41 * For overlay video, compute the relevant CRTC and
42 * clip video to that.
43@@ -952,6 +953,7 @@ xf86_crtc_clip_video_helper(ScrnInfoPtr
44 RegionPtr reg,
45 INT32 width,
46 INT32 height);
47+#endif
48
49 extern _X_EXPORT xf86_crtc_notify_proc_ptr
50 xf86_wrap_crtc_notify (ScreenPtr pScreen, xf86_crtc_notify_proc_ptr new);
diff --git a/debian/patches/1001-xfree86-modes-Let-the-driver-handle-the-transform.patch b/debian/patches/1001-xfree86-modes-Let-the-driver-handle-the-transform.patch
deleted file mode 100644
index 3f3fb6d..0000000
--- a/debian/patches/1001-xfree86-modes-Let-the-driver-handle-the-transform.patch
+++ /dev/null
@@ -1,333 +0,0 @@
1From 245cb8e94fd15990e1b7d6622added460f104dba Mon Sep 17 00:00:00 2001
2From: Aaron Plattner <aplattner@nvidia.com>
3Date: Thu, 25 Aug 2011 10:19:48 -0700
4Subject: [PATCH 1/2] xfree86/modes: Let the driver handle the transform
5
6If a driver can use hardware to handle the crtc transform, then
7there's no need for the server's shadow layer to do it. Add a crtc
8flag that lets the driver indicate that it is handling the transform.
9If it's set, consider the transformed size of the screen but don't
10actually enable the shadow layer. Also stop adjusting the cursor
11image and position.
12
13Signed-off-by: Aaron Plattner <aplattner@nvidia.com>
14---
15 hw/xfree86/modes/xf86Crtc.h | 16 +++++-
16 hw/xfree86/modes/xf86Cursors.c | 31 +++++++---
17 hw/xfree86/modes/xf86Rotate.c | 131 +++++++++++++++++++++-------------------
18 3 files changed, 107 insertions(+), 71 deletions(-)
19
20diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
21index 68a968c..0d7a6a6 100644
22--- a/hw/xfree86/modes/xf86Crtc.h
23+++ b/hw/xfree86/modes/xf86Crtc.h
24@@ -1,5 +1,6 @@
25 /*
26 * Copyright © 2006 Keith Packard
27+ * Copyright © 2011 Aaron Plattner
28 *
29 * Permission to use, copy, modify, distribute, and sell this software and its
30 * documentation for any purpose is hereby granted without fee, provided that
31@@ -223,7 +224,7 @@ typedef struct _xf86CrtcFuncs {
32
33 } xf86CrtcFuncsRec, *xf86CrtcFuncsPtr;
34
35-#define XF86_CRTC_VERSION 3
36+#define XF86_CRTC_VERSION 4
37
38 struct _xf86Crtc {
39 /**
40@@ -361,6 +362,19 @@ struct _xf86Crtc {
41 * Clear the shadow
42 */
43 Bool shadowClear;
44+
45+ /**
46+ * Indicates that the driver is handling the transform, so the shadow
47+ * surface should be disabled. The driver writes this field before calling
48+ * xf86CrtcRotate to indicate that it is handling the transform (including
49+ * rotation and reflection).
50+ *
51+ * Setting this flag also causes the server to stop adjusting the cursor
52+ * image and position.
53+ *
54+ * Added in ABI version 4
55+ */
56+ Bool driverIsPerformingTransform;
57 };
58
59 typedef struct _xf86OutputFuncs {
60diff --git a/hw/xfree86/modes/xf86Cursors.c b/hw/xfree86/modes/xf86Cursors.c
61index 23c48eb..02dea5c 100644
62--- a/hw/xfree86/modes/xf86Cursors.c
63+++ b/hw/xfree86/modes/xf86Cursors.c
64@@ -1,6 +1,6 @@
65 /*
66 * Copyright © 2007 Keith Packard
67- * Copyright © 2010 Aaron Plattner
68+ * Copyright © 2010-2011 Aaron Plattner
69 *
70 * Permission to use, copy, modify, distribute, and sell this software and its
71 * documentation for any purpose is hereby granted without fee, provided that
72@@ -47,6 +47,18 @@
73 #include "inputstr.h"
74
75 /*
76+ * Returns the rotation being performed by the server. If the driver indicates
77+ * that it's handling the screen transform, then this returns RR_Rotate_0.
78+ */
79+static Rotation
80+xf86_crtc_cursor_rotation (xf86CrtcPtr crtc)
81+{
82+ if (crtc->driverIsPerformingTransform)
83+ return RR_Rotate_0;
84+ return crtc->rotation;
85+}
86+
87+/*
88 * Given a screen coordinate, rotate back to a cursor source coordinate
89 */
90 static void
91@@ -214,6 +226,7 @@ xf86_crtc_convert_cursor_to_argb (xf86CrtcPtr crtc, unsigned char *src)
92 int xin, yin;
93 int flags = cursor_info->Flags;
94 CARD32 bits;
95+ const Rotation rotation = xf86_crtc_cursor_rotation(crtc);
96
97 #ifdef ARGB_CURSOR
98 crtc->cursor_argb = FALSE;
99@@ -222,7 +235,7 @@ xf86_crtc_convert_cursor_to_argb (xf86CrtcPtr crtc, unsigned char *src)
100 for (y = 0; y < cursor_info->MaxHeight; y++)
101 for (x = 0; x < cursor_info->MaxWidth; x++)
102 {
103- xf86_crtc_rotate_coord (crtc->rotation,
104+ xf86_crtc_rotate_coord (rotation,
105 cursor_info->MaxWidth,
106 cursor_info->MaxHeight,
107 x, y, &xin, &yin);
108@@ -338,7 +351,7 @@ xf86_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
109 /*
110 * Transform position of cursor on screen
111 */
112- if (crtc->transform_in_use)
113+ if (crtc->transform_in_use && !crtc->driverIsPerformingTransform)
114 {
115 ScreenPtr screen = scrn->pScreen;
116 xf86CursorScreenPtr ScreenPriv =
117@@ -420,12 +433,13 @@ xf86_crtc_load_cursor_image (xf86CrtcPtr crtc, CARD8 *src)
118 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
119 xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
120 CARD8 *cursor_image;
121+ const Rotation rotation = xf86_crtc_cursor_rotation(crtc);
122
123 #ifdef ARGB_CURSOR
124 crtc->cursor_argb = FALSE;
125 #endif
126
127- if (crtc->rotation == RR_Rotate_0)
128+ if (rotation == RR_Rotate_0)
129 cursor_image = src;
130 else
131 {
132@@ -439,7 +453,7 @@ xf86_crtc_load_cursor_image (xf86CrtcPtr crtc, CARD8 *src)
133 for (y = 0; y < cursor_info->MaxHeight; y++)
134 for (x = 0; x < cursor_info->MaxWidth; x++)
135 {
136- xf86_crtc_rotate_coord (crtc->rotation,
137+ xf86_crtc_rotate_coord (rotation,
138 cursor_info->MaxWidth,
139 cursor_info->MaxHeight,
140 x, y, &xin, &yin);
141@@ -532,12 +546,13 @@ xf86_crtc_load_cursor_argb (xf86CrtcPtr crtc, CursorPtr cursor)
142 int source_height = cursor->bits->height;
143 int image_width = cursor_info->MaxWidth;
144 int image_height = cursor_info->MaxHeight;
145-
146+ const Rotation rotation = xf86_crtc_cursor_rotation(crtc);
147+
148 for (y = 0; y < image_height; y++)
149 for (x = 0; x < image_width; x++)
150 {
151- xf86_crtc_rotate_coord (crtc->rotation, image_width, image_height,
152- x, y, &xin, &yin);
153+ xf86_crtc_rotate_coord (rotation, image_width, image_height, x, y,
154+ &xin, &yin);
155 if (xin < source_width && yin < source_height)
156 bits = cursor_source[yin * source_width + xin];
157 else
158diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c
159index 57c3499..45aabf0 100644
160--- a/hw/xfree86/modes/xf86Rotate.c
161+++ b/hw/xfree86/modes/xf86Rotate.c
162@@ -1,5 +1,6 @@
163 /*
164 * Copyright © 2006 Keith Packard
165+ * Copyright © 2011 Aaron Plattner
166 *
167 * Permission to use, copy, modify, distribute, and sell this software and its
168 * documentation for any purpose is hereby granted without fee, provided that
169@@ -84,7 +85,10 @@ xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region)
170 int n = RegionNumRects(region);
171 BoxPtr b = RegionRects(region);
172 XID include_inferiors = IncludeInferiors;
173-
174+
175+ if (crtc->driverIsPerformingTransform)
176+ return;
177+
178 src = CreatePicture (None,
179 &root->drawable,
180 format,
181@@ -290,7 +294,7 @@ xf86RotateDestroy (xf86CrtcPtr crtc)
182 }
183
184 for (c = 0; c < xf86_config->num_crtc; c++)
185- if (xf86_config->crtc[c]->transform_in_use)
186+ if (xf86_config->crtc[c]->rotatedData)
187 return;
188
189 /*
190@@ -414,52 +418,73 @@ xf86CrtcRotate (xf86CrtcPtr crtc)
191 }
192 else
193 {
194- /*
195- * these are the size of the shadow pixmap, which
196- * matches the mode, not the pre-rotated copy in the
197- * frame buffer
198- */
199- int width = crtc->mode.HDisplay;
200- int height = crtc->mode.VDisplay;
201- void *shadowData = crtc->rotatedData;
202- PixmapPtr shadow = crtc->rotatedPixmap;
203- int old_width = shadow ? shadow->drawable.width : 0;
204- int old_height = shadow ? shadow->drawable.height : 0;
205-
206- /* Allocate memory for rotation */
207- if (old_width != width || old_height != height)
208- {
209- if (shadow || shadowData)
210+ if (crtc->driverIsPerformingTransform) {
211+ xf86RotateDestroy(crtc);
212+ } else {
213+ /*
214+ * these are the size of the shadow pixmap, which
215+ * matches the mode, not the pre-rotated copy in the
216+ * frame buffer
217+ */
218+ int width = crtc->mode.HDisplay;
219+ int height = crtc->mode.VDisplay;
220+ void *shadowData = crtc->rotatedData;
221+ PixmapPtr shadow = crtc->rotatedPixmap;
222+ int old_width = shadow ? shadow->drawable.width : 0;
223+ int old_height = shadow ? shadow->drawable.height : 0;
224+
225+ /* Allocate memory for rotation */
226+ if (old_width != width || old_height != height)
227 {
228- crtc->funcs->shadow_destroy (crtc, shadow, shadowData);
229- crtc->rotatedPixmap = NULL;
230- crtc->rotatedData = NULL;
231+ if (shadow || shadowData)
232+ {
233+ crtc->funcs->shadow_destroy (crtc, shadow, shadowData);
234+ crtc->rotatedPixmap = NULL;
235+ crtc->rotatedData = NULL;
236+ }
237+ shadowData = crtc->funcs->shadow_allocate (crtc, width, height);
238+ if (!shadowData)
239+ goto bail1;
240+ crtc->rotatedData = shadowData;
241+ /* shadow will be damaged in xf86RotatePrepare */
242+ }
243+ else
244+ {
245+ /* mark shadowed area as damaged so it will be repainted */
246+ damage = TRUE;
247 }
248- shadowData = crtc->funcs->shadow_allocate (crtc, width, height);
249- if (!shadowData)
250- goto bail1;
251- crtc->rotatedData = shadowData;
252- /* shadow will be damaged in xf86RotatePrepare */
253- }
254- else
255- {
256- /* mark shadowed area as damaged so it will be repainted */
257- damage = TRUE;
258- }
259
260- if (!xf86_config->rotation_damage)
261- {
262- /* Create damage structure */
263- xf86_config->rotation_damage = DamageCreate (NULL, NULL,
264- DamageReportNone,
265- TRUE, pScreen, pScreen);
266 if (!xf86_config->rotation_damage)
267- goto bail2;
268-
269- /* Wrap block handler */
270- if (!xf86_config->BlockHandler) {
271- xf86_config->BlockHandler = pScreen->BlockHandler;
272- pScreen->BlockHandler = xf86RotateBlockHandler;
273+ {
274+ /* Create damage structure */
275+ xf86_config->rotation_damage = DamageCreate (NULL, NULL,
276+ DamageReportNone,
277+ TRUE, pScreen, pScreen);
278+ if (!xf86_config->rotation_damage)
279+ goto bail2;
280+
281+ /* Wrap block handler */
282+ if (!xf86_config->BlockHandler) {
283+ xf86_config->BlockHandler = pScreen->BlockHandler;
284+ pScreen->BlockHandler = xf86RotateBlockHandler;
285+ }
286+ }
287+
288+ if (0)
289+ {
290+ bail2:
291+ if (shadow || shadowData)
292+ {
293+ crtc->funcs->shadow_destroy (crtc, shadow, shadowData);
294+ crtc->rotatedPixmap = NULL;
295+ crtc->rotatedData = NULL;
296+ }
297+ bail1:
298+ if (old_width && old_height)
299+ crtc->rotatedPixmap =
300+ crtc->funcs->shadow_create (crtc, NULL, old_width,
301+ old_height);
302+ return FALSE;
303 }
304 }
305 #ifdef RANDR_12_INTERFACE
306@@ -482,24 +507,6 @@ xf86CrtcRotate (xf86CrtcPtr crtc)
307 }
308 }
309 #endif
310-
311- if (0)
312- {
313- bail2:
314- if (shadow || shadowData)
315- {
316- crtc->funcs->shadow_destroy (crtc, shadow, shadowData);
317- crtc->rotatedPixmap = NULL;
318- crtc->rotatedData = NULL;
319- }
320- bail1:
321- if (old_width && old_height)
322- crtc->rotatedPixmap = crtc->funcs->shadow_create (crtc,
323- NULL,
324- old_width,
325- old_height);
326- return FALSE;
327- }
328 crtc->transform_in_use = TRUE;
329 }
330 crtc->crtc_to_framebuffer = crtc_to_fb;
331--
3321.7.4.1
333
diff --git a/debian/patches/1002-xfree86-modes-Make-cursor-position-transform-a-helpe.patch b/debian/patches/1002-xfree86-modes-Make-cursor-position-transform-a-helpe.patch
deleted file mode 100644
index bbb3d07..0000000
--- a/debian/patches/1002-xfree86-modes-Make-cursor-position-transform-a-helpe.patch
+++ /dev/null
@@ -1,117 +0,0 @@
1From 57cd32e93425597317b4b7722859155419836e4c Mon Sep 17 00:00:00 2001
2From: Aaron Plattner <aplattner@nvidia.com>
3Date: Thu, 25 Aug 2011 15:41:55 -0700
4Subject: [PATCH 2/2] xfree86/modes: Make cursor position transform a helper function
5
6When the driver can handle the crtc transform in hardware, it sets
7crtc->driverIsPerformingTransform, which turns off both the shadow
8layer and the cursor's position-transforming code. However, some
9drivers actually do require the cursor position to still be
10transformed in these cases. Move the cursor position transform into a
11helper function that can be called by such drivers.
12
13Signed-off-by: Aaron Plattner <aplattner@nvidia.com>
14---
15 hw/xfree86/modes/xf86Crtc.h | 8 +++++
16 hw/xfree86/modes/xf86Cursors.c | 57 +++++++++++++++++++++------------------
17 2 files changed, 39 insertions(+), 26 deletions(-)
18
19Index: xserver/hw/xfree86/modes/xf86Crtc.h
20===================================================================
21--- xserver.orig/hw/xfree86/modes/xf86Crtc.h 2012-03-21 16:16:55.085740513 +0100
22+++ xserver/hw/xfree86/modes/xf86Crtc.h 2012-03-21 16:16:55.121740513 +0100
23@@ -903,6 +903,14 @@
24 extern _X_EXPORT char *
25 xf86ConnectorGetName(xf86ConnectorType connector);
26
27+/**
28+ * Transform the cursor's coordinates based on the crtc transform. Normally
29+ * this is done by the server, but if crtc->driverIsPerformingTransform is TRUE,
30+ * then the server does not transform the cursor position automatically.
31+ */
32+extern _X_EXPORT void
33+xf86CrtcTransformCursorPos (xf86CrtcPtr crtc, int *x, int *y);
34+
35 /*
36 * Using the desired mode information in each crtc, set
37 * modes (used in EnterVT functions, or at server startup)
38Index: xserver/hw/xfree86/modes/xf86Cursors.c
39===================================================================
40--- xserver.orig/hw/xfree86/modes/xf86Cursors.c 2012-03-21 16:16:55.089740513 +0100
41+++ xserver/hw/xfree86/modes/xf86Cursors.c 2012-03-21 16:16:55.121740513 +0100
42@@ -337,7 +337,36 @@
43 xf86_crtc_show_cursor (crtc);
44 }
45 }
46-
47+
48+void xf86CrtcTransformCursorPos (xf86CrtcPtr crtc, int *x, int *y)
49+{
50+ ScrnInfoPtr scrn = crtc->scrn;
51+ ScreenPtr screen = scrn->pScreen;
52+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
53+ xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
54+ xf86CursorScreenPtr ScreenPriv =
55+ (xf86CursorScreenPtr)dixLookupPrivate(&screen->devPrivates,
56+ xf86CursorScreenKey);
57+ struct pict_f_vector v;
58+ int dx, dy;
59+
60+ v.v[0] = (*x + ScreenPriv->HotX) + 0.5;
61+ v.v[1] = (*y + ScreenPriv->HotY) + 0.5;
62+ v.v[2] = 1;
63+ pixman_f_transform_point (&crtc->f_framebuffer_to_crtc, &v);
64+ /* cursor will have 0.5 added to it already so floor is sufficent */
65+ *x = floor (v.v[0]);
66+ *y = floor (v.v[1]);
67+ /*
68+ * Transform position of cursor upper left corner
69+ */
70+ xf86_crtc_rotate_coord_back (crtc->rotation, cursor_info->MaxWidth,
71+ cursor_info->MaxHeight, ScreenPriv->HotX,
72+ ScreenPriv->HotY, &dx, &dy);
73+ *x -= dx;
74+ *y -= dy;
75+}
76+
77 static void
78 xf86_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
79 {
80@@ -346,36 +375,12 @@
81 xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
82 DisplayModePtr mode = &crtc->mode;
83 Bool in_range;
84- int dx, dy;
85
86 /*
87 * Transform position of cursor on screen
88 */
89 if (crtc->transform_in_use && !crtc->driverIsPerformingTransform)
90- {
91- ScreenPtr screen = scrn->pScreen;
92- xf86CursorScreenPtr ScreenPriv =
93- (xf86CursorScreenPtr)dixLookupPrivate(&screen->devPrivates,
94- xf86CursorScreenKey);
95- struct pict_f_vector v;
96-
97- v.v[0] = (x + ScreenPriv->HotX) + 0.5;
98- v.v[1] = (y + ScreenPriv->HotY) + 0.5;
99- v.v[2] = 1;
100- pixman_f_transform_point (&crtc->f_framebuffer_to_crtc, &v);
101- /* cursor will have 0.5 added to it already so floor is sufficent */
102- x = floor (v.v[0]);
103- y = floor (v.v[1]);
104- /*
105- * Transform position of cursor upper left corner
106- */
107- xf86_crtc_rotate_coord_back (crtc->rotation,
108- cursor_info->MaxWidth,
109- cursor_info->MaxHeight,
110- ScreenPriv->HotX, ScreenPriv->HotY, &dx, &dy);
111- x -= dx;
112- y -= dy;
113- }
114+ xf86CrtcTransformCursorPos(crtc, &x, &y);
115 else
116 {
117 x -= crtc->x;
diff --git a/debian/patches/100_rethrow_signals.patch b/debian/patches/100_rethrow_signals.patch
deleted file mode 100644
index ffbc4b0..0000000
--- a/debian/patches/100_rethrow_signals.patch
+++ /dev/null
@@ -1,375 +0,0 @@
1Index: xorg-server/hw/dmx/dmxinit.c
2===================================================================
3--- xorg-server.orig/hw/dmx/dmxinit.c 2011-09-10 21:40:27.000000000 -0700
4+++ xorg-server/hw/dmx/dmxinit.c 2011-09-10 21:45:50.066123727 -0700
5@@ -821,7 +821,7 @@
6 /** This function is called in Xserver/os/utils.c from \a AbortServer().
7 * We must ensure that backend and console state is restored in the
8 * event the server shutdown wasn't clean. */
9-void AbortDDX(enum ExitCode error)
10+void SigAbortDDX(int signo, enum ExitCode error)
11 {
12 int i;
13
14@@ -839,6 +839,11 @@
15 }
16 #endif
17
18+void AbortDDX(enum ExitCode error)
19+{
20+ SigAbortDDX(0, error);
21+}
22+
23 /** This function is called in Xserver/dix/main.c from \a main() when
24 * dispatchException & DE_TERMINATE (which is the only way to exit the
25 * main loop without an interruption. */
26Index: xorg-server/hw/kdrive/src/kdrive.c
27===================================================================
28--- xorg-server.orig/hw/kdrive/src/kdrive.c 2011-09-10 21:40:27.000000000 -0700
29+++ xorg-server/hw/kdrive/src/kdrive.c 2011-09-10 21:52:09.393274790 -0700
30@@ -232,7 +232,7 @@
31 }
32
33 void
34-AbortDDX(enum ExitCode error)
35+SigAbortDDX(int signo, enum ExitCode error)
36 {
37 KdDisableScreens ();
38 if (kdOsFuncs)
39@@ -248,6 +248,11 @@
40 OsAbort();
41 }
42
43+AbortDDX(enum ExitCode error)
44+{
45+ SigAbortDDX(0, error);
46+}
47+
48 void
49 ddxGiveUp (enum ExitCode error)
50 {
51Index: xorg-server/hw/vfb/InitOutput.c
52===================================================================
53--- xorg-server.orig/hw/vfb/InitOutput.c 2011-09-10 21:40:27.000000000 -0700
54+++ xorg-server/hw/vfb/InitOutput.c 2011-09-10 21:53:51.404181875 -0700
55@@ -201,11 +201,17 @@
56 }
57
58 void
59-AbortDDX(enum ExitCode error)
60+SigAbortDDX(int signo, enum ExitCode error)
61 {
62 ddxGiveUp(error);
63 }
64-
65+
66+void
67+AbortDDX(enum ExitCode error)
68+{
69+ SigAbortDDX(0, error);
70+}
71+
72 #ifdef __APPLE__
73 void
74 DarwinHandleGUI(int argc, char *argv[])
75Index: xorg-server/hw/xfree86/common/xf86Events.c
76===================================================================
77--- xorg-server.orig/hw/xfree86/common/xf86Events.c 2011-09-10 21:40:27.000000000 -0700
78+++ xorg-server/hw/xfree86/common/xf86Events.c 2011-09-10 21:45:50.066123727 -0700
79@@ -348,6 +348,8 @@
80 int
81 xf86SigWrapper(int signo)
82 {
83+ static Bool beenhere = FALSE;
84+
85 if ((signo == SIGILL) && xf86SigIllHandler) {
86 (*xf86SigIllHandler)();
87 return 0; /* continue */
88Index: xorg-server/hw/xfree86/common/xf86Init.c
89===================================================================
90--- xorg-server.orig/hw/xfree86/common/xf86Init.c 2011-09-10 21:40:27.000000000 -0700
91+++ xorg-server/hw/xfree86/common/xf86Init.c 2011-09-11 09:58:17.741645191 -0700
92@@ -895,14 +895,17 @@
93 }
94
95 /*
96- * ddxGiveUp --
97+ * ddxSigGiveUp --
98 * Device dependent cleanup. Called by by dix before normal server death.
99 * For SYSV386 we must switch the terminal back to normal mode. No error-
100 * checking here, since there should be restored as much as possible.
101+ *
102+ * If a non-zero signo is passed, re-raise that signal rather than
103+ * calling abort().
104 */
105
106 void
107-ddxGiveUp(enum ExitCode error)
108+ddxSigGiveUp(int signo, enum ExitCode error)
109 {
110 int i;
111
112@@ -929,24 +932,46 @@
113 if (xorgHWOpenConsole)
114 xf86CloseConsole();
115
116+ ErrorF (" ddxSigGiveUp: Closing log\n");
117+
118 xf86CloseLog(error);
119
120 /* If an unexpected signal was caught, dump a core for debugging */
121- if (xf86Info.caughtSignal)
122- OsAbort();
123+ if (xf86Info.caughtSignal) {
124+ if (signo != 0) {
125+ raise(signo);
126+ } else {
127+ OsAbort();
128+ }
129+ }
130 }
131
132+/*
133+ * ddxGiveUp --
134+ * Device dependent cleanup. Called by by dix before normal server death.
135+ * For SYSV386 we must switch the terminal back to normal mode. No error-
136+ * checking here, since there should be restored as much as possible.
137+ */
138+
139+void
140+ddxGiveUp(enum ExitCode error)
141+{
142+ ddxSigGiveUp(0, error);
143+}
144
145
146 /*
147- * AbortDDX --
148+ * SigAbortDDX --
149 * DDX - specific abort routine. Called by AbortServer(). The attempt is
150 * made to restore all original setting of the displays. Also all devices
151 * are closed.
152+ *
153+ * If a non-zero signo is passed, re-raise that signal rather than calling
154+ * abort()
155 */
156
157 void
158-AbortDDX(enum ExitCode error)
159+SigAbortDDX(int signo, enum ExitCode error)
160 {
161 int i;
162
163@@ -979,7 +1004,20 @@
164 * This is needed for an abnormal server exit, since the normal exit stuff
165 * MUST also be performed (i.e. the vt must be left in a defined state)
166 */
167- ddxGiveUp(error);
168+ ddxSigGiveUp(signo, error);
169+}
170+
171+/*
172+ * AbortDDX --
173+ * DDX - specific abort routine. The attempt is made to restore
174+ * all original setting of the displays. Also all devices are
175+ * closed.
176+ */
177+
178+void
179+AbortDDX(enum ExitCode error)
180+{
181+ SigAbortDDX(0, error);
182 }
183
184 void
185Index: xorg-server/hw/xnest/Init.c
186===================================================================
187--- xorg-server.orig/hw/xnest/Init.c 2011-09-10 21:40:27.000000000 -0700
188+++ xorg-server/hw/xnest/Init.c 2011-09-10 21:45:50.076124422 -0700
189@@ -114,12 +114,17 @@
190 /*
191 * DDX - specific abort routine. Called by AbortServer().
192 */
193-void AbortDDX(enum ExitCode error)
194+void SigAbortDDX(int signo, enum ExitCode error)
195 {
196 xnestDoFullGeneration = True;
197 xnestCloseDisplay();
198 }
199
200+void AbortDDX(enum ExitCode error)
201+{
202+ SigAbortDDX(0, error);
203+}
204+
205 /* Called by GiveUp(). */
206 void ddxGiveUp(enum ExitCode error)
207 {
208Index: xorg-server/hw/xquartz/darwin.c
209===================================================================
210--- xorg-server.orig/hw/xquartz/darwin.c 2011-09-10 21:40:27.000000000 -0700
211+++ xorg-server/hw/xquartz/darwin.c 2011-09-10 22:01:07.976518255 -0700
212@@ -773,14 +773,20 @@
213
214
215 /*
216- * AbortDDX --
217+ * [Sig]AbortDDX --
218 * DDX - specific abort routine. Called by AbortServer(). The attempt is
219 * made to restore all original setting of the displays. Also all devices
220 * are closed.
221 */
222 _X_NORETURN
223-void AbortDDX( enum ExitCode error ) {
224+void SigAbortDDX( int signo, enum ExitCode error )
225+{
226 ErrorF( " AbortDDX\n" );
227 OsAbort();
228 }
229
230+_X_NORETURN
231+void AbortDDX( enum ExitCode error )
232+{
233+ SigAbortDDX(signo, error);
234+}
235Index: xorg-server/hw/xwin/InitOutput.c
236===================================================================
237--- xorg-server.orig/hw/xwin/InitOutput.c 2011-09-10 21:40:27.000000000 -0700
238+++ xorg-server/hw/xwin/InitOutput.c 2011-09-10 22:02:02.515804736 -0700
239@@ -258,7 +258,7 @@
240
241 /* See Porting Layer Definition - p. 57 */
242 void
243-AbortDDX (enum ExitCode error)
244+SigAbortDDX (int signo, enum ExitCode error)
245 {
246 #if CYGDEBUG
247 winDebug ("AbortDDX\n");
248@@ -266,6 +266,12 @@
249 ddxGiveUp (error);
250 }
251
252+void
253+AbortDDX (enum ExitCode error)
254+{
255+ SigAbortDDX(0, error);
256+}
257+
258 #ifdef __CYGWIN__
259 /* hasmntopt is currently not implemented for cygwin */
260 static const char *winCheckMntOpt(const struct mntent *mnt, const char *opt)
261Index: xorg-server/include/os.h
262===================================================================
263--- xorg-server.orig/include/os.h 2011-09-10 21:40:27.000000000 -0700
264+++ xorg-server/include/os.h 2011-09-11 09:51:52.766866712 -0700
265@@ -466,7 +466,9 @@
266 EXIT_ERR_DRIVERS = 3,
267 };
268
269+extern _X_EXPORT void SigAbortDDX(int signo, enum ExitCode error);
270 extern _X_EXPORT void AbortDDX(enum ExitCode error);
271+extern _X_EXPORT void ddxSigGiveUp(int signo, enum ExitCode error);
272 extern _X_EXPORT void ddxGiveUp(enum ExitCode error);
273 extern _X_EXPORT int TimeSinceLastInputEvent(void);
274
275Index: xorg-server/os/log.c
276===================================================================
277--- xorg-server.orig/os/log.c 2011-09-10 21:40:27.000000000 -0700
278+++ xorg-server/os/log.c 2011-09-11 09:51:21.555668560 -0700
279@@ -89,6 +89,8 @@
280 #include <stdlib.h> /* for malloc() */
281 #include <errno.h>
282
283+#include <signal.h> /* for raise() */
284+
285 #include "input.h"
286 #include "site.h"
287 #include "opaque.h"
288@@ -403,9 +405,11 @@
289
290 void
291 AbortServer(void) _X_NORETURN;
292+void
293+SigAbortServer(int signo) _X_NORETURN;
294
295 void
296-AbortServer(void)
297+SigAbortServer(int signo)
298 {
299 #ifdef XF86BIGFONT
300 XF86BigfontCleanup();
301@@ -413,11 +417,22 @@
302 CloseWellKnownConnections();
303 OsCleanup(TRUE);
304 CloseDownDevices();
305- AbortDDX(EXIT_ERR_ABORT);
306+ SigAbortDDX(signo, EXIT_ERR_ABORT);
307 fflush(stderr);
308- if (CoreDump)
309- OsAbort();
310- exit (1);
311+ if (CoreDump) {
312+ if (signo != 0)
313+ raise(signo);
314+ else
315+ OsAbort();
316+ } else {
317+ exit (1);
318+ }
319+}
320+
321+void
322+AbortServer()
323+{
324+ SigAbortServer(0);
325 }
326
327 #define AUDIT_PREFIX "AUDIT: %s: %ld: "
328@@ -518,6 +533,27 @@
329 }
330
331 void
332+FatalSignal(int signo)
333+{
334+ static Bool beenhere = FALSE;
335+
336+ if (beenhere)
337+ ErrorF("\nFatalSignal re-entered, aborting\n");
338+ else
339+ ErrorF("\nCaught signal %d (%s). Server aborting\n",
340+ signo, strsignal(signo));
341+
342+ if (!beenhere)
343+ OsVendorFatalError();
344+ if (!beenhere) {
345+ beenhere = TRUE;
346+ SigAbortServer(signo);
347+ } else
348+ abort();
349+ /*NOTREACHED*/
350+}
351+
352+void
353 FatalError(const char *f, ...)
354 {
355 va_list args;
356Index: xorg-server/os/osinit.c
357===================================================================
358--- xorg-server.orig/os/osinit.c 2011-09-10 21:40:27.000000000 -0700
359+++ xorg-server/os/osinit.c 2011-09-10 21:45:50.076124422 -0700
360@@ -138,13 +138,13 @@
361 case SIGBUS:
362 case SIGILL:
363 case SIGFPE:
364+ signal(signo,SIG_DFL);
365 ErrorF("%s at address %p\n", strsignal(signo), sip->si_addr);
366 }
367 }
368 #endif
369
370- FatalError("Caught signal %d (%s). Server aborting\n",
371- signo, strsignal(signo));
372+ FatalSignal(signo);
373 }
374
375 void
diff --git a/debian/patches/105_nvidia_fglrx_autodetect.patch b/debian/patches/105_nvidia_fglrx_autodetect.patch
deleted file mode 100644
index 5668e71..0000000
--- a/debian/patches/105_nvidia_fglrx_autodetect.patch
+++ /dev/null
@@ -1,83 +0,0 @@
1From 0366a844c36bf8424a2625425c181b9b97f35bee Mon Sep 17 00:00:00 2001
2From: Robert Hooker <sarvatt@ubuntu.com>
3Date: Wed, 1 Sep 2010 13:23:21 -0400
4Subject: [PATCH] Attempt to get nvidia and fglrx working without an xorg.conf.
5
6Signed-off-by: Robert Hooker <sarvatt@ubuntu.com>
7---
8 hw/xfree86/common/xf86AutoConfig.c | 12 +++++++++++-
9 hw/xfree86/common/xf86pciBus.c | 14 +++++++++-----
10 2 files changed, 20 insertions(+), 6 deletions(-)
11
12Index: xorg-server/hw/xfree86/common/xf86AutoConfig.c
13===================================================================
14--- xorg-server.orig/hw/xfree86/common/xf86AutoConfig.c 2011-08-24 12:52:45.775647148 +0300
15+++ xorg-server/hw/xfree86/common/xf86AutoConfig.c 2011-08-24 12:58:12.485651804 +0300
16@@ -75,6 +75,13 @@
17 "\tDevice\t" BUILTIN_DEVICE_NAME "\n" \
18 "EndSection\n\n"
19
20+#define BUILTIN_SCREEN_SECTION_PROPRIETARY \
21+ "Section \"Screen\"\n" \
22+ "\tIdentifier\t" BUILTIN_SCREEN_NAME "\n" \
23+ "\tDevice\t" BUILTIN_DEVICE_NAME "\n" \
24+ "\tDefaultDepth\t24\n" \
25+ "EndSection\n\n"
26+
27 #define BUILTIN_LAYOUT_SECTION_PRE \
28 "Section \"ServerLayout\"\n" \
29 "\tIdentifier\t\"Builtin Default Layout\"\n"
30@@ -153,7 +160,10 @@
31 for (p = deviceList; *p; p++) {
32 snprintf(buf, sizeof(buf), BUILTIN_DEVICE_SECTION, *p, 0, *p);
33 AppendToConfig(buf);
34- snprintf(buf, sizeof(buf), BUILTIN_SCREEN_SECTION, *p, 0, *p, 0);
35+ if( strcmp(*p, "fglrx") == 0 || strcmp(*p, "nvidia") == 0)
36+ snprintf(buf, sizeof(buf), BUILTIN_SCREEN_SECTION_PROPRIETARY, *p, 0, *p, 0);
37+ else
38+ snprintf(buf, sizeof(buf), BUILTIN_SCREEN_SECTION, *p, 0, *p, 0);
39 AppendToConfig(buf);
40 }
41
42Index: xorg-server/hw/xfree86/common/xf86pciBus.c
43===================================================================
44--- xorg-server.orig/hw/xfree86/common/xf86pciBus.c 2011-08-24 12:56:49.535650619 +0300
45+++ xorg-server/hw/xfree86/common/xf86pciBus.c 2011-08-24 12:57:52.775651523 +0300
46@@ -1107,7 +1107,10 @@
47 case 0x1142: driverList[0] = "apm"; break;
48 case 0xedd8: driverList[0] = "ark"; break;
49 case 0x1a03: driverList[0] = "ast"; break;
50- case 0x1002: driverList[0] = "ati"; break;
51+ case 0x1002:
52+ driverList[0] = "fglrx";
53+ driverList[1] = "ati";
54+ break;
55 case 0x102c: driverList[0] = "chips"; break;
56 case 0x1013: driverList[0] = "cirrus"; break;
57 case 0x3d3d: driverList[0] = "glint"; break;
58@@ -1124,20 +1127,21 @@
59 case 0x102b: driverList[0] = "mga"; break;
60 case 0x10c8: driverList[0] = "neomagic"; break;
61 case 0x10de: case 0x12d2:
62+ driverList[0] = "nvidia";
63 switch (dev->device_id) {
64 /* NV1 */
65 case 0x0008:
66 case 0x0009:
67- driverList[0] = "vesa";
68+ driverList[1] = "vesa";
69 break;
70 /* NV3 */
71 case 0x0018:
72 case 0x0019:
73- driverList[0] = "nv";
74+ driverList[1] = "nv";
75 break;
76 default:
77- driverList[0] = "nouveau";
78- driverList[1] = "nv";
79+ driverList[1] = "nouveau";
80+ driverList[2] = "nv";
81 break;
82 }
83 break;
diff --git a/debian/patches/111_armel-drv-fallbacks.patch b/debian/patches/111_armel-drv-fallbacks.patch
deleted file mode 100644
index 50d0c6f..0000000
--- a/debian/patches/111_armel-drv-fallbacks.patch
+++ /dev/null
@@ -1,62 +0,0 @@
1Index: xorg-server-1.11.4/hw/xfree86/common/xf86AutoConfig.c
2===================================================================
3--- xorg-server-1.11.4.orig/hw/xfree86/common/xf86AutoConfig.c 2012-05-21 13:27:14.460110121 -0300
4+++ xorg-server-1.11.4/hw/xfree86/common/xf86AutoConfig.c 2012-05-21 13:29:49.620879524 -0300
5@@ -44,6 +44,12 @@
6 # include "xf86sbusBus.h"
7 #endif
8
9+#if defined(__arm__) && defined(__linux__)
10+# include "loaderProcs.h"
11+# include <sys/types.h> /* For opendir in test_sysfs_device */
12+# include <dirent.h> /* For opendir in test_sysfs_device */
13+#endif
14+
15 #ifdef sun
16 # include <sys/visual_io.h>
17 # include <ctype.h>
18@@ -198,6 +204,26 @@
19 return ret == CONFIG_OK;
20 }
21
22+#if defined(__arm__) && defined(__linux__)
23+static int
24+test_sysfs_device (char * device_name, char * driver_name)
25+{
26+ DIR* dir = opendir("/sys/devices/platform");
27+ struct dirent *current_dir;
28+ int len = strlen(device_name);
29+
30+ while (current_dir = readdir(dir)) {
31+ if (strlen(current_dir->d_name) >= len && strncmp(device_name, current_dir->d_name, len) == 0)
32+ break;
33+ }
34+ closedir(dir);
35+ if(!current_dir)
36+ return 0;
37+
38+ return 1;
39+}
40+#endif /* defined(__arm__) && defined(__linux__) */
41+
42 static void
43 listPossibleVideoDrivers(char *matches[], int nmatches)
44 {
45@@ -282,6 +308,17 @@
46 #if !defined(__linux__) && defined(__sparc__)
47 matches[i++] = xnfstrdup("wsfb");
48 #else
49+#if defined(__linux__) && defined(__arm__)
50+ if (test_sysfs_device("mxc_gpu", "imx"))
51+ matches[i++] = xnfstrdup("imx");
52+ else if (test_sysfs_device("dovefb", "dovefb"))
53+ matches[i++] = xnfstrdup("dovefb");
54+ else if (test_sysfs_device("omap", "pvr")) {
55+ matches[i++] = xnfstrdup("pvr");
56+ matches[i++] = xnfstrdup("omap");
57+ } else if (test_sysfs_device("omapfb", "omapfb"))
58+ matches[i++] = xnfstrdup("omapfb");
59+#endif /* defined(__linux__) && defined(__arm__) */
60 matches[i++] = xnfstrdup("fbdev");
61 #endif
62 }
diff --git a/debian/patches/122_xext_fix_card32_overflow_in_xauth.patch b/debian/patches/122_xext_fix_card32_overflow_in_xauth.patch
deleted file mode 100644
index 69b7300..0000000
--- a/debian/patches/122_xext_fix_card32_overflow_in_xauth.patch
+++ /dev/null
@@ -1,38 +0,0 @@
1Description: Xext: "xauth generate" with large timeout crashes Xorg #27134
2 The security timout CARD32 millis would overflow with large timeouts, causing
3 the timer callback to be called immediately and hit an assertion in
4 SecurityAuthorizationExpired.
5 .
6 This has not been applied upstream yet. Discussion of the patch faltered
7 without resolution. This patch has a problem when the epoch time is
8 sufficiently far in the future (about 2035) that it doesn't matter right now.
9Origin: http://patchwork.freedesktop.org/patch/242/
10Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27134
11Bug-Ubuntu: https://launchpad.net/bugs/519049
12
13Index: xorg-server/Xext/security.c
14===================================================================
15--- xorg-server.orig/Xext/security.c 2011-08-24 12:52:45.635647146 +0300
16+++ xorg-server/Xext/security.c 2011-08-24 12:56:49.595650621 +0300
17@@ -271,10 +271,10 @@
18 /* maxSecs is the number of full seconds that can be expressed in
19 * 32 bits worth of milliseconds
20 */
21- CARD32 maxSecs = (CARD32)(~0) / (CARD32)MILLI_PER_SECOND;
22+ CARD32 maxSecs = (CARD32)(MAXINT) / (CARD32)MILLI_PER_SECOND;
23
24 if (seconds > maxSecs)
25- { /* only come here if we want to wait more than 49 days */
26+ { /* only come here if we want to wait more than 24 days */
27 pAuth->secondsRemaining = seconds - maxSecs;
28 return maxSecs * MILLI_PER_SECOND;
29 }
30@@ -312,8 +312,6 @@
31 {
32 SecurityAuthorizationPtr pAuth = (SecurityAuthorizationPtr)pval;
33
34- assert(pAuth->timer == timer);
35-
36 if (pAuth->secondsRemaining)
37 {
38 return SecurityComputeAuthorizationTimeout(pAuth,
diff --git a/debian/patches/13_debian_add_xkbpath_env_variable.diff b/debian/patches/13_debian_add_xkbpath_env_variable.diff
deleted file mode 100644
index bd6ca5b..0000000
--- a/debian/patches/13_debian_add_xkbpath_env_variable.diff
+++ /dev/null
@@ -1,27 +0,0 @@
1--- xorg-server.orig/xkb/xkbInit.c
2+++ xorg-server/xkb/xkbInit.c
3@@ -805,6 +805,14 @@
4 extern unsigned char XkbDfltAccessXOptions;
5
6 int
7+xkbInitGlobals()
8+{
9+ char * xkbpath= getenv("XKBPATH");
10+ if (xkbpath!=NULL)
11+ XkbBaseDirectory= xkbpath;
12+}
13+
14+int
15 XkbProcessArguments(int argc,char *argv[],int i)
16 {
17 if (strcmp(argv[i],"-kb")==0) {
18--- xorg-server.orig/os/utils.c
19+++ xorg-server/os/utils.c
20@@ -685,6 +685,7 @@
21 */
22 void InitGlobals(void)
23 {
24+ xkbInitGlobals();
25 ddxInitGlobals();
26 }
27
diff --git a/debian/patches/15-nouveau.diff b/debian/patches/15-nouveau.diff
deleted file mode 100644
index 98fec87..0000000
--- a/debian/patches/15-nouveau.diff
+++ /dev/null
@@ -1,68 +0,0 @@
1From a685b5cf34532cef96fc9b05f735088ac0c0c7ad Mon Sep 17 00:00:00 2001
2From: Fedora X Ninjas <x@fedoraproject.org>
3Date: Tue, 16 Feb 2010 11:38:17 +1000
4Subject: [PATCH 08/17] autoconfig: select nouveau by default for NVIDIA GPUs
5
6Also, don't treat DRI setup failure as an error for nouveau.
7---
8 glx/glxdri.c | 7 +++++--
9 glx/glxdri2.c | 7 +++++--
10 hw/xfree86/common/xf86AutoConfig.c | 19 ++++++++++++++++++-
11 3 files changed, 28 insertions(+), 5 deletions(-)
12---
13v2: Adapt the (II) part for nouveau after the move from glx/glxdri*.c to
14 glx/glxdricommon.c; the callers will still report (EE) after that
15 when mentioning the fallback to software rendering (since the error
16 case can be triggered in many various ways).
17
18Signed-off-by: Cyril Brulebois <kibi@debian.org>
19
20--- a/hw/xfree86/common/xf86pciBus.c
21+++ b/hw/xfree86/common/xf86pciBus.c
22@@ -1123,7 +1123,24 @@ videoPtrToDriverList(struct pci_device *
23 break;
24 case 0x102b: driverList[0] = "mga"; break;
25 case 0x10c8: driverList[0] = "neomagic"; break;
26- case 0x10de: case 0x12d2: driverList[0] = "nv"; break;
27+ case 0x10de: case 0x12d2:
28+ switch (dev->device_id) {
29+ /* NV1 */
30+ case 0x0008:
31+ case 0x0009:
32+ driverList[0] = "vesa";
33+ break;
34+ /* NV3 */
35+ case 0x0018:
36+ case 0x0019:
37+ driverList[0] = "nv";
38+ break;
39+ default:
40+ driverList[0] = "nouveau";
41+ driverList[1] = "nv";
42+ break;
43+ }
44+ break;
45 case 0x1106: driverList[0] = "openchrome"; break;
46 case 0x1b36: driverList[0] = "qxl"; break;
47 case 0x1163: driverList[0] = "rendition"; break;
48--- a/glx/glxdricommon.c
49+++ b/glx/glxdricommon.c
50@@ -217,6 +217,7 @@ glxProbeDriver(const char *driverName,
51 void *driver;
52 char filename[PATH_MAX];
53 const __DRIextension **extensions;
54+ int from = X_ERROR;
55
56 snprintf(filename, sizeof filename, "%s/%s_dri.so",
57 dri_driver_path, driverName);
58@@ -248,7 +249,9 @@ glxProbeDriver(const char *driverName,
59 }
60
61 if (*coreExt == NULL || *renderExt == NULL) {
62- LogMessage(X_ERROR,
63+ if (!strcmp(driverName, "nouveau"))
64+ from = X_INFO;
65+ LogMessage(from,
66 "AIGLX error: %s does not export required DRI extension\n",
67 driverName);
68 goto cleanup_failure;
diff --git a/debian/patches/157_check_null_modes.patch b/debian/patches/157_check_null_modes.patch
deleted file mode 100644
index a0d6370..0000000
--- a/debian/patches/157_check_null_modes.patch
+++ /dev/null
@@ -1,14 +0,0 @@
1Index: xorg-server/hw/xfree86/common/xf86VidMode.c
2===================================================================
3--- xorg-server.orig/hw/xfree86/common/xf86VidMode.c 2011-08-24 12:52:45.565647144 +0300
4+++ xorg-server/hw/xfree86/common/xf86VidMode.c 2011-08-24 12:56:49.605650623 +0300
5@@ -222,6 +222,9 @@
6
7 pScrn = xf86Screens[scrnIndex];
8 pVidMode = VMPTR(pScrn->pScreen);
9+ if (pScrn->modes == NULL)
10+ return FALSE;
11+
12 pVidMode->First = pScrn->modes;
13 pVidMode->Next = pVidMode->First->next;
14
diff --git a/debian/patches/162_null_crtc_in_rotation.patch b/debian/patches/162_null_crtc_in_rotation.patch
deleted file mode 100644
index 0f01921..0000000
--- a/debian/patches/162_null_crtc_in_rotation.patch
+++ /dev/null
@@ -1,14 +0,0 @@
1Index: xorg-server/hw/xfree86/modes/xf86RandR12.c
2===================================================================
3--- xorg-server.orig/hw/xfree86/modes/xf86RandR12.c 2011-08-24 12:52:45.505647142 +0300
4+++ xorg-server/hw/xfree86/modes/xf86RandR12.c 2011-08-24 12:56:49.615650622 +0300
5@@ -930,7 +930,8 @@
6 for (c = 0; c < config->num_crtc; c++) {
7 xf86CrtcPtr crtc = config->crtc[c];
8
9- RRCrtcSetRotations (crtc->randr_crtc, rotations);
10+ if (crtc != NULL)
11+ RRCrtcSetRotations (crtc->randr_crtc, rotations);
12 }
13 #endif
14 randrp->supported_rotations = rotations;
diff --git a/debian/patches/165_man_xorg_conf_no_device_ident.patch b/debian/patches/165_man_xorg_conf_no_device_ident.patch
deleted file mode 100644
index a11d2a1..0000000
--- a/debian/patches/165_man_xorg_conf_no_device_ident.patch
+++ /dev/null
@@ -1,26 +0,0 @@
1From b3bb14b11a58f7bfc3ba5617c524d01a6e683de1 Mon Sep 17 00:00:00 2001
2From: Bryce Harrington <bryce@bryceharrington.org>
3Date: Wed, 18 Mar 2009 21:08:19 -0700
4Subject: [PATCH] X boots up without a 'Device' identifier; don't need to say it
5 is mandatory in the xorg.conf man page anymore.
6
7Signed-off-by: Bryce Harrington <bryce@bryceharrington.org>
8---
9 hw/xfree86/man/xorg.conf.man.pre | 4 +---
10 1 files changed, 1 insertions(+), 3 deletions(-)
11
12Index: xorg-server/hw/xfree86/doc/man/xorg.conf.man
13===================================================================
14--- xorg-server.orig/hw/xfree86/man/xorg.conf.man 2011-08-24 12:52:45.445647143 +0300
15+++ xorg-server/hw/xfree86/man/xorg.conf.man 2011-08-24 12:56:49.625650620 +0300
16@@ -1816,9 +1816,7 @@
17 .PP
18 The
19 .B Identifier
20-and
21-.B Device
22-entries are mandatory.
23+entry is mandatory.
24 All others are optional.
25 .PP
26 The
diff --git a/debian/patches/166_nullptr_xinerama_keyrepeat.patch b/debian/patches/166_nullptr_xinerama_keyrepeat.patch
deleted file mode 100644
index cbff596..0000000
--- a/debian/patches/166_nullptr_xinerama_keyrepeat.patch
+++ /dev/null
@@ -1,27 +0,0 @@
1From f0ef98d8d54f5dfa3081b62ff672e0fe992b0a01 Mon Sep 17 00:00:00 2001
2From: Bryce Harrington <bryce@bryceharrington.org>
3Date: Wed, 18 Mar 2009 23:28:51 -0700
4Subject: [PATCH] Check for null pointer dereference to prevent crash
5 on non-primary Xinerama screens when key repeating.
6 (LP: #324465)
7
8Signed-off-by: Bryce Harrington <bryce@bryceharrington.org>
9---
10 mi/mipointer.c | 4 ++++
11 1 files changed, 4 insertions(+), 0 deletions(-)
12
13Index: xorg-server/mi/mipointer.c
14===================================================================
15--- xorg-server.orig/mi/mipointer.c 2011-08-24 12:52:45.385647143 +0300
16+++ xorg-server/mi/mipointer.c 2011-08-24 12:57:30.295651201 +0300
17@@ -300,6 +300,10 @@
18 SetupScreen (pScreen);
19 pPointer = MIPOINTER(pDev);
20
21+ /* Null pointer causes crash on keyrepeat with Xinerama LP: (#324465) */
22+ if (pPointer == NULL)
23+ return;
24+
25 if (pPointer->pScreen != pScreen)
26 {
27 (*pScreenPriv->screenFuncs->NewEventScreen) (pDev, pScreen, TRUE);
diff --git a/debian/patches/167_nullptr_xisbread.patch b/debian/patches/167_nullptr_xisbread.patch
deleted file mode 100644
index 0fa56bd..0000000
--- a/debian/patches/167_nullptr_xisbread.patch
+++ /dev/null
@@ -1,14 +0,0 @@
1Index: xorg-server/hw/xfree86/common/xisb.c
2===================================================================
3--- xorg-server.orig/hw/xfree86/common/xisb.c 2011-08-24 12:52:45.315647139 +0300
4+++ xorg-server/hw/xfree86/common/xisb.c 2011-08-24 12:56:49.655650624 +0300
5@@ -98,6 +98,9 @@
6 {
7 int ret;
8
9+ if (b == NULL)
10+ return -2;
11+
12 if (b->current >= b->end)
13 {
14 if (b->block_duration >= 0)
diff --git a/debian/patches/168_glibc_trace_to_stderr.patch b/debian/patches/168_glibc_trace_to_stderr.patch
deleted file mode 100644
index 5503a1c..0000000
--- a/debian/patches/168_glibc_trace_to_stderr.patch
+++ /dev/null
@@ -1,17 +0,0 @@
1Report abort traces to stderr instead of terminal. This enables apport
2to catch the error so it can file a bug report about the crash.
3
4Index: xorg-server/hw/xfree86/common/xf86Init.c
5===================================================================
6--- xorg-server.orig/hw/xfree86/common/xf86Init.c 2011-08-24 12:56:49.555650622 +0300
7+++ xorg-server/hw/xfree86/common/xf86Init.c 2011-08-24 12:56:49.665650623 +0300
8@@ -866,6 +866,9 @@
9
10 if (!beenHere) {
11 umask(022);
12+ /* have glibc report internal abort traces to stderr instead of
13+ the controlling terminal */
14+ setenv("LIBC_FATAL_STDERR_","1",0);
15 xf86LogInit();
16 }
17
diff --git a/debian/patches/172_cwgetbackingpicture_nullptr_check.patch b/debian/patches/172_cwgetbackingpicture_nullptr_check.patch
deleted file mode 100644
index 8d5bd4b..0000000
--- a/debian/patches/172_cwgetbackingpicture_nullptr_check.patch
+++ /dev/null
@@ -1,35 +0,0 @@
1From 7813adf66be31d8b0e8df21821e786e688f7fe78 Mon Sep 17 00:00:00 2001
2From: Bryce Harrington <bryce@bryceharrington.org>
3Date: Fri, 27 Mar 2009 19:01:32 -0700
4Subject: [PATCH] cwGetBackingPicture can segfault when minimizing/maximizing firefox with
5 a flash video playing. This appears to be a race condition in which the
6 backing picture's data is not always fully defined.
7
8Signed-off-by: Bryce Harrington <bryce@bryceharrington.org>
9---
10 miext/cw/cw_render.c | 13 +++++++++----
11 1 files changed, 9 insertions(+), 4 deletions(-)
12
13Index: xorg-server/miext/cw/cw_render.c
14===================================================================
15--- xorg-server.orig/miext/cw/cw_render.c 2011-08-24 12:52:45.195647139 +0300
16+++ xorg-server/miext/cw/cw_render.c 2011-08-24 12:56:49.675650621 +0300
17@@ -123,10 +123,15 @@
18 WindowPtr pWindow = (WindowPtr) pDrawable;
19 PixmapPtr pPixmap = getCwPixmap (pWindow);
20
21- *x_off = pDrawable->x - pPixmap->screen_x;
22- *y_off = pDrawable->y - pPixmap->screen_y;
23+ if (pDrawable && pPixmap) {
24+ *x_off = pDrawable->x - pPixmap->screen_x;
25+ *y_off = pDrawable->y - pPixmap->screen_y;
26
27- return pPicturePrivate->pBackingPicture;
28+ return pPicturePrivate->pBackingPicture;
29+ } else {
30+ *x_off = *y_off = 0;
31+ return pPicture;
32+ }
33 }
34 else
35 {
diff --git a/debian/patches/188_default_primary_to_first_busid.patch b/debian/patches/188_default_primary_to_first_busid.patch
deleted file mode 100644
index 2115a52..0000000
--- a/debian/patches/188_default_primary_to_first_busid.patch
+++ /dev/null
@@ -1,20 +0,0 @@
1If there seems to be more than one possible primary device, just
2pick the first device and carry on (LP 459512)
3
4signed-off-by: Bryce Harrington <bryce@canonical.com>
5
6Index: xorg-server/hw/xfree86/common/xf86pciBus.c
7===================================================================
8--- xorg-server.orig/hw/xfree86/common/xf86pciBus.c 2011-08-24 12:56:49.565650621 +0300
9+++ xorg-server/hw/xfree86/common/xf86pciBus.c 2011-08-24 12:56:49.685650622 +0300
10@@ -147,8 +147,8 @@
11 primaryBus.id.pci = info;
12 } else {
13 xf86Msg(X_NOTICE,
14- "More than one possible primary device found\n");
15- primaryBus.type ^= (BusType)(-1);
16+ "More than one possible primary device found. Using first one seen.\n");
17+ break;
18 }
19 }
20 }
diff --git a/debian/patches/190_cache-xkbcomp_output_for_fast_start_up.patch b/debian/patches/190_cache-xkbcomp_output_for_fast_start_up.patch
deleted file mode 100644
index ca4a57c..0000000
--- a/debian/patches/190_cache-xkbcomp_output_for_fast_start_up.patch
+++ /dev/null
@@ -1,343 +0,0 @@
1Patch from Moblin to cache xkbcomp output for faster booting
2
3Signed-off-by: Bryce Harrington <bryce@canonical.com>
4---
5
6Index: xorg-server/configure.ac
7===================================================================
8--- xorg-server.orig/configure.ac 2011-08-24 12:56:49.505650620 +0300
9+++ xorg-server/configure.ac 2011-08-24 12:57:47.895651453 +0300
10@@ -537,9 +537,9 @@
11 AC_ARG_WITH(xkb-path, AS_HELP_STRING([--with-xkb-path=PATH], [Path to XKB base dir (default: ${datadir}/X11/xkb)]),
12 [ XKBPATH="$withval" ],
13 [ XKBPATH="${datadir}/X11/xkb" ])
14-AC_ARG_WITH(xkb-output, AS_HELP_STRING([--with-xkb-output=PATH], [Path to XKB output dir (default: ${datadir}/X11/xkb/compiled)]),
15+AC_ARG_WITH(xkb-output, AS_HELP_STRING([--with-xkb-output=PATH], [Path to XKB output dir (default: ${localstatedir}/cache/xkb)]),
16 [ XKBOUTPUT="$withval" ],
17- [ XKBOUTPUT="compiled" ])
18+ [ XKBOUTPUT="${localstatedir}/cache/xkb" ])
19 AC_ARG_WITH(default-xkb-rules, AS_HELP_STRING([--with-default-xkb-rules=RULES],
20 [Keyboard ruleset (default: base/evdev)]),
21 [ XKB_DFLT_RULES="$withval" ],
22@@ -1173,7 +1173,7 @@
23 dnl Make sure XKM_OUTPUT_DIR is an absolute path
24 XKBOUTPUT_FIRSTCHAR=`echo $XKBOUTPUT | cut -b 1`
25 if [[ x$XKBOUTPUT_FIRSTCHAR != x/ -a x$XKBOUTPUT_FIRSTCHAR != 'x$' ]] ; then
26- XKBOUTPUT="$XKB_BASE_DIRECTORY/$XKBOUTPUT"
27+ AC_MSG_ERROR([xkb-output must be an absolute path.])
28 fi
29
30 dnl XKM_OUTPUT_DIR (used in code) must end in / or file names get hosed
31Index: xorg-server/xkb/README.compiled
32===================================================================
33--- xorg-server.orig/xkb/README.compiled 2011-08-24 12:52:45.055647137 +0300
34+++ xorg-server/xkb/README.compiled 2011-08-24 12:56:49.705650623 +0300
35@@ -4,10 +4,10 @@
36 or some other tool might destroy or replace the files in this directory,
37 so it is not a safe place to store compiled keymaps for long periods of
38 time. The default keymap for any server is usually stored in:
39- X<num>-default.xkm
40-where <num> is the display number of the server in question, which makes
41-it possible for several servers *on the same host* to share the same
42-directory.
43+ server-<SHA1>.xkm
44+
45+where <SHA1> is the SHA1 hash of keymap source, so that compiled
46+keymap of different keymap sources are stored in different files.
47
48 Unless the X server is modified, sharing this directory between servers on
49 different hosts could cause problems.
50Index: xorg-server/xkb/ddxLoad.c
51===================================================================
52--- xorg-server.orig/xkb/ddxLoad.c 2011-08-24 12:52:45.065647139 +0300
53+++ xorg-server/xkb/ddxLoad.c 2011-08-24 12:56:49.705650623 +0300
54@@ -30,6 +30,12 @@
55
56 #include <xkb-config.h>
57
58+#ifdef HAVE_SHA1_IN_LIBGCRYPT /* Use libgcrypt for SHA1 */
59+# include <gcrypt.h>
60+#else /* Use OpenSSL's libcrypto */
61+#warning "xkbcomp caching support disabled"
62+#endif
63+
64 #include <stdio.h>
65 #include <ctype.h>
66 #include <X11/X.h>
67@@ -43,20 +49,9 @@
68 #define XKBSRV_NEED_FILE_FUNCS
69 #include <xkbsrv.h>
70 #include <X11/extensions/XI.h>
71+#include <errno.h>
72 #include "xkb.h"
73
74- /*
75- * If XKM_OUTPUT_DIR specifies a path without a leading slash, it is
76- * relative to the top-level XKB configuration directory.
77- * Making the server write to a subdirectory of that directory
78- * requires some work in the general case (install procedure
79- * has to create links to /var or somesuch on many machines),
80- * so we just compile into /usr/tmp for now.
81- */
82-#ifndef XKM_OUTPUT_DIR
83-#define XKM_OUTPUT_DIR "compiled/"
84-#endif
85-
86 #define PRE_ERROR_MSG "\"The XKEYBOARD keymap compiler (xkbcomp) reports:\""
87 #define ERROR_PREFIX "\"> \""
88 #define POST_ERROR_MSG1 "\"Errors from xkbcomp are not fatal to the X server\""
89@@ -170,6 +165,47 @@
90 }
91 }
92
93+#ifndef SHA_DIGEST_LENGTH
94+#define SHA_DIGEST_LENGTH 20
95+#endif
96+
97+static Bool
98+Sha1Asc(char sha1Asc[SHA_DIGEST_LENGTH*2+1], const char * input)
99+{
100+ int i;
101+ unsigned char sha1[SHA_DIGEST_LENGTH];
102+
103+#ifdef HAVE_SHA1_IN_LIBGCRYPT /* Use libgcrypt for SHA1 */
104+ static int init;
105+ gcry_md_hd_t h;
106+ gcry_error_t err;
107+
108+ if (!init) {
109+ if (!gcry_check_version(NULL))
110+ return BadAlloc;
111+ gcry_control(GCRYCTL_DISABLE_SECMEM, 0);
112+ gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
113+ init = 1;
114+ }
115+
116+ err = gcry_md_open(&h, GCRY_MD_SHA1, 0);
117+ if (err)
118+ return BadAlloc;
119+ gcry_md_write(h, input, strlen(input));
120+ memcpy(sha1, gcry_md_read(h, GCRY_MD_SHA1), 20);
121+ gcry_md_close(h);
122+#endif
123+
124+ /* convert sha1 to sha1_asc */
125+ for(i=0; i<SHA_DIGEST_LENGTH; ++i) {
126+ sprintf(sha1Asc+i*2, "%02X", sha1[i]);
127+ }
128+
129+ return Success;
130+}
131+
132+/* call xkbcomp and compile XKB keymap, return xkm file name in
133+ nameRtrn */
134 static Bool
135 XkbDDXCompileKeymapByNames( XkbDescPtr xkb,
136 XkbComponentNamesPtr names,
137@@ -179,7 +215,11 @@
138 int nameRtrnLen)
139 {
140 FILE * out;
141- char *buf = NULL, keymap[PATH_MAX], xkm_output_dir[PATH_MAX];
142+ char * buf = NULL, xkmfile[PATH_MAX], xkm_output_dir[PATH_MAX];
143+ char * tmpXkmFile = NULL;
144+ char * canonicalXkmFileName = NULL;
145+ char sha1Asc[SHA_DIGEST_LENGTH*2+1], xkbKeyMapBuf[100*1024];
146+ int ret, result;
147
148 const char *emptystring = "";
149 char *xkbbasedirflag = NULL;
150@@ -190,14 +230,67 @@
151 /* WIN32 has no popen. The input must be stored in a file which is
152 used as input for xkbcomp. xkbcomp does not read from stdin. */
153 char tmpname[PATH_MAX];
154- const char *xkmfile = tmpname;
155+ const char *xkbfile = tmpname;
156 #else
157- const char *xkmfile = "-";
158+ const char *xkbfile = "-";
159 #endif
160
161- snprintf(keymap, sizeof(keymap), "server-%s", display);
162+ /* Write keymap source (xkbfile) to memory buffer `xkbKeyMapBuf',
163+ of which SHA1 is generated and used as result xkm file name */
164+ memset(xkbKeyMapBuf, 0, sizeof(xkbKeyMapBuf));
165+ out = fmemopen(xkbKeyMapBuf, sizeof(xkbKeyMapBuf), "w");
166+ if (NULL == out) {
167+ ErrorF("[xkb] Open xkbKeyMapBuf for writing failed\n");
168+ return FALSE;
169+ }
170+ ret = XkbWriteXKBKeymapForNames(out, names, xkb, want, need);
171+ if (fclose(out) !=0)
172+ {
173+ ErrorF("[xkb] XkbWriteXKBKeymapForNames error, perhaps xkbKeyMapBuf is too small\n");
174+ return FALSE;
175+ }
176+#ifdef DEBUG
177+ if (xkbDebugFlags) {
178+ ErrorF("[xkb] XkbDDXCompileKeymapByNames compiling keymap:\n");
179+ fputs(xkbKeyMapBuf, stderr);
180+ }
181+#endif
182+ if (!ret) {
183+ ErrorF("[xkb] Generating XKB Keymap failed, giving up compiling keymap\n");
184+ return FALSE;
185+ }
186+
187+ DebugF("[xkb] computing SHA1 of keymap\n");
188+ if (Success == Sha1Asc(sha1Asc, xkbKeyMapBuf)) {
189+ snprintf(xkmfile, sizeof(xkmfile), "server-%s", sha1Asc);
190+ }
191+ else {
192+ ErrorF("[xkb] Computing SHA1 of keymap failed, "
193+ "using display name instead as xkm file name\n");
194+ snprintf(xkmfile, sizeof(xkmfile), "server-%s", display);
195+ }
196
197 OutputDirectory(xkm_output_dir, sizeof(xkm_output_dir));
198+ /* set nameRtrn, fail if it's too small */
199+ if ((strlen(xkmfile)+1 > nameRtrnLen) && nameRtrn) {
200+ ErrorF("[xkb] nameRtrn too small to hold xkmfile name\n");
201+ return FALSE;
202+ }
203+ strncpy(nameRtrn, xkmfile, nameRtrnLen);
204+
205+ /* if the xkm file already exists, reuse it */
206+ canonicalXkmFileName = Xprintf("%s%s.xkm", xkm_output_dir, xkmfile);
207+ if (access(canonicalXkmFileName, R_OK) == 0) {
208+ /* yes, we can reuse the old xkm file */
209+ LogMessage(X_INFO, "XKB: reuse xkmfile %s\n", canonicalXkmFileName);
210+ result = TRUE;
211+ goto _ret;
212+ }
213+ LogMessage(X_INFO, "XKB: generating xkmfile %s\n", canonicalXkmFileName);
214+
215+ /* continue to call xkbcomp to compile the keymap. to avoid race
216+ condition, we compile it to a tmpfile then rename it to
217+ xkmfile */
218
219 #ifdef WIN32
220 strcpy(tmpname, Win32TempDir());
221@@ -222,15 +315,21 @@
222 }
223 }
224
225+ if ( (tmpXkmFile = tempnam(xkm_output_dir, NULL)) == NULL ) {
226+ ErrorF("[xkb] Can't generate temp xkm file name");
227+ result = FALSE;
228+ goto _ret;
229+ }
230+
231 if (asprintf(&buf,
232 "\"%s%sxkbcomp\" -w %d %s -xkm \"%s\" "
233- "-em1 %s -emp %s -eml %s \"%s%s.xkm\"",
234+ "-em1 %s -emp %s -eml %s \"%s\"",
235 xkbbindir, xkbbindirsep,
236 ((xkbDebugFlags < 2) ? 1 :
237 ((xkbDebugFlags > 10) ? 10 : (int) xkbDebugFlags)),
238- xkbbasedirflag ? xkbbasedirflag : "", xkmfile,
239+ xkbbasedirflag ? xkbbasedirflag : "", xkbfile,
240 PRE_ERROR_MSG, ERROR_PREFIX, POST_ERROR_MSG1,
241- xkm_output_dir, keymap) == -1)
242+ tmpXkmFile) == -1)
243 buf = NULL;
244
245 free(xkbbasedirflag);
246@@ -240,6 +339,11 @@
247 return FALSE;
248 }
249
250+ /* there's a potential race condition between calling tempnam()
251+ and invoking xkbcomp to write the result file (potential temp
252+ file name conflicts), but since xkbcomp is a standalone
253+ program, we have to live with this */
254+
255 #ifndef WIN32
256 out= Popen(buf,"w");
257 #else
258@@ -247,30 +351,42 @@
259 #endif
260
261 if (out!=NULL) {
262-#ifdef DEBUG
263- if (xkbDebugFlags) {
264- ErrorF("[xkb] XkbDDXCompileKeymapByNames compiling keymap:\n");
265- XkbWriteXKBKeymapForNames(stderr,names,xkb,want,need);
266- }
267-#endif
268- XkbWriteXKBKeymapForNames(out,names,xkb,want,need);
269+ /* write XKBKeyMapBuf to xkbcomp */
270+ if (EOF==fputs(xkbKeyMapBuf, out))
271+ {
272+ ErrorF("[xkb] Sending keymap to xkbcomp failed\n");
273+ result = FALSE;
274+ goto _ret;
275+ }
276 #ifndef WIN32
277 if (Pclose(out)==0)
278 #else
279 if (fclose(out)==0 && System(buf) >= 0)
280 #endif
281 {
282+ /* xkbcomp success */
283 if (xkbDebugFlags)
284- DebugF("[xkb] xkb executes: %s\n",buf);
285- if (nameRtrn) {
286- strncpy(nameRtrn,keymap,nameRtrnLen);
287- nameRtrn[nameRtrnLen-1]= '\0';
288- }
289- free(buf);
290- return TRUE;
291+ DebugF("[xkb] xkb executes: %s\n",buf);
292+
293+ /* if canonicalXkmFileName already exists now, we simply
294+ overwrite it, this is OK */
295+ ret = rename(tmpXkmFile, canonicalXkmFileName);
296+ if (0 != ret) {
297+ ErrorF("[xkb] Can't rename %s to %s, error: %s\n",
298+ tmpXkmFile, canonicalXkmFileName,
299+ strerror(errno));
300+
301+ /* in case of error, don't unlink tmpXkmFile, leave i
302+ for debugging */
303+
304+ result = FALSE;
305+ goto _ret;
306+ }
307+ result = TRUE;
308+ goto _ret;
309 }
310 else
311- LogMessage(X_ERROR, "Error compiling keymap (%s)\n", keymap);
312+ LogMessage(X_ERROR, "Error compiling keymap (%s)\n", xkbfile);
313 #ifdef WIN32
314 /* remove the temporary file */
315 unlink(tmpname);
316@@ -285,8 +401,17 @@
317 }
318 if (nameRtrn)
319 nameRtrn[0]= '\0';
320- free(buf);
321- return FALSE;
322+ result = FALSE;
323+
324+_ret:
325+ if (tmpXkmFile)
326+ free(tmpXkmFile);
327+ if (canonicalXkmFileName)
328+ free(canonicalXkmFileName);
329+ if (buf)
330+ free(buf);
331+
332+ return result;
333 }
334
335 static FILE *
336@@ -370,7 +495,6 @@
337 DebugF("Loaded XKB keymap %s, defined=0x%x\n",fileName,(*xkbRtrn)->defined);
338 }
339 fclose(file);
340- (void) unlink (fileName);
341 return (need|want)&(~missing);
342 }
343
diff --git a/debian/patches/191-Xorg-add-an-extra-module-path.patch b/debian/patches/191-Xorg-add-an-extra-module-path.patch
deleted file mode 100644
index 59ae2c1..0000000
--- a/debian/patches/191-Xorg-add-an-extra-module-path.patch
+++ /dev/null
@@ -1,99 +0,0 @@
1From 416a66de9d428a11776331926c23a61188b8fc16 Mon Sep 17 00:00:00 2001
2From: Ander Conselvan de Oliveira <ander@localhost.(none)>
3Date: Thu, 12 Mar 2009 09:45:57 -0300
4Subject: [PATCH 908/911] Xorg: add an extra module path
5
6If the extra module path is not an empty string (the default value),
7module path will be searched first in the extra module path and then in
8the default module path. This should simplify the alternatives system
9used on Mandriva's fglrx package.
10---
11Index: xorg-server/configure.ac
12===================================================================
13--- xorg-server.orig/configure.ac 2011-08-24 12:56:49.705650623 +0300
14+++ xorg-server/configure.ac 2011-08-24 12:57:34.655651265 +0300
15@@ -489,6 +489,10 @@
16 [Directory where modules are installed (default: $libdir/xorg/modules)]),
17 [ moduledir="$withval" ],
18 [ moduledir="${libdir}/xorg/modules" ])
19+AC_ARG_WITH(extra-module-dir,AS_HELP_STRING([--with-extra-module-dir=DIR],
20+ [Extra module directory to search for modules before the default one (default: empty)]),
21+ [ extra_moduledir="$withval" ],
22+ [ extra_moduledir="" ])
23 AC_ARG_WITH(log-dir, AS_HELP_STRING([--with-log-dir=DIR],
24 [Directory where log files are kept (default: $localstatedir/log)]),
25 [ logdir="$withval" ],
26@@ -1815,6 +1819,7 @@
27 AC_DEFINE_DIR(XF86CONFIGFILE, XF86CONFIGFILE, [Name of configuration file])
28 AC_DEFINE_DIR(__XCONFIGDIR__, XF86CONFIGDIR, [Name of configuration directory])
29 AC_DEFINE_DIR(DEFAULT_MODULE_PATH, moduledir, [Default module search path])
30+ AC_DEFINE_DIR(EXTRA_MODULE_PATH, extra_moduledir, [Extra module search path, searched before the default one])
31 AC_DEFINE_DIR(DEFAULT_LIBRARY_PATH, libdir, [Default library install path])
32 AC_DEFINE_DIR(DEFAULT_LOGPREFIX, LOGPREFIX, [Default log location])
33 AC_DEFINE_UNQUOTED(__VENDORDWEBSUPPORT__, ["$VENDOR_WEB"], [Vendor web address for support])
34Index: xorg-server/hw/xfree86/common/xf86Config.c
35===================================================================
36--- xorg-server.orig/hw/xfree86/common/xf86Config.c 2011-08-24 12:52:44.925647137 +0300
37+++ xorg-server/hw/xfree86/common/xf86Config.c 2011-08-24 12:56:49.715650621 +0300
38@@ -628,11 +628,21 @@
39
40 /* ModulePath */
41
42- if (fileconf) {
43- if (xf86ModPathFrom != X_CMDLINE && fileconf->file_modulepath) {
44+ if (xf86ModPathFrom != X_CMDLINE) {
45+ if (fileconf && fileconf->file_modulepath) {
46 xf86ModulePath = fileconf->file_modulepath;
47 xf86ModPathFrom = X_CONFIG;
48 }
49+ else if (strcmp(xf86ExtraModulePath, "") != 0) {
50+ char *newpath = malloc(strlen(xf86ExtraModulePath)
51+ + strlen(xf86ModulePath)
52+ + 2);
53+ strcpy(newpath, xf86ExtraModulePath);
54+ strcat(newpath, ",");
55+ strcat(newpath, xf86ModulePath);
56+
57+ xf86ModulePath = newpath;
58+ }
59 }
60
61 xf86Msg(xf86ModPathFrom, "ModulePath set to \"%s\"\n", xf86ModulePath);
62Index: xorg-server/hw/xfree86/common/xf86Globals.c
63===================================================================
64--- xorg-server.orig/hw/xfree86/common/xf86Globals.c 2011-08-24 12:52:44.935647136 +0300
65+++ xorg-server/hw/xfree86/common/xf86Globals.c 2011-08-24 12:56:49.715650621 +0300
66@@ -139,6 +139,7 @@
67 const char *xf86ConfigFile = NULL;
68 const char *xf86ConfigDir = NULL;
69 const char *xf86ModulePath = DEFAULT_MODULE_PATH;
70+const char *xf86ExtraModulePath = EXTRA_MODULE_PATH;
71 MessageType xf86ModPathFrom = X_DEFAULT;
72 const char *xf86LogFile = DEFAULT_LOGPREFIX;
73 MessageType xf86LogFileFrom = X_DEFAULT;
74Index: xorg-server/hw/xfree86/common/xf86Priv.h
75===================================================================
76--- xorg-server.orig/hw/xfree86/common/xf86Priv.h 2011-08-24 12:52:44.945647134 +0300
77+++ xorg-server/hw/xfree86/common/xf86Priv.h 2011-08-24 12:56:49.715650621 +0300
78@@ -75,6 +75,7 @@
79
80 extern _X_EXPORT xf86InfoRec xf86Info;
81 extern _X_EXPORT const char *xf86ModulePath;
82+extern _X_EXPORT const char *xf86ExtraModulePath;
83 extern _X_EXPORT MessageType xf86ModPathFrom;
84 extern _X_EXPORT const char *xf86LogFile;
85 extern _X_EXPORT MessageType xf86LogFileFrom;
86Index: xorg-server/include/xorg-config.h.in
87===================================================================
88--- xorg-server.orig/include/xorg-config.h.in 2011-08-24 12:52:44.965647137 +0300
89+++ xorg-server/include/xorg-config.h.in 2011-08-24 12:56:49.715650621 +0300
90@@ -42,6 +42,9 @@
91 /* Path to loadable modules. */
92 #undef DEFAULT_MODULE_PATH
93
94+/* Path to extra loadable modules. */
95+#undef EXTRA_MODULE_PATH
96+
97 /* Path to installed libraries. */
98 #undef DEFAULT_LIBRARY_PATH
99
diff --git a/debian/patches/198_nohwaccess.patch b/debian/patches/198_nohwaccess.patch
deleted file mode 100644
index 0bc9169..0000000
--- a/debian/patches/198_nohwaccess.patch
+++ /dev/null
@@ -1,55 +0,0 @@
1Two chunks of jbarne's nohwaccess patch got taken upstream; this patch
2contains just the remainder, which implements a -nohwaccess option.
3
4Index: xorg-server/hw/xfree86/os-support/linux/lnx_init.c
5===================================================================
6--- xorg-server.orig/hw/xfree86/os-support/linux/lnx_init.c 2011-08-24 12:52:44.815647133 +0300
7+++ xorg-server/hw/xfree86/os-support/linux/lnx_init.c 2011-08-24 12:56:49.725650622 +0300
8@@ -41,6 +41,7 @@
9 static Bool KeepTty = FALSE;
10 static Bool VTSwitch = TRUE;
11 static Bool ShareVTs = FALSE;
12+Bool NoHwAccess = FALSE;
13 static int activeVT = -1;
14
15 static char vtname[11];
16@@ -321,6 +322,11 @@
17 ShareVTs = TRUE;
18 return 1;
19 }
20+ if (!strcmp(argv[i], "-nohwaccess"))
21+ {
22+ NoHwAccess = TRUE;
23+ return(1);
24+ }
25 if ((argv[i][0] == 'v') && (argv[i][1] == 't'))
26 {
27 if (sscanf(argv[i], "vt%2d", &xf86Info.vtno) == 0)
28@@ -342,4 +348,5 @@
29 ErrorF("don't detach controlling tty (for debugging only)\n");
30 ErrorF("-novtswitch don't immediately switch to new VT\n");
31 ErrorF("-sharevts share VTs with another X server\n");
32+ ErrorF("-nohwaccess don't access hardware ports directly\n");
33 }
34Index: xorg-server/hw/xfree86/os-support/linux/lnx_video.c
35===================================================================
36--- xorg-server.orig/hw/xfree86/os-support/linux/lnx_video.c 2011-08-24 12:52:44.825647135 +0300
37+++ xorg-server/hw/xfree86/os-support/linux/lnx_video.c 2011-08-24 12:56:49.725650622 +0300
38@@ -50,6 +50,7 @@
39 #define MAP_FAILED ((void *)-1)
40 #endif
41
42+extern Bool NoHwAccess;
43 static Bool ExtendedEnabled = FALSE;
44
45 #ifdef __ia64__
46@@ -497,6 +498,9 @@
47 int fd;
48 unsigned int ioBase_phys;
49 #endif
50+ /* Fake it... */
51+ if (NoHwAccess)
52+ return TRUE;
53
54 if (ExtendedEnabled)
55 return TRUE;
diff --git a/debian/patches/200_randr-null.patch b/debian/patches/200_randr-null.patch
deleted file mode 100644
index d2ddbaa..0000000
--- a/debian/patches/200_randr-null.patch
+++ /dev/null
@@ -1,14 +0,0 @@
1=== modified file 'randr/randr.c'
2Index: xorg-server/randr/randr.c
3===================================================================
4--- xorg-server.orig/randr/randr.c 2011-08-24 12:52:44.745647133 +0300
5+++ xorg-server/randr/randr.c 2011-08-24 12:57:30.195651199 +0300
6@@ -235,7 +235,7 @@
7 /*
8 * Calling function best set these function vectors
9 */
10- pScrPriv->rrGetInfo = 0;
11+ pScrPriv->rrGetInfo = NULL;
12 pScrPriv->maxWidth = pScrPriv->minWidth = pScreen->width;
13 pScrPriv->maxHeight = pScrPriv->minHeight = pScreen->height;
14
diff --git a/debian/patches/201_report-real-dpi.patch b/debian/patches/201_report-real-dpi.patch
deleted file mode 100644
index 253f38d..0000000
--- a/debian/patches/201_report-real-dpi.patch
+++ /dev/null
@@ -1,46 +0,0 @@
1Description: Report physical DPI when EDID data exists.
2 .
3 This reverts git commit fff00df94d7ebd18a8e24537ec96073717375a3f, which
4 made X report 96DPI via the core protocol.
5 .
6 We want to make this policy decision higher up the stack than the X server,
7 so revert this and make X report the physical DPI when the EDID contains
8 physical size data.
9Author: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
10
11Index: xorg-server/hw/xfree86/modes/xf86RandR12.c
12===================================================================
13--- xorg-server.orig/hw/xfree86/modes/xf86RandR12.c 2010-08-03 15:59:57.750272356 +1000
14+++ xorg-server/hw/xfree86/modes/xf86RandR12.c 2010-08-03 16:00:00.750380508 +1000
15@@ -805,6 +805,7 @@
16 else
17 {
18 xf86OutputPtr output = xf86CompatOutput(pScrn);
19+ rrScrPriv(pScreen);
20
21 if (output &&
22 output->conf_monitor &&
23@@ -817,6 +818,23 @@
24 mmWidth = output->conf_monitor->mon_width;
25 mmHeight = output->conf_monitor->mon_height;
26 }
27+ else if (pScrPriv && pScrPriv->primaryOutput)
28+ {
29+ /* Calculate DPI based on primary display size, not the entire display size */
30+ mmWidth = pScrPriv->primaryOutput->mmWidth * width / pScrPriv->primaryOutput->crtc->mode->mode.width;
31+ mmHeight = pScrPriv->primaryOutput->mmHeight * height / pScrPriv->primaryOutput->crtc->mode->mode.height;
32+ }
33+ else if (output && output->crtc && output->crtc->mode.HDisplay &&
34+ output->mm_width && output->mm_height)
35+ {
36+ /*
37+ * If the output has a mode and a declared size, use that
38+ * to scale the screen size
39+ */
40+ DisplayModePtr mode = &output->crtc->mode;
41+ mmWidth = output->mm_width * width / mode->HDisplay;
42+ mmHeight = output->mm_height * height / mode->VDisplay;
43+ }
44 else
45 {
46 /*
diff --git a/debian/patches/208_switch_on_release.diff b/debian/patches/208_switch_on_release.diff
deleted file mode 100644
index 3eefde7..0000000
--- a/debian/patches/208_switch_on_release.diff
+++ /dev/null
@@ -1,109 +0,0 @@
1Index: xorg-server/xkb/xkbActions.c
2===================================================================
3--- xorg-server.orig/xkb/xkbActions.c 2011-12-14 15:15:20.000000000 -0800
4+++ xorg-server/xkb/xkbActions.c 2011-12-14 15:26:43.372680253 -0800
5@@ -328,24 +328,83 @@ _XkbFilterLatchState( XkbSrvInfoPtr xkbi
6 return 1;
7 }
8
9+static int xkbSwitchGroupOnRelease(void)
10+{
11+ /* TODO: user configuring */
12+ return TRUE;
13+}
14+
15+static void xkbUpdateLockedGroup(XkbSrvInfoPtr xkbi, XkbAction* pAction)
16+{
17+ XkbGroupAction ga = pAction->group;
18+ if (ga.flags&XkbSA_GroupAbsolute)
19+ xkbi->state.locked_group= XkbSAGroup(&ga);
20+ else xkbi->state.locked_group+= XkbSAGroup(&ga);
21+}
22+
23+static XkbFilterPtr _XkbNextFreeFilter(XkbSrvInfoPtr xkbi);
24+
25 static int
26-_XkbFilterLockState( XkbSrvInfoPtr xkbi,
27+_XkbFilterLockGroup( XkbSrvInfoPtr xkbi,
28 XkbFilterPtr filter,
29 unsigned keycode,
30 XkbAction * pAction)
31 {
32- if (pAction&&(pAction->type==XkbSA_LockGroup)) {
33- if (pAction->group.flags&XkbSA_GroupAbsolute)
34- xkbi->state.locked_group= XkbSAGroup(&pAction->group);
35- else xkbi->state.locked_group+= XkbSAGroup(&pAction->group);
36- return 1;
37+ int sendEvent = 1;
38+
39+ if (!xkbSwitchGroupOnRelease()) {
40+ xkbUpdateLockedGroup(xkbi, pAction);
41+ return sendEvent;
42+ }
43+
44+ /* Delay switch till button release */
45+ if (filter->keycode==0) { /* initial press */
46+ filter->keycode = keycode;
47+ filter->active = 1;
48+ filter->filterOthers = 0; /* for what? */
49+ filter->filter = _XkbFilterLockGroup;
50+
51+ /* filter->priv = 0; */
52+ filter->upAction = *pAction;
53+
54+ /* Ok, now we need to simulate the action which would go if this action didn't block it.
55+ XkbSA_SetMods is the one: it is to set modifier' flag up. */
56+ {
57+ XkbStateRec fake_state = xkbi->state;
58+ XkbAction act;
59+
60+ fake_state.mods = 0;
61+ act = XkbGetKeyAction(xkbi, &fake_state, keycode);
62+
63+ /* KLUDGE: XkbSA_SetMods only? */
64+ if (act.type == XkbSA_SetMods) {
65+ XkbFilterPtr filter = _XkbNextFreeFilter(xkbi);
66+ sendEvent = _XkbFilterSetState(xkbi,filter,keycode,&act);
67+ }
68+ }
69+ }
70+ else {
71+ /* do nothing if some button else is pressed */
72+ if (!pAction)
73+ xkbUpdateLockedGroup(xkbi, &filter->upAction);
74+ filter->active = 0;
75 }
76+
77+ return sendEvent;
78+}
79+
80+static int
81+_XkbFilterLockMods( XkbSrvInfoPtr xkbi,
82+ XkbFilterPtr filter,
83+ unsigned keycode,
84+ XkbAction * pAction)
85+{
86 if (filter->keycode==0) { /* initial press */
87 filter->keycode = keycode;
88 filter->active = 1;
89 filter->filterOthers = 0;
90 filter->priv = xkbi->state.locked_mods&pAction->mods.mask;
91- filter->filter = _XkbFilterLockState;
92+ filter->filter = _XkbFilterLockMods;
93 filter->upAction = *pAction;
94 if (!(filter->upAction.mods.flags&XkbSA_LockNoLock))
95 xkbi->state.locked_mods|= pAction->mods.mask;
96@@ -1118,9 +1177,12 @@ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEI
97 sendEvent=_XkbFilterLatchState(xkbi,filter,key,&act);
98 break;
99 case XkbSA_LockMods:
100+ filter = _XkbNextFreeFilter(xkbi);
101+ sendEvent=_XkbFilterLockMods(xkbi,filter,key,&act);
102+ break;
103 case XkbSA_LockGroup:
104 filter = _XkbNextFreeFilter(xkbi);
105- sendEvent=_XkbFilterLockState(xkbi,filter,key,&act);
106+ sendEvent=_XkbFilterLockGroup(xkbi,filter,key,&act);
107 break;
108 case XkbSA_ISOLock:
109 filter = _XkbNextFreeFilter(xkbi);
diff --git a/debian/patches/209_add_legacy_bgnone_option.patch b/debian/patches/209_add_legacy_bgnone_option.patch
deleted file mode 100644
index e53d24d..0000000
--- a/debian/patches/209_add_legacy_bgnone_option.patch
+++ /dev/null
@@ -1,21 +0,0 @@
1Index: xorg-server/os/utils.c
2===================================================================
3--- xorg-server.orig/os/utils.c 2011-08-24 12:52:44.625647130 +0300
4+++ xorg-server/os/utils.c 2011-08-24 12:57:14.805650982 +0300
5@@ -513,6 +513,7 @@
6 ErrorF("-nolisten string don't listen on protocol\n");
7 ErrorF("-noreset don't reset after last client exists\n");
8 ErrorF("-background [none] create root window with no background\n");
9+ ErrorF("-nr (Ubuntu-specific) Synonym for -background none\n");
10 ErrorF("-reset reset after last client exists\n");
11 ErrorF("-p # screen-saver pattern duration (minutes)\n");
12 ErrorF("-pn accept failure to listen on all ports\n");
13@@ -851,6 +852,8 @@
14 UseMsg();
15 }
16 }
17+ else if ( strcmp( argv[i], "-nr") == 0)
18+ bgNoneRoot = TRUE;
19 else if ( strcmp( argv[i], "-maxbigreqsize") == 0) {
20 if(++i < argc) {
21 long reqSizeArg = atol(argv[i]);
diff --git a/debian/patches/214_glx_dri_searchdirs.patch b/debian/patches/214_glx_dri_searchdirs.patch
deleted file mode 100644
index 3baa38f..0000000
--- a/debian/patches/214_glx_dri_searchdirs.patch
+++ /dev/null
@@ -1,240 +0,0 @@
1Index: xorg-server/glx/glxdricommon.h
2===================================================================
3--- xorg-server.orig/glx/glxdricommon.h 2011-09-11 18:41:08.000000000 -0500
4+++ xorg-server/glx/glxdricommon.h 2011-09-11 18:41:43.381346390 -0500
5@@ -39,7 +39,7 @@
6 extern const __DRIsystemTimeExtension systemTimeExtension;
7
8 void *
9-glxProbeDriver(const char *name,
10+glxProbeDriver(const char *name, void **cookie,
11 void **coreExt, const char *coreName, int coreVersion,
12 void **renderExt, const char *renderName, int renderVersion);
13
14Index: xorg-server/glx/glxdriswrast.c
15===================================================================
16--- xorg-server.orig/glx/glxdriswrast.c 2011-09-11 18:41:08.000000000 -0500
17+++ xorg-server/glx/glxdriswrast.c 2011-09-11 18:41:43.381346390 -0500
18@@ -427,6 +427,7 @@
19 const char *driverName = "swrast";
20 __GLXDRIscreen *screen;
21 const __DRIconfig **driConfigs;
22+ void *cookie = NULL;
23
24 screen = calloc(1, sizeof *screen);
25 if (screen == NULL)
26@@ -438,7 +439,7 @@
27 screen->base.swapInterval = NULL;
28 screen->base.pScreen = pScreen;
29
30- screen->driver = glxProbeDriver(driverName,
31+ screen->driver = glxProbeDriver(driverName, &cookie,
32 (void **)&screen->core,
33 __DRI_CORE, __DRI_CORE_VERSION,
34 (void **)&screen->swrast,
35Index: xorg-server/configure.ac
36===================================================================
37--- xorg-server.orig/configure.ac 2011-09-11 18:41:08.000000000 -0500
38+++ xorg-server/configure.ac 2011-09-11 18:41:43.381346390 -0500
39@@ -1260,7 +1260,12 @@
40 AC_DEFINE_DIR(SERVER_MISC_CONFIG_PATH, SERVERCONFIG, [Server miscellaneous config path])
41 AC_DEFINE_DIR(BASE_FONT_PATH, FONTROOTDIR, [Default base font path])
42 dridriverdir=`$PKG_CONFIG --variable=dridriverdir dri`
43-AC_DEFINE_DIR(DRI_DRIVER_PATH, dridriverdir, [Default DRI driver path])
44+drisearchdirs=`$PKG_CONFIG --variable=drisearchdirs dri`
45+if test -n "$drisearchdirs" ; then
46+ AC_DEFINE_DIR(DRI_DRIVER_PATH, drisearchdirs, [Default DRI search dirs])
47+else
48+ AC_DEFINE_DIR(DRI_DRIVER_PATH, dridriverdir, [Default DRI driver path])
49+fi
50 AC_DEFINE_UNQUOTED(XVENDORNAME, ["$VENDOR_NAME"], [Vendor name])
51 AC_DEFINE_UNQUOTED(XVENDORNAMESHORT, ["$VENDOR_NAME_SHORT"], [Short vendor name])
52 AC_DEFINE_UNQUOTED(XORG_DATE, ["$RELEASE_DATE"], [Vendor release])
53Index: xorg-server/glx/glxdricommon.c
54===================================================================
55--- xorg-server.orig/glx/glxdricommon.c 2011-09-11 18:41:08.000000000 -0500
56+++ xorg-server/glx/glxdricommon.c 2011-09-11 18:46:45.296354364 -0500
57@@ -209,7 +209,7 @@
58 static const char dri_driver_path[] = DRI_DRIVER_PATH;
59
60 void *
61-glxProbeDriver(const char *driverName,
62+glxProbeDriver(const char *driverName, void **cookie,
63 void **coreExt, const char *coreName, int coreVersion,
64 void **renderExt, const char *renderName, int renderVersion)
65 {
66@@ -218,49 +218,60 @@
67 char filename[PATH_MAX];
68 const __DRIextension **extensions;
69 int from = X_ERROR;
70-
71- snprintf(filename, sizeof filename, "%s/%s_dri.so",
72- dri_driver_path, driverName);
73-
74- driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
75- if (driver == NULL) {
76- LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n",
77- filename, dlerror());
78- goto cleanup_failure;
79- }
80-
81- extensions = dlsym(driver, __DRI_DRIVER_EXTENSIONS);
82- if (extensions == NULL) {
83- LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n",
84- driverName, dlerror());
85- goto cleanup_failure;
86- }
87-
88- for (i = 0; extensions[i]; i++) {
89- if (strcmp(extensions[i]->name, coreName) == 0 &&
90- extensions[i]->version >= coreVersion) {
91- *coreExt = (void *)extensions[i];
92+ char *driDriverPath;
93+ const char *pathStart = *cookie ? (const char*)*cookie : dri_driver_path;
94+ const char *pathEnd = strchr(pathStart, ':');
95+
96+ for (; *pathStart; pathEnd = strchr(pathStart, ':')) {
97+ driDriverPath = strndup(pathStart,
98+ pathEnd ? pathEnd - pathStart : sizeof filename);
99+ snprintf(filename, sizeof filename, "%s/%s_dri.so",
100+ driDriverPath, driverName);
101+ free(driDriverPath);
102+ pathStart = pathEnd ? pathEnd + 1 : pathStart + strlen(pathStart);
103+ *cookie = (void *)pathStart;
104+
105+ LogMessage(X_INFO, "AIGLX: Trying DRI driver %s\n", filename);
106+
107+ driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
108+ if (driver == NULL) {
109+ LogMessage(X_INFO, "AIGLX: dlopen of %s failed (%s)\n",
110+ filename, dlerror());
111+ continue;
112 }
113
114- if (strcmp(extensions[i]->name, renderName) == 0 &&
115- extensions[i]->version >= renderVersion) {
116- *renderExt = (void *)extensions[i];
117+ extensions = dlsym(driver, __DRI_DRIVER_EXTENSIONS);
118+ if (extensions == NULL) {
119+ LogMessage(X_INFO, "AIGLX: %s exports no extensions (%s)\n",
120+ driverName, dlerror());
121+ dlclose(driver);
122+ continue;
123+ }
124+
125+ for (i = 0; extensions[i]; i++) {
126+ if (strcmp(extensions[i]->name, coreName) == 0 &&
127+ extensions[i]->version >= coreVersion) {
128+ *coreExt = (void *)extensions[i];
129+ }
130+
131+ if (strcmp(extensions[i]->name, renderName) == 0 &&
132+ extensions[i]->version >= renderVersion) {
133+ *renderExt = (void *)extensions[i];
134+ }
135 }
136- }
137
138- if (*coreExt == NULL || *renderExt == NULL) {
139- if (!strcmp(driverName, "nouveau"))
140- from = X_INFO;
141- LogMessage(from,
142- "AIGLX error: %s does not export required DRI extension\n",
143- driverName);
144- goto cleanup_failure;
145+ if (*coreExt == NULL || *renderExt == NULL) {
146+ if (!strcmp(driverName, "nouveau"))
147+ from = X_INFO;
148+ LogMessage(from,
149+ "AIGLX: %s does not export required DRI extension\n",
150+ driverName);
151+ *coreExt = *renderExt = NULL;
152+ dlclose(driver);
153+ continue;
154+ }
155+ return driver;
156 }
157- return driver;
158-
159-cleanup_failure:
160- if (driver)
161- dlclose(driver);
162 *coreExt = *renderExt = NULL;
163 return NULL;
164 }
165Index: xorg-server/glx/glxdri.c
166===================================================================
167--- xorg-server.orig/glx/glxdri.c 2011-09-11 18:41:08.000000000 -0500
168+++ xorg-server/glx/glxdri.c 2011-09-11 18:41:43.381346390 -0500
169@@ -968,6 +968,7 @@
170 size_t buffer_size;
171 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
172 const __DRIconfig **driConfigs;
173+ void *cookie = NULL;
174
175 if (!xf86LoaderCheckSymbol("DRIQueryDirectRenderingCapable") ||
176 !DRIQueryDirectRenderingCapable(pScreen, &isCapable) ||
177@@ -1042,7 +1043,7 @@
178 goto handle_error;
179 }
180
181- screen->driver = glxProbeDriver(driverName,
182+ screen->driver = glxProbeDriver(driverName, &cookie,
183 (void **)&screen->core,
184 __DRI_CORE, __DRI_CORE_VERSION,
185 (void **)&screen->legacy,
186Index: xorg-server/glx/glxdri2.c
187===================================================================
188--- xorg-server.orig/glx/glxdri2.c 2011-09-11 18:41:08.000000000 -0500
189+++ xorg-server/glx/glxdri2.c 2011-09-11 18:41:43.381346390 -0500
190@@ -689,6 +689,7 @@
191 size_t buffer_size;
192 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
193 const __DRIconfig **driConfigs;
194+ void *cookie = NULL;
195
196 screen = calloc(1, sizeof *screen);
197 if (screen == NULL)
198@@ -710,24 +711,24 @@
199
200 __glXInitExtensionEnableBits(screen->glx_enable_bits);
201
202- screen->driver = glxProbeDriver(driverName, (void **)&screen->core, __DRI_CORE, 1,
203- (void **)&screen->dri2, __DRI_DRI2, 1);
204- if (screen->driver == NULL) {
205- goto handle_error;
206- }
207-
208- screen->driScreen =
209- (*screen->dri2->createNewScreen)(pScreen->myNum,
210- screen->fd,
211- loader_extensions,
212- &driConfigs,
213- screen);
214-
215- if (screen->driScreen == NULL) {
216- LogMessage(X_ERROR,
217- "AIGLX error: Calling driver entry point failed\n");
218- goto handle_error;
219- }
220+ do {
221+ screen->driver = glxProbeDriver(driverName, &cookie,
222+ (void **)&screen->core, __DRI_CORE, 1,
223+ (void **)&screen->dri2, __DRI_DRI2, 1);
224+ if (screen->driver == NULL)
225+ goto handle_error;
226+
227+ screen->driScreen =
228+ (*screen->dri2->createNewScreen)(pScreen->myNum,
229+ screen->fd,
230+ loader_extensions,
231+ &driConfigs,
232+ screen);
233+ if (screen->driScreen == NULL) {
234+ LogMessage(X_INFO,
235+ "AIGLX: Calling driver entry point failed\n");
236+ }
237+ } while (screen->driScreen == NULL);
238
239 initializeExtensions(screen);
240
diff --git a/debian/patches/217_revert_bgnonevisitwindow.patch b/debian/patches/217_revert_bgnonevisitwindow.patch
deleted file mode 100644
index 5388925..0000000
--- a/debian/patches/217_revert_bgnonevisitwindow.patch
+++ /dev/null
@@ -1,43 +0,0 @@
1From: Ian Pilcher <arequipeno@gmail.com>
2Subject: Backout commit 6dd775f57d2f94f0ddaee324aeec33b9b66ed5bc
3
4Index: xorg-server/composite/compalloc.c
5===================================================================
6--- xorg-server.orig/composite/compalloc.c 2011-08-24 12:52:44.405647129 +0300
7+++ xorg-server/composite/compalloc.c 2011-08-24 12:56:49.805650625 +0300
8@@ -508,17 +508,6 @@
9 return Success;
10 }
11
12-static int
13-bgNoneVisitWindow(WindowPtr pWin, void *null)
14-{
15- if (pWin->backgroundState != BackgroundPixmap)
16- return WT_WALKCHILDREN;
17- if (pWin->background.pixmap != None)
18- return WT_WALKCHILDREN;
19-
20- return WT_STOPWALKING;
21-}
22-
23 static PixmapPtr
24 compNewPixmap (WindowPtr pWin, int x, int y, int w, int h, Bool map)
25 {
26@@ -540,17 +529,6 @@
27 return pPixmap;
28
29 /*
30- * If there's no bg=None in the tree, we're done.
31- *
32- * We could optimize this more by collection the regions of all the
33- * bg=None subwindows and feeding that in as the clip for the
34- * CopyArea below, but since window trees are shallow these days it
35- * might not be worth the effort.
36- */
37- if (TraverseTree(pWin, bgNoneVisitWindow, NULL) == WT_NOMATCH)
38- return pPixmap;
39-
40- /*
41 * Copy bits from the parent into the new pixmap so that it will
42 * have "reasonable" contents in case for background None areas.
43 */
diff --git a/debian/patches/219_fedora-pointer-barriers.diff b/debian/patches/219_fedora-pointer-barriers.diff
deleted file mode 100644
index 8ec5ab0..0000000
--- a/debian/patches/219_fedora-pointer-barriers.diff
+++ /dev/null
@@ -1,1020 +0,0 @@
1From 14f1112bec18ccece8e732fe6c200a56546230c7 Mon Sep 17 00:00:00 2001
2From: Adam Jackson <ajax@redhat.com>
3Date: Thu, 17 Mar 2011 13:56:17 -0400
4Subject: [PATCH] CRTC confine and pointer barriers
5
6---
7 dix/events.c | 7 +
8 dix/getevents.c | 12 +-
9 include/dix.h | 1 +
10 include/protocol-versions.h | 2 +-
11 mi/mipointer.c | 16 ++-
12 mi/mipointer.h | 6 +
13 randr/randr.c | 2 +
14 randr/randrstr.h | 4 +
15 randr/rrcrtc.c | 155 ++++++++++++++++
16 xfixes/cursor.c | 399 ++++++++++++++++++++++++++++++++++++++++++-
17 xfixes/xfixes.c | 24 ++-
18 xfixes/xfixes.h | 17 ++
19 xfixes/xfixesint.h | 16 ++
20 14 files changed, 658 insertions(+), 16 deletions(-)
21
22Index: xorg-server/dix/events.c
23===================================================================
24--- xorg-server.orig/dix/events.c 2011-08-24 12:52:44.325647127 +0300
25+++ xorg-server/dix/events.c 2011-08-24 12:57:24.685651121 +0300
26@@ -328,6 +328,13 @@
27 return dev->type == MASTER_POINTER || dev->type == MASTER_KEYBOARD;
28 }
29
30+Bool
31+IsFloating(DeviceIntPtr dev)
32+{
33+ return GetMaster(dev, MASTER_KEYBOARD) == NULL;
34+}
35+
36+
37 /**
38 * Max event opcode.
39 */
40Index: xorg-server/dix/getevents.c
41===================================================================
42--- xorg-server.orig/dix/getevents.c 2011-08-24 12:52:44.315647128 +0300
43+++ xorg-server/dix/getevents.c 2011-08-24 12:57:20.625651063 +0300
44@@ -816,7 +816,11 @@
45 * miPointerSetPosition() and then scale back into device coordinates (if
46 * needed). miPSP will change x/y if the screen was crossed.
47 *
48+ * The coordinates provided are always absolute. The parameter mode whether
49+ * it was relative or absolute movement that landed us at those coordinates.
50+ *
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@@ -828,7 +832,8 @@
57 * @param screeny_frac Fractional part of screen y coordinate, as above.
58 */
59 static void
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)
64 {
65 int old_screenx, old_screeny;
66@@ -867,7 +872,7 @@
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);
72
73 if (dev->u.master) {
74 dev->u.master->last.valuators[0] = *screenx;
75@@ -1202,7 +1207,8 @@
76 if ((flags & POINTER_NORAW) == 0)
77 set_raw_valuators(raw, &mask, raw->valuators.data);
78
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);
83
84 /* Update the valuators with the true value sent to the client*/
85Index: xorg-server/include/dix.h
86===================================================================
87--- xorg-server.orig/include/dix.h 2011-08-24 12:52:44.355647127 +0300
88+++ xorg-server/include/dix.h 2011-08-24 12:57:24.695651123 +0300
89@@ -570,6 +570,7 @@
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);
94
95 extern _X_HIDDEN void CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master);
96 extern _X_HIDDEN int CorePointerProc(DeviceIntPtr dev, int what);
97Index: xorg-server/include/protocol-versions.h
98===================================================================
99--- xorg-server.orig/include/protocol-versions.h 2011-08-24 12:52:44.365647129 +0300
100+++ xorg-server/include/protocol-versions.h 2011-08-24 12:57:20.735651065 +0300
101@@ -126,7 +126,7 @@
102 #define SERVER_XF86VIDMODE_MINOR_VERSION 2
103
104 /* Fixes */
105-#define SERVER_XFIXES_MAJOR_VERSION 4
106+#define SERVER_XFIXES_MAJOR_VERSION 5
107 #define SERVER_XFIXES_MINOR_VERSION 0
108
109 /* X Input */
110Index: xorg-server/mi/mipointer.c
111===================================================================
112--- xorg-server.orig/mi/mipointer.c 2011-08-24 12:56:49.645650622 +0300
113+++ xorg-server/mi/mipointer.c 2011-08-24 12:56:49.825650624 +0300
114@@ -229,6 +229,10 @@
115 SetupScreen (pScreen);
116
117 GenerateEvent = generateEvent;
118+
119+ if (pScreen->ConstrainCursorHarder)
120+ pScreen->ConstrainCursorHarder(pDev, pScreen, Absolute, &x, &y);
121+
122 /* device dependent - must pend signal and call miPointerWarpCursor */
123 (*pScreenPriv->screenFuncs->WarpCursor) (pDev, pScreen, x, y);
124 if (!generateEvent)
125@@ -488,7 +492,7 @@
126 }
127
128 void
129-miPointerSetPosition(DeviceIntPtr pDev, int *x, int *y)
130+_miPointerSetPosition(DeviceIntPtr pDev, int mode, int *x, int *y)
131 {
132 miPointerScreenPtr pScreenPriv;
133 ScreenPtr pScreen;
134@@ -532,6 +536,9 @@
135 if (*y >= pPointer->limits.y2)
136 *y = pPointer->limits.y2 - 1;
137
138+ if (pScreen->ConstrainCursorHarder)
139+ pScreen->ConstrainCursorHarder(pDev, pScreen, mode, x, y);
140+
141 if (pPointer->x == *x && pPointer->y == *y &&
142 pPointer->pScreen == pScreen)
143 return;
144@@ -539,6 +546,13 @@
145 miPointerMoveNoEvent(pDev, pScreen, *x, *y);
146 }
147
148+/* ABI hack */
149+void
150+miPointerSetPosition(DeviceIntPtr pDev, int *x, int *y)
151+{
152+ _miPointerSetPosition(pDev, Absolute, x, y);
153+}
154+
155 void
156 miPointerGetPosition(DeviceIntPtr pDev, int *x, int *y)
157 {
158Index: xorg-server/mi/mipointer.h
159===================================================================
160--- xorg-server.orig/mi/mipointer.h 2011-08-24 12:52:44.375647128 +0300
161+++ xorg-server/mi/mipointer.h 2011-08-24 12:56:49.825650624 +0300
162@@ -131,6 +131,12 @@
163
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(
167+ DeviceIntPtr pDev,
168+ int mode,
169+ int *x,
170+ int *y);
171+
172 extern _X_EXPORT void miPointerSetPosition(
173 DeviceIntPtr pDev,
174 int *x,
175Index: xorg-server/randr/randr.c
176===================================================================
177--- xorg-server.orig/randr/randr.c 2011-08-24 12:56:49.745650625 +0300
178+++ xorg-server/randr/randr.c 2011-08-24 12:56:49.825650624 +0300
179@@ -270,6 +270,8 @@
180
181 wrap (pScrPriv, pScreen, CloseScreen, RRCloseScreen);
182
183+ pScreen->ConstrainCursorHarder = RRConstrainCursorHarder;
184+
185 pScrPriv->numOutputs = 0;
186 pScrPriv->outputs = NULL;
187 pScrPriv->numCrtcs = 0;
188Index: xorg-server/randr/randrstr.h
189===================================================================
190--- xorg-server.orig/randr/randrstr.h 2011-08-24 12:52:44.305647126 +0300
191+++ xorg-server/randr/randrstr.h 2011-08-24 12:56:49.825650624 +0300
192@@ -297,6 +297,7 @@
193 int rate;
194 int size;
195 #endif
196+ Bool discontiguous;
197 } rrScrPrivRec, *rrScrPrivPtr;
198
199 extern _X_EXPORT DevPrivateKeyRec rrPrivKeyRec;
200@@ -700,6 +701,9 @@
201 int
202 ProcRRSetPanning (ClientPtr client);
203
204+void
205+RRConstrainCursorHarder (DeviceIntPtr, ScreenPtr, int, int *, int *);
206+
207 /* rrdispatch.c */
208 extern _X_EXPORT Bool
209 RRClientKnowsRates (ClientPtr pClient);
210Index: xorg-server/randr/rrcrtc.c
211===================================================================
212--- xorg-server.orig/randr/rrcrtc.c 2011-08-24 12:52:44.285647124 +0300
213+++ xorg-server/randr/rrcrtc.c 2011-08-24 12:56:49.825650624 +0300
214@@ -1,5 +1,6 @@
215 /*
216 * Copyright © 2006 Keith Packard
217+ * Copyright 2010 Red Hat, Inc
218 *
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
221@@ -22,6 +23,7 @@
222
223 #include "randrstr.h"
224 #include "swaprep.h"
225+#include "mipointer.h"
226
227 RESTYPE RRCrtcType;
228
229@@ -292,6 +294,92 @@
230 return FALSE;
231 }
232
233+static void
234+crtc_bounds(RRCrtcPtr crtc, int *left, int *right, int *top, int *bottom)
235+{
236+ *left = crtc->x;
237+ *top = crtc->y;
238+
239+ switch (crtc->rotation) {
240+ case RR_Rotate_0:
241+ case RR_Rotate_180:
242+ default:
243+ *right = crtc->x + crtc->mode->mode.width;
244+ *bottom = crtc->y + crtc->mode->mode.height;
245+ return;
246+ case RR_Rotate_90:
247+ case RR_Rotate_270:
248+ *right = crtc->x + crtc->mode->mode.height;
249+ *bottom = crtc->y + crtc->mode->mode.width;
250+ return;
251+ }
252+}
253+
254+/* overlapping counts as adjacent */
255+static Bool
256+crtcs_adjacent(const RRCrtcPtr a, const RRCrtcPtr b)
257+{
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 */
262+
263+ crtc_bounds(a, &al, &ar, &at, &ab);
264+ crtc_bounds(b, &bl, &br, &bt, &bb);
265+
266+ cl = max(al, bl);
267+ cr = min(ar, br);
268+ ct = max(at, bt);
269+ cb = min(ab, bb);
270+
271+ return (cl <= cr) && (ct <= cb);
272+}
273+
274+/* Depth-first search and mark all CRTCs reachable from cur */
275+static void
276+mark_crtcs (rrScrPrivPtr pScrPriv, int *reachable, int cur)
277+{
278+ int i;
279+ reachable[cur] = TRUE;
280+ for (i = 0; i < pScrPriv->numCrtcs; ++i) {
281+ if (reachable[i] || !pScrPriv->crtcs[i]->mode)
282+ continue;
283+ if (crtcs_adjacent(pScrPriv->crtcs[cur], pScrPriv->crtcs[i]))
284+ mark_crtcs(pScrPriv, reachable, i);
285+ }
286+}
287+
288+static void
289+RRComputeContiguity (ScreenPtr pScreen)
290+{
291+ rrScrPriv(pScreen);
292+ Bool discontiguous = TRUE;
293+ int i, n = pScrPriv->numCrtcs;
294+
295+ int *reachable = calloc(n, sizeof(int));
296+ if (!reachable)
297+ goto out;
298+
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);
303+ break;
304+ }
305+ }
306+
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])
310+ goto out;
311+
312+ discontiguous = FALSE;
313+
314+out:
315+ free(reachable);
316+ pScrPriv->discontiguous = discontiguous;
317+}
318+
319 /*
320 * Request that the Crtc be reconfigured
321 */
322@@ -306,6 +394,7 @@
323 {
324 ScreenPtr pScreen = crtc->pScreen;
325 Bool ret = FALSE;
326+ Bool recompute = TRUE;
327 rrScrPriv(pScreen);
328
329 /* See if nothing changed */
330@@ -318,6 +407,7 @@
331 !RRCrtcPendingProperties (crtc) &&
332 !RRCrtcPendingTransform (crtc))
333 {
334+ recompute = FALSE;
335 ret = TRUE;
336 }
337 else
338@@ -381,6 +471,10 @@
339 RRPostPendingProperties (outputs[o]);
340 }
341 }
342+
343+ if (recompute)
344+ RRComputeContiguity(pScreen);
345+
346 return ret;
347 }
348
349@@ -1349,3 +1443,64 @@
350 free(reply);
351 return Success;
352 }
353+
354+void
355+RRConstrainCursorHarder(DeviceIntPtr pDev, ScreenPtr pScreen, int mode, int *x, int *y)
356+{
357+ rrScrPriv (pScreen);
358+ int i;
359+
360+ /* intentional dead space -> let it float */
361+ if (pScrPriv->discontiguous)
362+ return;
363+
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];
367+
368+ int left, right, top, bottom;
369+
370+ if (!crtc->mode)
371+ continue;
372+
373+ crtc_bounds(crtc, &left, &right, &top, &bottom);
374+
375+ if ((*x >= left) && (*x <= right) && (*y >= top) && (*y <= bottom))
376+ return;
377+ }
378+
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];
382+ int nx, ny;
383+ int left, right, top, bottom;
384+
385+ if (!crtc->mode)
386+ continue;
387+
388+ crtc_bounds(crtc, &left, &right, &top, &bottom);
389+ miPointerGetPosition(pDev, &nx, &ny);
390+
391+ if ((nx >= left) && (nx <= right) && (ny >= top) && (ny <= bottom)) {
392+ if ((*x <= left) || (*x >= right)) {
393+ int dx = *x - nx;
394+
395+ if (dx > 0)
396+ *x = right;
397+ else if (dx < 0)
398+ *x = left;
399+ }
400+
401+ if ((*y <= top) || (*y >= bottom)) {
402+ int dy = *y - ny;
403+
404+ if (dy > 0)
405+ *y = bottom;
406+ else if (dy < 0)
407+ *y = top;
408+ }
409+
410+ return;
411+ }
412+ }
413+}
414Index: xorg-server/xfixes/cursor.c
415===================================================================
416--- xorg-server.orig/xfixes/cursor.c 2011-08-24 12:52:44.345647126 +0300
417+++ xorg-server/xfixes/cursor.c 2011-08-24 12:56:49.825650624 +0300
418@@ -1,5 +1,6 @@
419 /*
420 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
421+ * Copyright 2010 Red Hat, Inc.
422 *
423 * Permission is hereby granted, free of charge, to any person obtaining a
424 * copy of this software and associated documentation files (the "Software"),
425@@ -50,13 +51,16 @@
426 #include "cursorstr.h"
427 #include "dixevents.h"
428 #include "servermd.h"
429+#include "mipointer.h"
430 #include "inputstr.h"
431 #include "windowstr.h"
432 #include "xace.h"
433+#include "list.h"
434
435 static RESTYPE CursorClientType;
436 static RESTYPE CursorHideCountType;
437 static RESTYPE CursorWindowType;
438+RESTYPE PointerBarrierType;
439 static CursorPtr CursorCurrent[MAXDEVICES];
440
441 static DevPrivateKeyRec CursorScreenPrivateKeyRec;
442@@ -107,6 +111,14 @@
443 XID resource;
444 } CursorHideCountRec;
445
446+typedef struct PointerBarrierClient *PointerBarrierClientPtr;
447+
448+struct PointerBarrierClient {
449+ ScreenPtr screen;
450+ struct PointerBarrier barrier;
451+ struct list entry;
452+};
453+
454 /*
455 * Wrap DisplayCursor to catch cursor change events
456 */
457@@ -114,7 +126,9 @@
458 typedef struct _CursorScreen {
459 DisplayCursorProcPtr DisplayCursor;
460 CloseScreenProcPtr CloseScreen;
461+ ConstrainCursorHarderProcPtr ConstrainCursorHarder;
462 CursorHideCountPtr pCursorHideCounts;
463+ struct list barriers;
464 } CursorScreenRec, *CursorScreenPtr;
465
466 #define GetCursorScreen(s) ((CursorScreenPtr)dixLookupPrivate(&(s)->devPrivates, CursorScreenPrivateKey))
467@@ -184,9 +198,11 @@
468 Bool ret;
469 CloseScreenProcPtr close_proc;
470 DisplayCursorProcPtr display_proc;
471+ ConstrainCursorHarderProcPtr constrain_proc;
472
473 Unwrap (cs, pScreen, CloseScreen, close_proc);
474 Unwrap (cs, pScreen, DisplayCursor, display_proc);
475+ Unwrap (cs, pScreen, ConstrainCursorHarder, constrain_proc);
476 deleteCursorHideCountsForScreen(pScreen);
477 ret = (*pScreen->CloseScreen) (index, pScreen);
478 free(cs);
479@@ -1029,6 +1045,382 @@
480 return 1;
481 }
482
483+static BOOL
484+barrier_is_horizontal(const struct PointerBarrier *barrier)
485+{
486+ return barrier->y1 == barrier->y2;
487+}
488+
489+static BOOL
490+barrier_is_vertical(const struct PointerBarrier *barrier)
491+{
492+ return barrier->x1 == barrier->x2;
493+}
494+
495+/**
496+ * @return The set of barrier movement directions the movement vector
497+ * x1/y1 → x2/y2 represents.
498+ */
499+int
500+barrier_get_direction(int x1, int y1, int x2, int y2)
501+{
502+ int direction = 0;
503+
504+ /* which way are we trying to go */
505+ if (x2 > x1)
506+ direction |= BarrierPositiveX;
507+ if (x2 < x1)
508+ direction |= BarrierNegativeX;
509+ if (y2 > y1)
510+ direction |= BarrierPositiveY;
511+ if (y2 < y1)
512+ direction |= BarrierNegativeY;
513+
514+ return direction;
515+}
516+
517+/**
518+ * Test if the barrier may block movement in the direction defined by
519+ * x1/y1 → x2/y2. This function only tests whether the directions could be
520+ * blocked, it does not test if the barrier actually blocks the movement.
521+ *
522+ * @return TRUE if the barrier blocks the direction of movement or FALSE
523+ * otherwise.
524+ */
525+BOOL
526+barrier_is_blocking_direction(const struct PointerBarrier *barrier, int direction)
527+{
528+ /* Barriers define which way is ok, not which way is blocking */
529+ return (barrier->directions & direction) != direction;
530+}
531+
532+/**
533+ * Test if the movement vector x1/y1 → x2/y2 is intersecting with the
534+ * barrier. A movement vector with the startpoint or endpoint adjacent to
535+ * the barrier itself counts as intersecting.
536+ *
537+ * @param x1 X start coordinate of movement vector
538+ * @param y1 Y start coordinate of movement vector
539+ * @param x2 X end coordinate of movement vector
540+ * @param y2 Y end coordinate of movement vector
541+ * @param[out] distance The distance between the start point and the
542+ * intersection with the barrier (if applicable).
543+ * @return TRUE if the barrier intersects with the given vector
544+ */
545+BOOL
546+barrier_is_blocking(const struct PointerBarrier *barrier,
547+ int x1, int y1, int x2, int y2,
548+ double *distance)
549+{
550+ BOOL rc = FALSE;
551+ float ua, ub, ud;
552+ int dir = barrier_get_direction(x1, y1, x2, y2);
553+
554+ /* Algorithm below doesn't handle edge cases well, hence the extra
555+ * checks. */
556+ if (barrier_is_vertical(barrier)) {
557+ /* handle immediate barrier adjacency, moving away */
558+ if (dir & BarrierPositiveX && x1 == barrier->x1)
559+ return FALSE;
560+ if (dir & BarrierNegativeX && x1 == (barrier->x1 - 1))
561+ return FALSE;
562+ /* startpoint adjacent to barrier, moving towards -> block */
563+ if (x1 == barrier->x1 && y1 >= barrier->y1 && y1 <= barrier->y2) {
564+ *distance = 0;
565+ return TRUE;
566+ }
567+ } else {
568+ /* handle immediate barrier adjacency, moving away */
569+ if (dir & BarrierPositiveY && y1 == barrier->y1)
570+ return FALSE;
571+ if (dir & BarrierNegativeY && y1 == (barrier->y1 - 1))
572+ return FALSE;
573+ /* startpoint adjacent to barrier, moving towards -> block */
574+ if (y1 == barrier->y1 && x1 >= barrier->x1 && x1 <= barrier->x2) {
575+ *distance = 0;
576+ return TRUE;
577+ }
578+ }
579+
580+ /* not an edge case, compute distance */
581+ ua = 0;
582+ ud = (barrier->y2 - barrier->y1) * (x2 - x1) - (barrier->x2 - barrier->x1) * (y2 - y1);
583+ if (ud != 0) {
584+ ua = ((barrier->x2 - barrier->x1) * (y1 - barrier->y1) -
585+ (barrier->y2 - barrier->y1) * (x1 - barrier->x1)) / ud;
586+ ub = ((x2 - x1) * (y1 - barrier->y1) -
587+ (y2 - y1) * (x1 - barrier->x1)) / ud;
588+ if (ua < 0 || ua > 1 || ub < 0 || ub > 1)
589+ ua = 0;
590+ }
591+
592+ if (ua > 0 && ua <= 1)
593+ {
594+ double ix = barrier->x1 + ua * (barrier->x2 - barrier->x1);
595+ double iy = barrier->y1 + ua * (barrier->y2 - barrier->y1);
596+
597+ *distance = sqrt(pow(x1 - ix, 2) + pow(y1 - iy, 2));
598+ rc = TRUE;
599+ }
600+
601+ return rc;
602+}
603+
604+/**
605+ * Find the nearest barrier that is blocking movement from x1/y1 to x2/y2.
606+ *
607+ * @param dir Only barriers blocking movement in direction dir are checked
608+ * @param x1 X start coordinate of movement vector
609+ * @param y1 Y start coordinate of movement vector
610+ * @param x2 X end coordinate of movement vector
611+ * @param y2 Y end coordinate of movement vector
612+ * @return The barrier nearest to the movement origin that blocks this movement.
613+ */
614+static struct PointerBarrier*
615+barrier_find_nearest(CursorScreenPtr cs, int dir,
616+ int x1, int y1, int x2, int y2)
617+{
618+ struct PointerBarrierClient *c;
619+ struct PointerBarrier *nearest = NULL;
620+ double min_distance = INT_MAX; /* can't get higher than that in X anyway */
621+
622+ list_for_each_entry(c, &cs->barriers, entry) {
623+ struct PointerBarrier *b = &c->barrier;
624+ double distance;
625+
626+ if (!barrier_is_blocking_direction(b, dir))
627+ continue;
628+
629+ if (barrier_is_blocking(b, x1, y1, x2, y2, &distance))
630+ {
631+ if (min_distance > distance)
632+ {
633+ min_distance = distance;
634+ nearest = b;
635+ }
636+ }
637+ }
638+
639+ return nearest;
640+}
641+
642+/**
643+ * Clamp to the given barrier given the movement direction specified in dir.
644+ *
645+ * @param barrier The barrier to clamp to
646+ * @param dir The movement direction
647+ * @param[out] x The clamped x coordinate.
648+ * @param[out] y The clamped x coordinate.
649+ */
650+void
651+barrier_clamp_to_barrier(struct PointerBarrier *barrier, int dir, int *x, int *y)
652+{
653+ if (barrier_is_vertical(barrier))
654+ {
655+ if ((dir & BarrierNegativeX) & ~barrier->directions)
656+ *x = barrier->x1;
657+ if ((dir & BarrierPositiveX) & ~barrier->directions)
658+ *x = barrier->x1 - 1;
659+ }
660+ if (barrier_is_horizontal(barrier))
661+ {
662+ if ((dir & BarrierNegativeY) & ~barrier->directions)
663+ *y = barrier->y1;
664+ if ((dir & BarrierPositiveY) & ~barrier->directions)
665+ *y = barrier->y1 - 1;
666+ }
667+}
668+
669+static void
670+CursorConstrainCursorHarder(DeviceIntPtr dev, ScreenPtr screen, int mode, int *x, int *y)
671+{
672+ CursorScreenPtr cs = GetCursorScreen(screen);
673+
674+ if (!list_is_empty(&cs->barriers) && !IsFloating(dev) && mode == Relative) {
675+ int ox, oy;
676+ int dir;
677+ struct PointerBarrier *nearest = NULL;
678+
679+ /* where are we coming from */
680+ miPointerGetPosition(dev, &ox, &oy);
681+
682+ /* How this works:
683+ * Given the origin and the movement vector, get the nearest barrier
684+ * to the origin that is blocking the movement.
685+ * Clamp to that barrier.
686+ * Then, check from the clamped intersection to the original
687+ * destination, again finding the nearest barrier and clamping.
688+ */
689+ dir = barrier_get_direction(ox, oy, *x, *y);
690+
691+ nearest = barrier_find_nearest(cs, dir, ox, oy, *x, *y);
692+ if (nearest) {
693+ barrier_clamp_to_barrier(nearest, dir, x, y);
694+
695+ if (barrier_is_vertical(nearest)) {
696+ dir &= ~(BarrierNegativeX | BarrierPositiveX);
697+ ox = *x;
698+ } else if (barrier_is_horizontal(nearest)) {
699+ dir &= ~(BarrierNegativeY | BarrierPositiveY);
700+ oy = *y;
701+ }
702+
703+ nearest = barrier_find_nearest(cs, dir, ox, oy, *x, *y);
704+ if (nearest) {
705+ barrier_clamp_to_barrier(nearest, dir, x, y);
706+ }
707+ }
708+ }
709+
710+ if (cs->ConstrainCursorHarder) {
711+ screen->ConstrainCursorHarder = cs->ConstrainCursorHarder;
712+ screen->ConstrainCursorHarder(dev, screen, mode, x, y);
713+ screen->ConstrainCursorHarder = CursorConstrainCursorHarder;
714+ }
715+}
716+
717+static struct PointerBarrierClient *
718+CreatePointerBarrierClient(ScreenPtr screen, ClientPtr client,
719+ xXFixesCreatePointerBarrierReq *stuff)
720+{
721+ CursorScreenPtr cs = GetCursorScreen(screen);
722+ struct PointerBarrierClient *ret = malloc(sizeof(*ret));
723+
724+ if (ret) {
725+ ret->screen = screen;
726+ ret->barrier.x1 = min(stuff->x1, stuff->x2);
727+ ret->barrier.x2 = max(stuff->x1, stuff->x2);
728+ ret->barrier.y1 = min(stuff->y1, stuff->y2);
729+ ret->barrier.y2 = max(stuff->y1, stuff->y2);
730+ ret->barrier.directions = stuff->directions & 0x0f;
731+ if (barrier_is_horizontal(&ret->barrier))
732+ ret->barrier.directions &= ~(BarrierPositiveX | BarrierNegativeX);
733+ if (barrier_is_vertical(&ret->barrier))
734+ ret->barrier.directions &= ~(BarrierPositiveY | BarrierNegativeY);
735+ list_add(&ret->entry, &cs->barriers);
736+ }
737+
738+ return ret;
739+}
740+
741+int
742+ProcXFixesCreatePointerBarrier (ClientPtr client)
743+{
744+ int err;
745+ WindowPtr pWin;
746+ struct PointerBarrierClient *barrier;
747+ struct PointerBarrier b;
748+ REQUEST (xXFixesCreatePointerBarrierReq);
749+
750+ REQUEST_SIZE_MATCH(xXFixesCreatePointerBarrierReq);
751+ LEGAL_NEW_RESOURCE(stuff->barrier, client);
752+
753+ err = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
754+ if (err != Success) {
755+ client->errorValue = stuff->window;
756+ return err;
757+ }
758+
759+ /* This sure does need fixing. */
760+ if (stuff->num_devices)
761+ return BadImplementation;
762+
763+ b.x1 = stuff->x1;
764+ b.x2 = stuff->x2;
765+ b.y1 = stuff->y1;
766+ b.y2 = stuff->y2;
767+
768+ if (!barrier_is_horizontal(&b) && !barrier_is_vertical(&b))
769+ return BadValue;
770+
771+ /* no 0-sized barriers */
772+ if (barrier_is_horizontal(&b) && barrier_is_vertical(&b))
773+ return BadValue;
774+
775+ if (!(barrier = CreatePointerBarrierClient(pWin->drawable.pScreen,
776+ client, stuff)))
777+ return BadAlloc;
778+
779+ if (!AddResource(stuff->barrier, PointerBarrierType, &barrier->barrier))
780+ return BadAlloc;
781+
782+ return Success;
783+}
784+
785+int
786+SProcXFixesCreatePointerBarrier (ClientPtr client)
787+{
788+ int n;
789+ REQUEST(xXFixesCreatePointerBarrierReq);
790+
791+ swaps(&stuff->length, n);
792+ REQUEST_SIZE_MATCH(xXFixesCreatePointerBarrierReq);
793+ swapl(&stuff->barrier, n);
794+ swapl(&stuff->window, n);
795+ swaps(&stuff->x1, n);
796+ swaps(&stuff->y1, n);
797+ swaps(&stuff->x2, n);
798+ swaps(&stuff->y2, n);
799+ swapl(&stuff->directions, n);
800+ return ProcXFixesVector[stuff->xfixesReqType](client);
801+}
802+
803+static int
804+CursorFreeBarrier(void *data, XID id)
805+{
806+ struct PointerBarrierClient *b = NULL, *barrier;
807+ ScreenPtr screen;
808+ CursorScreenPtr cs;
809+
810+ barrier = container_of(data, struct PointerBarrierClient, barrier);
811+ screen = barrier->screen;
812+ cs = GetCursorScreen(screen);
813+
814+ /* find and unlink from the screen private */
815+ list_for_each_entry(b, &cs->barriers, entry) {
816+ if (b == barrier) {
817+ list_del(&b->entry);
818+ break;
819+ }
820+ }
821+
822+ free(barrier);
823+ return Success;
824+}
825+
826+int
827+ProcXFixesDestroyPointerBarrier (ClientPtr client)
828+{
829+ int err;
830+ void *barrier;
831+ REQUEST (xXFixesDestroyPointerBarrierReq);
832+
833+ REQUEST_SIZE_MATCH(xXFixesDestroyPointerBarrierReq);
834+
835+ err = dixLookupResourceByType((void **)&barrier, stuff->barrier,
836+ PointerBarrierType, client,
837+ DixDestroyAccess);
838+ if (err != Success) {
839+ client->errorValue = stuff->barrier;
840+ return err;
841+ }
842+
843+ FreeResource(stuff->barrier, RT_NONE);
844+ return Success;
845+}
846+
847+int
848+SProcXFixesDestroyPointerBarrier (ClientPtr client)
849+{
850+ int n;
851+ REQUEST(xXFixesDestroyPointerBarrierReq);
852+
853+ swaps(&stuff->length, n);
854+ REQUEST_SIZE_MATCH(xXFixesDestroyPointerBarrierReq);
855+ swapl(&stuff->barrier, n);
856+ return ProcXFixesVector[stuff->xfixesReqType](client);
857+}
858+
859 Bool
860 XFixesCursorInit (void)
861 {
862@@ -1048,8 +1440,10 @@
863 cs = (CursorScreenPtr) calloc(1, sizeof (CursorScreenRec));
864 if (!cs)
865 return FALSE;
866+ list_init(&cs->barriers);
867 Wrap (cs, pScreen, CloseScreen, CursorCloseScreen);
868 Wrap (cs, pScreen, DisplayCursor, CursorDisplayCursor);
869+ Wrap (cs, pScreen, ConstrainCursorHarder, CursorConstrainCursorHarder);
870 cs->pCursorHideCounts = NULL;
871 SetCursorScreen (pScreen, cs);
872 }
873@@ -1059,7 +1453,10 @@
874 "XFixesCursorHideCount");
875 CursorWindowType = CreateNewResourceType(CursorFreeWindow,
876 "XFixesCursorWindow");
877+ PointerBarrierType = CreateNewResourceType(CursorFreeBarrier,
878+ "XFixesPointerBarrier");
879
880- return CursorClientType && CursorHideCountType && CursorWindowType;
881+ return CursorClientType && CursorHideCountType && CursorWindowType &&
882+ PointerBarrierType;
883 }
884
885Index: xorg-server/xfixes/xfixes.c
886===================================================================
887--- xorg-server.orig/xfixes/xfixes.c 2011-08-24 12:52:44.355647127 +0300
888+++ xorg-server/xfixes/xfixes.c 2011-08-24 12:56:49.825650624 +0300
889@@ -1,5 +1,6 @@
890 /*
891 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
892+ * Copyright 2010 Red Hat, Inc.
893 *
894 * Permission is hereby granted, free of charge, to any person obtaining a
895 * copy of this software and associated documentation files (the "Software"),
896@@ -47,10 +48,6 @@
897
898 #include "xfixesint.h"
899 #include "protocol-versions.h"
900-/*
901- * Must use these instead of the constants from xfixeswire.h. They advertise
902- * what we implement, not what the protocol headers define.
903- */
904
905 static unsigned char XFixesReqCode;
906 int XFixesEventBase;
907@@ -97,11 +94,12 @@
908
909 /* Major version controls available requests */
910 static const int version_requests[] = {
911- X_XFixesQueryVersion, /* before client sends QueryVersion */
912- X_XFixesGetCursorImage, /* Version 1 */
913- X_XFixesChangeCursorByName, /* Version 2 */
914- X_XFixesExpandRegion, /* Version 3 */
915- X_XFixesShowCursor, /* Version 4 */
916+ X_XFixesQueryVersion, /* before client sends QueryVersion */
917+ X_XFixesGetCursorImage, /* Version 1 */
918+ X_XFixesChangeCursorByName, /* Version 2 */
919+ X_XFixesExpandRegion, /* Version 3 */
920+ X_XFixesShowCursor, /* Version 4 */
921+ X_XFixesDestroyPointerBarrier, /* Version 5 */
922 };
923
924 #define NUM_VERSION_REQUESTS (sizeof (version_requests) / sizeof (version_requests[0]))
925@@ -142,6 +140,9 @@
926 /*************** Version 4 ****************/
927 ProcXFixesHideCursor,
928 ProcXFixesShowCursor,
929+/*************** Version 5 ****************/
930+ ProcXFixesCreatePointerBarrier,
931+ ProcXFixesDestroyPointerBarrier,
932 };
933
934 static int
935@@ -205,6 +206,9 @@
936 /*************** Version 4 ****************/
937 SProcXFixesHideCursor,
938 SProcXFixesShowCursor,
939+/*************** Version 5 ****************/
940+ SProcXFixesCreatePointerBarrier,
941+ SProcXFixesDestroyPointerBarrier,
942 };
943
944 static int
945@@ -260,6 +264,8 @@
946 EventSwapVector[XFixesEventBase + XFixesCursorNotify] =
947 (EventSwapPtr) SXFixesCursorNotifyEvent;
948 SetResourceTypeErrorValue(RegionResType, XFixesErrorBase + BadRegion);
949+ SetResourceTypeErrorValue(PointerBarrierType,
950+ XFixesErrorBase + BadBarrier);
951 }
952 }
953
954Index: xorg-server/xfixes/xfixes.h
955===================================================================
956--- xorg-server.orig/xfixes/xfixes.h 2011-08-24 12:52:44.335647125 +0300
957+++ xorg-server/xfixes/xfixes.h 2011-08-24 12:56:49.825650624 +0300
958@@ -30,6 +30,7 @@
959 #include "resource.h"
960
961 extern _X_EXPORT RESTYPE RegionResType;
962+extern _X_EXPORT RESTYPE PointerBarrierType;
963 extern _X_EXPORT int XFixesErrorBase;
964
965 #define VERIFY_REGION(pRegion, rid, client, mode) \
966@@ -51,5 +52,21 @@
967 extern _X_EXPORT RegionPtr
968 XFixesRegionCopy (RegionPtr pRegion);
969
970+struct PointerBarrier {
971+ CARD16 x1, x2, y1, y2;
972+ CARD32 directions;
973+};
974+
975+
976+extern int
977+barrier_get_direction(int, int, int, int);
978+extern BOOL
979+barrier_is_blocking(const struct PointerBarrier*, int, int, int, int, double*);
980+extern BOOL
981+barrier_is_blocking_direction(const struct PointerBarrier*, int);
982+extern void
983+barrier_clamp_to_barrier(struct PointerBarrier *barrier, int dir, int *x, int *y);
984+
985+
986
987 #endif /* _XFIXES_H_ */
988Index: xorg-server/xfixes/xfixesint.h
989===================================================================
990--- xorg-server.orig/xfixes/xfixesint.h 2011-08-24 12:52:44.345647126 +0300
991+++ xorg-server/xfixes/xfixesint.h 2011-08-24 12:56:49.825650624 +0300
992@@ -1,5 +1,6 @@
993 /*
994 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
995+ * Copyright 2010 Red Hat, Inc.
996 *
997 * Permission is hereby granted, free of charge, to any person obtaining a
998 * copy of this software and associated documentation files (the "Software"),
999@@ -278,6 +279,21 @@
1000 int
1001 SProcXFixesShowCursor (ClientPtr client);
1002
1003+/* Version 5 */
1004+
1005+int
1006+ProcXFixesCreatePointerBarrier (ClientPtr client);
1007+
1008+int
1009+SProcXFixesCreatePointerBarrier (ClientPtr client);
1010+
1011+int
1012+ProcXFixesDestroyPointerBarrier (ClientPtr client);
1013+
1014+int
1015+SProcXFixesDestroyPointerBarrier (ClientPtr client);
1016+
1017+/* Xinerama */
1018 extern int (*PanoramiXSaveXFixesVector[XFixesNumberRequests])(ClientPtr);
1019 void PanoramiXFixesInit (void);
1020 void PanoramiXFixesReset (void);
diff --git a/debian/patches/224_return_BadWindow_not_BadMatch.diff b/debian/patches/224_return_BadWindow_not_BadMatch.diff
deleted file mode 100644
index 12f59eb..0000000
--- a/debian/patches/224_return_BadWindow_not_BadMatch.diff
+++ /dev/null
@@ -1,47 +0,0 @@
1commit ef492e9797b6d4f6bbc25e86bedc24477819fde7
2Author: Chris Halse Rogers <christopher.halse.rogers@canonical.com>
3Date: Thu Jan 5 01:22:39 2012 +0000
4
5 dix: Return BadWindow rather than BadMatch from dixLookupWindow
6
7 dixLookupWindow uses dixLookupDrawable internally, which returns
8 BadMatch when the XID matches a non-Window drawable. Users
9 of dixLookupWindow don't care about this, just that it's not
10 a valid Window.
11
12 This is a generalised version of the fix for X.Org Bug 23562,
13 where GetProperty was incorrectly returning BadMatch. Auditing other
14 window requests, all that I checked would incorrectly return BadMatch
15 in these circumstances. An incomplete list of calls that could
16 incorrectly return BadMatch is: ListProperties, SetSelectionOwner,
17 {Destroy,Map,Unmap}{,Sub}Window.
18
19 None of the callers of dixLookupWindow, except for GetProperty, check
20 for BadMatch
21
22 Signed-off-by: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
23 Reviewed-by: Daniel Stone <daniel@fooishbar.org>
24 Reviewed-by: Adam Jackson <ajax@redhat.com>
25 Signed-off-by: Keith Packard <keithp@keithp.com>
26
27diff --git a/dix/dixutils.c b/dix/dixutils.c
28index 2b5391f..da26dc1 100644
29--- a/dix/dixutils.c
30+++ b/dix/dixutils.c
31@@ -224,7 +224,15 @@ dixLookupWindow(WindowPtr *pWin, XID id, ClientPtr client, Mask access)
32 {
33 int rc;
34 rc = dixLookupDrawable((DrawablePtr*)pWin, id, client, M_WINDOW, access);
35- return (rc == BadDrawable) ? BadWindow : rc;
36+ /* dixLookupDrawable returns BadMatch iff id is a valid Drawable
37+ but is not a Window. Users of dixLookupWindow expect a BadWindow
38+ error in this case; they don't care that it's a valid non-Window XID */
39+ if (rc == BadMatch)
40+ rc = BadWindow;
41+ /* Similarly, users of dixLookupWindow don't want BadDrawable. */
42+ if (rc == BadDrawable)
43+ rc = BadWindow;
44+ return rc;
45 }
46
47 int
diff --git a/debian/patches/225_non-root_config_paths.patch b/debian/patches/225_non-root_config_paths.patch
deleted file mode 100644
index 82661ea..0000000
--- a/debian/patches/225_non-root_config_paths.patch
+++ /dev/null
@@ -1,247 +0,0 @@
1From ead968a4300c0adeff89b9886e888b6d284c75cc Mon Sep 17 00:00:00 2001
2From: Antoine Martin <antoine@nagafix.co.uk>
3Date: Sat, 17 Dec 2011 01:36:51 +0700
4Subject: [PATCH] xserver: check for elevated privileges not uid=0
5
6This allows us to run the server as a normal user whilst still
7being able to use the -modulepath, -logfile and -config switches
8We define a xf86PrivsElevated which will do the checks and cache
9the result in case it is called more than once.
10Also renamed the paths #defines to match their new meaning.
11Original discussion which led to this patch can be found here:
12http://lists.freedesktop.org/archives/xorg-devel/2011-September/025853.html
13
14Signed-off-by: Antoine Martin <antoine@nagafix.co.uk>
15Tested-by: Michal Suchanek <hramrach at centrum.cz>
16Reviewed-by: Jamey Sharp <jamey at minilop.net>
17Reviewed-by: Adam Jackson <ajax@redhat.com>
18---
19 configure.ac | 2 +-
20 hw/xfree86/common/xf86Config.c | 28 +++++++-------
21 hw/xfree86/common/xf86Init.c | 78 +++++++++++++++++++++++++++++++++++-----
22 hw/xfree86/common/xf86Priv.h | 1 +
23 include/xorg-config.h.in | 6 +++
24 5 files changed, 91 insertions(+), 24 deletions(-)
25
26--- a/configure.ac
27+++ b/configure.ac
28@@ -210,7 +210,8 @@ dnl Checks for library functions.
29 AC_FUNC_VPRINTF
30 AC_CHECK_FUNCS([geteuid getuid link memmove memset mkstemp strchr strrchr \
31 strtol getopt getopt_long vsnprintf walkcontext backtrace \
32- getisax getzoneid shmctl64 strcasestr ffs vasprintf])
33+ getisax getzoneid shmctl64 strcasestr ffs vasprintf issetugid \
34+ getresuid])
35 AC_FUNC_ALLOCA
36 dnl Old HAS_* names used in os/*.c.
37 AC_CHECK_FUNC([getdtablesize],
38--- a/hw/xfree86/common/xf86Config.c
39+++ b/hw/xfree86/common/xf86Config.c
40@@ -72,8 +72,8 @@
41 * These paths define the way the config file search is done. The escape
42 * sequences are documented in parser/scan.c.
43 */
44-#ifndef ROOT_CONFIGPATH
45-#define ROOT_CONFIGPATH "%A," "%R," \
46+#ifndef ALL_CONFIGPATH
47+#define ALL_CONFIGPATH "%A," "%R," \
48 "/etc/X11/%R," "%P/etc/X11/%R," \
49 "%E," "%F," \
50 "/etc/X11/%F," "%P/etc/X11/%F," \
51@@ -83,8 +83,8 @@
52 "%P/lib/X11/%X.%H," \
53 "%P/lib/X11/%X"
54 #endif
55-#ifndef USER_CONFIGPATH
56-#define USER_CONFIGPATH "/etc/X11/%S," "%P/etc/X11/%S," \
57+#ifndef RESTRICTED_CONFIGPATH
58+#define RESTRICTED_CONFIGPATH "/etc/X11/%S," "%P/etc/X11/%S," \
59 "/etc/X11/%G," "%P/etc/X11/%G," \
60 "/etc/X11/%X," "/etc/%X," \
61 "%P/etc/X11/%X.%H," \
62@@ -92,14 +92,14 @@
63 "%P/lib/X11/%X.%H," \
64 "%P/lib/X11/%X"
65 #endif
66-#ifndef ROOT_CONFIGDIRPATH
67-#define ROOT_CONFIGDIRPATH "%A," "%R," \
68+#ifndef ALL_CONFIGDIRPATH
69+#define ALL_CONFIGDIRPATH "%A," "%R," \
70 "/etc/X11/%R," "%C/X11/%R," \
71 "/etc/X11/%X," "%C/X11/%X"
72 #endif
73-#ifndef USER_CONFIGDIRPATH
74-#define USER_CONFIGDIRPATH "/etc/X11/%R," "%C/X11/%R," \
75- "/etc/X11/%X," "%C/X11/%X"
76+#ifndef RESTRICTED_CONFIGDIRPATH
77+#define RESTRICTED_CONFIGDIRPATH "/etc/X11/%R," "%C/X11/%R," \
78+ "/etc/X11/%X," "%C/X11/%X"
79 #endif
80 #ifndef SYS_CONFIGDIRPATH
81 #define SYS_CONFIGDIRPATH "/usr/share/X11/%X," "%D/X11/%X"
82@@ -2361,12 +2361,12 @@ xf86HandleConfigFile(Bool autoconfig)
83 Bool implicit_layout = FALSE;
84
85 if (!autoconfig) {
86- if (getuid() == 0) {
87- filesearch = ROOT_CONFIGPATH;
88- dirsearch = ROOT_CONFIGDIRPATH;
89+ if (!xf86PrivsElevated()) {
90+ filesearch = ALL_CONFIGPATH;
91+ dirsearch = ALL_CONFIGDIRPATH;
92 } else {
93- filesearch = USER_CONFIGPATH;
94- dirsearch = USER_CONFIGDIRPATH;
95+ filesearch = RESTRICTED_CONFIGPATH;
96+ dirsearch = RESTRICTED_CONFIGDIRPATH;
97 }
98
99 if (xf86ConfigFile)
100--- a/hw/xfree86/common/xf86Init.c
101+++ b/hw/xfree86/common/xf86Init.c
102@@ -236,6 +236,65 @@ xf86PrintMarkers(void)
103 LogPrintMarkers();
104 }
105
106+Bool xf86PrivsElevated(void)
107+{
108+ static Bool privsTested = FALSE;
109+ static Bool privsElevated = TRUE;
110+
111+ if (!privsTested) {
112+#if defined(WIN32)
113+ privsElevated = FALSE;
114+#else
115+ if ((getuid() != geteuid()) || (getgid() != getegid())) {
116+ privsElevated = TRUE;
117+ } else {
118+#if defined(HAVE_ISSETUGID)
119+ privsElevated = issetugid();
120+#elif defined(HAVE_GETRESUID)
121+ uid_t ruid, euid, suid;
122+ gid_t rgid, egid, sgid;
123+
124+ if ((getresuid(&ruid, &euid, &suid) == 0) &&
125+ (getresgid(&rgid, &egid, &sgid) == 0)) {
126+ privsElevated = (euid != suid) || (egid != sgid);
127+ }
128+ else {
129+ printf("Failed getresuid or getresgid");
130+ /* Something went wrong, make defensive assumption */
131+ privsElevated = TRUE;
132+ }
133+#else
134+ if (getuid()==0) {
135+ /* running as root: uid==euid==0 */
136+ privsElevated = FALSE;
137+ }
138+ else {
139+ /*
140+ * If there are saved ID's the process might still be privileged
141+ * even though the above test succeeded. If issetugid() and
142+ * getresgid() aren't available, test this by trying to set
143+ * euid to 0.
144+ */
145+ unsigned int oldeuid;
146+ oldeuid = geteuid();
147+
148+ if (seteuid(0) != 0) {
149+ privsElevated = FALSE;
150+ } else {
151+ if (seteuid(oldeuid) != 0) {
152+ FatalError("Failed to drop privileges. Exiting\n");
153+ }
154+ privsElevated = TRUE;
155+ }
156+ }
157+#endif
158+ }
159+#endif
160+ privsTested = TRUE;
161+ }
162+ return privsElevated;
163+}
164+
165 static Bool
166 xf86CreateRootWindow(WindowPtr pWin)
167 {
168@@ -855,7 +914,7 @@ OsVendorInit(void)
169
170 #ifdef O_NONBLOCK
171 if (!beenHere) {
172- if (geteuid() == 0 && getuid() != geteuid())
173+ if (xf86PrivsElevated())
174 {
175 int status;
176
177@@ -1064,10 +1123,11 @@ ddxProcessArgument(int argc, char **argv
178 FatalError("Required argument to %s not specified\n", argv[i]); \
179 }
180
181- /* First the options that are only allowed for root */
182+ /* First the options that are not allowed with elevated privileges */
183 if (!strcmp(argv[i], "-modulepath") || !strcmp(argv[i], "-logfile")) {
184- if ( (geteuid() == 0) && (getuid() != 0) ) {
185- FatalError("The '%s' option can only be used by root.\n", argv[i]);
186+ if (xf86PrivsElevated()) {
187+ FatalError("The '%s' option cannot be used with "
188+ "elevated privileges.\n", argv[i]);
189 }
190 else if (!strcmp(argv[i], "-modulepath"))
191 {
192@@ -1095,9 +1155,9 @@ ddxProcessArgument(int argc, char **argv
193 if (!strcmp(argv[i], "-config") || !strcmp(argv[i], "-xf86config"))
194 {
195 CHECK_FOR_REQUIRED_ARGUMENT();
196- if (getuid() != 0 && !xf86PathIsSafe(argv[i + 1])) {
197+ if (xf86PrivsElevated() && !xf86PathIsSafe(argv[i + 1])) {
198 FatalError("\nInvalid argument for %s\n"
199- "\tFor non-root users, the file specified with %s must be\n"
200+ "\tWith elevated privileges, the file specified with %s must be\n"
201 "\ta relative path and must not contain any \"..\" elements.\n"
202 "\tUsing default "__XCONFIGFILE__" search path.\n\n",
203 argv[i], argv[i]);
204@@ -1108,9 +1168,9 @@ ddxProcessArgument(int argc, char **argv
205 if (!strcmp(argv[i], "-configdir"))
206 {
207 CHECK_FOR_REQUIRED_ARGUMENT();
208- if (getuid() != 0 && !xf86PathIsSafe(argv[i + 1])) {
209+ if (xf86PrivsElevated() && !xf86PathIsSafe(argv[i + 1])) {
210 FatalError("\nInvalid argument for %s\n"
211- "\tFor non-root users, the file specified with %s must be\n"
212+ "\tWith elevated privileges, the file specified with %s must be\n"
213 "\ta relative path and must not contain any \"..\" elements.\n"
214 "\tUsing default "__XCONFIGDIR__" search path.\n\n",
215 argv[i], argv[i]);
216@@ -1384,7 +1444,7 @@ ddxUseMsg(void)
217 ErrorF("\n");
218 ErrorF("\n");
219 ErrorF("Device Dependent Usage\n");
220- if (getuid() == 0 || geteuid() != 0)
221+ if (!xf86PrivsElevated())
222 {
223 ErrorF("-modulepath paths specify the module search path\n");
224 ErrorF("-logfile file specify a log file name\n");
225--- a/hw/xfree86/common/xf86Priv.h
226+++ b/hw/xfree86/common/xf86Priv.h
227@@ -148,6 +148,7 @@ extern _X_EXPORT Bool xf86LoadModules(ch
228 extern _X_EXPORT int xf86SetVerbosity(int verb);
229 extern _X_EXPORT int xf86SetLogVerbosity(int verb);
230 extern _X_EXPORT Bool xf86CallDriverProbe( struct _DriverRec * drv, Bool detect_only );
231+extern _X_EXPORT Bool xf86PrivsElevated(void);
232
233 #endif /* _NO_XF86_PROTOTYPES */
234
235--- a/include/xorg-config.h.in
236+++ b/include/xorg-config.h.in
237@@ -145,4 +145,10 @@
238 /* Build with libdrm support */
239 #undef WITH_LIBDRM
240
241+/* Have setugid */
242+#undef HAVE_ISSETUGID
243+
244+/* Have getresuid */
245+#undef HAVE_GETRESUID
246+
247 #endif /* _XORG_CONFIG_H_ */
diff --git a/debian/patches/226_fall_back_to_autoconfiguration.patch b/debian/patches/226_fall_back_to_autoconfiguration.patch
deleted file mode 100644
index 4a513fb..0000000
--- a/debian/patches/226_fall_back_to_autoconfiguration.patch
+++ /dev/null
@@ -1,105 +0,0 @@
1From 1d22d773f67f8c00ab8881d2cce00ef95abf24f7 Mon Sep 17 00:00:00 2001
2From: Alberto Milone <alberto.milone@canonical.com>
3Date: Fri, 27 Jan 2012 19:31:55 +0100
4Subject: [PATCH 1/1] Try to fall back to autoconfiguration in some cases
5 despite having configuration files
6
7Fall back to autoconfiguration if either the graphics
8driver module specified in configuration files can't be
9found or if there's no device supported by the specified
10driver.
11
12Signed-off-by: Alberto Milone <alberto.milone@canonical.com>
13---
14 hw/xfree86/common/xf86Globals.c | 1 +
15 hw/xfree86/common/xf86Init.c | 31 ++++++++++++++++++++++++++-----
16 hw/xfree86/common/xf86Priv.h | 1 +
17 3 files changed, 28 insertions(+), 5 deletions(-)
18
19diff --git a/hw/xfree86/common/xf86Globals.c b/hw/xfree86/common/xf86Globals.c
20index 16d5557..a1a06ad 100644
21--- a/hw/xfree86/common/xf86Globals.c
22+++ b/hw/xfree86/common/xf86Globals.c
23@@ -155,6 +155,7 @@ int xf86NumDrivers = 0;
24 InputDriverPtr *xf86InputDriverList = NULL;
25 int xf86NumInputDrivers = 0;
26 int xf86NumScreens = 0;
27+Bool xf86AttemptedFallback = FALSE;
28
29 const char *xf86VisualNames[] = {
30 "StaticGray",
31diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
32index 0a47140..a0c7f51 100644
33--- a/hw/xfree86/common/xf86Init.c
34+++ b/hw/xfree86/common/xf86Init.c
35@@ -411,20 +411,34 @@ InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
36 free(optionlist);
37 }
38
39+Fallback:
40 /* Load all driver modules specified in the config file */
41 /* If there aren't any specified in the config file, autoconfig them */
42 /* FIXME: Does not handle multiple active screen sections, but I'm not
43 * sure if we really want to handle that case*/
44 configured_device = xf86ConfigLayout.screens->screen->device;
45- if ((!configured_device) || (!configured_device->driver)) {
46+ if (xf86AttemptedFallback) {
47+ configured_device->driver = NULL;
48+ if (!autoConfigDevice(configured_device)) {
49+ xf86Msg(X_ERROR, "Auto configuration on fallback failed\n");
50+ return;
51+ }
52+ }
53+ else if ((!configured_device) || (!configured_device->driver)) {
54 if (!autoConfigDevice(configured_device)) {
55 xf86Msg(X_ERROR, "Automatic driver configuration failed\n");
56 return ;
57 }
58 }
59 if ((modulelist = xf86DriverlistFromConfig())) {
60- xf86LoadModules(modulelist, NULL);
61- free(modulelist);
62+ if (!xf86LoadModules(modulelist, NULL) && !xf86AttemptedFallback) {
63+ free(modulelist);
64+ xf86AttemptedFallback = TRUE;
65+ goto Fallback;
66+ }
67+ else {
68+ free(modulelist);
69+ }
70 }
71
72 /* Load all input driver modules specified in the config file. */
73@@ -483,8 +497,15 @@ InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
74 else
75 xf86Info.dontVTSwitch = TRUE;
76
77- if (xf86BusConfig() == FALSE)
78- return;
79+ if (xf86BusConfig() == FALSE) {
80+ if (!xf86AttemptedFallback) {
81+ xf86AttemptedFallback = TRUE;
82+ goto Fallback;
83+ }
84+ else {
85+ return;
86+ }
87+ }
88
89 xf86PostProbe();
90
91diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h
92index 1fe3d7e..c342424 100644
93--- a/hw/xfree86/common/xf86Priv.h
94+++ b/hw/xfree86/common/xf86Priv.h
95@@ -86,6 +86,7 @@ extern _X_EXPORT int xf86NumDrivers;
96 extern _X_EXPORT Bool xf86Resetting;
97 extern _X_EXPORT Bool xf86Initialising;
98 extern _X_EXPORT int xf86NumScreens;
99+extern _X_EXPORT Bool xf86AttemptedFallback;
100 extern _X_EXPORT const char *xf86VisualNames[];
101 extern _X_EXPORT int xf86Verbose; /* verbosity level */
102 extern _X_EXPORT int xf86LogVerbose; /* log file verbosity level */
103--
1041.7.5.4
105
diff --git a/debian/patches/227_null_ptr_midispcur.patch b/debian/patches/227_null_ptr_midispcur.patch
deleted file mode 100644
index 6d871ee..0000000
--- a/debian/patches/227_null_ptr_midispcur.patch
+++ /dev/null
@@ -1,14 +0,0 @@
1diff -u a/mi/midispcur.c b/mi/midispcur.c
2--- a/mi/midispcur.c 2011-08-05 09:59:03.000000000 +0400
3+++ b/mi/midispcur.c 2012-02-16 10:07:52.524576132 +0400
4@@ -479,6 +479,10 @@
5 GCPtr pGC;
6
7 pBuffer = miGetDCDevice(pDev, pScreen);
8+
9+ if (!pBuffer)
10+ return FALSE;
11+
12 pSave = pBuffer->pSave;
13
14 pWin = pScreen->root;
diff --git a/debian/patches/228_log-format-fix.patch b/debian/patches/228_log-format-fix.patch
deleted file mode 100644
index 61e7eae..0000000
--- a/debian/patches/228_log-format-fix.patch
+++ /dev/null
@@ -1,441 +0,0 @@
1Description: extreme backport of upstream log format fixes (CVE-2012-2118).
2Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/xorg-server/+bug/996250
3Origin: http://patchwork.freedesktop.org/patch/10001/
4
5Index: xorg-server-1.11.4/os/log.c
6===================================================================
7--- xorg-server-1.11.4.orig/os/log.c 2012-05-06 11:03:17.621808123 -0700
8+++ xorg-server-1.11.4/os/log.c 2012-05-06 11:03:18.057814189 -0700
9@@ -167,6 +167,12 @@
10 #ifndef X_NOT_IMPLEMENTED_STRING
11 #define X_NOT_IMPLEMENTED_STRING "(NI)"
12 #endif
13+#ifndef X_DEBUG_STRING
14+#define X_DEBUG_STRING "(DB)"
15+#endif
16+#ifndef X_NONE_STRING
17+#define X_NONE_STRING ""
18+#endif
19
20 /*
21 * LogInit is called to start logging to a file. It is also called (with
22@@ -223,7 +229,7 @@
23 * needed.
24 */
25 if (saveBuffer && bufferSize > 0) {
26- free(saveBuffer); /* Must be free(), not free() */
27+ free(saveBuffer);
28 saveBuffer = NULL;
29 bufferSize = 0;
30 }
31@@ -265,36 +271,19 @@
32 }
33
34 /* This function does the actual log message writes. */
35-
36-void
37-LogVWrite(int verb, const char *f, va_list args)
38+static void
39+LogSWrite(int verb, const char *buf, size_t len, Bool end_line)
40 {
41- static char tmpBuffer[1024];
42- int len = 0;
43 static Bool newline = TRUE;
44
45- if (newline) {
46- sprintf(tmpBuffer, "[%10.3f] ", GetTimeInMillis() / 1000.0);
47- len = strlen(tmpBuffer);
48- if (logFile)
49- fwrite(tmpBuffer, len, 1, logFile);
50- }
51-
52- /*
53- * Since a va_list can only be processed once, write the string to a
54- * buffer, and then write the buffer out to the appropriate output
55- * stream(s).
56- */
57- if (verb < 0 || logFileVerbosity >= verb || logVerbosity >= verb) {
58- vsnprintf(tmpBuffer, sizeof(tmpBuffer), f, args);
59- len = strlen(tmpBuffer);
60- }
61- newline = (tmpBuffer[len-1] == '\n');
62- if ((verb < 0 || logVerbosity >= verb) && len > 0)
63- fwrite(tmpBuffer, len, 1, stderr);
64- if ((verb < 0 || logFileVerbosity >= verb) && len > 0) {
65+ if (verb < 0 || logVerbosity >= verb)
66+ fwrite(buf, len, 1, stderr);
67+ if (verb < 0 || logFileVerbosity >= verb) {
68 if (logFile) {
69- fwrite(tmpBuffer, len, 1, logFile);
70+ if (newline)
71+ fprintf(logFile, "[%10.3f] ", GetTimeInMillis() / 1000.0);
72+ newline = end_line;
73+ fwrite(buf, len, 1, logFile);
74 if (logFlush) {
75 fflush(logFile);
76 #ifndef WIN32
77@@ -311,13 +300,19 @@
78 FatalError("realloc() failed while saving log messages\n");
79 }
80 bufferUnused -= len;
81- memcpy(saveBuffer + bufferPos, tmpBuffer, len);
82+ memcpy(saveBuffer + bufferPos, buf, len);
83 bufferPos += len;
84 }
85 }
86 }
87
88 void
89+LogVWrite(int verb, const char *f, va_list args)
90+{
91+ return LogVMessageVerb(X_NONE, verb, f, args);
92+}
93+
94+void
95 LogWrite(int verb, const char *f, ...)
96 {
97 va_list args;
98@@ -327,60 +322,75 @@
99 va_end(args);
100 }
101
102-void
103-LogVMessageVerb(MessageType type, int verb, const char *format, va_list args)
104+/* Returns the Message Type string to prepend to a logging message, or NULL
105+ * if the message will be dropped due to insufficient verbosity. */
106+static const char *
107+LogMessageTypeVerbString(MessageType type, int verb)
108 {
109- const char *s = X_UNKNOWN_STRING;
110- char tmpBuf[1024];
111+ if (type == X_ERROR)
112+ verb = 0;
113
114- /* Ignore verbosity for X_ERROR */
115- if (logVerbosity >= verb || logFileVerbosity >= verb || type == X_ERROR) {
116- switch (type) {
117- case X_PROBED:
118- s = X_PROBE_STRING;
119- break;
120- case X_CONFIG:
121- s = X_CONFIG_STRING;
122- break;
123- case X_DEFAULT:
124- s = X_DEFAULT_STRING;
125- break;
126- case X_CMDLINE:
127- s = X_CMDLINE_STRING;
128- break;
129- case X_NOTICE:
130- s = X_NOTICE_STRING;
131- break;
132- case X_ERROR:
133- s = X_ERROR_STRING;
134- if (verb > 0)
135- verb = 0;
136- break;
137- case X_WARNING:
138- s = X_WARNING_STRING;
139- break;
140- case X_INFO:
141- s = X_INFO_STRING;
142- break;
143- case X_NOT_IMPLEMENTED:
144- s = X_NOT_IMPLEMENTED_STRING;
145- break;
146- case X_UNKNOWN:
147- s = X_UNKNOWN_STRING;
148- break;
149- case X_NONE:
150- s = NULL;
151- break;
152- }
153+ if (logVerbosity < verb && logFileVerbosity < verb)
154+ return NULL;
155
156- /* if s is not NULL we need a space before format */
157- snprintf(tmpBuf, sizeof(tmpBuf), "%s%s%s", s ? s : "",
158- s ? " " : "",
159- format);
160- LogVWrite(verb, tmpBuf, args);
161+ switch (type) {
162+ case X_PROBED:
163+ return X_PROBE_STRING;
164+ case X_CONFIG:
165+ return X_CONFIG_STRING;
166+ case X_DEFAULT:
167+ return X_DEFAULT_STRING;
168+ case X_CMDLINE:
169+ return X_CMDLINE_STRING;
170+ case X_NOTICE:
171+ return X_NOTICE_STRING;
172+ case X_ERROR:
173+ return X_ERROR_STRING;
174+ case X_WARNING:
175+ return X_WARNING_STRING;
176+ case X_INFO:
177+ return X_INFO_STRING;
178+ case X_NOT_IMPLEMENTED:
179+ return X_NOT_IMPLEMENTED_STRING;
180+ case X_UNKNOWN:
181+ return X_UNKNOWN_STRING;
182+ case X_NONE:
183+ return X_NONE_STRING;
184+ case X_DEBUG:
185+ return X_DEBUG_STRING;
186+ default:
187+ return X_UNKNOWN_STRING;
188 }
189 }
190
191+void
192+LogVMessageVerb(MessageType type, int verb, const char *format, va_list args)
193+{
194+ const char *type_str;
195+ char buf[1024];
196+ const size_t size = sizeof(buf);
197+ Bool newline;
198+ size_t len = 0;
199+
200+ type_str = LogMessageTypeVerbString(type, verb);
201+ if (!type_str)
202+ return;
203+
204+ /* if type_str is not "", prepend it and ' ', to message */
205+ if (type_str[0] != '\0')
206+ len += Xscnprintf(&buf[len], size - len, "%s ", type_str);
207+
208+ if (size - len > 1)
209+ len += Xvscnprintf(&buf[len], size - len, format, args);
210+
211+ /* Force '\n' at end of truncated line */
212+ if (size - len == 1)
213+ buf[len - 1] = '\n';
214+
215+ newline = (buf[len - 1] == '\n');
216+ LogSWrite(verb, buf, len, newline);
217+}
218+
219 /* Log message with verbosity level specified. */
220 void
221 LogMessageVerb(MessageType type, int verb, const char *format, ...)
222@@ -404,6 +414,49 @@
223 }
224
225 void
226+LogVHdrMessageVerb(MessageType type, int verb, const char *msg_format,
227+ va_list msg_args, const char *hdr_format, va_list hdr_args)
228+{
229+ const char *type_str;
230+ char buf[1024];
231+ const size_t size = sizeof(buf);
232+ Bool newline;
233+ size_t len = 0;
234+
235+ type_str = LogMessageTypeVerbString(type, verb);
236+ if (!type_str)
237+ return;
238+
239+ /* if type_str is not "", prepend it and ' ', to message */
240+ if (type_str[0] != '\0')
241+ len += Xscnprintf(&buf[len], size - len, "%s ", type_str);
242+
243+ if (hdr_format && size - len > 1)
244+ len += Xvscnprintf(&buf[len], size - len, hdr_format, hdr_args);
245+
246+ if (msg_format && size - len > 1)
247+ len += Xvscnprintf(&buf[len], size - len, msg_format, msg_args);
248+
249+ /* Force '\n' at end of truncated line */
250+ if (size - len == 1)
251+ buf[len - 1] = '\n';
252+
253+ newline = (buf[len - 1] == '\n');
254+ LogSWrite(verb, buf, len, newline);
255+}
256+
257+void
258+LogHdrMessageVerb(MessageType type, int verb, const char *msg_format,
259+ va_list msg_args, const char *hdr_format, ...)
260+{
261+ va_list hdr_args;
262+
263+ va_start(hdr_args, hdr_format);
264+ LogVHdrMessageVerb(type, verb, msg_format, msg_args, hdr_format, hdr_args);
265+ va_end(hdr_args);
266+}
267+
268+void
269 AbortServer(void) _X_NORETURN;
270 void
271 SigAbortServer(int signo) _X_NORETURN;
272Index: xorg-server-1.11.4/include/Xprintf.h
273===================================================================
274--- xorg-server-1.11.4.orig/include/Xprintf.h 2012-05-06 10:32:42.436348011 -0700
275+++ xorg-server-1.11.4/include/Xprintf.h 2012-05-06 11:03:18.057814189 -0700
276@@ -66,4 +66,16 @@
277 # define vasprintf Xvasprintf
278 #endif
279
280+/*
281+ * These functions provide a portable implementation of the linux kernel
282+ * scnprintf & vscnprintf routines that return the number of bytes actually
283+ * copied during a snprintf, (excluding the final '\0').
284+ */
285+extern _X_EXPORT int
286+Xscnprintf(char *s, int n, const char * _X_RESTRICT_KYWD fmt, ...)
287+_X_ATTRIBUTE_PRINTF(3,4);
288+extern _X_EXPORT int
289+Xvscnprintf(char *s, int n, const char * _X_RESTRICT_KYWD fmt, va_list va)
290+_X_ATTRIBUTE_PRINTF(3,0);
291+
292 #endif /* XPRINTF_H */
293Index: xorg-server-1.11.4/os/xprintf.c
294===================================================================
295--- xorg-server-1.11.4.orig/os/xprintf.c 2012-05-06 10:32:42.472348510 -0700
296+++ xorg-server-1.11.4/os/xprintf.c 2012-05-06 11:03:18.057814189 -0700
297@@ -182,6 +182,50 @@
298 return size;
299 }
300
301+/**
302+ * Varargs snprintf that returns the actual number of bytes (excluding final
303+ * '\0') that were copied into the buffer.
304+ * This is opposed to the normal sprintf() usually returns the number of bytes
305+ * that would have been written.
306+ *
307+ * @param s buffer to copy into
308+ * @param n size of buffer s
309+ * @param format printf style format string
310+ * @param va variable argument list
311+ * @return number of bytes actually copied, excluding final '\0'
312+ */
313+int
314+Xvscnprintf(char *s, int n, const char *format, va_list args)
315+{
316+ int x;
317+ if (n == 0)
318+ return 0;
319+ x = vsnprintf(s, n , format, args);
320+ return (x >= n) ? (n - 1) : x;
321+}
322+
323+/**
324+ * snprintf that returns the actual number of bytes (excluding final '\0') that
325+ * were copied into the buffer.
326+ * This is opposed to the normal sprintf() usually returns the number of bytes
327+ * that would have been written.
328+ *
329+ * @param s buffer to copy into
330+ * @param n size of buffer s
331+ * @param format printf style format string
332+ * @param ... arguments for specified format
333+ * @return number of bytes actually copied, excluding final '\0'
334+ */
335+int Xscnprintf(char *s, int n, const char *format, ...)
336+{
337+ int x;
338+ va_list ap;
339+ va_start(ap, format);
340+ x = Xvscnprintf(s, n, format, ap);
341+ va_end(ap);
342+ return x;
343+}
344+
345 /* Old api, now deprecated, may be removed in the future */
346 char *
347 Xvprintf(const char *format, va_list va)
348Index: xorg-server-1.11.4/hw/xfree86/common/xf86Helper.c
349===================================================================
350--- xorg-server-1.11.4.orig/hw/xfree86/common/xf86Helper.c 2012-05-06 10:32:42.488348731 -0700
351+++ xorg-server-1.11.4/hw/xfree86/common/xf86Helper.c 2012-05-06 11:03:18.057814189 -0700
352@@ -1036,25 +1036,13 @@
353 xf86VDrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format,
354 va_list args)
355 {
356- char *tmpFormat;
357-
358 /* Prefix the scrnIndex name to the format string. */
359 if (scrnIndex >= 0 && scrnIndex < xf86NumScreens &&
360- xf86Screens[scrnIndex]->name) {
361- tmpFormat = malloc(strlen(format) +
362- strlen(xf86Screens[scrnIndex]->name) +
363- PREFIX_SIZE + 1);
364- if (!tmpFormat)
365- return;
366-
367- snprintf(tmpFormat, PREFIX_SIZE + 1, "%s(%d): ",
368- xf86Screens[scrnIndex]->name, scrnIndex);
369-
370- strcat(tmpFormat, format);
371- LogVMessageVerb(type, verb, tmpFormat, args);
372- free(tmpFormat);
373- } else
374- LogVMessageVerb(type, verb, format, args);
375+ xf86Screens[scrnIndex]->name)
376+ LogHdrMessageVerb(type, verb, format, args, "%s(%d): ",
377+ xf86Screens[scrnIndex]->name, scrnIndex);
378+ else
379+ LogVMessageVerb(type, verb, format, args);
380 }
381 #undef PREFIX_SIZE
382
383@@ -1087,15 +1075,18 @@
384 xf86VIDrvMsgVerb(InputInfoPtr dev, MessageType type, int verb, const char *format,
385 va_list args)
386 {
387- char *msg;
388+ const char *driverName = NULL;
389+ const char *deviceName = NULL;
390
391- if (asprintf(&msg, "%s: %s: %s", dev->drv->driverName, dev->name, format)
392- == -1) {
393- LogVMessageVerb(type, verb, "%s", args);
394- } else {
395- LogVMessageVerb(type, verb, msg, args);
396- free(msg);
397+ /* Prefix driver and device names to formatted message. */
398+ if (dev) {
399+ deviceName = dev->name;
400+ if (dev->drv)
401+ driverName = dev->drv->driverName;
402 }
403+
404+ LogHdrMessageVerb(type, verb, format, args, "%s: %s: ", driverName,
405+ deviceName);
406 }
407
408 /* Print input driver message, with verbose level specified directly */
409Index: xorg-server-1.11.4/include/os.h
410===================================================================
411--- xorg-server-1.11.4.orig/include/os.h 2012-05-06 11:03:17.621808123 -0700
412+++ xorg-server-1.11.4/include/os.h 2012-05-06 11:03:29.353971366 -0700
413@@ -514,6 +514,7 @@
414 X_INFO, /* Informational message */
415 X_NONE, /* No prefix */
416 X_NOT_IMPLEMENTED, /* Not implemented */
417+ X_DEBUG, /* Debug message */
418 X_UNKNOWN = -1 /* unknown -- this must always be last */
419 } MessageType;
420
421@@ -528,6 +529,20 @@
422 ...) _X_ATTRIBUTE_PRINTF(3,4);
423 extern _X_EXPORT void LogMessage(MessageType type, const char *format, ...)
424 _X_ATTRIBUTE_PRINTF(2,3);
425+
426+extern _X_EXPORT void
427+LogVHdrMessageVerb(MessageType type, int verb,
428+ const char *msg_format, va_list msg_args,
429+ const char *hdr_format, va_list hdr_args)
430+_X_ATTRIBUTE_PRINTF(3, 0)
431+_X_ATTRIBUTE_PRINTF(5, 0);
432+extern _X_EXPORT void
433+LogHdrMessageVerb(MessageType type, int verb,
434+ const char *msg_format, va_list msg_args,
435+ const char *hdr_format, ...)
436+_X_ATTRIBUTE_PRINTF(3, 0)
437+_X_ATTRIBUTE_PRINTF(5, 6);
438+
439 extern _X_EXPORT void FreeAuditTimer(void);
440 extern _X_EXPORT void AuditF(const char *f, ...) _X_ATTRIBUTE_PRINTF(1,2);
441 extern _X_EXPORT void VAuditF(const char *f, va_list args) _X_ATTRIBUTE_PRINTF(1,0);
diff --git a/debian/patches/229_randr_first_check_pScrPriv_before_using_the_pointer.patch b/debian/patches/229_randr_first_check_pScrPriv_before_using_the_pointer.patch
deleted file mode 100644
index 8c9cf71..0000000
--- a/debian/patches/229_randr_first_check_pScrPriv_before_using_the_pointer.patch
+++ /dev/null
@@ -1,30 +0,0 @@
1From 32603f57ca03b6390b109960f8bb5ea53ac95ecb Mon Sep 17 00:00:00 2001
2From: Ricardo Salveti de Araujo <ricardo.salveti@linaro.org>
3Date: Thu, 21 Jun 2012 00:55:53 -0300
4Subject: [PATCH] randr: first check pScrPriv before using the pointer at
5 RRFirstOutput
6
7Fix a seg fault in case pScrPriv is NULL at ProcRRGetScreenInfo,
8which later calls RRFirstOutput.
9
10Signed-off-by: Ricardo Salveti de Araujo <ricardo.salveti@linaro.org>
11Reviewed-by: Keith Packard <keithp@keithp.com>
12Signed-off-by: Keith Packard <keithp@keithp.com>
13---
14 randr/randr.c | 3 +++
15 1 file changed, 3 insertions(+)
16
17Index: xorg-server-1.11.4/randr/randr.c
18===================================================================
19--- xorg-server-1.11.4.orig/randr/randr.c 2012-07-17 18:46:06.000000000 -0300
20+++ xorg-server-1.11.4/randr/randr.c 2012-07-17 18:48:35.169824448 -0300
21@@ -454,6 +454,9 @@
22 rrScrPriv(pScreen);
23 RROutputPtr output;
24 int i, j;
25+
26+ if (!pScrPriv)
27+ return NULL;
28
29 if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc)
30 return pScrPriv->primaryOutput;
diff --git a/debian/patches/230_randr_catch_two_more_potential_unset_rrScrPriv_uses.patch b/debian/patches/230_randr_catch_two_more_potential_unset_rrScrPriv_uses.patch
deleted file mode 100644
index e37d073..0000000
--- a/debian/patches/230_randr_catch_two_more_potential_unset_rrScrPriv_uses.patch
+++ /dev/null
@@ -1,52 +0,0 @@
1From 855003c333a0ead1db912695bc9705ef2b3144b4 Mon Sep 17 00:00:00 2001
2From: Keith Packard <keithp@keithp.com>
3Date: Thu, 21 Jun 2012 18:45:18 -0700
4Subject: [PATCH] randr: Catch two more potential unset rrScrPriv uses
5
6Ricardo Salveti <ricardo.salveti@linaro.org> found one place where the
7randr code could use the randr screen private data without checking
8for null first. This happens when the X server is running with
9multiple screens, some of which are randr enabled and some of which
10are not. Applications making protocol requests to the non-randr
11screens can cause segfaults where the server touches the unset private
12structure.
13
14I audited the code and found two more possible problem spots; the
15trick to auditing for this issue was to look for functions not taking
16a RandR data structure and where there was no null screen private
17check above them in the call graph.
18
19Signed-off-by: Keith Packard <keithp@keithp.com>
20---
21 randr/rroutput.c | 3 ++-
22 randr/rrscreen.c | 3 +++
23 2 files changed, 5 insertions(+), 1 deletion(-)
24
25diff --git a/randr/rroutput.c b/randr/rroutput.c
26index 091e06b..fbd0e32 100644
27--- a/randr/rroutput.c
28+++ b/randr/rroutput.c
29@@ -546,7 +546,8 @@ ProcRRSetOutputPrimary(ClientPtr client)
30 }
31
32 pScrPriv = rrGetScrPriv(pWin->drawable.pScreen);
33- RRSetPrimaryOutput(pWin->drawable.pScreen, pScrPriv, output);
34+ if (pScrPriv)
35+ RRSetPrimaryOutput(pWin->drawable.pScreen, pScrPriv, output);
36
37 return Success;
38 }
39diff --git a/randr/rrscreen.c b/randr/rrscreen.c
40index f570afa..55110e0 100644
41--- a/randr/rrscreen.c
42+++ b/randr/rrscreen.c
43@@ -261,6 +261,9 @@
44
45 pScreen = pWin->drawable.pScreen;
46 pScrPriv = rrGetScrPriv(pScreen);
47+ if (!pScrPriv)
48+ return BadMatch;
49+
50 if (stuff->width < pScrPriv->minWidth || pScrPriv->maxWidth < stuff->width)
51 {
52 client->errorValue = stuff->width;
diff --git a/debian/patches/233-xf86events-valgrind.patch b/debian/patches/233-xf86events-valgrind.patch
deleted file mode 100644
index f2fbcfb..0000000
--- a/debian/patches/233-xf86events-valgrind.patch
+++ /dev/null
@@ -1,19 +0,0 @@
1diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
2index 41ffabd..6082bee 100644
3--- a/hw/xfree86/common/xf86Events.c
4+++ b/hw/xfree86/common/xf86Events.c
5@@ -270,10 +270,10 @@ xf86Wakeup(pointer blockData, int err, pointer pReadmask)
6 }
7 }
8
9- if (err >= 0) { /* we don't want the handlers called if select() */
10- IHPtr ih; /* returned with an error condition, do we? */
11-
12- for (ih = InputHandlers; ih; ih = ih->next) {
13+ if (err >= 0) { /* we don't want the handlers called if select() */
14+ IHPtr ih, ih_tmp; /* returned with an error condition, do we? */
15+
16+ nt_list_for_each_entry_safe(ih, ih_tmp, InputHandlers, next) {
17 if (ih->enabled && ih->fd >= 0 && ih->ihproc &&
18 (FD_ISSET(ih->fd, ((fd_set *)pReadmask)) != 0)) {
19 ih->ihproc(ih->fd, ih->data);
diff --git a/debian/patches/235-composite-tracking.diff b/debian/patches/235-composite-tracking.diff
deleted file mode 100644
index 20d2ce2..0000000
--- a/debian/patches/235-composite-tracking.diff
+++ /dev/null
@@ -1,63 +0,0 @@
1diff --git a/exa/exa_priv.h b/exa/exa_priv.h
2index 70de4bd..60aa328 100644
3--- a/exa/exa_priv.h
4+++ b/exa/exa_priv.h
5@@ -206,6 +206,7 @@ typedef struct {
6 RegionRec srcReg;
7 RegionRec maskReg;
8 PixmapPtr srcPix;
9+ PixmapPtr maskPix;
10
11 } ExaScreenPrivRec, *ExaScreenPrivPtr;
12
13diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
14index 219f903..7d83d15 100644
15--- a/exa/exa_unaccel.c
16+++ b/exa/exa_unaccel.c
17@@ -448,6 +448,13 @@ ExaSrcValidate(DrawablePtr pDrawable,
18 RegionPtr dst;
19 int xoff, yoff;
20
21+ if (pExaScr->srcPix == pPix)
22+ dst = &pExaScr->srcReg;
23+ else if (pExaScr->maskPix == pPix)
24+ dst = &pExaScr->maskReg;
25+ else
26+ return;
27+
28 exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff);
29
30 box.x1 = x + xoff;
31@@ -455,9 +462,6 @@ ExaSrcValidate(DrawablePtr pDrawable,
32 box.x2 = box.x1 + width;
33 box.y2 = box.y1 + height;
34
35- dst = (pExaScr->srcPix == pPix) ? &pExaScr->srcReg :
36- &pExaScr->maskReg;
37-
38 RegionInit(&reg, &box, 1);
39 RegionUnion(dst, dst, &reg);
40 RegionUninit(&reg);
41@@ -506,17 +510,20 @@ ExaPrepareCompositeReg(ScreenPtr pScreen,
42 RegionTranslate(pSrc->pCompositeClip,
43 -pSrc->pDrawable->x,
44 -pSrc->pDrawable->y);
45- }
46+ } else
47+ pExaScr->srcPix = NULL;
48
49 if (pMask && pMask->pDrawable) {
50 pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
51 RegionNull(&pExaScr->maskReg);
52 maskReg = &pExaScr->maskReg;
53+ pExaScr->maskPix = pMaskPix;
54 if (pMask != pDst && pMask != pSrc)
55 RegionTranslate(pMask->pCompositeClip,
56 -pMask->pDrawable->x,
57 -pMask->pDrawable->y);
58- }
59+ } else
60+ pExaScr->maskPix = NULL;
61
62 RegionTranslate(pDst->pCompositeClip,
63 -pDst->pDrawable->x,
diff --git a/debian/patches/238-xrandr-fix-panning.patch b/debian/patches/238-xrandr-fix-panning.patch
deleted file mode 100644
index 2dcb326..0000000
--- a/debian/patches/238-xrandr-fix-panning.patch
+++ /dev/null
@@ -1,129 +0,0 @@
1Description: disable CRTC cursor confinement when panning is enabled
2Origin: backport, http://cgit.freedesktop.org/xorg/xserver/commit/?id=1bf81af4a6be1113bcc3b940ab264d5c9e0f0c5d
3Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/xorg-server/+bug/883319
4Bug: https://bugs.freedesktop.org/show_bug.cgi?id=39949
5
6Index: xorg-server-1.11.4/hw/xfree86/modes/xf86RandR12.c
7===================================================================
8--- xorg-server-1.11.4.orig/hw/xfree86/modes/xf86RandR12.c 2012-12-20 10:46:57.594909196 -0500
9+++ xorg-server-1.11.4/hw/xfree86/modes/xf86RandR12.c 2012-12-20 10:52:27.706917648 -0500
10@@ -60,6 +60,9 @@
11 * See https://bugs.freedesktop.org/show_bug.cgi?id=21554
12 */
13 xf86EnterVTProc *orig_EnterVT;
14+
15+ Bool panning;
16+ ConstrainCursorHarderProcPtr orig_ConstrainCursorHarder;
17 } XF86RandRInfoRec, *XF86RandRInfoPtr;
18
19 #ifdef RANDR_12_INTERFACE
20@@ -678,6 +681,10 @@
21 return TRUE;
22 }
23
24+#define PANNING_ENABLED(crtc) \
25+ ((crtc)->panningTotalArea.x2 > (crtc)->panningTotalArea.x1 || \
26+ (crtc)->panningTotalArea.y2 > (crtc)->panningTotalArea.y1)
27+
28 static Bool
29 xf86RandR12ScreenSetSize (ScreenPtr pScreen,
30 CARD16 width,
31@@ -691,6 +698,7 @@
32 WindowPtr pRoot = pScreen->root;
33 PixmapPtr pScrnPix;
34 Bool ret = FALSE;
35+ Bool panning = FALSE;
36 int c;
37
38 if (xf86RandR12Key) {
39@@ -711,8 +719,7 @@
40 /* Update panning information */
41 for (c = 0; c < config->num_crtc; c++) {
42 xf86CrtcPtr crtc = config->crtc[c];
43- if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1 ||
44- crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
45+ if (PANNING_ENABLED (crtc)) {
46 if (crtc->panningTotalArea.x2 > crtc->panningTrackingArea.x1)
47 crtc->panningTotalArea.x2 += width - pScreen->width;
48 if (crtc->panningTotalArea.y2 > crtc->panningTrackingArea.y1)
49@@ -723,6 +730,7 @@
50 crtc->panningTrackingArea.y2 += height - pScreen->height;
51 xf86RandR13VerifyPanningArea (crtc, width, height);
52 xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
53+ panning = TRUE;
54 }
55 }
56
57@@ -930,6 +938,7 @@
58 randrp = XF86RANDRINFO(pScreen);
59 #if RANDR_12_INTERFACE
60 xf86Screens[pScreen->myNum]->EnterVT = randrp->orig_EnterVT;
61+ pScreen->ConstrainCursorHarder = randrp->orig_ConstrainCursorHarder;
62 #endif
63
64 free(randrp);
65@@ -1234,6 +1243,7 @@
66 }
67 xf86RandR13VerifyPanningArea (crtc, pScreen->width, pScreen->height);
68 xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
69+ randrp->panning = PANNING_ENABLED (crtc);
70 /*
71 * Save the last successful setting for EnterVT
72 */
73@@ -1667,7 +1677,7 @@
74 BoxRec oldTotalArea;
75 BoxRec oldTrackingArea;
76 INT16 oldBorder[4];
77-
78+ Bool oldPanning = randrp->panning;
79
80 if (crtc->version < 2)
81 return FALSE;
82@@ -1685,12 +1695,14 @@
83
84 if (xf86RandR13VerifyPanningArea (crtc, pScreen->width, pScreen->height)) {
85 xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
86+ randrp->panning = PANNING_ENABLED (crtc);
87 return TRUE;
88 } else {
89 /* Restore old settings */
90 memcpy (&crtc->panningTotalArea, &oldTotalArea, sizeof(BoxRec));
91 memcpy (&crtc->panningTrackingArea, &oldTrackingArea, sizeof(BoxRec));
92 memcpy (crtc->panningBorder, oldBorder, 4*sizeof(INT16));
93+ randrp->panning = oldPanning;
94 return FALSE;
95 }
96 }
97@@ -1775,6 +1787,21 @@
98 return RRGetInfo (pScreen, TRUE); /* force a re-probe of outputs and notify clients about changes */
99 }
100
101+static void
102+xf86RandR13ConstrainCursorHarder(DeviceIntPtr dev, ScreenPtr screen, int mode, int *x, int *y)
103+{
104+ XF86RandRInfoPtr randrp = XF86RANDRINFO(screen);
105+
106+ if (randrp->panning)
107+ return;
108+
109+ if (randrp->orig_ConstrainCursorHarder) {
110+ screen->ConstrainCursorHarder = randrp->orig_ConstrainCursorHarder;
111+ screen->ConstrainCursorHarder(dev, screen, mode, x, y);
112+ screen->ConstrainCursorHarder = xf86RandR13ConstrainCursorHarder;
113+ }
114+}
115+
116 static Bool
117 xf86RandR12Init12 (ScreenPtr pScreen)
118 {
119@@ -1803,6 +1830,10 @@
120 randrp->orig_EnterVT = pScrn->EnterVT;
121 pScrn->EnterVT = xf86RandR12EnterVT;
122
123+ randrp->panning = FALSE;
124+ randrp->orig_ConstrainCursorHarder = pScreen->ConstrainCursorHarder;
125+ pScreen->ConstrainCursorHarder = xf86RandR13ConstrainCursorHarder;
126+
127 if (!xf86RandR12CreateObjects12 (pScreen))
128 return FALSE;
129
diff --git a/debian/patches/500_pointer_barrier_thresholds.diff b/debian/patches/500_pointer_barrier_thresholds.diff
deleted file mode 100644
index 9e255ad..0000000
--- a/debian/patches/500_pointer_barrier_thresholds.diff
+++ /dev/null
@@ -1,1694 +0,0 @@
1Index: xorg-server/include/protocol-versions.h
2===================================================================
3--- xorg-server.orig/include/protocol-versions.h 2012-03-07 22:24:45.540697115 +1100
4+++ xorg-server/include/protocol-versions.h 2012-03-08 07:40:35.472111389 +1100
5@@ -122,7 +122,7 @@
6 #define SERVER_XF86VIDMODE_MINOR_VERSION 2
7
8 /* Fixes */
9-#define SERVER_XFIXES_MAJOR_VERSION 5
10+#define SERVER_XFIXES_MAJOR_VERSION 6
11 #define SERVER_XFIXES_MINOR_VERSION 0
12
13 /* X Input */
14Index: xorg-server/xfixes/cursor.c
15===================================================================
16--- xorg-server.orig/xfixes/cursor.c 2012-03-07 22:24:45.580697117 +1100
17+++ xorg-server/xfixes/cursor.c 2012-03-08 11:00:53.155469738 +1100
18@@ -61,6 +61,7 @@
19 static RESTYPE CursorHideCountType;
20 static RESTYPE CursorWindowType;
21 RESTYPE PointerBarrierType;
22+static RESTYPE PointerBarrierClientType;
23 static CursorPtr CursorCurrent[MAXDEVICES];
24
25 static DevPrivateKeyRec CursorScreenPrivateKeyRec;
26@@ -119,6 +120,11 @@
27 struct list entry;
28 };
29
30+/**
31+ * Pick up unclamped (x,y) coordinates from dix/getevents
32+ */
33+extern int unclamped_prex, unclamped_prey;
34+
35 /*
36 * Wrap DisplayCursor to catch cursor change events
37 */
38@@ -129,6 +135,7 @@
39 ConstrainCursorHarderProcPtr ConstrainCursorHarder;
40 CursorHideCountPtr pCursorHideCounts;
41 struct list barriers;
42+ struct list barrierClients;
43 } CursorScreenRec, *CursorScreenPtr;
44
45 #define GetCursorScreen(s) ((CursorScreenPtr)dixLookupPrivate(&(s)->devPrivates, CursorScreenPrivateKey))
46@@ -1118,7 +1125,8 @@
47
48 /* Algorithm below doesn't handle edge cases well, hence the extra
49 * checks. */
50- if (barrier_is_vertical(barrier)) {
51+ if (barrier_is_vertical(barrier) &&
52+ (dir & (BarrierPositiveX | BarrierNegativeX))) {
53 /* handle immediate barrier adjacency, moving away */
54 if (dir & BarrierPositiveX && x1 == barrier->x1)
55 return FALSE;
56@@ -1129,7 +1137,8 @@
57 *distance = 0;
58 return TRUE;
59 }
60- } else {
61+ } else if (barrier_is_horizontal(barrier) &&
62+ (dir & (BarrierPositiveY | BarrierNegativeY))){
63 /* handle immediate barrier adjacency, moving away */
64 if (dir & BarrierPositiveY && y1 == barrier->y1)
65 return FALSE;
66@@ -1231,6 +1240,127 @@
67 }
68 }
69
70+/*
71+ * ConstrainCursorHarder is called from the SIGIO context.
72+ * This means we cannot safely send a client event from anything in
73+ * CursorConstrainCursorHarder's callgraph.
74+ *
75+ * Allocate a set of WorkQueue items to use.
76+ */
77+
78+struct BarrierEventStore {
79+ WorkQueueRec wq_item;
80+ xXFixesBarrierNotifyEvent ev;
81+ Bool in_use;
82+};
83+
84+/* Let's guess that 100 events is enough of a buffer. */
85+#define BARRIER_EVENT_QUEUE_SIZE 100
86+struct BarrierEventStore barrierEventQueue[BARRIER_EVENT_QUEUE_SIZE];
87+
88+static void
89+CursorWorkQueueDestroyProc (WorkQueuePtr this)
90+{
91+ struct BarrierEventStore *store;
92+ store = container_of (this, struct BarrierEventStore, wq_item);
93+
94+ store->in_use = FALSE;
95+}
96+
97+static Bool
98+CursorSendBarrierEvent (ClientPtr client, pointer eventStore)
99+{
100+ struct BarrierEventStore *store = (struct BarrierEventStore *)eventStore;
101+ WriteEventsToClient (client, 1, (xEvent *)&store->ev);
102+
103+ return TRUE;
104+}
105+
106+static struct BarrierEventStore *
107+CursorFindFreeEventStore (void)
108+{
109+ for (int i = 0; i < BARRIER_EVENT_QUEUE_SIZE; ++i) {
110+ if (!barrierEventQueue[i].in_use) {
111+ return &barrierEventQueue[i];
112+ }
113+ }
114+ return NULL;
115+}
116+
117+static void
118+QueueBarrierEvent(CursorScreenPtr cs, struct PointerBarrier *barrier,
119+ int x, int y, int velocity, Bool threshold_exceeded)
120+{
121+ PointerBarrierEventClientPtr client;
122+ struct BarrierEventStore *store;
123+ list_for_each_entry(client, &cs->barrierClients, entry) {
124+ store = CursorFindFreeEventStore ();
125+ if (store == NULL) {
126+ ErrorF ("[xfixes] Barrier event queue full. Dropping further events\n");
127+ return;
128+ }
129+
130+ store->in_use = TRUE;
131+
132+ store->ev.type = XFixesEventBase + XFixesBarrierNotify;
133+ store->ev.subtype = threshold_exceeded ? XFixesBarrierThresholdExceededNotify :
134+ XFixesBarrierHitNotify;
135+ store->ev.event_id = barrier->barrierEventID;
136+ store->ev.barrier = barrier->barrier;
137+ store->ev.x = x;
138+ store->ev.y = y;
139+ store->ev.velocity = velocity;
140+ store->ev.timestamp = currentTime.milliseconds;
141+
142+ if (client->client->swapped) {
143+ int n;
144+
145+ swapl(&store->ev.event_id, n);
146+ swapl(&store->ev.barrier, n);
147+ swaps(&store->ev.x, n);
148+ swaps(&store->ev.y, n);
149+ swapl(&store->ev.velocity, n);
150+ swapl(&store->ev.timestamp, n);
151+ }
152+
153+ store->wq_item.function = CursorSendBarrierEvent;
154+ store->wq_item.client = client->client;
155+ store->wq_item.closure = store;
156+ store->wq_item.destroyProc = CursorWorkQueueDestroyProc;
157+
158+ QueueWorkItem (&store->wq_item);
159+ }
160+}
161+
162+static void
163+barrier_calculate_velocity_components (int x1, int y1, int x2, int y2,
164+ int *vel_x, int *vel_y)
165+{
166+ static CARD32 last_timestamp = 0;
167+ CARD32 timestamp = GetTimeInMillis();
168+ int dx, dy;
169+ int dt = timestamp - last_timestamp;
170+
171+ if (last_timestamp == 0) {
172+ /* Not much we can do for the first event */
173+ *vel_x = 0;
174+ *vel_y = 0;
175+ last_timestamp = timestamp;
176+ return;
177+ }
178+
179+ /* Lets not divide by zero if we can avoid it */
180+ dt = dt > 0 ? dt : 1;
181+
182+ dx = x2 - x1;
183+ dy = y2 - y1;
184+
185+ *vel_x = abs(dx) * 1000.0 / dt;
186+ *vel_y = abs(dy) * 1000.0 / dt;
187+
188+ last_timestamp = timestamp;
189+}
190+
191 static void
192 CursorConstrainCursorHarder(DeviceIntPtr dev, ScreenPtr screen, int mode, int *x, int *y)
193 {
194@@ -1238,12 +1368,23 @@
195
196 if (!list_is_empty(&cs->barriers) && !IsFloating(dev) && mode == Relative) {
197 int ox, oy;
198+ int vel_x, vel_y;
199 int dir;
200 struct PointerBarrier *nearest = NULL;
201+ PointerBarrierClientPtr c;
202
203 /* where are we coming from */
204 miPointerGetPosition(dev, &ox, &oy);
205
206+ /* Use the unclamped values, if available. If not, *x, *y
207+ * will have to do.
208+ * NOTE: We should never get here with unclamped values unset.
209+ */
210+ if (unclamped_prex == -1 || unclamped_prey == -1) {
211+ unclamped_prex = *x;
212+ unclamped_prey = *y;
213+ }
214+
215 /* How this works:
216 * Given the origin and the movement vector, get the nearest barrier
217 * to the origin that is blocking the movement.
218@@ -1251,11 +1392,27 @@
219 * Then, check from the clamped intersection to the original
220 * destination, again finding the nearest barrier and clamping.
221 */
222- dir = barrier_get_direction(ox, oy, *x, *y);
223+ dir = barrier_get_direction(ox, oy, unclamped_prex, unclamped_prey);
224+ barrier_calculate_velocity_components(ox, oy, unclamped_prex, unclamped_prey, &vel_x, &vel_y);
225
226- nearest = barrier_find_nearest(cs, dir, ox, oy, *x, *y);
227+ nearest = barrier_find_nearest(cs, dir, ox, oy, unclamped_prex, unclamped_prey);
228 if (nearest) {
229- barrier_clamp_to_barrier(nearest, dir, x, y);
230+ int velocity = barrier_is_vertical(nearest) ? vel_x : vel_y;
231+ Bool threshold_exceeded = (nearest->velocity != 0) &&
232+ (velocity > nearest->velocity);
233+
234+ if (!nearest->lastHit) {
235+ /* This is the start of a new barrier event */
236+ nearest->barrierEventID++;
237+ }
238+
239+ if ((!threshold_exceeded || nearest->lastHit) &&
240+ (nearest->barrierEventID != nearest->releaseEventID)) {
241+ barrier_clamp_to_barrier(nearest, dir, x, y);
242+ nearest->hit = TRUE;
243+ }
244+
245+ QueueBarrierEvent(cs, nearest, *x, *y, velocity, threshold_exceeded);
246
247 if (barrier_is_vertical(nearest)) {
248 dir &= ~(BarrierNegativeX | BarrierPositiveX);
249@@ -1265,11 +1422,31 @@
250 oy = *y;
251 }
252
253- nearest = barrier_find_nearest(cs, dir, ox, oy, *x, *y);
254+ nearest = barrier_find_nearest(cs, dir, ox, oy, unclamped_prex, unclamped_prey);
255 if (nearest) {
256- barrier_clamp_to_barrier(nearest, dir, x, y);
257+ velocity = barrier_is_vertical(nearest) ? vel_x : vel_y;
258+ threshold_exceeded = (nearest->velocity != 0) &&
259+ (velocity > nearest->velocity);
260+
261+ if (!nearest->lastHit) {
262+ /* This is the start of a new barrier event */
263+ nearest->barrierEventID++;
264+ }
265+
266+ if ((!threshold_exceeded || nearest->lastHit) &&
267+ (nearest->barrierEventID != nearest->releaseEventID)) {
268+ barrier_clamp_to_barrier(nearest, dir, x, y);
269+ nearest->hit = TRUE;
270+ }
271+
272+ QueueBarrierEvent(cs, nearest, *x, *y, velocity, threshold_exceeded);
273 }
274 }
275+
276+ list_for_each_entry(c, &cs->barriers, entry) {
277+ c->barrier.lastHit = c->barrier.hit;
278+ c->barrier.hit = FALSE;
279+ }
280 }
281
282 if (cs->ConstrainCursorHarder) {
283@@ -1284,15 +1461,45 @@
284 xXFixesCreatePointerBarrierReq *stuff)
285 {
286 CursorScreenPtr cs = GetCursorScreen(screen);
287- struct PointerBarrierClient *ret = malloc(sizeof(*ret));
288+ struct PointerBarrierClient *ret = calloc(sizeof(*ret), 1);
289
290 if (ret) {
291 ret->screen = screen;
292+ ret->barrier.barrier = stuff->barrier;
293 ret->barrier.x1 = min(stuff->x1, stuff->x2);
294 ret->barrier.x2 = max(stuff->x1, stuff->x2);
295 ret->barrier.y1 = min(stuff->y1, stuff->y2);
296 ret->barrier.y2 = max(stuff->y1, stuff->y2);
297 ret->barrier.directions = stuff->directions & 0x0f;
298+ ret->barrier.velocity = 0;
299+ ret->barrier.barrierEventID = 0;
300+ if (barrier_is_horizontal(&ret->barrier))
301+ ret->barrier.directions &= ~(BarrierPositiveX | BarrierNegativeX);
302+ if (barrier_is_vertical(&ret->barrier))
303+ ret->barrier.directions &= ~(BarrierPositiveY | BarrierNegativeY);
304+ list_add(&ret->entry, &cs->barriers);
305+ }
306+
307+ return ret;
308+}
309+
310+static struct PointerBarrierClient *
311+CreatePointerBarrierVelocityClient(ScreenPtr screen, ClientPtr client,
312+ xXFixesCreatePointerBarrierVelocityReq *stuff)
313+{
314+ CursorScreenPtr cs = GetCursorScreen(screen);
315+ struct PointerBarrierClient *ret = calloc(sizeof(*ret), 1);
316+
317+ if (ret) {
318+ ret->screen = screen;
319+ ret->barrier.barrier = stuff->barrier;
320+ ret->barrier.x1 = min(stuff->x1, stuff->x2);
321+ ret->barrier.x2 = max(stuff->x1, stuff->x2);
322+ ret->barrier.y1 = min(stuff->y1, stuff->y2);
323+ ret->barrier.y2 = max(stuff->y1, stuff->y2);
324+ ret->barrier.directions = stuff->directions & 0x0f;
325+ ret->barrier.velocity = stuff->velocity;
326+ ret->barrier.barrierEventID = 0;
327 if (barrier_is_horizontal(&ret->barrier))
328 ret->barrier.directions &= ~(BarrierPositiveX | BarrierNegativeX);
329 if (barrier_is_vertical(&ret->barrier))
330@@ -1365,6 +1572,69 @@
331 return ProcXFixesVector[stuff->xfixesReqType](client);
332 }
333
334+int
335+ProcXFixesCreatePointerBarrierVelocity (ClientPtr client)
336+{
337+ int err;
338+ WindowPtr pWin;
339+ struct PointerBarrierClient *barrier;
340+ struct PointerBarrier b;
341+ REQUEST (xXFixesCreatePointerBarrierVelocityReq);
342+
343+ REQUEST_SIZE_MATCH(xXFixesCreatePointerBarrierVelocityReq);
344+ LEGAL_NEW_RESOURCE(stuff->barrier, client);
345+
346+ err = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
347+ if (err != Success) {
348+ client->errorValue = stuff->window;
349+ return err;
350+ }
351+
352+ /* This sure does need fixing. */
353+ if (stuff->num_devices)
354+ return BadImplementation;
355+
356+ b.x1 = stuff->x1;
357+ b.x2 = stuff->x2;
358+ b.y1 = stuff->y1;
359+ b.y2 = stuff->y2;
360+
361+ if (!barrier_is_horizontal(&b) && !barrier_is_vertical(&b))
362+ return BadValue;
363+
364+ /* no 0-sized barriers */
365+ if (barrier_is_horizontal(&b) && barrier_is_vertical(&b))
366+ return BadValue;
367+
368+ if (!(barrier = CreatePointerBarrierVelocityClient(pWin->drawable.pScreen,
369+ client, stuff)))
370+ return BadAlloc;
371+
372+ if (!AddResource(stuff->barrier, PointerBarrierType, &barrier->barrier))
373+ return BadAlloc;
374+
375+ return Success;
376+}
377+
378+int
379+SProcXFixesCreatePointerBarrierVelocity (ClientPtr client)
380+{
381+ int n;
382+ REQUEST(xXFixesCreatePointerBarrierVelocityReq);
383+
384+ swaps(&stuff->length, n);
385+ REQUEST_SIZE_MATCH(xXFixesCreatePointerBarrierReq);
386+ swapl(&stuff->barrier, n);
387+ swapl(&stuff->window, n);
388+ swaps(&stuff->x1, n);
389+ swaps(&stuff->y1, n);
390+ swaps(&stuff->x2, n);
391+ swaps(&stuff->y2, n);
392+ swapl(&stuff->directions, n);
393+ swapl(&stuff->velocity, n);
394+ return ProcXFixesVector[stuff->xfixesReqType](client);
395+}
396+
397 static int
398 CursorFreeBarrier(void *data, XID id)
399 {
400@@ -1421,6 +1691,118 @@
401 return ProcXFixesVector[stuff->xfixesReqType](client);
402 }
403
404+static int
405+CursorFreeBarrierClient(void *data, XID id)
406+{
407+ PointerBarrierEventClientPtr client = data, c;
408+ ScreenPtr screen = client->screen;
409+ CursorScreenPtr cs = GetCursorScreen(screen);
410+
411+ /* find and unlink from the screen private */
412+ list_for_each_entry(c, &cs->barrierClients, entry) {
413+ if (c == client) {
414+ list_del(&c->entry);
415+ break;
416+ }
417+ }
418+
419+ free(client);
420+ return Success;
421+}
422+
423+static struct PointerBarrierEventClient *
424+CreatePointerBarrierEventClient(ScreenPtr screen, ClientPtr client,
425+ xXFixesSelectBarrierInputReq *stuff)
426+{
427+ CursorScreenPtr cs = GetCursorScreen(screen);
428+ struct PointerBarrierEventClient *ret = malloc(sizeof(*ret));
429+
430+ if (ret) {
431+ ret->screen = screen;
432+ ret->client = client;
433+ ret->eventMask = stuff->eventMask;
434+ ret->window = stuff->window;
435+ ret->resource = FakeClientID (client->index);
436+ list_add(&ret->entry, &cs->barrierClients);
437+ }
438+
439+ return ret;
440+}
441+
442+int
443+ProcXFixesSelectBarrierInput (ClientPtr client)
444+{
445+ int err;
446+ WindowPtr pWin;
447+ struct PointerBarrierEventClient *eventClient;
448+ REQUEST (xXFixesSelectBarrierInputReq);
449+
450+ REQUEST_SIZE_MATCH(xXFixesSelectBarrierInputReq);
451+
452+ err = dixLookupWindow(&pWin , stuff->window, client, DixReadAccess);
453+ if (err != Success) {
454+ client->errorValue = stuff->window;
455+ return err;
456+ }
457+
458+ if (!(eventClient = CreatePointerBarrierEventClient(pWin->drawable.pScreen,
459+ client,
460+ stuff)))
461+ return BadAlloc;
462+
463+ if (!AddResource (eventClient->resource, PointerBarrierClientType, eventClient))
464+ return BadAlloc;
465+
466+ return Success;
467+}
468+
469+int
470+SProcXFixesSelectBarrierInput (ClientPtr client)
471+{
472+ int n;
473+ REQUEST(xXFixesSelectBarrierInputReq);
474+
475+ swaps(&stuff->length, n);
476+ REQUEST_SIZE_MATCH(xXFixesSelectBarrierInputReq);
477+ swapl(&stuff->window, n);
478+ swapl(&stuff->eventMask, n);
479+ return ProcXFixesVector[stuff->xfixesReqType](client);
480+}
481+
482+int
483+ProcXFixesBarrierReleasePointer (ClientPtr client)
484+{
485+ int err;
486+ struct PointerBarrier *barrier;
487+ REQUEST (xXFixesBarrierReleasePointerReq);
488+ REQUEST_SIZE_MATCH(xXFixesBarrierReleasePointerReq);
489+
490+ err = dixLookupResourceByType((void **)&barrier, stuff->barrier,
491+ PointerBarrierType, client,
492+ DixReadAccess);
493+ if (err != Success) {
494+ client->errorValue = stuff->barrier;
495+ return err;
496+ }
497+
498+ barrier->releaseEventID = stuff->event_id;
499+
500+ return Success;
501+}
502+
503+int
504+SProcXFixesBarrierReleasePointer (ClientPtr client)
505+{
506+ int n;
507+ REQUEST(xXFixesBarrierReleasePointerReq);
508+
509+ swaps(&stuff->length, n);
510+ REQUEST_SIZE_MATCH(xXFixesBarrierReleasePointerReq);
511+ swapl(&stuff->barrier, n);
512+ swapl(&stuff->event_id, n);
513+ return ProcXFixesVector[stuff->xfixesReqType](client);
514+}
515+
516 Bool
517 XFixesCursorInit (void)
518 {
519@@ -1441,6 +1823,7 @@
520 if (!cs)
521 return FALSE;
522 list_init(&cs->barriers);
523+ list_init(&cs->barrierClients);
524 Wrap (cs, pScreen, CloseScreen, CursorCloseScreen);
525 Wrap (cs, pScreen, DisplayCursor, CursorDisplayCursor);
526 Wrap (cs, pScreen, ConstrainCursorHarder, CursorConstrainCursorHarder);
527@@ -1455,8 +1838,10 @@
528 "XFixesCursorWindow");
529 PointerBarrierType = CreateNewResourceType(CursorFreeBarrier,
530 "XFixesPointerBarrier");
531+ PointerBarrierClientType = CreateNewResourceType(CursorFreeBarrierClient,
532+ "XFixesPointerBarrierClient");
533
534 return CursorClientType && CursorHideCountType && CursorWindowType &&
535- PointerBarrierType;
536+ PointerBarrierType && PointerBarrierClientType;
537 }
538
539Index: xorg-server/xfixes/xfixes.c
540===================================================================
541--- xorg-server.orig/xfixes/xfixes.c 2012-03-07 22:24:45.592697117 +1100
542+++ xorg-server/xfixes/xfixes.c 2012-03-08 07:40:35.480111388 +1100
543@@ -100,6 +100,7 @@
544 X_XFixesExpandRegion, /* Version 3 */
545 X_XFixesShowCursor, /* Version 4 */
546 X_XFixesDestroyPointerBarrier, /* Version 5 */
547+ X_XFixesBarrierReleasePointer, /* Version 6 */
548 };
549
550 #define NUM_VERSION_REQUESTS (sizeof (version_requests) / sizeof (version_requests[0]))
551@@ -143,6 +144,10 @@
552 /*************** Version 5 ****************/
553 ProcXFixesCreatePointerBarrier,
554 ProcXFixesDestroyPointerBarrier,
555+/*************** Version 6 ****************/
556+ ProcXFixesCreatePointerBarrierVelocity,
557+ ProcXFixesSelectBarrierInput,
558+ ProcXFixesBarrierReleasePointer,
559 };
560
561 static int
562@@ -209,6 +214,10 @@
563 /*************** Version 5 ****************/
564 SProcXFixesCreatePointerBarrier,
565 SProcXFixesDestroyPointerBarrier,
566+/*************** Version 6 ****************/
567+ SProcXFixesCreatePointerBarrierVelocity,
568+ SProcXFixesSelectBarrierInput,
569+ SProcXFixesBarrierReleasePointer,
570 };
571
572 static int
573Index: xorg-server/xfixes/xfixes.h
574===================================================================
575--- xorg-server.orig/xfixes/xfixes.h 2012-03-07 22:24:45.608697118 +1100
576+++ xorg-server/xfixes/xfixes.h 2012-03-08 07:40:35.480111388 +1100
577@@ -28,6 +28,7 @@
578 #define _XFIXES_H_
579
580 #include "resource.h"
581+#include "list.h"
582
583 extern _X_EXPORT RESTYPE RegionResType;
584 extern _X_EXPORT RESTYPE PointerBarrierType;
585@@ -52,9 +53,25 @@
586 extern _X_EXPORT RegionPtr
587 XFixesRegionCopy (RegionPtr pRegion);
588
589+typedef struct PointerBarrierEventClient *PointerBarrierEventClientPtr;
590+
591+struct PointerBarrierEventClient {
592+ ScreenPtr screen;
593+ ClientPtr client;
594+ CARD32 eventMask;
595+ XID window;
596+ XID resource;
597+ struct list entry;
598+};
599+
600 struct PointerBarrier {
601+ XID barrier;
602 CARD16 x1, x2, y1, y2;
603 CARD32 directions;
604+ CARD32 velocity;
605+ CARD32 barrierEventID;
606+ CARD32 releaseEventID;
607+ Bool hit, lastHit;
608 };
609
610
611Index: xorg-server/xfixes/xfixesint.h
612===================================================================
613--- xorg-server.orig/xfixes/xfixesint.h 2012-03-07 22:24:45.616697118 +1100
614+++ xorg-server/xfixes/xfixesint.h 2012-03-08 07:40:35.480111388 +1100
615@@ -59,6 +59,7 @@
616 #include "windowstr.h"
617 #include "selection.h"
618 #include "xfixes.h"
619+#include "list.h"
620
621 extern int XFixesEventBase;
622
623@@ -293,6 +294,26 @@
624 int
625 SProcXFixesDestroyPointerBarrier (ClientPtr client);
626
627+/* Version 6 */
628+
629+int
630+ProcXFixesSelectBarrierInput (ClientPtr client);
631+
632+int
633+SProcXFixesSelectBarrierInput (ClientPtr client);
634+
635+int
636+ProcXFixesCreatePointerBarrierVelocity (ClientPtr client);
637+
638+int
639+SProcXFixesCreatePointerBarrierVelocity (ClientPtr client);
640+
641+int
642+ProcXFixesBarrierReleasePointer (ClientPtr client);
643+
644+int
645+SProcXFixesBarrierReleasePointer (ClientPtr client);
646+
647 /* Xinerama */
648 extern int (*PanoramiXSaveXFixesVector[XFixesNumberRequests])(ClientPtr);
649 void PanoramiXFixesInit (void);
650Index: xorg-server/dix/getevents.c
651===================================================================
652--- xorg-server.orig/dix/getevents.c 2012-03-07 22:24:45.624697119 +1100
653+++ xorg-server/dix/getevents.c 2012-03-08 11:02:31.739464474 +1100
654@@ -79,6 +79,12 @@
655 InternalEvent* InputEventList = NULL;
656
657 /**
658+ * xfixes/cursor.c wants the unclamped (x,y) values for velocity
659+ * calculation. Export them here.
660+ */
661+int unclamped_prex = -1, unclamped_prey = -1;
662+
663+/**
664 * Pick some arbitrary size for Xi motion history.
665 */
666 int
667@@ -903,7 +909,15 @@
668 /* miPointerSetPosition takes care of crossing screens for us, as well as
669 * clipping to the current screen. Coordinates returned are in desktop
670 * coord system */
671+ /**
672+ * Hack to pass the unclipped values through to the pointer barrier code.
673+ * Required (for now) to calculate the velocity.
674+ */
675+ unclamped_prex = (int)floor(*screenx) - scr->x;
676+ unclamped_prey = (int)floor(*screeny) - scr->y;
677 scr = miPointerSetPosition(dev, mode, screenx, screeny);
678+ unclamped_prex = -1;
679+ unclamped_prey = -1;
680
681 /* If we were constrained, rescale x/y from the screen coordinates so
682 * the device valuators reflect the correct position. For screen
683Index: xorg-server/test/gtest/xfixes_barriers.cpp
684===================================================================
685--- /dev/null 1970-01-01 00:00:00.000000000 +0000
686+++ xorg-server/test/gtest/xfixes_barriers.cpp 2012-03-08 07:42:49.188104249 +1100
687@@ -0,0 +1,828 @@
688+/*
689+
690+Copyright (c) 2012, Canonical Ltd
691+
692+Permission is hereby granted, free of charge, to any person obtaining a
693+copy of this software and associated documentation files (the "Software"),
694+to deal in the Software without restriction, including without limitation
695+the rights to use, copy, modify, merge, publish, distribute, sublicense,
696+and/or sell copies of the Software, and to permit persons to whom the
697+Software is furnished to do so, subject to the following conditions:
698+
699+The above copyright notice and this permission notice (including the next
700+paragraph) shall be included in all copies or substantial portions of the
701+Software.
702+
703+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
704+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
705+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
706+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
707+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
708+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
709+DEALINGS IN THE SOFTWARE.
710+*/
711+
712+#include <iostream>
713+#include <sys/time.h>
714+#include <unistd.h>
715+#include <gtest/gtest.h>
716+#include <xorg/gtest/test.h>
717+#include <xorg/gtest/environment.h>
718+#include <X11/Xlib.h>
719+#include <X11/extensions/XTest.h>
720+#include <X11/extensions/Xfixes.h>
721+
722+
723+int main (int argc, char **argv)
724+{
725+ ::testing::InitGoogleTest (&argc, argv);
726+ xorg::testing::Environment* environment = new xorg::testing::Environment ();
727+ environment->set_conf_file (XORG_DUMMY_CONF);
728+ environment->set_server (XORG_BINARY);
729+ testing::AddGlobalTestEnvironment (environment);
730+ return RUN_ALL_TESTS ();
731+}
732+
733+class BarrierTest : public xorg::testing::Test {
734+ public:
735+ ::Display *dpy;
736+ static XErrorEvent *lastError;
737+ int xtest_eventbase;
738+ int xtest_errorbase;
739+ int fixes_eventbase;
740+ int fixes_errorbase;
741+
742+ void AssertPointerPosition (int expected_x, int expected_y)
743+ {
744+ int x, y, unused_int;
745+ unsigned int unused_uint;
746+ Window unused_win;
747+
748+ XQueryPointer (Display (), DefaultRootWindow (Display ()),
749+ &unused_win, &unused_win, &x, &y,
750+ &unused_int, &unused_int, &unused_uint);
751+
752+ ASSERT_TRUE (x == expected_x && y == expected_y) <<
753+ "Incorrect pointer position: Expected ("<<
754+ expected_x<< ", "<<expected_y<<"), got "<<
755+ "("<<x<<", "<<y<<")\n";
756+ }
757+
758+ bool WaitForXEvent (int msTimeout = 1000)
759+ {
760+ fd_set fds;
761+ int xfd = ConnectionNumber (Display ());
762+ struct timeval tv;
763+ int retval;
764+
765+ FD_ZERO (&fds);
766+ FD_SET (xfd, &fds);
767+
768+ tv.tv_sec = msTimeout / 1000;
769+ tv.tv_usec = (msTimeout % 1000) * 1000;
770+
771+ retval = select (xfd + 1, &fds, NULL, NULL, &tv);
772+
773+ EXPECT_NE (-1, retval)<<"Error waiting for X event";
774+
775+ return retval;
776+ }
777+
778+ protected:
779+ virtual void SetUp ()
780+ {
781+ ASSERT_NO_FATAL_FAILURE (xorg::testing::Test::SetUp());
782+
783+ dpy = Display ();
784+ int major = 2, minor = 2;
785+ ASSERT_TRUE (XTestQueryExtension (dpy,
786+ &xtest_eventbase, &xtest_errorbase,
787+ &major, &minor));
788+ ASSERT_EQ (2, major);
789+ ASSERT_TRUE (minor >= 2);
790+
791+ major = 6;
792+ minor = 0;
793+ XFixesQueryVersion (dpy, &major, &minor);
794+ ASSERT_EQ (6, major);
795+ ASSERT_TRUE (minor >= 0);
796+
797+ ASSERT_TRUE (XFixesQueryExtension (dpy,
798+ &fixes_eventbase, &fixes_errorbase));
799+
800+ lastError = new XErrorEvent;
801+ XSetErrorHandler (ErrorHandler);
802+ }
803+
804+ private:
805+ static int ErrorHandler (::Display *dpy, XErrorEvent *error)
806+ {
807+ memcpy (lastError, error, sizeof (*lastError));
808+ return 0;
809+ }
810+};
811+
812+XErrorEvent *BarrierTest::lastError = NULL;
813+
814+TEST_F (BarrierTest, CreateVerticalBarrierSucceeds)
815+{
816+ PointerBarrier barrier;
817+ barrier = XFixesCreatePointerBarrier (dpy, DefaultRootWindow(dpy),
818+ 100, 0,
819+ 100, 100,
820+ 0,
821+ 0, NULL);
822+ ASSERT_NE(None, barrier);
823+}
824+
825+TEST_F (BarrierTest, CreateHorizontalBarrierSucceds)
826+{
827+ PointerBarrier barrier;
828+ barrier = XFixesCreatePointerBarrier (dpy, DefaultRootWindow(dpy),
829+ 100, 100,
830+ 200, 100,
831+ 0,
832+ 0, NULL);
833+ ASSERT_NE(None, barrier);
834+}
835+
836+TEST_F (BarrierTest, CreateNonAxisAlignedBarrierFails)
837+{
838+ XFixesCreatePointerBarrier (dpy, DefaultRootWindow(dpy),
839+ 0, 0,
840+ 100, 100,
841+ 0,
842+ 0, NULL);
843+ XSync (Display (), false);
844+ ASSERT_EQ(BadValue, lastError->error_code);
845+}
846+
847+TEST_F (BarrierTest, VerticalBidirectionalBarrierBlocksRelativeMotion)
848+{
849+ int barrier_x = 100;
850+ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
851+ barrier_x, 0,
852+ barrier_x, 300,
853+ 0, 0, NULL);
854+
855+ int x = 200, y = 100, dx = -200, dy = 0;
856+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
857+ x, y, 0);
858+
859+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
860+
861+ // Relative motion should block on barrier
862+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
863+
864+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (barrier_x, y));
865+}
866+
867+TEST_F (BarrierTest, VerticalPositiveXBarrierBlocksMotion)
868+{
869+ int barrier_x = 100;
870+ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
871+ barrier_x, 0,
872+ barrier_x, 300,
873+ BarrierPositiveX, 0, NULL);
874+ int x = 200, y = 100, dx = -200, dy = 0;
875+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
876+ x, y, 0);
877+
878+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
879+
880+ // Relative motion in -ve X direction should block on barrier
881+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
882+
883+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (barrier_x, y + dy));
884+
885+ x = 0, y = 100, dx = 200, dy = 0;
886+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
887+ x, y, 0);
888+
889+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
890+
891+ // Relative motion in +ve X direction should ignore barrier
892+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
893+
894+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, y + dy));
895+}
896+
897+TEST_F (BarrierTest, VerticalNegativeXBarrierBlocksMotion)
898+{
899+ int barrier_x = 100;
900+ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
901+ barrier_x, 0,
902+ barrier_x, 300,
903+ BarrierNegativeX,
904+ 0, NULL);
905+
906+ int x = 200, y = 100, dx = -200, dy = 0;
907+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
908+ x, y, 0);
909+
910+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
911+
912+ // Relative motion in -ve X direction should ignore barrier
913+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
914+
915+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, y + dy));
916+
917+ x = 0, y = 100, dx = 200, dy = 0;
918+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
919+ x, y, 0);
920+
921+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
922+
923+ // Relative motion in +ve X direction should block on barrier
924+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
925+
926+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (barrier_x - 1, y + dy));
927+}
928+
929+TEST_F (BarrierTest, HorizontalBidirectionalBarrierBlocksRelativeMotion)
930+{
931+ int barrier_y = 100;
932+ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
933+ 0, barrier_y,
934+ 300, barrier_y,
935+ 0, 0, NULL);
936+
937+ int x = 200, y = 0;
938+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
939+ x, y, 0);
940+
941+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
942+
943+ // Relative motion in +ve Y direction should block on barrier
944+ int dx = 0, dy = 200;
945+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
946+
947+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, barrier_y - 1));
948+
949+ x = 100, y = 200;
950+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
951+ x, y, 0);
952+
953+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
954+
955+ // Relative motion in -ve Y direction should block on barrier
956+ dx = 0, dy = -200;
957+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
958+
959+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, barrier_y));
960+}
961+
962+TEST_F (BarrierTest, HorizontalPositiveYBarrierBlocksMotion)
963+{
964+ int barrier_y = 100;
965+ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
966+ 0, barrier_y,
967+ 300, barrier_y,
968+ BarrierPositiveY, 0, NULL);
969+
970+ int x = 200, y = 0;
971+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
972+ x, y, 0);
973+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
974+
975+ // Relative motion in +ve Y direction should ignore barrier
976+ int dx = 0, dy = 200;
977+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
978+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, y + dy));
979+
980+ x = 100, y = 200;
981+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
982+ x, y, 0);
983+
984+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
985+
986+ // Relative motion in -ve Y direction should block on barrier
987+ dx = 0, dy = -200;
988+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
989+
990+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, barrier_y));
991+}
992+
993+TEST_F (BarrierTest, HorizontalNegativeYBarrierBlocksMotion)
994+{
995+ int barrier_y = 100;
996+ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
997+ 0, barrier_y,
998+ 300, barrier_y,
999+ BarrierNegativeY, 0, NULL);
1000+
1001+ int x = 200, y = 0;
1002+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1003+ x, y, 0);
1004+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1005+
1006+ // Relative motion in +ve Y direction should block on barrier
1007+ int dx = 0, dy = 200;
1008+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
1009+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, barrier_y - 1));
1010+
1011+ x = 100, y = 200;
1012+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1013+ x, y, 0);
1014+
1015+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1016+
1017+ // Relative motion in -ve Y direction should ignore barrier
1018+ dx = 0, dy = -200;
1019+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
1020+
1021+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, y + dy));
1022+}
1023+
1024+TEST_F (BarrierTest, DestroyPointerBarrierSucceeds)
1025+{
1026+ int barrier_x = 100;
1027+ PointerBarrier barrier;
1028+ barrier = XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
1029+ barrier_x, 0,
1030+ barrier_x, 300,
1031+ 0, 0, NULL);
1032+
1033+ int x = 0, y = 200;
1034+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1035+ x, y, 0);
1036+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1037+
1038+ // Check that the barrier exists before we destroy it.
1039+ int dx = 200, dy = 0;
1040+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
1041+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (barrier_x - 1, y + dy));
1042+
1043+ // Destroy the barrier...
1044+ XFixesDestroyPointerBarrier (Display (), barrier);
1045+
1046+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1047+ x, y, 0);
1048+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1049+
1050+ // There should be no barrier to block this.
1051+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
1052+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, y + dy));
1053+}
1054+
1055+TEST_F (BarrierTest, BarrierIgnoresNonsensicalDirections)
1056+{
1057+ int barrier_x = 100;
1058+ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
1059+ barrier_x, 0,
1060+ barrier_x, 300,
1061+ BarrierPositiveY | BarrierNegativeY,
1062+ 0, NULL);
1063+
1064+ int x = 200, y = 100;
1065+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1066+ x, y, 0);
1067+
1068+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1069+
1070+ int dx = -200, dy = 0;
1071+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
1072+
1073+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (barrier_x, y + dy));
1074+
1075+ int barrier_y = 100;
1076+ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
1077+ 0, barrier_y,
1078+ 400, barrier_y,
1079+ BarrierPositiveX | BarrierNegativeX,
1080+ 0, NULL);
1081+
1082+ x = 100, y = 200;
1083+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1084+ x, y, 0);
1085+
1086+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1087+
1088+ dx = 0, dy = -200;
1089+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
1090+
1091+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, barrier_y));
1092+}
1093+
1094+TEST_F (BarrierTest, VerticalBarrierEdges)
1095+{
1096+ int barrier_x = 300, barrier_y1 = 300 , barrier_y2 = 500;
1097+ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
1098+ barrier_x, barrier_y1,
1099+ barrier_x, barrier_y2,
1100+ 0, 0, NULL);
1101+
1102+ int x = barrier_x + 100, y = barrier_y1 - 1;
1103+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1104+ x, y, 0);
1105+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1106+
1107+ // Motion should take us past the top of the barrier...
1108+ int dx = -200, dy = 0;
1109+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
1110+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, y + dy));
1111+
1112+ x = barrier_x + 100, y = barrier_y1;
1113+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1114+ x, y, 0);
1115+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1116+
1117+ // Motion should hit the top of the barrier...
1118+ dx = -200, dy = 0;
1119+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
1120+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (barrier_x, y + dy));
1121+
1122+ x = barrier_x + 100, y = barrier_y2;
1123+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1124+ x, y, 0);
1125+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1126+
1127+ // Motion should hit the bottom of the barrier...
1128+ dx = -200, dy = 0;
1129+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
1130+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (barrier_x, y + dy));
1131+
1132+ x = barrier_x + 100, y = barrier_y2 + 1;
1133+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1134+ x, y, 0);
1135+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1136+
1137+ // Motion should take us past the bottom of the barrier...
1138+ dx = -200, dy = 0;
1139+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
1140+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, y + dy));
1141+}
1142+
1143+TEST_F (BarrierTest, HorizontalBarrierEdges)
1144+{
1145+ int barrier_x1 = 200, barrier_x2 = 500, barrier_y = 300;
1146+ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
1147+ barrier_x1, barrier_y,
1148+ barrier_x2, barrier_y,
1149+ 0, 0, NULL);
1150+
1151+ int x = barrier_x1 - 1, y = barrier_y - 100;
1152+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1153+ x, y, 0);
1154+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1155+
1156+ // Motion should take us past the left edge of the barrier...
1157+ int dx = 0, dy = 200;
1158+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
1159+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, y + dy));
1160+
1161+ x = barrier_x1, y = barrier_y - 100;
1162+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1163+ x, y, 0);
1164+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1165+
1166+ // Motion should hit the top of the barrier...
1167+ dx = 0, dy = 200;
1168+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
1169+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, barrier_y - 1));
1170+
1171+ x = barrier_x2, y = barrier_y - 100;
1172+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1173+ x, y, 0);
1174+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1175+
1176+ // Motion should hit the bottom of the barrier...
1177+ dx = 0, dy = 200;
1178+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
1179+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, barrier_y - 1));
1180+
1181+ x = barrier_x2 + 1, y = barrier_y - 100;
1182+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1183+ x, y, 0);
1184+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1185+
1186+ // Motion should take us past the bottom of the barrier...
1187+ dx = 0, dy = 200;
1188+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
1189+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, y + dy));
1190+}
1191+
1192+TEST_F (BarrierTest, CornerBlocksMotion)
1193+{
1194+ int corner_x, corner_y;
1195+ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
1196+ corner_x, corner_y,
1197+ corner_x, corner_y + 300,
1198+ 0, 0, NULL);
1199+ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
1200+ corner_x, corner_y,
1201+ corner_x + 300, corner_y,
1202+ 0, 0, NULL);
1203+
1204+ int x = corner_x + 100, y = corner_y + 100;
1205+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1206+ x, y, 0);
1207+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1208+
1209+ XTestFakeRelativeMotionEvent (Display (), -200, -200, 0);
1210+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (corner_x, corner_y));
1211+}
1212+
1213+TEST_F (BarrierTest, VerticalBarrierWithAdjacentStart)
1214+{
1215+ int barrier_x = 350;
1216+ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
1217+ barrier_x, 100,
1218+ barrier_x, 300,
1219+ 0, 0, NULL);
1220+
1221+ int x = barrier_x, y = 200;
1222+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1223+ x, y, 0);
1224+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1225+
1226+ int dx = -10, dy = 0;
1227+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
1228+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (barrier_x, y + dy));
1229+
1230+ x = barrier_x, y = 200;
1231+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1232+ x, y, 0);
1233+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1234+
1235+ dx = 10, dy = 0;
1236+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
1237+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, y + dy));
1238+
1239+ x = barrier_x - 1, y = 200;
1240+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1241+ x, y, 0);
1242+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1243+
1244+ dx = 10, dy = 0;
1245+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
1246+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (barrier_x - 1, y + dy));
1247+
1248+ x = barrier_x - 1, y = 200;
1249+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1250+ x, y, 0);
1251+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1252+
1253+ dx = -10, dy = 0;
1254+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
1255+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, y + dy));
1256+}
1257+
1258+TEST_F (BarrierTest, HorizontalBarrierWithAdjacentStart)
1259+{
1260+ int barrier_y = 300;
1261+ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
1262+ 100, barrier_y,
1263+ 400, barrier_y,
1264+ 0, 0, NULL);
1265+
1266+ int x = 240, y = barrier_y;
1267+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1268+ x, y, 0);
1269+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1270+
1271+ int dx = 0, dy = -10;
1272+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
1273+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, barrier_y));
1274+
1275+ x = 240, y = barrier_y;
1276+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1277+ x, y, 0);
1278+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1279+
1280+ dx = 0, dy = 10;
1281+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
1282+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, y + dy));
1283+
1284+ x = 240, y = barrier_y - 1;
1285+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1286+ x, y, 0);
1287+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1288+
1289+ dx = 0, dy = 10;
1290+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
1291+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, barrier_y - 1));
1292+
1293+ x = 240, y = barrier_y - 1;
1294+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1295+ x, y, 0);
1296+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1297+
1298+ dx = 0, dy = -10;
1299+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
1300+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x + dx, y + dy));
1301+}
1302+
1303+TEST_F (BarrierTest, BarrierNotifyEventFires)
1304+{
1305+ int barrier_y = 300;
1306+ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
1307+ 100, barrier_y,
1308+ 400, barrier_y,
1309+ 0, 0, NULL);
1310+
1311+ XFixesSelectBarrierInput (Display (), DefaultRootWindow (Display ()),
1312+ XFixesBarrierHitNotifyMask);
1313+
1314+ int x = 240, y = barrier_y + 50;
1315+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1316+ x, y, 0);
1317+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1318+
1319+ XTestFakeRelativeMotionEvent (Display (), 0, -100, 0);
1320+
1321+ XFlush (Display ());
1322+ ASSERT_TRUE (WaitForXEvent ())<<"Timed out waiting to receive X event";
1323+ while (XPending (Display ())) {
1324+ XEvent e;
1325+ XNextEvent (Display (), &e);
1326+ switch (e.xany.type - fixes_eventbase) {
1327+ case XFixesBarrierNotify:
1328+ return;
1329+ }
1330+ }
1331+ FAIL () << "Failed to recieve BarrierNotify event";
1332+}
1333+
1334+TEST_F (BarrierTest, RecieveOneNotifyEventPerHit)
1335+{
1336+ int barrier_x = 100;
1337+ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
1338+ barrier_x, 0,
1339+ barrier_x, 300,
1340+ 0, 0, NULL);
1341+
1342+ XFixesSelectBarrierInput (Display (), DefaultRootWindow (Display ()),
1343+ XFixesBarrierHitNotifyMask);
1344+
1345+ int x = 200, y = 100, dx = -200, dy = 0;
1346+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1347+ x, y, 0);
1348+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1349+
1350+ /* Generate 5 barrier events */
1351+ for (int i = 0; i < 5; ++i) {
1352+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
1353+ }
1354+
1355+ int barrierEventCount = 0;
1356+ XFlush (Display ());
1357+ ASSERT_TRUE (WaitForXEvent ())<<"Timed out waiting to receive X event";
1358+ while (XPending (Display ())) {
1359+ XEvent e;
1360+ XNextEvent (Display (), &e);
1361+ switch (e.xany.type - fixes_eventbase) {
1362+ case XFixesBarrierNotify:
1363+ barrierEventCount++;
1364+ break;
1365+ }
1366+ }
1367+ ASSERT_EQ (5, barrierEventCount);
1368+}
1369+
1370+TEST_F (BarrierTest, BarrierEventHasNonZeroVelocity)
1371+{
1372+ int barrier_x = 100;
1373+ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
1374+ barrier_x, 0,
1375+ barrier_x, 300,
1376+ 0, 0, NULL);
1377+
1378+ XFixesSelectBarrierInput (Display (), DefaultRootWindow (Display ()),
1379+ XFixesBarrierHitNotifyMask);
1380+
1381+ int x = 200, y = 100, dx = -200, dy = 0;
1382+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1383+ x, y, 0);
1384+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1385+
1386+ /* One relative event to ensure the server has a non-zero
1387+ * last-event-time */
1388+ XTestFakeRelativeMotionEvent (Display (), 10, 10, 0);
1389+ /* Run the pointer into the barrier */
1390+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
1391+
1392+ XFlush (Display ());
1393+ ASSERT_TRUE (WaitForXEvent ())<<"Timed out waiting to receive X event";
1394+ while (XPending (Display ())) {
1395+ XEvent e;
1396+ XNextEvent (Display (), &e);
1397+ switch (e.xany.type - fixes_eventbase) {
1398+ case XFixesBarrierNotify:
1399+ XFixesBarrierNotifyEvent *notify = (XFixesBarrierNotifyEvent *)&e;
1400+ ASSERT_LT (0, notify->velocity);
1401+ return;
1402+ }
1403+ }
1404+ FAIL () << "Failed to receive barrier event";
1405+}
1406+
1407+TEST_F (BarrierTest, ScreenEdgeVerticalBarrierEventHasNonZeroVelocity)
1408+{
1409+ int barrier_x = 0;
1410+ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
1411+ barrier_x, 0,
1412+ barrier_x, 300,
1413+ 0, 0, NULL);
1414+
1415+ XFixesSelectBarrierInput (Display (), DefaultRootWindow (Display ()),
1416+ XFixesBarrierHitNotifyMask);
1417+
1418+ int x = 100, y = 100, dx = -200, dy = 0;
1419+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1420+ x, y, 0);
1421+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1422+
1423+ /* One relative event to ensure the server has a non-zero
1424+ * last-event-time */
1425+ XTestFakeRelativeMotionEvent (Display (), 10, 10, 0);
1426+ /* Run the pointer into the barrier */
1427+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
1428+
1429+ XFlush (Display ());
1430+ ASSERT_TRUE (WaitForXEvent ())<<"Timed out waiting to receive X event";
1431+ while (XPending (Display ())) {
1432+ XEvent e;
1433+ XNextEvent (Display (), &e);
1434+ switch (e.xany.type - fixes_eventbase) {
1435+ case XFixesBarrierNotify:
1436+ XFixesBarrierNotifyEvent *notify = (XFixesBarrierNotifyEvent *)&e;
1437+ ASSERT_LT (0, notify->velocity);
1438+ return;
1439+ }
1440+ }
1441+ FAIL () << "Failed to receive barrier event";
1442+}
1443+
1444+TEST_F (BarrierTest, ScreenEdgeHorizontalBarrierEventHasNonZeroVelocity)
1445+{
1446+ int barrier_y = 0;
1447+ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
1448+ 0, barrier_y,
1449+ 300, barrier_y,
1450+ 0, 0, NULL);
1451+
1452+ XFixesSelectBarrierInput (Display (), DefaultRootWindow (Display ()),
1453+ XFixesBarrierHitNotifyMask);
1454+
1455+ int x = 100, y = 100, dx = 0, dy = -200;
1456+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1457+ x, y, 0);
1458+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1459+
1460+ /* One relative event to ensure the server has a non-zero
1461+ * last-event-time */
1462+ XTestFakeRelativeMotionEvent (Display (), 10, 10, 0);
1463+ /* Run the pointer into the barrier */
1464+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
1465+
1466+ XFlush (Display ());
1467+ ASSERT_TRUE (WaitForXEvent ())<<"Timed out waiting to receive X event";
1468+ while (XPending (Display ())) {
1469+ XEvent e;
1470+ XNextEvent (Display (), &e);
1471+ switch (e.xany.type - fixes_eventbase) {
1472+ case XFixesBarrierNotify:
1473+ XFixesBarrierNotifyEvent *notify = (XFixesBarrierNotifyEvent *)&e;
1474+ ASSERT_LT (0, notify->velocity);
1475+ return;
1476+ }
1477+ }
1478+ FAIL () << "Failed to receive barrier event";
1479+}
1480+
1481+TEST_F (BarrierTest, ReceiveOneBarrierEventPerHitOnScreenEdge)
1482+{
1483+ int barrier_x = 0;
1484+ XFixesCreatePointerBarrier (Display (), DefaultRootWindow (Display ()),
1485+ barrier_x, 0,
1486+ barrier_x, 300,
1487+ 0, 0, NULL);
1488+
1489+ XFixesSelectBarrierInput (Display (), DefaultRootWindow (Display ()),
1490+ XFixesBarrierHitNotifyMask);
1491+
1492+ int x = 20, y = 100, dx = -40, dy = 0;
1493+ XTestFakeMotionEvent (Display (), DefaultScreen (Display ()),
1494+ x, y, 0);
1495+ ASSERT_NO_FATAL_FAILURE (AssertPointerPosition (x, y));
1496+
1497+ /* Generate 5 barrier events */
1498+ for (int i = 0; i < 5; ++i) {
1499+ XTestFakeRelativeMotionEvent (Display (), dx, dy, 0);
1500+ }
1501+
1502+ int barrierEventCount = 0;
1503+ XFlush (Display ());
1504+ ASSERT_TRUE (WaitForXEvent ())<<"Timed out waiting to receive X event";
1505+ while (XPending (Display ())) {
1506+ XEvent e;
1507+ XNextEvent (Display (), &e);
1508+ switch (e.xany.type - fixes_eventbase) {
1509+ case XFixesBarrierNotify:
1510+ barrierEventCount++;
1511+ break;
1512+ }
1513+ }
1514+ ASSERT_EQ (5, barrierEventCount);
1515+}
1516Index: xorg-server/configure.ac
1517===================================================================
1518--- xorg-server.orig/configure.ac 2012-03-08 07:40:35.416111392 +1100
1519+++ xorg-server/configure.ac 2012-03-08 11:02:31.783464472 +1100
1520@@ -2155,6 +2155,25 @@
1521
1522 AC_CONFIG_COMMANDS([sdksyms], [touch hw/xfree86/sdksyms.dep])
1523
1524+AC_PROG_CXX
1525+
1526+PKG_CHECK_MODULES(XORG_GTEST, xorg-gtest,
1527+ [have_xorg_gtest="yes"],
1528+ [AC_MSG_WARN([xorg-gtest not installed, tests will not be built])])
1529+AM_CONDITIONAL([HAVE_XORG_GTEST], [test "x$have_xorg_gtest" = xyes])
1530+AC_SUBST([XORG_GTEST_CFLAGS])
1531+AC_SUBST([XORG_GTEST_LIBS])
1532+
1533+PKG_CHECK_MODULES([XFIXES], xfixes, [have_xfixes="yes"], [have_xfixes="no"])
1534+AM_CONDITIONAL([HAVE_XFIXES], [test "x$have_xfixes" = xyes])
1535+AC_SUBST([XFIXES_CFLAGS])
1536+AC_SUBST([XFIXES_LIBS])
1537+
1538+PKG_CHECK_MODULES([XTEST], xtst, [have_xtest="yes"], [have_xtest="no"])
1539+AM_CONDITIONAL([HAVE_XTEST], [test "x$have_xtest" = xyes])
1540+AC_SUBST([XTEST_CFLAGS])
1541+AC_SUBST([XTEST_LIBS])
1542+
1543 AC_OUTPUT([
1544 Makefile
1545 glx/Makefile
1546@@ -2254,6 +2273,7 @@
1547 hw/kdrive/src/Makefile
1548 test/Makefile
1549 test/xi2/Makefile
1550+test/gtest/Makefile
1551 xserver.ent
1552 xorg-server.pc
1553 ])
1554Index: xorg-server/test/gtest/Makefile.am
1555===================================================================
1556--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1557+++ xorg-server/test/gtest/Makefile.am 2012-03-08 07:40:35.488111388 +1100
1558@@ -0,0 +1,27 @@
1559+check_PROGRAMS = xfixes_barriers
1560+check_DATA = dummy.conf
1561+
1562+TESTS=xfixes_barriers
1563+
1564+GTEST_SRC_DIR = /usr/src/gtest
1565+GTEST_SOURCES = $(GTEST_SRC_DIR)/src/gtest-all.cc
1566+
1567+xfixes_barriers_CXXFLAGS = $(AM_CXXFLAGS) \
1568+ -I$(GTEST_SRC_DIR) \
1569+ $(XORG_GTEST_CFLAGS) \
1570+ $(XTEST_CFLAGS) \
1571+ $(XFIXES_CFLAGS) \
1572+ -DXORG_BINARY=\"$(top_builddir)/hw/xfree86/Xorg\" \
1573+ -DXORG_DUMMY_CONF=\"$(abs_srcdir)/dummy.conf\"
1574+
1575+xfixes_barriers_LDADD = \
1576+ $(XFIXES_LIBS) \
1577+ $(XTEST_LIBS) \
1578+ $(XORG_GTEST_LIBS) \
1579+ -lpthread
1580+
1581+xfixes_barriers_SOURCES = \
1582+ xfixes_barriers.cpp
1583+
1584+nodist_xfixes_barriers_SOURCES = \
1585+ $(GTEST_SOURCES)
1586Index: xorg-server/test/Makefile.am
1587===================================================================
1588--- xorg-server.orig/test/Makefile.am 2012-03-07 22:24:45.684697122 +1100
1589+++ xorg-server/test/Makefile.am 2012-03-08 07:40:35.488111388 +1100
1590@@ -1,5 +1,10 @@
1591 if ENABLE_UNIT_TESTS
1592 SUBDIRS= . xi2
1593+
1594+if HAVE_XORG_GTEST
1595+SUBDIRS+= gtest
1596+endif
1597+
1598 noinst_PROGRAMS = xkb input xtest list misc fixes xfree86 touch
1599 check_LTLIBRARIES = libxservertest.la
1600
1601Index: xorg-server/test/gtest/dummy.conf
1602===================================================================
1603--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1604+++ xorg-server/test/gtest/dummy.conf 2012-03-08 07:40:35.488111388 +1100
1605@@ -0,0 +1,4 @@
1606+Section "Device"
1607+ Identifier "Dummy video device"
1608+ Driver "dummy"
1609+EndSection
1610Index: xorg-server/dix/dixutils.c
1611===================================================================
1612--- xorg-server.orig/dix/dixutils.c 2012-03-08 07:40:35.392111393 +1100
1613+++ xorg-server/dix/dixutils.c 2012-03-08 07:40:35.488111388 +1100
1614@@ -537,7 +537,7 @@
1615 {
1616 /* remove q from the list */
1617 *p = q->next; /* don't fetch until after func called */
1618- free(q);
1619+ (*q->destroyProc) (q);
1620 }
1621 else
1622 {
1623@@ -560,7 +560,7 @@
1624 (void) (*q->function) (q->client, q->closure);
1625 /* remove q from the list */
1626 *p = q->next; /* don't fetch until after func called */
1627- free(q);
1628+ (*q->destroyProc) (q);
1629 }
1630 else
1631 {
1632@@ -570,6 +570,12 @@
1633 workQueueLast = p;
1634 }
1635
1636+static void
1637+FreeWorkQueueItem (WorkQueuePtr this)
1638+{
1639+ free(this);
1640+}
1641+
1642 Bool
1643 QueueWorkProc (
1644 Bool (*function)(ClientPtr /* pClient */, pointer /* closure */),
1645@@ -583,12 +589,22 @@
1646 q->function = function;
1647 q->client = client;
1648 q->closure = closure;
1649+ q->destroyProc = FreeWorkQueueItem;
1650 q->next = NULL;
1651 *workQueueLast = q;
1652 workQueueLast = &q->next;
1653 return TRUE;
1654 }
1655
1656+Bool
1657+QueueWorkItem (WorkQueuePtr item)
1658+{
1659+ item->next = NULL;
1660+ *workQueueLast = item;
1661+ workQueueLast = &item->next;
1662+ return TRUE;
1663+}
1664+
1665 /*
1666 * Manage a queue of sleeping clients, awakening them
1667 * when requested, by using the OS functions IgnoreClient
1668Index: xorg-server/include/dixstruct.h
1669===================================================================
1670--- xorg-server.orig/include/dixstruct.h 2012-03-07 22:24:45.552697115 +1100
1671+++ xorg-server/include/dixstruct.h 2012-03-08 07:40:35.492111388 +1100
1672@@ -153,6 +153,9 @@
1673 );
1674 ClientPtr client;
1675 pointer closure;
1676+ void (*destroyProc) (
1677+ struct _WorkQueue * /* this */
1678+);
1679 } WorkQueueRec;
1680
1681 extern _X_EXPORT TimeStamp currentTime;
1682Index: xorg-server/include/dix.h
1683===================================================================
1684--- xorg-server.orig/include/dix.h 2012-03-07 22:24:45.568697116 +1100
1685+++ xorg-server/include/dix.h 2012-03-08 07:40:35.492111388 +1100
1686@@ -266,6 +266,8 @@
1687 pointer /*closure*/
1688 );
1689
1690+extern _X_EXPORT Bool QueueWorkItem(WorkQueuePtr item);
1691+
1692 typedef Bool (* ClientSleepProcPtr)(
1693 ClientPtr /*client*/,
1694 pointer /*closure*/);
diff --git a/debian/patches/505_query_pointer_touchscreen.patch b/debian/patches/505_query_pointer_touchscreen.patch
deleted file mode 100644
index 0443acf..0000000
--- a/debian/patches/505_query_pointer_touchscreen.patch
+++ /dev/null
@@ -1,32 +0,0 @@
1From 3d6bd9fd8bd565f4c0513b2649a678109f60bd27 Mon Sep 17 00:00:00 2001
2From: Chase Douglas <chase.douglas@canonical.com>
3Date: Tue, 3 Apr 2012 17:18:43 -0700
4Subject: [PATCH] Use touch state when querying pointer through core protocol
5
6QueryPointer is part of the core protocol. As such, it knows nothing
7about touch devices. Touches are converted to button 1 press, pointer
8motion, and button 1 release for core clients, so we should ensure the
9pointer state mask has button 1 set when XQueryPointer is used.
10
11Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
12---
13 dix/events.c | 3 +--
14 1 files changed, 1 insertions(+), 2 deletions(-)
15
16diff --git a/dix/events.c b/dix/events.c
17index 4470947..b9f9cfa 100644
18--- a/dix/events.c
19+++ b/dix/events.c
20@@ -5098,8 +5098,7 @@ ProcQueryPointer(ClientPtr client)
21 memset(&rep, 0, sizeof(xQueryPointerReply));
22 rep.type = X_Reply;
23 rep.sequenceNumber = client->sequence;
24- rep.mask = mouse->button ? (mouse->button->state) : 0;
25- rep.mask |= XkbStateFieldFromRec(&keyboard->key->xkbInfo->state);
26+ rep.mask = event_get_corestate(mouse, keyboard);
27 rep.length = 0;
28 rep.root = (GetCurrentRootWindow(mouse))->drawable.id;
29 rep.rootX = pSprite->hot.x;
30--
311.7.9.1
32
diff --git a/debian/patches/506_touchscreen_pointer_emulation_checks.patch b/debian/patches/506_touchscreen_pointer_emulation_checks.patch
deleted file mode 100644
index c6fcac8..0000000
--- a/debian/patches/506_touchscreen_pointer_emulation_checks.patch
+++ /dev/null
@@ -1,159 +0,0 @@
1From ec9c4295830c3de610e65aca17f4da4a7af3c4c5 Mon Sep 17 00:00:00 2001
2From: Chase Douglas <chase.douglas@canonical.com>
3Date: Wed, 18 Apr 2012 12:04:58 -0700
4Subject: [PATCH] Check other clients' core masks properly when adding touch
5 listener
6
7The current code checks the core event mask as though it were an XI
8mask. This change fixes the checks so the proper client and event masks
9are used.
10
11Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
12Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
13---
14 dix/touch.c | 8 ++++----
15 1 files changed, 4 insertions(+), 4 deletions(-)
16
17diff --git a/dix/touch.c b/dix/touch.c
18index 572bdfb..f8f26c8 100644
19--- a/dix/touch.c
20+++ b/dix/touch.c
21@@ -811,6 +811,7 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
22 if (mask & EVENT_CORE_MASK) {
23 int coretype = GetCoreType(TouchGetPointerEventType(ev));
24 Mask core_filter = event_get_filter_from_type(dev, coretype);
25+ OtherClients *oclients;
26
27 /* window owner */
28 if (IsMaster(dev) && (win->eventMask & core_filter)) {
29@@ -822,13 +823,12 @@ TouchAddRegularListener(DeviceIntPtr dev, TouchPointInfoPtr ti,
30 }
31
32 /* all others */
33- nt_list_for_each_entry(iclients, (InputClients*)wOtherClients(win), next)
34- {
35- if (!(iclients->mask[XIAllDevices] & core_filter))
36+ nt_list_for_each_entry(oclients, wOtherClients(win), next) {
37+ if (!(oclients->mask & core_filter))
38 continue;
39
40 TouchEventHistoryAllocate(ti);
41- TouchAddListener(ti, iclients->resource, CORE,
42+ TouchAddListener(ti, oclients->resource, CORE,
43 type, LISTENER_AWAITING_BEGIN, win);
44 return TRUE;
45 }
46--
471.7.9.1
48
49From 01091806f762f6f8fc83dc1051b5f3cfb38e88b1 Mon Sep 17 00:00:00 2001
50From: Chase Douglas <chase.douglas@canonical.com>
51Date: Wed, 4 Apr 2012 12:57:40 -0700
52Subject: [PATCH 2/3] Check core event mask properly for pointer emulated
53 touch events
54
55The current code checks the core event mask as though it were an XI2
56mask. This change fixes the checks so the proper client and event masks
57are used.
58
59Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
60
61Conflicts:
62
63 Xi/exevents.c
64---
65 Xi/exevents.c | 13 +++++++++----
66 1 files changed, 9 insertions(+), 4 deletions(-)
67
68diff --git a/Xi/exevents.c b/Xi/exevents.c
69index f390f67..72e6d91 100644
70--- a/Xi/exevents.c
71+++ b/Xi/exevents.c
72@@ -1342,6 +1342,8 @@ RetrieveTouchDeliveryData(DeviceIntPtr dev, TouchPointInfoPtr ti,
73 BUG_WARN(!iclients);
74 if (!iclients)
75 return FALSE;
76+
77+ *client = rClient(iclients);
78 } else if (listener->level == XI)
79 {
80 int xi_type = GetXIType(TouchGetPointerEventType(ev));
81@@ -1352,19 +1354,22 @@ RetrieveTouchDeliveryData(DeviceIntPtr dev, TouchPointInfoPtr ti,
82 BUG_WARN(!iclients);
83 if (!iclients)
84 return FALSE;
85+
86+ *client = rClient(iclients);
87 } else
88 {
89 int coretype = GetCoreType(TouchGetPointerEventType(ev));
90 Mask core_filter = event_get_filter_from_type(dev, coretype);
91+ OtherClients *oclients;
92
93 /* all others */
94- nt_list_for_each_entry(iclients, (InputClients*)wOtherClients(*win), next)
95- if (iclients->mask[XIAllDevices] & core_filter)
96+ nt_list_for_each_entry(oclients, (InputClients*)wOtherClients(*win), next)
97+ if (oclients->mask & core_filter)
98 break;
99- /* if owner selected, iclients is NULL */
100+ /* if owner selected, oclients is NULL */
101+ *client = oclients ? rClient(oclients) : wClient(*win);
102 }
103
104- *client = iclients ? rClient(iclients) : wClient(*win);
105 *mask = iclients ? iclients->xi2mask : NULL;
106 *grab = NULL;
107 }
108--
1091.7.9.1
110
111From 4b4c88b247c6435578c983d74a90f35472849f3a Mon Sep 17 00:00:00 2001
112From: Chase Douglas <chase.douglas@canonical.com>
113Date: Wed, 4 Apr 2012 12:59:55 -0700
114Subject: [PATCH 3/3] Only set XI2 mask if pointer emulation is for XI2 client
115
116The current code returns a reference to memory that may not actually be
117an XI2 mask. Instead, only return a value when an XI2 client has
118selected for events.
119
120Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
121
122Conflicts:
123
124 Xi/exevents.c
125---
126 Xi/exevents.c | 3 ++-
127 1 files changed, 2 insertions(+), 1 deletions(-)
128
129diff --git a/Xi/exevents.c b/Xi/exevents.c
130index 72e6d91..fe06efa 100644
131--- a/Xi/exevents.c
132+++ b/Xi/exevents.c
133@@ -1293,6 +1293,7 @@ RetrieveTouchDeliveryData(DeviceIntPtr dev, TouchPointInfoPtr ti,
134 {
135 int rc;
136 InputClients *iclients = NULL;
137+ *mask = NULL;
138
139 if (listener->type == LISTENER_GRAB ||
140 listener->type == LISTENER_POINTER_GRAB)
141@@ -1343,6 +1344,7 @@ RetrieveTouchDeliveryData(DeviceIntPtr dev, TouchPointInfoPtr ti,
142 if (!iclients)
143 return FALSE;
144
145+ *mask = iclients->xi2mask;
146 *client = rClient(iclients);
147 } else if (listener->level == XI)
148 {
149@@ -1370,7 +1372,6 @@ RetrieveTouchDeliveryData(DeviceIntPtr dev, TouchPointInfoPtr ti,
150 *client = oclients ? rClient(oclients) : wClient(*win);
151 }
152
153- *mask = iclients ? iclients->xi2mask : NULL;
154 *grab = NULL;
155 }
156
157--
1581.7.9.1
159
diff --git a/debian/patches/507_touchscreen_fixes.patch b/debian/patches/507_touchscreen_fixes.patch
deleted file mode 100644
index 2209bac..0000000
--- a/debian/patches/507_touchscreen_fixes.patch
+++ /dev/null
@@ -1,540 +0,0 @@
1--- a/Xi/exevents.c
2+++ b/Xi/exevents.c
3@@ -1148,6 +1148,48 @@ EmitTouchEnd(DeviceIntPtr dev, TouchPoin
4 }
5
6 /**
7+ * Find the oldest touch that still has a pointer emulation client.
8+ *
9+ * Pointer emulation can only be performed for the oldest touch. Otherwise, the
10+ * order of events seen by the client will be wrong. This function helps us find
11+ * the next touch to be emulated.
12+ *
13+ * @param dev The device to find touches for.
14+ */
15+static TouchPointInfoPtr
16+FindOldestPointerEmulatedTouch(DeviceIntPtr dev)
17+{
18+ TouchPointInfoPtr oldest = NULL;
19+ int i;
20+
21+ for (i = 0; i < dev->touch->num_touches; i++) {
22+ TouchPointInfoPtr ti = dev->touch->touches + i;
23+ int j;
24+
25+ if (!ti->active || !ti->emulate_pointer)
26+ continue;
27+
28+ for (j = 0; j < ti->num_listeners; j++) {
29+ if (ti->listeners[j].type == LISTENER_POINTER_GRAB ||
30+ ti->listeners[j].type == LISTENER_POINTER_REGULAR)
31+ break;
32+ }
33+ if (j == ti->num_listeners)
34+ continue;
35+
36+ if (!oldest) {
37+ oldest = ti;
38+ continue;
39+ }
40+
41+ if (oldest->client_id - ti->client_id < UINT_MAX / 2)
42+ oldest = ti;
43+ }
44+
45+ return oldest;
46+}
47+
48+/**
49 * If the current owner has rejected the event, deliver the
50 * TouchOwnership/TouchBegin to the next item in the sprite stack.
51 */
52@@ -1159,8 +1201,16 @@ TouchPuntToNextOwner(DeviceIntPtr dev, T
53 if (ti->listeners[0].state == LISTENER_AWAITING_OWNER ||
54 ti->listeners[0].state == LISTENER_EARLY_ACCEPT)
55 DeliverTouchEvents(dev, ti, (InternalEvent*)ev, ti->listeners[0].listener);
56- else if (ti->listeners[0].state == LISTENER_AWAITING_BEGIN)
57+ else if (ti->listeners[0].state == LISTENER_AWAITING_BEGIN) {
58+ /* We can't punt to a pointer listener unless all older pointer
59+ * emulated touches have been seen already. */
60+ if ((ti->listeners[0].type == LISTENER_POINTER_GRAB ||
61+ ti->listeners[0].type == LISTENER_POINTER_REGULAR) &&
62+ ti != FindOldestPointerEmulatedTouch(dev))
63+ return;
64+
65 TouchEventHistoryReplay(ti, dev, ti->listeners[0].listener);
66+ }
67
68 /* If we've just removed the last grab and the touch has physically
69 * ended, send a TouchEnd event too and finalise the touch. */
70@@ -1177,6 +1227,25 @@ TouchPuntToNextOwner(DeviceIntPtr dev, T
71 }
72
73 /**
74+ * Check the oldest touch to see if it needs to be replayed to its pointer
75+ * owner.
76+ *
77+ * Touch event propagation is paused if it hits a pointer listener while an
78+ * older touch with a pointer listener is waiting on accept or reject. This
79+ * function will restart propagation of a paused touch if needed.
80+ *
81+ * @param dev The device to check touches for.
82+ */
83+static void
84+CheckOldestTouch(DeviceIntPtr dev)
85+{
86+ TouchPointInfoPtr oldest = FindOldestPointerEmulatedTouch(dev);
87+
88+ if (oldest && oldest->listeners[0].state == LISTENER_AWAITING_BEGIN)
89+ TouchPuntToNextOwner(dev, oldest, NULL);
90+}
91+
92+/**
93 * Process a touch rejection.
94 *
95 * @param sourcedev The source device of the touch sequence.
96@@ -1205,14 +1274,6 @@ TouchRejected(DeviceIntPtr sourcedev, To
97 }
98 }
99
100- /* If there are no other listeners left, and the touchpoint is pending
101- * finish, then we can just kill it now. */
102- if (ti->num_listeners == 1 && ti->pending_finish)
103- {
104- TouchEndTouch(sourcedev, ti);
105- return;
106- }
107-
108 /* Remove the resource from the listener list, updating
109 * ti->num_listeners, as well as ti->num_grabs if it was a grab. */
110 if (TouchRemoveListener(ti, resource))
111@@ -1226,6 +1287,10 @@ TouchRejected(DeviceIntPtr sourcedev, To
112 * the TouchOwnership or TouchBegin event to the new owner. */
113 if (ev && ti->num_listeners > 0 && was_owner)
114 TouchPuntToNextOwner(sourcedev, ti, ev);
115+ else if (ti->num_listeners == 0)
116+ TouchEndTouch(sourcedev, ti);
117+
118+ CheckOldestTouch(sourcedev);
119 }
120
121 /**
122@@ -1243,9 +1308,18 @@ ProcessTouchOwnershipEvent(DeviceIntPtr
123 if (ev->reason == XIRejectTouch)
124 TouchRejected(dev, ti, ev->resource, ev);
125 else if (ev->reason == XIAcceptTouch) {
126+ int i;
127+
128+ /* Go through the motions of ending the touch if the listener has
129+ * already seen the end. This ensures that the touch record is ended in
130+ * the server. */
131+ if (ti->listeners[0].state == LISTENER_HAS_END)
132+ EmitTouchEnd(dev, ti, TOUCH_ACCEPT, ti->listeners[0].listener);
133+
134 /* The touch owner has accepted the touch. Send TouchEnd events to
135 * everyone else, and truncate the list of listeners. */
136- EmitTouchEnd(dev, ti, TOUCH_ACCEPT, 0);
137+ for (i = 1; i < ti->num_listeners; i++)
138+ EmitTouchEnd(dev, ti, TOUCH_ACCEPT, ti->listeners[i].listener);
139
140 while (ti->num_listeners > 1)
141 TouchRemoveListener(ti, ti->listeners[1].listener);
142@@ -1428,11 +1502,21 @@ DeliverTouchEmulatedEvent(DeviceIntPtr d
143 if (!deliveries)
144 DeliverOneGrabbedEvent(ptrev, dev, grab->grabtype);
145
146+ /* We must accept the touch sequence once a pointer listener has
147+ * received one event past ButtonPress. */
148+ if (deliveries && ev->any.type != ET_TouchBegin &&
149+ !(ev->device_event.flags & TOUCH_CLIENT_ID))
150+ TouchListenerAcceptReject(dev, ti, 0, XIAcceptTouch);
151+
152 if (ev->any.type == ET_TouchEnd &&
153+ !(ev->device_event.flags & TOUCH_CLIENT_ID) &&
154 !dev->button->buttonsDown &&
155 dev->deviceGrab.fromPassiveGrab &&
156- GrabIsPointerGrab(grab))
157+ GrabIsPointerGrab(grab)) {
158 (*dev->deviceGrab.DeactivateGrab)(dev);
159+ CheckOldestTouch(dev);
160+ return Success;
161+ }
162 }
163 } else
164 {
165@@ -1552,12 +1636,43 @@ ProcessTouchEvent(InternalEvent *ev, Dev
166 else
167 touchid = ev->device_event.touchid;
168
169+ if (emulate_pointer)
170+ UpdateDeviceState(dev, &ev->device_event);
171+
172 if (type == ET_TouchBegin) {
173 ti = TouchBeginTouch(dev, ev->device_event.sourceid, touchid,
174 emulate_pointer);
175 } else
176 ti = TouchFindByClientID(dev, touchid);
177
178+ /* Under the following circumstances we create a new touch record for an
179+ * existing touch:
180+ *
181+ * - The touch may be pointer emulated
182+ * - An explicit grab is active on the device
183+ * - The grab is a pointer grab
184+ *
185+ * This allows for an explicit grab to receive pointer events for an already
186+ * active touch.
187+ */
188+ if (!ti && type != ET_TouchBegin && emulate_pointer &&
189+ dev->deviceGrab.grab && !dev->deviceGrab.fromPassiveGrab &&
190+ (dev->deviceGrab.grab->grabtype == CORE ||
191+ dev->deviceGrab.grab->grabtype == XI ||
192+ !xi2mask_isset(dev->deviceGrab.grab->xi2mask, dev, XI_TouchBegin))) {
193+ ti = TouchBeginTouch(dev, ev->device_event.sourceid, touchid,
194+ emulate_pointer);
195+ if (!ti) {
196+ DebugF("[Xi] %s: Failed to create new dix record for explicitly "
197+ "grabbed touchpoint %d\n",
198+ dev->name, type, touchid);
199+ return;
200+ }
201+
202+ TouchBuildSprite(dev, ti, ev);
203+ TouchSetupListeners(dev, ti, ev);
204+ }
205+
206 if (!ti)
207 {
208 DebugF("[Xi] %s: Failed to get event %d for touchpoint %d\n",
209@@ -1575,9 +1690,11 @@ ProcessTouchEvent(InternalEvent *ev, Dev
210 CheckMotion(&ev->device_event, dev);
211
212 /* Make sure we have a valid window trace for event delivery; must be
213- * called after event type mutation. */
214+ * called after event type mutation. Touch end events are always processed
215+ * in order to end touch records. */
216 /* FIXME: check this */
217- if (!TouchEnsureSprite(dev, ti, ev))
218+ if ((type == ET_TouchBegin && !TouchBuildSprite(dev, ti, ev)) ||
219+ (type != ET_TouchEnd && ti->sprite.spriteTraceGood == 0))
220 return;
221
222 /* TouchOwnership events are handled separately from the rest, as they
223@@ -1813,6 +1930,14 @@ DeliverTouchEndEvent(DeviceIntPtr dev, T
224 {
225 rc = DeliverTouchEmulatedEvent(dev, ti, ev, listener, client, win,
226 grab, xi2mask);
227+
228+ if (ti->num_listeners > 1) {
229+ ev->any.type = ET_TouchUpdate;
230+ ev->device_event.flags |= TOUCH_PENDING_END;
231+ if (!(ev->device_event.flags & TOUCH_CLIENT_ID))
232+ ti->pending_finish = TRUE;
233+ }
234+
235 goto out;
236 }
237
238@@ -1923,9 +2048,6 @@ DeliverTouchEvents(DeviceIntPtr dev, Tou
239
240 DeliverTouchEvent(dev, ti, ev, listener, client, win, grab, mask);
241 }
242-
243- if (ti->emulate_pointer)
244- UpdateDeviceState(dev, &ev->device_event);
245 }
246
247 int
248--- a/dix/dispatch.c
249+++ b/dix/dispatch.c
250@@ -215,7 +215,7 @@ UpdateCurrentTimeIf(void)
251 systime.milliseconds = GetTimeInMillis();
252 if (systime.milliseconds < currentTime.milliseconds)
253 systime.months++;
254- if (*checkForInput[0] == *checkForInput[1])
255+ if (CompareTimeStamps(systime, currentTime) == LATER)
256 currentTime = systime;
257 }
258
259@@ -408,6 +408,9 @@ Dispatch(void)
260 }
261 /* now, finally, deal with client requests */
262
263+ /* Update currentTime so request time checks, such as for input
264+ * device grabs, are calculated correctly */
265+ UpdateCurrentTimeIf();
266 result = ReadRequestFromClient(client);
267 if (result <= 0)
268 {
269--- a/dix/events.c
270+++ b/dix/events.c
271@@ -1312,14 +1312,10 @@ ComputeFreezes(void)
272 {
273 if (IsTouchEvent((InternalEvent*)event))
274 {
275- InternalEvent *events = InitEventList(GetMaximumEventsNum());
276- int i, nev;
277 TouchPointInfoPtr ti = TouchFindByClientID(replayDev, event->touchid);
278 BUG_WARN(!ti);
279- nev = GetTouchOwnershipEvents(events, replayDev, ti, XIRejectTouch, ti->listeners[0].listener, 0);
280- for (i = 0; i < nev; i++)
281- mieqProcessDeviceEvent(replayDev, events + i, NULL);
282- ProcessInputEvents();
283+
284+ TouchListenerAcceptReject(replayDev, ti, 0, XIRejectTouch);
285 } else if (replayDev->focus && !IsPointerEvent((InternalEvent*)event))
286 DeliverFocusedEvent(replayDev, (InternalEvent*)event, w);
287 else
288@@ -1459,6 +1455,38 @@ ReattachToOldMaster(DeviceIntPtr dev)
289 }
290
291 /**
292+ * Update touch records when an explicit grab is activated. Any touches owned by
293+ * the grabbing client are updated so the listener state reflects the new grab.
294+ */
295+static void
296+UpdateTouchesForGrab(DeviceIntPtr mouse)
297+{
298+ int i;
299+
300+ if (!mouse->touch || mouse->deviceGrab.fromPassiveGrab)
301+ return;
302+
303+ for (i = 0; i < mouse->touch->num_touches; i++) {
304+ TouchPointInfoPtr ti = mouse->touch->touches + i;
305+ GrabPtr grab = mouse->deviceGrab.grab;
306+
307+ if (ti->active &&
308+ CLIENT_BITS(ti->listeners[0].listener) == grab->resource) {
309+ ti->listeners[0].listener = grab->resource;
310+ ti->listeners[0].level = grab->grabtype;
311+ ti->listeners[0].state = LISTENER_IS_OWNER;
312+ ti->listeners[0].window = grab->window;
313+
314+ if (grab->grabtype == CORE || grab->grabtype == XI ||
315+ !xi2mask_isset(grab->xi2mask, mouse, XI_TouchBegin))
316+ ti->listeners[0].type = LISTENER_POINTER_GRAB;
317+ else
318+ ti->listeners[0].type = LISTENER_GRAB;
319+ }
320+ }
321+}
322+
323+/**
324 * Activate a pointer grab on the given device. A pointer grab will cause all
325 * core pointer events of this device to be delivered to the grabbing client only.
326 * No other device will send core events to the grab client while the grab is
327@@ -1509,6 +1537,7 @@ ActivatePointerGrab(DeviceIntPtr mouse,
328 grabinfo->fromPassiveGrab = isPassive;
329 grabinfo->implicitGrab = autoGrab & ImplicitGrabMask;
330 PostNewCursor(mouse);
331+ UpdateTouchesForGrab(mouse);
332 CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
333 }
334
335@@ -1524,6 +1553,8 @@ DeactivatePointerGrab(DeviceIntPtr mouse
336 DeviceIntPtr dev;
337 Bool wasImplicit = (mouse->deviceGrab.fromPassiveGrab &&
338 mouse->deviceGrab.implicitGrab);
339+ XID grab_resource = grab->resource;
340+ int i;
341
342 TouchRemovePointerGrab(mouse);
343
344@@ -1549,6 +1580,15 @@ DeactivatePointerGrab(DeviceIntPtr mouse
345 ReattachToOldMaster(mouse);
346
347 ComputeFreezes();
348+
349+ /* If an explicit grab was deactivated, we must remove it from the head of
350+ * all the touches' listener lists. */
351+ for (i = 0; mouse->touch && i < mouse->touch->num_touches; i++) {
352+ TouchPointInfoPtr ti = mouse->touch->touches + i;
353+
354+ if (ti->active && TouchResourceIsOwner(ti, grab_resource))
355+ TouchListenerAcceptReject(mouse, ti, 0, XIRejectTouch);
356+ }
357 }
358
359 /**
360--- a/dix/touch.c
361+++ b/dix/touch.c
362@@ -375,13 +375,6 @@ TouchEndTouch(DeviceIntPtr dev, TouchPoi
363 if (ti->emulate_pointer)
364 {
365 GrabPtr grab;
366- DeviceEvent ev;
367- memset(&ev, 0, sizeof(ev));
368- ev.type = ET_TouchEnd;
369- ev.detail.button = 1;
370- ev.touchid = ti->client_id;
371- ev.flags = TOUCH_POINTER_EMULATED|TOUCH_END;
372- UpdateDeviceState(dev, &ev);
373
374 if ((grab = dev->deviceGrab.grab))
375 {
376@@ -496,10 +489,22 @@ TouchEventHistoryReplay(TouchPointInfoPt
377 flags = TOUCH_CLIENT_ID|TOUCH_REPLAYING;
378 if (ti->emulate_pointer)
379 flags |= TOUCH_POINTER_EMULATED;
380- /* send fake begin event to next owner */
381+ /* Generate events based on a fake touch begin event to get DCCE events if
382+ * needed */
383+ /* FIXME: This needs to be cleaned up */
384 nev = GetTouchEvents(tel, dev, ti->client_id, XI_TouchBegin, flags, mask);
385- for (i = 0; i < nev; i++)
386- DeliverTouchEvents(dev, ti, tel + i, resource);
387+ for (i = 0; i < nev; i++) {
388+ /* Send saved touch begin event */
389+ if (tel[i].any.type == ET_TouchBegin) {
390+ DeviceEvent *ev = &ti->history[0];
391+ ev->flags |= TOUCH_REPLAYING;
392+ DeliverTouchEvents(dev, ti, (InternalEvent*)ev, resource);
393+ }
394+ else {/* Send DCCE event */
395+ tel[i].any.time = ti->history[0].time;
396+ DeliverTouchEvents(dev, ti, tel + i, resource);
397+ }
398+ }
399
400 valuator_mask_free(&mask);
401 FreeEventList(tel, GetMaximumEventsNum());
402@@ -558,22 +563,12 @@ TouchBuildDependentSpriteTrace(DeviceInt
403 * TouchBegin events.
404 */
405 Bool
406-TouchEnsureSprite(DeviceIntPtr sourcedev, TouchPointInfoPtr ti,
407- InternalEvent *ev)
408+TouchBuildSprite(DeviceIntPtr sourcedev, TouchPointInfoPtr ti,
409+ InternalEvent *ev)
410 {
411 TouchClassPtr t = sourcedev->touch;
412 SpritePtr sprite = &ti->sprite;
413
414- /* We may not have a sprite if there are no applicable grabs or
415- * event selections, or if they've disappeared, or if all the grab
416- * owners have rejected the touch. Don't bother delivering motion
417- * events if not, but TouchEnd events still need to be processed so
418- * we can call FinishTouchPoint and release it for later use. */
419- if (ev->any.type == ET_TouchEnd)
420- return TRUE;
421- else if (ev->any.type != ET_TouchBegin)
422- return (sprite->spriteTraceGood > 0);
423-
424 if (t->mode == XIDirectTouch)
425 {
426 /* Focus immediately under the touchpoint in direct touch mode.
427@@ -897,6 +892,11 @@ TouchSetupListeners(DeviceIntPtr dev, To
428 if (dev->deviceGrab.grab)
429 TouchAddActiveGrabListener(dev, ti, ev, dev->deviceGrab.grab);
430
431+ /* We set up an active touch listener for existing touches, but not any
432+ * passive grab or regular listeners. */
433+ if (ev->any.type != ET_TouchBegin)
434+ return;
435+
436 /* First, find all grabbing clients from the root window down
437 * to the deepest child window. */
438 for (i = 0; i < sprite->spriteTraceGood; i++)
439@@ -988,15 +988,48 @@ TouchListenerGone(XID resource)
440 }
441
442 int
443+TouchListenerAcceptReject(DeviceIntPtr dev, TouchPointInfoPtr ti, int listener,
444+ int mode)
445+{
446+ InternalEvent *events;
447+ int nev;
448+ int i;
449+
450+ if (listener > 0) {
451+ if (mode == XIRejectTouch)
452+ TouchRejected(dev, ti, ti->listeners[listener].listener, NULL);
453+ else
454+ ti->listeners[listener].state = LISTENER_EARLY_ACCEPT;
455+
456+ return Success;
457+ }
458+
459+ events = InitEventList(GetMaximumEventsNum());
460+ if (!events) {
461+ BUG_WARN_MSG(TRUE, "Failed to allocate touch ownership events\n");
462+ return BadAlloc;
463+ }
464+
465+ nev = GetTouchOwnershipEvents(events, dev, ti, mode,
466+ ti->listeners[0].listener, 0);
467+ BUG_WARN_MSG(nev == 0, "Failed to get touch ownership events\n");
468+
469+ for (i = 0; i < nev; i++)
470+ mieqProcessDeviceEvent(dev, events + i, NULL);
471+
472+ ProcessInputEvents();
473+
474+ FreeEventList(events, GetMaximumEventsNum());
475+
476+ return nev ? Success : BadMatch;
477+}
478+
479+int
480 TouchAcceptReject(ClientPtr client, DeviceIntPtr dev, int mode,
481 uint32_t touchid, Window grab_window, XID *error)
482 {
483 TouchPointInfoPtr ti;
484- int nev, i;
485- InternalEvent *events = InitEventList(GetMaximumEventsNum());
486-
487- if (!events)
488- return BadAlloc;
489+ int i;
490
491 if (!dev->touch)
492 {
493@@ -1020,25 +1053,5 @@ TouchAcceptReject(ClientPtr client, Devi
494 if (i == ti->num_listeners)
495 return BadAccess;
496
497- if (i > 0)
498- {
499- if (mode == XIRejectTouch)
500- TouchRejected(dev, ti, ti->listeners[i].listener, NULL);
501- else
502- ti->listeners[i].state = LISTENER_EARLY_ACCEPT;
503-
504- return Success;
505- }
506-
507- nev = GetTouchOwnershipEvents(events, dev, ti, mode,
508- ti->listeners[0].listener, 0);
509- if (nev == 0)
510- return BadAlloc;
511- for (i = 0; i < nev; i++)
512- mieqProcessDeviceEvent(dev, events + i, NULL);
513-
514- ProcessInputEvents();
515-
516- FreeEventList(events, GetMaximumEventsNum());
517- return Success;
518+ return TouchListenerAcceptReject(dev, ti, i, mode);
519 }
520--- a/include/input.h
521+++ b/include/input.h
522@@ -624,14 +624,16 @@ extern void TouchAddListener(TouchPointI
523 WindowPtr window);
524 extern Bool TouchRemoveListener(TouchPointInfoPtr ti, XID resource);
525 extern void TouchSetupListeners(DeviceIntPtr dev, TouchPointInfoPtr ti, InternalEvent *ev);
526-extern Bool TouchEnsureSprite(DeviceIntPtr sourcedev, TouchPointInfoPtr ti,
527- InternalEvent *ev);
528+extern Bool TouchBuildSprite(DeviceIntPtr sourcedev, TouchPointInfoPtr ti,
529+ InternalEvent *ev);
530 extern Bool TouchBuildDependentSpriteTrace(DeviceIntPtr dev, SpritePtr sprite);
531 extern int TouchConvertToPointerEvent(const InternalEvent *ev,
532 InternalEvent *motion, InternalEvent *button);
533 extern int TouchGetPointerEventType(const InternalEvent *ev);
534 extern void TouchRemovePointerGrab(DeviceIntPtr dev);
535 extern void TouchListenerGone(XID resource);
536+extern int TouchListenerAcceptReject(DeviceIntPtr dev, TouchPointInfoPtr ti,
537+ int listener, int mode);
538 extern int TouchAcceptReject(ClientPtr client, DeviceIntPtr dev, int mode,
539 uint32_t touchid, Window grab_window, XID *error);
540
diff --git a/debian/patches/508_device_off_release_buttons.patch b/debian/patches/508_device_off_release_buttons.patch
deleted file mode 100644
index 91d2249..0000000
--- a/debian/patches/508_device_off_release_buttons.patch
+++ /dev/null
@@ -1,37 +0,0 @@
1From adaf1adecf5697455e9f3fb0234939113873f959 Mon Sep 17 00:00:00 2001
2From: Peter Hutterer <peter.hutterer@who-t.net>
3Date: Mon, 30 Apr 2012 10:01:48 +1000
4Subject: [PATCH] dix: when disabling a device, release all buttons and keys
5
6A suspend-induced device disable may happen before the device gets to see
7the button release event. On resume, the server's internal state still has
8some buttons pressed, causing inconsistent behaviour.
9
10Force the release and the matching events to be sent to the client.
11
12Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
13Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
14
15Conflicts:
16
17 dix/devices.c
18---
19 dix/devices.c | 2 ++
20 1 files changed, 2 insertions(+), 0 deletions(-)
21
22diff --git a/dix/devices.c b/dix/devices.c
23index 9624424..b325d17 100644
24--- a/dix/devices.c
25+++ b/dix/devices.c
26@@ -447,6 +447,8 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
27 if (*prev != dev)
28 return FALSE;
29
30+ ReleaseButtonsAndKeys(dev);
31+
32 /* float attached devices */
33 if (IsMaster(dev))
34 {
35--
361.7.9.1
37
diff --git a/debian/patches/510-dix-return-early-from-DisableDevice-if-the-device-is.patch b/debian/patches/510-dix-return-early-from-DisableDevice-if-the-device-is.patch
deleted file mode 100644
index 87ae244..0000000
--- a/debian/patches/510-dix-return-early-from-DisableDevice-if-the-device-is.patch
+++ /dev/null
@@ -1,29 +0,0 @@
1From 46adcefb0e08515195d8e49985a4e210395700b3 Mon Sep 17 00:00:00 2001
2From: Peter Hutterer <peter.hutterer@who-t.net>
3Date: Thu, 10 May 2012 12:10:12 +1000
4Subject: [PATCH 07/12] dix: return early from DisableDevice if the device is
5 already disabled
6
7Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
8Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
9---
10 dix/devices.c | 3 +++
11 1 file changed, 3 insertions(+)
12
13diff --git a/dix/devices.c b/dix/devices.c
14index df46497..6acff4f 100644
15--- a/dix/devices.c
16+++ b/dix/devices.c
17@@ -428,6 +428,9 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
18 BOOL enabled;
19 int flags[MAXDEVICES] = { 0 };
20
21+ if (!dev->enabled)
22+ return TRUE;
23+
24 for (prev = &inputInfo.devices;
25 *prev && (*prev != dev); prev = &(*prev)->next);
26 if (*prev != dev)
27--
281.7.9.5
29
diff --git a/debian/patches/511-dix-move-freeing-the-sprite-into-a-function.patch b/debian/patches/511-dix-move-freeing-the-sprite-into-a-function.patch
deleted file mode 100644
index d48b876..0000000
--- a/debian/patches/511-dix-move-freeing-the-sprite-into-a-function.patch
+++ /dev/null
@@ -1,62 +0,0 @@
1From e57d6a89027c55fef987cdc259668c48a8b4ea1b Mon Sep 17 00:00:00 2001
2From: Peter Hutterer <peter.hutterer@who-t.net>
3Date: Thu, 10 May 2012 15:32:20 +1000
4Subject: [PATCH 08/12] dix: move freeing the sprite into a function
5
6Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
7Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
8---
9 dix/devices.c | 7 +------
10 dix/events.c | 12 ++++++++++++
11 include/dix.h | 2 ++
12 3 files changed, 15 insertions(+), 6 deletions(-)
13
14--- a/dix/devices.c
15+++ b/dix/devices.c
16@@ -949,12 +949,7 @@
17 free(classes);
18 }
19
20- if (DevHasCursor(dev) && dev->spriteInfo->sprite) {
21- if (dev->spriteInfo->sprite->current)
22- FreeCursor(dev->spriteInfo->sprite->current, None);
23- free(dev->spriteInfo->sprite->spriteTrace);
24- free(dev->spriteInfo->sprite);
25- }
26+ FreeSprite(dev);
27
28 /* a client may have the device set as client pointer */
29 for (j = 0; j < currentMaxClients; j++)
30--- a/dix/events.c
31+++ b/dix/events.c
32@@ -3323,6 +3323,18 @@
33 #endif
34 }
35
36+void FreeSprite(DeviceIntPtr dev)
37+{
38+ if (DevHasCursor(dev) && dev->spriteInfo->sprite) {
39+ if (dev->spriteInfo->sprite->current)
40+ FreeCursor(dev->spriteInfo->sprite->current, None);
41+ free(dev->spriteInfo->sprite->spriteTrace);
42+ free(dev->spriteInfo->sprite);
43+ }
44+ dev->spriteInfo->sprite = NULL;
45+}
46+
47+
48 /**
49 * Update the mouse sprite info when the server switches from a pScreen to another.
50 * Otherwise, the pScreen of the mouse sprite is never updated when we switch
51--- a/include/dix.h
52+++ b/include/dix.h
53@@ -417,6 +417,9 @@
54 DeviceIntPtr /* pDev */,
55 WindowPtr /* pWin */);
56
57+extern void FreeSprite(
58+ DeviceIntPtr /* pDev */);
59+
60 extern void UpdateSpriteForScreen(
61 DeviceIntPtr /* pDev */,
62 ScreenPtr /* pScreen */);
diff --git a/debian/patches/512-dix-free-the-sprite-when-disabling-the-device.patch b/debian/patches/512-dix-free-the-sprite-when-disabling-the-device.patch
deleted file mode 100644
index 0ba5be4..0000000
--- a/debian/patches/512-dix-free-the-sprite-when-disabling-the-device.patch
+++ /dev/null
@@ -1,31 +0,0 @@
1From df1704365e700d3cf1d36a241bdfc479159a8df7 Mon Sep 17 00:00:00 2001
2From: Peter Hutterer <peter.hutterer@who-t.net>
3Date: Thu, 10 May 2012 15:33:15 +1000
4Subject: [PATCH 09/12] dix: free the sprite when disabling the device
5
6Disabled devices don't need sprites (they can't send events anyway) and the
7device init process is currently geared to check for whether sprite is
8present to check if the device should be paired/attached.
9
10Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
11Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
12---
13 dix/devices.c | 2 ++
14 1 file changed, 2 insertions(+)
15
16diff --git a/dix/devices.c b/dix/devices.c
17index a280dee..f134f31 100644
18--- a/dix/devices.c
19+++ b/dix/devices.c
20@@ -465,6 +465,8 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent)
21 (void) (*dev->deviceProc) (dev, DEVICE_OFF);
22 dev->enabled = FALSE;
23
24+ FreeSprite(dev);
25+
26 /* now that the device is disabled, we can reset the signal handler's
27 * last.slave */
28 OsBlockSignals();
29--
301.7.9.5
31
diff --git a/debian/patches/513-dix-disable-non-sprite-owners-first-when-disabling-p.patch b/debian/patches/513-dix-disable-non-sprite-owners-first-when-disabling-p.patch
deleted file mode 100644
index f8e05ee..0000000
--- a/debian/patches/513-dix-disable-non-sprite-owners-first-when-disabling-p.patch
+++ /dev/null
@@ -1,41 +0,0 @@
1From e433d1046c222f9d969c2c28a4651ff9097614f4 Mon Sep 17 00:00:00 2001
2From: Peter Hutterer <peter.hutterer@who-t.net>
3Date: Thu, 10 May 2012 12:42:59 +1000
4Subject: [PATCH 10/12] dix: disable non-sprite-owners first when disabling
5 paired devices
6
7If a sprite-owner is to be disabled but still paired, disable the paired
8device first. i.e. disabling a master pointer will disable the master
9keyboard first.
10
11Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
12Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
13---
14Altered to apply to stable
15
16 dix/devices.c | 7 +++++--
17 1 file changed, 5 insertions(+), 2 deletions(-)
18
19--- a/dix/devices.c
20+++ b/dix/devices.c
21@@ -477,15 +477,14 @@
22 {
23 for (other = inputInfo.devices; other; other = other->next)
24 {
25- if (other->spriteInfo->paired == dev)
26- {
27- ErrorF("[dix] cannot disable device, still paired. "
28- "This is a bug. \n");
29- return FALSE;
30- }
31+ if (other->spriteInfo->paired == dev && !other->spriteInfo->spriteOwner)
32+ DisableDevice(other, sendevent);
33 }
34 }
35
36+ if (dev->spriteInfo->paired)
37+ dev->spriteInfo->paired = NULL;
38+
39 (void)(*dev->deviceProc)(dev, DEVICE_OFF);
40 dev->enabled = FALSE;
41
diff --git a/debian/patches/514-Xi-drop-forced-unpairing-when-changing-the-hierarchy.patch b/debian/patches/514-Xi-drop-forced-unpairing-when-changing-the-hierarchy.patch
deleted file mode 100644
index 19e3d8a..0000000
--- a/debian/patches/514-Xi-drop-forced-unpairing-when-changing-the-hierarchy.patch
+++ /dev/null
@@ -1,33 +0,0 @@
1From 9c0e820216cd1631f75b037b7908d55ac091692c Mon Sep 17 00:00:00 2001
2From: Peter Hutterer <peter.hutterer@who-t.net>
3Date: Thu, 10 May 2012 12:55:44 +1000
4Subject: [PATCH 11/12] Xi: drop forced unpairing when changing the hierarchy
5
6Devices are unpaired as needed on DisableDevice now.
7
8Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
9Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
10---
11 Xi/xichangehierarchy.c | 6 ------
12 1 file changed, 6 deletions(-)
13
14diff --git a/Xi/xichangehierarchy.c b/Xi/xichangehierarchy.c
15index 756aaac..89f16d8 100644
16--- a/Xi/xichangehierarchy.c
17+++ b/Xi/xichangehierarchy.c
18@@ -293,12 +293,6 @@ remove_master(ClientPtr client, xXIRemoveMasterInfo * r, int flags[MAXDEVICES])
19 }
20 }
21
22- /* can't disable until we removed pairing */
23- keybd->spriteInfo->paired = NULL;
24- ptr->spriteInfo->paired = NULL;
25- XTestptr->spriteInfo->paired = NULL;
26- XTestkeybd->spriteInfo->paired = NULL;
27-
28 /* disable the remove the devices, XTest devices must be done first
29 else the sprites they rely on will be destroyed */
30 DisableDevice(XTestptr, FALSE);
31--
321.7.9.5
33
diff --git a/debian/patches/515-dix-disable-all-devices-before-shutdown.patch b/debian/patches/515-dix-disable-all-devices-before-shutdown.patch
deleted file mode 100644
index 4853e50..0000000
--- a/debian/patches/515-dix-disable-all-devices-before-shutdown.patch
+++ /dev/null
@@ -1,85 +0,0 @@
1From 4c68f5d395c66f28b56e488cb3cd12f36820357b Mon Sep 17 00:00:00 2001
2From: Peter Hutterer <peter.hutterer@who-t.net>
3Date: Wed, 9 May 2012 09:21:28 +1000
4Subject: [PATCH 12/12] dix: disable all devices before shutdown
5
6f3410b97cf9b48a47bee3d15d232f8a88e75f4ef introduced a regression on server
7shutdown. If any button or key was held on shutdown (ctrl, alt, backspace
8are usually still down) sending a raw event will segfault the server. The
9the root windows are set to NULL before calling CloseDownDevices().
10
11Avoid this by disabling all devices first when shutting down. Disabled
12devices won't send events anymore.
13
14Master keyboards must be disabled first, otherwise disabling the pointer
15will trigger DisableDevice(keyboard) and the keyboard is removed from the
16inputInfo.devices list and moved to inputInfo.off_devices. A regular loop
17through inputInfo.devices would thus jump to off_devices and not recover.
18
19Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
20Acked-by: Chase Douglas <chase.douglas@canonical.com>
21Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
22---
23 dix/devices.c | 20 ++++++++++++++++++++
24 dix/main.c | 4 ++++
25 include/input.h | 2 +-
26 3 files changed, 25 insertions(+), 1 deletion(-)
27
28--- a/dix/devices.c
29+++ b/dix/devices.c
30@@ -524,6 +524,26 @@
31 return TRUE;
32 }
33
34+void
35+DisableAllDevices(void)
36+{
37+ DeviceIntPtr dev, tmp;
38+
39+ nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) {
40+ if (!IsMaster(dev))
41+ DisableDevice(dev, FALSE);
42+ }
43+ /* master keyboards need to be disabled first */
44+ nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) {
45+ if (dev->enabled && IsMaster(dev) && IsKeyboardDevice(dev))
46+ DisableDevice(dev, FALSE);
47+ }
48+ nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) {
49+ if (dev->enabled)
50+ DisableDevice(dev, FALSE);
51+ }
52+}
53+
54 /**
55 * Initialise a new device through the driver and tell all clients about the
56 * new device.
57--- a/dix/main.c
58+++ b/dix/main.c
59@@ -105,6 +105,7 @@
60 #include "privates.h"
61 #include "registry.h"
62 #include "client.h"
63+#include "exevents.h"
64 #ifdef PANORAMIX
65 #include "panoramiXsrv.h"
66 #else
67@@ -294,6 +295,7 @@
68 #endif
69
70 UndisplayDevices();
71+ DisableAllDevices();
72
73 /* Now free up whatever must be freed */
74 if (screenIsSaved == SCREEN_SAVER_ON)
75--- a/include/input.h
76+++ b/include/input.h
77@@ -280,7 +280,7 @@
78 extern _X_EXPORT Bool DisableDevice(
79 DeviceIntPtr /*device*/,
80 BOOL /* sendevent */);
81-
82+extern void DisableAllDevices(void);
83 extern int InitAndStartDevices(void);
84
85 extern void CloseDownDevices(void);
diff --git a/debian/patches/516-dix-dont-emulate-scroll-events-for-non-existing-axes.patch b/debian/patches/516-dix-dont-emulate-scroll-events-for-non-existing-axes.patch
deleted file mode 100644
index 7d022e1..0000000
--- a/debian/patches/516-dix-dont-emulate-scroll-events-for-non-existing-axes.patch
+++ /dev/null
@@ -1,39 +0,0 @@
1commit b53cdf4c53f0787ed41281278877e0405fcb2674
2Author: Peter Hutterer <peter.hutterer@who-t.net>
3Date: Fri Apr 27 16:31:17 2012 +1000
4
5 dix: don't emulate scroll events for non-existing axes (#47281)
6
7 Test case:
8 - create a device with REL_HWHEEL and ABS_X and ABS_Y. evdev 2.7.0 will set
9 that up as device with 1 relative axis
10 - move pointer to VGA1
11 - xrandr --output VGA1 --off
12
13 Warps the pointer to the new spot and calls GPE with the x/y mask bits set.
14 When running through the loop to check for scroll event, this overruns the
15 axes and may try to emulate scroll events based on random garbage in the
16 memory. If that memory contained non-zero for the scroll type but near-zero
17 for the increment field, the server would hang in an infinite loop.
18
19 This was the trigger for this suggested, never-merged, patch here:
20 http://patchwork.freedesktop.org/patch/9543/
21
22 X.Org Bug 47281 <http://bugs.freedesktop.org/show_bug.cgi?id=47281>
23
24 Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
25 Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
26 (cherry picked from commit af88b43f9e604157b74270d609c08bdfa256a792)
27
28--- a/dix/getevents.c
29+++ b/dix/getevents.c
30@@ -1593,6 +1593,9 @@
31 /* Now turn the smooth-scrolling axes back into emulated button presses
32 * for legacy clients, based on the integer delta between before and now */
33 for (i = 0; i < valuator_mask_size(&mask); i++) {
34+ if (i >= pDev->valuator->numAxes)
35+ break;
36+
37 if (!valuator_mask_isset(&mask, i))
38 continue;
39
diff --git a/debian/patches/516-randr-first-check-pScrPriv-before-using-the-pointer.patch b/debian/patches/516-randr-first-check-pScrPriv-before-using-the-pointer.patch
deleted file mode 100644
index 8c9cf71..0000000
--- a/debian/patches/516-randr-first-check-pScrPriv-before-using-the-pointer.patch
+++ /dev/null
@@ -1,30 +0,0 @@
1From 32603f57ca03b6390b109960f8bb5ea53ac95ecb Mon Sep 17 00:00:00 2001
2From: Ricardo Salveti de Araujo <ricardo.salveti@linaro.org>
3Date: Thu, 21 Jun 2012 00:55:53 -0300
4Subject: [PATCH] randr: first check pScrPriv before using the pointer at
5 RRFirstOutput
6
7Fix a seg fault in case pScrPriv is NULL at ProcRRGetScreenInfo,
8which later calls RRFirstOutput.
9
10Signed-off-by: Ricardo Salveti de Araujo <ricardo.salveti@linaro.org>
11Reviewed-by: Keith Packard <keithp@keithp.com>
12Signed-off-by: Keith Packard <keithp@keithp.com>
13---
14 randr/randr.c | 3 +++
15 1 file changed, 3 insertions(+)
16
17Index: xorg-server-1.11.4/randr/randr.c
18===================================================================
19--- xorg-server-1.11.4.orig/randr/randr.c 2012-07-17 18:46:06.000000000 -0300
20+++ xorg-server-1.11.4/randr/randr.c 2012-07-17 18:48:35.169824448 -0300
21@@ -454,6 +454,9 @@
22 rrScrPriv(pScreen);
23 RROutputPtr output;
24 int i, j;
25+
26+ if (!pScrPriv)
27+ return NULL;
28
29 if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc)
30 return pScrPriv->primaryOutput;
diff --git a/debian/patches/517-randr-Catch-two-more-potential-unset-rrScrPriv-uses.patch b/debian/patches/517-randr-Catch-two-more-potential-unset-rrScrPriv-uses.patch
deleted file mode 100644
index e37d073..0000000
--- a/debian/patches/517-randr-Catch-two-more-potential-unset-rrScrPriv-uses.patch
+++ /dev/null
@@ -1,52 +0,0 @@
1From 855003c333a0ead1db912695bc9705ef2b3144b4 Mon Sep 17 00:00:00 2001
2From: Keith Packard <keithp@keithp.com>
3Date: Thu, 21 Jun 2012 18:45:18 -0700
4Subject: [PATCH] randr: Catch two more potential unset rrScrPriv uses
5
6Ricardo Salveti <ricardo.salveti@linaro.org> found one place where the
7randr code could use the randr screen private data without checking
8for null first. This happens when the X server is running with
9multiple screens, some of which are randr enabled and some of which
10are not. Applications making protocol requests to the non-randr
11screens can cause segfaults where the server touches the unset private
12structure.
13
14I audited the code and found two more possible problem spots; the
15trick to auditing for this issue was to look for functions not taking
16a RandR data structure and where there was no null screen private
17check above them in the call graph.
18
19Signed-off-by: Keith Packard <keithp@keithp.com>
20---
21 randr/rroutput.c | 3 ++-
22 randr/rrscreen.c | 3 +++
23 2 files changed, 5 insertions(+), 1 deletion(-)
24
25diff --git a/randr/rroutput.c b/randr/rroutput.c
26index 091e06b..fbd0e32 100644
27--- a/randr/rroutput.c
28+++ b/randr/rroutput.c
29@@ -546,7 +546,8 @@ ProcRRSetOutputPrimary(ClientPtr client)
30 }
31
32 pScrPriv = rrGetScrPriv(pWin->drawable.pScreen);
33- RRSetPrimaryOutput(pWin->drawable.pScreen, pScrPriv, output);
34+ if (pScrPriv)
35+ RRSetPrimaryOutput(pWin->drawable.pScreen, pScrPriv, output);
36
37 return Success;
38 }
39diff --git a/randr/rrscreen.c b/randr/rrscreen.c
40index f570afa..55110e0 100644
41--- a/randr/rrscreen.c
42+++ b/randr/rrscreen.c
43@@ -261,6 +261,9 @@
44
45 pScreen = pWin->drawable.pScreen;
46 pScrPriv = rrGetScrPriv(pScreen);
47+ if (!pScrPriv)
48+ return BadMatch;
49+
50 if (stuff->width < pScrPriv->minWidth || pScrPriv->maxWidth < stuff->width)
51 {
52 client->errorValue = stuff->width;
diff --git a/debian/patches/series b/debian/patches/series
deleted file mode 100644
index 8688706..0000000
--- a/debian/patches/series
+++ /dev/null
@@ -1,62 +0,0 @@
1## Patches with a number < 100 are applied in debian.
2## Ubuntu patches start with 100.
30001-add-dri2video.patch
4001_fedora_extramodes.patch
502_Add-libnettle-as-option-for-sha1.diff
607-xfree86-fix-build-with-xv-disabled.diff
7#13_debian_add_xkbpath_env_variable.diff
815-nouveau.diff
9
10# Ubuntu patches
11100_rethrow_signals.patch
12105_nvidia_fglrx_autodetect.patch
13111_armel-drv-fallbacks.patch
14122_xext_fix_card32_overflow_in_xauth.patch
15157_check_null_modes.patch
16162_null_crtc_in_rotation.patch
17165_man_xorg_conf_no_device_ident.patch
18166_nullptr_xinerama_keyrepeat.patch
19167_nullptr_xisbread.patch
20168_glibc_trace_to_stderr.patch
21172_cwgetbackingpicture_nullptr_check.patch
22188_default_primary_to_first_busid.patch
23190_cache-xkbcomp_output_for_fast_start_up.patch
24191-Xorg-add-an-extra-module-path.patch
25198_nohwaccess.patch
26200_randr-null.patch
27#201_report-real-dpi.patch
28208_switch_on_release.diff
29209_add_legacy_bgnone_option.patch
30224_return_BadWindow_not_BadMatch.diff
31225_non-root_config_paths.patch
32226_fall_back_to_autoconfiguration.patch
33227_null_ptr_midispcur.patch
34228_log-format-fix.patch
35229_randr_first_check_pScrPriv_before_using_the_pointer.patch
36230_randr_catch_two_more_potential_unset_rrScrPriv_uses.patch
37233-xf86events-valgrind.patch
38235-composite-tracking.diff
39238-xrandr-fix-panning.patch
40
41## Input Stack Patches (from xserver 1.12) ##
42500_pointer_barrier_thresholds.diff
43505_query_pointer_touchscreen.patch
44506_touchscreen_pointer_emulation_checks.patch
45507_touchscreen_fixes.patch
46# Patch 508 attempted to fix LP: #968845, but caused regression
47# crash bug #1009629. Patches 510-515 attempted to fix that
48# regression, but this led to the severe crash bug #1021517.
49# So, disabling the patch set until this can be studied better.
50#508_device_off_release_buttons.patch
51#510-dix-return-early-from-DisableDevice-if-the-device-is.patch
52#511-dix-move-freeing-the-sprite-into-a-function.patch
53#512-dix-free-the-sprite-when-disabling-the-device.patch
54#513-dix-disable-non-sprite-owners-first-when-disabling-p.patch
55#514-Xi-drop-forced-unpairing-when-changing-the-hierarchy.patch
56#515-dix-disable-all-devices-before-shutdown.patch
57516-dix-dont-emulate-scroll-events-for-non-existing-axes.patch
58
59# Rotation patches
601001-xfree86-modes-Let-the-driver-handle-the-transform.patch
611002-xfree86-modes-Make-cursor-position-transform-a-helpe.patch
62