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
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.
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 *-----------------------------------------------------------------------
44 #include "dixstruct.h"
46 #include "pixmapstr.h"
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>
58 #include <sys/utsname.h>
60 #endif /* SERVER_DGA */
64 #include "dga_Xrequests.h"
65 #include "dga_incls.h"
67 #include "XineramaInfo.h"
70 #define NEW 1 /* Flag for SHAPES to use new window grabber */
74 #define X_DGA 0 /* a hack, so GetReq and GetResReq work below */
77 #define MIN(i,j) ((i)<(j)?(i):(j))
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();
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 */
103 int _dga_client_version
= -1;
106 dga_init_version(ver
)
110 _dga_client_version
= ver
;
112 dgaThreaded
= (_thr_main() != -1) ? 1 : 0;
114 mutex_init(&dgaGlobalMutex
, USYNC_THREAD
, NULL
);
115 mutex_init(&dgaGlobalPixmapMutex
, USYNC_THREAD
, NULL
);
122 static struct dga_extinfo
*
126 int protmajor
, protminor
;
128 struct dga_extinfo
*infop
;
131 if (_dga_client_version
< 0)
134 if (dga_extinfo_table_size
< (dpy
->fd
+ 1)) {
136 /* We've got to allocate or grow the table */
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))
145 tblptr
= (struct dga_extinfo
**) ((dga_extinfo_table_size
) ?
146 realloc(dga_extinfo_table
, sizeof(struct dga_extinfo
*) *
148 malloc(sizeof(struct dga_extinfo
*) * size
));
151 dga_extinfo_table
= tblptr
;
152 memset((char *) &dga_extinfo_table
[dga_extinfo_table_size
],
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
))
165 if ((xecp
= XInitExtension(dpy
, "SUN_DGA")) != NULL
) {
166 if (XDgaQueryVersion(dpy
, &protmajor
, &protminor
) == 0) {
168 /* protminor = 0; let minor number pass through */
174 if ((infop
= (struct dga_extinfo
*)
175 malloc(sizeof(struct dga_extinfo
))) == NULL
)
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
);
193 unsigned int namelen
;
194 size_t hostlen
, phostlen
;
196 struct addrinfo
*localhostaddr
;
197 struct addrinfo
*otherhostaddr
;
198 struct addrinfo
*i
, *j
;
200 char host
[NI_MAXHOST
];
202 struct hostent
*phost
;
206 struct sockaddr generic
;
207 struct sockaddr_in internet
;
209 struct sockaddr_in6 internetv6
;
210 struct sockaddr_storage maximumsize
;
212 struct sockaddr_un nuxi
;
215 if (dpy
->display_name
[0] == ':')
218 colon
= strrchr(dpy
->display_name
, ':');
220 colon
= rindex(dpy
->display_name
, ':');
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))
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
,
235 hostlen
= _XGetHostname(hostname
, sizeof(hostname
));
238 if (getaddrinfo(hostname
, NULL
, NULL
, &localhostaddr
) != 0)
240 if (getnameinfo(&addr
.generic
, namelen
, host
, sizeof(host
),
242 freeaddrinfo(localhostaddr
);
245 if (getaddrinfo(host
, NULL
, NULL
, &otherhostaddr
) != 0) {
246 freeaddrinfo(localhostaddr
);
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) {
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) {
280 freeaddrinfo(localhostaddr
);
281 freeaddrinfo(otherhostaddr
);
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))
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
)))
302 static struct dga_extinfo
*
306 if (dga_extinfo_table_size
< (dpy
->fd
+ 1))
308 return dga_extinfo_table
[dpy
->fd
];
312 terminate_dga_ext(dpy
, 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? */
322 #endif /* SERVER_DGA */
325 XDgaGrabWindow(dpy
, win
)
331 WindowPtr pWin
= (WindowPtr
)LookupIDByType(win
, RT_WINDOW
);
335 if (((DrawablePtr
)pWin
)->type
== DRAWABLE_PIXMAP
)
337 val
= DgaWgGrab(pWin
, NEW
);
340 if (dga_winlist_add(val
, dpy
, win
) == 0) {
341 XDgaUnGrabWindow(dpy
, win
);
349 struct dga_extinfo
*extinfop
;
351 if ((extinfop
= init_dga_ext(dpy
)) == NULL
)
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
)) {
366 if (dga_winlist_add(rep
.data00
, dpy
, win
) == 0) {
367 XDgaUnGrabWindow(dpy
, win
);
372 #endif /* SERVER_DGA */
376 XDgaUnGrabWindow(dpy
, win
)
381 WindowPtr pWin
= (WindowPtr
)LookupIDByType(win
, RT_WINDOW
);
386 if (((DrawablePtr
)pWin
)->type
== DRAWABLE_PIXMAP
)
388 val
= DgaWgUngrab(pWin
, NEW
);
391 if (dga_winlist_free(dpy
, win
) == 0)
398 struct dga_extinfo
*extinfop
;
400 if ((extinfop
= lookup_dga_ext(dpy
)) == NULL
)
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
)) {
415 if (dga_winlist_free(dpy
, win
) == 0)
418 return rep
.data00
; /* Status */
419 #endif /* SERVER_DGA */
425 XDgaGrabColormap(dpy
, cmap
)
431 struct dga_extinfo
*extinfop
;
434 mutex_lock(&dgaGlobalMutex
);
436 if ((extinfop
= init_dga_ext(dpy
)) == NULL
) {
438 mutex_unlock(&dgaGlobalMutex
);
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
)) {
451 mutex_unlock(&dgaGlobalMutex
);
458 mutex_unlock(&dgaGlobalMutex
);
464 XDgaUnGrabColormap(dpy
, cmap
)
470 struct dga_extinfo
*extinfop
;
473 mutex_lock(&dgaGlobalMutex
);
475 if ((extinfop
= lookup_dga_ext(dpy
)) == NULL
) {
477 mutex_unlock(&dgaGlobalMutex
);
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
)) {
490 mutex_unlock(&dgaGlobalMutex
);
497 mutex_unlock(&dgaGlobalMutex
);
499 return rep
.data00
; /* Status */
501 #endif /* SERVER_DGA */
504 XDgaDrawGrabWids(dpy
, drawid
, nwids
)
510 WindowPtr pWin
= (WindowPtr
)LookupIDByType(drawid
, RT_WINDOW
);
514 if (((DrawablePtr
)pWin
)->type
== DRAWABLE_PIXMAP
)
516 return(DgaWidGrab(pWin
, nwids
));
520 struct dga_extinfo
*extinfop
;
523 mutex_lock(&dgaGlobalMutex
);
525 if (((extinfop
= lookup_dga_ext(dpy
)) == NULL
) ||
526 (extinfop
->protocol_major_version
< 2)) {
528 mutex_unlock(&dgaGlobalMutex
);
534 req
->reqType
= extinfop
->major_opcode
;
535 req
->pad
= X_DgaGrabWids
;
537 req
->number_objects
= nwids
;
538 if (!_XReply(dpy
, (xReply
*) &rep
, 0, xTrue
)) {
542 mutex_unlock(&dgaGlobalMutex
);
549 mutex_unlock(&dgaGlobalMutex
);
552 #endif /* SERVER_DGA */
556 XDgaGrabWids(dpy
, win
, nwids
)
561 return (XDgaDrawGrabWids(dpy
, (Drawable
)win
, nwids
));
565 XDgaDrawGrabFCS(dpy
, drawid
, nfcs
)
571 WindowPtr pWin
= (WindowPtr
)LookupIDByType(drawid
, RT_WINDOW
);
575 if (((DrawablePtr
)pWin
)->type
== DRAWABLE_PIXMAP
)
577 /* When OWGX supports PIXMAPS, can be reomoved */
578 return(DgaFcsGrab(pWin
, nfcs
));
582 struct dga_extinfo
*extinfop
;
585 mutex_lock(&dgaGlobalMutex
);
587 if (((extinfop
= lookup_dga_ext(dpy
)) == NULL
) ||
588 (extinfop
->protocol_major_version
< 2)) {
590 mutex_unlock(&dgaGlobalMutex
);
596 req
->reqType
= extinfop
->major_opcode
;
597 req
->pad
= X_DgaGrabFCS
;
599 req
->number_objects
= nfcs
;
600 if (!_XReply(dpy
, (xReply
*) &rep
, 0, xTrue
)) {
604 mutex_unlock(&dgaGlobalMutex
);
611 mutex_unlock(&dgaGlobalMutex
);
614 #endif /* SERVER_DGA */
618 XDgaGrabFCS(dpy
, win
, nfcs
)
623 return (XDgaDrawGrabFCS(dpy
, (Drawable
)win
, nfcs
));
627 XDgaDrawGrabZbuf(dpy
, drawid
, nzbuftype
)
633 WindowPtr pWin
= (WindowPtr
)LookupIDByType(drawid
, RT_WINDOW
);
637 if (((DrawablePtr
)pWin
)->type
== DRAWABLE_PIXMAP
)
639 return(DgaZbufGrab(pWin
, nzbuftype
));
643 struct dga_extinfo
*extinfop
;
646 mutex_lock(&dgaGlobalMutex
);
648 if (((extinfop
= lookup_dga_ext(dpy
)) == NULL
) ||
649 (extinfop
->protocol_major_version
< 2)) {
651 mutex_unlock(&dgaGlobalMutex
);
657 req
->reqType
= extinfop
->major_opcode
;
658 req
->pad
= X_DgaGrabZbuf
;
660 req
->number_objects
= nzbuftype
;
661 if (!_XReply(dpy
, (xReply
*) &rep
, 0, xTrue
)) {
665 mutex_unlock(&dgaGlobalMutex
);
672 mutex_unlock(&dgaGlobalMutex
);
675 #endif /* SERVER_DGA */
679 XDgaGrabZbuf(dpy
, win
, nzbuftype
)
684 return (XDgaDrawGrabZbuf(dpy
, (Drawable
)win
, nzbuftype
));
688 XDgaDrawGrabStereo(dpy
, drawid
, st_mode
)
694 WindowPtr pWin
= (WindowPtr
)LookupIDByType(drawid
, RT_WINDOW
);
698 if (((DrawablePtr
)pWin
)->type
== DRAWABLE_PIXMAP
)
700 return(DgaStereoGrab(pWin
, st_mode
));
704 struct dga_extinfo
*extinfop
;
707 mutex_lock(&dgaGlobalMutex
);
709 if (((extinfop
= lookup_dga_ext(dpy
)) == NULL
) ||
710 (extinfop
->protocol_major_version
< 2)) {
712 mutex_unlock(&dgaGlobalMutex
);
718 req
->reqType
= extinfop
->major_opcode
;
719 req
->pad
= X_DgaGrabStereo
;
721 req
->number_objects
= st_mode
;
722 if (!_XReply(dpy
, (xReply
*) &rep
, 0, xTrue
)) {
726 mutex_unlock(&dgaGlobalMutex
);
733 mutex_unlock(&dgaGlobalMutex
);
736 #endif /* SERVER_DGA */
740 XDgaGrabStereo(dpy
, win
, st_mode
)
745 return (XDgaDrawGrabStereo(dpy
, (Drawable
)win
, st_mode
));
749 XDgaGrabABuffers(dpy
, win
, type
, buffer_site
)
756 WindowPtr pWin
= (WindowPtr
)LookupIDByType(win
, RT_WINDOW
);
760 if (((DrawablePtr
)pWin
)->type
== DRAWABLE_PIXMAP
)
762 /* Some surf prep may be needed for mpg */
763 return(DgaABuffersGrabInfo((DrawablePtr
)pWin
, type
, buffer_site
));
765 xDgaGrabABuffersReq
*req
;
767 struct dga_extinfo
*extinfop
;
769 if ((extinfop
= lookup_dga_ext(dpy
)) == NULL
)
771 if (extinfop
->protocol_major_version
< 2)
774 GetReq(DgaGrabABuffers
, req
);
775 req
->reqType
= extinfop
->major_opcode
;
776 req
->pad
= X_DgaGrabABuffers
;
779 req
->buffer_site
= buffer_site
;
780 if (!_XReply(dpy
, (xReply
*) &rep
, 0, xTrue
)) {
788 #endif /* SERVER_DGA */
792 XDgaUnGrabABuffers(dpy
, win
, type
)
798 WindowPtr pWin
= (WindowPtr
)LookupIDByType(win
, RT_WINDOW
);
802 if (((DrawablePtr
)pWin
)->type
== DRAWABLE_PIXMAP
)
804 return(DgaABuffersUngrabInfo((DrawablePtr
)pWin
, type
));
806 xDgaGrabABuffersReq
*req
;
808 struct dga_extinfo
*extinfop
;
810 if ((extinfop
= lookup_dga_ext(dpy
)) == NULL
)
812 if (extinfop
->protocol_major_version
< 2)
815 GetReq(DgaGrabABuffers
, req
);
816 req
->reqType
= extinfop
->major_opcode
;
817 req
->pad
= X_DgaUnGrabABuffers
;
820 req
->buffer_site
= 0;
821 if (!_XReply(dpy
, (xReply
*) &rep
, 0, xTrue
)) {
829 #endif /* SERVER_DGA */
833 XDgaGrabBuffers(dpy
, win
, nbuffers
)
839 WindowPtr pWin
= (WindowPtr
)LookupIDByType(win
, RT_WINDOW
);
843 if (((DrawablePtr
)pWin
)->type
== DRAWABLE_PIXMAP
)
845 /* Some surf prep may be needed for mpg */
846 return(DgaBufGrab(pWin
, nbuffers
));
850 struct dga_extinfo
*extinfop
;
852 if ((extinfop
= lookup_dga_ext(dpy
)) == NULL
)
854 if (extinfop
->protocol_major_version
< 2)
858 req
->reqType
= extinfop
->major_opcode
;
859 req
->pad
= X_DgaGrabBuffers
;
861 req
->number_objects
= nbuffers
;
862 if (!_XReply(dpy
, (xReply
*) &rep
, 0, xTrue
)) {
870 #endif /* SERVER_DGA */
875 XDgaUnGrabBuffers(dpy
, win
)
880 WindowPtr pWin
= (WindowPtr
)LookupIDByType(win
, RT_WINDOW
);
884 if (((DrawablePtr
)pWin
)->type
== DRAWABLE_PIXMAP
)
886 return(DgaBufUngrab(pWin
));
890 struct dga_extinfo
*extinfop
;
892 if ((extinfop
= lookup_dga_ext(dpy
)) == NULL
)
894 if (extinfop
->protocol_major_version
< 2)
897 GetResReq(DGA
, win
, req
);
898 req
->reqType
= extinfop
->major_opcode
;
899 req
->pad
= X_DgaUnGrabBuffers
;
900 if (!_XReply(dpy
, (xReply
*) &rep
, 0, xTrue
)) {
908 #endif /* SERVER_DGA */
913 XDgaGrabRetainedWindow(dpy
, win
)
918 WindowPtr pWin
= (WindowPtr
)LookupIDByType(win
, RT_WINDOW
);
922 if (((DrawablePtr
)pWin
)->type
== DRAWABLE_PIXMAP
)
924 return(DgaSharedRetained(pWin
, 1, win
));
928 struct dga_extinfo
*extinfop
;
930 if ((extinfop
= lookup_dga_ext(dpy
)) == NULL
)
932 if (extinfop
->protocol_major_version
< 3)
935 GetResReq(DGA
, win
, req
);
936 req
->reqType
= extinfop
->major_opcode
;
937 req
->pad
= X_DgaGrabRetained
;
938 if (!_XReply(dpy
, (xReply
*) &rep
, 0, xTrue
)) {
946 #endif /* SERVER_DGA */
951 XDgaUnGrabRetainedWindow(dpy
, win
)
956 WindowPtr pWin
= (WindowPtr
)LookupIDByType(win
, RT_WINDOW
);
960 if (((DrawablePtr
)pWin
)->type
== DRAWABLE_PIXMAP
)
962 return(DgaSharedRetained(pWin
, 0, win
));
966 struct dga_extinfo
*extinfop
;
968 if ((extinfop
= lookup_dga_ext(dpy
)) == NULL
)
970 if (extinfop
->protocol_major_version
< 3)
973 GetResReq(DGA
, win
, req
);
974 req
->reqType
= extinfop
->major_opcode
;
975 req
->pad
= X_DgaUnGrabRetained
;
976 if (!_XReply(dpy
, (xReply
*) &rep
, 0, xTrue
)) {
983 return rep
.data00
; /* Status */
984 #endif /* SERVER_DGA */
989 XDgaGetRetainedPath(dpy
, win
, path
)
995 extern char *DgaSharedRetainedPath
;
997 if (DgaSharedRetainedPath
)
998 strcpy((char *)path
, (char *)DgaSharedRetainedPath
);
1002 xDGARtndPathReply rep
;
1003 struct dga_extinfo
*extinfop
;
1005 if ((extinfop
= lookup_dga_ext(dpy
)) == NULL
)
1007 if (extinfop
->protocol_major_version
< 3)
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
)) {
1021 strcpy(path
, (char *) rep
.path
);
1023 #endif /* SERVER_DGA */
1028 XDgaQueryVersion(dpy
, major_versionp
, minor_versionp
)
1030 int *major_versionp
,
1034 *major_versionp
= SUN_DGA_MAJOR_VERSION
;
1035 *minor_versionp
= SUN_DGA_MINOR_VERSION
;
1038 xDgaQueryVersionReply rep
;
1039 xDgaQueryVersionReq
*req
;
1042 if (XQueryExtension(dpy
, "SUN_DGA", &opcode
, &tmp
, &tmp
) == 0)
1046 GetReq(DgaQueryVersion
, req
);
1047 req
->reqType
= opcode
;
1048 req
->dgaReqType
= X_DgaQueryVersion
;
1049 if (!_XReply(dpy
, (xReply
*) & rep
, 0, xTrue
)) {
1054 *major_versionp
= rep
.majorVersion
;
1055 *minor_versionp
= rep
.minorVersion
;
1059 #endif /* SERVER_DGA */
1064 XDgaGrabPixmap(dpy
, d
)
1070 PixmapPtr pPix
= (PixmapPtr
)LookupIDByType(d
, RT_PIXMAP
);
1074 if (((DrawablePtr
)pPix
)->type
== DRAWABLE_WINDOW
)
1076 val
= DgaInitSharedPixmap(pPix
, NEW
);
1079 if (dga_pixlist_add(val
, dpy
, d
) == 0) {
1080 XDgaUnGrabPixmap(dpy
, d
);
1088 struct dga_extinfo
*extinfop
;
1090 if ((extinfop
= init_dga_ext(dpy
)) == NULL
)
1092 if (extinfop
->protocol_major_version
< 3)
1095 GetResReq(DGA
, d
, req
);
1096 req
->reqType
= extinfop
->major_opcode
;
1097 req
->pad
= X_DgaGrabPixmap
;
1098 if (!_XReply(dpy
, (xReply
*) &rep
, 0, xTrue
)) {
1106 if (dga_pixlist_add(rep
.data00
, dpy
, d
) == 0) {
1107 XDgaUnGrabPixmap(dpy
, d
);
1112 #endif /* SERVER_DGA */
1117 XDgaUnGrabPixmap(dpy
, d
)
1122 PixmapPtr pPix
= (PixmapPtr
)LookupIDByType(d
, RT_PIXMAP
);
1127 if (((DrawablePtr
)pPix
)->type
== DRAWABLE_WINDOW
)
1129 val
= DgaDestroySharedPixmap(pPix
);
1132 if (dga_pixlist_free(dpy
, d
) == 0)
1139 struct dga_extinfo
*extinfop
;
1141 if ((extinfop
= lookup_dga_ext(dpy
)) == NULL
)
1143 if (extinfop
->protocol_major_version
< 3)
1146 GetResReq(DGA
, d
, req
);
1147 req
->reqType
= extinfop
->major_opcode
;
1148 req
->pad
= X_DgaUnGrabPixmap
;
1149 if (!_XReply(dpy
, (xReply
*) &rep
, 0, xTrue
)) {
1156 return rep
.data00
; /* Status */
1157 #endif /* SERVER_DGA */
1162 dgai_grabDrawRequest (Display
*dpy
, Drawable drawid
, int *drawType
)
1165 DrawablePtr pDraw
= (DrawablePtr
)LookupIDByClass(drawid
, RC_DRAWABLE
);
1169 return(DgaDrawGrab(drawid
, pDraw
, NEW
, drawType
));
1173 struct dga_extinfo
*extinfop
;
1175 if ((extinfop
= init_dga_ext(dpy
)) == NULL
)
1177 if (extinfop
->protocol_major_version
< 3)
1180 GetResReq(DGA
, drawid
, req
);
1181 req
->reqType
= extinfop
->major_opcode
;
1182 req
->pad
= X_DgaGrabDrawable
;
1183 if (!_XReply(dpy
, (xReply
*) &rep
, 0, xTrue
)) {
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)
1197 *drawType
= rep
.data01
;
1200 return (rep
.data00
);
1201 #endif /* SERVER_DGA */
1205 dgai_ungrabDrawRequest (Display
*dpy
, Drawable drawid
)
1208 DrawablePtr pDraw
= (DrawablePtr
)LookupIDByClass(drawid
, RC_DRAWABLE
);
1212 return(DgaDrawUngrab(drawid
, pDraw
, NEW
));
1216 struct dga_extinfo
*extinfop
;
1218 if ((extinfop
= lookup_dga_ext(dpy
)) == NULL
)
1220 if (extinfop
->protocol_major_version
< 3)
1223 GetResReq(DGA
, drawid
, req
);
1224 req
->reqType
= extinfop
->major_opcode
;
1225 req
->pad
= X_DgaUnGrabDrawable
;
1226 if (!_XReply(dpy
, (xReply
*) &rep
, 0, xTrue
)) {
1233 return rep
.data00
; /* Status */
1234 #endif /* SERVER_DGA */
1239 XDgaGrabDrawable(Display
*dpy
, Drawable drawid
)
1245 mutex_lock(&dgaGlobalMutex
);
1247 if (!(token
= dgai_grabDrawRequest(dpy
, drawid
, &drawType
))) {
1249 mutex_unlock(&dgaGlobalMutex
);
1256 case DGA_PROTO_OVERLAY
:
1257 case DGA_PROTO_WINDOW
: {
1260 if (!dga_winlist_add(token
, dpy
, (Window
)drawid
)) {
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
;
1274 mutex_unlock(&dgaGlobalMutex
);
1276 return ((Dga_drawable
)dgawin
);
1279 case DGA_PROTO_PIXMAP
: {
1282 if (!dga_pixlist_add(token
, dpy
, (Pixmap
)drawid
)) {
1285 if (!(dgapix
= (_Dga_pixmap
) dga_pix_grab(token
, (Pixmap
)drawid
))) {
1288 dgapix
->p_dpy
= dpy
;
1289 dgapix
->p_id
= (Pixmap
) drawid
;
1291 mutex_unlock(&dgaGlobalMutex
);
1293 return ((Dga_drawable
)dgapix
);
1299 (void) dgai_ungrabDrawRequest(dpy
, drawid
);
1301 mutex_unlock(&dgaGlobalMutex
);
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
);
1320 mutex_lock(&dgaGlobalMutex
);
1323 case DGA_DRAW_WINDOW
:
1324 case DGA_DRAW_OVERLAY
:
1325 dgai_win_ungrab_common((Dga_window
)dgadraw
, -1,1);
1327 case DGA_DRAW_PIXMAP
:
1328 dga_pix_ungrab((Dga_pixmap
)dgadraw
);
1332 status
= dgai_ungrabDrawRequest(dpy
, drawid
);
1334 mutex_unlock(&dgaGlobalMutex
);
1341 static struct dga_xwinrec
*dga_xwinlist
= NULL
;
1344 dga_winlist_add(token
, dpy
, win
)
1349 struct dga_xwinrec
*recp
;
1354 (struct dga_xwinrec
*) _dga_is_X_window(token
,&listdpy
,&listwin
)) {
1355 if ((win
== listwin
) && (dpy
== listdpy
)) {
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
));
1364 recp
->next
= dga_xwinlist
;
1365 dga_xwinlist
= recp
;
1366 recp
->token
= token
;
1374 * Free dga_xwinrec structure for a particular window and display.
1375 * If win is NULL free all entries on list for this display.
1378 dga_winlist_free(dpy
, win
)
1382 struct dga_xwinrec
*recp
, **prevp
;
1385 prevp
= &dga_xwinlist
;
1386 recp
= dga_xwinlist
;
1388 if (recp
->dpy
== dpy
) {
1390 *prevp
= recp
->next
;
1394 else if (recp
->win
== win
) {
1395 if (--recp
->refcnt
== 0) {
1396 *prevp
= recp
->next
;
1402 prevp
= &recp
->next
;
1406 prevp
= &recp
->next
;
1415 _dga_is_X_window(token
, dpyp
, winp
)
1420 struct dga_xwinrec
*recp
= dga_xwinlist
;
1423 if (recp
->token
== token
) {
1426 return ((void *) recp
);
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
)
1443 struct dga_xpixrec
*recp
;
1446 if (recp
= (struct dga_xpixrec
*) _dga_is_X_pixmap(pix
, &listdpy
)) {
1447 if (dpy
== listdpy
) {
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
));
1456 recp
->next
= dga_xpixlist
;
1457 dga_xpixlist
= recp
;
1458 recp
->token
= token
;
1466 dga_pixlist_free(dpy
, pix
)
1470 struct dga_xpixrec
*recp
, **prevp
;
1473 prevp
= &dga_xpixlist
;
1474 recp
= dga_xpixlist
;
1476 if (recp
->dpy
== dpy
) {
1478 *prevp
= recp
->next
;
1482 else if (recp
->pix
== pix
) {
1483 if (--recp
->refcnt
== 0) {
1484 *prevp
= recp
->next
;
1490 prevp
= &recp
->next
;
1494 prevp
= &recp
->next
;
1503 _dga_is_X_pixmap(pix
, dpyp
)
1507 struct dga_xpixrec
*recp
= dga_xpixlist
;
1510 if (recp
->pix
== pix
) {
1512 return ((void *) recp
);
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
1533 **************************************/
1537 XDgaGetXineramaInfo(dpy
, VirtualWID
, info
)
1542 register xDgaXineramaInfoReq
*req
;
1543 xDgaXineramaInfoReply
*rep
;
1544 struct dga_extinfo
*extinfop
;
1546 if ((extinfop
= init_dga_ext(dpy
)) == NULL
)
1549 rep
= malloc(sizeof(xDgaXineramaInfoReply
));
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,
1565 info
->wid
= VirtualWID
;
1566 memcpy(&info
->subs
[0],&rep
->subs
[0],(MAXSCREEN
-1) * sizeof(SubWID
));