diff options
author | Nikhil Devshatwar | 2013-06-10 08:58:41 -0500 |
---|---|---|
committer | Nikhil Devshatwar | 2013-06-10 08:58:41 -0500 |
commit | 1680ed87f202cedafa8e80239a825c2694172de2 (patch) | |
tree | 8be2642cd461c4b8e350790e185f23f405e8f561 | |
parent | d57f3032216f67daf49b532cdbb9231a0c2827b2 (diff) | |
download | xserver-1680ed87f202cedafa8e80239a825c2694172de2.tar.gz xserver-1680ed87f202cedafa8e80239a825c2694172de2.tar.xz xserver-1680ed87f202cedafa8e80239a825c2694172de2.zip |
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 @@ | |||
1 | From 1301542b17a9ea3cc185e24a3e40d33daa66e8ce Mon Sep 17 00:00:00 2001 | ||
2 | From: Rob Clark <rob@ti.com> | ||
3 | Date: Tue, 15 Nov 2011 14:28:06 -0600 | ||
4 | Subject: [PATCH] add dri2video | ||
5 | |||
6 | TODO: | ||
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 | |||
16 | Index: 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 | } | ||
682 | Index: 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 | ||
889 | Index: 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 @@ | |||
1 | From: Adam Jackson <ajax@redhat.com> | ||
2 | Date: Sun, 28 Oct 2007 09:37:52 +0100 | ||
3 | Subject: [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 @@ | |||
1 | From a6119f6cd7e47041044fcc9c15a6e3f9f189b3ed Mon Sep 17 00:00:00 2001 | ||
2 | From: Cyril Brulebois <kibi@debian.org> | ||
3 | Date: Sun, 14 Mar 2010 22:01:47 +0100 | ||
4 | Subject: [PATCH] Add libnettle as option for sha1. | ||
5 | |||
6 | Signed-off-by: Cyril Brulebois <kibi@debian.org> | ||
7 | |||
8 | [jcristau: forward-ported from 1.7 to 1.8] | ||
9 | Signed-off-by: Julien Cristau <jcristau@debian.org> | ||
10 | --- | ||
11 | Index: 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]) | ||
41 | Index: 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 | |||
55 | Index: 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 @@ | |||
1 | From fe7575e929d65e8c798104ec2f72b879051694d3 Mon Sep 17 00:00:00 2001 | ||
2 | From: Julien Cristau <jcristau@debian.org> | ||
3 | Date: Mon, 8 Feb 2010 02:04:33 +0100 | ||
4 | Subject: [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 | |||
11 | Index: 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) | ||
31 | Index: 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 @@ | |||
1 | From 245cb8e94fd15990e1b7d6622added460f104dba Mon Sep 17 00:00:00 2001 | ||
2 | From: Aaron Plattner <aplattner@nvidia.com> | ||
3 | Date: Thu, 25 Aug 2011 10:19:48 -0700 | ||
4 | Subject: [PATCH 1/2] xfree86/modes: Let the driver handle the transform | ||
5 | |||
6 | If a driver can use hardware to handle the crtc transform, then | ||
7 | there's no need for the server's shadow layer to do it. Add a crtc | ||
8 | flag that lets the driver indicate that it is handling the transform. | ||
9 | If it's set, consider the transformed size of the screen but don't | ||
10 | actually enable the shadow layer. Also stop adjusting the cursor | ||
11 | image and position. | ||
12 | |||
13 | Signed-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 | |||
20 | diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h | ||
21 | index 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 { | ||
60 | diff --git a/hw/xfree86/modes/xf86Cursors.c b/hw/xfree86/modes/xf86Cursors.c | ||
61 | index 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 | ||
158 | diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c | ||
159 | index 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 | -- | ||
332 | 1.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 @@ | |||
1 | From 57cd32e93425597317b4b7722859155419836e4c Mon Sep 17 00:00:00 2001 | ||
2 | From: Aaron Plattner <aplattner@nvidia.com> | ||
3 | Date: Thu, 25 Aug 2011 15:41:55 -0700 | ||
4 | Subject: [PATCH 2/2] xfree86/modes: Make cursor position transform a helper function | ||
5 | |||
6 | When the driver can handle the crtc transform in hardware, it sets | ||
7 | crtc->driverIsPerformingTransform, which turns off both the shadow | ||
8 | layer and the cursor's position-transforming code. However, some | ||
9 | drivers actually do require the cursor position to still be | ||
10 | transformed in these cases. Move the cursor position transform into a | ||
11 | helper function that can be called by such drivers. | ||
12 | |||
13 | Signed-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 | |||
19 | Index: 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) | ||
38 | Index: 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 @@ | |||
1 | Index: 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. */ | ||
26 | Index: 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 | { | ||
51 | Index: 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[]) | ||
75 | Index: 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 */ | ||
88 | Index: 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 | ||
185 | Index: 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 | { | ||
208 | Index: 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 | +} | ||
235 | Index: 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) | ||
261 | Index: 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 | |||
275 | Index: 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; | ||
356 | Index: 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 @@ | |||
1 | From 0366a844c36bf8424a2625425c181b9b97f35bee Mon Sep 17 00:00:00 2001 | ||
2 | From: Robert Hooker <sarvatt@ubuntu.com> | ||
3 | Date: Wed, 1 Sep 2010 13:23:21 -0400 | ||
4 | Subject: [PATCH] Attempt to get nvidia and fglrx working without an xorg.conf. | ||
5 | |||
6 | Signed-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 | |||
12 | Index: 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 | |||
42 | Index: 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 @@ | |||
1 | Index: 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 @@ | |||
1 | Description: 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. | ||
9 | Origin: http://patchwork.freedesktop.org/patch/242/ | ||
10 | Bug: https://bugs.freedesktop.org/show_bug.cgi?id=27134 | ||
11 | Bug-Ubuntu: https://launchpad.net/bugs/519049 | ||
12 | |||
13 | Index: 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 @@ | |||
1 | From a685b5cf34532cef96fc9b05f735088ac0c0c7ad Mon Sep 17 00:00:00 2001 | ||
2 | From: Fedora X Ninjas <x@fedoraproject.org> | ||
3 | Date: Tue, 16 Feb 2010 11:38:17 +1000 | ||
4 | Subject: [PATCH 08/17] autoconfig: select nouveau by default for NVIDIA GPUs | ||
5 | |||
6 | Also, 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 | --- | ||
13 | v2: 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 | |||
18 | Signed-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 @@ | |||
1 | Index: 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 @@ | |||
1 | Index: 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 @@ | |||
1 | From b3bb14b11a58f7bfc3ba5617c524d01a6e683de1 Mon Sep 17 00:00:00 2001 | ||
2 | From: Bryce Harrington <bryce@bryceharrington.org> | ||
3 | Date: Wed, 18 Mar 2009 21:08:19 -0700 | ||
4 | Subject: [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 | |||
7 | Signed-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 | |||
12 | Index: 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 @@ | |||
1 | From f0ef98d8d54f5dfa3081b62ff672e0fe992b0a01 Mon Sep 17 00:00:00 2001 | ||
2 | From: Bryce Harrington <bryce@bryceharrington.org> | ||
3 | Date: Wed, 18 Mar 2009 23:28:51 -0700 | ||
4 | Subject: [PATCH] Check for null pointer dereference to prevent crash | ||
5 | on non-primary Xinerama screens when key repeating. | ||
6 | (LP: #324465) | ||
7 | |||
8 | Signed-off-by: Bryce Harrington <bryce@bryceharrington.org> | ||
9 | --- | ||
10 | mi/mipointer.c | 4 ++++ | ||
11 | 1 files changed, 4 insertions(+), 0 deletions(-) | ||
12 | |||
13 | Index: 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 @@ | |||
1 | Index: 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 @@ | |||
1 | Report abort traces to stderr instead of terminal. This enables apport | ||
2 | to catch the error so it can file a bug report about the crash. | ||
3 | |||
4 | Index: 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 @@ | |||
1 | From 7813adf66be31d8b0e8df21821e786e688f7fe78 Mon Sep 17 00:00:00 2001 | ||
2 | From: Bryce Harrington <bryce@bryceharrington.org> | ||
3 | Date: Fri, 27 Mar 2009 19:01:32 -0700 | ||
4 | Subject: [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 | |||
8 | Signed-off-by: Bryce Harrington <bryce@bryceharrington.org> | ||
9 | --- | ||
10 | miext/cw/cw_render.c | 13 +++++++++---- | ||
11 | 1 files changed, 9 insertions(+), 4 deletions(-) | ||
12 | |||
13 | Index: 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 @@ | |||
1 | If there seems to be more than one possible primary device, just | ||
2 | pick the first device and carry on (LP 459512) | ||
3 | |||
4 | signed-off-by: Bryce Harrington <bryce@canonical.com> | ||
5 | |||
6 | Index: 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 @@ | |||
1 | Patch from Moblin to cache xkbcomp output for faster booting | ||
2 | |||
3 | Signed-off-by: Bryce Harrington <bryce@canonical.com> | ||
4 | --- | ||
5 | |||
6 | Index: 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 | ||
31 | Index: 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. | ||
50 | Index: 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 @@ | |||
1 | From 416a66de9d428a11776331926c23a61188b8fc16 Mon Sep 17 00:00:00 2001 | ||
2 | From: Ander Conselvan de Oliveira <ander@localhost.(none)> | ||
3 | Date: Thu, 12 Mar 2009 09:45:57 -0300 | ||
4 | Subject: [PATCH 908/911] Xorg: add an extra module path | ||
5 | |||
6 | If the extra module path is not an empty string (the default value), | ||
7 | module path will be searched first in the extra module path and then in | ||
8 | the default module path. This should simplify the alternatives system | ||
9 | used on Mandriva's fglrx package. | ||
10 | --- | ||
11 | Index: 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]) | ||
34 | Index: 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); | ||
62 | Index: 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; | ||
74 | Index: 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; | ||
86 | Index: 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 @@ | |||
1 | Two chunks of jbarne's nohwaccess patch got taken upstream; this patch | ||
2 | contains just the remainder, which implements a -nohwaccess option. | ||
3 | |||
4 | Index: 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 | } | ||
34 | Index: 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' | ||
2 | Index: 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 @@ | |||
1 | Description: 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. | ||
9 | Author: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com> | ||
10 | |||
11 | Index: 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 @@ | |||
1 | Index: 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 @@ | |||
1 | Index: 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 @@ | |||
1 | Index: 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 | |||
14 | Index: 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, | ||
35 | Index: 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]) | ||
53 | Index: 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 | } | ||
165 | Index: 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, | ||
186 | Index: 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 @@ | |||
1 | From: Ian Pilcher <arequipeno@gmail.com> | ||
2 | Subject: Backout commit 6dd775f57d2f94f0ddaee324aeec33b9b66ed5bc | ||
3 | |||
4 | Index: 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 @@ | |||
1 | From 14f1112bec18ccece8e732fe6c200a56546230c7 Mon Sep 17 00:00:00 2001 | ||
2 | From: Adam Jackson <ajax@redhat.com> | ||
3 | Date: Thu, 17 Mar 2011 13:56:17 -0400 | ||
4 | Subject: [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 | |||
22 | Index: 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 | */ | ||
40 | Index: 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*/ | ||
85 | Index: 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); | ||
97 | Index: 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 */ | ||
110 | Index: 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 | { | ||
158 | Index: 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, | ||
175 | Index: 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; | ||
188 | Index: 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); | ||
210 | Index: 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 | +} | ||
414 | Index: 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 | |||
885 | Index: 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 | |||
954 | Index: 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_ */ | ||
988 | Index: 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 @@ | |||
1 | commit ef492e9797b6d4f6bbc25e86bedc24477819fde7 | ||
2 | Author: Chris Halse Rogers <christopher.halse.rogers@canonical.com> | ||
3 | Date: 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 | |||
27 | diff --git a/dix/dixutils.c b/dix/dixutils.c | ||
28 | index 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 @@ | |||
1 | From ead968a4300c0adeff89b9886e888b6d284c75cc Mon Sep 17 00:00:00 2001 | ||
2 | From: Antoine Martin <antoine@nagafix.co.uk> | ||
3 | Date: Sat, 17 Dec 2011 01:36:51 +0700 | ||
4 | Subject: [PATCH] xserver: check for elevated privileges not uid=0 | ||
5 | |||
6 | This allows us to run the server as a normal user whilst still | ||
7 | being able to use the -modulepath, -logfile and -config switches | ||
8 | We define a xf86PrivsElevated which will do the checks and cache | ||
9 | the result in case it is called more than once. | ||
10 | Also renamed the paths #defines to match their new meaning. | ||
11 | Original discussion which led to this patch can be found here: | ||
12 | http://lists.freedesktop.org/archives/xorg-devel/2011-September/025853.html | ||
13 | |||
14 | Signed-off-by: Antoine Martin <antoine@nagafix.co.uk> | ||
15 | Tested-by: Michal Suchanek <hramrach at centrum.cz> | ||
16 | Reviewed-by: Jamey Sharp <jamey at minilop.net> | ||
17 | Reviewed-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 @@ | |||
1 | From 1d22d773f67f8c00ab8881d2cce00ef95abf24f7 Mon Sep 17 00:00:00 2001 | ||
2 | From: Alberto Milone <alberto.milone@canonical.com> | ||
3 | Date: Fri, 27 Jan 2012 19:31:55 +0100 | ||
4 | Subject: [PATCH 1/1] Try to fall back to autoconfiguration in some cases | ||
5 | despite having configuration files | ||
6 | |||
7 | Fall back to autoconfiguration if either the graphics | ||
8 | driver module specified in configuration files can't be | ||
9 | found or if there's no device supported by the specified | ||
10 | driver. | ||
11 | |||
12 | Signed-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 | |||
19 | diff --git a/hw/xfree86/common/xf86Globals.c b/hw/xfree86/common/xf86Globals.c | ||
20 | index 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", | ||
31 | diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c | ||
32 | index 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 | |||
91 | diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h | ||
92 | index 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 | -- | ||
104 | 1.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 @@ | |||
1 | diff -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 @@ | |||
1 | Description: extreme backport of upstream log format fixes (CVE-2012-2118). | ||
2 | Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/xorg-server/+bug/996250 | ||
3 | Origin: http://patchwork.freedesktop.org/patch/10001/ | ||
4 | |||
5 | Index: 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; | ||
272 | Index: 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 */ | ||
293 | Index: 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) | ||
348 | Index: 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 */ | ||
409 | Index: 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 @@ | |||
1 | From 32603f57ca03b6390b109960f8bb5ea53ac95ecb Mon Sep 17 00:00:00 2001 | ||
2 | From: Ricardo Salveti de Araujo <ricardo.salveti@linaro.org> | ||
3 | Date: Thu, 21 Jun 2012 00:55:53 -0300 | ||
4 | Subject: [PATCH] randr: first check pScrPriv before using the pointer at | ||
5 | RRFirstOutput | ||
6 | |||
7 | Fix a seg fault in case pScrPriv is NULL at ProcRRGetScreenInfo, | ||
8 | which later calls RRFirstOutput. | ||
9 | |||
10 | Signed-off-by: Ricardo Salveti de Araujo <ricardo.salveti@linaro.org> | ||
11 | Reviewed-by: Keith Packard <keithp@keithp.com> | ||
12 | Signed-off-by: Keith Packard <keithp@keithp.com> | ||
13 | --- | ||
14 | randr/randr.c | 3 +++ | ||
15 | 1 file changed, 3 insertions(+) | ||
16 | |||
17 | Index: 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 @@ | |||
1 | From 855003c333a0ead1db912695bc9705ef2b3144b4 Mon Sep 17 00:00:00 2001 | ||
2 | From: Keith Packard <keithp@keithp.com> | ||
3 | Date: Thu, 21 Jun 2012 18:45:18 -0700 | ||
4 | Subject: [PATCH] randr: Catch two more potential unset rrScrPriv uses | ||
5 | |||
6 | Ricardo Salveti <ricardo.salveti@linaro.org> found one place where the | ||
7 | randr code could use the randr screen private data without checking | ||
8 | for null first. This happens when the X server is running with | ||
9 | multiple screens, some of which are randr enabled and some of which | ||
10 | are not. Applications making protocol requests to the non-randr | ||
11 | screens can cause segfaults where the server touches the unset private | ||
12 | structure. | ||
13 | |||
14 | I audited the code and found two more possible problem spots; the | ||
15 | trick to auditing for this issue was to look for functions not taking | ||
16 | a RandR data structure and where there was no null screen private | ||
17 | check above them in the call graph. | ||
18 | |||
19 | Signed-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 | |||
25 | diff --git a/randr/rroutput.c b/randr/rroutput.c | ||
26 | index 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 | } | ||
39 | diff --git a/randr/rrscreen.c b/randr/rrscreen.c | ||
40 | index 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 @@ | |||
1 | diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c | ||
2 | index 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 @@ | |||
1 | diff --git a/exa/exa_priv.h b/exa/exa_priv.h | ||
2 | index 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 | |||
13 | diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c | ||
14 | index 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(®, &box, 1); | ||
39 | RegionUnion(dst, dst, ®); | ||
40 | RegionUninit(®); | ||
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 @@ | |||
1 | Description: disable CRTC cursor confinement when panning is enabled | ||
2 | Origin: backport, http://cgit.freedesktop.org/xorg/xserver/commit/?id=1bf81af4a6be1113bcc3b940ab264d5c9e0f0c5d | ||
3 | Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/xorg-server/+bug/883319 | ||
4 | Bug: https://bugs.freedesktop.org/show_bug.cgi?id=39949 | ||
5 | |||
6 | Index: 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 @@ | |||
1 | Index: 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 */ | ||
14 | Index: 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 | |||
539 | Index: 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 | ||
573 | Index: 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 | |||
611 | Index: 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); | ||
650 | Index: 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 | ||
683 | Index: 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 | +} | ||
1516 | Index: 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 | ]) | ||
1554 | Index: 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) | ||
1586 | Index: 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 | |||
1601 | Index: 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 | ||
1610 | Index: 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 | ||
1668 | Index: 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; | ||
1682 | Index: 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 @@ | |||
1 | From 3d6bd9fd8bd565f4c0513b2649a678109f60bd27 Mon Sep 17 00:00:00 2001 | ||
2 | From: Chase Douglas <chase.douglas@canonical.com> | ||
3 | Date: Tue, 3 Apr 2012 17:18:43 -0700 | ||
4 | Subject: [PATCH] Use touch state when querying pointer through core protocol | ||
5 | |||
6 | QueryPointer is part of the core protocol. As such, it knows nothing | ||
7 | about touch devices. Touches are converted to button 1 press, pointer | ||
8 | motion, and button 1 release for core clients, so we should ensure the | ||
9 | pointer state mask has button 1 set when XQueryPointer is used. | ||
10 | |||
11 | Signed-off-by: Chase Douglas <chase.douglas@canonical.com> | ||
12 | --- | ||
13 | dix/events.c | 3 +-- | ||
14 | 1 files changed, 1 insertions(+), 2 deletions(-) | ||
15 | |||
16 | diff --git a/dix/events.c b/dix/events.c | ||
17 | index 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 | -- | ||
31 | 1.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 @@ | |||
1 | From ec9c4295830c3de610e65aca17f4da4a7af3c4c5 Mon Sep 17 00:00:00 2001 | ||
2 | From: Chase Douglas <chase.douglas@canonical.com> | ||
3 | Date: Wed, 18 Apr 2012 12:04:58 -0700 | ||
4 | Subject: [PATCH] Check other clients' core masks properly when adding touch | ||
5 | listener | ||
6 | |||
7 | The current code checks the core event mask as though it were an XI | ||
8 | mask. This change fixes the checks so the proper client and event masks | ||
9 | are used. | ||
10 | |||
11 | Signed-off-by: Chase Douglas <chase.douglas@canonical.com> | ||
12 | Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net> | ||
13 | --- | ||
14 | dix/touch.c | 8 ++++---- | ||
15 | 1 files changed, 4 insertions(+), 4 deletions(-) | ||
16 | |||
17 | diff --git a/dix/touch.c b/dix/touch.c | ||
18 | index 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 | -- | ||
47 | 1.7.9.1 | ||
48 | |||
49 | From 01091806f762f6f8fc83dc1051b5f3cfb38e88b1 Mon Sep 17 00:00:00 2001 | ||
50 | From: Chase Douglas <chase.douglas@canonical.com> | ||
51 | Date: Wed, 4 Apr 2012 12:57:40 -0700 | ||
52 | Subject: [PATCH 2/3] Check core event mask properly for pointer emulated | ||
53 | touch events | ||
54 | |||
55 | The current code checks the core event mask as though it were an XI2 | ||
56 | mask. This change fixes the checks so the proper client and event masks | ||
57 | are used. | ||
58 | |||
59 | Signed-off-by: Chase Douglas <chase.douglas@canonical.com> | ||
60 | |||
61 | Conflicts: | ||
62 | |||
63 | Xi/exevents.c | ||
64 | --- | ||
65 | Xi/exevents.c | 13 +++++++++---- | ||
66 | 1 files changed, 9 insertions(+), 4 deletions(-) | ||
67 | |||
68 | diff --git a/Xi/exevents.c b/Xi/exevents.c | ||
69 | index 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 | -- | ||
109 | 1.7.9.1 | ||
110 | |||
111 | From 4b4c88b247c6435578c983d74a90f35472849f3a Mon Sep 17 00:00:00 2001 | ||
112 | From: Chase Douglas <chase.douglas@canonical.com> | ||
113 | Date: Wed, 4 Apr 2012 12:59:55 -0700 | ||
114 | Subject: [PATCH 3/3] Only set XI2 mask if pointer emulation is for XI2 client | ||
115 | |||
116 | The current code returns a reference to memory that may not actually be | ||
117 | an XI2 mask. Instead, only return a value when an XI2 client has | ||
118 | selected for events. | ||
119 | |||
120 | Signed-off-by: Chase Douglas <chase.douglas@canonical.com> | ||
121 | |||
122 | Conflicts: | ||
123 | |||
124 | Xi/exevents.c | ||
125 | --- | ||
126 | Xi/exevents.c | 3 ++- | ||
127 | 1 files changed, 2 insertions(+), 1 deletions(-) | ||
128 | |||
129 | diff --git a/Xi/exevents.c b/Xi/exevents.c | ||
130 | index 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 | -- | ||
158 | 1.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 @@ | |||
1 | From adaf1adecf5697455e9f3fb0234939113873f959 Mon Sep 17 00:00:00 2001 | ||
2 | From: Peter Hutterer <peter.hutterer@who-t.net> | ||
3 | Date: Mon, 30 Apr 2012 10:01:48 +1000 | ||
4 | Subject: [PATCH] dix: when disabling a device, release all buttons and keys | ||
5 | |||
6 | A suspend-induced device disable may happen before the device gets to see | ||
7 | the button release event. On resume, the server's internal state still has | ||
8 | some buttons pressed, causing inconsistent behaviour. | ||
9 | |||
10 | Force the release and the matching events to be sent to the client. | ||
11 | |||
12 | Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> | ||
13 | Reviewed-by: Chase Douglas <chase.douglas@canonical.com> | ||
14 | |||
15 | Conflicts: | ||
16 | |||
17 | dix/devices.c | ||
18 | --- | ||
19 | dix/devices.c | 2 ++ | ||
20 | 1 files changed, 2 insertions(+), 0 deletions(-) | ||
21 | |||
22 | diff --git a/dix/devices.c b/dix/devices.c | ||
23 | index 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 | -- | ||
36 | 1.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 @@ | |||
1 | From 46adcefb0e08515195d8e49985a4e210395700b3 Mon Sep 17 00:00:00 2001 | ||
2 | From: Peter Hutterer <peter.hutterer@who-t.net> | ||
3 | Date: Thu, 10 May 2012 12:10:12 +1000 | ||
4 | Subject: [PATCH 07/12] dix: return early from DisableDevice if the device is | ||
5 | already disabled | ||
6 | |||
7 | Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> | ||
8 | Reviewed-by: Chase Douglas <chase.douglas@canonical.com> | ||
9 | --- | ||
10 | dix/devices.c | 3 +++ | ||
11 | 1 file changed, 3 insertions(+) | ||
12 | |||
13 | diff --git a/dix/devices.c b/dix/devices.c | ||
14 | index 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 | -- | ||
28 | 1.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 @@ | |||
1 | From e57d6a89027c55fef987cdc259668c48a8b4ea1b Mon Sep 17 00:00:00 2001 | ||
2 | From: Peter Hutterer <peter.hutterer@who-t.net> | ||
3 | Date: Thu, 10 May 2012 15:32:20 +1000 | ||
4 | Subject: [PATCH 08/12] dix: move freeing the sprite into a function | ||
5 | |||
6 | Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> | ||
7 | Reviewed-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 @@ | |||
1 | From df1704365e700d3cf1d36a241bdfc479159a8df7 Mon Sep 17 00:00:00 2001 | ||
2 | From: Peter Hutterer <peter.hutterer@who-t.net> | ||
3 | Date: Thu, 10 May 2012 15:33:15 +1000 | ||
4 | Subject: [PATCH 09/12] dix: free the sprite when disabling the device | ||
5 | |||
6 | Disabled devices don't need sprites (they can't send events anyway) and the | ||
7 | device init process is currently geared to check for whether sprite is | ||
8 | present to check if the device should be paired/attached. | ||
9 | |||
10 | Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> | ||
11 | Reviewed-by: Chase Douglas <chase.douglas@canonical.com> | ||
12 | --- | ||
13 | dix/devices.c | 2 ++ | ||
14 | 1 file changed, 2 insertions(+) | ||
15 | |||
16 | diff --git a/dix/devices.c b/dix/devices.c | ||
17 | index 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 | -- | ||
30 | 1.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 @@ | |||
1 | From e433d1046c222f9d969c2c28a4651ff9097614f4 Mon Sep 17 00:00:00 2001 | ||
2 | From: Peter Hutterer <peter.hutterer@who-t.net> | ||
3 | Date: Thu, 10 May 2012 12:42:59 +1000 | ||
4 | Subject: [PATCH 10/12] dix: disable non-sprite-owners first when disabling | ||
5 | paired devices | ||
6 | |||
7 | If a sprite-owner is to be disabled but still paired, disable the paired | ||
8 | device first. i.e. disabling a master pointer will disable the master | ||
9 | keyboard first. | ||
10 | |||
11 | Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> | ||
12 | Reviewed-by: Chase Douglas <chase.douglas@canonical.com> | ||
13 | --- | ||
14 | Altered 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 @@ | |||
1 | From 9c0e820216cd1631f75b037b7908d55ac091692c Mon Sep 17 00:00:00 2001 | ||
2 | From: Peter Hutterer <peter.hutterer@who-t.net> | ||
3 | Date: Thu, 10 May 2012 12:55:44 +1000 | ||
4 | Subject: [PATCH 11/12] Xi: drop forced unpairing when changing the hierarchy | ||
5 | |||
6 | Devices are unpaired as needed on DisableDevice now. | ||
7 | |||
8 | Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> | ||
9 | Reviewed-by: Chase Douglas <chase.douglas@canonical.com> | ||
10 | --- | ||
11 | Xi/xichangehierarchy.c | 6 ------ | ||
12 | 1 file changed, 6 deletions(-) | ||
13 | |||
14 | diff --git a/Xi/xichangehierarchy.c b/Xi/xichangehierarchy.c | ||
15 | index 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 | -- | ||
32 | 1.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 @@ | |||
1 | From 4c68f5d395c66f28b56e488cb3cd12f36820357b Mon Sep 17 00:00:00 2001 | ||
2 | From: Peter Hutterer <peter.hutterer@who-t.net> | ||
3 | Date: Wed, 9 May 2012 09:21:28 +1000 | ||
4 | Subject: [PATCH 12/12] dix: disable all devices before shutdown | ||
5 | |||
6 | f3410b97cf9b48a47bee3d15d232f8a88e75f4ef introduced a regression on server | ||
7 | shutdown. If any button or key was held on shutdown (ctrl, alt, backspace | ||
8 | are usually still down) sending a raw event will segfault the server. The | ||
9 | the root windows are set to NULL before calling CloseDownDevices(). | ||
10 | |||
11 | Avoid this by disabling all devices first when shutting down. Disabled | ||
12 | devices won't send events anymore. | ||
13 | |||
14 | Master keyboards must be disabled first, otherwise disabling the pointer | ||
15 | will trigger DisableDevice(keyboard) and the keyboard is removed from the | ||
16 | inputInfo.devices list and moved to inputInfo.off_devices. A regular loop | ||
17 | through inputInfo.devices would thus jump to off_devices and not recover. | ||
18 | |||
19 | Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> | ||
20 | Acked-by: Chase Douglas <chase.douglas@canonical.com> | ||
21 | Reviewed-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 @@ | |||
1 | commit b53cdf4c53f0787ed41281278877e0405fcb2674 | ||
2 | Author: Peter Hutterer <peter.hutterer@who-t.net> | ||
3 | Date: 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 @@ | |||
1 | From 32603f57ca03b6390b109960f8bb5ea53ac95ecb Mon Sep 17 00:00:00 2001 | ||
2 | From: Ricardo Salveti de Araujo <ricardo.salveti@linaro.org> | ||
3 | Date: Thu, 21 Jun 2012 00:55:53 -0300 | ||
4 | Subject: [PATCH] randr: first check pScrPriv before using the pointer at | ||
5 | RRFirstOutput | ||
6 | |||
7 | Fix a seg fault in case pScrPriv is NULL at ProcRRGetScreenInfo, | ||
8 | which later calls RRFirstOutput. | ||
9 | |||
10 | Signed-off-by: Ricardo Salveti de Araujo <ricardo.salveti@linaro.org> | ||
11 | Reviewed-by: Keith Packard <keithp@keithp.com> | ||
12 | Signed-off-by: Keith Packard <keithp@keithp.com> | ||
13 | --- | ||
14 | randr/randr.c | 3 +++ | ||
15 | 1 file changed, 3 insertions(+) | ||
16 | |||
17 | Index: 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 @@ | |||
1 | From 855003c333a0ead1db912695bc9705ef2b3144b4 Mon Sep 17 00:00:00 2001 | ||
2 | From: Keith Packard <keithp@keithp.com> | ||
3 | Date: Thu, 21 Jun 2012 18:45:18 -0700 | ||
4 | Subject: [PATCH] randr: Catch two more potential unset rrScrPriv uses | ||
5 | |||
6 | Ricardo Salveti <ricardo.salveti@linaro.org> found one place where the | ||
7 | randr code could use the randr screen private data without checking | ||
8 | for null first. This happens when the X server is running with | ||
9 | multiple screens, some of which are randr enabled and some of which | ||
10 | are not. Applications making protocol requests to the non-randr | ||
11 | screens can cause segfaults where the server touches the unset private | ||
12 | structure. | ||
13 | |||
14 | I audited the code and found two more possible problem spots; the | ||
15 | trick to auditing for this issue was to look for functions not taking | ||
16 | a RandR data structure and where there was no null screen private | ||
17 | check above them in the call graph. | ||
18 | |||
19 | Signed-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 | |||
25 | diff --git a/randr/rroutput.c b/randr/rroutput.c | ||
26 | index 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 | } | ||
39 | diff --git a/randr/rrscreen.c b/randr/rrscreen.c | ||
40 | index 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. | ||
3 | 0001-add-dri2video.patch | ||
4 | 001_fedora_extramodes.patch | ||
5 | 02_Add-libnettle-as-option-for-sha1.diff | ||
6 | 07-xfree86-fix-build-with-xv-disabled.diff | ||
7 | #13_debian_add_xkbpath_env_variable.diff | ||
8 | 15-nouveau.diff | ||
9 | |||
10 | # Ubuntu patches | ||
11 | 100_rethrow_signals.patch | ||
12 | 105_nvidia_fglrx_autodetect.patch | ||
13 | 111_armel-drv-fallbacks.patch | ||
14 | 122_xext_fix_card32_overflow_in_xauth.patch | ||
15 | 157_check_null_modes.patch | ||
16 | 162_null_crtc_in_rotation.patch | ||
17 | 165_man_xorg_conf_no_device_ident.patch | ||
18 | 166_nullptr_xinerama_keyrepeat.patch | ||
19 | 167_nullptr_xisbread.patch | ||
20 | 168_glibc_trace_to_stderr.patch | ||
21 | 172_cwgetbackingpicture_nullptr_check.patch | ||
22 | 188_default_primary_to_first_busid.patch | ||
23 | 190_cache-xkbcomp_output_for_fast_start_up.patch | ||
24 | 191-Xorg-add-an-extra-module-path.patch | ||
25 | 198_nohwaccess.patch | ||
26 | 200_randr-null.patch | ||
27 | #201_report-real-dpi.patch | ||
28 | 208_switch_on_release.diff | ||
29 | 209_add_legacy_bgnone_option.patch | ||
30 | 224_return_BadWindow_not_BadMatch.diff | ||
31 | 225_non-root_config_paths.patch | ||
32 | 226_fall_back_to_autoconfiguration.patch | ||
33 | 227_null_ptr_midispcur.patch | ||
34 | 228_log-format-fix.patch | ||
35 | 229_randr_first_check_pScrPriv_before_using_the_pointer.patch | ||
36 | 230_randr_catch_two_more_potential_unset_rrScrPriv_uses.patch | ||
37 | 233-xf86events-valgrind.patch | ||
38 | 235-composite-tracking.diff | ||
39 | 238-xrandr-fix-panning.patch | ||
40 | |||
41 | ## Input Stack Patches (from xserver 1.12) ## | ||
42 | 500_pointer_barrier_thresholds.diff | ||
43 | 505_query_pointer_touchscreen.patch | ||
44 | 506_touchscreen_pointer_emulation_checks.patch | ||
45 | 507_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 | ||
57 | 516-dix-dont-emulate-scroll-events-for-non-existing-axes.patch | ||
58 | |||
59 | # Rotation patches | ||
60 | 1001-xfree86-modes-Let-the-driver-handle-the-transform.patch | ||
61 | 1002-xfree86-modes-Make-cursor-position-transform-a-helpe.patch | ||
62 | |||