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