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