XEVI.c revision e5383a99
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        for (visualIndex = 0; visualIndex < n_visual; visualIndex++) {
137	    isValid = False;
138            for (vinfoIndex = 0; vinfoIndex < sz_info; vinfoIndex++) {
139	        if (visual[visualIndex] == vinfo[vinfoIndex].visualid) {
140		    isValid = True;
141		    break;
142	        }
143	    }
144	    if (!isValid) {
145		XFree(vinfo);
146	        return BadValue;
147	    }
148	}
149	temp_visual = (VisualID32 *)Xmalloc(sz_VisualID32 * n_visual);
150        for (visualIndex = 0; visualIndex < n_visual; visualIndex++)
151	    temp_visual[visualIndex] = visual[visualIndex];
152    }
153    XFree(vinfo);
154    LockDisplay(dpy);
155    GetReq(EVIGetVisualInfo, req);
156    req->reqType = info->codes->major_opcode;
157    req->xeviReqType = X_EVIGetVisualInfo;
158    req->n_visual = n_visual;
159    SetReqLen(req, n_visual, 1);
160    Data(dpy, (char *)temp_visual, n_visual * sz_VisualID32);
161    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
162	UnlockDisplay(dpy);
163	SyncHandle();
164	Xfree(temp_visual);
165	return BadAccess;
166    }
167    Xfree(temp_visual);
168    if ((rep.n_info < 65536) && (rep.n_conflicts < 65536)) {
169	sz_info = rep.n_info * sizeof(ExtendedVisualInfo);
170	sz_xInfo = rep.n_info * sz_xExtendedVisualInfo;
171	sz_conflict = rep.n_conflicts * sizeof(VisualID);
172	sz_xConflict = rep.n_conflicts * sz_VisualID32;
173	*evi_return = Xmalloc(sz_info + sz_conflict);
174	temp_xInfo = Xmalloc(sz_xInfo);
175	temp_conflict = Xmalloc(sz_xConflict);
176    } else {
177	sz_xInfo = sz_xConflict = 0;
178	*evi_return = NULL;
179	temp_xInfo = NULL;
180	temp_conflict = NULL;
181    }
182    if (!*evi_return || !temp_xInfo || !temp_conflict) {
183	_XEatDataWords(dpy, rep.length);
184	UnlockDisplay(dpy);
185	SyncHandle();
186	if (*evi_return) {
187	   Xfree(*evi_return);
188	   *evi_return = NULL;
189	}
190	if (temp_xInfo)
191	   Xfree(temp_xInfo);
192	if (temp_conflict)
193	   Xfree(temp_conflict);
194	return BadAlloc;
195    }
196    _XRead(dpy, (char *)temp_xInfo, sz_xInfo);
197    _XRead(dpy, (char *)temp_conflict, sz_xConflict);
198    UnlockDisplay(dpy);
199    SyncHandle();
200    infoPtr = *evi_return;
201    xInfoPtr = temp_xInfo;
202    xConflictPtr = temp_conflict;
203    n_data = rep.n_info;
204    conflict = (VisualID *)(infoPtr + n_data);
205    while (n_data-- > 0) {
206	infoPtr->core_visual_id		= xInfoPtr->core_visual_id;
207	infoPtr->screen			= xInfoPtr->screen;
208	infoPtr->level			= xInfoPtr->level;
209	infoPtr->transparency_type	= xInfoPtr->transparency_type;
210	infoPtr->transparency_value	= xInfoPtr->transparency_value;
211	infoPtr->min_hw_colormaps	= xInfoPtr->min_hw_colormaps;
212	infoPtr->max_hw_colormaps	= xInfoPtr->max_hw_colormaps;
213	infoPtr->num_colormap_conflicts = xInfoPtr->num_colormap_conflicts;
214	infoPtr->colormap_conflicts	= conflict;
215	conflict += infoPtr->num_colormap_conflicts;
216	infoPtr++;
217	xInfoPtr++;
218    }
219    n_data = rep.n_conflicts;
220    conflict = (VisualID *)(infoPtr);
221    while (n_data-- > 0)
222       *conflict++ = *xConflictPtr++;
223    Xfree(temp_xInfo);
224    Xfree(temp_conflict);
225    *n_info_return = rep.n_info;
226    return Success;
227}
228