Commit | Line | Data |
---|---|---|
a09e091a JB |
1 | /* |
2 | * Copyright © 2003 Keith Packard | |
3 | * | |
4 | * Permission to use, copy, modify, distribute, and sell this software and its | |
5 | * documentation for any purpose is hereby granted without fee, provided that | |
6 | * the above copyright notice appear in all copies and that both that | |
7 | * copyright notice and this permission notice appear in supporting | |
8 | * documentation, and that the name of Keith Packard not be used in | |
9 | * advertising or publicity pertaining to distribution of the software without | |
10 | * specific, written prior permission. Keith Packard makes no | |
11 | * representations about the suitability of this software for any purpose. It | |
12 | * is provided "as is" without express or implied warranty. | |
13 | * | |
14 | * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | |
15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | |
16 | * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR | |
17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, | |
18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |
19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | |
20 | * PERFORMANCE OF THIS SOFTWARE. | |
21 | */ | |
22 | ||
23 | #ifdef HAVE_DIX_CONFIG_H | |
24 | #include <dix-config.h> | |
25 | #endif | |
26 | ||
27 | #include "xfixesint.h" | |
28 | #include "scrnintstr.h" | |
29 | #include <picturestr.h> | |
30 | ||
31 | #include <regionstr.h> | |
32 | #include <gcstruct.h> | |
33 | #include <window.h> | |
34 | ||
35 | RESTYPE RegionResType; | |
36 | ||
37 | static int | |
38 | RegionResFree(pointer data, XID id) | |
39 | { | |
40 | RegionPtr pRegion = (RegionPtr) data; | |
41 | ||
42 | RegionDestroy(pRegion); | |
43 | return Success; | |
44 | } | |
45 | ||
46 | RegionPtr | |
47 | XFixesRegionCopy(RegionPtr pRegion) | |
48 | { | |
49 | RegionPtr pNew = RegionCreate(RegionExtents(pRegion), | |
50 | RegionNumRects(pRegion)); | |
51 | ||
52 | if (!pNew) | |
53 | return 0; | |
54 | if (!RegionCopy(pNew, pRegion)) { | |
55 | RegionDestroy(pNew); | |
56 | return 0; | |
57 | } | |
58 | return pNew; | |
59 | } | |
60 | ||
61 | Bool | |
62 | XFixesRegionInit(void) | |
63 | { | |
64 | RegionResType = CreateNewResourceType(RegionResFree, "XFixesRegion"); | |
65 | ||
66 | return RegionResType != 0; | |
67 | } | |
68 | ||
69 | int | |
70 | ProcXFixesCreateRegion(ClientPtr client) | |
71 | { | |
72 | int things; | |
73 | RegionPtr pRegion; | |
74 | ||
75 | REQUEST(xXFixesCreateRegionReq); | |
76 | ||
77 | REQUEST_AT_LEAST_SIZE(xXFixesCreateRegionReq); | |
78 | LEGAL_NEW_RESOURCE(stuff->region, client); | |
79 | ||
80 | things = (client->req_len << 2) - sizeof(xXFixesCreateRegionReq); | |
81 | if (things & 4) | |
82 | return BadLength; | |
83 | things >>= 3; | |
84 | ||
85 | pRegion = RegionFromRects(things, (xRectangle *) (stuff + 1), CT_UNSORTED); | |
86 | if (!pRegion) | |
87 | return BadAlloc; | |
88 | if (!AddResource(stuff->region, RegionResType, (pointer) pRegion)) | |
89 | return BadAlloc; | |
90 | ||
91 | return Success; | |
92 | } | |
93 | ||
94 | int | |
95 | SProcXFixesCreateRegion(ClientPtr client) | |
96 | { | |
97 | REQUEST(xXFixesCreateRegionReq); | |
98 | ||
99 | swaps(&stuff->length); | |
100 | REQUEST_AT_LEAST_SIZE(xXFixesCreateRegionReq); | |
101 | swapl(&stuff->region); | |
102 | SwapRestS(stuff); | |
103 | return (*ProcXFixesVector[stuff->xfixesReqType]) (client); | |
104 | } | |
105 | ||
106 | int | |
107 | ProcXFixesCreateRegionFromBitmap(ClientPtr client) | |
108 | { | |
109 | RegionPtr pRegion; | |
110 | PixmapPtr pPixmap; | |
111 | int rc; | |
112 | ||
113 | REQUEST(xXFixesCreateRegionFromBitmapReq); | |
114 | ||
115 | REQUEST_SIZE_MATCH(xXFixesCreateRegionFromBitmapReq); | |
116 | LEGAL_NEW_RESOURCE(stuff->region, client); | |
117 | ||
118 | rc = dixLookupResourceByType((pointer *) &pPixmap, stuff->bitmap, RT_PIXMAP, | |
119 | client, DixReadAccess); | |
120 | if (rc != Success) { | |
121 | client->errorValue = stuff->bitmap; | |
122 | return rc; | |
123 | } | |
124 | if (pPixmap->drawable.depth != 1) | |
125 | return BadMatch; | |
126 | ||
127 | pRegion = BitmapToRegion(pPixmap->drawable.pScreen, pPixmap); | |
128 | ||
129 | if (!pRegion) | |
130 | return BadAlloc; | |
131 | ||
132 | if (!AddResource(stuff->region, RegionResType, (pointer) pRegion)) | |
133 | return BadAlloc; | |
134 | ||
135 | return Success; | |
136 | } | |
137 | ||
138 | int | |
139 | SProcXFixesCreateRegionFromBitmap(ClientPtr client) | |
140 | { | |
141 | REQUEST(xXFixesCreateRegionFromBitmapReq); | |
142 | ||
143 | swaps(&stuff->length); | |
144 | REQUEST_SIZE_MATCH(xXFixesCreateRegionFromBitmapReq); | |
145 | swapl(&stuff->region); | |
146 | swapl(&stuff->bitmap); | |
147 | return (*ProcXFixesVector[stuff->xfixesReqType]) (client); | |
148 | } | |
149 | ||
150 | int | |
151 | ProcXFixesCreateRegionFromWindow(ClientPtr client) | |
152 | { | |
153 | RegionPtr pRegion; | |
154 | Bool copy = TRUE; | |
155 | WindowPtr pWin; | |
156 | int rc; | |
157 | ||
158 | REQUEST(xXFixesCreateRegionFromWindowReq); | |
159 | ||
160 | REQUEST_SIZE_MATCH(xXFixesCreateRegionFromWindowReq); | |
161 | LEGAL_NEW_RESOURCE(stuff->region, client); | |
162 | rc = dixLookupResourceByType((pointer *) &pWin, stuff->window, RT_WINDOW, | |
163 | client, DixGetAttrAccess); | |
164 | if (rc != Success) { | |
165 | client->errorValue = stuff->window; | |
166 | return rc; | |
167 | } | |
168 | switch (stuff->kind) { | |
169 | case WindowRegionBounding: | |
170 | pRegion = wBoundingShape(pWin); | |
171 | if (!pRegion) { | |
172 | pRegion = CreateBoundingShape(pWin); | |
173 | copy = FALSE; | |
174 | } | |
175 | break; | |
176 | case WindowRegionClip: | |
177 | pRegion = wClipShape(pWin); | |
178 | if (!pRegion) { | |
179 | pRegion = CreateClipShape(pWin); | |
180 | copy = FALSE; | |
181 | } | |
182 | break; | |
183 | default: | |
184 | client->errorValue = stuff->kind; | |
185 | return BadValue; | |
186 | } | |
187 | if (copy && pRegion) | |
188 | pRegion = XFixesRegionCopy(pRegion); | |
189 | if (!pRegion) | |
190 | return BadAlloc; | |
191 | if (!AddResource(stuff->region, RegionResType, (pointer) pRegion)) | |
192 | return BadAlloc; | |
193 | ||
194 | return Success; | |
195 | } | |
196 | ||
197 | int | |
198 | SProcXFixesCreateRegionFromWindow(ClientPtr client) | |
199 | { | |
200 | REQUEST(xXFixesCreateRegionFromWindowReq); | |
201 | ||
202 | swaps(&stuff->length); | |
203 | REQUEST_SIZE_MATCH(xXFixesCreateRegionFromWindowReq); | |
204 | swapl(&stuff->region); | |
205 | swapl(&stuff->window); | |
206 | return (*ProcXFixesVector[stuff->xfixesReqType]) (client); | |
207 | } | |
208 | ||
209 | int | |
210 | ProcXFixesCreateRegionFromGC(ClientPtr client) | |
211 | { | |
212 | RegionPtr pRegion, pClip; | |
213 | GCPtr pGC; | |
214 | int rc; | |
215 | ||
216 | REQUEST(xXFixesCreateRegionFromGCReq); | |
217 | ||
218 | REQUEST_SIZE_MATCH(xXFixesCreateRegionFromGCReq); | |
219 | LEGAL_NEW_RESOURCE(stuff->region, client); | |
220 | ||
221 | rc = dixLookupGC(&pGC, stuff->gc, client, DixGetAttrAccess); | |
222 | if (rc != Success) | |
223 | return rc; | |
224 | ||
225 | switch (pGC->clientClipType) { | |
226 | case CT_PIXMAP: | |
227 | pRegion = BitmapToRegion(pGC->pScreen, (PixmapPtr) pGC->clientClip); | |
228 | if (!pRegion) | |
229 | return BadAlloc; | |
230 | break; | |
231 | case CT_REGION: | |
232 | pClip = (RegionPtr) pGC->clientClip; | |
233 | pRegion = XFixesRegionCopy(pClip); | |
234 | if (!pRegion) | |
235 | return BadAlloc; | |
236 | break; | |
237 | default: | |
238 | return BadImplementation; /* assume sane server bits */ | |
239 | } | |
240 | ||
241 | if (!AddResource(stuff->region, RegionResType, (pointer) pRegion)) | |
242 | return BadAlloc; | |
243 | ||
244 | return Success; | |
245 | } | |
246 | ||
247 | int | |
248 | SProcXFixesCreateRegionFromGC(ClientPtr client) | |
249 | { | |
250 | REQUEST(xXFixesCreateRegionFromGCReq); | |
251 | ||
252 | swaps(&stuff->length); | |
253 | REQUEST_SIZE_MATCH(xXFixesCreateRegionFromGCReq); | |
254 | swapl(&stuff->region); | |
255 | swapl(&stuff->gc); | |
256 | return (*ProcXFixesVector[stuff->xfixesReqType]) (client); | |
257 | } | |
258 | ||
259 | int | |
260 | ProcXFixesCreateRegionFromPicture(ClientPtr client) | |
261 | { | |
262 | RegionPtr pRegion; | |
263 | PicturePtr pPicture; | |
264 | ||
265 | REQUEST(xXFixesCreateRegionFromPictureReq); | |
266 | ||
267 | REQUEST_SIZE_MATCH(xXFixesCreateRegionFromPictureReq); | |
268 | LEGAL_NEW_RESOURCE(stuff->region, client); | |
269 | ||
270 | VERIFY_PICTURE(pPicture, stuff->picture, client, DixGetAttrAccess); | |
271 | ||
272 | switch (pPicture->clientClipType) { | |
273 | case CT_PIXMAP: | |
274 | pRegion = BitmapToRegion(pPicture->pDrawable->pScreen, | |
275 | (PixmapPtr) pPicture->clientClip); | |
276 | if (!pRegion) | |
277 | return BadAlloc; | |
278 | break; | |
279 | case CT_REGION: | |
280 | pRegion = XFixesRegionCopy((RegionPtr) pPicture->clientClip); | |
281 | if (!pRegion) | |
282 | return BadAlloc; | |
283 | break; | |
284 | default: | |
285 | return BadImplementation; /* assume sane server bits */ | |
286 | } | |
287 | ||
288 | if (!AddResource(stuff->region, RegionResType, (pointer) pRegion)) | |
289 | return BadAlloc; | |
290 | ||
291 | return Success; | |
292 | } | |
293 | ||
294 | int | |
295 | SProcXFixesCreateRegionFromPicture(ClientPtr client) | |
296 | { | |
297 | REQUEST(xXFixesCreateRegionFromPictureReq); | |
298 | ||
299 | swaps(&stuff->length); | |
300 | REQUEST_SIZE_MATCH(xXFixesCreateRegionFromPictureReq); | |
301 | swapl(&stuff->region); | |
302 | swapl(&stuff->picture); | |
303 | return (*ProcXFixesVector[stuff->xfixesReqType]) (client); | |
304 | } | |
305 | ||
306 | int | |
307 | ProcXFixesDestroyRegion(ClientPtr client) | |
308 | { | |
309 | REQUEST(xXFixesDestroyRegionReq); | |
310 | RegionPtr pRegion; | |
311 | ||
312 | REQUEST_SIZE_MATCH(xXFixesDestroyRegionReq); | |
313 | VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess); | |
314 | FreeResource(stuff->region, RT_NONE); | |
315 | return Success; | |
316 | } | |
317 | ||
318 | int | |
319 | SProcXFixesDestroyRegion(ClientPtr client) | |
320 | { | |
321 | REQUEST(xXFixesDestroyRegionReq); | |
322 | ||
323 | swaps(&stuff->length); | |
324 | REQUEST_SIZE_MATCH(xXFixesDestroyRegionReq); | |
325 | swapl(&stuff->region); | |
326 | return (*ProcXFixesVector[stuff->xfixesReqType]) (client); | |
327 | } | |
328 | ||
329 | int | |
330 | ProcXFixesSetRegion(ClientPtr client) | |
331 | { | |
332 | int things; | |
333 | RegionPtr pRegion, pNew; | |
334 | ||
335 | REQUEST(xXFixesSetRegionReq); | |
336 | ||
337 | REQUEST_AT_LEAST_SIZE(xXFixesSetRegionReq); | |
338 | VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess); | |
339 | ||
340 | things = (client->req_len << 2) - sizeof(xXFixesCreateRegionReq); | |
341 | if (things & 4) | |
342 | return BadLength; | |
343 | things >>= 3; | |
344 | ||
345 | pNew = RegionFromRects(things, (xRectangle *) (stuff + 1), CT_UNSORTED); | |
346 | if (!pNew) | |
347 | return BadAlloc; | |
348 | if (!RegionCopy(pRegion, pNew)) { | |
349 | RegionDestroy(pNew); | |
350 | return BadAlloc; | |
351 | } | |
352 | RegionDestroy(pNew); | |
353 | return Success; | |
354 | } | |
355 | ||
356 | int | |
357 | SProcXFixesSetRegion(ClientPtr client) | |
358 | { | |
359 | REQUEST(xXFixesSetRegionReq); | |
360 | ||
361 | swaps(&stuff->length); | |
362 | REQUEST_AT_LEAST_SIZE(xXFixesSetRegionReq); | |
363 | swapl(&stuff->region); | |
364 | SwapRestS(stuff); | |
365 | return (*ProcXFixesVector[stuff->xfixesReqType]) (client); | |
366 | } | |
367 | ||
368 | int | |
369 | ProcXFixesCopyRegion(ClientPtr client) | |
370 | { | |
371 | RegionPtr pSource, pDestination; | |
372 | ||
373 | REQUEST(xXFixesCopyRegionReq); | |
374 | ||
375 | VERIFY_REGION(pSource, stuff->source, client, DixReadAccess); | |
376 | VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); | |
377 | ||
378 | if (!RegionCopy(pDestination, pSource)) | |
379 | return BadAlloc; | |
380 | ||
381 | return Success; | |
382 | } | |
383 | ||
384 | int | |
385 | SProcXFixesCopyRegion(ClientPtr client) | |
386 | { | |
387 | REQUEST(xXFixesCopyRegionReq); | |
388 | ||
389 | swaps(&stuff->length); | |
390 | REQUEST_AT_LEAST_SIZE(xXFixesCopyRegionReq); | |
391 | swapl(&stuff->source); | |
392 | swapl(&stuff->destination); | |
393 | return (*ProcXFixesVector[stuff->xfixesReqType]) (client); | |
394 | } | |
395 | ||
396 | int | |
397 | ProcXFixesCombineRegion(ClientPtr client) | |
398 | { | |
399 | RegionPtr pSource1, pSource2, pDestination; | |
400 | ||
401 | REQUEST(xXFixesCombineRegionReq); | |
402 | ||
403 | REQUEST_SIZE_MATCH(xXFixesCombineRegionReq); | |
404 | VERIFY_REGION(pSource1, stuff->source1, client, DixReadAccess); | |
405 | VERIFY_REGION(pSource2, stuff->source2, client, DixReadAccess); | |
406 | VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); | |
407 | ||
408 | switch (stuff->xfixesReqType) { | |
409 | case X_XFixesUnionRegion: | |
410 | if (!RegionUnion(pDestination, pSource1, pSource2)) | |
411 | return BadAlloc; | |
412 | break; | |
413 | case X_XFixesIntersectRegion: | |
414 | if (!RegionIntersect(pDestination, pSource1, pSource2)) | |
415 | return BadAlloc; | |
416 | break; | |
417 | case X_XFixesSubtractRegion: | |
418 | if (!RegionSubtract(pDestination, pSource1, pSource2)) | |
419 | return BadAlloc; | |
420 | break; | |
421 | } | |
422 | ||
423 | return Success; | |
424 | } | |
425 | ||
426 | int | |
427 | SProcXFixesCombineRegion(ClientPtr client) | |
428 | { | |
429 | REQUEST(xXFixesCombineRegionReq); | |
430 | ||
431 | swaps(&stuff->length); | |
432 | REQUEST_SIZE_MATCH(xXFixesCombineRegionReq); | |
433 | swapl(&stuff->source1); | |
434 | swapl(&stuff->source2); | |
435 | swapl(&stuff->destination); | |
436 | return (*ProcXFixesVector[stuff->xfixesReqType]) (client); | |
437 | } | |
438 | ||
439 | int | |
440 | ProcXFixesInvertRegion(ClientPtr client) | |
441 | { | |
442 | RegionPtr pSource, pDestination; | |
443 | BoxRec bounds; | |
444 | ||
445 | REQUEST(xXFixesInvertRegionReq); | |
446 | ||
447 | REQUEST_SIZE_MATCH(xXFixesInvertRegionReq); | |
448 | VERIFY_REGION(pSource, stuff->source, client, DixReadAccess); | |
449 | VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); | |
450 | ||
451 | /* Compute bounds, limit to 16 bits */ | |
452 | bounds.x1 = stuff->x; | |
453 | bounds.y1 = stuff->y; | |
454 | if ((int) stuff->x + (int) stuff->width > MAXSHORT) | |
455 | bounds.x2 = MAXSHORT; | |
456 | else | |
457 | bounds.x2 = stuff->x + stuff->width; | |
458 | ||
459 | if ((int) stuff->y + (int) stuff->height > MAXSHORT) | |
460 | bounds.y2 = MAXSHORT; | |
461 | else | |
462 | bounds.y2 = stuff->y + stuff->height; | |
463 | ||
464 | if (!RegionInverse(pDestination, pSource, &bounds)) | |
465 | return BadAlloc; | |
466 | ||
467 | return Success; | |
468 | } | |
469 | ||
470 | int | |
471 | SProcXFixesInvertRegion(ClientPtr client) | |
472 | { | |
473 | REQUEST(xXFixesInvertRegionReq); | |
474 | ||
475 | swaps(&stuff->length); | |
476 | REQUEST_SIZE_MATCH(xXFixesInvertRegionReq); | |
477 | swapl(&stuff->source); | |
478 | swaps(&stuff->x); | |
479 | swaps(&stuff->y); | |
480 | swaps(&stuff->width); | |
481 | swaps(&stuff->height); | |
482 | swapl(&stuff->destination); | |
483 | return (*ProcXFixesVector[stuff->xfixesReqType]) (client); | |
484 | } | |
485 | ||
486 | int | |
487 | ProcXFixesTranslateRegion(ClientPtr client) | |
488 | { | |
489 | RegionPtr pRegion; | |
490 | ||
491 | REQUEST(xXFixesTranslateRegionReq); | |
492 | ||
493 | REQUEST_SIZE_MATCH(xXFixesTranslateRegionReq); | |
494 | VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess); | |
495 | ||
496 | RegionTranslate(pRegion, stuff->dx, stuff->dy); | |
497 | return Success; | |
498 | } | |
499 | ||
500 | int | |
501 | SProcXFixesTranslateRegion(ClientPtr client) | |
502 | { | |
503 | REQUEST(xXFixesTranslateRegionReq); | |
504 | ||
505 | swaps(&stuff->length); | |
506 | REQUEST_SIZE_MATCH(xXFixesTranslateRegionReq); | |
507 | swapl(&stuff->region); | |
508 | swaps(&stuff->dx); | |
509 | swaps(&stuff->dy); | |
510 | return (*ProcXFixesVector[stuff->xfixesReqType]) (client); | |
511 | } | |
512 | ||
513 | int | |
514 | ProcXFixesRegionExtents(ClientPtr client) | |
515 | { | |
516 | RegionPtr pSource, pDestination; | |
517 | ||
518 | REQUEST(xXFixesRegionExtentsReq); | |
519 | ||
520 | REQUEST_SIZE_MATCH(xXFixesRegionExtentsReq); | |
521 | VERIFY_REGION(pSource, stuff->source, client, DixReadAccess); | |
522 | VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); | |
523 | ||
524 | RegionReset(pDestination, RegionExtents(pSource)); | |
525 | ||
526 | return Success; | |
527 | } | |
528 | ||
529 | int | |
530 | SProcXFixesRegionExtents(ClientPtr client) | |
531 | { | |
532 | REQUEST(xXFixesRegionExtentsReq); | |
533 | ||
534 | swaps(&stuff->length); | |
535 | REQUEST_SIZE_MATCH(xXFixesRegionExtentsReq); | |
536 | swapl(&stuff->source); | |
537 | swapl(&stuff->destination); | |
538 | return (*ProcXFixesVector[stuff->xfixesReqType]) (client); | |
539 | } | |
540 | ||
541 | int | |
542 | ProcXFixesFetchRegion(ClientPtr client) | |
543 | { | |
544 | RegionPtr pRegion; | |
545 | xXFixesFetchRegionReply *reply; | |
546 | xRectangle *pRect; | |
547 | BoxPtr pExtent; | |
548 | BoxPtr pBox; | |
549 | int i, nBox; | |
550 | ||
551 | REQUEST(xXFixesFetchRegionReq); | |
552 | ||
553 | REQUEST_SIZE_MATCH(xXFixesFetchRegionReq); | |
554 | VERIFY_REGION(pRegion, stuff->region, client, DixReadAccess); | |
555 | ||
556 | pExtent = RegionExtents(pRegion); | |
557 | pBox = RegionRects(pRegion); | |
558 | nBox = RegionNumRects(pRegion); | |
559 | ||
560 | reply = calloc(sizeof(xXFixesFetchRegionReply) + nBox * sizeof(xRectangle), | |
561 | 1); | |
562 | if (!reply) | |
563 | return BadAlloc; | |
564 | reply->type = X_Reply; | |
565 | reply->sequenceNumber = client->sequence; | |
566 | reply->length = nBox << 1; | |
567 | reply->x = pExtent->x1; | |
568 | reply->y = pExtent->y1; | |
569 | reply->width = pExtent->x2 - pExtent->x1; | |
570 | reply->height = pExtent->y2 - pExtent->y1; | |
571 | ||
572 | pRect = (xRectangle *) (reply + 1); | |
573 | for (i = 0; i < nBox; i++) { | |
574 | pRect[i].x = pBox[i].x1; | |
575 | pRect[i].y = pBox[i].y1; | |
576 | pRect[i].width = pBox[i].x2 - pBox[i].x1; | |
577 | pRect[i].height = pBox[i].y2 - pBox[i].y1; | |
578 | } | |
579 | if (client->swapped) { | |
580 | swaps(&reply->sequenceNumber); | |
581 | swapl(&reply->length); | |
582 | swaps(&reply->x); | |
583 | swaps(&reply->y); | |
584 | swaps(&reply->width); | |
585 | swaps(&reply->height); | |
586 | SwapShorts((INT16 *) pRect, nBox * 4); | |
587 | } | |
588 | WriteToClient(client, sizeof(xXFixesFetchRegionReply) + | |
589 | nBox * sizeof(xRectangle), (char *) reply); | |
590 | free(reply); | |
591 | return Success; | |
592 | } | |
593 | ||
594 | int | |
595 | SProcXFixesFetchRegion(ClientPtr client) | |
596 | { | |
597 | REQUEST(xXFixesFetchRegionReq); | |
598 | ||
599 | swaps(&stuff->length); | |
600 | REQUEST_SIZE_MATCH(xXFixesFetchRegionReq); | |
601 | swapl(&stuff->region); | |
602 | return (*ProcXFixesVector[stuff->xfixesReqType]) (client); | |
603 | } | |
604 | ||
605 | int | |
606 | ProcXFixesSetGCClipRegion(ClientPtr client) | |
607 | { | |
608 | GCPtr pGC; | |
609 | RegionPtr pRegion; | |
610 | ChangeGCVal vals[2]; | |
611 | int rc; | |
612 | ||
613 | REQUEST(xXFixesSetGCClipRegionReq); | |
614 | REQUEST_SIZE_MATCH(xXFixesSetGCClipRegionReq); | |
615 | ||
616 | rc = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess); | |
617 | if (rc != Success) | |
618 | return rc; | |
619 | ||
620 | VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, DixReadAccess); | |
621 | ||
622 | if (pRegion) { | |
623 | pRegion = XFixesRegionCopy(pRegion); | |
624 | if (!pRegion) | |
625 | return BadAlloc; | |
626 | } | |
627 | ||
628 | vals[0].val = stuff->xOrigin; | |
629 | vals[1].val = stuff->yOrigin; | |
630 | ChangeGC(NullClient, pGC, GCClipXOrigin | GCClipYOrigin, vals); | |
631 | (*pGC->funcs->ChangeClip) (pGC, pRegion ? CT_REGION : CT_NONE, | |
632 | (pointer) pRegion, 0); | |
633 | ||
634 | return Success; | |
635 | } | |
636 | ||
637 | int | |
638 | SProcXFixesSetGCClipRegion(ClientPtr client) | |
639 | { | |
640 | REQUEST(xXFixesSetGCClipRegionReq); | |
641 | ||
642 | swaps(&stuff->length); | |
643 | REQUEST_SIZE_MATCH(xXFixesSetGCClipRegionReq); | |
644 | swapl(&stuff->gc); | |
645 | swapl(&stuff->region); | |
646 | swaps(&stuff->xOrigin); | |
647 | swaps(&stuff->yOrigin); | |
648 | return (*ProcXFixesVector[stuff->xfixesReqType]) (client); | |
649 | } | |
650 | ||
651 | typedef RegionPtr (*CreateDftPtr) (WindowPtr pWin); | |
652 | ||
653 | int | |
654 | ProcXFixesSetWindowShapeRegion(ClientPtr client) | |
655 | { | |
656 | WindowPtr pWin; | |
657 | RegionPtr pRegion; | |
658 | RegionPtr *pDestRegion; | |
659 | int rc; | |
660 | ||
661 | REQUEST(xXFixesSetWindowShapeRegionReq); | |
662 | ||
663 | REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq); | |
664 | rc = dixLookupResourceByType((pointer *) &pWin, stuff->dest, RT_WINDOW, | |
665 | client, DixSetAttrAccess); | |
666 | if (rc != Success) { | |
667 | client->errorValue = stuff->dest; | |
668 | return rc; | |
669 | } | |
670 | VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, DixWriteAccess); | |
671 | switch (stuff->destKind) { | |
672 | case ShapeBounding: | |
673 | case ShapeClip: | |
674 | case ShapeInput: | |
675 | break; | |
676 | default: | |
677 | client->errorValue = stuff->destKind; | |
678 | return BadValue; | |
679 | } | |
680 | if (pRegion) { | |
681 | pRegion = XFixesRegionCopy(pRegion); | |
682 | if (!pRegion) | |
683 | return BadAlloc; | |
684 | if (!pWin->optional) | |
685 | MakeWindowOptional(pWin); | |
686 | switch (stuff->destKind) { | |
687 | default: | |
688 | case ShapeBounding: | |
689 | pDestRegion = &pWin->optional->boundingShape; | |
690 | break; | |
691 | case ShapeClip: | |
692 | pDestRegion = &pWin->optional->clipShape; | |
693 | break; | |
694 | case ShapeInput: | |
695 | pDestRegion = &pWin->optional->inputShape; | |
696 | break; | |
697 | } | |
698 | if (stuff->xOff || stuff->yOff) | |
699 | RegionTranslate(pRegion, stuff->xOff, stuff->yOff); | |
700 | } | |
701 | else { | |
702 | if (pWin->optional) { | |
703 | switch (stuff->destKind) { | |
704 | default: | |
705 | case ShapeBounding: | |
706 | pDestRegion = &pWin->optional->boundingShape; | |
707 | break; | |
708 | case ShapeClip: | |
709 | pDestRegion = &pWin->optional->clipShape; | |
710 | break; | |
711 | case ShapeInput: | |
712 | pDestRegion = &pWin->optional->inputShape; | |
713 | break; | |
714 | } | |
715 | } | |
716 | else | |
717 | pDestRegion = &pRegion; /* a NULL region pointer */ | |
718 | } | |
719 | if (*pDestRegion) | |
720 | RegionDestroy(*pDestRegion); | |
721 | *pDestRegion = pRegion; | |
722 | (*pWin->drawable.pScreen->SetShape) (pWin, stuff->destKind); | |
723 | SendShapeNotify(pWin, stuff->destKind); | |
724 | return Success; | |
725 | } | |
726 | ||
727 | int | |
728 | SProcXFixesSetWindowShapeRegion(ClientPtr client) | |
729 | { | |
730 | REQUEST(xXFixesSetWindowShapeRegionReq); | |
731 | ||
732 | swaps(&stuff->length); | |
733 | REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq); | |
734 | swapl(&stuff->dest); | |
735 | swaps(&stuff->xOff); | |
736 | swaps(&stuff->yOff); | |
737 | swapl(&stuff->region); | |
738 | return (*ProcXFixesVector[stuff->xfixesReqType]) (client); | |
739 | } | |
740 | ||
741 | int | |
742 | ProcXFixesSetPictureClipRegion(ClientPtr client) | |
743 | { | |
744 | PicturePtr pPicture; | |
745 | RegionPtr pRegion; | |
746 | ||
747 | REQUEST(xXFixesSetPictureClipRegionReq); | |
748 | ||
749 | REQUEST_SIZE_MATCH(xXFixesSetPictureClipRegionReq); | |
750 | VERIFY_PICTURE(pPicture, stuff->picture, client, DixSetAttrAccess); | |
751 | VERIFY_REGION_OR_NONE(pRegion, stuff->region, client, DixReadAccess); | |
752 | ||
753 | return SetPictureClipRegion(pPicture, stuff->xOrigin, stuff->yOrigin, | |
754 | pRegion); | |
755 | } | |
756 | ||
757 | int | |
758 | SProcXFixesSetPictureClipRegion(ClientPtr client) | |
759 | { | |
760 | REQUEST(xXFixesSetPictureClipRegionReq); | |
761 | ||
762 | swaps(&stuff->length); | |
763 | REQUEST_SIZE_MATCH(xXFixesSetPictureClipRegionReq); | |
764 | swapl(&stuff->picture); | |
765 | swapl(&stuff->region); | |
766 | swaps(&stuff->xOrigin); | |
767 | swaps(&stuff->yOrigin); | |
768 | return (*ProcXFixesVector[stuff->xfixesReqType]) (client); | |
769 | } | |
770 | ||
771 | int | |
772 | ProcXFixesExpandRegion(ClientPtr client) | |
773 | { | |
774 | RegionPtr pSource, pDestination; | |
775 | ||
776 | REQUEST(xXFixesExpandRegionReq); | |
777 | BoxPtr pTmp; | |
778 | BoxPtr pSrc; | |
779 | int nBoxes; | |
780 | int i; | |
781 | ||
782 | REQUEST_SIZE_MATCH(xXFixesExpandRegionReq); | |
783 | VERIFY_REGION(pSource, stuff->source, client, DixReadAccess); | |
784 | VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); | |
785 | ||
786 | nBoxes = RegionNumRects(pSource); | |
787 | pSrc = RegionRects(pSource); | |
788 | if (nBoxes) { | |
789 | pTmp = malloc(nBoxes * sizeof(BoxRec)); | |
790 | if (!pTmp) | |
791 | return BadAlloc; | |
792 | for (i = 0; i < nBoxes; i++) { | |
793 | pTmp[i].x1 = pSrc[i].x1 - stuff->left; | |
794 | pTmp[i].x2 = pSrc[i].x2 + stuff->right; | |
795 | pTmp[i].y1 = pSrc[i].y1 - stuff->top; | |
796 | pTmp[i].y2 = pSrc[i].y2 + stuff->bottom; | |
797 | } | |
798 | RegionEmpty(pDestination); | |
799 | for (i = 0; i < nBoxes; i++) { | |
800 | RegionRec r; | |
801 | ||
802 | RegionInit(&r, &pTmp[i], 0); | |
803 | RegionUnion(pDestination, pDestination, &r); | |
804 | } | |
805 | free(pTmp); | |
806 | } | |
807 | return Success; | |
808 | } | |
809 | ||
810 | int | |
811 | SProcXFixesExpandRegion(ClientPtr client) | |
812 | { | |
813 | REQUEST(xXFixesExpandRegionReq); | |
814 | ||
815 | swaps(&stuff->length); | |
816 | REQUEST_SIZE_MATCH(xXFixesExpandRegionReq); | |
817 | swapl(&stuff->source); | |
818 | swapl(&stuff->destination); | |
819 | swaps(&stuff->left); | |
820 | swaps(&stuff->right); | |
821 | swaps(&stuff->top); | |
822 | swaps(&stuff->bottom); | |
823 | return (*ProcXFixesVector[stuff->xfixesReqType]) (client); | |
824 | } | |
825 | ||
826 | #ifdef PANORAMIX | |
827 | #include "panoramiX.h" | |
828 | #include "panoramiXsrv.h" | |
829 | ||
830 | int | |
831 | PanoramiXFixesSetGCClipRegion(ClientPtr client) | |
832 | { | |
833 | REQUEST(xXFixesSetGCClipRegionReq); | |
834 | int result = Success, j; | |
835 | PanoramiXRes *gc; | |
836 | ||
837 | REQUEST_SIZE_MATCH(xXFixesSetGCClipRegionReq); | |
838 | ||
839 | if ((result = dixLookupResourceByType((void **) &gc, stuff->gc, XRT_GC, | |
840 | client, DixWriteAccess))) { | |
841 | client->errorValue = stuff->gc; | |
842 | return result; | |
843 | } | |
844 | ||
845 | FOR_NSCREENS_BACKWARD(j) { | |
846 | stuff->gc = gc->info[j].id; | |
847 | result = (*PanoramiXSaveXFixesVector[X_XFixesSetGCClipRegion]) (client); | |
848 | if (result != Success) | |
849 | break; | |
850 | } | |
851 | ||
852 | return result; | |
853 | } | |
854 | ||
855 | int | |
856 | PanoramiXFixesSetWindowShapeRegion(ClientPtr client) | |
857 | { | |
858 | int result = Success, j; | |
859 | PanoramiXRes *win; | |
860 | RegionPtr reg = NULL; | |
861 | ||
862 | REQUEST(xXFixesSetWindowShapeRegionReq); | |
863 | ||
864 | REQUEST_SIZE_MATCH(xXFixesSetWindowShapeRegionReq); | |
865 | ||
866 | if ((result = dixLookupResourceByType((void **) &win, stuff->dest, | |
867 | XRT_WINDOW, client, | |
868 | DixWriteAccess))) { | |
869 | client->errorValue = stuff->dest; | |
870 | return result; | |
871 | } | |
872 | ||
873 | if (win->u.win.root) | |
874 | VERIFY_REGION_OR_NONE(reg, stuff->region, client, DixReadAccess); | |
875 | ||
876 | FOR_NSCREENS_FORWARD(j) { | |
877 | ScreenPtr screen = screenInfo.screens[j]; | |
878 | stuff->dest = win->info[j].id; | |
879 | ||
880 | if (reg) | |
881 | RegionTranslate(reg, -screen->x, -screen->y); | |
882 | ||
883 | result = | |
884 | (*PanoramiXSaveXFixesVector[X_XFixesSetWindowShapeRegion]) (client); | |
885 | ||
886 | if (reg) | |
887 | RegionTranslate(reg, screen->x, screen->y); | |
888 | ||
889 | if (result != Success) | |
890 | break; | |
891 | } | |
892 | ||
893 | return result; | |
894 | } | |
895 | ||
896 | int | |
897 | PanoramiXFixesSetPictureClipRegion(ClientPtr client) | |
898 | { | |
899 | REQUEST(xXFixesSetPictureClipRegionReq); | |
900 | int result = Success, j; | |
901 | PanoramiXRes *pict; | |
902 | RegionPtr reg = NULL; | |
903 | ||
904 | REQUEST_SIZE_MATCH(xXFixesSetPictureClipRegionReq); | |
905 | ||
906 | if ((result = dixLookupResourceByType((void **) &pict, stuff->picture, | |
907 | XRT_PICTURE, client, | |
908 | DixWriteAccess))) { | |
909 | client->errorValue = stuff->picture; | |
910 | return result; | |
911 | } | |
912 | ||
913 | if (pict->u.pict.root) | |
914 | VERIFY_REGION_OR_NONE(reg, stuff->region, client, DixReadAccess); | |
915 | ||
916 | FOR_NSCREENS_BACKWARD(j) { | |
917 | ScreenPtr screen = screenInfo.screens[j]; | |
918 | stuff->picture = pict->info[j].id; | |
919 | ||
920 | if (reg) | |
921 | RegionTranslate(reg, -screen->x, -screen->y); | |
922 | ||
923 | result = | |
924 | (*PanoramiXSaveXFixesVector[X_XFixesSetPictureClipRegion]) (client); | |
925 | ||
926 | if (reg) | |
927 | RegionTranslate(reg, screen->x, screen->y); | |
928 | ||
929 | if (result != Success) | |
930 | break; | |
931 | } | |
932 | ||
933 | return result; | |
934 | } | |
935 | ||
936 | #endif |