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