XEVI.c revision af9a7ee5
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#include "eat.h"
35
36static XExtensionInfo *xevi_info;/* needs to move to globals.c */
37static const char *xevi_extension_name = EVINAME;
38#define XeviCheckExtension(dpy,i,val) \
39  XextCheckExtension (dpy, i, xevi_extension_name, val)
40/*****************************************************************************
41 *                                                                           *
42 *			   private utility routines                          *
43 *                                                                           *
44 *****************************************************************************/
45static /* const */ XExtensionHooks xevi_extension_hooks = {
46    NULL,			/* create_gc */
47    NULL,			/* copy_gc */
48    NULL,			/* flush_gc */
49    NULL,			/* free_gc */
50    NULL,			/* create_font */
51    NULL,			/* free_font */
52    NULL,			/* close_display */
53    NULL,			/* wire_to_event */
54    NULL,			/* event_to_wire */
55    NULL,			/* error */
56    NULL,			/* error_string */
57};
58static XEXT_GENERATE_FIND_DISPLAY (find_display, xevi_info,
59                                   xevi_extension_name,
60                                   &xevi_extension_hooks, 0, NULL)
61Bool XeviQueryExtension (Display *dpy)
62{
63    XExtDisplayInfo *info = find_display (dpy);
64    if (XextHasExtension(info)) {
65	return True;
66    } else {
67	return False;
68    }
69}
70Bool XeviQueryVersion(Display *dpy, int *majorVersion, int *minorVersion)
71{
72    XExtDisplayInfo *info = find_display (dpy);
73    xEVIQueryVersionReply rep;
74    register xEVIQueryVersionReq *req;
75    XeviCheckExtension (dpy, info, False);
76    LockDisplay(dpy);
77    GetReq(EVIQueryVersion, req);
78    req->reqType = info->codes->major_opcode;
79    req->xeviReqType = X_EVIQueryVersion;
80    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
81	UnlockDisplay(dpy);
82	SyncHandle();
83	return False;
84    }
85    *majorVersion = rep.majorVersion;
86    *minorVersion = rep.minorVersion;
87    UnlockDisplay(dpy);
88    SyncHandle();
89    return True;
90}
91static Bool notInList(VisualID32 *visual, int sz_visual, VisualID newVisualid)
92{
93    while  (sz_visual-- > 0)  {
94	if (*visual == newVisualid)
95	    return False;
96	visual++;
97    }
98    return True;
99}
100Status XeviGetVisualInfo(
101    register Display *dpy,
102    VisualID *visual,
103    int n_visual,
104    ExtendedVisualInfo **evi_return,
105    int *n_info_return)
106{
107    XExtDisplayInfo *info = find_display (dpy);
108    register xEVIGetVisualInfoReq *req;
109    xEVIGetVisualInfoReply rep;
110    int sz_info, sz_xInfo, sz_conflict, sz_xConflict;
111    VisualID32 *temp_conflict, *temp_visual, *xConflictPtr;
112    VisualID *conflict;
113    xExtendedVisualInfo *temp_xInfo;
114    XVisualInfo *vinfo;
115    register ExtendedVisualInfo *infoPtr;
116    register xExtendedVisualInfo *xInfoPtr;
117    register int n_data, visualIndex, vinfoIndex;
118    Bool isValid;
119    XeviCheckExtension (dpy, info, 0);
120    if (!n_info_return || !evi_return) {
121	return BadValue;
122    }
123    *n_info_return = 0;
124    *evi_return = NULL;
125    vinfo = XGetVisualInfo(dpy, 0, NULL, &sz_info);
126    if (!vinfo) {
127	return BadValue;
128    }
129    if (!n_visual || !visual) {		/* copy the all visual */
130    	temp_visual = (VisualID32 *)Xmalloc(sz_VisualID32 * sz_info);
131    	n_visual = 0;
132        for (vinfoIndex = 0; vinfoIndex < sz_info; vinfoIndex++)
133	    if (notInList(temp_visual, n_visual, vinfo[vinfoIndex].visualid))
134	        temp_visual[n_visual++] = vinfo[vinfoIndex].visualid;
135    }
136    else {	/* check if the visual is valid */
137        for (visualIndex = 0; visualIndex < n_visual; visualIndex++) {
138	    isValid = False;
139            for (vinfoIndex = 0; vinfoIndex < sz_info; vinfoIndex++) {
140	        if (visual[visualIndex] == vinfo[vinfoIndex].visualid) {
141		    isValid = True;
142		    break;
143	        }
144	    }
145	    if (!isValid) {
146		XFree(vinfo);
147	        return BadValue;
148	    }
149	}
150	temp_visual = (VisualID32 *)Xmalloc(sz_VisualID32 * n_visual);
151        for (visualIndex = 0; visualIndex < n_visual; visualIndex++)
152	    temp_visual[visualIndex] = visual[visualIndex];
153    }
154    XFree(vinfo);
155    LockDisplay(dpy);
156    GetReq(EVIGetVisualInfo, req);
157    req->reqType = info->codes->major_opcode;
158    req->xeviReqType = X_EVIGetVisualInfo;
159    req->n_visual = n_visual;
160    SetReqLen(req, n_visual, 1);
161    Data(dpy, (char *)temp_visual, n_visual * sz_VisualID32);
162    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
163	UnlockDisplay(dpy);
164	SyncHandle();
165	Xfree(temp_visual);
166	return BadAccess;
167    }
168    Xfree(temp_visual);
169    if ((rep.n_info < 65536) && (rep.n_conflicts < 65536)) {
170	sz_info = rep.n_info * sizeof(ExtendedVisualInfo);
171	sz_xInfo = rep.n_info * sz_xExtendedVisualInfo;
172	sz_conflict = rep.n_conflicts * sizeof(VisualID);
173	sz_xConflict = rep.n_conflicts * sz_VisualID32;
174	*evi_return = Xmalloc(sz_info + sz_conflict);
175	temp_xInfo = Xmalloc(sz_xInfo);
176	temp_conflict = Xmalloc(sz_xConflict);
177    } else {
178	sz_xInfo = sz_xConflict = 0;
179	*evi_return = NULL;
180	temp_xInfo = NULL;
181	temp_conflict = NULL;
182    }
183    if (!*evi_return || !temp_xInfo || !temp_conflict) {
184	_XEatDataWords(dpy, rep.length);
185	UnlockDisplay(dpy);
186	SyncHandle();
187	if (evi_return)
188	   Xfree(evi_return);
189	if (temp_xInfo)
190	   Xfree(temp_xInfo);
191	if (temp_conflict)
192	   Xfree(temp_conflict);
193	return BadAlloc;
194    }
195    _XRead(dpy, (char *)temp_xInfo, sz_xInfo);
196    _XRead(dpy, (char *)temp_conflict, sz_xConflict);
197    UnlockDisplay(dpy);
198    SyncHandle();
199    infoPtr = *evi_return;
200    xInfoPtr = temp_xInfo;
201    xConflictPtr = temp_conflict;
202    n_data = rep.n_info;
203    conflict = (VisualID *)(infoPtr + n_data);
204    while (n_data-- > 0) {
205	infoPtr->core_visual_id		= xInfoPtr->core_visual_id;
206	infoPtr->screen			= xInfoPtr->screen;
207	infoPtr->level			= xInfoPtr->level;
208	infoPtr->transparency_type	= xInfoPtr->transparency_type;
209	infoPtr->transparency_value	= xInfoPtr->transparency_value;
210	infoPtr->min_hw_colormaps	= xInfoPtr->min_hw_colormaps;
211	infoPtr->max_hw_colormaps	= xInfoPtr->max_hw_colormaps;
212	infoPtr->num_colormap_conflicts = xInfoPtr->num_colormap_conflicts;
213	infoPtr->colormap_conflicts	= conflict;
214	conflict += infoPtr->num_colormap_conflicts;
215	infoPtr++;
216	xInfoPtr++;
217    }
218    n_data = rep.n_conflicts;
219    conflict = (VisualID *)(infoPtr);
220    while (n_data-- > 0)
221       *conflict++ = *xConflictPtr++;
222    Xfree(temp_xInfo);
223    Xfree(temp_conflict);
224    *n_info_return = rep.n_info;
225    return Success;
226}
227