home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / mesa-1.2.8 / nt / mesagl32.c < prev    next >
C/C++ Source or Header  |  1996-05-27  |  35KB  |  1,490 lines

  1. /*
  2.     MesaGL32.c
  3. */
  4. #define MESAGL32_C
  5.  
  6. #include <windows.h>
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <mesagl/MesaGL32.h>
  10. #include "../../src/context.h"
  11. #include "../../src/dd.h"
  12. #include "../../src/xform.h"
  13. #include "../../src/vb.h"
  14. #ifdef PROFILE
  15. #include "../../src/profile.h"
  16. #endif
  17. #include "../../src/wmesadef.h"
  18. #include <wing.h>
  19.  
  20. /* Bit's used for dest: */
  21. #define FRONT_PIXMAP    1
  22. #define BACK_PIXMAP    2
  23. #define BACK_XIMAGE    4
  24.  
  25. static PWMC Current = NULL;
  26. WMesaContext WC = NULL;
  27.  
  28. #ifdef NDEBUG
  29.   #define assert(ignore)    ((void) 0)
  30. #else
  31.   void Mesa_Assert(void *Cond,void *File,unsigned Line)
  32.   {
  33.     char Msg[512];
  34.     sprintf(Msg,"%s %s %d",Cond,File,Line);
  35.     MessageBox(NULL,Msg,"Assertion failed.",MB_OK);
  36.     exit(1);
  37.   }
  38.   #define assert(e)    if (!e) Mesa_Assert(#e,__FILE__,__LINE__);
  39. #endif
  40.  
  41. #define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC)
  42. #define DD_RELEASEDC
  43.  
  44. #define BEGINGDICALL    if(Current->rgb_flag)wmFlushBits(Current);
  45. #define ENDGDICALL        if(Current->rgb_flag)wmGetBits(Current);
  46.  
  47. #define FLIP(Y)  (Current->height-(Y)-1)
  48.  
  49.  
  50. static void FlushToFile(PWMC pwc, PSTR    szFile);
  51.  
  52.  
  53. /* Finish all pending operations and synchronize. */
  54. static void finish(void)
  55. {
  56.    /* no op */
  57. }
  58.  
  59.  
  60. //
  61. // We cache all gl draw routines until a flush is made
  62. //
  63. static void flush(void)
  64. {
  65.     STARTPROFILE
  66.     if(Current->rgb_flag && !(Current->dib.fFlushed)){
  67.         wmFlush(Current);
  68.     }
  69.     ENDPROFILE(flush)
  70.    
  71. }
  72.  
  73.  
  74.  
  75. /*
  76.  * Set the color index used to clear the color buffer.
  77.  */
  78. static void clear_index(GLuint index)
  79. {
  80.     STARTPROFILE
  81.   Current->clearpixel = index;
  82.     ENDPROFILE(clear_index)
  83. }
  84.  
  85.  
  86.  
  87. /*
  88.  * Set the color used to clear the color buffer.
  89.  */
  90. static void clear_color( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
  91. {
  92.    STARTPROFILE
  93.   Current->clearpixel=RGB(r, g, b );
  94.   ENDPROFILE(clear_color)
  95. }
  96.  
  97.  
  98.  
  99. /*
  100.  * Clear the specified region of the color buffer using the clear color
  101.  * or index as specified by one of the two functions above.
  102.  */
  103. static void clear(GLboolean all,GLint x, GLint y, GLint width, GLint height )
  104. {
  105.     STARTPROFILE
  106.     DWORD    dwColor;    
  107.     WORD    wColor;
  108.     LPDWORD    lpdw = (LPDWORD)Current->pbPixels;
  109.     LPWORD    lpw = (LPWORD)Current->pbPixels;
  110.     LPBYTE    lpb;
  111.     BYTE    bPix[12];
  112.     LPBYTE    lpb = Current->pbPixels;
  113.  
  114.     if (all){
  115.         x=y=0;
  116.         width=Current->width;
  117.         height=Current->height;
  118.     }
  119.     if (Current->rgb_flag==GL_TRUE){
  120.         UINT    nBypp = Current->cColorBits / 8;
  121.         int        i = 0;
  122.         int        iSize;
  123.  
  124.         if(nBypp == 2){
  125.             iSize = (Current->width * Current->height) / nBypp;
  126.  
  127.             wColor = BGR16(GetRValue(Current->clearpixel), 
  128.                            GetGValue(Current->clearpixel), 
  129.                            GetBValue(Current->clearpixel));
  130.             dwColor = MAKELONG(wColor, wColor);
  131.         }
  132.         else if nBypp == 4{
  133.             iSize = (Current->width * Current->height);
  134.  
  135.             dwColor = BGR32(GetRValue(Current->clearpixel), 
  136.                            GetGValue(Current->clearpixel), 
  137.                            GetBValue(Current->clearpixel));
  138.         }
  139.         //
  140.         // This is the 24bit case
  141.         //
  142.         else {
  143.  
  144.             iSize = (Current->width * Current->height) / nBypp;
  145.  
  146.             dwColor = BGR24(GetRValue(Current->clearpixel), 
  147.                            GetGValue(Current->clearpixel), 
  148.                            GetBValue(Current->clearpixel));
  149.  
  150.  
  151.             while(i < iSize){
  152.                 *lpdw = dwColor;
  153.                 lpb += nBypp;
  154.                 lpdw = (LPDWORD)lpb;
  155.                 i++;
  156.             }
  157.  
  158.             ENDPROFILE(clear)
  159.  
  160.             return;
  161.         }
  162.  
  163.         while(i < iSize){
  164.             *lpdw = dwColor;
  165.             lpdw++;
  166.             i++;
  167.         }
  168.     }
  169.  
  170.     else {
  171.         int i;
  172.         char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
  173.         for (i=0; i<height; i++){
  174.             memset(Mem,Current->clearpixel,width);
  175.             Mem+=width;
  176.         }
  177.     }
  178.  
  179.     ENDPROFILE(clear)
  180. }
  181.  
  182.  
  183.  
  184. /* Set the current color index. */
  185. static void set_index(GLuint index)
  186. {
  187.    STARTPROFILE
  188.   Current->pixel=index;
  189.    ENDPROFILE(set_index)
  190. }
  191.  
  192.  
  193.  
  194. /* Set the current RGBA color. */
  195. static void set_color( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
  196. {
  197.    STARTPROFILE
  198.   Current->pixel = RGB( r, g, b );
  199.    ENDPROFILE(set_color)
  200. }
  201.  
  202.  
  203.  
  204. /* Set the index mode bitplane mask. */
  205. static GLboolean index_mask(GLuint mask)
  206. {
  207.    /* can't implement */
  208.    return GL_FALSE;
  209. }
  210.  
  211.  
  212.  
  213. /* Set the RGBA drawing mask. */
  214. static GLboolean color_mask( GLboolean rmask, GLboolean gmask,
  215.                              GLboolean bmask, GLboolean amask)
  216. {
  217.    /* can't implement */
  218.    return GL_FALSE;
  219. }
  220.  
  221.  
  222.  
  223. /*
  224.  * Set the pixel logic operation.  Return GL_TRUE if the device driver
  225.  * can perform the operation, otherwise return GL_FALSE.  If GL_FALSE
  226.  * is returned, the logic op will be done in software by Mesa.
  227.  */
  228. GLboolean logicop( GLenum op )
  229. {
  230.    /* can't implement */
  231.    return GL_FALSE;
  232. }
  233.  
  234.  
  235. static void dither( GLboolean enable )
  236. {
  237.    /* No op */
  238. }
  239.  
  240.  
  241.  
  242. static GLboolean set_buffer( GLenum mode )
  243. {
  244.    STARTPROFILE
  245.    /* TODO: this could be better */
  246.    if (mode==GL_FRONT || mode==GL_BACK) {
  247.       return GL_TRUE;
  248.    }
  249.    else {
  250.       return GL_FALSE;
  251.    }
  252.    ENDPROFILE(set_buffer)
  253. }
  254.  
  255.  
  256.  
  257. /* Return characteristics of the output buffer. */
  258. static void buffer_size( GLuint *width, GLuint *height, GLuint *depth )
  259. {
  260.     STARTPROFILE
  261.     int New_Size;
  262.     RECT CR;
  263.     
  264.     GetClientRect(Current->Window,&CR);
  265.  
  266.     *width=CR.right;
  267.     *height=CR.bottom;
  268.     *depth = Current->depth;
  269.  
  270.     New_Size=((*width)!=Current->width) || ((*height)!=Current->height);
  271.  
  272.     if (New_Size){
  273.         Current->width=*width;
  274.         Current->ScanWidth=Current->width;
  275.         Current->height=*height;
  276.  
  277.         if (Current->db_flag){
  278.             if (Current->rgb_flag==GL_TRUE){
  279.                 wmDeleteBackingStore(Current);
  280.                 wmCreateBackingStore(Current, Current->width, current->height);
  281.             }
  282.             else{
  283.                 Current->IndexFormat->bmiHeader.biWidth=Current->width;
  284.  
  285.                 if (Current->IndexFormat->bmiHeader.biHeight<0)
  286.                     Current->IndexFormat->bmiHeader.biHeight=-Current->height;
  287.                 else
  288.                     Current->IndexFormat->bmiHeader.biHeight=Current->height;
  289.  
  290.                 Current->Compat_BM=WinGCreateBitmap(Current->dib.hDC,Current->IndexFormat,&((void *) Current->ScreenMem));
  291.  
  292.                 DeleteObject(SelectObject(Current->dib.hDC,Current->Compat_BM));
  293.             }
  294.         }
  295.     }
  296.  
  297.     ENDPROFILE(buffer_size)
  298. }
  299.  
  300.  
  301.  
  302. /**********************************************************************/
  303. /*****           Accelerated point, line, polygon rendering       *****/
  304. /**********************************************************************/
  305.  
  306.  
  307. static void fast_rgb_points( GLuint first, GLuint last )
  308. {
  309.    STARTPROFILE
  310.    GLuint i;
  311.    HDC DC=DD_GETDC;
  312.     PWMC    pwc = Current;
  313.    if (VB.MonoColor) {
  314.       /* all drawn with current color */
  315.       for (i=first;i<=last;i++) {
  316.          if (VB.Unclipped[i]) {
  317.             int x, y;
  318.             x =       (GLint) VB.Win[i][0];
  319.             y = FLIP( (GLint) VB.Win[i][1] );
  320.             wmSetPixel(pwc, y,x,GetRValue(Current->pixel), 
  321.                         GetGValue(Current->pixel), GetBValue(Current->pixel));
  322.          }
  323.       }
  324.    }
  325.    else {
  326.       /* draw points of different colors */
  327.       for (i=first;i<=last;i++) {
  328.          if (VB.Unclipped[i]) {
  329.             int x, y;
  330.             unsigned long pixel=RGB(VB.Color[i][0]*255.0,
  331.                                     VB.Color[i][1]*255.0,
  332.                                     VB.Color[i][2]*255.0);
  333.             x =       (GLint) VB.Win[i][0];
  334.             y = FLIP( (GLint) VB.Win[i][1] );
  335.             wmSetPixel(pwc, y,x,VB.Color[i][0]*255.0, 
  336.                                     VB.Color[i][1]*255.0,
  337.                                     VB.Color[i][2]*255.0);
  338.          }
  339.       }
  340.    }
  341.    DD_RELEASEDC;
  342.    ENDPROFILE(fast_rgb_points)
  343. }
  344.  
  345.  
  346.  
  347. /* Return pointer to accerated points function */
  348. static points_func choose_points_function( void )
  349. {
  350.    STARTPROFILE
  351.    if (CC.Point.Size==1.0 && !CC.Point.SmoothFlag && CC.RasterMask==0
  352.        && !CC.Texture.Enabled  && Current->rgb_flag) {
  353.    ENDPROFILE(choose_points_function)
  354.       return fast_rgb_points;
  355.    }
  356.    else {
  357.    ENDPROFILE(choose_points_function)
  358.       return NULL;
  359.    }
  360. }
  361.  
  362.  
  363.  
  364. /* Draw a line using the color specified by VB.Color[pv] */
  365. static void fast_flat_rgb_line( GLuint v0, GLuint v1, GLuint pv )
  366. {
  367.     STARTPROFILE
  368.     int x0, y0, x1, y1;
  369.     unsigned long pixel;
  370.     HDC DC=DD_GETDC;
  371.     HPEN Pen;
  372.     HPEN Old_Pen;
  373.  
  374.     if (VB.MonoColor) {
  375.       pixel = Current->pixel;  /* use current color */
  376.     }
  377.     else {
  378.       pixel = RGB(VB.Color[pv][0]*255.0, VB.Color[pv][1]*255.0, VB.Color[pv][2]*255.0);
  379.     }
  380.  
  381.     x0 =       (int) VB.Win[v0][0];
  382.     y0 = FLIP( (int) VB.Win[v0][1] );
  383.     x1 =       (int) VB.Win[v1][0];
  384.     y1 = FLIP( (int) VB.Win[v1][1] );
  385.  
  386.  
  387.     BEGINGDICALL
  388.  
  389.     Pen=CreatePen(PS_SOLID,1,pixel);
  390.     Old_Pen=SelectObject(DC,Pen);
  391.     MoveToEx(DC,x0,y0,NULL);
  392.     LineTo(DC,x1,y1);
  393.     SelectObject(DC,Old_Pen);
  394.     DeleteObject(Pen);
  395.     DD_RELEASEDC;
  396.  
  397.     ENDGDICALL
  398.  
  399.     ENDPROFILE(fast_flat_rgb_line)
  400. }
  401.  
  402.  
  403.  
  404. /* Return pointer to accerated line function */
  405. static line_func choose_line_function( void )
  406. {
  407.    STARTPROFILE
  408.    if (CC.Line.Width==1.0 && !CC.Line.SmoothFlag && !CC.Line.StippleFlag
  409.        && CC.Light.ShadeModel==GL_FLAT && CC.RasterMask==0
  410.        && !CC.Texture.Enabled && Current->rgb_flag) {
  411.    ENDPROFILE(choose_line_function)
  412.       return fast_flat_rgb_line;
  413.    }
  414.    else {
  415.    ENDPROFILE(choose_line_function)
  416.       return NULL;
  417.    }
  418. }
  419.  
  420.  
  421. /* Draw a convex polygon using color VB.Color[pv] */
  422. static void fast_flat_rgb_polygon( GLuint n, GLuint vlist[], GLuint pv )
  423. {
  424.    STARTPROFILE
  425.    POINT *Pts=(POINT *) malloc(n*sizeof(POINT));
  426.    HDC DC=DD_GETDC;
  427.    HPEN Pen;
  428.    HBRUSH Brush;
  429.    HPEN Old_Pen;
  430.    HBRUSH Old_Brush;
  431.    GLint pixel;
  432.    GLuint i;
  433.  
  434.    if (VB.MonoColor) {
  435.       pixel = Current->pixel;  /* use current color */
  436.    }
  437.    else {
  438.       pixel = RGB(VB.Color[pv][0]*255.0, VB.Color[pv][1]*255.0, VB.Color[pv][2]*255.0);
  439.    }
  440.  
  441.    Pen=CreatePen(PS_SOLID,1,pixel);
  442.    Brush=CreateSolidBrush(pixel);
  443.    Old_Pen=SelectObject(DC,Pen);
  444.    Old_Brush=SelectObject(DC,Brush);
  445.  
  446.    for (i=0; i<n; i++) {
  447.       int j = vlist[i];
  448.       Pts[i].x =       (int) VB.Win[j][0];
  449.       Pts[i].y = FLIP( (int) VB.Win[j][1] );
  450.    }
  451.  
  452.    BEGINGDICALL
  453.  
  454.    Polygon(DC,Pts,n);
  455.    SelectObject(DC,Old_Pen);
  456.    SelectObject(DC,Old_Brush);
  457.    DeleteObject(Pen);
  458.    DeleteObject(Brush);
  459.    DD_RELEASEDC;
  460.    free(Pts);
  461.  
  462.    ENDGDICALL
  463.  
  464.    ENDPROFILE(fast_flat_rgb_polygon)
  465. }
  466.  
  467.  
  468.  
  469. /* Return pointer to accerated polygon function */
  470. static polygon_func choose_polygon_function( void )
  471. {
  472.    STARTPROFILE
  473.    if (!CC.Polygon.SmoothFlag && !CC.Polygon.StippleFlag
  474.        && CC.Light.ShadeModel==GL_FLAT && CC.RasterMask==0
  475.        && !CC.Texture.Enabled && Current->rgb_flag==GL_TRUE) {
  476.    ENDPROFILE(choose_polygon_function)
  477.       return fast_flat_rgb_polygon;
  478.    }
  479.    else {
  480.    ENDPROFILE(choose_polygon_function)
  481.       return NULL;
  482.    }
  483. }
  484.  
  485.  
  486.  
  487. /**********************************************************************/
  488. /*****                 Span-based pixel drawing                   *****/
  489. /**********************************************************************/
  490.  
  491.  
  492. /* Write a horizontal span of color-index pixels with a boolean mask. */
  493. static void write_index_span( GLuint n, GLint x, GLint y,
  494.                               const GLuint index[],
  495.                               const GLubyte mask[] )
  496. {
  497.    STARTPROFILE
  498.   GLuint i;
  499.   char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
  500.   assert(Current->rgb_flag==GL_FALSE);
  501.   for (i=0; i<n; i++)
  502.     if (mask[i])
  503.       Mem[i]=index[i];
  504.    ENDPROFILE(write_index_span)
  505. }
  506.  
  507.  
  508.  
  509. /*
  510.  * Write a horizontal span of pixels with a boolean mask.  The current
  511.  * color index is used for all pixels.
  512.  */
  513. static void write_monoindex_span(GLuint n,GLint x,GLint y,const GLubyte mask[])
  514. {
  515.    STARTPROFILE
  516.   GLuint i;
  517.   char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
  518.   assert(Current->rgb_flag==GL_FALSE);
  519.   for (i=0; i<n; i++)
  520.     if (mask[i])
  521.       Mem[i]=Current->pixel;
  522.    ENDPROFILE(write_monoindex_span)
  523. }
  524.  
  525. /*
  526.     To improve the performance of this routine, frob the data into an actual scanline
  527.     and call bitblt on the complete scan line instead of SetPixel.
  528. */
  529.  
  530. /* Write a horizontal span of color pixels with a boolean mask. */
  531. static void write_color_span( GLuint n, GLint x, GLint y,
  532.               const GLubyte
  533.               red[], const GLubyte green[],
  534.               const GLubyte blue[], const GLubyte alpha[],
  535.               const GLubyte mask[] )
  536. {
  537.     STARTPROFILE
  538.  
  539.     PWMC    pwc = Current;
  540.  
  541.     if (pwc->rgb_flag==GL_TRUE)
  542.     {
  543.         GLuint i;
  544.         HDC DC=DD_GETDC;
  545.         y=FLIP(y);
  546.  
  547.         if (mask) {
  548.             for (i=0; i<n; i++)
  549.                 if (mask[i])
  550.                     wmSetPixel(pwc, y, x + i,red[i], green[i], blue[i]);
  551.         }
  552.  
  553.         else {
  554.             for (i=0; i<n; i++)
  555.                 wmSetPixel(pwc, y, x + i, red[i], green[i], blue[i]);
  556.         }
  557.  
  558.         DD_RELEASEDC;
  559.  
  560.     }
  561.  
  562.   else
  563.   {
  564.     GLuint i;
  565.     char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
  566.     if (mask) {
  567.        for (i=0; i<n; i++)
  568.          if (mask[i])
  569.            Mem[i]=GetNearestPaletteIndex(Current->hPal,RGB(red[i],green[i],blue[i]));
  570.     }
  571.     else {
  572.        for (i=0; i<n; i++)
  573.          Mem[i]=GetNearestPaletteIndex(Current->hPal,RGB(red[i],green[i],blue[i]));
  574.     }
  575.   }
  576.    ENDPROFILE(write_color_span)
  577.  
  578. }
  579.  
  580. /*
  581.  * Write a horizontal span of pixels with a boolean mask.  The current color
  582.  * is used for all pixels.
  583.  */
  584. static void write_monocolor_span( GLuint n, GLint x, GLint y,const GLubyte mask[])
  585. {
  586.    STARTPROFILE
  587.   GLuint i;
  588.   HDC DC=DD_GETDC;
  589.   assert(Current->rgb_flag==GL_TRUE);
  590.   y=FLIP(y);
  591.  
  592.   if(Current->rgb_flag==GL_TRUE){
  593.       for (i=0; i<n; i++)
  594.         if (mask[i])
  595.           wmSetPixel(DC,x+i,y,GetRValue(Current->pixel), GetGValue(Current->pixel), GetBValue(Current->pixel));
  596.   }
  597.   else {
  598.       for (i=0; i<n; i++)
  599.         if (mask[i])
  600.             SetPixel(DC, y, x+i, Current->pixel);
  601.   }
  602.  
  603.     DD_RELEASEDC;
  604.  
  605.     ENDPROFILE(write_monocolor_span)
  606. }
  607.  
  608.  
  609.  
  610. /**********************************************************************/
  611. /*****                   Array-based pixel drawing                *****/
  612. /**********************************************************************/
  613.  
  614.  
  615. /* Write an array of pixels with a boolean mask. */
  616. static void write_index_pixels( GLuint n, const GLint x[], const GLint y[],
  617.                                 const GLuint index[], const GLubyte mask[] )
  618. {
  619.    STARTPROFILE
  620.    GLuint i;
  621.    assert(Current->rgb_flag==GL_FALSE);
  622.    for (i=0; i<n; i++) {
  623.       if (mask[i]) {
  624.          char *Mem=Current->ScreenMem+y[i]*Current->ScanWidth+x[i];
  625.          *Mem = index[i];
  626.       }
  627.    }
  628.    ENDPROFILE(write_index_pixels)
  629. }
  630.  
  631.  
  632.  
  633. /*
  634.  * Write an array of pixels with a boolean mask.  The current color
  635.  * index is used for all pixels.
  636.  */
  637. static void write_monoindex_pixels( GLuint n,
  638.                                     const GLint x[], const GLint y[],
  639.                                     const GLubyte mask[] )
  640. {
  641.    STARTPROFILE
  642.    GLuint i;
  643.    assert(Current->rgb_flag==GL_FALSE);
  644.    for (i=0; i<n; i++) {
  645.       if (mask[i]) {
  646.          char *Mem=Current->ScreenMem+y[i]*Current->ScanWidth+x[i];
  647.          *Mem = Current->pixel;
  648.       }
  649.    }
  650.    ENDPROFILE(write_monoindex_pixels)
  651. }
  652.  
  653.  
  654.  
  655. /* Write an array of pixels with a boolean mask. */
  656. static void write_color_pixels( GLuint n, const GLint x[], const GLint y[],
  657.                                 const GLubyte r[], const GLubyte g[],
  658.                                 const GLubyte b[], const GLubyte a[],
  659.                                 const GLubyte mask[] )
  660. {
  661.     STARTPROFILE
  662.     GLuint i;
  663.     PWMC    pwc = Current;
  664.     HDC DC=DD_GETDC;
  665.     assert(Current->rgb_flag==GL_TRUE);
  666.     for (i=0; i<n; i++)
  667.         if (mask[i])
  668.             wmSetPixel(pwc, FLIP(y[i]),x[i],r[i],g[i],b[i]);
  669.     DD_RELEASEDC;
  670.     ENDPROFILE(write_color_pixels)
  671. }
  672.  
  673.  
  674.  
  675. /*
  676.  * Write an array of pixels with a boolean mask.  The current color
  677.  * is used for all pixels.
  678.  */
  679. static void write_monocolor_pixels( GLuint n,
  680.                                     const GLint x[], const GLint y[],
  681.                                     const GLubyte mask[] )
  682. {
  683.     STARTPROFILE
  684.     GLuint i;
  685.     PWMC    pwc = Current;
  686.     HDC DC=DD_GETDC;
  687.     assert(Current->rgb_flag==GL_TRUE);
  688.     for (i=0; i<n; i++)
  689.         if (mask[i])
  690.             wmSetPixel(pwc, FLIP(y[i]),x[i],GetRValue(Current->pixel), 
  691.                         GetGValue(Current->pixel), GetBValue(Current->pixel));
  692.     DD_RELEASEDC;
  693.     ENDPROFILE(write_monocolor_pixels)
  694. }
  695.  
  696.  
  697.  
  698. /**********************************************************************/
  699. /*****            Read spans/arrays of pixels                     *****/
  700. /**********************************************************************/
  701.  
  702.  
  703. /* Read a horizontal span of color-index pixels. */
  704. static void read_index_span( GLuint n, GLint x, GLint y, GLuint index[])
  705. {
  706.    STARTPROFILE
  707.    GLuint i;
  708.   char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
  709.   assert(Current->rgb_flag==GL_FALSE);
  710.   for (i=0; i<n; i++)
  711.     index[i]=Mem[i];
  712.    ENDPROFILE(read_index_span)
  713. }
  714.  
  715.  
  716.  
  717.  
  718. /* Read an array of color index pixels. */
  719. static void read_index_pixels( GLuint n, const GLint x[], const GLint y[],
  720.                                GLuint indx[], const GLubyte mask[] )
  721. {
  722.    STARTPROFILE
  723.    GLuint i;
  724.   assert(Current->rgb_flag==GL_FALSE);
  725.   for (i=0; i<n; i++) {
  726.      if (mask[i]) {
  727.         indx[i]=*(Current->ScreenMem+y[i]*Current->ScanWidth+x[i]);
  728.      }
  729.   }
  730.    ENDPROFILE(read_index_pixels)
  731. }
  732.  
  733.  
  734.  
  735. /* Read a horizontal span of color pixels. */
  736. static void read_color_span( GLuint n, GLint x, GLint y,
  737.                              GLubyte red[], GLubyte green[],
  738.                              GLubyte blue[], GLubyte alpha[] )
  739. {
  740.    STARTPROFILE
  741.   UINT i;
  742.   COLORREF Color;
  743.   HDC DC=DD_GETDC;
  744.   assert(Current->rgb_flag==GL_TRUE);
  745.   y=FLIP(y);
  746.   for (i=0; i<n; i++)
  747.   {
  748.     Color=GetPixel(DC,x+i,y);
  749.     red[i]=GetRValue(Color);
  750.     green[i]=GetGValue(Color);
  751.     blue[i]=GetBValue(Color);
  752.     alpha[i]=255;
  753.   }
  754.   DD_RELEASEDC;
  755.   memset(alpha,0,n*sizeof(GLint));
  756.    ENDPROFILE(read_color_span)
  757. }
  758.  
  759.  
  760. /* Read an array of color pixels. */
  761. static void read_color_pixels( GLuint n, const GLint x[], const GLint y[],
  762.                                GLubyte red[], GLubyte green[],
  763.                                GLubyte blue[], GLubyte alpha[],
  764.                                const GLubyte mask[] )
  765. {
  766.    STARTPROFILE
  767.   GLuint i;
  768.   COLORREF Color;
  769.   HDC DC=DD_GETDC;
  770.   assert(Current->rgb_flag==GL_TRUE);
  771.   for (i=0; i<n; i++) {
  772.      if (mask[i]) {
  773.         Color=GetPixel(DC,x[i],FLIP(y[i]));
  774.         red[i]=GetRValue(Color);
  775.         green[i]=GetGValue(Color);
  776.         blue[i]=GetBValue(Color);
  777.         alpha[i]=255;
  778.      }
  779.   }
  780.   DD_RELEASEDC;
  781.   memset(alpha,0,n*sizeof(GLint));
  782.    ENDPROFILE(read_color_pixels)
  783. }
  784.  
  785.  
  786.  
  787. /**********************************************************************/
  788. /**********************************************************************/
  789.  
  790.  
  791.  
  792. void setup_DD_pointers( void )
  793. {
  794.    DD.finish = finish;
  795.    DD.flush = flush;
  796.  
  797.    DD.clear_index = clear_index;
  798.    DD.clear_color = clear_color;
  799.    DD.clear = clear;
  800.  
  801.    DD.index = set_index;
  802.    DD.color = set_color;
  803.    DD.index_mask = index_mask;
  804.    DD.color_mask = color_mask;
  805.  
  806.    DD.logicop = logicop;
  807.    DD.dither = dither;
  808.  
  809.    DD.set_buffer = set_buffer;
  810.    DD.buffer_size = buffer_size;
  811.  
  812.    DD.get_points_func = choose_points_function;
  813.    DD.get_line_func = choose_line_function;
  814.    DD.get_polygon_func = choose_polygon_function;
  815.  
  816.    /* Pixel/span writing functions: */
  817.    DD.write_color_span       = write_color_span;
  818.    DD.write_monocolor_span   = write_monocolor_span;
  819.    DD.write_color_pixels     = write_color_pixels;
  820.    DD.write_monocolor_pixels = write_monocolor_pixels;
  821.    DD.write_index_span       = write_index_span;
  822.    DD.write_monoindex_span   = write_monoindex_span;
  823.    DD.write_index_pixels     = write_index_pixels;
  824.    DD.write_monoindex_pixels = write_monoindex_pixels;
  825.  
  826.    /* Pixel/span reading functions: */
  827.    DD.read_index_span = read_index_span;
  828.    DD.read_color_span = read_color_span;
  829.    DD.read_index_pixels = read_index_pixels;
  830.    DD.read_color_pixels = read_color_pixels;
  831. }
  832.  
  833. //
  834. // MesaGL32 is the DLL version of MesaGL for Win32
  835. //
  836.  
  837. /**********************************************************************/
  838. /*****                  WMesa API Functions                       *****/
  839. /**********************************************************************/
  840.  
  841.  
  842.  
  843. #define PAL_SIZE 256
  844. static void GetPalette(HPALETTE Pal,RGBQUAD *aRGB)
  845. {
  846.    STARTPROFILE
  847.     int i;
  848.     HDC hdc;
  849.     struct
  850.     {
  851.         WORD Version;
  852.         WORD NumberOfEntries;
  853.         PALETTEENTRY aEntries[PAL_SIZE];
  854.     } Palette =
  855.     {
  856.         0x300,
  857.         PAL_SIZE
  858.     };
  859.     hdc=GetDC(NULL);
  860.     if (Pal!=NULL)
  861.     GetPaletteEntries(Pal,0,PAL_SIZE,Palette.aEntries);
  862.   else
  863.     GetSystemPaletteEntries(hdc,0,PAL_SIZE,Palette.aEntries);
  864.     if (GetSystemPaletteUse(hdc) == SYSPAL_NOSTATIC)
  865.     {
  866.         for(i = 0; i <PAL_SIZE; i++)
  867.             Palette.aEntries[i].peFlags = PC_RESERVED;
  868.         Palette.aEntries[255].peRed = 255;
  869.         Palette.aEntries[255].peGreen = 255;
  870.         Palette.aEntries[255].peBlue = 255;
  871.         Palette.aEntries[255].peFlags = 0;
  872.         Palette.aEntries[0].peRed = 0;
  873.         Palette.aEntries[0].peGreen = 0;
  874.         Palette.aEntries[0].peBlue = 0;
  875.         Palette.aEntries[0].peFlags = 0;
  876.     }
  877.     else
  878.     {
  879.         int nStaticColors;
  880.         int nUsableColors;
  881.         nStaticColors = GetDeviceCaps(hdc, NUMCOLORS)/2;
  882.         for (i=0; i<nStaticColors; i++)
  883.             Palette.aEntries[i].peFlags = 0;
  884.         nUsableColors = PAL_SIZE-nStaticColors;
  885.         for (; i<nUsableColors; i++)
  886.             Palette.aEntries[i].peFlags = PC_RESERVED;
  887.         for (; i<PAL_SIZE-nStaticColors; i++)
  888.             Palette.aEntries[i].peFlags = PC_RESERVED;
  889.         for (i=PAL_SIZE-nStaticColors; i<PAL_SIZE; i++)
  890.             Palette.aEntries[i].peFlags = 0;
  891.     }
  892.     ReleaseDC(NULL,hdc);
  893.   for (i=0; i<PAL_SIZE; i++)
  894.   {
  895.     aRGB[i].rgbRed=Palette.aEntries[i].peRed;
  896.     aRGB[i].rgbGreen=Palette.aEntries[i].peGreen;
  897.     aRGB[i].rgbBlue=Palette.aEntries[i].peBlue;
  898.     aRGB[i].rgbReserved=Palette.aEntries[i].peFlags;
  899.   }
  900.         ENDPROFILE(GetPalette)
  901. }
  902.  
  903.  
  904. WMesaContext APIENTRY WMesaCreateContext( HWND hWnd, HPALETTE Pal, HDC hDC, GLboolean rgb_flag,
  905.                                  GLboolean db_flag )
  906. {
  907.   BITMAPINFO *Rec;
  908.   HDC DC;
  909.   RECT CR;
  910.   WMesaContext c;
  911.  
  912.   c = (wmesa_context *) calloc(1,sizeof(wmesa_context));
  913.   if (!c)
  914.     return NULL;
  915.  
  916.   c->Window=hWnd;
  917.  
  918.   if (rgb_flag==GL_FALSE)
  919.   {
  920.     c->rgb_flag = GL_FALSE;
  921.     c->pixel = 1;
  922.     db_flag=GL_TRUE; // WinG requires double buffering
  923.     //c->gl_ctx->BufferDepth = windepth;
  924.   }
  925.   else
  926.   {
  927.     c->rgb_flag = GL_TRUE;
  928.     c->pixel = 0;
  929.   }
  930.   GetClientRect(c->Window,&CR);
  931.   c->width=CR.right;
  932.   c->height=CR.bottom;
  933.   if (db_flag)
  934.   {
  935.     c->db_flag = 1;
  936.     /* Double buffered */
  937.     if (c->rgb_flag==GL_TRUE)
  938.     {
  939.       DC = c->hDC = hDC;
  940.       wmCreateBackingStore(c, c->width, c->height);
  941.     }
  942.     else
  943.     {
  944.       c->dib.hDC=WinGCreateDC();
  945.       Rec=(BITMAPINFO *) malloc(sizeof(BITMAPINFO)+(PAL_SIZE-1)*sizeof(RGBQUAD));
  946.       c->hPal=Pal;
  947.       GetPalette(Pal,Rec->bmiColors);
  948.       WinGRecommendDIBFormat(Rec);
  949.       Rec->bmiHeader.biWidth=c->width;
  950.       Rec->bmiHeader.biHeight*=c->height;
  951.       Rec->bmiHeader.biClrUsed=PAL_SIZE;
  952.       if (Rec->bmiHeader.biPlanes!=1 || Rec->bmiHeader.biBitCount!=8)
  953.       {
  954.         MessageBox(NULL,"Error.","This code presumes a 256 color, single plane, WinG Device.\n",MB_OK);
  955.         exit(1);
  956.       }
  957.       c->Compat_BM=WinGCreateBitmap(c->dib.hDC,Rec,&((void *) c->ScreenMem));
  958.       c->Old_Compat_BM=SelectObject(c->dib.hDC,c->Compat_BM);
  959.       WinGSetDIBColorTable(c->dib.hDC,0,PAL_SIZE,Rec->bmiColors);
  960.       c->IndexFormat=Rec;
  961.       c->ScanWidth=c->width;
  962.       if ((c->ScanWidth%sizeof(long))!=0)
  963.         c->ScanWidth+=(sizeof(long)-(c->ScanWidth%sizeof(long)));
  964.     }
  965.   }
  966.   else
  967.   {
  968.     /* Single Buffered */
  969.     c->db_flag = 0;
  970.     DC = c->hDC = hDC;
  971.     wmCreateBackingStore(c, c->width, c->height);
  972.   }
  973.  
  974.   /* allocate a new Mesa context */
  975.   c->gl_ctx = gl_new_context( rgb_flag,
  976.                               255.0, 255.0, 255.0, 255.0,
  977.                               db_flag, NULL);
  978.  
  979.   setup_DD_pointers();
  980.  
  981.   return c;
  982. }
  983.  
  984.  
  985.  
  986. void APIENTRY WMesaDestroyContext( WMesaContext c )
  987. {
  988.     WC = c;
  989.     gl_destroy_context( c->gl_ctx );
  990.  
  991.     if (c->db_flag){
  992.         wmDeleteBackingStore(c);
  993.     }
  994.     free( (void *) c );
  995. }
  996.  
  997.  
  998.  
  999. void APIENTRY WMesaMakeCurrent( WMesaContext c )
  1000. {
  1001.     if(!c){
  1002.         Current = c;
  1003.         return;
  1004.     }
  1005.     
  1006.     //
  1007.     // A little optimization
  1008.     // If it already is current,
  1009.     // don't set it again
  1010.     //
  1011.     if(Current == c)
  1012.         return;
  1013.  
  1014.     gl_set_context( c->gl_ctx );
  1015.     Current = c;
  1016.     setup_DD_pointers();
  1017.     if (Current->gl_ctx->Viewport.Width==0) {
  1018.       /* initialize viewport to window size */
  1019.       gl_viewport( 0, 0, Current->width, Current->height );
  1020.     }
  1021. }
  1022.  
  1023.  
  1024.  
  1025. void APIENTRY WMesaSwapBuffers( void )
  1026. {
  1027.   HDC DC = Current->hDC;
  1028.   if (Current->db_flag)
  1029.   {
  1030.     if (Current->rgb_flag)
  1031.         wmFlush(Current);
  1032.     else
  1033.       WinGBitBlt(DC,0,0,Current->width,Current->height,Current->dib.hDC,0,0);
  1034.   }
  1035. }
  1036.  
  1037.  
  1038.  
  1039. void APIENTRY WMesaPaletteChange(HPALETTE Pal)
  1040. {
  1041.   if (Current && Current->rgb_flag==GL_FALSE)
  1042.   {
  1043.     Current->hPal=Pal;
  1044.     GetPalette(Pal,Current->IndexFormat->bmiColors);
  1045.     WinGSetDIBColorTable(Current->dib.hDC,0,PAL_SIZE,Current->IndexFormat->bmiColors);
  1046.   }
  1047. }
  1048.  
  1049. //
  1050. // Free up the dib section that was created
  1051. //
  1052. BOOL wmDeleteBackingStore(PWMC pwc)
  1053. {
  1054.     SelectObject(pwc->dib.hDC, pwc->hOldBitmap);
  1055.     DeleteDC(pwc->dib.hDC);
  1056.     DeleteObject(pwc->hbmDIB);
  1057.     UnmapViewOfFile(pwc->dib.base);
  1058.     CloseHandle(pwc->dib.hFileMap);
  1059.  
  1060. }
  1061.  
  1062.  
  1063. //
  1064. // This function creates the DIB section that is used for combined
  1065. // GL and GDI calls
  1066. //
  1067. BOOL WINAPI wmCreateBackingStore(PWMC pwc, long lxSize, long lySize)
  1068. {
  1069.     HDC hdc = pwc->hDC;
  1070.     LPBITMAPINFO pbmi = &(pwc->bmi);
  1071.     int        iUsage;
  1072.  
  1073.     pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  1074.     pbmi->bmiHeader.biWidth = lxSize;
  1075.     pbmi->bmiHeader.biHeight= -lySize;
  1076.     pbmi->bmiHeader.biPlanes = 1;
  1077.     pbmi->bmiHeader.biBitCount = GetDeviceCaps(pwc->hDC, BITSPIXEL);
  1078.     pbmi->bmiHeader.biCompression = BI_RGB;
  1079.     pbmi->bmiHeader.biSizeImage = 0;
  1080.     pbmi->bmiHeader.biXPelsPerMeter = 0;
  1081.     pbmi->bmiHeader.biYPelsPerMeter = 0;
  1082.     pbmi->bmiHeader.biClrUsed = 0;
  1083.     pbmi->bmiHeader.biClrImportant = 0;
  1084.  
  1085.     iUsage = (pbmi->bmiHeader.biBitCount <= 8) ? DIB_PAL_COLORS : DIB_RGB_COLORS;
  1086.  
  1087.     pwc->cColorBits = pbmi->bmiHeader.biBitCount;
  1088.     pwc->ScanWidth = lxSize;
  1089.  
  1090.     wmCreateDIBSection(hdc, pwc, pbmi, iUsage, (void **)&(pwc->pbPixels));
  1091.  
  1092.     if ((iUsage == DIB_PAL_COLORS) && !(pwc->hGLPalette)) {
  1093.         wmCreatePalette( pwc );
  1094.         wmSetDibColors( pwc );
  1095.     }
  1096.  
  1097.     return(TRUE);
  1098.  
  1099. }
  1100.  
  1101.  
  1102. //
  1103. // This function copies one scan line in a DIB section to another
  1104. //
  1105. BOOL WINAPI wmSetDIBits(PWMC pwc, UINT uiScanWidth, UINT uiNumScans, UINT nBypp, UINT uiNewWidth, LPBYTE pBits)
  1106. {
  1107.     UINT uiScans = 0;
  1108.     LPBYTE    pDest = pwc->pbPixels;
  1109.     DWORD    dwNextScan = uiScanWidth;
  1110.     DWORD    dwNewScan = uiNewWidth;
  1111.     DWORD    dwScanWidth = (uiScanWidth * nBypp);
  1112.  
  1113.     //
  1114.     // We need to round up to the nearest DWORD
  1115.     // and multiply by the number of bytes per
  1116.     // pixel
  1117.     //
  1118.     dwNextScan = (((dwNextScan * nBypp)+ 3) & ~3);
  1119.     dwNewScan = (((dwNewScan * nBypp)+ 3) & ~3);
  1120.  
  1121.     for(uiScans = 0; uiScans < uiNumScans; uiScans++){
  1122.         CopyMemory(pDest, pBits, dwScanWidth);
  1123.         pBits += dwNextScan;
  1124.         pDest += dwNewScan;
  1125.     }
  1126.  
  1127.     return(TRUE);
  1128.  
  1129. }
  1130.  
  1131. BOOL WINAPI wmSetPixelFormat( PWMC pwdc, HDC hDC, DWORD dwFlags )
  1132. {
  1133.     return(TRUE);
  1134. }
  1135.  
  1136. static unsigned char threeto8[8] = {
  1137.     0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
  1138. };
  1139.  
  1140. static unsigned char twoto8[4] = {
  1141.     0, 0x55, 0xaa, 0xff
  1142. };
  1143.  
  1144. static unsigned char oneto8[2] = {
  1145.     0, 255
  1146. };
  1147.  
  1148. static unsigned char componentFromIndex(UCHAR i, UINT nbits, UINT shift)
  1149. {
  1150.     unsigned char val;
  1151.  
  1152.     val = i >> shift;
  1153.     switch (nbits) {
  1154.  
  1155.         case 1:
  1156.             val &= 0x1;
  1157.             return oneto8[val];
  1158.  
  1159.         case 2:
  1160.             val &= 0x3;
  1161.             return twoto8[val];
  1162.  
  1163.         case 3:
  1164.             val &= 0x7;
  1165.             return threeto8[val];
  1166.  
  1167.         default:
  1168.             return 0;
  1169.     }
  1170. }
  1171.  
  1172. void WINAPI wmCreatePalette( PWMC pwdc )
  1173. {
  1174.     /* Create a compressed and re-expanded 3:3:2 palette */
  1175.       BYTE            i;
  1176.     LOGPALETTE     *pPal;
  1177.     BYTE           rb, rs, gb, gs, bb, bs;
  1178.  
  1179.     pwdc->nColors = 0x100;
  1180.  
  1181.     pPal = (PLOGPALETTE)malloc(sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY));
  1182.     memset( pPal, 0, sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY) );
  1183.  
  1184.     pPal->palVersion = 0x300;
  1185.  
  1186.     rb = REDBITS;
  1187.     rs = REDSHIFT;
  1188.     gb = GREENBITS;
  1189.     gs = GREENSHIFT;
  1190.     bb = BLUEBITS;
  1191.     bs = BLUESHIFT;
  1192.  
  1193.     if (pwdc->db_flag) {
  1194.  
  1195.         /* Need to make two palettes: one for the screen DC and one for the DIB. */
  1196.         pPal->palNumEntries = pwdc->nColors;
  1197.         for (i = 0; i < pwdc->nColors; i++) {
  1198.             pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
  1199.             pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
  1200.             pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
  1201.             pPal->palPalEntry[i].peFlags = 0;
  1202.         }
  1203.         pwdc->hGLPalette = CreatePalette( pPal );
  1204.         pwdc->hPalette = CreatePalette( pPal );
  1205.     } 
  1206.  
  1207.     else {
  1208.         pPal->palNumEntries = pwdc->nColors;
  1209.         for (i = 0; i < pwdc->nColors; i++) {
  1210.             pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
  1211.             pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
  1212.             pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
  1213.             pPal->palPalEntry[i].peFlags = 0;
  1214.         }
  1215.         pwdc->hGLPalette = CreatePalette( pPal );
  1216.     }
  1217.     
  1218.     free(pPal);
  1219.  
  1220. }
  1221.  
  1222. //
  1223. // This function sets the color table of a DIB section
  1224. // to match that of the destination DC
  1225. //
  1226. BOOL WINAPI wmSetDibColors(PWMC pwc)
  1227. {
  1228.     RGBQUAD            *pColTab, *pRGB;
  1229.     PALETTEENTRY    *pPal, *pPE;
  1230.     int                i, nColors;
  1231.     BOOL            bRet=TRUE;
  1232.     DWORD            dwErr=0;
  1233.  
  1234.     /* Build a color table in the DIB that maps to the
  1235.        selected palette in the DC.
  1236.     */
  1237.     nColors = 1 << pwc->cColorBits;
  1238.     pPal = (PALETTEENTRY *)malloc( nColors * sizeof(PALETTEENTRY));
  1239.     memset( pPal, 0, nColors * sizeof(PALETTEENTRY) );
  1240.     GetPaletteEntries( pwc->hGLPalette, 0, nColors, pPal );
  1241.     pColTab = (RGBQUAD *)malloc( nColors * sizeof(RGBQUAD));
  1242.     for (i = 0, pRGB = pColTab, pPE = pPal; i < nColors; i++, pRGB++, pPE++) {
  1243.         pRGB->rgbRed = pPE->peRed;
  1244.         pRGB->rgbGreen = pPE->peGreen;
  1245.         pRGB->rgbBlue = pPE->peBlue;
  1246.     }
  1247.     if(pwc->db_flag)
  1248.         bRet = SetDIBColorTable(pwc->hDC, 0, nColors, pColTab );
  1249.  
  1250.     if(!bRet)
  1251.         dwErr = GetLastError();
  1252.  
  1253.     free( pColTab );
  1254.     free( pPal );
  1255.  
  1256.     return(bRet);
  1257. }
  1258.  
  1259. void WINAPI wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
  1260. {
  1261.     LPBYTE    lpb = pwc->pbPixels;
  1262.     LPDWORD    lpdw;
  1263.     LPWORD    lpw;
  1264.     UINT    nBypp = pwc->cColorBits / 8;
  1265.     UINT    nOffset = iPixel % nBypp;
  1266.  
  1267.     // Move the pixel buffer pointer to the scanline that we
  1268.     // want to access
  1269.  
  1270.     pwc->dib.fFlushed = FALSE;
  1271.  
  1272.     lpb += pwc->ScanWidth * iScanLine;
  1273.     // Now move to the desired pixel
  1274.     lpb += iPixel * nBypp;
  1275.  
  1276.     lpdw = (LPDWORD)lpb;
  1277.     lpw = (LPWORD)lpb;
  1278.  
  1279.     if(nBypp == 2)
  1280.         *lpw = BGR16(r,g,b);
  1281.     else if (nBypp == 3){
  1282.         *lpdw = BGR24(r,g,b);
  1283.     }
  1284.     else
  1285.         *lpdw = BGR32(r,g,b);
  1286.  
  1287. }
  1288.  
  1289. void WINAPI wmCreateDIBSection(
  1290.     HDC     hDC,
  1291.     PWMC pwc,    // handle of device context
  1292.     CONST BITMAPINFO *pbmi,    // address of structure containing bitmap size, format, and color data
  1293.     UINT iUsage,    // color data type indicator: RGB values or palette indices
  1294.     VOID **ppvBits    // pointer to variable to receive a pointer to the bitmap's bit values
  1295. )
  1296. {
  1297.     DWORD    dwSize = 0;
  1298.     DWORD    dwScanWidth;
  1299.     UINT    nBypp = pwc->cColorBits / 8;
  1300.     HDC        hic;
  1301.  
  1302.     dwScanWidth = (((pwc->ScanWidth * nBypp)+ 3) & ~3);
  1303.  
  1304.     pwc->ScanWidth = dwScanWidth;
  1305.  
  1306.     dwSize = sizeof(BITMAPINFO) + (dwScanWidth * pwc->height);
  1307.  
  1308.     pwc->dib.hFileMap = CreateFileMapping((HANDLE)PAGE_FILE,
  1309.                                           NULL,
  1310.                                           PAGE_READWRITE | SEC_COMMIT,
  1311.                                           0,
  1312.                                           dwSize,
  1313.                                           NULL);
  1314.  
  1315.     if (!pwc->dib.hFileMap)
  1316.         return;
  1317.  
  1318.     pwc->dib.base = MapViewOfFile(pwc->dib.hFileMap,
  1319.                                   FILE_MAP_ALL_ACCESS,
  1320.                                   0,
  1321.                                   0,
  1322.                                   0);
  1323.  
  1324.     if(!pwc->dib.base){
  1325.         CloseHandle(pwc->dib.hFileMap);
  1326.         return;
  1327.     }
  1328.  
  1329.     *ppvBits = ((LPBYTE)pwc->dib.base) + sizeof(BITMAPINFO);
  1330.  
  1331.     pwc->dib.hDC = CreateCompatibleDC(hDC);
  1332.  
  1333.     CopyMemory(pwc->dib.base, pbmi, sizeof(BITMAPINFO));
  1334.  
  1335.     hic = CreateIC("display", NULL, NULL, NULL);
  1336.  
  1337.     pwc->hbmDIB = CreateDIBitmap(hic,
  1338.                          &(pwc->bmi.bmiHeader),
  1339.                          CBM_INIT,
  1340.                          pwc->pbPixels,
  1341.                          &(pwc->bmi),
  1342.                          DIB_RGB_COLORS);
  1343.  
  1344.     pwc->hOldBitmap = SelectObject(pwc->dib.hDC, pwc->hbmDIB);
  1345.  
  1346.     DeleteDC(hic);
  1347.  
  1348.     return;
  1349.  
  1350. }
  1351.  
  1352. //
  1353. // Get bits from memory DC and read into "back buffer"
  1354. //
  1355. BOOL wmGetBits(PWMC pwc)
  1356. {
  1357.     int        iRet;
  1358.  
  1359.     iRet = GetDIBits(pwc->dib.hDC,
  1360.               pwc->hbmDIB,
  1361.               0,
  1362.               pwc->height,
  1363.               pwc->pbPixels,
  1364.               &(pwc->bmi),
  1365.               DIB_RGB_COLORS);
  1366.  
  1367.     return(iRet);
  1368.  
  1369. }
  1370.  
  1371.  
  1372.  
  1373. //
  1374. // Flush the DIBits from memory buffer to the memory DC
  1375. // and clear the buffer
  1376. //
  1377. BOOL wmFlushBits(PWMC pwc)
  1378. {
  1379.     int        iRet;
  1380.  
  1381.     iRet = SetDIBits(pwc->dib.hDC,
  1382.               pwc->hbmDIB,
  1383.               0,
  1384.               pwc->height,
  1385.               pwc->pbPixels,
  1386.               &(pwc->bmi),
  1387.               DIB_RGB_COLORS);
  1388.  
  1389.     ZeroMemory(pwc->pbPixels, pwc->ScanWidth * pwc->height);
  1390.  
  1391.     return(iRet);
  1392.  
  1393. }
  1394.  
  1395. //
  1396. // Blit memory DC to screen DC
  1397. //
  1398. BOOL WINAPI wmFlush(PWMC pwc)
  1399. {
  1400.     BOOL    bRet = 0;
  1401.     DWORD    dwErr = 0;
  1402.  
  1403.  
  1404.     wmFlushBits(pwc);
  1405.  
  1406.     bRet = BitBlt(pwc->hDC, 0, 0, pwc->width, pwc->height, 
  1407.            pwc->dib.hDC, 0, 0, SRCCOPY);
  1408.  
  1409.     if(!bRet)
  1410.         dwErr = GetLastError();
  1411.  
  1412.     pwc->dib.fFlushed = TRUE;
  1413.  
  1414.     return(TRUE);
  1415.  
  1416. }
  1417.  
  1418. /************************************************************
  1419. wgl Stubs
  1420. ************************************************************/
  1421. HGLRC WINAPI wglCreateContext(HDC  hdc)
  1422. {
  1423.     return(NULL);
  1424. }
  1425.  
  1426. HDC WINAPI wglGetCurrentDC(VOID)
  1427. {
  1428.     return(NULL);
  1429. }
  1430.  
  1431. BOOL WINAPI wglDeleteContext(HGLRC  hglrc)
  1432. {
  1433.     WMesaDestroyContext((WMesaContext)hglrc );
  1434.     return(TRUE);
  1435. }
  1436.  
  1437. HGLRC WINAPI wglGetCurrentContext(VOID)
  1438. {
  1439.     return((HGLRC)Current);
  1440. }
  1441.  
  1442. PROC WINAPI wglGetProcAddress(LPCSTR  lpszProc)
  1443. {
  1444.     return(NULL);
  1445. }
  1446.  
  1447. BOOL WINAPI wglMakeCurrent(HDC  hdc, HGLRC  hglrc)
  1448. {
  1449.     WMesaMakeCurrent((WMesaContext)hglrc);
  1450.     return(TRUE);
  1451. }
  1452.  
  1453. BOOL WINAPI wlgMakeShareLists(HGLRC  hglrc1, HGLRC  hglrc2)
  1454. {
  1455.     return(FALSE);
  1456. }
  1457.  
  1458. BOOL WINAPI wglUseFontBitmaps(
  1459.     HDC  hdc,    //Device context whose font will be used
  1460.     DWORD  first,    //Glyph that is the first of a run of glyphs to be turned into bitmap display lists
  1461.     DWORD  count,    //Number of glyphs to turn into bitmap display lists
  1462.     DWORD  listBase     //Specifies starting display list
  1463. )
  1464. {
  1465.     return(FALSE);
  1466. }
  1467.  
  1468. BOOL WINAPI wglUseFontOutlines(
  1469.     HDC  hdc,    //Device context of the outline font
  1470.     DWORD  first,    //First glyph to be turned into a display list
  1471.     DWORD  count,    //Number of glyphs to be turned into display lists
  1472.     DWORD  listBase,    //Specifies the starting display list
  1473.     FLOAT  deviation,    //Specifies the maximum chordal deviation from the true outlines
  1474.     FLOAT  extrusion,    //Extrusion value in the negative z direction
  1475.     int  format,    //Specifies line segments or polygons in display lists
  1476.     LPGLYPHMETRICSFLOAT  lpgmf     //Address of buffer to receive glyphs metric data
  1477. )
  1478. {
  1479.     return(FALSE);
  1480. }
  1481.  
  1482. BOOL WINAPI SwapBuffers(
  1483.     HDC  hdc    //Device context whose buffers get swapped
  1484. )
  1485. {
  1486.     WMesaSwapBuffers();
  1487.     return(TRUE);
  1488. }
  1489.  
  1490.