home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / mesa-1.2.8 / src / xmesa2.c < prev    next >
C/C++ Source or Header  |  1996-05-27  |  79KB  |  2,869 lines

  1. /* $Id: xmesa2.c,v 1.22 1996/04/25 21:09:53 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  1.2
  6.  * Copyright (C) 1995-1996  Brian Paul  (brianp@ssec.wisc.edu)
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25. $Log: xmesa2.c,v $
  26.  * Revision 1.22  1996/04/25  21:09:53  brianp
  27.  * removed references to amult, added DD.update_state assignment
  28.  *
  29.  * Revision 1.21  1996/03/22  20:55:40  brianp
  30.  * nicer monochrome visual output
  31.  *
  32.  * Revision 1.20  1996/03/02  21:41:05  brianp
  33.  * added PF_8R8G8B pixel format
  34.  *
  35.  * Revision 1.19  1996/03/01  20:06:42  brianp
  36.  * added byte-swapping code to clear_16/32_bit_ximage() functions
  37.  *
  38.  * Revision 1.18  1996/02/26  16:23:09  brianp
  39.  * added PF_5R6G5B pixel format from Joerg Hessdoerfer
  40.  *
  41.  * Revision 1.17  1996/02/23  22:19:23  brianp
  42.  * optimized pixel reading for PF_HPCR per Jean-Luc Daems
  43.  *
  44.  * Revision 1.16  1996/02/06  03:25:43  brianp
  45.  * added new gamma correction code
  46.  *
  47.  * Revision 1.15  1996/01/19  18:09:13  brianp
  48.  * added XGetImage error trapping
  49.  *
  50.  * Revision 1.14  1996/01/16  15:07:53  brianp
  51.  * used wrong pixel array function for PF_LOOKUP pixmap mode
  52.  *
  53.  * Revision 1.13  1995/12/30  01:05:11  brianp
  54.  * use renamed DITHER macro
  55.  * fixed XImage clearing problem on Crays
  56.  *
  57.  * Revision 1.11  1995/12/14  19:44:08  brianp
  58.  * fixed a syntax error
  59.  *
  60.  * Revision 1.10  1995/12/13  23:30:07  brianp
  61.  * replaced OFFSET macros with PIXELADDR macros
  62.  *
  63.  * Revision 1.9  1995/11/30  00:52:30  brianp
  64.  * fixed a few type warnings for Sun compiler
  65.  *
  66.  * Revision 1.8  1995/11/30  00:21:23  brianp
  67.  * added new PF_GRAYSCALE mode
  68.  *
  69.  * Revision 1.7  1995/11/03  17:41:48  brianp
  70.  * removed unused vars, fixed code for C++ compilation
  71.  *
  72.  * Revision 1.6  1995/11/01  23:19:21  brianp
  73.  * fixed bugs in write_span_DITHER_pixmap and write_span_LOOKUP_pixmap
  74.  *
  75.  * Revision 1.5  1995/10/30  15:33:49  brianp
  76.  * added mask argument to read_[color|index]_pixels functions
  77.  *
  78.  * Revision 1.4  1995/10/30  15:13:53  brianp
  79.  * replaced Current variable with XMesa
  80.  * moved accelerated point, line, polygon functions to xmesa3.c
  81.  *
  82.  * Revision 1.3  1995/10/22  20:28:34  brianp
  83.  * removed some dead code
  84.  *
  85.  * Revision 1.2  1995/10/19  15:54:06  brianp
  86.  * changed clear_color and set_color arguments to GLubytes
  87.  *
  88.  * Revision 1.1  1995/10/17  21:37:09  brianp
  89.  * Initial revision
  90.  *
  91.  */
  92.  
  93.  
  94.  
  95. /*
  96.  * Mesa/X11 interface, part 2.
  97.  *
  98.  * This file contains the implementations of all the DD.* functions.
  99.  */
  100.  
  101.  
  102.  
  103. #include <stdio.h>
  104. #include <stdlib.h>
  105. #include <string.h>
  106. #include <X11/Xlib.h>
  107. #include "dd.h"
  108. #include "macros.h"
  109. #include "xmesaP.h"
  110. #include "GL/xmesa.h"
  111.  
  112.  
  113.  
  114.  
  115. /*
  116.  * Abort with an error message.
  117.  */
  118. static void die( char *s )
  119. {
  120.    fprintf( stderr, "%s\n", s );
  121.    abort();
  122. }
  123.  
  124.  
  125.  
  126. /*
  127.  * The following functions are used to trap XGetImage() calls which
  128.  * generate BadMatch errors if the drawable isn't mapped.
  129.  */
  130.  
  131. static int caught_xgetimage_error = 0;
  132. static int (*old_xerror_handler)( Display *dpy, XErrorEvent *ev );
  133. static unsigned long xgetimage_serial;
  134.  
  135. /*
  136.  * This is the error handler which will be called if XGetImage fails.
  137.  */
  138. static int xgetimage_error_handler( Display *dpy, XErrorEvent *ev )
  139. {
  140.    if (ev->serial==xgetimage_serial && ev->error_code==BadMatch) {
  141.       /* caught the expected error */
  142.       caught_xgetimage_error = 0;
  143.    }
  144.    else {
  145.       /* call the original X error handler, if any.  otherwise ignore */
  146.       if (old_xerror_handler) {
  147.          (*old_xerror_handler)( dpy, ev );
  148.       }
  149.    }
  150.    return 0;
  151. }
  152.  
  153.  
  154. /*
  155.  * Call this right before XGetImage to setup error trap.
  156.  */
  157. static void catch_xgetimage_errors( Display *dpy )
  158. {
  159.    xgetimage_serial = NextRequest( dpy );
  160.    old_xerror_handler = XSetErrorHandler( xgetimage_error_handler );
  161.    caught_xgetimage_error = 0;
  162. }
  163.  
  164.  
  165. /*
  166.  * Call this right after XGetImage to check if an error occured.
  167.  */
  168. static int check_xgetimage_errors( void )
  169. {
  170.    /* restore old handler */
  171.    (void) XSetErrorHandler( old_xerror_handler );
  172.    /* return 0=no error, 1=error caught */
  173.    return caught_xgetimage_error;
  174. }
  175.  
  176.  
  177. /*
  178.  * Read a pixel from an X drawable.
  179.  */
  180. static unsigned long read_pixel( Display *dpy, Drawable d, int x, int y )
  181. {
  182.    XImage *pixel;
  183.    unsigned long p;
  184.    int error;
  185.    catch_xgetimage_errors( dpy );
  186.    pixel = XGetImage( dpy, d, x, y, 1, 1, AllPlanes, ZPixmap );
  187.    error = check_xgetimage_errors();
  188.    if (pixel && !error) {
  189.       p = XGetPixel( pixel, 0, 0 );
  190.    }
  191.    else {
  192.       p = 0;
  193.    }
  194.    if (pixel) {
  195.       XDestroyImage( pixel );
  196.    }
  197.    return p;
  198. }
  199.  
  200.  
  201.  
  202.  
  203. /*
  204.  * Return the size (width,height,depth) of the current color buffer.
  205.  * This function should be called by the glViewport function because
  206.  * glViewport is often called when the window gets resized.  We need to
  207.  * update some X/Mesa stuff when that happens.
  208.  * Output:  width - width of buffer in pixels.
  209.  *          height - height of buffer in pixels.
  210.  *          depth - In Color Index mode, return bits/pixel
  211.  *                - In RGBA mode, return bits/component
  212.  */
  213. static void buffer_size( GLuint *width, GLuint *height, GLuint *depth )
  214. {
  215.    Window root;
  216.    int winx, winy;
  217.    unsigned int winwidth, winheight;
  218.    unsigned int bw, d;
  219.  
  220.    XGetGeometry( XMesa->display, XMesa->frontbuffer, &root,
  221.          &winx, &winy, &winwidth, &winheight, &bw, &d );
  222.  
  223.    *width = winwidth;
  224.    *height = winheight;
  225.    *depth = XMesa->depth;
  226.  
  227.    if (winwidth!=XMesa->width || winheight!=XMesa->height) {
  228.       XMesa->width = winwidth;
  229.       XMesa->height = winheight;
  230.       xmesa_alloc_back_buffer( XMesa );
  231.  
  232.    }
  233.  
  234.    /* Needed by FLIP macro */
  235.    XMesa->bottom = (int) winheight - 1;
  236.  
  237.    if (XMesa->backimage) {
  238.       /* Needed by PIXELADDR1 macro */
  239.       XMesa->ximage_width1 = XMesa->backimage->bytes_per_line;
  240.       XMesa->ximage_origin1 = (GLubyte *) XMesa->backimage->data
  241.                             + XMesa->ximage_width1 * (winheight-1);
  242.  
  243.       /* Needed by PIXELADDR2 macro */
  244.       XMesa->ximage_width2 = XMesa->backimage->bytes_per_line / 2;
  245.       XMesa->ximage_origin2 = (GLushort *) XMesa->backimage->data
  246.                             + XMesa->ximage_width2 * (winheight-1);
  247.  
  248.       /* Needed by PIXELADDR4 macro */
  249.       XMesa->ximage_width4 = XMesa->backimage->width;
  250.       XMesa->ximage_origin4 = (GLuint *) XMesa->backimage->data
  251.                             + XMesa->ximage_width4 * (winheight-1);
  252.    }
  253. }
  254.  
  255.  
  256. static void finish( void )
  257. {
  258.    if (XMesa) {
  259.       XSync( XMesa->display, False );
  260.    }
  261. }
  262.  
  263.  
  264. static void flush( void )
  265. {
  266.    if (XMesa) {
  267.       XFlush( XMesa->display );
  268.    }
  269. }
  270.  
  271.  
  272.  
  273. static GLboolean set_buffer( GLenum mode )
  274. {
  275.    if (mode==GL_FRONT) {
  276.       /* read/write front buffer */
  277.       XMesa->buffer = XMesa->frontbuffer;
  278.       xmesa_setup_DD_pointers();
  279.       return GL_TRUE;
  280.    }
  281.    else if (mode==GL_BACK && XMesa->db_state) {
  282.       /* read/write back buffer */
  283.       if (XMesa->backpixmap) {
  284.          XMesa->buffer = XMesa->backpixmap;
  285.       }
  286.       else if (XMesa->backimage) {
  287.          XMesa->buffer = None;
  288.       }
  289.       else {
  290.          /* just in case, probably a serious error? */
  291.          XMesa->buffer = XMesa->frontbuffer;
  292.       }
  293.       xmesa_setup_DD_pointers();
  294.       return GL_TRUE;
  295.    }
  296.    else {
  297.       return GL_FALSE;
  298.    }
  299. }
  300.  
  301.  
  302.  
  303. static void clear_index( GLuint index )
  304. {
  305.    XMesa->clearpixel = (unsigned long) index;
  306.    XSetForeground( XMesa->display, XMesa->cleargc, (unsigned long) index );
  307. }
  308.  
  309.  
  310. static void clear_color( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
  311. {
  312.    unsigned long p;
  313.    switch (XMesa->pixelformat) {
  314.       case PF_INDEX:
  315.          return;
  316.       case PF_TRUECOLOR:
  317.      p = PACK_RGB( r, g, b );
  318.      break;
  319.       case PF_8A8B8G8R:
  320.          p = PACK_8A8B8G8R( r, g, b, a );
  321.      break;
  322.       case PF_8R8G8B:
  323.          p = PACK_8R8G8B( r, g, b );
  324.      break;
  325.       case PF_5R6G5B:
  326.          p = PACK_5R6G5B( r, g, b );
  327.      break;
  328.       case PF_DITHER:
  329.      p = DITHER( 0, 0, r, g, b );
  330.      break;
  331.       case PF_1BIT:
  332.      p = (r+g+b) > 382U;   /* 382 = (3*255)/2 */
  333.      break;
  334.       case PF_HPCR:
  335.          p = DITHER_HPCR(1, 1, r, g, b);
  336.          break;
  337.       case PF_LOOKUP:
  338.          p = LOOKUP( r, g, b );
  339.          break;
  340.       case PF_GRAYSCALE:
  341.          p = GRAY_RGB( r, g, b );
  342.          break;
  343.       default:
  344.      abort();
  345.    }
  346.    XMesa->clearpixel = p;
  347.    XSetForeground( XMesa->display, XMesa->cleargc, p );
  348. }
  349.  
  350.  
  351. /* Set current color index */
  352. static void set_index( GLuint index )
  353. {
  354.    unsigned long p = (unsigned long) index;
  355.    XMesa->pixel = p;
  356.    XSetForeground( XMesa->display, XMesa->gc1, p );
  357. }
  358.  
  359.  
  360. /* Set current drawing color */
  361. static void set_color( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
  362. {
  363.    register unsigned long p;
  364.    switch (XMesa->pixelformat) {
  365.       case PF_INDEX:
  366.          return;
  367.       case PF_TRUECOLOR:
  368.      p = PACK_RGB( r, g, b );
  369.      break;
  370.       case PF_8A8B8G8R:
  371.          p = PACK_8A8B8G8R( r, g, b, a );
  372.      break;
  373.       case PF_8R8G8B:
  374.          p = PACK_8R8G8B( r, g, b );
  375.      break;
  376.       case PF_5R6G5B:
  377.          p = PACK_5R6G5B( r, g, b );
  378.      break;
  379.       case PF_DITHER:
  380.          XMesa->red = r;
  381.          XMesa->green = g;
  382.          XMesa->blue = b;
  383.      p = DITHER( 0, 0, r, g, b );
  384.      break;
  385.       case PF_1BIT:
  386.          XMesa->red = r;
  387.          XMesa->green = g;
  388.          XMesa->blue = b;
  389.      p = (r+g+b) > 382U;   /* 382 = (3*255)/2 */
  390.      break;
  391.       case PF_HPCR:
  392.          XMesa->red = r;
  393.          XMesa->green = g;
  394.          XMesa->blue = b;
  395.          p = DITHER_HPCR(1, 1, r, g, b);
  396.          break;
  397.       case PF_LOOKUP:
  398.          p = LOOKUP( r, g, b );
  399.          break;
  400.       case PF_GRAYSCALE:
  401.          p = GRAY_RGB( r, g, b );
  402.          break;
  403.       default:
  404.      abort();
  405.    }
  406.    XMesa->pixel = p;
  407.    XSetForeground( XMesa->display, XMesa->gc1, p );
  408. }
  409.  
  410.  
  411.  
  412. /* Set index mask ala glIndexMask */
  413. static GLboolean index_mask( GLuint mask )
  414. {
  415.    if (XMesa->buffer==XIMAGE) {
  416.       return GL_FALSE;
  417.    }
  418.    else {
  419.       unsigned long m;
  420.       if (mask==0xffffffff) {
  421.          m = AllPlanes;
  422.       }
  423.       else {
  424.          m = (unsigned long) mask;
  425.       }
  426.       XSetPlaneMask( XMesa->display, XMesa->gc1, m );
  427.       XSetPlaneMask( XMesa->display, XMesa->gc2, m );
  428.       XSetPlaneMask( XMesa->display, XMesa->cleargc, m );
  429.       return GL_TRUE;
  430.    }
  431. }
  432.  
  433.  
  434. /* Implements glColorMask() */
  435. static GLboolean color_mask( GLboolean rmask, GLboolean gmask,
  436.                              GLboolean bmask, GLboolean amask )
  437. {
  438. #if defined(__cplusplus) || defined(c_plusplus)
  439.    int xclass = XMesa->visual->c_class;
  440. #else
  441.    int xclass = XMesa->visual->class;
  442. #endif
  443.  
  444.    if (XMesa->buffer!=XIMAGE && (xclass==TrueColor || xclass==DirectColor)) {
  445.       unsigned long m;
  446.       if (rmask && gmask && bmask) {
  447.          m = AllPlanes;
  448.       }
  449.       else {
  450.          m = 0;
  451.          if (rmask)   m |= XMesa->visual->red_mask;
  452.          if (gmask)   m |= XMesa->visual->green_mask;
  453.          if (bmask)   m |= XMesa->visual->blue_mask;
  454.       }
  455.       XSetPlaneMask( XMesa->display, XMesa->gc1, m );
  456.       XSetPlaneMask( XMesa->display, XMesa->gc2, m );
  457.       XSetPlaneMask( XMesa->display, XMesa->cleargc, m );
  458.       return GL_TRUE;
  459.    }
  460.    else {
  461.       return GL_FALSE;
  462.    }
  463. }
  464.  
  465.  
  466. /*
  467.  * Set the pixel logic operation.  Return GL_TRUE if the device driver
  468.  * can perform the operation, otherwise return GL_FALSE.  GL_COPY _must_
  469.  * be operational, obviously.
  470.  */
  471. static GLboolean logicop( GLenum op )
  472. {
  473.    int func;
  474.    if (!XMesa)  return GL_FALSE;
  475.    if ((XMesa->buffer==XIMAGE) && op!=GL_COPY) {
  476.       /* X can't do logic ops in Ximages, except for GL_COPY */
  477.       return GL_FALSE;
  478.    }
  479.    switch (op) {
  480.       case GL_CLEAR:        func = GXclear;        break;
  481.       case GL_SET:        func = GXset;        break;
  482.       case GL_COPY:        func = GXcopy;        break;
  483.       case GL_COPY_INVERTED:    func = GXcopyInverted;    break;
  484.       case GL_NOOP:        func = GXnoop;        break;
  485.       case GL_INVERT:        func = GXinvert;    break;
  486.       case GL_AND:        func = GXand;        break;
  487.       case GL_NAND:        func = GXnand;        break;
  488.       case GL_OR:        func = GXor;        break;
  489.       case GL_NOR:        func = GXnor;        break;
  490.       case GL_XOR:        func = GXxor;        break;
  491.       case GL_EQUIV:        func = GXequiv;        break;
  492.       case GL_AND_REVERSE:    func = GXandReverse;    break;
  493.       case GL_AND_INVERTED:    func = GXandInverted;    break;
  494.       case GL_OR_REVERSE:    func = GXorReverse;    break;
  495.       case GL_OR_INVERTED:    func = GXorInverted;    break;
  496.       default:  return GL_FALSE;
  497.    }
  498.    XSetFunction( XMesa->display, XMesa->gc1, func );
  499.    XSetFunction( XMesa->display, XMesa->gc2, func );
  500.    return GL_TRUE;
  501. }
  502.  
  503.  
  504. /*
  505.  * Enable/disable dithering
  506.  */
  507. static void dither( GLboolean enable )
  508. {
  509.    if (enable) {
  510.       XMesa->pixelformat = XMesa->dithered_pf;
  511.    }
  512.    else {
  513.       XMesa->pixelformat = XMesa->undithered_pf;
  514.    }
  515.    xmesa_setup_DD_pointers();
  516. }
  517.  
  518.  
  519.  
  520. /**********************************************************************/
  521. /*** glClear implementations                                        ***/
  522. /**********************************************************************/
  523.  
  524. static void clear_pixmap( GLboolean all,
  525.                           GLint x, GLint y, GLint width, GLint height )
  526. {
  527.    if (all) {
  528.       XFillRectangle( XMesa->display, XMesa->buffer,
  529.                       XMesa->cleargc,
  530.                       0, 0, XMesa->width+1, XMesa->height+1 );
  531.    }
  532.    else {
  533.       XFillRectangle( XMesa->display, XMesa->buffer,
  534.                       XMesa->cleargc,
  535.                       x, XMesa->height - y - height, width, height );
  536.    }
  537. }
  538.  
  539.  
  540. static void clear_8bit_ximage( GLboolean all,
  541.                                GLint x, GLint y, GLint width, GLint height )
  542. {
  543.    if (all) {
  544.       size_t n = XMesa->backimage->bytes_per_line*XMesa->backimage->height;
  545.       MEMSET( XMesa->backimage->data, XMesa->clearpixel, n );
  546.    }
  547.    else {
  548.       GLint i;
  549.       for (i=0;i<height;i++) {
  550.          GLubyte *ptr = PIXELADDR1( x, y+i );
  551.          MEMSET( ptr, XMesa->clearpixel, width );
  552.       }
  553.    }
  554. }
  555.  
  556.  
  557. static void clear_16bit_ximage( GLboolean all,
  558.                                 GLint x, GLint y, GLint width, GLint height )
  559. {
  560.    if (all) {
  561.       register GLuint n;
  562.       register GLushort *ptr2 =(GLushort *) XMesa->backimage->data;
  563.       register GLushort pixel = (GLushort) XMesa->clearpixel;
  564.       if (XMesa->swapbytes) {
  565.          pixel = ((pixel >> 8) & 0x00ff)
  566.                | ((pixel << 8) & 0xff00);
  567.       }
  568.       if ((pixel & 0xff) == (pixel >> 8)) {
  569.          /* low and high bytes are equal so use memset() */
  570.          n = XMesa->backimage->bytes_per_line * XMesa->height;
  571.          MEMSET( ptr2, pixel & 0xff, n );
  572.       }
  573.       else {
  574.          n = XMesa->backimage->bytes_per_line/2 * XMesa->height;
  575.      do {
  576.         *ptr2++ = pixel;
  577.         n--;
  578.      } while (n!=0);
  579.       }
  580.    }
  581.    else {
  582.       register int i, j;
  583.       register GLushort pixel = (GLushort) XMesa->clearpixel;
  584.       for (j=0;j<height;j++) {
  585.      register GLushort *ptr2 = PIXELADDR2( x, y+j );
  586.          for (i=0;i<width;i++) {
  587.             *ptr2++ = pixel;
  588.          }
  589.       }
  590.    }
  591. }
  592.  
  593.  
  594. static void clear_32bit_ximage( GLboolean all,
  595.                                 GLint x, GLint y, GLint width, GLint height )
  596. {
  597.    if (all) {
  598.       register GLint n = XMesa->width * XMesa->height;
  599.       register GLuint *ptr = (GLuint *) XMesa->backimage->data;
  600.       register GLuint pixel = (GLuint) XMesa->clearpixel;
  601.       if (XMesa->swapbytes) {
  602.          pixel = ((pixel >> 24) & 0x000000ff)
  603.                | ((pixel >> 8)  & 0x0000ff00)
  604.                | ((pixel << 8)  & 0x00ff0000)
  605.                | ((pixel << 24) & 0xff000000);
  606.       }
  607.       if (pixel==0) {
  608.          MEMSET( ptr, pixel, 4*n );
  609.       }
  610.       else {
  611.          do {
  612.             *ptr++ = pixel;
  613.             n--;
  614.          } while (n!=0);
  615.       }
  616.    }
  617.    else {
  618.       register int i, j;
  619.       register GLuint pixel = (GLuint) XMesa->clearpixel;
  620.       for (j=0;j<height;j++) {
  621.          register GLuint *ptr4 = PIXELADDR4( x, y+j );
  622.          for (i=0;i<width;i++) {
  623.             *ptr4++ = pixel;
  624.          }
  625.       }
  626.    }
  627. }
  628.  
  629.  
  630. static void clear_nbit_ximage( GLboolean all,
  631.                                GLint x, GLint y, GLint width, GLint height )
  632. {
  633.    if (all) {
  634.       register int i, j;
  635.       for (j=0;j<XMesa->height;j++) {
  636.          for (i=0;i<XMesa->width;i++) {
  637.             XPutPixel( XMesa->backimage, i, j, XMesa->clearpixel );
  638.          }
  639.       }
  640.    }
  641.    else {
  642.       /* TODO: optimize this */
  643.       register int i, j;
  644.       y = FLIP(y);
  645.       for (j=0;j<height;j++) {
  646.          for (i=0;i<width;i++) {
  647.             XPutPixel( XMesa->backimage, x+i, y-j, XMesa->clearpixel );
  648.          }
  649.       }
  650.    }
  651. }
  652.  
  653.  
  654.  
  655.  
  656. /*
  657.  * The Mesa library needs to be able to draw pixels in a number of ways:
  658.  *   1. RGB vs Color Index
  659.  *   2. as horizontal spans (polygons, images) vs random locations (points,
  660.  *      lines)
  661.  *   3. different color per-pixel or same color for all pixels
  662.  *
  663.  * Furthermore, the X driver needs to support rendering to 3 possible
  664.  * "buffers", usually one, but sometimes two at a time:
  665.  *   1. The front buffer as an X window
  666.  *   2. The back buffer as a Pixmap
  667.  *   3. The back buffer as an XImage
  668.  *
  669.  * Finally, if the back buffer is an XImage, we can avoid using XPutPixel and
  670.  * optimize common cases such as 24-bit and 8-bit modes.
  671.  *
  672.  * By multiplication, there's at least 48 possible combinations of the above.
  673.  *
  674.  * Below are implementations of the most commonly used combinations.  They are
  675.  * accessed through function pointers which get initialized here and are used
  676.  * directly from the Mesa library.  The 8 function pointers directly correspond
  677.  * to the first 3 cases listed above.
  678.  *
  679.  *
  680.  * The function naming convention is:
  681.  *
  682.  *   write_[span|pixels]_[mono]_[format]_[pixmap|ximage]
  683.  *
  684.  * New functions optimized for specific cases can be added without too much
  685.  * trouble.  An example might be the 24-bit TrueColor mode 8A8R8G8B which is
  686.  * found on IBM RS/6000 X servers.
  687.  */
  688.  
  689.  
  690.  
  691.  
  692. /**********************************************************************/
  693. /*** Write COLOR SPAN functions                                     ***/
  694. /**********************************************************************/
  695.  
  696.  
  697. #define COLOR_SPAN_ARGS    GLuint n, GLint x, GLint y,            \
  698.             const GLubyte red[], const GLubyte green[],    \
  699.             const GLubyte blue[], const GLubyte alpha[],    \
  700.             const GLubyte mask[]
  701.  
  702. /* NOTE: if mask==NULL, draw all pixels */
  703.  
  704.  
  705. /*
  706.  * Write a span of PF_TRUECOLOR pixels to a pixmap.
  707.  */
  708. static void write_span_TRUECOLOR_pixmap( COLOR_SPAN_ARGS )
  709. {
  710.    register GLuint i;
  711.    y = FLIP(y);
  712.    if (mask) {
  713.       for (i=0;i<n;i++,x++) {
  714.          if (mask[i]) {
  715.             register unsigned long p = PACK_RGB( red[i], green[i], blue[i] );
  716.             XSetForeground( XMesa->display, XMesa->gc2, p );
  717.             XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  718.                        (int) x, (int) y );
  719.          }
  720.       }
  721.    }
  722.    else {
  723.       /* draw all pixels */
  724.       for (i=0;i<n;i++) {
  725.          XPutPixel( XMesa->rowimage, i, 0,
  726.                     PACK_RGB( red[i], green[i], blue[i] ) );
  727.       }
  728.       XPutImage( XMesa->display, XMesa->buffer, XMesa->gc2,
  729.                  XMesa->rowimage, 0, 0, x, y, n, 1 );
  730.    }
  731. }
  732.  
  733.  
  734. /*
  735.  * Write a span of PF_8A8B8G8R pixels to a pixmap.
  736.  */
  737. static void write_span_8A8B8G8R_pixmap( COLOR_SPAN_ARGS )
  738. {
  739.    register GLuint i;
  740.    y = FLIP( y );
  741.    if (mask) {
  742.       for (i=0;i<n;i++,x++) {
  743.          if (mask[i]) {
  744.             register unsigned long p;
  745.             p = PACK_8A8B8G8R( red[i], green[i], blue[i], alpha[i] );
  746.             XSetForeground( XMesa->display, XMesa->gc2, p );
  747.             XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  748.                         (int) x, (int) y );
  749.          }
  750.       }
  751.    }
  752.    else {
  753.       /* draw all pixels */
  754.       register GLuint *ptr4 = (GLuint *) XMesa->rowimage->data;
  755.       for (i=0;i<n;i++) {
  756.          *ptr4++ = PACK_8A8B8G8R( red[i], green[i], blue[i], alpha[i] );
  757.       }
  758.       XPutImage( XMesa->display, XMesa->buffer, XMesa->gc2,
  759.                  XMesa->rowimage, 0, 0, x, y, n, 1 );
  760.    }
  761. }
  762.  
  763.  
  764. /*
  765.  * Write a span of PF_8R8G8B pixels to a pixmap.
  766.  */
  767. static void write_span_8R8G8B_pixmap( COLOR_SPAN_ARGS )
  768. {
  769.    register GLuint i;
  770.    y = FLIP( y );
  771.    if (mask) {
  772.       for (i=0;i<n;i++,x++) {
  773.          if (mask[i]) {
  774.             register unsigned long p;
  775.             p = PACK_8R8G8B( red[i], green[i], blue[i] );
  776.             XSetForeground( XMesa->display, XMesa->gc2, p );
  777.             XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  778.                         (int) x, (int) y );
  779.          }
  780.       }
  781.    }
  782.    else {
  783.       /* draw all pixels */
  784.       register GLuint *ptr4 = (GLuint *) XMesa->rowimage->data;
  785.       for (i=0;i<n;i++) {
  786.          *ptr4++ = PACK_8R8G8B( red[i], green[i], blue[i] );
  787.       }
  788.       XPutImage( XMesa->display, XMesa->buffer, XMesa->gc2,
  789.                  XMesa->rowimage, 0, 0, x, y, n, 1 );
  790.    }
  791. }
  792.  
  793.  
  794. /*
  795.  * Write a span of PF_5R6G5B pixels to a pixmap.
  796.  */
  797. static void write_span_5R6G5B_pixmap( COLOR_SPAN_ARGS )
  798. {
  799.    register GLuint i;
  800.    y = FLIP( y );
  801.    if (mask) {
  802.       for (i=0;i<n;i++,x++) {
  803.          if (mask[i]) {
  804.             register unsigned short p;
  805.             p = PACK_5R6G5B( red[i], green[i], blue[i] );
  806.             XSetForeground( XMesa->display, XMesa->gc2, p );
  807.             XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  808.                         (int) x, (int) y );
  809.          }
  810.       }
  811.    }
  812.    else {
  813.       /* draw all pixels */
  814.       register GLushort *ptr2 = (GLushort *) XMesa->rowimage->data;
  815.       for (i=0;i<n;i++) {
  816.          *ptr2++ = PACK_5R6G5B( red[i], green[i], blue[i] );
  817.       }
  818.       XPutImage( XMesa->display, XMesa->buffer, XMesa->gc2,
  819.                  XMesa->rowimage, 0, 0, x, y, n, 1 );
  820.    }
  821. }
  822.  
  823.  
  824. /*
  825.  * Write a span of PF_DITHER pixels to a pixmap.
  826.  */
  827. static void write_span_DITHER_pixmap( COLOR_SPAN_ARGS )
  828. {
  829.    register GLuint i;
  830.    y = FLIP( y );
  831.    if (mask) {
  832.       for (i=0;i<n;i++,x++) {
  833.          if (mask[i]) {
  834.             register unsigned long p;
  835.             p = DITHER( x, y, red[i], green[i], blue[i] );
  836.             XSetForeground( XMesa->display, XMesa->gc2, p );
  837.             XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  838.                         (int) x, (int) y );
  839.          }
  840.       }
  841.    }
  842.    else {
  843.       /* draw all pixels */
  844.       for (i=0;i<n;i++) {
  845.          XPutPixel( XMesa->rowimage, i, 0,
  846.                     DITHER( i, y, red[i], green[i], blue[i] ) );
  847.       }
  848.       XPutImage( XMesa->display, XMesa->buffer, XMesa->gc2,
  849.                  XMesa->rowimage, 0, 0, x, y, n, 1 );
  850.    }
  851. }
  852.  
  853.  
  854. /*
  855.  * Write a span of PF_1BIT pixels to a pixmap.
  856.  */
  857. static void write_span_1BIT_pixmap( COLOR_SPAN_ARGS )
  858. {
  859.    register GLuint i;
  860.    y = FLIP( y );
  861.    if (mask) {
  862.       for (i=0;i<n;i++,x++) {
  863.          if (mask[i]) {
  864.             register unsigned long p;
  865.             p = DITHER_1BIT( x, y, red[i], green[i], blue[i] );
  866.             XSetForeground( XMesa->display, XMesa->gc2, p );
  867.             XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  868.                         (int) x, (int) y );
  869.          }
  870.       }
  871.    }
  872.    else {
  873.       /* draw all pixels */
  874.       for (i=0;i<n;i++) {
  875.          XPutPixel( XMesa->rowimage, i, 0,
  876.                     DITHER_1BIT( x+i, y, red[i], green[i], blue[i] ) );
  877.       }
  878.       XPutImage( XMesa->display, XMesa->buffer, XMesa->gc2,
  879.                  XMesa->rowimage, 0, 0, x, y, n, 1 );
  880.    }
  881. }
  882.  
  883.  
  884.  
  885. /*
  886.  * Write a span of PF_HPCR pixels to a pixmap.
  887.  */
  888. static void write_span_HPCR_pixmap( COLOR_SPAN_ARGS )
  889. {
  890.    register GLuint i;
  891.    y = FLIP( y );
  892.    if (mask) {
  893.       for (i=0;i<n;i++,x++) {
  894.          if (mask[i]) {
  895.             register unsigned long p;
  896.             p = DITHER_HPCR( x, y, red[i], green[i], blue[i] );
  897.             XSetForeground( XMesa->display, XMesa->gc2, p );
  898.             XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  899.                        (int) x, (int) y );
  900.          }
  901.       }
  902.    }
  903.    else {
  904.       register GLubyte *ptr = (GLubyte *) XMesa->rowimage->data;
  905.       for (i=0;i<n;i++) {
  906.          *ptr++ = DITHER_HPCR( (x+i), y, red[i], green[i], blue[i] );
  907.       }
  908.       XPutImage( XMesa->display, XMesa->buffer, XMesa->gc2,
  909.                  XMesa->rowimage, 0, 0, x, y, n, 1 );
  910.    }
  911. }
  912.  
  913.  
  914. /*
  915.  * Write a span of PF_LOOKUP pixels to a pixmap.
  916.  */
  917. static void write_span_LOOKUP_pixmap( COLOR_SPAN_ARGS )
  918. {
  919.    register GLuint i;
  920.    y = FLIP( y );
  921.    if (mask) {
  922.       for (i=0;i<n;i++,x++) {
  923.          if (mask[i]) {
  924.             register unsigned long p;
  925.             p = LOOKUP( red[i], green[i], blue[i] );
  926.             XSetForeground( XMesa->display, XMesa->gc2, p );
  927.             XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  928.                        (int) x, (int) y );
  929.          }
  930.       }
  931.    }
  932.    else {
  933.       for (i=0;i<n;i++) {
  934.          XPutPixel( XMesa->rowimage, i, 0, LOOKUP(red[i],green[i],blue[i]) );
  935.       }
  936.       XPutImage( XMesa->display, XMesa->buffer, XMesa->gc2,
  937.                  XMesa->rowimage, 0, 0, x, y, n, 1 );
  938.    }
  939. }
  940.  
  941.  
  942.  
  943. /*
  944.  * Write a span of PF_GRAYSCALE pixels to a pixmap.
  945.  */
  946. static void write_span_GRAYSCALE_pixmap( COLOR_SPAN_ARGS )
  947. {
  948.    register GLuint i;
  949.    y = FLIP( y );
  950.    if (mask) {
  951.       for (i=0;i<n;i++,x++) {
  952.          if (mask[i]) {
  953.             register unsigned long p;
  954.             p = GRAY_RGB( red[i], green[i], blue[i] );
  955.             XSetForeground( XMesa->display, XMesa->gc2, p );
  956.             XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  957.                        (int) x, (int) y );
  958.          }
  959.       }
  960.    }
  961.    else {
  962.       for (i=0;i<n;i++) {
  963.          XPutPixel( XMesa->rowimage, i, 0, GRAY_RGB(red[i],green[i],blue[i]) );
  964.       }
  965.       XPutImage( XMesa->display, XMesa->buffer, XMesa->gc2,
  966.                  XMesa->rowimage, 0, 0, x, y, n, 1 );
  967.    }
  968. }
  969.  
  970.  
  971.  
  972. /*
  973.  * Write a span of PF_TRUECOLOR pixels to an XImage.
  974.  */
  975. static void write_span_TRUECOLOR_ximage( COLOR_SPAN_ARGS )
  976. {
  977.    register GLuint i;
  978.    y = FLIP(y);
  979.    if (mask) {
  980.       for (i=0;i<n;i++,x++) {
  981.          if (mask[i]) {
  982.             register unsigned long p = PACK_RGB( red[i], green[i], blue[i] );
  983.             XPutPixel( XMesa->backimage, x, y, p );
  984.          }
  985.       }
  986.    }
  987.    else {
  988.       /* draw all pixels */
  989.       for (i=0;i<n;i++,x++) {
  990.          register unsigned long p = PACK_RGB( red[i], green[i], blue[i] );
  991.          XPutPixel( XMesa->backimage, x, y, p );
  992.       }
  993.    }
  994. }
  995.  
  996.  
  997. /*
  998.  * Write a span of PF_8A8B8G8R-format pixels to an ximage.
  999.  */
  1000. static void write_span_8A8B8G8R_ximage( COLOR_SPAN_ARGS )
  1001. {
  1002.    register GLuint i;
  1003.    register GLuint *ptr = PIXELADDR4( x, y );
  1004.    if (mask) {
  1005.       for (i=0;i<n;i++,ptr++) {
  1006.          if (mask[i]) {
  1007.             *ptr = PACK_8A8B8G8R( red[i], green[i], blue[i], alpha[i] );
  1008.          }
  1009.       }
  1010.    }
  1011.    else {
  1012.       /* draw all pixels */
  1013.       for (i=0;i<n;i++,ptr++) {
  1014.          *ptr = PACK_8A8B8G8R( red[i], green[i], blue[i], alpha[i] );
  1015.       }
  1016.    }
  1017. }
  1018.  
  1019.  
  1020. /*
  1021.  * Write a span of PF_8R8G8B-format pixels to an ximage.
  1022.  */
  1023. static void write_span_8R8G8B_ximage( COLOR_SPAN_ARGS )
  1024. {
  1025.    register GLuint i;
  1026.    register GLuint *ptr = PIXELADDR4( x, y );
  1027.    if (mask) {
  1028.       for (i=0;i<n;i++,ptr++) {
  1029.          if (mask[i]) {
  1030.             *ptr = PACK_8R8G8B( red[i], green[i], blue[i] );
  1031.          }
  1032.       }
  1033.    }
  1034.    else {
  1035.       /* draw all pixels */
  1036.       for (i=0;i<n;i++,ptr++) {
  1037.          *ptr = PACK_8R8G8B( red[i], green[i], blue[i] );
  1038.       }
  1039.    }
  1040. }
  1041.  
  1042.  
  1043. /*
  1044.  * Write a span of PF_5R6G5B-format pixels to an ximage.
  1045.  */
  1046. static void write_span_5R6G5B_ximage( COLOR_SPAN_ARGS )
  1047. {
  1048.    register GLuint i;
  1049.    register GLushort *ptr = PIXELADDR2( x, y );
  1050.    if (mask) {
  1051.       for (i=0;i<n;i++,ptr++) {
  1052.          if (mask[i]) {
  1053.             *ptr = PACK_5R6G5B( red[i], green[i], blue[i] );
  1054.          }
  1055.       }
  1056.    }
  1057.    else {
  1058.       /* draw all pixels */
  1059.       for (i=0;i<n;i++,ptr++) {
  1060.          *ptr = PACK_5R6G5B( red[i], green[i], blue[i] );
  1061.       }
  1062.    }
  1063. }
  1064.  
  1065.  
  1066. /*
  1067.  * Write a span of PF_DITHER pixels to an XImage.
  1068.  */
  1069. static void write_span_DITHER_ximage( COLOR_SPAN_ARGS )
  1070. {
  1071.    register GLuint i;
  1072.    y = FLIP(y);
  1073.    if (mask) {
  1074.       for (i=0;i<n;i++,x++) {
  1075.          if (mask[i]) {
  1076.             register unsigned long p;
  1077.             p = DITHER( x, y, red[i], green[i], blue[i] );
  1078.             XPutPixel( XMesa->backimage, x, y, p );
  1079.          }
  1080.       }
  1081.    }
  1082.    else {
  1083.       /* draw all pixels */
  1084.       for (i=0;i<n;i++,x++) {
  1085.          register unsigned long p;
  1086.          p = DITHER( x, y, red[i], green[i], blue[i] );
  1087.          XPutPixel( XMesa->backimage, x, y, p );
  1088.       }
  1089.    }
  1090. }
  1091.  
  1092.  
  1093.  
  1094. /*
  1095.  * Write a span of 8-bit PF_DITHER pixels to an XImage.
  1096.  */
  1097. static void write_span_DITHER8_ximage( COLOR_SPAN_ARGS )
  1098. {
  1099.    register GLuint i;
  1100.    register GLubyte *ptr = PIXELADDR1( x, y );
  1101.    if (mask) {
  1102.       for (i=0;i<n;i++,x++,ptr++) {
  1103.          if (mask[i]) {
  1104.             *ptr = DITHER( x, y, red[i], green[i], blue[i] );
  1105.          }
  1106.       }
  1107.    }
  1108.    else {
  1109.       for (i=0;i<n;i++,x++,ptr++) {
  1110.          *ptr = DITHER( x, y, red[i], green[i], blue[i] );
  1111.       }
  1112.    }
  1113. }
  1114.  
  1115.  
  1116.  
  1117. /*
  1118.  * Write a span of PF_1BIT pixels to an XImage.
  1119.  */
  1120. static void write_span_1BIT_ximage( COLOR_SPAN_ARGS )
  1121. {
  1122.    register GLuint i;
  1123.    y = FLIP(y);
  1124.    if (mask) {
  1125.       for (i=0;i<n;i++,x++) {
  1126.          if (mask[i]) {
  1127.             register unsigned long p;
  1128.             p = DITHER_1BIT( x, y, red[i], green[i], blue[i] );
  1129.             XPutPixel( XMesa->backimage, x, y, p );
  1130.          }
  1131.       }
  1132.    }
  1133.    else {
  1134.       for (i=0;i<n;i++,x++) {
  1135.          register unsigned long p;
  1136.          p = DITHER_1BIT( x, y, red[i], green[i], blue[i] );
  1137.          XPutPixel( XMesa->backimage, x, y, p );
  1138.       }
  1139.    }
  1140. }
  1141.  
  1142.  
  1143. /*
  1144.  * Write a span of PF_HPCR pixels to an XImage.
  1145.  */
  1146. static void write_span_HPCR_ximage( COLOR_SPAN_ARGS )
  1147. {
  1148.    register GLuint i;
  1149.    register GLubyte *ptr = PIXELADDR1( x, y );
  1150.    if (mask) {
  1151.       for (i=0;i<n;i++,x++,ptr++) {
  1152.          if (mask[i]) {
  1153.             *ptr = DITHER_HPCR( x, y, red[i], green[i], blue[i] );
  1154.          }
  1155.       }
  1156.    }
  1157.    else {
  1158.       /* draw all pixels */
  1159.       for (i=0;i<n;i++,x++,ptr++) {
  1160.          *ptr = DITHER_HPCR( x, y, red[i], green[i], blue[i] );
  1161.       }
  1162.    }
  1163. }
  1164.  
  1165.  
  1166. /*
  1167.  * Write a span of PF_LOOKUP pixels to an XImage.
  1168.  */
  1169. static void write_span_LOOKUP_ximage( COLOR_SPAN_ARGS )
  1170. {
  1171.    register GLuint i;
  1172.    y = FLIP(y);
  1173.    if (mask) {
  1174.       for (i=0;i<n;i++,x++) {
  1175.          if (mask[i]) {
  1176.             register unsigned long p;
  1177.             p = LOOKUP( red[i], green[i], blue[i] );
  1178.             XPutPixel( XMesa->backimage, x, y, p );
  1179.          }
  1180.       }
  1181.    }
  1182.    else {
  1183.       /* draw all pixels */
  1184.       for (i=0;i<n;i++,x++) {
  1185.          register unsigned long p;
  1186.          p = LOOKUP( red[i], green[i], blue[i] );
  1187.          XPutPixel( XMesa->backimage, x, y, p );
  1188.       }
  1189.    }
  1190. }
  1191.  
  1192.  
  1193. /*
  1194.  * Write a span of PF_GRAYSCALE pixels to an XImage.
  1195.  */
  1196. static void write_span_GRAYSCALE_ximage( COLOR_SPAN_ARGS )
  1197. {
  1198.    register GLuint i;
  1199.    y = FLIP(y);
  1200.    if (mask) {
  1201.       for (i=0;i<n;i++,x++) {
  1202.          if (mask[i]) {
  1203.             register unsigned long p = GRAY_RGB( red[i], green[i], blue[i] );
  1204.             XPutPixel( XMesa->backimage, x, y, p );
  1205.          }
  1206.       }
  1207.    }
  1208.    else {
  1209.       /* draw all pixels */
  1210.       for (i=0;i<n;i++,x++) {
  1211.          register unsigned long p = GRAY_RGB( red[i], green[i], blue[i] );
  1212.          XPutPixel( XMesa->backimage, x, y, p );
  1213.       }
  1214.    }
  1215. }
  1216.  
  1217.  
  1218. /*
  1219.  * Write a span of 8-bit PF_GRAYSCALE pixels to an XImage.
  1220.  */
  1221. static void write_span_GRAYSCALE8_ximage( COLOR_SPAN_ARGS )
  1222. {
  1223.    register GLuint i;
  1224.    register GLubyte *ptr = PIXELADDR1( x, y );
  1225.    if (mask) {
  1226.       for (i=0;i<n;i++,ptr++) {
  1227.          if (mask[i]) {
  1228.             *ptr = GRAY_RGB( red[i], green[i], blue[i] );
  1229.          }
  1230.       }
  1231.    }
  1232.    else {
  1233.       /* draw all pixels */
  1234.       for (i=0;i<n;i++,ptr++) {
  1235.          *ptr = GRAY_RGB( red[i], green[i], blue[i] );
  1236.       }
  1237.    }
  1238. }
  1239.  
  1240.  
  1241.  
  1242.  
  1243. /**********************************************************************/
  1244. /*** Write COLOR PIXEL functions                                    ***/
  1245. /**********************************************************************/
  1246.  
  1247.  
  1248. #define COLOR_PIXEL_ARGS   GLuint n, const GLint x[], const GLint y[],    \
  1249.                const GLubyte red[], const GLubyte green[],    \
  1250.                const GLubyte blue[], const GLubyte alpha[],    \
  1251.                const GLubyte mask[]
  1252.  
  1253.  
  1254. /*
  1255.  * Write an array of PF_TRUECOLOR pixels to a pixmap.
  1256.  */
  1257. static void write_pixels_TRUECOLOR_pixmap( COLOR_PIXEL_ARGS )
  1258. {
  1259.    register GLuint i;
  1260.    for (i=0;i<n;i++) {
  1261.       if (mask[i]) {
  1262.      register unsigned long p;
  1263.      p = PACK_RGB( red[i], green[i], blue[i] );
  1264.      XSetForeground( XMesa->display, XMesa->gc2, p );
  1265.      XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  1266.             (int) x[i], (int) FLIP(y[i]) );
  1267.       }
  1268.    }
  1269. }
  1270.  
  1271.  
  1272. /*
  1273.  * Write an array of PF_8A8B8G8R pixels to a pixmap.
  1274.  */
  1275. static void write_pixels_8A8B8G8R_pixmap( COLOR_PIXEL_ARGS )
  1276. {
  1277.    register GLuint i;
  1278.    for (i=0;i<n;i++) {
  1279.       if (mask[i]) {
  1280.      register unsigned long p;
  1281.          p = PACK_8A8B8G8R( red[i], green[i], blue[i], alpha[i] );
  1282.      XSetForeground( XMesa->display, XMesa->gc2, p );
  1283.      XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  1284.                  (int) x[i], (int) FLIP(y[i]) );
  1285.       }
  1286.    }
  1287. }
  1288.  
  1289.  
  1290. /*
  1291.  * Write an array of PF_8R8G8B pixels to a pixmap.
  1292.  */
  1293. static void write_pixels_8R8G8B_pixmap( COLOR_PIXEL_ARGS )
  1294. {
  1295.    register GLuint i;
  1296.    for (i=0;i<n;i++) {
  1297.       if (mask[i]) {
  1298.      register unsigned long p;
  1299.          p = PACK_8R8G8B( red[i], green[i], blue[i] );
  1300.      XSetForeground( XMesa->display, XMesa->gc2, p );
  1301.      XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  1302.                  (int) x[i], (int) FLIP(y[i]) );
  1303.       }
  1304.    }
  1305. }
  1306.  
  1307.  
  1308. /*
  1309.  * Write an array of PF_5R6G5B pixels to a pixmap.
  1310.  */
  1311. static void write_pixels_5R6G5B_pixmap( COLOR_PIXEL_ARGS )
  1312. {
  1313.    register GLuint i;
  1314.    for (i=0;i<n;i++) {
  1315.       if (mask[i]) {
  1316.      register unsigned long p;
  1317.          p = PACK_5R6G5B( red[i], green[i], blue[i] );
  1318.      XSetForeground( XMesa->display, XMesa->gc2, p );
  1319.      XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  1320.                  (int) x[i], (int) FLIP(y[i]) );
  1321.       }
  1322.    }
  1323. }
  1324.  
  1325.  
  1326. /*
  1327.  * Write an array of PF_DITHER pixels to a pixmap.
  1328.  */
  1329. static void write_pixels_DITHER_pixmap( COLOR_PIXEL_ARGS )
  1330. {
  1331.    register GLuint i;
  1332.    for (i=0;i<n;i++) {
  1333.       if (mask[i]) {
  1334.      register unsigned long p;
  1335.      p = DITHER( x[i], y[i], red[i], green[i], blue[i] );
  1336.      XSetForeground( XMesa->display, XMesa->gc2, p );
  1337.      XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  1338.                  (int) x[i], (int) FLIP(y[i]) );
  1339.       }
  1340.    }
  1341. }
  1342.  
  1343.  
  1344. /*
  1345.  * Write an array of PF_1BIT pixels to a pixmap.
  1346.  */
  1347. static void write_pixels_1BIT_pixmap( COLOR_PIXEL_ARGS )
  1348. {
  1349.    register GLuint i;
  1350.    for (i=0;i<n;i++) {
  1351.       if (mask[i]) {
  1352.      register unsigned long p;
  1353.      p = DITHER_1BIT( x[i], y[i], red[i], green[i], blue[i] );
  1354.      XSetForeground( XMesa->display, XMesa->gc2, p );
  1355.      XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  1356.                  (int) x[i], (int) FLIP(y[i]) );
  1357.       }
  1358.    }
  1359. }
  1360.  
  1361.  
  1362. /*
  1363.  * Write an array of PF_HPCR pixels to a pixmap.
  1364.  */
  1365. static void write_pixels_HPCR_pixmap( COLOR_PIXEL_ARGS )
  1366. {
  1367.    register GLuint i;
  1368.    for (i=0;i<n;i++) {
  1369.       if (mask[i]) {
  1370.          register unsigned long p;
  1371.          p = DITHER_HPCR( x[i], y[i], red[i], green[i], blue[i] );
  1372.          XSetForeground( XMesa->display, XMesa->gc2, p );
  1373.          XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  1374.                      (int) x[i], (int) FLIP(y[i]) );
  1375.       }
  1376.    }
  1377. }
  1378.  
  1379.  
  1380. /*
  1381.  * Write an array of PF_LOOKUP pixels to a pixmap.
  1382.  */
  1383. static void write_pixels_LOOKUP_pixmap( COLOR_PIXEL_ARGS )
  1384. {
  1385.    register GLuint i;
  1386.    for (i=0;i<n;i++) {
  1387.       if (mask[i]) {
  1388.          register unsigned long p;
  1389.          p = LOOKUP( red[i], green[i], blue[i] );
  1390.          XSetForeground( XMesa->display, XMesa->gc2, p );
  1391.          XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  1392.                      (int) x[i], (int) FLIP(y[i]) );
  1393.       }
  1394.    }
  1395. }
  1396.  
  1397.  
  1398. /*
  1399.  * Write an array of PF_GRAYSCALE pixels to a pixmap.
  1400.  */
  1401. static void write_pixels_GRAYSCALE_pixmap( COLOR_PIXEL_ARGS )
  1402. {
  1403.    register GLuint i;
  1404.    for (i=0;i<n;i++) {
  1405.       if (mask[i]) {
  1406.          register unsigned long p;
  1407.          p = GRAY_RGB( red[i], green[i], blue[i] );
  1408.          XSetForeground( XMesa->display, XMesa->gc2, p );
  1409.          XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  1410.                      (int) x[i], (int) FLIP(y[i]) );
  1411.       }
  1412.    }
  1413. }
  1414.  
  1415.  
  1416. /*
  1417.  * Write an array of PF_TRUECOLOR pixels to an ximage.
  1418.  */
  1419. static void write_pixels_TRUECOLOR_ximage( COLOR_PIXEL_ARGS )
  1420. {
  1421.    register GLuint i;
  1422.    for (i=0;i<n;i++) {
  1423.       if (mask[i]) {
  1424.      register unsigned long p;
  1425.      p = PACK_RGB( red[i], green[i], blue[i] );
  1426.      XPutPixel( XMesa->backimage, x[i], FLIP(y[i]), p );
  1427.       }
  1428.    }
  1429. }
  1430.  
  1431.  
  1432. /*
  1433.  * Write an array of PF_8A8B8G8R pixels to an ximage.
  1434.  */
  1435. static void write_pixels_8A8B8G8R_ximage( COLOR_PIXEL_ARGS )
  1436. {
  1437.    register GLuint i;
  1438.    for (i=0;i<n;i++) {
  1439.       if (mask[i]) {
  1440.      GLuint *ptr = PIXELADDR4( x[i], y[i] );
  1441.          *ptr = PACK_8A8B8G8R( red[i], green[i], blue[i], alpha[i] );
  1442.       }
  1443.    }
  1444. }
  1445.  
  1446.  
  1447. /*
  1448.  * Write an array of PF_8R8G8B pixels to an ximage.
  1449.  */
  1450. static void write_pixels_8R8G8B_ximage( COLOR_PIXEL_ARGS )
  1451. {
  1452.    register GLuint i;
  1453.    for (i=0;i<n;i++) {
  1454.       if (mask[i]) {
  1455.      GLuint *ptr = PIXELADDR4( x[i], y[i] );
  1456.          *ptr = PACK_8R8G8B( red[i], green[i], blue[i] );
  1457.       }
  1458.    }
  1459. }
  1460.  
  1461.  
  1462. /*
  1463.  * Write an array of PF_5R6G5B pixels to an ximage.
  1464.  */
  1465. static void write_pixels_5R6G5B_ximage( COLOR_PIXEL_ARGS )
  1466. {
  1467.    register GLuint i;
  1468.    for (i=0;i<n;i++) {
  1469.       if (mask[i]) {
  1470.      GLushort *ptr = PIXELADDR2( x[i], y[i] );
  1471.          *ptr = PACK_5R6G5B( red[i], green[i], blue[i] );
  1472.       }
  1473.    }
  1474. }
  1475.  
  1476.  
  1477. /*
  1478.  * Write an array of PF_DITHER pixels to an XImage.
  1479.  */
  1480. static void write_pixels_DITHER_ximage( COLOR_PIXEL_ARGS )
  1481. {
  1482.    register GLuint i;
  1483.    for (i=0;i<n;i++) {
  1484.       if (mask[i]) {
  1485.      register unsigned long p;
  1486.      p = DITHER( x[i], y[i], red[i], green[i], blue[i] );
  1487.      XPutPixel( XMesa->backimage, x[i], FLIP(y[i]), p );
  1488.       }
  1489.    }
  1490. }
  1491.  
  1492.  
  1493. /*
  1494.  * Write an array of 8-bit PF_DITHER pixels to an XImage.
  1495.  */
  1496. static void write_pixels_DITHER8_ximage( COLOR_PIXEL_ARGS )
  1497. {
  1498.    register GLuint i;
  1499.    for (i=0;i<n;i++) {
  1500.       if (mask[i]) {
  1501.      GLubyte *ptr = PIXELADDR1(x[i],y[i]);
  1502.      *ptr = DITHER( x[i], y[i], red[i], green[i], blue[i] );
  1503.       }
  1504.    }
  1505. }
  1506.  
  1507.  
  1508. /*
  1509.  * Write an array of PF_1BIT pixels to an XImage.
  1510.  */
  1511. static void write_pixels_1BIT_ximage( COLOR_PIXEL_ARGS )
  1512. {
  1513.    register GLuint i;
  1514.    for (i=0;i<n;i++) {
  1515.       if (mask[i]) {
  1516.      register unsigned long p;
  1517.      p = DITHER_1BIT( x[i], y[i], red[i], green[i], blue[i] );
  1518.      XPutPixel( XMesa->backimage, x[i], FLIP(y[i]), p );
  1519.       }
  1520.    }
  1521. }
  1522.  
  1523.  
  1524. /*
  1525.  * Write an array of PF_HPCR pixels to an XImage.
  1526.  */
  1527. static void write_pixels_HPCR_ximage( COLOR_PIXEL_ARGS )
  1528. {
  1529.    register GLuint i;
  1530.    for (i=0;i<n;i++) {
  1531.       if (mask[i]) {
  1532.          GLubyte *ptr = PIXELADDR1(x[i],y[i]);
  1533.          *ptr = DITHER_HPCR( x[i], y[i], red[i], green[i], blue[i] );
  1534.       }
  1535.    }
  1536. }
  1537.  
  1538.  
  1539. /*
  1540.  * Write an array of PF_LOOKUP pixels to an XImage.
  1541.  */
  1542. static void write_pixels_LOOKUP_ximage( COLOR_PIXEL_ARGS )
  1543. {
  1544.    register GLuint i;
  1545.    for (i=0;i<n;i++) {
  1546.       if (mask[i]) {
  1547.          register unsigned long p = LOOKUP( red[i], green[i], blue[i] );
  1548.      XPutPixel( XMesa->backimage, x[i], FLIP(y[i]), p );
  1549.       }
  1550.    }
  1551. }
  1552.  
  1553.  
  1554. /*
  1555.  * Write an array of PF_GRAYSCALE pixels to an XImage.
  1556.  */
  1557. static void write_pixels_GRAYSCALE_ximage( COLOR_PIXEL_ARGS )
  1558. {
  1559.    register GLuint i;
  1560.    for (i=0;i<n;i++) {
  1561.       if (mask[i]) {
  1562.      register unsigned long p = GRAY_RGB( red[i], green[i], blue[i] );
  1563.      XPutPixel( XMesa->backimage, x[i], FLIP(y[i]), p );
  1564.       }
  1565.    }
  1566. }
  1567.  
  1568.  
  1569. /*
  1570.  * Write an array of 8-bit PF_GRAYSCALE pixels to an XImage.
  1571.  */
  1572. static void write_pixels_GRAYSCALE8_ximage( COLOR_PIXEL_ARGS )
  1573. {
  1574.    register GLuint i;
  1575.    for (i=0;i<n;i++) {
  1576.       if (mask[i]) {
  1577.      GLubyte *ptr = PIXELADDR1( x[i], y[i] );
  1578.      *ptr = GRAY_RGB( red[i], green[i], blue[i] );
  1579.       }
  1580.    }
  1581. }
  1582.  
  1583.  
  1584.  
  1585.  
  1586. /**********************************************************************/
  1587. /*** Write MONO COLOR SPAN functions                                ***/
  1588. /**********************************************************************/
  1589.  
  1590. #define MONO_SPAN_ARGS  GLuint n, GLint x, GLint y, const GLubyte mask[]
  1591.  
  1592.  
  1593. /*
  1594.  * Write a span of identical pixels to a pixmap.  The pixel value is
  1595.  * the one set by DD.color() or DD.index().
  1596.  */
  1597. static void write_span_mono_pixmap( MONO_SPAN_ARGS )
  1598. {
  1599.    register GLuint i;
  1600.    register GLboolean write_all;
  1601.    y = FLIP( y );
  1602.    write_all = GL_TRUE;
  1603.    for (i=0;i<n;i++) {
  1604.       if (!mask[i]) {
  1605.      write_all = GL_FALSE;
  1606.      break;
  1607.       }
  1608.    }
  1609.    if (write_all) {
  1610.       XFillRectangle( XMesa->display, XMesa->buffer, XMesa->gc1,
  1611.               (int) x, (int) y, n, 1 );
  1612.    }
  1613.    else {
  1614.       for (i=0;i<n;i++,x++) {
  1615.      if (mask[i]) {
  1616.         XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc1,
  1617.                 (int) x, (int) y );
  1618.      }
  1619.       }
  1620.    }
  1621. }
  1622.  
  1623.  
  1624. /*
  1625.  * Write a span of PF_DITHER pixels to a pixmap.  The pixel value is
  1626.  * the one set by DD.color() or DD.index().
  1627.  */
  1628. static void write_span_mono_DITHER_pixmap( MONO_SPAN_ARGS )
  1629. {
  1630.    register GLuint i;
  1631.    register unsigned long p = XMesa->pixel;
  1632.    register GLubyte r, g, b;
  1633.    r = XMesa->red;
  1634.    g = XMesa->green;
  1635.    b = XMesa->blue;
  1636.    y = FLIP( y );
  1637.    for (i=0;i<n;i++,x++) {
  1638.       if (mask[i]) {
  1639.          p = DITHER( x, y, r, g, b );
  1640.          XSetForeground( XMesa->display, XMesa->gc2, p );
  1641.          XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  1642.                     (int) x, (int) y );
  1643.       }
  1644.    }
  1645. }
  1646.  
  1647.  
  1648. /*
  1649.  * Write a span of PF_1BIT pixels to a pixmap.  The pixel value is
  1650.  * the one set by DD.color() or DD.index().
  1651.  */
  1652. static void write_span_mono_1BIT_pixmap( MONO_SPAN_ARGS )
  1653. {
  1654.    register GLuint i;
  1655.    register unsigned long p = XMesa->pixel;
  1656.    register GLubyte r, g, b;
  1657.    r = XMesa->red;
  1658.    g = XMesa->green;
  1659.    b = XMesa->blue;
  1660.    y = FLIP( y );
  1661.    for (i=0;i<n;i++,x++) {
  1662.       if (mask[i]) {
  1663.          p = DITHER_1BIT( x, y, r, g, b );
  1664.          XSetForeground( XMesa->display, XMesa->gc2, p );
  1665.          XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  1666.                     (int) x, (int) y );
  1667.       }
  1668.    }
  1669. }
  1670.  
  1671.  
  1672. /*
  1673.  * Write a span of identical pixels to an XImage.  The pixel value is
  1674.  * the one set by DD.color() or DD.index().
  1675.  */
  1676. static void write_span_mono_ximage( MONO_SPAN_ARGS )
  1677. {
  1678.    register GLuint i;
  1679.    register unsigned long p = XMesa->pixel;
  1680.    y = FLIP( y );
  1681.    for (i=0;i<n;i++,x++) {
  1682.       if (mask[i]) {
  1683.      XPutPixel( XMesa->backimage, x, y, p );
  1684.       }
  1685.    }
  1686. }
  1687.  
  1688.  
  1689. /*
  1690.  * Write a span of identical 8A8B8G8R pixels to an XImage.  The pixel
  1691.  * value is the one set by DD.color().
  1692.  */
  1693. static void write_span_mono_8A8B8G8R_ximage( MONO_SPAN_ARGS )
  1694. {
  1695.    GLuint i, p, *ptr;
  1696.    p = (GLuint) XMesa->pixel;
  1697.    ptr = PIXELADDR4( x, y );
  1698.    for (i=0;i<n;i++,ptr++) {
  1699.       if (mask[i]) {
  1700.      *ptr = p;
  1701.       }
  1702.    }
  1703. }
  1704.  
  1705.  
  1706. /*
  1707.  * Write a span of identical 8R8G8B pixels to an XImage.  The pixel
  1708.  * value is the one set by DD.color().
  1709.  */
  1710. static void write_span_mono_8R8G8B_ximage( MONO_SPAN_ARGS )
  1711. {
  1712.    GLuint i, p, *ptr;
  1713.    p = (GLuint) XMesa->pixel;
  1714.    ptr = PIXELADDR4( x, y );
  1715.    for (i=0;i<n;i++,ptr++) {
  1716.       if (mask[i]) {
  1717.      *ptr = p;
  1718.       }
  1719.    }
  1720. }
  1721.  
  1722.  
  1723. /*
  1724.  * Write a span of identical DITHER pixels to an XImage.  The pixel
  1725.  * value is the one set by DD.color().
  1726.  */
  1727. static void write_span_mono_DITHER_ximage( MONO_SPAN_ARGS )
  1728. {
  1729.    register GLuint i;
  1730.    register GLubyte r, g, b;
  1731.    r = XMesa->red;
  1732.    g = XMesa->green;
  1733.    b = XMesa->blue;
  1734.    y = FLIP(y);
  1735.    for (i=0;i<n;i++,x++) {
  1736.       if (mask[i]) {
  1737.      unsigned long p = DITHER( x, y, r, g, b );
  1738.      XPutPixel( XMesa->backimage, x, y, p );
  1739.       }
  1740.    }
  1741. }
  1742.  
  1743.  
  1744. /*
  1745.  * Write a span of identical 8-bit DITHER pixels to an XImage.  The pixel
  1746.  * value is the one set by DD.color().
  1747.  */
  1748. static void write_span_mono_DITHER8_ximage( MONO_SPAN_ARGS )
  1749. {
  1750.    register GLuint i;
  1751.    register GLubyte *ptr = PIXELADDR1(x,y);
  1752.    register GLubyte r, g, b;
  1753.    r = XMesa->red;
  1754.    g = XMesa->green;
  1755.    b = XMesa->blue;
  1756.    for (i=0;i<n;i++,ptr++,x++) {
  1757.       if (mask[i]) {
  1758.      *ptr = DITHER( x, y, r, g, b );
  1759.       }
  1760.    }
  1761. }
  1762.  
  1763.  
  1764. /*
  1765.  * Write a span of identical PF_1BIT pixels to an XImage.  The pixel
  1766.  * value is the one set by DD.color().
  1767.  */
  1768. static void write_span_mono_1BIT_ximage( MONO_SPAN_ARGS )
  1769. {
  1770.    register GLuint i;
  1771.    register GLubyte r, g, b;
  1772.    r = XMesa->red;
  1773.    g = XMesa->green;
  1774.    b = XMesa->blue;
  1775.    y = FLIP(y);
  1776.    for (i=0;i<n;i++,x++) {
  1777.       if (mask[i]) {
  1778.      unsigned long p = DITHER_1BIT( x, y, r, g, b );
  1779.      XPutPixel( XMesa->backimage, x, y, p );
  1780.       }
  1781.    }
  1782. }
  1783.  
  1784.  
  1785. /*
  1786.  * Write a span of identical HPCR pixels to an XImage.  The pixel
  1787.  * value is the one set by DD.color().
  1788.  */
  1789. static void write_span_mono_HPCR_ximage( MONO_SPAN_ARGS )
  1790. {
  1791.    register GLuint i;
  1792.    register GLubyte *ptr = PIXELADDR1(x,y);
  1793.    register GLubyte r, g, b;
  1794.    r = XMesa->red;
  1795.    g = XMesa->green;
  1796.    b = XMesa->blue;
  1797.    for (i=0;i<n;i++,ptr++,x++) {
  1798.       if (mask[i]) {
  1799.          *ptr = DITHER_HPCR( x, y, r, g, b );
  1800.       }
  1801.    }
  1802. }
  1803.  
  1804.  
  1805.  
  1806. /*
  1807.  * Write a span of identical 8-bit GRAYSCALE pixels to an XImage.  The pixel
  1808.  * value is the one set by DD.color().
  1809.  */
  1810. static void write_span_mono_GRAYSCALE8_ximage( MONO_SPAN_ARGS )
  1811. {
  1812.    GLuint i;
  1813.    unsigned long p = XMesa->pixel;
  1814.    GLubyte *ptr = PIXELADDR1(x,y);
  1815.    for (i=0;i<n;i++,ptr++) {
  1816.       if (mask[i]) {
  1817.      *ptr = p;
  1818.       }
  1819.    }
  1820. }
  1821.  
  1822.  
  1823.  
  1824.  
  1825. /**********************************************************************/
  1826. /*** Write MONO COLOR PIXELS functions                              ***/
  1827. /**********************************************************************/
  1828.  
  1829. #define MONO_PIXEL_ARGS        GLuint n, const GLint x[], const GLint y[], \
  1830.                 const GLubyte mask[]
  1831.  
  1832. /*
  1833.  * Write an array of identical pixels to a pixmap.  The pixel value is
  1834.  * the one set by DD.color() or DD.index.
  1835.  */
  1836. static void write_pixels_mono_pixmap( MONO_PIXEL_ARGS )
  1837. {
  1838.    register GLuint i;
  1839.    for (i=0;i<n;i++) {
  1840.       if (mask[i]) {
  1841.      XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc1,
  1842.             (int) x[i], (int) FLIP(y[i]) );
  1843.       }
  1844.    }
  1845. }
  1846.  
  1847.  
  1848. /*
  1849.  * Write an array of PF_DITHER pixels to a pixmap.  The pixel value is
  1850.  * the one set by DD.color() or DD.index.
  1851.  */
  1852. static void write_pixels_mono_DITHER_pixmap( MONO_PIXEL_ARGS )
  1853. {
  1854.    register GLuint i;
  1855.    register GLubyte r, g, b;
  1856.    r = XMesa->red;
  1857.    g = XMesa->green;
  1858.    b = XMesa->blue;
  1859.    for (i=0;i<n;i++) {
  1860.       if (mask[i]) {
  1861.          unsigned long p = DITHER( x[i], y[i], r, g, b );
  1862.          XSetForeground( XMesa->display, XMesa->gc2, p );
  1863.      XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  1864.             (int) x[i], (int) FLIP(y[i]) );
  1865.       }
  1866.    }
  1867. }
  1868.  
  1869.  
  1870. /*
  1871.  * Write an array of PF_1BIT pixels to a pixmap.  The pixel value is
  1872.  * the one set by DD.color() or DD.index.
  1873.  */
  1874. static void write_pixels_mono_1BIT_pixmap( MONO_PIXEL_ARGS )
  1875. {
  1876.    register GLuint i;
  1877.    register GLubyte r, g, b;
  1878.    r = XMesa->red;
  1879.    g = XMesa->green;
  1880.    b = XMesa->blue;
  1881.    for (i=0;i<n;i++) {
  1882.       if (mask[i]) {
  1883.          unsigned long p = DITHER_1BIT( x[i], y[i], r, g, b );
  1884.          XSetForeground( XMesa->display, XMesa->gc2, p );
  1885.      XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2,
  1886.             (int) x[i], (int) FLIP(y[i]) );
  1887.       }
  1888.    }
  1889. }
  1890.  
  1891.  
  1892. /*
  1893.  * Write an array of identical pixels to an XImage.  The pixel value is
  1894.  * the one set by DD.color() or DD.index.
  1895.  */
  1896. static void write_pixels_mono_ximage( MONO_PIXEL_ARGS )
  1897. {
  1898.    register GLuint i;
  1899.    register unsigned long p = XMesa->pixel;
  1900.    for (i=0;i<n;i++) {
  1901.       if (mask[i]) {
  1902.      XPutPixel( XMesa->backimage, x[i], FLIP(y[i]), p );
  1903.       }
  1904.    }
  1905. }
  1906.  
  1907.  
  1908.  
  1909. /*
  1910.  * Write an array of identical 8A8B8G8R pixels to an XImage.  The pixel value
  1911.  * is the one set by DD.color().
  1912.  */
  1913. static void write_pixels_mono_8A8B8G8R_ximage( MONO_PIXEL_ARGS )
  1914. {
  1915.    register GLuint i;
  1916.    register GLuint p = (GLuint) XMesa->pixel;
  1917.    for (i=0;i<n;i++) {
  1918.       if (mask[i]) {
  1919.      GLuint *ptr = PIXELADDR4( x[i], y[i] );
  1920.      *ptr = p;
  1921.       }
  1922.    }
  1923. }
  1924.  
  1925.  
  1926. /*
  1927.  * Write an array of identical 8R8G8B pixels to an XImage.  The pixel value
  1928.  * is the one set by DD.color().
  1929.  */
  1930. static void write_pixels_mono_8R8G8B_ximage( MONO_PIXEL_ARGS )
  1931. {
  1932.    register GLuint i;
  1933.    register GLuint p = (GLuint) XMesa->pixel;
  1934.    for (i=0;i<n;i++) {
  1935.       if (mask[i]) {
  1936.      GLuint *ptr = PIXELADDR4( x[i], y[i] );
  1937.      *ptr = p;
  1938.       }
  1939.    }
  1940. }
  1941.  
  1942.  
  1943. /*
  1944.  * Write an array of identical PF_DITHER pixels to an XImage.  The pixel
  1945.  * value is the one set by DD.color().
  1946.  */
  1947. static void write_pixels_mono_DITHER_ximage( MONO_PIXEL_ARGS )
  1948. {
  1949.    register GLuint i;
  1950.    register GLubyte r, g, b;
  1951.    r = XMesa->red;
  1952.    g = XMesa->green;
  1953.    b = XMesa->blue;
  1954.    for (i=0;i<n;i++) {
  1955.       if (mask[i]) {
  1956.      unsigned long p = DITHER( x[i], y[i], r, g, b );
  1957.      XPutPixel( XMesa->backimage, x[i], FLIP(y[i]), p );
  1958.       }
  1959.    }
  1960. }
  1961.  
  1962.  
  1963. /*
  1964.  * Write an array of identical 8-bit PF_DITHER pixels to an XImage.  The
  1965.  * pixel value is the one set by DD.color().
  1966.  */
  1967. static void write_pixels_mono_DITHER8_ximage( MONO_PIXEL_ARGS )
  1968. {
  1969.    register GLuint i;
  1970.    register GLubyte r, g, b;
  1971.    r = XMesa->red;
  1972.    g = XMesa->green;
  1973.    b = XMesa->blue;
  1974.    for (i=0;i<n;i++) {
  1975.       if (mask[i]) {
  1976.      GLubyte *ptr = PIXELADDR1(x[i],y[i]);
  1977.      *ptr = DITHER( x[i], y[i], r, g, b );
  1978.       }
  1979.    }
  1980. }
  1981.  
  1982.  
  1983. /*
  1984.  * Write an array of identical PF_1BIT pixels to an XImage.  The pixel
  1985.  * value is the one set by DD.color().
  1986.  */
  1987. static void write_pixels_mono_1BIT_ximage( MONO_PIXEL_ARGS )
  1988. {
  1989.    register GLuint i;
  1990.    register GLubyte r, g, b;
  1991.    r = XMesa->red;
  1992.    g = XMesa->green;
  1993.    b = XMesa->blue;
  1994.    for (i=0;i<n;i++) {
  1995.       if (mask[i]) {
  1996.      unsigned long p = DITHER_1BIT( x[i], y[i], r, g, b );
  1997.      XPutPixel( XMesa->backimage, x[i], FLIP(y[i]), p );
  1998.       }
  1999.    }
  2000. }
  2001.  
  2002.  
  2003. /*
  2004.  * Write an array of identical PF_HPCR pixels to an XImage.  The
  2005.  * pixel value is the one set by DD.color().
  2006.  */
  2007. static void write_pixels_mono_HPCR_ximage( MONO_PIXEL_ARGS )
  2008. {
  2009.    register GLuint i;
  2010.    register GLubyte r, g, b;
  2011.    r = XMesa->red;
  2012.    g = XMesa->green;
  2013.    b = XMesa->blue;
  2014.    for (i=0;i<n;i++) {
  2015.       if (mask[i]) {
  2016.          GLubyte *ptr = PIXELADDR1(x[i],y[i]);
  2017.          *ptr = DITHER_HPCR( x[i], y[i], r, g, b );
  2018.       }
  2019.    }
  2020. }
  2021.  
  2022.  
  2023. /*
  2024.  * Write an array of identical 8-bit PF_GRAYSCALE pixels to an XImage.  The
  2025.  * pixel value is the one set by DD.color().
  2026.  */
  2027. static void write_pixels_mono_GRAYSCALE8_ximage( MONO_PIXEL_ARGS )
  2028. {
  2029.    register GLuint i;
  2030.    register unsigned long p = XMesa->pixel;
  2031.    for (i=0;i<n;i++) {
  2032.       if (mask[i]) {
  2033.      GLubyte *ptr = PIXELADDR1(x[i],y[i]);
  2034.      *ptr = p;
  2035.       }
  2036.    }
  2037. }
  2038.  
  2039.  
  2040.  
  2041.  
  2042. /**********************************************************************/
  2043. /*** Write INDEX SPAN functions                                     ***/
  2044. /**********************************************************************/
  2045.  
  2046. #define INDEX_SPAN_ARGS   GLuint n, GLint x, GLint y, const GLuint index[], \
  2047.               const GLubyte mask[]
  2048.  
  2049.  
  2050. /*
  2051.  * Write a span of CI pixels to a Pixmap.
  2052.  */
  2053. static void write_span_index_pixmap( INDEX_SPAN_ARGS )
  2054. {
  2055.    register GLuint i;
  2056.    y = FLIP(y);
  2057.    for (i=0;i<n;i++,x++) {
  2058.       if (mask[i]) {
  2059.      XSetForeground( XMesa->display, XMesa->gc2,
  2060.              (unsigned long) index[i] );
  2061.      XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2, (int) x, (int) y );
  2062.       }
  2063.    }
  2064. }
  2065.  
  2066.  
  2067. /*
  2068.  * Write a span of CI pixels to an XImage.
  2069.  */
  2070. static void write_span_index_ximage( INDEX_SPAN_ARGS )
  2071. {
  2072.    register GLuint i;
  2073.    y = FLIP(y);
  2074.    for (i=0;i<n;i++,x++) {
  2075.       if (mask[i]) {
  2076.      XPutPixel( XMesa->backimage, x, y, (unsigned long) index[i] );
  2077.       }
  2078.    }
  2079. }
  2080.  
  2081.  
  2082.  
  2083. /**********************************************************************/
  2084. /*** Write INDEX PIXELS functions                                   ***/
  2085. /**********************************************************************/
  2086.  
  2087. #define INDEX_PIXELS_ARGS    GLuint n, const GLint x[], const GLint y[], \
  2088.                 const GLuint index[], const GLubyte mask[]
  2089.  
  2090.  
  2091. /*
  2092.  * Write an array of CI pixels to a Pixmap.
  2093.  */
  2094. static void write_pixels_index_pixmap( INDEX_PIXELS_ARGS )
  2095. {
  2096.    register GLuint i;
  2097.    for (i=0;i<n;i++) {
  2098.       if (mask[i]) {
  2099.      XSetForeground( XMesa->display, XMesa->gc2,
  2100.              (unsigned long) index[i] );
  2101.      XDrawPoint( XMesa->display, XMesa->buffer, XMesa->gc2, 
  2102.              (int) x[i], (int) FLIP(y[i]) );
  2103.       }
  2104.    }
  2105. }
  2106.  
  2107.  
  2108. /*
  2109.  * Write an array of CI pixels to an XImage.
  2110.  */
  2111. static void write_pixels_index_ximage( INDEX_PIXELS_ARGS )
  2112. {
  2113.    register GLuint i;
  2114.    for (i=0;i<n;i++) {
  2115.       if (mask[i]) {
  2116.      XPutPixel( XMesa->backimage, x[i], FLIP(y[i]), (unsigned long) index[i] );
  2117.       }
  2118.    }
  2119. }
  2120.  
  2121.  
  2122.  
  2123.  
  2124. /**********************************************************************/
  2125. /*****                      Pixel reading                         *****/
  2126. /**********************************************************************/
  2127.  
  2128.  
  2129.  
  2130. /*
  2131.  * Read a horizontal span of color-index pixels.
  2132.  */
  2133. static void read_index_span( GLuint n, GLint x, GLint y, GLuint index[] )
  2134. {
  2135.    int i;
  2136.  
  2137.    y = FLIP(y);
  2138.  
  2139.    if (XMesa->buffer) {
  2140.       XImage *span;
  2141.       int error;
  2142.       catch_xgetimage_errors( XMesa->display );
  2143.       span = XGetImage( XMesa->display, XMesa->buffer,
  2144.                 x, y, n, 1, AllPlanes, ZPixmap );
  2145.       error = check_xgetimage_errors();
  2146.       if (span && !error) {
  2147.      for (i=0;i<n;i++) {
  2148.         index[i] = (GLuint) XGetPixel( span, i, 0 );
  2149.      }
  2150.       }
  2151.       else {
  2152.      /* return 0 pixels */
  2153.      for (i=0;i<n;i++) {
  2154.         index[i] = 0;
  2155.      }
  2156.       }
  2157.       if (span) {
  2158.      XDestroyImage( span );
  2159.       }
  2160.    }
  2161.    else if (XMesa->backimage) {
  2162.       for (i=0;i<n;i++,x++) {
  2163.      index[i] = (GLuint) XGetPixel( XMesa->backimage, x, y );
  2164.       }
  2165.    }
  2166. }
  2167.  
  2168.  
  2169.  
  2170. /*
  2171.  * Read a horizontal span of color pixels.
  2172.  */
  2173. static void read_color_span( GLuint n, GLint x, GLint y,
  2174.                              GLubyte red[], GLubyte green[],
  2175.                              GLubyte blue[], GLubyte alpha[] )
  2176. {
  2177.    register GLuint i;
  2178.  
  2179.    if (XMesa->buffer) {
  2180.       XImage *span;
  2181.       int error;
  2182.       catch_xgetimage_errors( XMesa->display );
  2183.       span = XGetImage( XMesa->display, XMesa->buffer,
  2184.                 x, FLIP(y), n, 1, AllPlanes, ZPixmap );
  2185.       error = check_xgetimage_errors();
  2186.       if (span && !error) {
  2187.      switch (XMesa->pixelformat) {
  2188.         case PF_TRUECOLOR:
  2189.                {
  2190.                   GLint rshift = XMesa->rshift, rmult = XMesa->rmult;
  2191.                   GLint gshift = XMesa->gshift, gmult = XMesa->gmult;
  2192.                   GLint bshift = XMesa->bshift, bmult = XMesa->bmult;
  2193.                   for (i=0;i<n;i++) {
  2194.                      unsigned long p = XGetPixel( span, i, 0 );
  2195.                      red[i]   = (GLubyte) ((p >> rshift) & rmult);
  2196.                      green[i] = (GLubyte) ((p >> gshift) & gmult);
  2197.                      blue[i]  = (GLubyte) ((p >> bshift) & bmult);
  2198.                      alpha[i] = 255;
  2199.                   }
  2200.                }
  2201.            break;
  2202.         case PF_8A8B8G8R:
  2203.                {
  2204.                   GLuint *ptr4 = (GLuint *) span->data;
  2205.                   for (i=0;i<n;i++) {
  2206.                      GLuint p4 = *ptr4++;
  2207.                      red[i]   = (GLubyte) ( p4        & 0xff);
  2208.                      green[i] = (GLubyte) ((p4 >> 8)  & 0xff);
  2209.                      blue[i]  = (GLubyte) ((p4 >> 16) & 0xff);
  2210.                      alpha[i] = (GLubyte) ((p4 >> 24) & 0xff);
  2211.                   }
  2212.            }
  2213.            break;
  2214.             case PF_8R8G8B:
  2215.                {
  2216.                   GLuint *ptr4 = (GLuint *) span->data;
  2217.                   for (i=0;i<n;i++) {
  2218.                      GLuint p4 = *ptr4++;
  2219.                      red[i]   = (GLubyte) ((p4 >> 16) & 0xff);
  2220.                      green[i] = (GLubyte) ((p4 >> 8)  & 0xff);
  2221.                      blue[i]  = (GLubyte) ( p4        & 0xff);
  2222.                      alpha[i] = 255;
  2223.                   }
  2224.            }
  2225.            break;
  2226.             case PF_5R6G5B:
  2227.                {
  2228.                   GLushort *ptr2 = (GLushort *) span->data;
  2229.                   for (i=0;i<n;i++) {
  2230.                      GLushort p2 = *ptr2++;
  2231.                      red[i]   = (GLubyte) ((p2 >> 11) & 0x1f);
  2232.                      green[i] = (GLubyte) ((p2 >> 5)  & 0x3f);
  2233.                      blue[i]  = (GLubyte) ( p2        & 0x1f);
  2234.                      alpha[i] = 255;
  2235.                   }
  2236.            }
  2237.                break;
  2238.             case PF_HPCR:
  2239.                {
  2240.                   GLubyte *ptr1 = (GLubyte *) span->data;
  2241.                   for (i=0;i<n;i++) {
  2242.                      GLubyte p = *ptr1++;
  2243.                      red[i]   =  p & 0xE0;
  2244.                      green[i] = (p & 0x1C) << 3;
  2245.                      blue[i]  = (p & 0x03) << 6;
  2246.                      alpha[i] = 255;
  2247.                   }
  2248.                }
  2249.                break;
  2250.         case PF_DITHER:
  2251.         case PF_LOOKUP:
  2252.         case PF_GRAYSCALE:
  2253.                {
  2254.                   GLubyte *red_table   = XMesa->pixel_to_r;
  2255.                   GLubyte *green_table = XMesa->pixel_to_g;
  2256.                   GLubyte *blue_table  = XMesa->pixel_to_b;
  2257.                   if (XMesa->depth==8) {
  2258.                      GLubyte *ptr1 = (GLubyte *) span->data;
  2259.                      for (i=0;i<n;i++) {
  2260.                         unsigned long p = *ptr1++;
  2261.                         red[i]   = red_table[p];
  2262.                         green[i] = green_table[p];
  2263.                         blue[i]  = blue_table[p];
  2264.                         alpha[i] = 255;
  2265.                      }
  2266.                   }
  2267.                   else {
  2268.                      for (i=0;i<n;i++) {
  2269.                         unsigned long p = XGetPixel( span, i, 0 );
  2270.                         red[i]   = red_table[p];
  2271.                         green[i] = green_table[p];
  2272.                         blue[i]  = blue_table[p];
  2273.                         alpha[i] = 255;
  2274.                      }
  2275.                   }
  2276.                }
  2277.            break;
  2278.         case PF_1BIT:
  2279.            for (i=0;i<n;i++) {
  2280.           unsigned long p = XGetPixel( span, i, 0 );
  2281.           red[i]   = (GLubyte) (p * 255);
  2282.           green[i] = (GLubyte) (p * 255);
  2283.           blue[i]  = (GLubyte) (p * 255);
  2284.           alpha[i] = 255;
  2285.            }
  2286.            break;
  2287.         default:
  2288.            die("Problem in DD.read_color_span (1)");
  2289.      }
  2290.       }
  2291.       else {
  2292.      /* return black pixels */
  2293.      for (i=0;i<n;i++) {
  2294.         red[i] = green[i] = blue[i] = alpha[i] = 0;
  2295.      }
  2296.       }
  2297.       if (span) {
  2298.      XDestroyImage( span );
  2299.       }
  2300.    }
  2301.    else if (XMesa->backimage) {
  2302.       switch (XMesa->pixelformat) {
  2303.      case PF_TRUECOLOR:
  2304.             {
  2305.                GLint rshift = XMesa->rshift, rmult = XMesa->rmult;
  2306.                GLint gshift = XMesa->gshift, gmult = XMesa->gmult;
  2307.                GLint bshift = XMesa->bshift, bmult = XMesa->bmult;
  2308.                y = FLIP(y);
  2309.                for (i=0;i<n;i++,x++) {
  2310.                   unsigned long p = XGetPixel( XMesa->backimage, x, y );
  2311.                   red[i]   = (GLubyte) ((p >> rshift) & rmult);
  2312.                   green[i] = (GLubyte) ((p >> gshift) & gmult);
  2313.                   blue[i]  = (GLubyte) ((p >> bshift) & bmult);
  2314.                   alpha[i] = 255;
  2315.                }
  2316.             }
  2317.         break;
  2318.      case PF_8A8B8G8R:
  2319.             {
  2320.                GLuint *ptr4 = PIXELADDR4( x, y );
  2321.                for (i=0;i<n;i++) {
  2322.                   GLuint p4 = *ptr4++;
  2323.                   red[i]   = (GLubyte) ( p4        & 0xff);
  2324.                   green[i] = (GLubyte) ((p4 >> 8)  & 0xff);
  2325.                   blue[i]  = (GLubyte) ((p4 >> 16) & 0xff);
  2326.                   alpha[i] = (GLint)   ((p4 >> 24) & 0xff);
  2327.                }
  2328.             }
  2329.         break;
  2330.      case PF_8R8G8B:
  2331.             {
  2332.                GLuint *ptr4 = PIXELADDR4( x, y );
  2333.                for (i=0;i<n;i++) {
  2334.                   GLuint p4 = *ptr4++;
  2335.                   red[i]   = (GLubyte) ((p4 >> 16) & 0xff);
  2336.                   green[i] = (GLubyte) ((p4 >> 8)  & 0xff);
  2337.                   blue[i]  = (GLubyte) ( p4        & 0xff);
  2338.                   alpha[i] = 255;
  2339.                }
  2340.             }
  2341.         break;
  2342.          case PF_5R6G5B:
  2343.             {
  2344.                GLushort *ptr2 = PIXELADDR2( x, y );
  2345.                for (i=0;i<n;i++) {
  2346.                   GLushort p2 = *ptr2++;
  2347.                   red[i]   = (GLubyte) ((p2 >> 11) & 0x1f);
  2348.                   green[i] = (GLubyte) ((p2 >> 5)  & 0x3f);
  2349.                   blue[i]  = (GLubyte) ( p2        & 0x1f);
  2350.                   alpha[i] = 255;
  2351.                }
  2352.             }
  2353.             break;
  2354.          case PF_HPCR:
  2355.             {
  2356.                GLubyte *ptr1 = PIXELADDR1( x, y );
  2357.                for (i=0;i<n;i++) {
  2358.                   GLubyte p = *ptr1++;
  2359.                   red[i]   =  p & 0xE0;
  2360.                   green[i] = (p & 0x1C) << 3;
  2361.                   blue[i]  = (p & 0x03) << 6;
  2362.                   alpha[i] = 255;
  2363.                }
  2364.             }
  2365.             break;
  2366.      case PF_DITHER:
  2367.      case PF_LOOKUP:
  2368.      case PF_GRAYSCALE:
  2369.             {
  2370.                GLubyte *red_table   = XMesa->pixel_to_r;
  2371.                GLubyte *green_table = XMesa->pixel_to_g;
  2372.                GLubyte *blue_table  = XMesa->pixel_to_b;
  2373.                if (XMesa->depth==8) {
  2374.                   GLubyte *ptr1 = PIXELADDR1(x,y);
  2375.                   for (i=0;i<n;i++) {
  2376.                      unsigned long p = *ptr1++;
  2377.                      red[i]   = red_table[p];
  2378.                      green[i] = green_table[p];
  2379.                      blue[i]  = blue_table[p];
  2380.                      alpha[i] = 255;
  2381.                   }
  2382.                }
  2383.                else {
  2384.                   y = FLIP(y);
  2385.                   for (i=0;i<n;i++,x++) {
  2386.                      unsigned long p = XGetPixel( XMesa->backimage, x, y );
  2387.                      red[i]   = red_table[p];
  2388.                      green[i] = green_table[p];
  2389.                      blue[i]  = blue_table[p];
  2390.                      alpha[i] = 255;
  2391.                   }
  2392.                }
  2393.             }
  2394.         break;
  2395.      case PF_1BIT:
  2396.             y = FLIP(y);
  2397.         for (i=0;i<n;i++,x++) {
  2398.            unsigned long p = XGetPixel( XMesa->backimage, x, y );
  2399.            red[i]   = (GLubyte) (p * 255);
  2400.            green[i] = (GLubyte) (p * 255);
  2401.            blue[i]  = (GLubyte) (p * 255);
  2402.            alpha[i] = 255;
  2403.         }
  2404.         break;
  2405.      default:
  2406.         die("Problem in DD.read_color_span (2)");
  2407.       }
  2408.    }
  2409. }
  2410.  
  2411.  
  2412.  
  2413. /*
  2414.  * Read an array of color index pixels.
  2415.  */
  2416. static void read_index_pixels( GLuint n, const GLint x[], const GLint y[],
  2417.                                GLuint indx[], const GLubyte mask[] )
  2418. {
  2419.    register GLuint i;
  2420.    if (XMesa->buffer) {
  2421.       for (i=0;i<n;i++) {
  2422.          if (mask[i]) {
  2423.             indx[i] = (GLuint) read_pixel( XMesa->display, XMesa->buffer,
  2424.                                            x[i], FLIP(y[i]) );
  2425.          }
  2426.       }
  2427.    }
  2428.    else if (XMesa->backimage) {
  2429.       for (i=0;i<n;i++) {
  2430.          if (mask[i]) {
  2431.             indx[i] = (GLuint) XGetPixel( XMesa->backimage, x[i], FLIP(y[i]) );
  2432.          }
  2433.       }
  2434.    }
  2435. }
  2436.  
  2437.  
  2438.  
  2439. static void read_color_pixels( GLuint n, const GLint x[], const GLint y[],
  2440.                                GLubyte red[], GLubyte green[],
  2441.                                GLubyte blue[], GLubyte alpha[],
  2442.                                const GLubyte mask[] )
  2443. {
  2444.    register GLuint i;
  2445.  
  2446.    if (XMesa->buffer) {
  2447.       switch (XMesa->pixelformat) {
  2448.      case PF_TRUECOLOR:
  2449.             {
  2450.                GLint rshift = XMesa->rshift, rmult = XMesa->rmult;
  2451.                GLint gshift = XMesa->gshift, gmult = XMesa->gmult;
  2452.                GLint bshift = XMesa->bshift, bmult = XMesa->bmult;
  2453.                for (i=0;i<n;i++) {
  2454.                   if (mask[i] ) {
  2455.                      unsigned long p = read_pixel( XMesa->display,
  2456.                                           XMesa->buffer, x[i], FLIP(y[i]) );
  2457.                      red[i]   = (GLubyte) ((p >> rshift) & rmult);
  2458.                      green[i] = (GLubyte) ((p >> gshift) & gmult);
  2459.                      blue[i]  = (GLubyte) ((p >> bshift) & bmult);
  2460.                      alpha[i] = 255;
  2461.                   }
  2462.                }
  2463.         }
  2464.         break;
  2465.      case PF_8A8B8G8R:
  2466.         for (i=0;i<n;i++) {
  2467.                if (mask[i]) {
  2468.                   unsigned long p = read_pixel( XMesa->display, XMesa->buffer,
  2469.                                                 x[i], FLIP(y[i]) );
  2470.                   red[i]   = (GLubyte) ( p        & 0xff);
  2471.                   green[i] = (GLubyte) ((p >> 8)  & 0xff);
  2472.                   blue[i]  = (GLubyte) ((p >> 16) & 0xff);
  2473.                   alpha[i] = (GLubyte) ((p >> 24) & 0xff);
  2474.                }
  2475.         }
  2476.         break;
  2477.      case PF_8R8G8B:
  2478.         for (i=0;i<n;i++) {
  2479.                if (mask[i]) {
  2480.                   unsigned long p = read_pixel( XMesa->display, XMesa->buffer,
  2481.                                                 x[i], FLIP(y[i]) );
  2482.                   red[i]   = (GLubyte) ((p >> 16) & 0xff);
  2483.                   green[i] = (GLubyte) ((p >> 8)  & 0xff);
  2484.                   blue[i]  = (GLubyte) ( p        & 0xff);
  2485.                   alpha[i] = 255;
  2486.                }
  2487.         }
  2488.         break;
  2489.          case PF_5R6G5B:
  2490.             for (i=0;i<n;i++) {
  2491.                if (mask[i]) {
  2492.                   unsigned long p = read_pixel( XMesa->display, XMesa->buffer,
  2493.                                                 x[i], FLIP(y[i]) );
  2494.                   red[i]   = (GLubyte) ((p >> 11) & 0x1f);
  2495.                   green[i] = (GLubyte) ((p >> 5)  & 0x3f);
  2496.                   blue[i]  = (GLubyte) ( p        & 0x1f);
  2497.                   alpha[i] = 255;
  2498.                }
  2499.             }
  2500.             break;
  2501.          case PF_HPCR:
  2502.             {
  2503.                for (i=0;i<n;i++) {
  2504.                   if (mask[i]) {
  2505.                      unsigned long p = read_pixel( XMesa->display,
  2506.                                           XMesa->buffer, x[i], FLIP(y[i]) );
  2507.                      red[i]   =  p & 0xE0;
  2508.                      green[i] = (p & 0x1C) << 3;
  2509.                      blue[i]  = (p & 0x03) << 6;
  2510.                      alpha[i] = 255;
  2511.                   }
  2512.                }
  2513.             }
  2514.             break;
  2515.      case PF_DITHER:
  2516.      case PF_LOOKUP:
  2517.      case PF_GRAYSCALE:
  2518.             {
  2519.                GLubyte *red_table   = XMesa->pixel_to_r;
  2520.                GLubyte *green_table = XMesa->pixel_to_g;
  2521.                GLubyte *blue_table  = XMesa->pixel_to_b;
  2522.                for (i=0;i<n;i++) {
  2523.                   if (mask[i]) {
  2524.                      unsigned long p = read_pixel( XMesa->display,
  2525.                                          XMesa->buffer, x[i], FLIP(y[i]) );
  2526.                      red[i]   = red_table[p];
  2527.                      green[i] = green_table[p];
  2528.                      blue[i]  = blue_table[p];
  2529.                      alpha[i] = 255;
  2530.                   }
  2531.                }
  2532.         }
  2533.         break;
  2534.      case PF_1BIT:
  2535.         for (i=0;i<n;i++) {
  2536.                if (mask[i]) {
  2537.                   unsigned long p = read_pixel( XMesa->display, XMesa->buffer,
  2538.                                                 x[i], FLIP(y[i]) );
  2539.                   red[i]   = (GLubyte) (p * 255);
  2540.                   green[i] = (GLubyte) (p * 255);
  2541.                   blue[i]  = (GLubyte) (p * 255);
  2542.                   alpha[i] = 255;
  2543.                }
  2544.         }
  2545.         break;
  2546.      default:
  2547.         die("Problem in DD.read_color_pixels (1)");
  2548.       }
  2549.    }
  2550.    else if (XMesa->backimage) {
  2551.       switch (XMesa->pixelformat) {
  2552.      case PF_TRUECOLOR:
  2553.             {
  2554.                GLint rshift = XMesa->rshift, rmult = XMesa->rmult;
  2555.                GLint gshift = XMesa->gshift, gmult = XMesa->gmult;
  2556.                GLint bshift = XMesa->bshift, bmult = XMesa->bmult;
  2557.                for (i=0;i<n;i++) {
  2558.                   if (mask[i]) {
  2559.                      unsigned long p;
  2560.                      p = XGetPixel( XMesa->backimage, x[i], FLIP(y[i]) );
  2561.                      red[i]   = (GLubyte) ((p >> rshift) & rmult);
  2562.                      green[i] = (GLubyte) ((p >> gshift) & gmult);
  2563.                      blue[i]  = (GLubyte) ((p >> bshift) & bmult);
  2564.                      alpha[i] = 255;
  2565.                   }
  2566.                }
  2567.         }
  2568.         break;
  2569.      case PF_8A8B8G8R:
  2570.         for (i=0;i<n;i++) {
  2571.            if (mask[i]) {
  2572.                   GLuint *ptr4 = PIXELADDR4( x[i], y[i] );
  2573.                   GLuint p4 = *ptr4;
  2574.                   red[i]   = (GLubyte) ( p4        & 0xff);
  2575.                   green[i] = (GLubyte) ((p4 >> 8)  & 0xff);
  2576.                   blue[i]  = (GLubyte) ((p4 >> 16) & 0xff);
  2577.                   alpha[i] = (GLubyte) ((p4 >> 24) & 0xff);
  2578.                }
  2579.         }
  2580.         break;
  2581.      case PF_8R8G8B:
  2582.         for (i=0;i<n;i++) {
  2583.            if (mask[i]) {
  2584.                   GLuint *ptr4 = PIXELADDR4( x[i], y[i] );
  2585.                   GLuint p4 = *ptr4;
  2586.                   red[i]   = (GLubyte) ((p4 >> 16) & 0xff);
  2587.                   green[i] = (GLubyte) ((p4 >> 8)  & 0xff);
  2588.                   blue[i]  = (GLubyte) ( p4        & 0xff);
  2589.                   alpha[i] = 255;
  2590.                }
  2591.         }
  2592.         break;
  2593.          case PF_5R6G5B:
  2594.             for (i=0;i<n;i++) {
  2595.                if (mask[i]) {
  2596.                   GLushort *ptr2 = PIXELADDR2( x[i], y[i] );
  2597.                   GLushort p2 = *ptr2;
  2598.                   red[i]   = (GLubyte) ((p2 >> 11) & 0x1f);
  2599.                   green[i] = (GLubyte) ((p2 >> 5)  & 0x3f);
  2600.                   blue[i]  = (GLubyte) ( p2        & 0x1f);
  2601.                   alpha[i] = 255;
  2602.                }
  2603.             }
  2604.             break;
  2605.          case PF_HPCR:
  2606.             for (i=0;i<n;i++) {
  2607.                if (mask[i]) {
  2608.                   GLubyte *ptr1 = PIXELADDR1( x[i], y[i] );
  2609.                   GLubyte p = *ptr1;
  2610.                   red[i]   =  p & 0xE0;
  2611.                   green[i] = (p & 0x1C) << 3;
  2612.                   blue[i]  = (p & 0x03) << 6;
  2613.                   alpha[i] = 255;
  2614.                }
  2615.             }
  2616.             break;
  2617.      case PF_DITHER:
  2618.      case PF_LOOKUP:
  2619.      case PF_GRAYSCALE:
  2620.             {
  2621.                GLubyte *red_table   = XMesa->pixel_to_r;
  2622.                GLubyte *green_table = XMesa->pixel_to_g;
  2623.                GLubyte *blue_table  = XMesa->pixel_to_b;
  2624.                for (i=0;i<n;i++) {
  2625.                   if (mask[i]) {
  2626.                      unsigned long p;
  2627.                      p = XGetPixel( XMesa->backimage, x[i], FLIP(y[i]) );
  2628.                      red[i]   = red_table[p];
  2629.                      green[i] = green_table[p];
  2630.                      blue[i]  = blue_table[p];
  2631.                      alpha[i] = 255;
  2632.                   }
  2633.                }
  2634.         }
  2635.         break;
  2636.      case PF_1BIT:
  2637.         for (i=0;i<n;i++) {
  2638.                if (mask[i]) {
  2639.                   unsigned long p;
  2640.                   p = XGetPixel( XMesa->backimage, x[i], FLIP(y[i]) );
  2641.                   red[i]   = (GLubyte) (p * 255);
  2642.                   green[i] = (GLubyte) (p * 255);
  2643.                   blue[i]  = (GLubyte) (p * 255);
  2644.                   alpha[i] = 255;
  2645.                }
  2646.         }
  2647.         break;
  2648.      default:
  2649.         die("Problem in DD.read_color_pixels (1)");
  2650.       }
  2651.    }
  2652. }
  2653.  
  2654.  
  2655.  
  2656.  
  2657. /*
  2658.  * Initialize all the DD.* function pointers depeding on the current
  2659.  * color buffer configuration.  This is mainly called by XMesaMakeCurrent.
  2660.  */
  2661. void xmesa_setup_DD_pointers( void )
  2662. {
  2663.  
  2664.    /*
  2665.     * Always the same:
  2666.     */
  2667.    DD.update_state = xmesa_setup_DD_pointers;
  2668.    DD.buffer_size = buffer_size;
  2669.    DD.flush = flush;
  2670.    DD.finish = finish;
  2671.  
  2672.    DD.set_buffer = set_buffer;
  2673.  
  2674.    DD.index = set_index;
  2675.    DD.color = set_color;
  2676.    DD.clear_index = clear_index;
  2677.    DD.clear_color = clear_color;
  2678.    DD.index_mask = index_mask;
  2679.    DD.color_mask = color_mask;
  2680.    DD.logicop = logicop;
  2681.    DD.dither = dither;
  2682.    DD.get_points_func = xmesa_get_points_func;
  2683.    DD.get_line_func = xmesa_get_line_func;
  2684.    DD.get_polygon_func = xmesa_get_polygon_func;
  2685.  
  2686.    /*
  2687.     * These drawing functions depend on current color buffer config:
  2688.     */
  2689.    if (XMesa->buffer!=XIMAGE) {
  2690.       /* Writing to window or back pixmap */
  2691.       DD.clear = clear_pixmap;
  2692.       switch (XMesa->pixelformat) {
  2693.      case PF_INDEX:
  2694.         DD.write_index_span       = write_span_index_pixmap;
  2695.         DD.write_monoindex_span   = write_span_mono_pixmap;
  2696.         DD.write_index_pixels     = write_pixels_index_pixmap;
  2697.         DD.write_monoindex_pixels = write_pixels_mono_pixmap;
  2698.         break;
  2699.      case PF_TRUECOLOR:
  2700.         DD.write_color_span       = write_span_TRUECOLOR_pixmap;
  2701.         DD.write_monocolor_span   = write_span_mono_pixmap;
  2702.         DD.write_color_pixels     = write_pixels_TRUECOLOR_pixmap;
  2703.         DD.write_monocolor_pixels = write_pixels_mono_pixmap;
  2704.         break;
  2705.      case PF_8A8B8G8R:
  2706.         DD.write_color_span       = write_span_8A8B8G8R_pixmap;
  2707.         DD.write_monocolor_span   = write_span_mono_pixmap;
  2708.         DD.write_color_pixels     = write_pixels_8A8B8G8R_pixmap;
  2709.         DD.write_monocolor_pixels = write_pixels_mono_pixmap;
  2710.         break;
  2711.      case PF_8R8G8B:
  2712.         DD.write_color_span       = write_span_8R8G8B_pixmap;
  2713.         DD.write_monocolor_span   = write_span_mono_pixmap;
  2714.         DD.write_color_pixels     = write_pixels_8R8G8B_pixmap;
  2715.         DD.write_monocolor_pixels = write_pixels_mono_pixmap;
  2716.         break;
  2717.      case PF_5R6G5B:
  2718.         DD.write_color_span       = write_span_5R6G5B_pixmap;
  2719.         DD.write_monocolor_span   = write_span_mono_pixmap;
  2720.         DD.write_color_pixels     = write_pixels_5R6G5B_pixmap;
  2721.         DD.write_monocolor_pixels = write_pixels_mono_pixmap;
  2722.         break;
  2723.      case PF_DITHER:
  2724.         DD.write_color_span       = write_span_DITHER_pixmap;
  2725.         DD.write_monocolor_span   = write_span_mono_DITHER_pixmap;
  2726.         DD.write_color_pixels     = write_pixels_DITHER_pixmap;
  2727.         DD.write_monocolor_pixels = write_pixels_mono_DITHER_pixmap;
  2728.         break;
  2729.      case PF_1BIT:
  2730.         DD.write_color_span       = write_span_1BIT_pixmap;
  2731.         DD.write_monocolor_span   = write_span_mono_1BIT_pixmap;
  2732.         DD.write_color_pixels     = write_pixels_1BIT_pixmap;
  2733.         DD.write_monocolor_pixels = write_pixels_mono_1BIT_pixmap;
  2734.         break;
  2735.          case PF_HPCR:
  2736.             DD.write_color_span       = write_span_HPCR_pixmap;
  2737.             DD.write_monocolor_span   = write_span_mono_pixmap;
  2738.             DD.write_color_pixels     = write_pixels_HPCR_pixmap;
  2739.             DD.write_monocolor_pixels = write_pixels_mono_pixmap;
  2740.             break;
  2741.          case PF_LOOKUP:
  2742.             DD.write_color_span       = write_span_LOOKUP_pixmap;
  2743.             DD.write_monocolor_span   = write_span_mono_pixmap;
  2744.             DD.write_color_pixels     = write_pixels_LOOKUP_pixmap;
  2745.             DD.write_monocolor_pixels = write_pixels_mono_pixmap;
  2746.             break;
  2747.          case PF_GRAYSCALE:
  2748.             DD.write_color_span       = write_span_GRAYSCALE_pixmap;
  2749.             DD.write_monocolor_span   = write_span_mono_pixmap;
  2750.             DD.write_color_pixels     = write_pixels_GRAYSCALE_pixmap;
  2751.             DD.write_monocolor_pixels = write_pixels_mono_pixmap;
  2752.             break;
  2753.      default:
  2754.         die("Bad pixel format in xmesa_setup_DD_pointers (1)");
  2755.       }
  2756.    }
  2757.    else if (XMesa->buffer==XIMAGE) {
  2758.       /* Writing to back XImage */
  2759.       if (sizeof(GLushort)!=2 || sizeof(GLuint)!=4) {
  2760.          /* Do this on Crays */
  2761.          DD.clear = clear_nbit_ximage;
  2762.       }
  2763.       else {
  2764.          /* Do this on most machines */
  2765.          switch (XMesa->backimage->bits_per_pixel) {
  2766.             case 8:
  2767.                DD.clear = clear_8bit_ximage;
  2768.                break;
  2769.             case 16:
  2770.                DD.clear = clear_16bit_ximage;
  2771.                break;
  2772.             case 32:
  2773.                DD.clear = clear_32bit_ximage;
  2774.                break;
  2775.             default:
  2776.                DD.clear = clear_nbit_ximage;
  2777.                break;
  2778.          }
  2779.       }
  2780.       switch (XMesa->pixelformat) {
  2781.      case PF_INDEX:
  2782.         DD.write_index_span       = write_span_index_ximage;
  2783.         DD.write_monoindex_span   = write_span_mono_ximage;
  2784.         DD.write_index_pixels     = write_pixels_index_ximage;
  2785.         DD.write_monoindex_pixels = write_pixels_mono_ximage;
  2786.         break;
  2787.      case PF_TRUECOLOR:
  2788.         /* Generic RGB */
  2789.         DD.write_color_span       = write_span_TRUECOLOR_ximage;
  2790.         DD.write_monocolor_span   = write_span_mono_ximage;
  2791.         DD.write_color_pixels     = write_pixels_TRUECOLOR_ximage;
  2792.         DD.write_monocolor_pixels = write_pixels_mono_ximage;
  2793.         break;
  2794.      case PF_8A8B8G8R:
  2795.         DD.write_color_span       = write_span_8A8B8G8R_ximage;
  2796.         DD.write_monocolor_span   = write_span_mono_8A8B8G8R_ximage;
  2797.         DD.write_color_pixels     = write_pixels_8A8B8G8R_ximage;
  2798.         DD.write_monocolor_pixels = write_pixels_mono_8A8B8G8R_ximage;
  2799.         break;
  2800.      case PF_8R8G8B:
  2801.         DD.write_color_span       = write_span_8R8G8B_ximage;
  2802.         DD.write_monocolor_span   = write_span_mono_8R8G8B_ximage;
  2803.         DD.write_color_pixels     = write_pixels_8R8G8B_ximage;
  2804.         DD.write_monocolor_pixels = write_pixels_mono_8R8G8B_ximage;
  2805.         break;
  2806.      case PF_5R6G5B:
  2807.         DD.write_color_span       = write_span_5R6G5B_ximage;
  2808.         DD.write_monocolor_span   = write_span_mono_ximage;
  2809.         DD.write_color_pixels     = write_pixels_5R6G5B_ximage;
  2810.         DD.write_monocolor_pixels = write_pixels_mono_ximage;
  2811.         break;
  2812.      case PF_DITHER:
  2813.         if (XMesa->depth==8) {
  2814.            DD.write_color_span       = write_span_DITHER8_ximage;
  2815.            DD.write_monocolor_span   = write_span_mono_DITHER8_ximage;
  2816.            DD.write_color_pixels     = write_pixels_DITHER8_ximage;
  2817.            DD.write_monocolor_pixels = write_pixels_mono_DITHER8_ximage;
  2818.         }
  2819.         else {
  2820.            DD.write_color_span       = write_span_DITHER_ximage;
  2821.            DD.write_monocolor_span   = write_span_mono_DITHER_ximage;
  2822.            DD.write_color_pixels     = write_pixels_DITHER_ximage;
  2823.            DD.write_monocolor_pixels = write_pixels_mono_DITHER_ximage;
  2824.         }
  2825.         break;
  2826.      case PF_1BIT:
  2827.         DD.write_color_span       = write_span_1BIT_ximage;
  2828.         DD.write_monocolor_span   = write_span_mono_1BIT_ximage;
  2829.         DD.write_color_pixels     = write_pixels_1BIT_ximage;
  2830.         DD.write_monocolor_pixels = write_pixels_mono_1BIT_ximage;
  2831.         break;
  2832.          case PF_HPCR:
  2833.             DD.write_color_span       = write_span_HPCR_ximage;
  2834.             DD.write_monocolor_span   = write_span_mono_HPCR_ximage;
  2835.             DD.write_color_pixels     = write_pixels_HPCR_ximage;
  2836.             DD.write_monocolor_pixels = write_pixels_mono_HPCR_ximage;
  2837.             break;
  2838.          case PF_LOOKUP:
  2839.             DD.write_color_span       = write_span_LOOKUP_ximage;
  2840.             DD.write_monocolor_span   = write_span_mono_ximage;
  2841.             DD.write_color_pixels     = write_pixels_LOOKUP_ximage;
  2842.             DD.write_monocolor_pixels = write_pixels_mono_ximage;
  2843.             break;
  2844.          case PF_GRAYSCALE:
  2845.         if (XMesa->depth==8) {
  2846.            DD.write_color_span       = write_span_GRAYSCALE8_ximage;
  2847.            DD.write_monocolor_span   = write_span_mono_GRAYSCALE8_ximage;
  2848.            DD.write_color_pixels     = write_pixels_GRAYSCALE8_ximage;
  2849.            DD.write_monocolor_pixels = write_pixels_mono_ximage;
  2850.         }
  2851.         else {
  2852.            DD.write_color_span       = write_span_GRAYSCALE_ximage;
  2853.            DD.write_monocolor_span   = write_span_mono_ximage;
  2854.            DD.write_color_pixels     = write_pixels_GRAYSCALE_ximage;
  2855.            DD.write_monocolor_pixels = write_pixels_mono_ximage;
  2856.         }
  2857.         break;
  2858.      default:
  2859.         die("Bad pixel format in xmesa_setup_DD_pointers (2)");
  2860.       }
  2861.    }
  2862.  
  2863.    /* Pixel/span reading functions: */
  2864.    DD.read_index_span = read_index_span;
  2865.    DD.read_color_span = read_color_span;
  2866.    DD.read_index_pixels = read_index_pixels;
  2867.    DD.read_color_pixels = read_color_pixels;
  2868. }
  2869.