rust/cargo-c: update to 0.10.7+cargo-0.84.0
[oi-userland.git] / components / x11 / libdga / src / dga_Xrequests.c
blob0c40d924c4cbfec09ab7f0d496f41a85063f9e31
1 /* Copyright (c) 1993, 2015, Oracle and/or its affiliates. All rights reserved.
3 * Permission is hereby granted, free of charge, to any person obtaining a
4 * copy of this software and associated documentation files (the "Software"),
5 * to deal in the Software without restriction, including without limitation
6 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 * and/or sell copies of the Software, and to permit persons to whom the
8 * Software is furnished to do so, subject to the following conditions:
10 * The above copyright notice and this permission notice (including the next
11 * paragraph) shall be included in all copies or substantial portions of the
12 * Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
24 /*
25 * dga_Xrequests.c - the client side code for DGA X11 requests
29 *-----------------------------------------------------------------------
31 * This code uses the standard extension mechanism for sending
32 * SUN_DGA private extension requests.
34 *-----------------------------------------------------------------------
37 #define NEED_REPLIES
38 #define NEED_EVENTS
40 #ifdef SERVER_DGA
41 #include <X11/X.h>
42 #include <X11/Xmd.h>
43 #include "resource.h"
44 #include "dixstruct.h"
45 #include <stdio.h>
46 #include "pixmapstr.h"
47 #else
49 #include <X11/Xlibint.h>
50 #include <sys/resource.h>
51 #include <sys/types.h>
52 #include <sys/socket.h>
53 #include <netinet/in.h>
54 #include <sys/un.h>
55 #include <netdb.h>
57 #ifdef SVR4
58 #include <sys/utsname.h>
59 #endif
60 #endif /* SERVER_DGA */
63 #include "dga.h"
64 #include "dga_Xrequests.h"
65 #include "dga_incls.h"
67 #include "XineramaInfo.h"
69 #ifdef SERVER_DGA
70 #define NEW 1 /* Flag for SHAPES to use new window grabber */
71 #define BadCookie 0
72 #endif
74 #define X_DGA 0 /* a hack, so GetReq and GetResReq work below */
76 #ifndef MIN
77 #define MIN(i,j) ((i)<(j)?(i):(j))
78 #endif
80 static struct dga_extinfo **dga_extinfo_table = 0; /* No table to start with */
81 static int dga_extinfo_table_size = 0;
83 static int terminate_dga_ext();
84 static int islocalhost();
85 static int dga_winlist_add();
86 static int dga_winlist_free();
87 void * _dga_is_X_window();
88 int dga_pixlist_add();
89 static int dga_pixlist_free();
90 void *_dga_is_X_pixmap();
92 extern void dgai_win_ungrab_common();
93 extern int _thr_main();
95 #ifdef SVR4
97 #ifdef MT
98 mutex_t dgaGlobalMutex;
99 mutex_t dgaGlobalPixmapMutex;
100 int dgaThreaded; /* 1 == linked with libthread, else 0 */
101 int dgaMTOn; /* 1 == MT per-drawable locking is turned on, else 0 */
102 #endif
103 int _dga_client_version = -1;
105 void
106 dga_init_version(ver)
107 int ver;
109 if (ver > -1)
110 _dga_client_version = ver;
111 #ifdef MT
112 dgaThreaded = (_thr_main() != -1) ? 1 : 0;
113 dgaMTOn = 0;
114 mutex_init(&dgaGlobalMutex, USYNC_THREAD, NULL);
115 mutex_init(&dgaGlobalPixmapMutex, USYNC_THREAD, NULL);
116 #endif
119 #endif
121 #ifndef SERVER_DGA
122 static struct dga_extinfo *
123 init_dga_ext(dpy)
124 Display *dpy;
126 int protmajor, protminor;
127 XExtCodes *xecp;
128 struct dga_extinfo *infop;
130 #ifdef SVR4
131 if (_dga_client_version < 0)
132 return 0;
133 #endif
134 if (dga_extinfo_table_size < (dpy->fd + 1)) {
136 /* We've got to allocate or grow the table */
137 struct rlimit rl;
138 int size;
139 struct dga_extinfo **tblptr;
141 size = (getrlimit(RLIMIT_NOFILE, &rl) < 0) ?
142 dga_extinfo_table_size : rl.rlim_cur;
143 if (size < (dpy->fd + 1))
144 return 0;
145 tblptr = (struct dga_extinfo **) ((dga_extinfo_table_size) ?
146 realloc(dga_extinfo_table, sizeof(struct dga_extinfo *) *
147 size) :
148 malloc(sizeof(struct dga_extinfo *) * size));
149 if (tblptr == NULL)
150 return 0;
151 dga_extinfo_table = tblptr;
152 memset((char *) &dga_extinfo_table[dga_extinfo_table_size],
153 (int)'\0',
154 sizeof(struct dga_extinfo *) *
155 (size - dga_extinfo_table_size));
156 dga_extinfo_table_size = size;
159 if (dga_extinfo_table[dpy->fd] != NULL)
160 return dga_extinfo_table[dpy->fd];
162 if (!islocalhost(dpy))
163 return 0;
165 if ((xecp = XInitExtension(dpy, "SUN_DGA")) != NULL) {
166 if (XDgaQueryVersion(dpy, &protmajor, &protminor) == 0) {
167 protmajor = 3;
168 /* protminor = 0; let minor number pass through */
171 else
172 return 0;
174 if ((infop = (struct dga_extinfo *)
175 malloc(sizeof(struct dga_extinfo))) == NULL)
176 return 0;
178 infop->protocol_major_version = protmajor;
179 infop->protocol_minor_version = protminor;
180 infop->extension = xecp->extension;
181 infop->major_opcode = xecp->major_opcode;
182 dga_extinfo_table[dpy->fd] = infop;
183 XESetCloseDisplay(dpy, infop->extension, terminate_dga_ext);
184 return infop;
187 static int
188 islocalhost(dpy)
189 Display *dpy;
191 char hostname[256];
192 char *colon;
193 unsigned int namelen;
194 size_t hostlen, phostlen;
195 #ifdef IPv6
196 struct addrinfo *localhostaddr;
197 struct addrinfo *otherhostaddr;
198 struct addrinfo *i, *j;
199 int equiv = 0;
200 char host[NI_MAXHOST];
201 #else
202 struct hostent *phost;
203 struct hostent *h;
204 #endif
205 union genericaddr {
206 struct sockaddr generic;
207 struct sockaddr_in internet;
208 #ifdef IPv6
209 struct sockaddr_in6 internetv6;
210 struct sockaddr_storage maximumsize;
211 #endif
212 struct sockaddr_un nuxi;
213 } addr;
215 if (dpy->display_name[0] == ':')
216 return 1;
217 #ifdef SVR4
218 colon = strrchr(dpy->display_name, ':');
219 #else
220 colon = rindex(dpy->display_name, ':');
221 #endif
222 phostlen = strlen(dpy->display_name) - (colon ? strlen(colon) : 0);
223 if((strncmp("unix", dpy->display_name, MIN(phostlen, 4)) == 0) ||
224 (strncmp("localhost", dpy->display_name, MIN(phostlen, 9)) == 0))
225 return 1;
227 /* We're not a unix domain connection so what are we? */
229 namelen = sizeof addr;
230 memset((char *) &addr, (int)'\0', sizeof addr);
231 if(getpeername(dpy->fd, (struct sockaddr *) &addr,
232 &namelen) < 0)
233 return 0;
235 hostlen = _XGetHostname(hostname, sizeof(hostname));
237 #ifdef IPv6
238 if (getaddrinfo(hostname, NULL, NULL, &localhostaddr) != 0)
239 return 0;
240 if (getnameinfo(&addr.generic, namelen, host, sizeof(host),
241 NULL, 0, 0) != 0) {
242 freeaddrinfo(localhostaddr);
243 return 0;
245 if (getaddrinfo(host, NULL, NULL, &otherhostaddr) != 0) {
246 freeaddrinfo(localhostaddr);
247 return 0;
250 for (i = localhostaddr; i != NULL && equiv == 0; i = i->ai_next) {
251 for (j = otherhostaddr; j != NULL && equiv == 0; j = j->ai_next) {
252 if (i->ai_family == j->ai_family) {
253 if (i->ai_family == AF_INET) {
254 struct sockaddr_in *sinA
255 = (struct sockaddr_in *) i->ai_addr;
256 struct sockaddr_in *sinB
257 = (struct sockaddr_in *) j->ai_addr;
258 struct in_addr *A = &sinA->sin_addr;
259 struct in_addr *B = &sinB->sin_addr;
261 if (memcmp(A,B,sizeof(struct in_addr)) == 0) {
262 equiv = 1;
264 } else if (i->ai_family == AF_INET6) {
265 struct sockaddr_in6 *sinA
266 = (struct sockaddr_in6 *) i->ai_addr;
267 struct sockaddr_in6 *sinB
268 = (struct sockaddr_in6 *) j->ai_addr;
269 struct in6_addr *A = &sinA->sin6_addr;
270 struct in6_addr *B = &sinB->sin6_addr;
272 if (memcmp(A,B,sizeof(struct in6_addr)) == 0) {
273 equiv = 1;
280 freeaddrinfo(localhostaddr);
281 freeaddrinfo(otherhostaddr);
282 return equiv;
283 #else
284 if ((addr.generic.sa_family != AF_INET) ||
285 ((h = gethostbyaddr((char *)&addr.internet.sin_addr,
286 sizeof addr.internet.sin_addr,
287 addr.internet.sin_family)) == 0))
288 return 0;
290 /* Find real host name on TCPIP */
291 phost = gethostbyname(h->h_name);
292 phostlen = strlen(phost->h_name);
294 if (strncmp(hostname, phost->h_name, MIN(phostlen, hostlen)))
295 return 0;
297 return 1;
298 #endif
302 static struct dga_extinfo *
303 lookup_dga_ext(dpy)
304 Display *dpy;
306 if (dga_extinfo_table_size < (dpy->fd + 1))
307 return 0;
308 return dga_extinfo_table[dpy->fd];
311 static int
312 terminate_dga_ext(dpy, codes)
313 Display *dpy;
314 XExtCodes *codes;
316 free(dga_extinfo_table[dpy->fd]);
317 dga_extinfo_table[dpy->fd] = NULL;
318 dga_winlist_free(dpy, NULL);
319 /* TODO: free pixmaps as well? */
320 return(1);
322 #endif /* SERVER_DGA */
324 Dga_token
325 XDgaGrabWindow(dpy, win)
326 Display *dpy;
327 Window win;
329 #ifdef SERVER_DGA
330 int val;
331 WindowPtr pWin = (WindowPtr)LookupIDByType(win, RT_WINDOW);
332 if (!pWin)
333 return (BadCookie);
335 if (((DrawablePtr)pWin)->type == DRAWABLE_PIXMAP)
336 return (BadCookie);
337 val = DgaWgGrab(pWin, NEW);
339 if (val) {
340 if (dga_winlist_add(val, dpy, win) == 0) {
341 XDgaUnGrabWindow(dpy, win);
342 return 0;
345 return val;
346 #else
347 xResourceReq *req;
348 xGenericReply rep;
349 struct dga_extinfo *extinfop;
351 if ((extinfop = init_dga_ext(dpy)) == NULL)
352 return 0;
353 LockDisplay(dpy);
354 GetResReq(DGA, win, req);
355 req->reqType = extinfop->major_opcode;
356 req->pad = (extinfop->protocol_major_version >= 2) ?
357 X_DgaGrabWindow : X_DgaGrabWindow_Old ;
358 if (!_XReply(dpy, (xReply *) &rep, 0, xTrue)) {
359 UnlockDisplay(dpy);
360 SyncHandle();
361 return 0;
363 UnlockDisplay(dpy);
364 SyncHandle();
365 if (rep.data00) {
366 if (dga_winlist_add(rep.data00, dpy, win) == 0) {
367 XDgaUnGrabWindow(dpy, win);
368 return 0;
371 return rep.data00;
372 #endif /* SERVER_DGA */
376 XDgaUnGrabWindow(dpy, win)
377 Display *dpy;
378 Window win;
380 #ifdef SERVER_DGA
381 WindowPtr pWin = (WindowPtr)LookupIDByType(win, RT_WINDOW);
382 int val;
384 if (!pWin)
385 return (BadCookie);
386 if (((DrawablePtr)pWin)->type == DRAWABLE_PIXMAP)
387 return (BadCookie);
388 val = DgaWgUngrab(pWin, NEW);
390 if (val) {
391 if (dga_winlist_free(dpy, win) == 0)
392 return 0;
394 return val;
395 #else
396 xResourceReq *req;
397 xGenericReply rep;
398 struct dga_extinfo *extinfop;
400 if ((extinfop = lookup_dga_ext(dpy)) == NULL)
401 return 0;
402 LockDisplay(dpy);
403 GetResReq(DGA, win, req);
404 req->reqType = extinfop->major_opcode;
405 req->pad = (extinfop->protocol_major_version >= 2) ?
406 X_DgaUnGrabWindow : X_DgaUnGrabWindow_Old;
407 if (!_XReply(dpy, (xReply *) &rep, 0, xTrue)) {
408 UnlockDisplay(dpy);
409 SyncHandle();
410 return 0;
412 UnlockDisplay(dpy);
413 SyncHandle();
414 if (rep.data00) {
415 if (dga_winlist_free(dpy, win) == 0)
416 return 0;
418 return rep.data00; /* Status */
419 #endif /* SERVER_DGA */
423 #ifndef SERVER_DGA
424 Dga_token
425 XDgaGrabColormap(dpy, cmap)
426 Display *dpy;
427 Colormap cmap;
429 xResourceReq *req;
430 xGenericReply rep;
431 struct dga_extinfo *extinfop;
433 #ifdef MT
434 mutex_lock(&dgaGlobalMutex);
435 #endif
436 if ((extinfop = init_dga_ext(dpy)) == NULL) {
437 #ifdef MT
438 mutex_unlock(&dgaGlobalMutex);
439 #endif
440 return 0;
442 LockDisplay(dpy);
443 GetResReq(DGA, cmap, req);
444 req->reqType = extinfop->major_opcode;
445 req->pad = (extinfop->protocol_major_version >= 3) ?
446 X_DgaGrabColormap : X_DgaGrabColormap_Old;
447 if (!_XReply(dpy, (xReply *) &rep, 0, xTrue)) {
448 UnlockDisplay(dpy);
449 SyncHandle();
450 #ifdef MT
451 mutex_unlock(&dgaGlobalMutex);
452 #endif
453 return 0;
455 UnlockDisplay(dpy);
456 SyncHandle();
457 #ifdef MT
458 mutex_unlock(&dgaGlobalMutex);
459 #endif
460 return rep.data00;
464 XDgaUnGrabColormap(dpy, cmap)
465 Display *dpy;
466 Colormap cmap;
468 xResourceReq *req;
469 xGenericReply rep;
470 struct dga_extinfo *extinfop;
472 #ifdef MT
473 mutex_lock(&dgaGlobalMutex);
474 #endif
475 if ((extinfop = lookup_dga_ext(dpy)) == NULL) {
476 #ifdef MT
477 mutex_unlock(&dgaGlobalMutex);
478 #endif
479 return 0;
481 LockDisplay(dpy);
482 GetResReq(DGA, cmap, req);
483 req->reqType = extinfop->major_opcode;
484 req->pad = (extinfop->protocol_major_version >= 3) ?
485 X_DgaUnGrabColormap : X_DgaUnGrabColormap_Old;
486 if (!_XReply(dpy, (xReply *) &rep, 0, xTrue)) {
487 UnlockDisplay(dpy);
488 SyncHandle();
489 #ifdef MT
490 mutex_unlock(&dgaGlobalMutex);
491 #endif
492 return 0;
494 UnlockDisplay(dpy);
495 SyncHandle();
496 #ifdef MT
497 mutex_unlock(&dgaGlobalMutex);
498 #endif
499 return rep.data00; /* Status */
501 #endif /* SERVER_DGA */
503 int
504 XDgaDrawGrabWids(dpy, drawid, nwids)
505 Display *dpy;
506 Drawable drawid;
507 int nwids;
509 #ifdef SERVER_DGA
510 WindowPtr pWin = (WindowPtr)LookupIDByType(drawid, RT_WINDOW);
512 if (!pWin)
513 return (BadCookie);
514 if (((DrawablePtr)pWin)->type == DRAWABLE_PIXMAP)
515 return (BadCookie);
516 return(DgaWidGrab(pWin, nwids));
517 #else
518 xDGAReq *req;
519 xGenericReply rep;
520 struct dga_extinfo *extinfop;
522 #ifdef MT
523 mutex_lock(&dgaGlobalMutex);
524 #endif
525 if (((extinfop = lookup_dga_ext(dpy)) == NULL) ||
526 (extinfop->protocol_major_version < 2)) {
527 #ifdef MT
528 mutex_unlock(&dgaGlobalMutex);
529 #endif
530 return 0;
532 LockDisplay(dpy);
533 GetReq(DGA, req);
534 req->reqType = extinfop->major_opcode;
535 req->pad = X_DgaGrabWids;
536 req->id = drawid;
537 req->number_objects = nwids;
538 if (!_XReply(dpy, (xReply *) &rep, 0, xTrue)) {
539 UnlockDisplay(dpy);
540 SyncHandle();
541 #ifdef MT
542 mutex_unlock(&dgaGlobalMutex);
543 #endif
544 return 0;
546 UnlockDisplay(dpy);
547 SyncHandle();
548 #ifdef MT
549 mutex_unlock(&dgaGlobalMutex);
550 #endif
551 return rep.data00;
552 #endif /* SERVER_DGA */
555 int
556 XDgaGrabWids(dpy, win, nwids)
557 Display *dpy;
558 Window win;
559 int nwids;
561 return (XDgaDrawGrabWids(dpy, (Drawable)win, nwids));
564 int
565 XDgaDrawGrabFCS(dpy, drawid, nfcs)
566 Display *dpy;
567 Drawable drawid;
568 int nfcs;
570 #ifdef SERVER_DGA
571 WindowPtr pWin = (WindowPtr)LookupIDByType(drawid, RT_WINDOW);
573 if (!pWin)
574 return (BadCookie);
575 if (((DrawablePtr)pWin)->type == DRAWABLE_PIXMAP)
576 return (BadCookie);
577 /* When OWGX supports PIXMAPS, can be reomoved */
578 return(DgaFcsGrab(pWin, nfcs));
579 #else
580 xDGAReq *req;
581 xGenericReply rep;
582 struct dga_extinfo *extinfop;
584 #ifdef MT
585 mutex_lock(&dgaGlobalMutex);
586 #endif
587 if (((extinfop = lookup_dga_ext(dpy)) == NULL) ||
588 (extinfop->protocol_major_version < 2)) {
589 #ifdef MT
590 mutex_unlock(&dgaGlobalMutex);
591 #endif
592 return 0;
594 LockDisplay(dpy);
595 GetReq(DGA, req);
596 req->reqType = extinfop->major_opcode;
597 req->pad = X_DgaGrabFCS;
598 req->id = drawid;
599 req->number_objects = nfcs;
600 if (!_XReply(dpy, (xReply *) &rep, 0, xTrue)) {
601 UnlockDisplay(dpy);
602 SyncHandle();
603 #ifdef MT
604 mutex_unlock(&dgaGlobalMutex);
605 #endif
606 return 0;
608 UnlockDisplay(dpy);
609 SyncHandle();
610 #ifdef MT
611 mutex_unlock(&dgaGlobalMutex);
612 #endif
613 return(rep.data00);
614 #endif /* SERVER_DGA */
617 int
618 XDgaGrabFCS(dpy, win, nfcs)
619 Display *dpy;
620 Window win;
621 int nfcs;
623 return (XDgaDrawGrabFCS(dpy, (Drawable)win, nfcs));
626 int
627 XDgaDrawGrabZbuf(dpy, drawid, nzbuftype)
628 Display *dpy;
629 Drawable drawid;
630 int nzbuftype;
632 #ifdef SERVER_DGA
633 WindowPtr pWin = (WindowPtr)LookupIDByType(drawid, RT_WINDOW);
635 if (!pWin)
636 return (BadCookie);
637 if (((DrawablePtr)pWin)->type == DRAWABLE_PIXMAP)
638 return (BadCookie);
639 return(DgaZbufGrab(pWin, nzbuftype));
640 #else
641 xDGAReq *req;
642 xGenericReply rep;
643 struct dga_extinfo *extinfop;
645 #ifdef MT
646 mutex_lock(&dgaGlobalMutex);
647 #endif
648 if (((extinfop = lookup_dga_ext(dpy)) == NULL) ||
649 (extinfop->protocol_major_version < 2)) {
650 #ifdef MT
651 mutex_unlock(&dgaGlobalMutex);
652 #endif
653 return 0;
655 LockDisplay(dpy);
656 GetReq(DGA, req);
657 req->reqType = extinfop->major_opcode;
658 req->pad = X_DgaGrabZbuf;
659 req->id = drawid;
660 req->number_objects = nzbuftype;
661 if (!_XReply(dpy, (xReply *) &rep, 0, xTrue)) {
662 UnlockDisplay(dpy);
663 SyncHandle();
664 #ifdef MT
665 mutex_unlock(&dgaGlobalMutex);
666 #endif
667 return 0;
669 UnlockDisplay(dpy);
670 SyncHandle();
671 #ifdef MT
672 mutex_unlock(&dgaGlobalMutex);
673 #endif
674 return(rep.data00);
675 #endif /* SERVER_DGA */
678 int
679 XDgaGrabZbuf(dpy, win, nzbuftype)
680 Display *dpy;
681 Window win;
682 int nzbuftype;
684 return (XDgaDrawGrabZbuf(dpy, (Drawable)win, nzbuftype));
687 int
688 XDgaDrawGrabStereo(dpy, drawid, st_mode)
689 Display *dpy;
690 Drawable drawid;
691 int st_mode;
693 #ifdef SERVER_DGA
694 WindowPtr pWin = (WindowPtr)LookupIDByType(drawid, RT_WINDOW);
696 if (!pWin)
697 return (BadCookie);
698 if (((DrawablePtr)pWin)->type == DRAWABLE_PIXMAP)
699 return (BadCookie);
700 return(DgaStereoGrab(pWin, st_mode));
701 #else
702 xDGAReq *req;
703 xGenericReply rep;
704 struct dga_extinfo *extinfop;
706 #ifdef MT
707 mutex_lock(&dgaGlobalMutex);
708 #endif
709 if (((extinfop = lookup_dga_ext(dpy)) == NULL) ||
710 (extinfop->protocol_major_version < 2)) {
711 #ifdef MT
712 mutex_unlock(&dgaGlobalMutex);
713 #endif
714 return 0;
716 LockDisplay(dpy);
717 GetReq(DGA, req);
718 req->reqType = extinfop->major_opcode;
719 req->pad = X_DgaGrabStereo;
720 req->id = drawid;
721 req->number_objects = st_mode;
722 if (!_XReply(dpy, (xReply *) &rep, 0, xTrue)) {
723 UnlockDisplay(dpy);
724 SyncHandle();
725 #ifdef MT
726 mutex_unlock(&dgaGlobalMutex);
727 #endif
728 return 0;
730 UnlockDisplay(dpy);
731 SyncHandle();
732 #ifdef MT
733 mutex_unlock(&dgaGlobalMutex);
734 #endif
735 return rep.data00;
736 #endif /* SERVER_DGA */
739 int
740 XDgaGrabStereo(dpy, win, st_mode)
741 Display *dpy;
742 Window win;
743 int st_mode;
745 return (XDgaDrawGrabStereo(dpy, (Drawable)win, st_mode));
749 XDgaGrabABuffers(dpy, win, type, buffer_site)
750 Display *dpy;
751 Window win;
752 int type;
753 int buffer_site;
755 #ifdef SERVER_DGA
756 WindowPtr pWin = (WindowPtr)LookupIDByType(win, RT_WINDOW);
758 if (!pWin)
759 return (BadCookie);
760 if (((DrawablePtr)pWin)->type == DRAWABLE_PIXMAP)
761 return (BadCookie);
762 /* Some surf prep may be needed for mpg */
763 return(DgaABuffersGrabInfo((DrawablePtr)pWin, type, buffer_site));
764 #else
765 xDgaGrabABuffersReq *req;
766 xGenericReply rep;
767 struct dga_extinfo *extinfop;
769 if ((extinfop = lookup_dga_ext(dpy)) == NULL)
770 return 0;
771 if (extinfop->protocol_major_version < 2)
772 return 0;
773 LockDisplay(dpy);
774 GetReq(DgaGrabABuffers, req);
775 req->reqType = extinfop->major_opcode;
776 req->pad = X_DgaGrabABuffers;
777 req->id = win;
778 req->type = type;
779 req->buffer_site = buffer_site;
780 if (!_XReply(dpy, (xReply *) &rep, 0, xTrue)) {
781 UnlockDisplay(dpy);
782 SyncHandle();
783 return 0;
785 UnlockDisplay(dpy);
786 SyncHandle();
787 return rep.data00;
788 #endif /* SERVER_DGA */
792 XDgaUnGrabABuffers(dpy, win, type)
793 Display *dpy;
794 Window win;
795 int type;
797 #ifdef SERVER_DGA
798 WindowPtr pWin = (WindowPtr)LookupIDByType(win, RT_WINDOW);
800 if (!pWin)
801 return (BadCookie);
802 if (((DrawablePtr)pWin)->type == DRAWABLE_PIXMAP)
803 return (BadCookie);
804 return(DgaABuffersUngrabInfo((DrawablePtr)pWin, type));
805 #else
806 xDgaGrabABuffersReq *req;
807 xGenericReply rep;
808 struct dga_extinfo *extinfop;
810 if ((extinfop = lookup_dga_ext(dpy)) == NULL)
811 return 0;
812 if (extinfop->protocol_major_version < 2)
813 return 0;
814 LockDisplay(dpy);
815 GetReq(DgaGrabABuffers, req);
816 req->reqType = extinfop->major_opcode;
817 req->pad = X_DgaUnGrabABuffers;
818 req->id = win;
819 req->type = type;
820 req->buffer_site = 0;
821 if (!_XReply(dpy, (xReply *) &rep, 0, xTrue)) {
822 UnlockDisplay(dpy);
823 SyncHandle();
824 return 0;
826 UnlockDisplay(dpy);
827 SyncHandle();
828 return rep.data00;
829 #endif /* SERVER_DGA */
832 int
833 XDgaGrabBuffers(dpy, win, nbuffers)
834 Display *dpy;
835 Window win;
836 int nbuffers;
838 #ifdef SERVER_DGA
839 WindowPtr pWin = (WindowPtr)LookupIDByType(win, RT_WINDOW);
841 if (!pWin)
842 return (BadCookie);
843 if (((DrawablePtr)pWin)->type == DRAWABLE_PIXMAP)
844 return (BadCookie);
845 /* Some surf prep may be needed for mpg */
846 return(DgaBufGrab(pWin, nbuffers));
847 #else
848 xDGAReq *req;
849 xGenericReply rep;
850 struct dga_extinfo *extinfop;
852 if ((extinfop = lookup_dga_ext(dpy)) == NULL)
853 return 0;
854 if (extinfop->protocol_major_version < 2)
855 return 0;
856 LockDisplay(dpy);
857 GetReq(DGA, req);
858 req->reqType = extinfop->major_opcode;
859 req->pad = X_DgaGrabBuffers;
860 req->id = win;
861 req->number_objects = nbuffers;
862 if (!_XReply(dpy, (xReply *) &rep, 0, xTrue)) {
863 UnlockDisplay(dpy);
864 SyncHandle();
865 return 0;
867 UnlockDisplay(dpy);
868 SyncHandle();
869 return rep.data00;
870 #endif /* SERVER_DGA */
875 XDgaUnGrabBuffers(dpy, win)
876 Display *dpy;
877 Window win;
879 #ifdef SERVER_DGA
880 WindowPtr pWin = (WindowPtr)LookupIDByType(win, RT_WINDOW);
882 if (!pWin)
883 return (BadCookie);
884 if (((DrawablePtr)pWin)->type == DRAWABLE_PIXMAP)
885 return (BadCookie);
886 return(DgaBufUngrab(pWin));
887 #else
888 xResourceReq *req;
889 xGenericReply rep;
890 struct dga_extinfo *extinfop;
892 if ((extinfop = lookup_dga_ext(dpy)) == NULL)
893 return 0;
894 if (extinfop->protocol_major_version < 2)
895 return 0;
896 LockDisplay(dpy);
897 GetResReq(DGA, win, req);
898 req->reqType = extinfop->major_opcode;
899 req->pad = X_DgaUnGrabBuffers;
900 if (!_XReply(dpy, (xReply *) &rep, 0, xTrue)) {
901 UnlockDisplay(dpy);
902 SyncHandle();
903 return 0;
905 UnlockDisplay(dpy);
906 SyncHandle();
907 return rep.data00;
908 #endif /* SERVER_DGA */
912 int
913 XDgaGrabRetainedWindow(dpy, win)
914 Display *dpy;
915 Window win;
917 #ifdef SERVER_DGA
918 WindowPtr pWin = (WindowPtr)LookupIDByType(win, RT_WINDOW);
920 if (!pWin)
921 return (BadCookie);
922 if (((DrawablePtr)pWin)->type == DRAWABLE_PIXMAP)
923 return (BadCookie);
924 return(DgaSharedRetained(pWin, 1, win));
925 #else
926 xResourceReq *req;
927 xGenericReply rep;
928 struct dga_extinfo *extinfop;
930 if ((extinfop = lookup_dga_ext(dpy)) == NULL)
931 return 0;
932 if (extinfop->protocol_major_version < 3)
933 return 0;
934 LockDisplay(dpy);
935 GetResReq(DGA, win, req);
936 req->reqType = extinfop->major_opcode;
937 req->pad = X_DgaGrabRetained;
938 if (!_XReply(dpy, (xReply *) &rep, 0, xTrue)) {
939 UnlockDisplay(dpy);
940 SyncHandle();
941 return 0;
943 UnlockDisplay(dpy);
944 SyncHandle();
945 return rep.data00;
946 #endif /* SERVER_DGA */
951 XDgaUnGrabRetainedWindow(dpy, win)
952 Display *dpy;
953 Window win;
955 #ifdef SERVER_DGA
956 WindowPtr pWin = (WindowPtr)LookupIDByType(win, RT_WINDOW);
958 if (!pWin)
959 return (BadCookie);
960 if (((DrawablePtr)pWin)->type == DRAWABLE_PIXMAP)
961 return (BadCookie);
962 return(DgaSharedRetained(pWin, 0, win));
963 #else
964 xResourceReq *req;
965 xGenericReply rep;
966 struct dga_extinfo *extinfop;
968 if ((extinfop = lookup_dga_ext(dpy)) == NULL)
969 return 0;
970 if (extinfop->protocol_major_version < 3)
971 return 0;
972 LockDisplay(dpy);
973 GetResReq(DGA, win, req);
974 req->reqType = extinfop->major_opcode;
975 req->pad = X_DgaUnGrabRetained;
976 if (!_XReply(dpy, (xReply *) &rep, 0, xTrue)) {
977 UnlockDisplay(dpy);
978 SyncHandle();
979 return 0;
981 UnlockDisplay(dpy);
982 SyncHandle();
983 return rep.data00; /* Status */
984 #endif /* SERVER_DGA */
989 XDgaGetRetainedPath(dpy, win, path)
990 Display *dpy;
991 Window win;
992 char *path;
994 #ifdef SERVER_DGA
995 extern char *DgaSharedRetainedPath;
997 if (DgaSharedRetainedPath)
998 strcpy((char *)path, (char *)DgaSharedRetainedPath);
999 return 1;
1000 #else
1001 xResourceReq *req;
1002 xDGARtndPathReply rep;
1003 struct dga_extinfo *extinfop;
1005 if ((extinfop = lookup_dga_ext(dpy)) == NULL)
1006 return 0;
1007 if (extinfop->protocol_major_version < 3)
1008 return 0;
1009 LockDisplay(dpy);
1010 GetResReq(DGA, win, req);
1011 req->reqType = extinfop->major_opcode;
1012 req->pad = X_DgaGetRetainedPath;
1013 if (!_XReply(dpy, (xReply *) &rep,
1014 (SIZEOF(xDGARtndPathReply) - SIZEOF(xReply)) >> 2, xFalse)) {
1015 UnlockDisplay(dpy);
1016 SyncHandle();
1017 return 0;
1019 UnlockDisplay(dpy);
1020 SyncHandle();
1021 strcpy(path, (char *) rep.path);
1022 return 1;
1023 #endif /* SERVER_DGA */
1028 XDgaQueryVersion(dpy, major_versionp, minor_versionp)
1029 Display *dpy;
1030 int *major_versionp,
1031 *minor_versionp;
1033 #ifdef SERVER_DGA
1034 *major_versionp = SUN_DGA_MAJOR_VERSION;
1035 *minor_versionp = SUN_DGA_MINOR_VERSION;
1036 return(1);
1037 #else
1038 xDgaQueryVersionReply rep;
1039 xDgaQueryVersionReq *req;
1040 int opcode, tmp;
1042 if (XQueryExtension(dpy, "SUN_DGA", &opcode, &tmp, &tmp) == 0)
1043 return 0;
1045 LockDisplay(dpy);
1046 GetReq(DgaQueryVersion, req);
1047 req->reqType = opcode;
1048 req->dgaReqType = X_DgaQueryVersion;
1049 if (!_XReply(dpy, (xReply *) & rep, 0, xTrue)) {
1050 UnlockDisplay(dpy);
1051 SyncHandle();
1052 return 0;
1054 *major_versionp = rep.majorVersion;
1055 *minor_versionp = rep.minorVersion;
1056 UnlockDisplay(dpy);
1057 SyncHandle();
1058 return 1;
1059 #endif /* SERVER_DGA */
1063 Dga_token
1064 XDgaGrabPixmap(dpy, d)
1065 Display *dpy;
1066 Pixmap d;
1068 #ifdef SERVER_DGA
1069 int val;
1070 PixmapPtr pPix = (PixmapPtr)LookupIDByType(d, RT_PIXMAP);
1071 if (!pPix)
1072 return (BadCookie);
1074 if (((DrawablePtr)pPix)->type == DRAWABLE_WINDOW)
1075 return (BadCookie);
1076 val = DgaInitSharedPixmap(pPix, NEW);
1078 if (val) {
1079 if (dga_pixlist_add(val, dpy, d) == 0) {
1080 XDgaUnGrabPixmap(dpy, d);
1081 return 0;
1084 return val;
1085 #else
1086 xResourceReq *req;
1087 xGenericReply rep;
1088 struct dga_extinfo *extinfop;
1090 if ((extinfop = init_dga_ext(dpy)) == NULL)
1091 return 0;
1092 if (extinfop->protocol_major_version < 3)
1093 return 0;
1094 LockDisplay(dpy);
1095 GetResReq(DGA, d, req);
1096 req->reqType = extinfop->major_opcode;
1097 req->pad = X_DgaGrabPixmap;
1098 if (!_XReply(dpy, (xReply *) &rep, 0, xTrue)) {
1099 UnlockDisplay(dpy);
1100 SyncHandle();
1101 return 0;
1103 UnlockDisplay(dpy);
1104 SyncHandle();
1105 if (rep.data00) {
1106 if (dga_pixlist_add(rep.data00, dpy, d) == 0) {
1107 XDgaUnGrabPixmap(dpy, d);
1108 return 0;
1111 return rep.data00;
1112 #endif /* SERVER_DGA */
1117 XDgaUnGrabPixmap(dpy, d)
1118 Display *dpy;
1119 Pixmap d;
1121 #ifdef SERVER_DGA
1122 PixmapPtr pPix = (PixmapPtr)LookupIDByType(d, RT_PIXMAP);
1123 int val;
1125 if (!pPix)
1126 return (BadCookie);
1127 if (((DrawablePtr)pPix)->type == DRAWABLE_WINDOW)
1128 return (BadCookie);
1129 val = DgaDestroySharedPixmap(pPix);
1131 if (val) {
1132 if (dga_pixlist_free(dpy, d) == 0)
1133 return 0;
1135 return val;
1136 #else
1137 xResourceReq *req;
1138 xGenericReply rep;
1139 struct dga_extinfo *extinfop;
1141 if ((extinfop = lookup_dga_ext(dpy)) == NULL)
1142 return 0;
1143 if (extinfop->protocol_major_version < 3)
1144 return 0;
1145 LockDisplay(dpy);
1146 GetResReq(DGA, d, req);
1147 req->reqType = extinfop->major_opcode;
1148 req->pad = X_DgaUnGrabPixmap;
1149 if (!_XReply(dpy, (xReply *) &rep, 0, xTrue)) {
1150 UnlockDisplay(dpy);
1151 SyncHandle();
1152 return 0;
1154 UnlockDisplay(dpy);
1155 SyncHandle();
1156 return rep.data00; /* Status */
1157 #endif /* SERVER_DGA */
1161 static Dga_token
1162 dgai_grabDrawRequest (Display *dpy, Drawable drawid, int *drawType)
1164 #ifdef SERVER_DGA
1165 DrawablePtr pDraw = (DrawablePtr)LookupIDByClass(drawid, RC_DRAWABLE);
1167 if (!pDraw)
1168 return(BadCookie);
1169 return(DgaDrawGrab(drawid, pDraw, NEW, drawType));
1170 #else
1171 xResourceReq *req;
1172 xGenericReply rep;
1173 struct dga_extinfo *extinfop;
1175 if ((extinfop = init_dga_ext(dpy)) == NULL)
1176 return 0;
1177 if (extinfop->protocol_major_version < 3)
1178 return 0;
1179 LockDisplay(dpy);
1180 GetResReq(DGA, drawid, req);
1181 req->reqType = extinfop->major_opcode;
1182 req->pad = X_DgaGrabDrawable;
1183 if (!_XReply(dpy, (xReply *) &rep, 0, xTrue)) {
1184 UnlockDisplay(dpy);
1185 SyncHandle();
1186 return 0;
1188 UnlockDisplay(dpy);
1189 SyncHandle();
1192 ** data00 is the opaque token identifying the drawable shared file.
1193 ** data01 is the type of the drawable: window (0) or pixmap (1),
1194 ** (Note: an attempt to grab a multibuffer drawable XID will fail)
1196 if (rep.data00) {
1197 *drawType = rep.data01;
1200 return (rep.data00);
1201 #endif /* SERVER_DGA */
1204 static int
1205 dgai_ungrabDrawRequest (Display *dpy, Drawable drawid)
1207 #ifdef SERVER_DGA
1208 DrawablePtr pDraw = (DrawablePtr)LookupIDByClass(drawid, RC_DRAWABLE);
1210 if (!pDraw)
1211 return(BadCookie);
1212 return(DgaDrawUngrab(drawid, pDraw, NEW));
1213 #else
1214 xResourceReq *req;
1215 xGenericReply rep;
1216 struct dga_extinfo *extinfop;
1218 if ((extinfop = lookup_dga_ext(dpy)) == NULL)
1219 return 0;
1220 if (extinfop->protocol_major_version < 3)
1221 return 0;
1222 LockDisplay(dpy);
1223 GetResReq(DGA, drawid, req);
1224 req->reqType = extinfop->major_opcode;
1225 req->pad = X_DgaUnGrabDrawable;
1226 if (!_XReply(dpy, (xReply *) &rep, 0, xTrue)) {
1227 UnlockDisplay(dpy);
1228 SyncHandle();
1229 return 0;
1231 UnlockDisplay(dpy);
1232 SyncHandle();
1233 return rep.data00; /* Status */
1234 #endif /* SERVER_DGA */
1238 Dga_drawable
1239 XDgaGrabDrawable(Display *dpy, Drawable drawid)
1241 Dga_token token;
1242 int drawType;
1244 #ifdef MT
1245 mutex_lock(&dgaGlobalMutex);
1246 #endif
1247 if (!(token = dgai_grabDrawRequest(dpy, drawid, &drawType))) {
1248 #ifdef MT
1249 mutex_unlock(&dgaGlobalMutex);
1250 #endif
1251 return (NULL);
1254 switch (drawType) {
1256 case DGA_PROTO_OVERLAY:
1257 case DGA_PROTO_WINDOW: {
1258 _Dga_window dgawin;
1260 if (!dga_winlist_add(token, dpy, (Window)drawid)) {
1261 goto Bad;
1263 if (!(dgawin = (_Dga_window) dgai_win_grab_common(dpy, -1, token, 1))) { goto Bad;
1265 dgawin->w_dpy = dpy;
1266 dgawin->w_id = (Window) drawid;
1267 if (dgawin->isOverlay = (drawType == DGA_PROTO_OVERLAY)) {
1268 dgawin->s_ovlstate_p = &((WXINFO *)dgawin->w_info)->w_ovlstate;
1269 dgawin->s_ovlshapevalid_p =
1270 &((WXINFO *)dgawin->w_info)->w_ovlshapevalid;
1271 dgawin->ovlStateNotifyFunc = NULL;
1273 #ifdef MT
1274 mutex_unlock(&dgaGlobalMutex);
1275 #endif
1276 return ((Dga_drawable)dgawin);
1279 case DGA_PROTO_PIXMAP: {
1280 _Dga_pixmap dgapix;
1282 if (!dga_pixlist_add(token, dpy, (Pixmap)drawid)) {
1283 goto Bad;
1285 if (!(dgapix = (_Dga_pixmap) dga_pix_grab(token, (Pixmap)drawid))) {
1286 goto Bad;
1288 dgapix->p_dpy = dpy;
1289 dgapix->p_id = (Pixmap) drawid;
1290 #ifdef MT
1291 mutex_unlock(&dgaGlobalMutex);
1292 #endif
1293 return ((Dga_drawable)dgapix);
1298 Bad:
1299 (void) dgai_ungrabDrawRequest(dpy, drawid);
1300 #ifdef MT
1301 mutex_unlock(&dgaGlobalMutex);
1302 #endif
1303 return (NULL);
1309 XDgaUnGrabDrawable(Dga_drawable dgadraw)
1311 Drawable drawid = dga_draw_id(dgadraw);
1312 Display *dpy = dga_draw_display(dgadraw);
1313 int type = dga_draw_type(dgadraw);
1314 int status;
1316 if (dpy == NULL)
1317 return BadDrawable;
1319 #ifdef MT
1320 mutex_lock(&dgaGlobalMutex);
1321 #endif
1322 switch (type) {
1323 case DGA_DRAW_WINDOW:
1324 case DGA_DRAW_OVERLAY:
1325 dgai_win_ungrab_common((Dga_window)dgadraw, -1,1);
1326 break;
1327 case DGA_DRAW_PIXMAP:
1328 dga_pix_ungrab((Dga_pixmap)dgadraw);
1329 break;
1332 status = dgai_ungrabDrawRequest(dpy, drawid);
1333 #ifdef MT
1334 mutex_unlock(&dgaGlobalMutex);
1335 #endif
1336 return (status);
1341 static struct dga_xwinrec *dga_xwinlist = NULL;
1343 static int
1344 dga_winlist_add(token, dpy, win)
1345 Dga_token token;
1346 Display *dpy;
1347 Window win;
1349 struct dga_xwinrec *recp;
1350 Display *listdpy;
1351 Window listwin;
1353 while (recp =
1354 (struct dga_xwinrec *) _dga_is_X_window(token,&listdpy,&listwin)) {
1355 if ((win == listwin) && (dpy == listdpy)) {
1356 recp->refcnt += 1;
1357 return 1; /* already in list */
1359 dga_winlist_free(listdpy, listwin); /* remove bogus entry from list */
1361 recp = (struct dga_xwinrec *) malloc(sizeof(struct dga_xwinrec));
1362 if (recp == NULL)
1363 return 0;
1364 recp->next = dga_xwinlist;
1365 dga_xwinlist = recp;
1366 recp->token = token;
1367 recp->dpy = dpy;
1368 recp->win = win;
1369 recp->refcnt = 1;
1370 return 1;
1374 * Free dga_xwinrec structure for a particular window and display.
1375 * If win is NULL free all entries on list for this display.
1377 static int
1378 dga_winlist_free(dpy, win)
1379 Display *dpy;
1380 Window win;
1382 struct dga_xwinrec *recp, **prevp;
1383 int match = 0;
1385 prevp = &dga_xwinlist;
1386 recp = dga_xwinlist;
1387 while (recp) {
1388 if (recp->dpy == dpy) {
1389 if (win == NULL) {
1390 *prevp = recp->next;
1391 free(recp);
1392 match = 1;
1394 else if (recp->win == win) {
1395 if (--recp->refcnt == 0) {
1396 *prevp = recp->next;
1397 free(recp);
1399 return 1;
1401 else {
1402 prevp = &recp->next;
1405 else {
1406 prevp = &recp->next;
1408 recp = *prevp;
1410 return (match);
1414 void *
1415 _dga_is_X_window(token, dpyp, winp)
1416 Dga_token token;
1417 Display **dpyp;
1418 Window *winp;
1420 struct dga_xwinrec *recp = dga_xwinlist;
1422 while (recp) {
1423 if (recp->token == token) {
1424 *dpyp = recp->dpy;
1425 *winp = recp->win;
1426 return ((void *) recp);
1428 recp = recp->next;
1430 return 0;
1433 static struct dga_xpixrec *dga_xpixlist = NULL;
1435 /* REMIND DARYL: This routine is used to clean up "bogus" entries from
1436 * list. Shouldn't that be done in Ungrab??? */
1438 dga_pixlist_add(token, dpy, pix)
1439 Dga_token token;
1440 Display *dpy;
1441 Pixmap pix;
1443 struct dga_xpixrec *recp;
1444 Display *listdpy;
1446 if (recp = (struct dga_xpixrec *) _dga_is_X_pixmap(pix, &listdpy)) {
1447 if (dpy == listdpy) {
1448 recp->refcnt += 1;
1449 return 1; /* already in list */
1451 dga_pixlist_free(dpy, pix); /* remove bogus entry from list */
1453 recp = (struct dga_xpixrec *) malloc(sizeof(struct dga_xpixrec));
1454 if (recp == NULL)
1455 return 0;
1456 recp->next = dga_xpixlist;
1457 dga_xpixlist = recp;
1458 recp->token = token;
1459 recp->dpy = dpy;
1460 recp->pix = pix;
1461 recp->refcnt = 1;
1462 return 1;
1465 static int
1466 dga_pixlist_free(dpy, pix)
1467 Display *dpy;
1468 Pixmap pix;
1470 struct dga_xpixrec *recp, **prevp;
1471 int match = 0;
1473 prevp = &dga_xpixlist;
1474 recp = dga_xpixlist;
1475 while (recp) {
1476 if (recp->dpy == dpy) {
1477 if (pix == NULL) {
1478 *prevp = recp->next;
1479 free(recp);
1480 match = 1;
1482 else if (recp->pix == pix) {
1483 if (--recp->refcnt == 0) {
1484 *prevp = recp->next;
1485 free(recp);
1487 return 1;
1489 else {
1490 prevp = &recp->next;
1493 else {
1494 prevp = &recp->next;
1496 recp = *prevp;
1498 return (match);
1502 void *
1503 _dga_is_X_pixmap(pix, dpyp)
1504 Pixmap pix;
1505 Display **dpyp;
1507 struct dga_xpixrec *recp = dga_xpixlist;
1509 while (recp) {
1510 if (recp->pix == pix) {
1511 *dpyp = recp->dpy;
1512 return ((void *) recp);
1514 recp = recp->next;
1516 return 0;
1519 #ifndef SERVER_DGA
1521 /************************************
1523 Addition to DGA for Xinerama extension.
1525 This code allows the client to mine out
1526 the window ID's that would normaly be
1527 hidden from the user in Xinerama mode.
1529 Xinerama keeps a list of WIDs that are
1530 connected to a virtual WID that the user
1531 gets to handle.
1533 **************************************/
1536 BOOL
1537 XDgaGetXineramaInfo(dpy , VirtualWID, info )
1538 Display *dpy;
1539 XID VirtualWID;
1540 XineramaInfo *info;
1542 register xDgaXineramaInfoReq *req;
1543 xDgaXineramaInfoReply *rep;
1544 struct dga_extinfo *extinfop;
1546 if ((extinfop = init_dga_ext(dpy)) == NULL)
1547 return 0;
1549 rep = malloc(sizeof(xDgaXineramaInfoReply));
1551 LockDisplay(dpy);
1552 GetReq(DgaXineramaInfo, req);
1553 req->reqType = extinfop->major_opcode;
1554 req->xdgaReqType = X_DgaXineramaInfo;
1555 req->visual = VirtualWID;
1557 if (!_XReply(dpy, (xReply *)rep, (sizeof(xDgaXineramaInfoReply)-32) >> 2,
1558 xFalse))
1560 UnlockDisplay(dpy);
1561 SyncHandle();
1562 Xfree(rep);
1563 return NULL;
1565 info->wid = VirtualWID;
1566 memcpy(&info->subs[0],&rep->subs[0],(MAXSCREEN-1) * sizeof(SubWID));
1567 UnlockDisplay(dpy);
1568 SyncHandle();
1569 free(rep);
1570 return 1;
1572 #endif