home *** CD-ROM | disk | FTP | other *** search
/ Chestnut's Multimedia Mania / MM_MANIA.ISO / graphics / povsrc20 / xwind.c < prev    next >
C/C++ Source or Header  |  1993-09-30  |  25KB  |  654 lines

  1. /****************************************************************************
  2. *                xwind.c
  3. *
  4. *  This file contains the XWindows code for the display-as-you-trace feature.
  5. *
  6. *  from Persistence of Vision Raytracer
  7. *  Copyright 1993 Persistence of Vision Team
  8. *---------------------------------------------------------------------------
  9. *  NOTICE: This source code file is provided so that users may experiment
  10. *  with enhancements to POV-Ray and to port the software to platforms other
  11. *  than those supported by the POV-Ray Team.  There are strict rules under
  12. *  which you are permitted to use this file.  The rules are in the file
  13. *  named POVLEGAL.DOC which should be distributed with this file. If
  14. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  15. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  16. *  Forum.  The latest version of POV-Ray may be found there as well.
  17. *
  18. * This program is based on the popular DKB raytracer version 2.12.
  19. * DKBTrace was originally written by David K. Buck.
  20. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  21. *
  22. *****************************************************************************/
  23.  
  24. /******************************************************************************/
  25. /*                                                                            */
  26. /* X Windows code for POV-Ray.                                                */
  27. /* Written by Christopher J. Cason.                                           */
  28. /* CIS 100032,1644                                                            */
  29. /* Internet 100032.1644@compuserve.com                                        */
  30. /*                                                                            */
  31. /******************************************************************************/
  32.  
  33. /******************************************************************************/
  34. /*                                                                            */
  35. /* Original IBM VGA "colour" output routines for MS/DOS by Aaron A. Collins.  */
  36. /*                                                                            */
  37. /* Converted for X Windows and arbitrary #of colours by Christopher J. Cason. */
  38. /*                                                                            */
  39. /* This will deliver approximate colorings using HSV values for the selection.*/
  40. /* The palette map is divided into 4 parts - upper and lower half generated   */
  41. /* with full and half "value" (intensity), respectively.  These halves are    */
  42. /* further halved by full and half saturation values of each range (pastels). */
  43. /* There are three constant colors, black, white, and grey.  They are used    */
  44. /* when the saturation is low enough that the hue becomes undefined, and which*/
  45. /* one is selected is based on a simple range map of "value".  Usage of the   */
  46. /* palette is accomplished by converting the requested color RGB into an HSV  */
  47. /* value.  If the saturation is too low (< .25) then black, white or grey is  */
  48. /* selected.  If there is enough saturation to consider looking at the hue,   */
  49. /* then the hue range of 1-63 is scaled into one of the 4 palette quadrants   */
  50. /* based on its "value" and "saturation" characteristics.                     */
  51. /*                                                                            */
  52. /******************************************************************************/
  53.  
  54. /******************************************************************************/
  55. /*                                                                            */
  56. /* define X_GETS_ARGS if you want to use X options such as '-display xxx:n.n' */
  57. /*                                                                            */
  58. /******************************************************************************/
  59.  
  60. #define DBL             double
  61. #define NAME            "POV-Ray"
  62.  
  63. #include <stdio.h>
  64. #include <math.h>
  65. #include <x11/xlib.h>
  66. #include <x11/xutil.h>
  67. #include <x11/stringdefs.h>
  68. #include <x11/intrinsic.h>
  69. #include <x11/shell.h>
  70. #include "config.h"
  71.  
  72. #define MIN_COLOURS     128
  73. #define MAX_COLOURS     256
  74.  
  75. #define min(x,y)        ((x) < (y) ? (x) : (y))
  76. #define max(x,y)        ((x) > (y) ? (x) : (y))
  77.  
  78. char                    filename [192] ;              /* don't really need it */
  79. unsigned                gWidth ;                      /* +wxxx                */
  80. unsigned                gHeight ;                     /* +hyyy                */
  81. unsigned                gScreenNumber ;               /* screen number        */
  82. unsigned                nColours ;                    /* colours available    */
  83. unsigned                quarterPalette ;              /* 1/4 of nColours      */
  84. unsigned                CooperationLevel = 5 ;        /* for message loop     */
  85. unsigned                screenWidth ;                 /* of root screen       */
  86. unsigned                screenHeight ;                /* ditto                */
  87. unsigned long           gColours [MAX_COLOURS] ;      /* colour lookup        */
  88. GC                      gGc ;                         /* graphics context     */
  89. Screen                  *gScreen ;                    /* the X screen         */
  90. XImage                  *gXimage = NULL ;             /* to buffer the trace  */
  91. Widget                  gParent ;                     /* parent widget        */
  92. Widget                  gPopupwindow ;                /* trace displayed here */
  93. Window                  gWindow ;                     /* child of gPopupWin.. */
  94. Display                 *gDisplay ;                   /* X display connection */
  95. Colormap                gColourmap ;                  /* the colourmap        */
  96. XtAppContext            gAppcontext ;                 /* application context  */
  97.  
  98. /* in POVRAY.C                                                                */
  99. unsigned alt_main (unsigned argc, char *argv []) ;
  100.  
  101. /******************************************************************************/
  102. /*                                                                            */
  103. /* set a pixel in an XImage                                                   */
  104. /*                                                                            */
  105. /******************************************************************************/
  106.  
  107. void SetPixel (Display *display, XImage *ximage, Window window, GC gc, unsigned x, unsigned y, unsigned index)
  108. {
  109.   static unsigned       lastY = 0 ;
  110.  
  111.   if (lastY > y) lastY = y ;
  112.   if (y != lastY)
  113.   {
  114.     /* for efficiency, only display the pixels after a full line is buffered  */
  115.     XPutImage (display, window, gc, ximage, 0, lastY, 0, lastY, gWidth, gHeight) ;
  116.     lastY = y ;
  117.   }
  118.   XPutPixel (ximage, x, y, gColours [index]) ;
  119. }
  120.  
  121. /******************************************************************************/
  122. /*                                                                            */
  123. /* create an XImage                                                           */
  124. /*                                                                            */
  125. /******************************************************************************/
  126.  
  127. XImage *CreateXImage (Display *display, Visual *visual,
  128.                       unsigned depth, unsigned width, unsigned height)
  129. {
  130.   unsigned    format ;
  131.   unsigned    number_of_bytes ;
  132.   XImage      *ximage ;
  133.  
  134.   format = depth == 1 ? XYBitmap : ZPixmap ;
  135.  
  136.   ximage = XCreateImage (display, visual, depth, format,
  137.                          0, NULL, width, height, XBitmapPad (display), 0) ;
  138.  
  139.   if (ximage == NULL) return (NULL) ;
  140.  
  141.   number_of_bytes = ximage->bytes_per_line * ximage->height ;
  142.   if ((ximage->data = malloc (number_of_bytes)) == NULL) return (NULL) ;
  143.   return (ximage) ;
  144. }
  145.  
  146. /******************************************************************************/
  147. /*                                                                            */
  148. /* create an XImage to be compatible with the supplied widget                 */
  149. /*                                                                            */
  150. /******************************************************************************/
  151.  
  152. XImage *CreateXImageFromWidget (Widget widget, unsigned width, unsigned height)
  153. {
  154.   unsigned    depth ;
  155.   XImage      *ximage ;
  156.   Visual      *visual ;
  157.   Display     *display ;
  158.  
  159.   XtVaGetValues (widget, XtNdepth, &depth, XtNvisual, &visual, NULL) ;
  160.   display = XtDisplay (widget) ;
  161.   ximage = CreateXImage (display, visual, depth, width, height) ;
  162.   return (ximage) ;
  163. }
  164.  
  165. /******************************************************************************/
  166. /*                                                                            */
  167. /* make an XImage given a widget, width and height                            */
  168. /*                                                                            */
  169. /******************************************************************************/
  170.  
  171. XImage *MakeImage (Widget widget, unsigned width, unsigned height)
  172. {
  173.   unsigned              x ;
  174.   unsigned              y ;
  175.   XImage                *ximage ;
  176.  
  177.   if ((ximage = CreateXImageFromWidget (widget, width, height)) != NULL)
  178.   {
  179.     for (x = 0 ; x < width ; x++)
  180.       for (y = 0 ; y < height ; y++)
  181.         XPutPixel (ximage, x, y, gColours [0]) ;
  182.   }
  183.  
  184.   return (ximage) ;
  185. }
  186.  
  187. /******************************************************************************/
  188. /*                                                                            */
  189. /* redraw the traced data using the XImage                                    */
  190. /*                                                                            */
  191. /******************************************************************************/
  192.  
  193. void processExpose (XExposeEvent *expose)
  194. {
  195.   if (gXimage == NULL || (void *) gWindow == NULL) return ;
  196.   XPutImage (gDisplay, gWindow, gGc, gXimage,
  197.              expose->x, expose->y,
  198.              expose->x, expose->y,
  199.              expose->width, expose->height) ;
  200. }
  201.  
  202. /******************************************************************************/
  203. /*                                                                            */
  204. /* this is called by the COOPERATE macro from within POVRAY                   */
  205. /*                                                                            */
  206. /******************************************************************************/
  207.  
  208. void XTraceEventHandler (void)
  209. {
  210.   XEvent                event ;
  211.   static unsigned       cooperationCounter = 10 ;
  212.  
  213.   if (CooperationLevel < 10 && --cooperationCounter) return ;
  214.   cooperationCounter = 11 - CooperationLevel ;
  215.  
  216.   if (CooperationLevel > 5)
  217.   {
  218.     /* loop until all messages retrieved */
  219.     while (XtAppPending (gAppcontext))
  220.     {
  221.       XtAppNextEvent (gAppcontext, &event) ;
  222.       if (event.type == Expose && event.xexpose.window == gWindow)
  223.       {
  224.         if (event.xexpose.count == 0) processExpose (&event.xexpose) ;
  225.         return ;
  226.       }
  227.       XtDispatchEvent (&event) ;
  228.     }
  229.   }
  230.   else
  231.   {
  232.     /* only process 1 event */
  233.     if (XtAppPending (gAppcontext))
  234.     {
  235.       XtAppNextEvent (gAppcontext, &event) ;
  236.       if (event.type == Expose && event.xexpose.window == gWindow)
  237.       {
  238.         if (event.xexpose.count == 0) processExpose (&event.xexpose) ;
  239.         return ;
  240.       }
  241.       XtDispatchEvent (&event) ;
  242.     }
  243.   }
  244. }
  245.  
  246. /******************************************************************************/
  247. /*                                                                            */
  248. /* called if the user closes the popup window during a trace                  */
  249. /*                                                                            */
  250. /******************************************************************************/
  251.  
  252. void destroyProc (Widget widget)
  253. {
  254.   XDestroyImage (gXimage) ;
  255.   XFreeGC (gDisplay, gGc) ;
  256.   gPopupwindow = NULL ;
  257. }
  258.  
  259. /******************************************************************************/
  260. /*                                                                            */
  261. /* create a popup window, centered on the screen                              */
  262. /*                                                                            */
  263. /******************************************************************************/
  264.  
  265. Widget CreatePopupWindow (Widget parent, char *name, unsigned width, unsigned height, void (*destroyProc) (Widget))
  266. {
  267.   int         n ;
  268.   unsigned    x = 0 ;
  269.   unsigned    y = 0 ;
  270.   Arg         args [8] ;
  271.   Widget      window ;
  272.  
  273.   n = 0 ;
  274.   if (width < screenWidth)
  275.     x = screenWidth / 2 - width / 2 ;
  276.   if (height < screenHeight)
  277.     y = screenHeight / 2 - height / 2 ;
  278.   XtSetArg (args [n], XtNwidth, width) ; n++ ;
  279.   XtSetArg (args [n], XtNheight, height) ; n++ ;
  280.   XtSetArg (args [n], XtNx, x) ; n++ ;
  281.   XtSetArg (args [n], XtNy, y) ; n++ ;
  282.   window = XtCreatePopupShell (name, topLevelShellWidgetClass, parent, args, n) ;
  283.   XtAddCallback (window, XtNdestroyCallback, destroyProc, window) ;
  284.   return (window) ;
  285. }
  286.  
  287. /******************************************************************************/
  288. /*                                                                            */
  289. /* allocate a colour based on the RGB values and place it at index            */
  290. /*                                                                            */
  291. /******************************************************************************/
  292.  
  293. void set_palette (unsigned index, unsigned red, unsigned green, unsigned blue)
  294. {
  295.   XColor      colour ;
  296.  
  297.   colour.pixel = gColours [index] ;
  298.   colour.flags = DoRed | DoGreen | DoBlue ;
  299.   colour.red = (65535 * red) / 256 ;
  300.   colour.blue = (65535 * blue) / 256 ;
  301.   colour.green = (65535 * green) / 256 ;
  302.   XStoreColor (gDisplay, gColourmap, &colour) ;
  303. }
  304.  
  305. /******************************************************************************/
  306. /*                                                                            */
  307. /* Conversion from Hue, Saturation, Value to Red, Green, and Blue and back    */
  308. /* From "Computer Graphics", Donald Hearn & M. Pauline Baker, p. 304          */
  309. /* Extracted from the POV machine specific file IBM.C and modified for X      */
  310. /*                                                                            */
  311. /* See the start of this file for information as to how this code works       */
  312. /*                                                                            */
  313. /******************************************************************************/
  314.  
  315. void hsv_to_rgb (DBL hue, DBL s, DBL v, unsigned *r, unsigned *g, unsigned *b)
  316. {
  317.   DBL         i ;
  318.   DBL         f ;
  319.   DBL         p1 ;
  320.   DBL         p2 ;
  321.   DBL         p3 ;
  322.   DBL         xh ;
  323.   DBL         nr ;
  324.   DBL         ng ;
  325.   DBL         nb ;
  326.  
  327.   if (hue == 360.0) hue = 0.0 ;
  328.  
  329.   xh = hue / 60.0 ;               /* convert hue to be in 0..6 */
  330.   i = floor (xh) ;                /* i = greatest integer <= h */
  331.   f = xh - i ;                    /* f = fractional part of h  */
  332.   p1 = v * (1 - s) ;
  333.   p2 = v * (1 - (s * f)) ;
  334.   p3 = v * (1 - (s * (1 - f))) ;
  335.  
  336.   switch ((int) i)
  337.   {
  338.     case 0 :
  339.          nr = v ;
  340.          ng = p3 ;
  341.          nb = p1 ;
  342.          break ;
  343.  
  344.     case 1 :
  345.          nr = p2 ;
  346.          ng = v ;
  347.          nb = p1 ;
  348.          break ;
  349.  
  350.     case 2 :
  351.          nr = p1 ;
  352.          ng = v ;
  353.          nb = p3 ;
  354.          break ;
  355.  
  356.     case 3 :
  357.          nr = p1 ;
  358.          ng = p2 ;
  359.          nb = v ;
  360.          break ;
  361.  
  362.     case 4 :
  363.          nr = p3 ;
  364.          ng = p1 ;
  365.          nb = v ;
  366.          break ;
  367.  
  368.     case 5 :
  369.          nr = v ;
  370.          ng = p1 ;
  371.          nb = p2 ;
  372.          break ;
  373.  
  374.     default :
  375.          nr = ng = nb = 0 ;
  376.   }
  377.   *r = (unsigned) (nr * 255.0) ;
  378.   *g = (unsigned) (ng * 255.0) ;
  379.   *b = (unsigned) (nb * 255.0) ;
  380. }
  381.  
  382. void rgb_to_hsv (unsigned r, unsigned g, unsigned b, DBL *h, DBL *s, DBL *v)
  383. {
  384.   DBL         m ;
  385.   DBL         r1 ;
  386.   DBL         g1 ;
  387.   DBL         b1 ;
  388.   DBL         nr ;
  389.   DBL         ng ;
  390.   DBL         nb ;
  391.   DBL         nh = 0.0 ;
  392.   DBL         ns = 0.0 ;
  393.   DBL         nv ;
  394.  
  395.   nr = (DBL) r / 255.0 ;
  396.   ng = (DBL) g / 255.0 ;
  397.   nb = (DBL) b / 255.0 ;
  398.  
  399.   nv = max (nr, max (ng, nb)) ;
  400.   m = min (nr, min (ng, nb)) ;
  401.  
  402.   if (nv != 0.0) ns = (nv - m) / nv ;
  403.  
  404.   if (ns == 0.0)
  405.   {
  406.     /* hue undefined if no saturation */
  407.     *h = 0.0 ;
  408.     *s = 0.0 ;
  409.     *v = nv ;
  410.     return ;
  411.   }
  412.  
  413.   r1 = (nv - nr) / (nv - m) ;     /* distance of color from red   */
  414.   g1 = (nv - ng) / (nv - m) ;     /* distance of color from green */
  415.   b1 = (nv - nb) / (nv - m) ;     /* distance of color from blue  */
  416.  
  417.   if (nv == nr)
  418.   {
  419.     if (m == ng)
  420.       nh = 5.0 + b1 ;
  421.     else
  422.       nh = 1.0 - g1 ;
  423.   }
  424.  
  425.   if (nv == ng)
  426.   {
  427.     if (m == nb)
  428.       nh = 1.0 + r1 ;
  429.     else
  430.       nh = 3.0 - b1 ;
  431.   }
  432.  
  433.   if (nv == nb)
  434.   {
  435.     if (m == nr)
  436.       nh = 3.0 + g1 ;
  437.     else
  438.       nh = 5.0 - r1 ;
  439.   }
  440.  
  441.   *h = nh * 60.0 ;                /* return h converted to degrees */
  442.   *s = ns ;
  443.   *v = nv ;
  444. }
  445.  
  446. /******************************************************************************/
  447. /*                                                                            */
  448. /* set up the X palette                                                       */
  449. /* try to allocate at least as many colours as MIN_COLOURS                    */
  450. /* exit with an error if we cannot get at least this many                     */
  451. /* divide the available colour up into four quadrants, and divide each        */
  452. /* quadrant up into specific hues from 0 to 359 degrees                       */
  453. /*                                                                            */
  454. /******************************************************************************/
  455.  
  456. void palette_init (void)
  457. {
  458.   unsigned    m ;
  459.   unsigned    r ;
  460.   unsigned    g ;
  461.   unsigned    b ;
  462.   DBL         hue ;
  463.   DBL         sat ;
  464.   DBL         val ;
  465.  
  466.   for (nColours = MAX_COLOURS ; nColours >= MIN_COLOURS ; nColours--)
  467.     if (XAllocColorCells (gDisplay, gColourmap, False, NULL, 0, gColours, nColours))
  468.       break ;
  469.   if (nColours < MIN_COLOURS)
  470.   {
  471.     printf ("failed to allocate colour cells needed for display\r\n") ;
  472.     exit (1) ;
  473.   }
  474.  
  475.   quarterPalette = nColours / 4 ;
  476.  
  477.   /* for the first quarter of the palette ... */
  478.   for (m = 1 ; m < quarterPalette ; m++)
  479.   {
  480.     /* normalise to 360 */
  481.     hue = 360.0 * ((DBL) (m)) / (DBL) quarterPalette ;
  482.     hsv_to_rgb (hue, 0.5, 0.5, &r, &g, &b) ;
  483.     set_palette (m, r, g, b) ;
  484.  
  485.     hue = 360.0 * ((DBL) (m)) / (DBL) quarterPalette ;
  486.     hsv_to_rgb (hue, 1.0, 0.5, &r, &g, &b) ;
  487.     set_palette (m + quarterPalette, r, g, b) ;
  488.  
  489.     hue = 360.0 * ((DBL) (m)) / (DBL) quarterPalette ;
  490.     hsv_to_rgb (hue, 0.5, 1.0, &r, &g, &b) ;
  491.     set_palette (m + quarterPalette * 2, r, g, b) ;
  492.  
  493.     hue = 360.0 * ((DBL) (m)) / (DBL) quarterPalette ;
  494.     hsv_to_rgb (hue, 1.0, 1.0, &r, &g, &b) ;
  495.     set_palette (m + quarterPalette * 3, r, g, b) ;
  496.   }
  497.  
  498.   set_palette (0, 0, 0, 0) ;                        /* black        */
  499.   set_palette (quarterPalette, 255, 255, 255) ;     /* white        */
  500.   set_palette (quarterPalette * 2, 128, 128, 128) ; /* dark grey    */
  501.   set_palette (quarterPalette * 3, 192, 192, 192) ; /* light grey   */
  502. }
  503.  
  504. /******************************************************************************/
  505. /*                                                                            */
  506. /* display code called directly by POV-Ray via [machine-name].C               */
  507. /*                                                                            */
  508. /******************************************************************************/
  509.  
  510. void x_display_finished ()
  511. {
  512. }
  513.  
  514. void x_display_init (unsigned width, unsigned height)
  515. {
  516.   unsigned              n ;
  517.   unsigned              y = 0 ;
  518.   unsigned              x = 0 ;
  519.   unsigned long         white ;
  520.   unsigned long         black ;
  521.   Arg                   args [20] ;
  522.  
  523.   gDisplay = XtDisplay (gParent) ;
  524.   gScreen = XtScreen (gParent) ;
  525.   gScreenNumber = XScreenNumberOfScreen (gScreen) ;
  526.   gColourmap = DefaultColormapOfScreen (gScreen) ;
  527.   screenWidth = DisplayWidth (gDisplay, gScreenNumber) ;
  528.   screenHeight = DisplayHeight (gDisplay, gScreenNumber) ;
  529.  
  530.   white = WhitePixel (gDisplay, gScreenNumber) ;
  531.   black = BlackPixel (gDisplay, gScreenNumber) ;
  532.  
  533.   n = 0 ;
  534.   x = screenWidth / 2 - gWidth / 2 ;
  535.   y = screenHeight / 2 - gHeight / 2 ;
  536.   XtSetArg (args [n], XtNx, x) ; n++ ;
  537.   XtSetArg (args [n], XtNy, y) ; n++ ;
  538.   XtSetValues (gParent, args, n) ;
  539.  
  540.   gWidth = width ;
  541.   gHeight = height ;
  542.   gPopupwindow = CreatePopupWindow (gParent, NAME, width, height, destroyProc) ;
  543.  
  544.   XtRealizeWidget (gPopupwindow) ;
  545.   XtMapWidget (gPopupwindow) ;
  546.  
  547.   gWindow = XCreateSimpleWindow (gDisplay, XtWindow (gPopupwindow), 0, 0, width, height, 0, white, black) ;
  548.   XSetWindowBackground (gDisplay, gWindow, black) ;
  549.   XMapWindow (gDisplay, gWindow) ;
  550.   XtPopup (gPopupwindow, XtGrabNonexclusive) ;
  551.  
  552.   palette_init () ;
  553.  
  554.   gGc = XCreateGC (gDisplay, gWindow, 0L, NULL) ;
  555.   gXimage = MakeImage (gPopupwindow, width, height) ;
  556.  
  557.   /* draw a rectangle into the XImage to show trace progress */
  558.  
  559.   for (x = 0 ; x < width ; x++)
  560.   {
  561.     XPutPixel (gXimage, x, 0, white) ;
  562.     XPutPixel (gXimage, x, height - 1, white) ;
  563.   }
  564.  
  565.   for (y = 0 ; y < height ; y++)
  566.   {
  567.     XPutPixel (gXimage, 0, y, white) ;
  568.     XPutPixel (gXimage, width - 1, y, white) ;
  569.   }
  570.  
  571.   XSelectInput (gDisplay, gWindow, ExposureMask) ;
  572. }
  573.  
  574. void x_display_close ()
  575. {
  576.   if (gPopupwindow)
  577.     XtDestroyWidget (gPopupwindow) ;
  578. }
  579.  
  580. void x_display_plot (unsigned x, unsigned y, char Red, char Green, char Blue)
  581. {
  582.   unsigned    colour ;
  583.   DBL         h ;
  584.   DBL         s ;
  585.   DBL         v ;
  586.  
  587.   if (gPopupwindow == NULL) return ;
  588.  
  589.   rgb_to_hsv ((unsigned) Red, (unsigned) Green, (unsigned) Blue, &h, &s, &v) ;
  590.  
  591.   if (s < 0.20)         /* black or white if no saturation of colour ... */
  592.   {
  593.     if (v < 0.25)
  594.       colour = 0 ;                  /* black      */
  595.     else if (v > 0.8)
  596.       colour = quarterPalette ;     /* white      */
  597.     else if (v > 0.5)
  598.       colour = quarterPalette * 3 ; /* light grey */
  599.     else
  600.       colour = quarterPalette * 2 ; /* dark grey  */
  601.   }
  602.   else
  603.   {
  604.     colour = (unsigned) ((DBL) quarterPalette * h / 360.0) ;
  605.  
  606.     if (colour == 0)
  607.       colour = 1 ;                   /* avoid black, white or grey         */
  608.  
  609.     if (colour > quarterPalette)
  610.       colour = quarterPalette ;      /* avoid same                         */
  611.  
  612.     if (v > 0.50)
  613.       colour += quarterPalette * 2 ; /* colours 128-255 for high intensity */
  614.  
  615.     if (s > 0.50)                    /* more than half saturated ?         */
  616.       colour += quarterPalette ;     /* colour range 64-128 or 192-255     */
  617.   }
  618.  
  619.   /* only displays after a full line is received (the Y co-ordinate changes)  */
  620.   SetPixel (gDisplay, gXimage, gWindow, gGc, x, y, colour) ;
  621. }
  622.  
  623. /******************************************************************************/
  624. /*                                                                            */
  625. /* our main routine. when XWIND is linked in this is main () for POV-Ray      */
  626. /*                                                                            */
  627. /******************************************************************************/
  628.  
  629. int main (unsigned argc, char *argv [])
  630. {
  631.   unsigned              n ;
  632.   unsigned              count = 0 ;
  633.   Arg                   args [20] ;
  634.  
  635.   strncpy (filename, argv [0], sizeof (filename)) ;
  636.  
  637.   n = 0 ;
  638.   XtSetArg (args [n], XtNmappedWhenManaged, False) ; n++ ;
  639.   XtSetArg (args [n], XtNallowShellResize, False) ; n++ ;
  640.   XtSetArg (args [n], XtNwidth, 10) ; n++ ;
  641.   XtSetArg (args [n], XtNheight, 10) ; n++ ;
  642.  
  643. /* define X_GETS_ARGS if you want to use X options such as '-display xxx:n.n' */
  644.  
  645. #ifdef X_GETS_ARGS
  646.   gParent = XtAppInitialize (&gAppcontext, NAME, NULL, 0, &argc, argv, NULL, args, n) ;
  647. #else
  648.   gParent = XtAppInitialize (&gAppcontext, NAME, NULL, 0, &count, NULL, NULL, args, n) ;
  649. #endif
  650.  
  651.   /* call POV-Ray ! */
  652.   alt_main (argc, argv) ;
  653.   return (0) ;
  654. }