home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 5 / MA_Cover_5.iso / ppc / mesa / src / xmesa3.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-31  |  19.7 KB  |  710 lines

  1. /* $Id: xmesa3.c,v 1.18 1997/06/20 02:56:52 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  2.3
  6.  * Copyright (C) 1995-1997  Brian Paul
  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: xmesa3.c,v $
  26.  * Revision 1.18  1997/06/20 02:56:52  brianp
  27.  * changed color components from GLfixed to GLubyte
  28.  *
  29.  * Revision 1.17  1997/05/26 20:34:57  brianp
  30.  * renamed PACK_RGB to PACK_TRUECOLOR
  31.  *
  32.  * Revision 1.16  1997/04/02 03:15:30  brianp
  33.  * replaced VB->Unclipped with VB->ClipMask
  34.  *
  35.  * Revision 1.15  1997/03/16 02:16:32  brianp
  36.  * moved PACK_8B8G8R macro to xmesaP.h
  37.  *
  38.  * Revision 1.14  1997/03/16 02:14:05  brianp
  39.  * moved triangle code to xmesa4.c
  40.  *
  41.  * Revision 1.13  1997/03/16 02:08:31  brianp
  42.  * now use linetemp.h in line drawing functions
  43.  *
  44.  * Revision 1.12  1997/01/31 23:45:19  brianp
  45.  * faster flat-shaded dithered triangles from code by Martin Schenk (schenkm@ping.at)
  46.  *
  47.  * Revision 1.11  1996/11/30 15:13:26  brianp
  48.  * added some parenthesis to WINCLIP macros
  49.  *
  50.  * Revision 1.10  1996/11/02 06:17:02  brianp
  51.  * removed some unused local vars
  52.  *
  53.  * Revision 1.9  1996/10/22 02:59:12  brianp
  54.  * incorporated Micheal Pichler's X line stipple patches
  55.  *
  56.  * Revision 1.8  1996/10/22 02:48:18  brianp
  57.  * now use DITHER_SETUP and XDITHER macros
  58.  * use array indexing instead of pointer dereferencing in inner loops
  59.  *
  60.  * Revision 1.7  1996/10/11 03:43:03  brianp
  61.  * add LineZoffset factor to window Z coords
  62.  *
  63.  * Revision 1.6  1996/10/01 03:31:30  brianp
  64.  * use new FixedToDepth() macro
  65.  *
  66.  * Revision 1.5  1996/09/27 01:31:54  brianp
  67.  * removed unused variables
  68.  *
  69.  * Revision 1.4  1996/09/25 02:02:59  brianp
  70.  * coordinates were incorrectly biased in flat_pixmap_triangle()
  71.  *
  72.  * Revision 1.3  1996/09/19 03:16:04  brianp
  73.  * new X/Mesa interface with XMesaContext, XMesaVisual, and XMesaBuffer types
  74.  *
  75.  * Revision 1.2  1996/09/15 14:21:43  brianp
  76.  * now use GLframebuffer and GLvisual
  77.  *
  78.  * Revision 1.1  1996/09/13 01:38:16  brianp
  79.  * Initial revision
  80.  *
  81.  */
  82.  
  83.  
  84. /*
  85.  * Mesa/X11 interface, part 3.
  86.  *
  87.  * This file contains "accelerated" point, line, and triangle functions.
  88.  * It should be fairly easy to write new special-purpose point, line or
  89.  * triangle functions and hook them into this module.
  90.  */
  91.  
  92.  
  93.  
  94. #include <sys/time.h>
  95. #include <assert.h>
  96. #include <stdlib.h>
  97. #include <stdio.h>
  98. #include <X11/Xlib.h>
  99. #include "depth.h"
  100. #include "macros.h"
  101. #include "vb.h"
  102. #include "types.h"
  103. #include "xmesaP.h"
  104.  
  105.  
  106.  
  107.  
  108. /**********************************************************************/
  109. /***                    Point rendering                             ***/
  110. /**********************************************************************/
  111.  
  112.  
  113. /*
  114.  * Render an array of points into a pixmap, any pixel format.
  115.  */
  116. static void draw_points_ANY_pixmap( GLcontext *ctx, GLuint first, GLuint last )
  117. {
  118.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  119.    Display *dpy = xmesa->xm_visual->display;
  120.    Drawable buffer = xmesa->xm_buffer->buffer;
  121.    GC gc = xmesa->xm_buffer->gc2;
  122.    struct vertex_buffer *VB = ctx->VB;
  123.    register GLuint i;
  124.  
  125.    if (VB->MonoColor) {
  126.       /* all same color */
  127.       XPoint p[VB_SIZE];
  128.       int n = 0;
  129.       for (i=first;i<=last;i++) {
  130.          if (VB->ClipMask[i]==0) {
  131.             p[n].x =       (GLint) VB->Win[i][0];
  132.             p[n].y = FLIP( (GLint) VB->Win[i][1] );
  133.             n++;
  134.          }
  135.       }
  136.       XDrawPoints( dpy, buffer, xmesa->xm_buffer->gc1, p, n, CoordModeOrigin );
  137.    }
  138.    else {
  139.       /* all different colors */
  140.       if (xmesa->xm_visual->gl_visual->RGBAflag) {
  141.          /* RGB mode */
  142.          for (i=first;i<=last;i++) {
  143.             if (VB->ClipMask[i]==0) {
  144.                register int x, y;
  145.                unsigned long pixel = xmesa_color_to_pixel( xmesa,
  146.                                                 VB->Color[i][0],
  147.                                                 VB->Color[i][1],
  148.                                                 VB->Color[i][2],
  149.                                                 VB->Color[i][3] );
  150.                XSetForeground( dpy, gc, pixel );
  151.                x =       (GLint) VB->Win[i][0];
  152.                y = FLIP( (GLint) VB->Win[i][1] );
  153.                XDrawPoint( dpy, buffer, gc, x, y);
  154.             }
  155.          }
  156.       }
  157.       else {
  158.          /* Color index mode */
  159.          for (i=first;i<=last;i++) {
  160.             if (VB->ClipMask[i]==0) {
  161.                register int x, y;
  162.                XSetForeground( dpy, gc, VB->Index[i] );
  163.                x =       (GLint) VB->Win[i][0];
  164.                y = FLIP( (GLint) VB->Win[i][1] );
  165.                XDrawPoint( dpy, buffer, gc, x, y);
  166.             }
  167.          }
  168.       }
  169.    }
  170. }
  171.  
  172.  
  173.  
  174. /*
  175.  * Analyze context state to see if we can provide a fast points drawing
  176.  * function, like those in points.c.  Otherwise, return NULL.
  177.  */
  178. points_func xmesa_get_points_func( GLcontext *ctx )
  179. {
  180.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  181.  
  182.    if (ctx->Point.Size==1.0F && !ctx->Point.SmoothFlag && ctx->RasterMask==0
  183.        && !ctx->Texture.Enabled) {
  184.       if (xmesa->xm_buffer->buffer==XIMAGE) {
  185.          return NULL; /*draw_points_ximage;*/
  186.       }
  187.       else {
  188.          return draw_points_ANY_pixmap;
  189.       }
  190.    }
  191.    else {
  192.       return NULL;
  193.    }
  194. }
  195.  
  196.  
  197.  
  198. /**********************************************************************/
  199. /***                      Line rendering                            ***/
  200. /**********************************************************************/
  201.  
  202. /*
  203.  * Render a line into a pixmap, any pixel format.
  204.  */
  205. static void flat_pixmap_line( GLcontext *ctx,
  206.                               GLuint vert0, GLuint vert1, GLuint pv )
  207. {
  208.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  209.    struct vertex_buffer *VB = ctx->VB;
  210.    register int x0, y0, x1, y1;
  211.    GC gc;
  212.    if (VB->MonoColor) {
  213.       gc = xmesa->xm_buffer->gc1;  /* use current color */
  214.    }
  215.    else {
  216.       unsigned long pixel;
  217.       if (xmesa->xm_visual->gl_visual->RGBAflag) {
  218.          pixel = xmesa_color_to_pixel( xmesa,
  219.                                        VB->Color[pv][0], VB->Color[pv][1],
  220.                                        VB->Color[pv][2], VB->Color[pv][3] );
  221.       }
  222.       else {
  223.          pixel = VB->Index[pv];
  224.       }
  225.       gc = xmesa->xm_buffer->gc2;
  226.       XSetForeground( xmesa->display, gc, pixel );
  227.    }
  228.    x0 =       (GLint) VB->Win[vert0][0];
  229.    y0 = FLIP( (GLint) VB->Win[vert0][1] );
  230.    x1 =       (GLint) VB->Win[vert1][0];
  231.    y1 = FLIP( (GLint) VB->Win[vert1][1] );
  232.    XDrawLine( xmesa->display, xmesa->xm_buffer->buffer, gc, x0, y0, x1, y1 );
  233. }
  234.  
  235.  
  236.  
  237. /*
  238.  * Draw a flat-shaded, PF_TRUECOLOR line into an XImage.
  239.  */
  240. static void flat_TRUECOLOR_line( GLcontext *ctx,
  241.                                  GLuint vert0, GLuint vert1, GLuint pv )
  242. {
  243.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  244.    GLubyte *color = ctx->VB->Color[pv];
  245.    XImage *img = xmesa->xm_buffer->backimage;
  246.    unsigned long pixel;
  247.    PACK_TRUECOLOR( pixel, color[0], color[1], color[2] );
  248.  
  249. #define INTERP_XY 1
  250. #define CLIP_HACK 1
  251. #define PLOT(X,Y) XPutPixel( img, X, FLIP(Y), pixel );
  252.  
  253. #include "linetemp.h"
  254. }
  255.  
  256.  
  257.  
  258. /*
  259.  * Draw a flat-shaded, PF_8A8B8G8R line into an XImage.
  260.  */
  261. static void flat_8A8B8G8R_line( GLcontext *ctx,
  262.                                 GLuint vert0, GLuint vert1, GLuint pv )
  263. {
  264.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  265.    GLubyte *color = ctx->VB->Color[pv];
  266.    GLuint pixel = PACK_8B8G8R( color[0], color[1], color[2] );
  267.  
  268. #define PIXEL_TYPE GLuint
  269. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  270. #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
  271. #define CLIP_HACK 1
  272. #define PLOT(X,Y) *pixelPtr = pixel;
  273.  
  274. #include "linetemp.h"
  275. }
  276.  
  277.  
  278. /*
  279.  * Draw a flat-shaded, PF_8R8G8B line into an XImage.
  280.  */
  281. static void flat_8R8G8B_line( GLcontext *ctx,
  282.                               GLuint vert0, GLuint vert1, GLuint pv )
  283. {
  284.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  285.    GLubyte *color = ctx->VB->Color[pv];
  286.    GLuint pixel = PACK_8R8G8B( color[0], color[1], color[2] );
  287.  
  288. #define PIXEL_TYPE GLuint
  289. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  290. #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
  291. #define CLIP_HACK 1
  292. #define PLOT(X,Y) *pixelPtr = pixel;
  293.  
  294. #include "linetemp.h"
  295. }
  296.  
  297.  
  298. /*
  299.  * Draw a flat-shaded, PF_5R6G5B line into an XImage.
  300.  */
  301. static void flat_5R6G5B_line( GLcontext *ctx,
  302.                               GLuint vert0, GLuint vert1, GLuint pv )
  303. {
  304.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  305.    GLubyte *color = ctx->VB->Color[pv];
  306.    GLushort pixel = PACK_5R6G5B( color[0], color[1], color[2] );
  307.  
  308. #define PIXEL_TYPE GLushort
  309. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  310. #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
  311. #define CLIP_HACK 1
  312. #define PLOT(X,Y) *pixelPtr = pixel;
  313.  
  314. #include "linetemp.h"
  315. }
  316.  
  317.  
  318.  
  319. /*
  320.  * Draw a flat-shaded, PF_DITHER 8-bit line into an XImage.
  321.  */
  322. static void flat_DITHER8_line( GLcontext *ctx,
  323.                                GLuint vert0, GLuint vert1, GLuint pv )
  324. {
  325.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  326.    GLubyte *color = ctx->VB->Color[pv];
  327.    GLint r = color[0], g = color[1], b = color[2];
  328.    DITHER_SETUP;
  329.  
  330. #define INTERP_XY 1
  331. #define PIXEL_TYPE GLubyte
  332. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  333. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  334. #define CLIP_HACK 1
  335. #define PLOT(X,Y) *pixelPtr = DITHER(X,Y,r,g,b);
  336.  
  337. #include "linetemp.h"
  338. }
  339.  
  340.  
  341. /*
  342.  * Draw a flat-shaded, PF_LOOKUP 8-bit line into an XImage.
  343.  */
  344. static void flat_LOOKUP8_line( GLcontext *ctx,
  345.                                GLuint vert0, GLuint vert1, GLuint pv )
  346. {
  347.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  348.    GLubyte *color = ctx->VB->Color[pv];
  349.    GLubyte pixel;
  350.    LOOKUP_SETUP;
  351.    pixel = LOOKUP( color[0], color[1], color[2] );
  352.  
  353. #define PIXEL_TYPE GLubyte
  354. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  355. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  356. #define CLIP_HACK 1
  357. #define PLOT(X,Y) *pixelPtr = pixel;
  358.  
  359. #include "linetemp.h"
  360. }
  361.  
  362.  
  363. /*
  364.  * Draw a flat-shaded, PF_HPCR line into an XImage.
  365.  */
  366. static void flat_HPCR_line( GLcontext *ctx,
  367.                             GLuint vert0, GLuint vert1, GLuint pv )
  368. {
  369.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  370.    GLubyte *color = ctx->VB->Color[pv];
  371.    GLint r = color[0], g = color[1], b = color[2];
  372.  
  373. #define INTERP_XY 1
  374. #define PIXEL_TYPE GLubyte
  375. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  376. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  377. #define CLIP_HACK 1
  378. #define PLOT(X,Y) *pixelPtr = DITHER_HPCR(X,Y,r,g,b);
  379.  
  380. #include "linetemp.h"
  381. }
  382.  
  383.  
  384.  
  385. /*
  386.  * Draw a flat-shaded, Z-less, PF_TRUECOLOR line into an XImage.
  387.  */
  388. static void flat_TRUECOLOR_z_line( GLcontext *ctx,
  389.                                    GLuint vert0, GLuint vert1, GLuint pv )
  390. {
  391.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  392.    GLubyte *color = ctx->VB->Color[pv];
  393.    XImage *img = xmesa->xm_buffer->backimage;
  394.    unsigned long pixel;
  395.    PACK_TRUECOLOR( pixel, color[0], color[1], color[2] );
  396.  
  397. #define INTERP_XY 1
  398. #define INTERP_Z 1
  399. #define CLIP_HACK 1
  400. #define PLOT(X,Y)                \
  401.     if (Z < *zPtr) {            \
  402.        *zPtr = Z;                \
  403.            XPutPixel( img, X, FLIP(Y), pixel );    \
  404.     }
  405.  
  406. #include "linetemp.h"
  407. }
  408.  
  409.  
  410. /*
  411.  * Draw a flat-shaded, Z-less, PF_8A8B8G8R line into an XImage.
  412.  */
  413. static void flat_8A8B8G8R_z_line( GLcontext *ctx,
  414.                                   GLuint vert0, GLuint vert1, GLuint pv )
  415. {
  416.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  417.    GLubyte *color = ctx->VB->Color[pv];
  418.    GLuint pixel = PACK_8B8G8R( color[0], color[1], color[2] );
  419.  
  420. #define INTERP_Z 1
  421. #define PIXEL_TYPE GLuint
  422. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  423. #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
  424. #define CLIP_HACK 1
  425. #define PLOT(X,Y)        \
  426.     if (Z < *zPtr) {    \
  427.        *zPtr = Z;        \
  428.        *pixelPtr = pixel;    \
  429.     }
  430.  
  431. #include "linetemp.h"
  432. }
  433.  
  434.  
  435. /*
  436.  * Draw a flat-shaded, Z-less, PF_8R8G8B line into an XImage.
  437.  */
  438. static void flat_8R8G8B_z_line( GLcontext *ctx,
  439.                                 GLuint vert0, GLuint vert1, GLuint pv )
  440. {
  441.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  442.    GLubyte *color = ctx->VB->Color[pv];
  443.    GLuint pixel = PACK_8R8G8B( color[0], color[1], color[2] );
  444.  
  445. #define INTERP_Z 1
  446. #define PIXEL_TYPE GLuint
  447. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  448. #define PIXEL_ADDRESS(X,Y) PIXELADDR4(X,Y)
  449. #define CLIP_HACK 1
  450. #define PLOT(X,Y)        \
  451.     if (Z < *zPtr) {    \
  452.        *zPtr = Z;        \
  453.        *pixelPtr = pixel;    \
  454.     }
  455.  
  456. #include "linetemp.h"
  457. }
  458.  
  459.  
  460. /*
  461.  * Draw a flat-shaded, Z-less, PF_5R6G5B line into an XImage.
  462.  */
  463. static void flat_5R6G5B_z_line( GLcontext *ctx,
  464.                                 GLuint vert0, GLuint vert1, GLuint pv )
  465. {
  466.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  467.    GLubyte *color = ctx->VB->Color[pv];
  468.    GLushort pixel = PACK_5R6G5B( color[0], color[1], color[2] );
  469.  
  470. #define INTERP_Z 1
  471. #define PIXEL_TYPE GLushort
  472. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  473. #define PIXEL_ADDRESS(X,Y) PIXELADDR2(X,Y)
  474. #define CLIP_HACK 1
  475. #define PLOT(X,Y)        \
  476.     if (Z < *zPtr) {    \
  477.        *zPtr = Z;        \
  478.        *pixelPtr = pixel;    \
  479.     }
  480. #include "linetemp.h"
  481. }
  482.  
  483.  
  484. /*
  485.  * Draw a flat-shaded, Z-less, PF_DITHER 8-bit line into an XImage.
  486.  */
  487. static void flat_DITHER8_z_line( GLcontext *ctx,
  488.                                  GLuint vert0, GLuint vert1, GLuint pv )
  489. {
  490.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  491.    GLubyte *color = ctx->VB->Color[pv];
  492.    GLint r = color[0], g = color[1], b = color[2];
  493.    DITHER_SETUP;
  494.  
  495. #define INTERP_XY 1
  496. #define INTERP_Z 1
  497. #define PIXEL_TYPE GLubyte
  498. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  499. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  500. #define CLIP_HACK 1
  501. #define PLOT(X,Y)                \
  502.     if (Z < *zPtr) {            \
  503.        *zPtr = Z;                \
  504.        *pixelPtr = DITHER( X, Y, r, g, b);    \
  505.     }
  506. #include "linetemp.h"
  507. }
  508.  
  509.  
  510. /*
  511.  * Draw a flat-shaded, Z-less, PF_LOOKUP 8-bit line into an XImage.
  512.  */
  513. static void flat_LOOKUP8_z_line( GLcontext *ctx,
  514.                                  GLuint vert0, GLuint vert1, GLuint pv )
  515. {
  516.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  517.    GLubyte *color = ctx->VB->Color[pv];
  518.    GLubyte pixel;
  519.    LOOKUP_SETUP;
  520.    pixel = LOOKUP( color[0], color[1], color[2] );
  521.  
  522. #define INTERP_Z 1
  523. #define PIXEL_TYPE GLubyte
  524. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  525. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  526. #define CLIP_HACK 1
  527. #define PLOT(X,Y)        \
  528.     if (Z < *zPtr) {    \
  529.        *zPtr = Z;        \
  530.        *pixelPtr = pixel;    \
  531.     }
  532.  
  533. #include "linetemp.h"
  534. }
  535.  
  536.  
  537. /*
  538.  * Draw a flat-shaded, Z-less, PF_HPCR line into an XImage.
  539.  */
  540. static void flat_HPCR_z_line( GLcontext *ctx,
  541.                               GLuint vert0, GLuint vert1, GLuint pv )
  542. {
  543.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  544.    GLubyte *color = ctx->VB->Color[pv];
  545.    GLint r = color[0], g = color[1], b = color[2];
  546.  
  547. #define INTERP_XY 1
  548. #define INTERP_Z 1
  549. #define PIXEL_TYPE GLubyte
  550. #define BYTES_PER_ROW (xmesa->xm_buffer->backimage->bytes_per_line)
  551. #define PIXEL_ADDRESS(X,Y) PIXELADDR1(X,Y)
  552. #define CLIP_HACK 1
  553. #define PLOT(X,Y)                    \
  554.     if (Z < *zPtr) {                \
  555.        *zPtr = Z;                    \
  556.        *pixelPtr = DITHER_HPCR( X, Y, r, g, b);    \
  557.     }
  558.  
  559. #include "linetemp.h"
  560. }
  561.  
  562.  
  563. /*
  564.  * Examine ctx->Line attributes and set xmesa->xm_buffer->gc1
  565.  * and xmesa->xm_buffer->gc2 appropriately.
  566.  */
  567. static void setup_x_line_options( GLcontext *ctx )
  568. {
  569.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  570.    int i, state, state0, new_state, len, offs;
  571.    int tbit;
  572.    char *dptr;
  573.    int n_segments = 0;
  574.    char dashes[20];
  575.    int line_width, line_style;
  576.  
  577.    /*** Line Stipple ***/
  578.    if (ctx->Line.StippleFlag) {
  579.       const int pattern = ctx->Line.StipplePattern;
  580.  
  581.       dptr = dashes;
  582.       state0 = state = ((pattern & 1) != 0);
  583.  
  584.       /* Decompose the pattern */
  585.       for (i=1,tbit=2,len=1;i<16;++i,tbit=(tbit<<1))
  586.     {
  587.       new_state = ((tbit & pattern) != 0);
  588.       if (state != new_state)
  589.         {
  590.           *dptr++ = ctx->Line.StippleFactor * len;
  591.           len = 1;
  592.           state = new_state;
  593.         }
  594.       else
  595.         ++len;
  596.     }
  597.       *dptr = ctx->Line.StippleFactor * len;
  598.       n_segments = 1 + (dptr - dashes);
  599.  
  600.       /* ensure an even no. of segments, or X may toggle on/off for consecutive patterns */
  601.       /* if (n_segments & 1)  dashes [n_segments++] = 0;  value of 0 not allowed in dash list */
  602.  
  603.       /* Handle case where line style starts OFF */
  604.       if (state0 == 0)
  605.         offs = dashes[0];
  606.       else
  607.         offs = 0;
  608.  
  609. #if 0
  610. fprintf (stderr, "input pattern: 0x%04x, offset %d, %d segments:", pattern, offs, n_segments);
  611. for (i = 0;  i < n_segments;  i++)
  612. fprintf (stderr, " %d", dashes[i]);
  613. fprintf (stderr, "\n");
  614. #endif
  615.  
  616.       XSetDashes( xmesa->display, xmesa->xm_buffer->gc1, offs, dashes, n_segments );
  617.       XSetDashes( xmesa->display, xmesa->xm_buffer->gc2, offs, dashes, n_segments );
  618.  
  619.       line_style = LineOnOffDash;
  620.    }
  621.    else {
  622.       line_style = LineSolid;
  623.    }
  624.  
  625.    /*** Line Width ***/
  626.    line_width = (int) (ctx->Line.Width+0.5F);
  627.    if (line_width < 2) {
  628.       /* Use fast lines when possible */
  629.       line_width = 0;
  630.    }
  631.  
  632.    /*** Set GC attributes ***/
  633.    XSetLineAttributes( xmesa->display, xmesa->xm_buffer->gc1,
  634.                        line_width, line_style, CapButt, JoinBevel);
  635.    XSetLineAttributes( xmesa->display, xmesa->xm_buffer->gc2,
  636.                        line_width, line_style, CapButt, JoinBevel);
  637.    XSetFillStyle( xmesa->display, xmesa->xm_buffer->gc1, FillSolid );
  638.    XSetFillStyle( xmesa->display, xmesa->xm_buffer->gc2, FillSolid );
  639. }
  640.  
  641.  
  642.  
  643. /*
  644.  * Analyze context state to see if we can provide a fast line drawing
  645.  * function, like those in lines.c.  Otherwise, return NULL.
  646.  */
  647. line_func xmesa_get_line_func( GLcontext *ctx )
  648. {
  649.    XMesaContext xmesa = (XMesaContext) ctx->DriverCtx;
  650.    int depth = xmesa->xm_visual->visinfo->depth;
  651.  
  652.    if (ctx->Line.SmoothFlag)              return NULL;
  653.    if (ctx->Texture.Enabled)              return NULL;
  654.    if (ctx->Light.ShadeModel!=GL_FLAT)    return NULL;
  655.  
  656.    if (xmesa->xm_buffer->buffer==XIMAGE
  657.        && ctx->RasterMask==DEPTH_BIT
  658.        && ctx->Depth.Func==GL_LESS
  659.        && ctx->Depth.Mask==GL_TRUE
  660.        && ctx->Line.Width==1.0F
  661.        && ctx->Line.StippleFlag==GL_FALSE) {
  662.       switch (xmesa->pixelformat) {
  663.          case PF_TRUECOLOR:
  664.             return flat_TRUECOLOR_z_line;
  665.          case PF_8A8B8G8R:
  666.             return flat_8A8B8G8R_z_line;
  667.          case PF_8R8G8B:
  668.             return flat_8R8G8B_z_line;
  669.          case PF_5R6G5B:
  670.             return flat_5R6G5B_z_line;
  671.          case PF_DITHER:
  672.             return (depth==8) ? flat_DITHER8_z_line : NULL;
  673.          case PF_LOOKUP:
  674.             return (depth==8) ? flat_LOOKUP8_z_line : NULL;
  675.          case PF_HPCR:
  676.             return flat_HPCR_z_line;
  677.          default:
  678.             return NULL;
  679.       }
  680.    }
  681.    if (xmesa->xm_buffer->buffer==XIMAGE
  682.        && ctx->RasterMask==0
  683.        && ctx->Line.Width==1.0F
  684.        && ctx->Line.StippleFlag==GL_FALSE) {
  685.       switch (xmesa->pixelformat) {
  686.          case PF_TRUECOLOR:
  687.             return flat_TRUECOLOR_line;
  688.          case PF_8A8B8G8R:
  689.             return flat_8A8B8G8R_line;
  690.          case PF_8R8G8B:
  691.             return flat_8R8G8B_line;
  692.          case PF_5R6G5B:
  693.             return flat_5R6G5B_line;
  694.          case PF_DITHER:
  695.             return (depth==8) ? flat_DITHER8_line : NULL;
  696.          case PF_LOOKUP:
  697.             return (depth==8) ? flat_LOOKUP8_line : NULL;
  698.          case PF_HPCR:
  699.             return flat_HPCR_line;
  700.      default:
  701.         return NULL;
  702.       }
  703.    }
  704.    if (xmesa->xm_buffer->buffer!=XIMAGE && ctx->RasterMask==0) {
  705.       setup_x_line_options( ctx );
  706.       return flat_pixmap_line;
  707.    }
  708.    return NULL;
  709. }
  710.