XEVI.c revision cb543c5f
1/************************************************************
2Copyright (c) 1997 by Silicon Graphics Computer Systems, Inc.
3Permission to use, copy, modify, and distribute this
4software and its documentation for any purpose and without
5fee is hereby granted, provided that the above copyright
6notice appear in all copies and that both that copyright
7notice and this permission notice appear in supporting
8documentation, and that the name of Silicon Graphics not be
9used in advertising or publicity pertaining to distribution
10of the software without specific prior written permission.
11Silicon Graphics makes no representation about the suitability
12of this software for any purpose. It is provided "as is"
13without any express or implied warranty.
14SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
15SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
16AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
17GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
18DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
20OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
21THE USE OR PERFORMANCE OF THIS SOFTWARE.
22********************************************************/
23
24#ifdef HAVE_CONFIG_H
25#include <config.h>
26#endif
27#include <X11/Xlibint.h>
28#include <X11/extensions/XEVI.h>
29#include <X11/extensions/EVIproto.h>
30#include <X11/extensions/Xext.h>
31#include <X11/extensions/extutil.h>
32#include <X11/Xutil.h>
33#include <limits.h>
34
35static XExtensionInfo *xevi_info;/* needs to move to globals.c */
36static const char *xevi_extension_name = EVINAME;
37#define XeviCheckExtension(dpy,i,val) \
38  XextCheckExtension (dpy, i, xevi_extension_name, val)
39/*****************************************************************************
40 *                                                                           *
41 *			   private utility routines                          *
42 *                                                                           *
43 *****************************************************************************/
44static /* const */ XExtensionHooks xevi_extension_hooks = {
45    NULL,			/* create_gc */
46    NULL,			/* copy_gc */
47    NULL,			/* flush_gc */
48    NULL,			/* free_gc */
49    NULL,			/* create_font */
50    NULL,			/* free_font */
51    NULL,			/* close_display */
52    NULL,			/* wire_to_event */
53    NULL,			/* event_to_wire */
54    NULL,			/* error */
55    NULL,			/* error_string */
56};
57static XEXT_GENERATE_FIND_DISPLAY (find_display, xevi_info,
58                                   xevi_extension_name,
59                                   &xevi_extension_hooks, 0, NULL)
60Bool XeviQueryExtension (Display *dpy)
61{
62    XExtDisplayInfo *info = find_display (dpy);
63    if (XextHasExtension(info)) {
64	return True;
65    } else {
66	return False;
67    }
68}
69Bool XeviQueryVersion(Display *dpy, int *majorVersion, int *minorVersion)
70{
71    XExtDisplayInfo *info = find_display (dpy);
72    xEVIQueryVersionReply rep;
73    register xEVIQueryVersionReq *req;
74    XeviCheckExtension (dpy, info, False);
75    LockDisplay(dpy);
76    GetReq(EVIQueryVersion, req);
77    req->reqType = info->codes->major_opcode;
78    req->xeviReqType = X_EVIQueryVersion;
79    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
80	UnlockDisplay(dpy);
81	SyncHandle();
82	return False;
83    }
84    *majorVersion = rep.majorVersion;
85    *minorVersion = rep.minorVersion;
86    UnlockDisplay(dpy);
87    SyncHandle();
88    return True;
89}
90static Bool notInList(VisualID32 *visual, int sz_visual, VisualID newVisualid)
91{
92    while  (sz_visual-- > 0)  {
93	if (*visual == newVisualid)
94	    return False;
95	visual++;
96    }
97    return True;
98}
99Status XeviGetVisualInfo(
100    register Display *dpy,
101    VisualID *visual,
102    int n_visual,
103    ExtendedVisualInfo **evi_return,
104    int *n_info_return)
105{
106    XExtDisplayInfo *info = find_display (dpy);
107    register xEVIGetVisualInfoReq *req;
108    xEVIGetVisualInfoReply rep;
109    int sz_info, sz_xInfo, sz_conflict, sz_xConflict;
110    VisualID32 *temp_conflict, *temp_visual, *xConflictPtr;
111    VisualID *conflict;
112    xExtendedVisualInfo *temp_xInfo;
113    XVisualInfo *vinfo;
114    register ExtendedVisualInfo *infoPtr;
115    register xExtendedVisualInfo *xInfoPtr;
116    register int n_data, visualIndex, vinfoIndex;
117    Bool isValid;
118    XeviCheckExtension (dpy, info, 0);
119    if (!n_info_return || !evi_return) {
120	return BadValue;
121    }
122    *n_info_return = 0;
123    *evi_return = NULL;
124    vinfo = XGetVisualInfo(dpy, 0, NULL, &sz_info);
125    if (!vinfo) {
126	return BadValue;
127    }
128    if (!n_visual || !visual) {		/* copy the all visual */
129    	temp_visual = (VisualID32 *)Xmalloc(sz_VisualID32 * sz_info);
130    	n_visual = 0;
131        for (vinfoIndex = 0; vinfoIndex < sz_info; vinfoIndex++)
132	    if (notInList(temp_visual, n_visual, vinfo[vinfoIndex].visualid))
133	        temp_visual[n_visual++] = vinfo[vinfoIndex].visualid;
134    }
135    else {	/* check if the visual is valid */
136	if (n_visual > 65536)
137		n_visual = 65536;
138        for (visualIndex = 0; visualIndex < n_visual; visualIndex++) {
139	    isValid = False;
140            for (vinfoIndex = 0; vinfoIndex < sz_info; vinfoIndex++) {
141	        if (visual[visualIndex] == vinfo[vinfoIndex].visualid) {
142		    isValid = True;
143		    break;
144	        }
145	    }
146	    if (!isValid) {
147		XFree(vinfo);
148	        return BadValue;
149	    }
150	}
151	temp_visual = (VisualID32 *)Xmalloc(sz_VisualID32 * n_visual);
152        for (visualIndex = 0; visualIndex < n_visual; visualIndex++)
153	    temp_visual[visualIndex] = visual[visualIndex];
154    }
155    XFree(vinfo);
156    LockDisplay(dpy);
157    GetReq(EVIGetVisualInfo, req);
158    req->reqType = info->codes->major_opcode;
159    req->xeviReqType = X_EVIGetVisualInfo;
160    req->n_visual = n_visual;
161    SetReqLen(req, n_visual, 1);
162    Data(dpy, (char *)temp_visual, n_visual * sz_VisualID32);
163    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
164	UnlockDisplay(dpy);
165	SyncHandle();
166	Xfree(temp_visual);
167	return BadAccess;
168    }
169    Xfree(temp_visual);
170    if ((rep.n_info < 65536) && (rep.n_conflicts < 65536)) {
171	sz_info = rep.n_info * sizeof(ExtendedVisualInfo);
172	sz_xInfo = rep.n_info * sz_xExtendedVisualInfo;
173	sz_conflict = rep.n_conflicts * sizeof(VisualID);
174	sz_xConflict = rep.n_conflicts * sz_VisualID32;
175	*evi_return = Xmalloc(sz_info + sz_conflict);
176	temp_xInfo = Xmalloc(sz_xInfo);
177	temp_conflict = Xmalloc(sz_xConflict);
178    } else {
179	sz_xInfo = sz_xConflict = 0;
180	*evi_return = NULL;
181	temp_xInfo = NULL;
182	temp_conflict = NULL;
183    }
184    if (!*evi_return || !temp_xInfo || !temp_conflict) {
185	_XEatDataWords(dpy, rep.length);
186	UnlockDisplay(dpy);
187	SyncHandle();
188	if (*evi_return) {
189	   Xfree(*evi_return);
190	   *evi_return = NULL;
191	}
192	if (temp_xInfo)
193	   Xfree(temp_xInfo);
194	if (temp_conflict)
195	   Xfree(temp_conflict);
196	return BadAlloc;
197    }
198    _XRead(dpy, (char *)temp_xInfo, sz_xInfo);
199    _XRead(dpy, (char *)temp_conflict, sz_xConflict);
200    UnlockDisplay(dpy);
201    SyncHandle();
202    infoPtr = *evi_return;
203    xInfoPtr = temp_xInfo;
204    xConflictPtr = temp_conflict;
205    n_data = rep.n_info;
206    conflict = (VisualID *)(infoPtr + n_data);
207    while (n_data-- > 0) {
208	infoPtr->core_visual_id		= xInfoPtr->core_visual_id;
209	infoPtr->screen			= xInfoPtr->screen;
210	infoPtr->level			= xInfoPtr->level;
211	infoPtr->transparency_type	= xInfoPtr->transparency_type;
212	infoPtr->transparency_value	= xInfoPtr->transparency_value;
213	infoPtr->min_hw_colormaps	= xInfoPtr->min_hw_colormaps;
214	infoPtr->max_hw_colormaps	= xInfoPtr->max_hw_colormaps;
215	infoPtr->num_colormap_conflicts = xInfoPtr->num_colormap_conflicts;
216	infoPtr->colormap_conflicts	= conflict;
217	conflict += infoPtr->num_colormap_conflicts;
218	infoPtr++;
219	xInfoPtr++;
220    }
221    n_data = rep.n_conflicts;
222    conflict = (VisualID *)(infoPtr);
223    while (n_data-- > 0)
224       *conflict++ = *xConflictPtr++;
225    Xfree(temp_xInfo);
226    Xfree(temp_conflict);
227    *n_info_return = rep.n_info;
228    return Success;
229}
230