/* * Copyright (c) 1996 by * PARALLAX GRAPHICS, INCORPORATED, Santa Clara, California. * All rights reserved * * This software is furnished on an as-is basis, and may be used and copied * only with the inclusion of the above copyright notice. * * The information in this software is subject to change without notice. * No committment is made as to the usability or reliability of this * software. * * Parallax Graphics, Inc. * 2500 Condensa Street * Santa Clara, California 95051 * Author: Scott Schmitz */ #define DOMAINLOOP /* */ #include #include #include #include "rasterfile.h" #include #include #include #include #include #include #include #ifndef OPENLOOK #include /* #include */ #include "Xm/PanedW.h" #include "Xm/BulletinB.h" /* Menus */ #include "Xm/RowColumn.h" #include "Xm/PushBG.h" #include "Xm/XmStrDefs.h" /* Added for use with Motif pushbuttons */ #include "Xm/CascadeB.h" #include "Xm/PushB.h" #include "Xm/RowColumn.h" #include "Xm/Form.h" #include "Xm/DrawingA.h" #else #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #endif /* OPENLOOK */ #include #include #include #include /* Number of bytes in an XImage */ #define bytes_in_ximage(x) ((x)->bytes_per_line*(x)->height) #define ESCAPE 128 #define PLX_93 XVisualInfo* GetDefaultVisualInfo(int screenNumber, Display* display); #ifndef PLX_93 XVisualInfo* GetTrueColorVisual(int screenNumber, Display* display); #endif static Widget top, swidgetform, swidget, dwidgetform, dwidget; static Widget right,left,stop,start; static Widget controlPopup,rightPopup,control,form; int videowidth = 320; int videoheight = 240; /*int videowidth = 640; /*int videoheight = 480; */ static int sourcewidth, sourceheight, sourcestart; static Arg args[25]; static unsigned int n; static GC leftGC, rightGC; static Display *leftDisplay, *rightDisplay; static Window leftVideoWindow, rightVideoWindow, leftTopWindow, rightTopWindow; static int first = 1, first1 = 1; static int leftZoomFactor; static int rightZoomFactor; #ifdef PLX_93 XPlxHardwareInfo hardwareInfo; #endif int currentInput2Channel; /* external declarations necessary now but not forever */ static unsigned char *qt; static int size; static short QFactor; static int holdit = 1 ; /* * this function figures the size of a window since sometimes the * the xt functions don't work properly. */ static void get_size(leftDisplay, win, w, h, bw) Display *leftDisplay; Window win; int *w, *h, *bw; { XWindowAttributes attrib; XGetWindowAttributes(leftDisplay, win, &attrib); *w = attrib.width; *h = attrib.height; *bw = attrib.border_width; } /* * function to make the destination window the same size as the source * when the source size changes. */ static flag = 0; void configit(Widget w, XtPointer data, XEvent* event, Boolean* unusedBooleanPointer) { int bw; int origWidth; int origHeight; get_size(leftDisplay, leftTopWindow, &videowidth, &videoheight, &bw); videowidth /= leftZoomFactor; videoheight /= leftZoomFactor; origWidth = videowidth; origHeight = videoheight; if(videowidth > sourcewidth) videowidth = sourcewidth; videowidth -= videowidth % (16 * leftZoomFactor); if(videoheight > sourceheight) videoheight = sourceheight; videoheight -= videoheight % (16 * leftZoomFactor); if(((videowidth * 3) / 4) != videoheight) videoheight = (videowidth * 3) / 4; if(origWidth != videowidth || origHeight != videoheight) { XtResizeWidget(top, videowidth * leftZoomFactor, videoheight * leftZoomFactor, bw); } XtResizeWidget(rightPopup, videowidth * rightZoomFactor, videoheight * rightZoomFactor, bw); first = 1; first1 = 1; } /* * Since we tag the windows such that the tag is not drawn * we need to tag as video so the next video/decompress * will set the tags properly */ void exposit(Widget w, XtPointer data, XEvent* event, Boolean* unusedBooleanPointer) { if(w == swidget) first = 1; else first1 = 1; } static int loopflag = 0; /* * Start things going on first button press */ void Start(Widget w, XtPointer data, XtPointer event) { holdit = 0 ; } void Left(Widget w, XtPointer data, XtPointer event) { char* fileName = "left.ras"; FILE* imageFile; XImage* localImage; int result; char windowName[256]; #ifdef PLX_93 localImage = (XImage*)XPlxGetImage(leftDisplay, leftVideoWindow, 0, 0, videowidth, videoheight, AllPlanes, ZPixmap); #else localImage = (XImage*)XGetImage(leftDisplay, leftVideoWindow, 0, 0, videowidth, videoheight, AllPlanes, ZPixmap); #endif imageFile = fopen(fileName, "w"); if (imageFile == (FILE*)NULL) { printf("Could not open the file %s for writing.\n", fileName); return; } pr_dump_ximage(imageFile, localImage, 0, NULL, NULL, NULL); fclose(imageFile); /* Make sure all data are written out, then close the file */ XDestroyImage(localImage); } void Right(Widget w, XtPointer data, XtPointer event) { char* fileName = "right.ras"; char* jfiffileName = "right.jpg"; FILE* imageFile; XImage* localImage; int result; char windowName[256]; char convertCommand[128]; XPlxCImage *image; int recfd; int imgsize; int imgwd; int imght; char jfileName[40]; image = (XPlxCImage *) XPlxGetCImage(rightDisplay,rightVideoWindow, rightGC, 0, 0, 640, 480, 640, 480); XPlxVideoStop(rightDisplay,rightVideoWindow,rightGC); sprintf(jfileName, "right%d.jpg", 1); if ((recfd = open(jfileName, O_RDWR | O_CREAT)) < 0 ) { printf("Could NOT open the file %s for writing \n", jfileName); } imgsize = image->size; imgwd = image->width; imght = image->height; printf("Image size %d width %d height %d\n",imgsize,imgwd,imght); if (write(recfd, image->data, image->size) <0) { printf("Image file %s writing error.\n", jfileName); } XPlxDestroyCImage(image); close(recfd); /*#ifdef PLX_93 /* localImage = (XImage*)XPlxGetImage(rightDisplay, rightVideoWindow, 0, 0, /* videowidth, videoheight, /* AllPlanes, ZPixmap); /*#else /* localImage = (XImage*)XGetImage(rightDisplay, rightVideoWindow, 0, 0, /* videowidth, videoheight, /* AllPlanes, ZPixmap); /*#endif /* /* imageFile = fopen(fileName, "w"); /* if (imageFile == (FILE*)NULL) /* { /* printf("Could not open the file %s for writing.\n", fileName); /* return; /* } /* pr_dump_ximage(imageFile, localImage, 0, NULL, NULL, NULL); /* fclose(imageFile); /* Make sure all data are written out, then close the file */ /* XDestroyImage(localImage); /* sprintf(convertCommand, /* "convert %s jpeg:%s", /* fileName, /* jfiffileName); /* result = system(convertCommand); /* if (result == -1) /* printf("Could not create the JPEG image %s\n", jfiffileName); /* unlink(fileName); */ } void Stop(Widget w, XtPointer data, XtPointer event) { XPlxVideoStop(leftDisplay, leftVideoWindow, leftGC); XPlxVideoStop(rightDisplay, rightVideoWindow, rightGC); XCloseDisplay(rightDisplay); XCloseDisplay(leftDisplay); exit(0); } void buttonp(Widget w, XtPointer data, XtPointer event) { holdit = 0 ; } /* * Main work process. * turn on live video, video overlay to remove flickering */ Boolean worker(XtPointer data) { int count; char ibuf[0x10000]; int i; if (holdit) return FALSE; /* wait until button is pressed */ if(first) { XPlxVideoTag(leftDisplay, leftVideoWindow, leftGC, PLX_VIDEO); /* Start the live video in the left display */ XPlxVideoSqueezeLive(leftDisplay, leftVideoWindow, leftGC, 0, sourcestart, sourcewidth /* leftZoomFactor*/, sourceheight /* leftZoomFactor*/, 0, 0, videowidth * leftZoomFactor, videoheight * leftZoomFactor); /* Start the live video in the right display */ XPlxVideoSqueezeLive(rightDisplay, rightVideoWindow, rightGC, 0, sourcestart, sourcewidth /* leftZoomFactor*/, sourceheight /* leftZoomFactor*/, 0, 0, videowidth * leftZoomFactor, videoheight * leftZoomFactor); } if(first1) XPlxVideoTag(rightDisplay, rightVideoWindow, rightGC, PLX_VIDEO); if(first) /* only do this when necessary */ { XPlxVideoTag(leftDisplay, leftVideoWindow, leftGC, PLX_VIDEO_OVR); first = 0; } if(first1) /* only do this when necessary */ { XPlxVideoTag(rightDisplay, rightVideoWindow, rightGC, PLX_VIDEO_OVR); first1 = 0; } return(FALSE); /* work processes must return FALSE */ } static void usage() { printf("captwo \n"); exit(1); } void main(argc, argv) int argc; char **argv; { XtAppContext app_context; char *displayName; plx_IO *plxio; plx_IO *plxior; plx_IO_list *iolist; plx_IO_list *iolistr; plx_signal_list *siglist; plx_signal_list *siglistr; plx_signal *sig; plx_signal *sigr; static int mask = ButtonPressMask | ExposureMask; static int mask1 = StructureNotifyMask; int leftScreen, rightScreen; Colormap leftColormap, rightColormap; XVisualInfo *leftVisual; XVisualInfo *rightVisual; XVisualInfo *defaultVisual; int copy_of_argc; char** copy_of_argv; int argv_size; int i, tmp, badsync; XWindowAttributes winAttrs; unsigned char *qt; int size; /* the rest from here is straight xt/openlook stuff */ XtToolkitInitialize(); app_context = XtCreateApplicationContext(); copy_of_argc = argc; argv_size = argc * (sizeof(char*)); copy_of_argv = (char**) XtMalloc(argv_size); memcpy(copy_of_argv, argv, argv_size); leftDisplay = XtOpenDisplay(app_context, NULL, NULL, "captwo", (XrmOptionDescList) NULL, 0, &argc, argv); if((Display *) NULL == leftDisplay) { printf("Unable to open left display check permisions\n"); exit(1); } leftScreen = DefaultScreen(leftDisplay); /* * Set up the TrueColor visual: */ #ifdef PLX_93 leftVisual = XPlxGetVideoVisual(leftScreen, leftDisplay); #else leftVisual = GetTrueColorVisual(leftScreen, leftDisplay); #endif if(leftVisual == (XVisualInfo*)NULL) { XtWarning("Could not find the TrueColor visual being requested."); /* exit(-1); */ } n = 0; XtSetArg(args[n], XmNvisual, leftVisual->visual); n++; XtSetArg(args[n], XmNdepth, leftVisual->depth); n++; defaultVisual = GetDefaultVisualInfo(leftScreen, leftDisplay); if((defaultVisual->class == leftVisual->class) && (defaultVisual->depth == leftVisual->depth)) { XGetWindowAttributes(leftDisplay, XRootWindow(leftDisplay, leftScreen), &winAttrs); leftColormap = winAttrs.colormap; } else { leftColormap = XCreateColormap(leftDisplay, XRootWindow(leftDisplay, leftScreen), leftVisual->visual, AllocNone); } XtSetArg(args[n], XmNcolormap, leftColormap); n++; XtSetArg(args[n], XmNargc, copy_of_argc); n++; XtSetArg(args[n], XmNargv, copy_of_argv); n++; top = XtAppCreateShell("left", "captwo", applicationShellWidgetClass, leftDisplay, args, n); rightDisplay=XtOpenDisplay(app_context, NULL, "captwo", "captwo", NULL, 0, &argc, (String *)argv); if((Display *)NULL == rightDisplay) { printf("Unable to open display %s, check permisions\n", displayName); exit(1); } rightScreen = DefaultScreen(rightDisplay); #ifdef PLX_93 rightVisual = XPlxGetVideoVisual(rightScreen, rightDisplay); #else rightVisual = GetTrueColorVisual(rightScreen, rightDisplay); #endif if(rightVisual == (XVisualInfo*)NULL) { XtWarning("Could not find the TrueColor visual being requested."); /* exit(-1); */ } n = 0; n = 0; XtSetArg(args[n], XmNvisual, rightVisual->visual); n++; XtSetArg(args[n], XmNdepth, rightVisual->depth); n++; defaultVisual = GetDefaultVisualInfo(rightScreen, rightDisplay); if((defaultVisual->class == rightVisual->class) && (defaultVisual->depth == rightVisual->depth)) { XGetWindowAttributes(rightDisplay, XRootWindow(rightDisplay, rightScreen), &winAttrs); rightColormap = winAttrs.colormap; } else { rightColormap = XCreateColormap(rightDisplay, XRootWindow(rightDisplay, rightScreen), rightVisual->visual, AllocNone); } XtSetArg(args[n], XmNcolormap, rightColormap); n++; rightPopup = XtAppCreateShell("right","captwo", applicationShellWidgetClass, rightDisplay, args, n); #ifdef DOMAINLOOP n = 0; XtSetArg(args[n], XtNwidth, 450); n++; XtSetArg(args[n], XtNheight, 50); n++; controlPopup = XtAppCreateShell("Controls","Controls", applicationShellWidgetClass, XtDisplay(top), args, n); n = 0; XtSetArg(args[n], XtNborderWidth, 0); n++; form = XtCreateManagedWidget("form", xmFormWidgetClass, controlPopup, args, n); n = 0; XtSetArg(args[n], XtNorientation, XmHORIZONTAL); n++; control = XtCreateManagedWidget("control", xmRowColumnWidgetClass, form, args, n); n = 0; start = XtCreateManagedWidget("Start Video", xmPushButtonGadgetClass, control, args, n); XtAddCallback(start,XmNactivateCallback,Start,NULL); n = 0; left = XtCreateManagedWidget("Grab Left Video", xmPushButtonGadgetClass, control, args, n); XtAddCallback(left,XmNactivateCallback,Left,NULL); n = 0; right = XtCreateManagedWidget("Grab Right Video", xmPushButtonGadgetClass, control, args, n); XtAddCallback(right,XmNactivateCallback,Right,NULL); n = 0; stop = XtCreateManagedWidget("Exit", xmPushButtonGadgetClass, control, args, n); XtAddCallback(stop,XmNactivateCallback,Stop,NULL); #endif n = 0; XtSetArg(args[n], XtNborderWidth, 0); n ++; XtSetArg(args[n], XtNwidth, videowidth); n ++; XtSetArg(args[n], XtNheight, videoheight); n++; XtSetArg(args[n], XtNx, 0); n++; XtSetArg(args[n], XtNy, 0); n++; swidgetform = XtCreateManagedWidget("src", xmFormWidgetClass, top, args, n); dwidgetform = XtCreateManagedWidget("dest", xmFormWidgetClass, rightPopup, args, n); n = 0; XtSetArg(args[n], XtNborderWidth, 0); n++; XtSetArg(args[n], XtNwidth, videowidth); n++; XtSetArg(args[n], XtNheight, videoheight); n++; XtSetArg(args[n], XtNx, 0); n++; XtSetArg(args[n], XtNy, 0); n++; swidget = XtVaCreateManagedWidget("src", xmDrawingAreaWidgetClass, swidgetform, XmNtopAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNbackground, BlackPixel(leftDisplay, leftScreen), NULL); dwidget = XtVaCreateManagedWidget("dest", xmDrawingAreaWidgetClass, dwidgetform, XmNtopAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNbackground, BlackPixel(rightDisplay, rightScreen), NULL); #ifdef DOMAINLOOP XtAddEventHandler(swidget, ExposureMask, False, exposit, NULL); XtAddEventHandler(dwidget, ExposureMask, False, exposit, NULL); XtAddEventHandler(swidget, StructureNotifyMask, False, configit, NULL); XtAppAddWorkProc(app_context, worker, NULL); #endif /* * all set up, let her fly. */ XtRealizeWidget(top); XtRealizeWidget(rightPopup); #ifdef DOMAINLOOP XtRealizeWidget(controlPopup); #endif leftTopWindow = XtWindow(top); rightTopWindow = XtWindow(rightPopup); leftVideoWindow = XtWindow(swidget); rightVideoWindow = XtWindow(dwidget); leftGC = XCreateGC(leftDisplay, leftVideoWindow, 0, 0); rightGC = XCreateGC(rightDisplay, rightVideoWindow, 0, 0); XSetForeground(leftDisplay, leftGC, 0); XSetForeground(rightDisplay, rightGC, 0); /* * Get the zoom factor for left and right displays. */ leftZoomFactor = XPlxGetZoomFactor(XtDisplay(top), XtWindow(top)); rightZoomFactor = XPlxGetZoomFactor(XtDisplay(rightPopup), XtWindow(rightPopup)); XtVaSetValues(top, XtNwidth, videowidth * leftZoomFactor, XtNheight, videoheight * leftZoomFactor, NULL); XtVaSetValues(rightPopup, XtNwidth, videowidth * rightZoomFactor, XtNheight, videoheight * rightZoomFactor, NULL); /* Set up system for compression */ size = MakeQTables(100,&qt); XPlxPutTable(rightDisplay,rightVideoWindow,rightGC,(char*)qt,size,0); /* * query the server to get hardware/signal information. */ plxio = (plx_IO *) XPlxQueryConfig(leftDisplay, leftVideoWindow, leftGC); /* if the hardware type is not XVideo, can't work */ if(plxio->hardware != PLX_XVIDEO_24) { printf("%s can only run on Parallax XVideo hardware\n", argv[0]); exit(1); } /* find a pointer to channel one input */ for (iolist = plxio->inputs; iolist && (iolist->channel != PLX_INPUT_0); iolist = iolist->next_IO); /* has to work, can't fail */ /* go through the list of signals and find an active signal */ badsync = 1; for(siglist = iolist->signal_list; siglist; siglist = siglist->next_signal) { XPlxVideoInputSelect(leftDisplay, leftVideoWindow, leftGC, PLX_INPUT_0, siglist->signal->standard, (0<<16 | PLX_COMP), PLX_RGB24); XPlxVideoInputSelect(rightDisplay, rightVideoWindow, rightGC, PLX_INPUT_1, siglist->signal->standard, (1<<16 | PLX_COMP), PLX_RGB24); /* now do a query video to find out if there is sync */ sig = (plx_signal *) XPlxQueryVideo(leftDisplay, leftVideoWindow, leftGC); if(sig->sync_ok) { badsync = 0; break; } } if(badsync) { printf("no video connected to input 0\n"); exit(1); } sourcewidth = sig->w; sourceheight = ((sig->w * 3) / 4); sourcestart = sig->b; XFlush(leftDisplay); XFlush(rightDisplay); #ifdef DOMAINLOOP XtAppMainLoop(app_context); #else XSelectInput(leftDisplay, leftVideoWindow, mask); XSelectInput(rightDisplay, rightVideoWindow, mask); while(1) { XEvent event; XExposeEvent *xevent; XConfigureEvent *cevent; worker(NULL); if(XPending(leftDisplay)) { if(XCheckWindowEvent(leftDisplay, leftVideoWindow, mask, &event)) { if(event.type == ButtonPress) buttonp(swidget, 0, &event); else exposit(swidget, 0, &event, NULL); continue; } if(XCheckWindowEvent(rightDisplay, rightVideoWindow, mask, &event)) { if(event.type == ButtonPress) buttonp(dwidget, 0, &event); else exposit(dwidget, 0, &event, NULL); continue; } if(XCheckWindowEvent(leftDisplay, leftTopWindow, mask1, &event)) { configit(swidget, 0, &event, NULL); continue; } } } #endif } XVisualInfo* GetDefaultVisualInfo(int screenNumber, Display* display) { long visualInfoMask; int visualsMatched; XVisualInfo visualHints; static XVisualInfo* visualList = (XVisualInfo*)NULL; Visual* tempVisual; if (visualList != (XVisualInfo*)NULL) free(visualList); tempVisual = XDefaultVisual(display, /* Failed to get a TrueColor visual, so get the default... */ XDefaultScreen(display)); /* ...visual. */ visualHints.visualid = tempVisual->visualid; visualInfoMask = (VisualIDMask); /* For overlay products, don't actually need a TrueColor class */ visualList = XGetVisualInfo(display, visualInfoMask, &visualHints, &visualsMatched); if (visualsMatched == 0) /* Did the search for, in essence, *any* visual fail? */ return((XVisualInfo*)NULL); /* Yes, return a NULL structure to represent failure */ return(visualList); /* If this statement was reached, no good fallback was... */ /* ...found. In this case, simply return the first... */ /* ...visual found. */ } pr_dump_ximage(file, ximage, map_length, r, g, b) FILE *file; XImage *ximage; int map_length; u_char *r, *g, *b; { struct rasterfile rh; int rc; u_char *data_ptr, *out_data; register int i, ras_bytes, bytesPerScanline; if (!ximage) return(-1); rh.ras_magic = RAS_MAGIC; rh.ras_width = ximage->width; rh.ras_height = ximage->height; /* This needs more work here rh.ras_depth = ximage->depth; */ rh.ras_depth = 32; rh.ras_type = RT_STANDARD; if (map_length == 0) { rh.ras_maptype = RMT_NONE; rh.ras_maplength = 0; } else { rh.ras_maptype = RMT_EQUAL_RGB; rh.ras_maplength = 3*map_length; } /* * Dump everything to the file * 1. Calculate the amount of image data to be dumped * 2. The rasterfile header * 3. the colour map if there is one * 4. the image data */ ras_bytes = ximage->width * rh.ras_depth / 8; /* Bytes per scan line = width in pixels * bytes per pixel */ if ((out_data = (u_char *) malloc(ras_bytes)) == NULL) return(-1); memset(out_data, 0, ras_bytes); rh.ras_length = ras_bytes * ximage->height; rc = fwrite(&rh, sizeof(struct rasterfile), 1, file); if(rh.ras_maptype == RMT_EQUAL_RGB) { rc = fwrite(r, sizeof(u_char), map_length, file); rc = fwrite(g, sizeof(u_char), map_length, file); rc = fwrite(b, sizeof(u_char), map_length, file); } data_ptr = (u_char *) ximage->data; /* Writing image data line by line ensures good raster file */ if (rh.ras_depth == 1) bytesPerScanline = ximage->width/8 + (ximage->width%8 ? 1 : 0); else bytesPerScanline = ximage->width * rh.ras_depth/8; for (i=0; iheight; i++) { memcpy(out_data, data_ptr, bytesPerScanline); rc = fwrite(out_data, sizeof(u_char), ras_bytes, file); memset(out_data, 0, ras_bytes); data_ptr += ras_bytes; } free(out_data); return(0); } #ifndef PLX_93 XVisualInfo* GetTrueColorVisual(int screenNumber, Display* display) { int i; long visualInfoMask; int visualsMatched; XVisualInfo visualHints; static XVisualInfo* visualList = (XVisualInfo*)NULL; XVisualInfo* theVisual; Visual* tempVisual; if (visualList != (XVisualInfo*)NULL) /* Was data saved by a previous call to this function? */ XFree((void*)visualList); /* Yes, release the data since it is no longer needed */ visualHints.class = TrueColor; /* Set up hints to determine the type of visual needed... */ visualHints.screen = screenNumber; /* ...to create a window that can display video */ visualInfoMask = (VisualClassMask | VisualScreenMask); /* For Sun, need to get real TrueColor class */ visualList = XGetVisualInfo(display, /* Try to find a visual that matches what is needed for... */ visualInfoMask, /* ... a window that will display video or TrueColor... */ &visualHints, /* ...graphics. */ &visualsMatched); if (visualsMatched != 0) /* Did the search for a TrueColor visual fail? */ { /* No */ for (theVisual = visualList, i = 0; /* Look at all the visuals returned by XGetVisualInfo... */ i < visualsMatched; /* ...to find the best match. The idea match would be... */ i++, theVisual++) /* ...a 24-bit depth Visual. */ { if (theVisual->depth == 24) /* Was an ideal match found? */ return(theVisual); /* Yes, return this Visual */ } for (theVisual = visualList, i = 0; /* If this statement is reached, no 24-bit TrueColor... */ i < visualsMatched; /* ...Visual was found; in this case, fallback and try... */ i++, theVisual++) /* ...to find the next best thing: any TrueColor visual... */ { /* ...of depth >= 24 bits (probably a 32-bit is what will... */ if (theVisual->depth >= 24) /* ...be found). */ return(theVisual); /* Was a good fallback Visual found? If so, return it. */ } } return(GetDefaultVisualInfo(screenNumber, display)); } /* end function GetTrueColorVisual */ #endif