XEVI.c revision 485f0483
1/* $Xorg: XEVI.c,v 1.3 2000/08/17 19:45:51 cpqbld Exp $ */
2/************************************************************
3Copyright (c) 1997 by Silicon Graphics Computer Systems, Inc.
4Permission to use, copy, modify, and distribute this
5software and its documentation for any purpose and without
6fee is hereby granted, provided that the above copyright
7notice appear in all copies and that both that copyright
8notice and this permission notice appear in supporting
9documentation, and that the name of Silicon Graphics not be
10used in advertising or publicity pertaining to distribution
11of the software without specific prior written permission.
12Silicon Graphics makes no representation about the suitability
13of this software for any purpose. It is provided "as is"
14without any express or implied warranty.
15SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
16SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
17AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
18GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
19DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
21OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
22THE USE OR PERFORMANCE OF THIS SOFTWARE.
23********************************************************/
24/* $XFree86$ */
25#define NEED_EVENTS
26#define NEED_REPLIES
27#ifdef HAVE_CONFIG_H
28#include <config.h>
29#endif
30#include <X11/Xlibint.h>
31#include <X11/extensions/XEVI.h>
32#include <X11/extensions/EVIproto.h>
33#include <X11/extensions/Xext.h>
34#include <X11/extensions/extutil.h>
35#include <X11/Xutil.h>
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    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    infoPtr = *evi_return = (ExtendedVisualInfo *)Xmalloc(sz_info + sz_conflict);
174    xInfoPtr = temp_xInfo = (xExtendedVisualInfo *)Xmalloc(sz_xInfo);
175    xConflictPtr = temp_conflict = (VisualID32 *)Xmalloc(sz_xConflict);
176    if (!*evi_return || !temp_xInfo || !temp_conflict) {
177        _XEatData(dpy, (sz_xInfo + sz_xConflict + 3) & ~3);
178	UnlockDisplay(dpy);
179	SyncHandle();
180	if (evi_return)
181	   Xfree(evi_return);
182	if (temp_xInfo)
183	   Xfree(temp_xInfo);
184	if (temp_conflict)
185	   Xfree(temp_conflict);
186	return BadAlloc;
187    }
188    _XRead(dpy, (char *)temp_xInfo, sz_xInfo);
189    _XRead(dpy, (char *)temp_conflict, sz_xConflict);
190    UnlockDisplay(dpy);
191    SyncHandle();
192    n_data = rep.n_info;
193    conflict = (VisualID *)(infoPtr + n_data);
194    while (n_data-- > 0) {
195	infoPtr->core_visual_id		= xInfoPtr->core_visual_id;
196	infoPtr->screen			= xInfoPtr->screen;
197	infoPtr->level			= xInfoPtr->level;
198	infoPtr->transparency_type	= xInfoPtr->transparency_type;
199	infoPtr->transparency_value	= xInfoPtr->transparency_value;
200	infoPtr->min_hw_colormaps	= xInfoPtr->min_hw_colormaps;
201	infoPtr->max_hw_colormaps	= xInfoPtr->max_hw_colormaps;
202	infoPtr->num_colormap_conflicts = xInfoPtr->num_colormap_conflicts;
203	infoPtr->colormap_conflicts	= conflict;
204	conflict += infoPtr->num_colormap_conflicts;
205	infoPtr++;
206	xInfoPtr++;
207    }
208    n_data = rep.n_conflicts;
209    conflict = (VisualID *)(infoPtr);
210    while (n_data-- > 0)
211       *conflict++ = *xConflictPtr++;
212    Xfree(temp_xInfo);
213    Xfree(temp_conflict);
214    *n_info_return = rep.n_info;
215    return Success;
216}
217