Merge branch 'master-merge' into vbo-0.2
[mesa.git] / src / mesa / drivers / dos / dmesa.c
index ac21e8a15f3e5fb8616ca01982c65133447a9263..ee87e638529b967d5b0d43548245bc13aee660bf 100644 (file)
-/*\r
- * Mesa 3-D graphics library\r
- * Version:  4.0\r
- * \r
- * Copyright (C) 1999  Brian Paul   All Rights Reserved.\r
- * \r
- * Permission is hereby granted, free of charge, to any person obtaining a\r
- * copy of this software and associated documentation files (the "Software"),\r
- * to deal in the Software without restriction, including without limitation\r
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
- * and/or sell copies of the Software, and to permit persons to whom the\r
- * Software is furnished to do so, subject to the following conditions:\r
- * \r
- * The above copyright notice and this permission notice shall be included\r
- * in all copies or substantial portions of the Software.\r
- * \r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\r
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN\r
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
- */\r
-\r
-/*\r
- * DOS/DJGPP device driver v1.1 for Mesa 4.0\r
- *\r
- *  Copyright (C) 2002 - Borca Daniel\r
- *  Email : dborca@yahoo.com\r
- *  Web   : http://www.geocities.com/dborca\r
- */\r
-\r
-\r
-#ifdef PC_HEADER\r
-#include "all.h"\r
-#else\r
-#include "glheader.h"\r
-#include "context.h"\r
-#include "GL/dmesa.h"\r
-#include "extensions.h"\r
-#include "macros.h"\r
-#include "matrix.h"\r
-#include "mmath.h"\r
-#include "texformat.h"\r
-#include "texstore.h"\r
-#include "array_cache/acache.h"\r
-#include "swrast/s_context.h"\r
-#include "swrast/s_depth.h"\r
-#include "swrast/s_lines.h"\r
-#include "swrast/s_triangle.h"\r
-#include "swrast/s_trispan.h"\r
-#include "swrast/swrast.h"\r
-#include "swrast_setup/swrast_setup.h"\r
-#include "tnl/tnl.h"\r
-#include "tnl/t_context.h"\r
-#include "tnl/t_pipeline.h"\r
-#endif\r
-\r
-#include "video.h"\r
-\r
-\r
-\r
-/*\r
- * In C++ terms, this class derives from the GLvisual class.\r
- * Add system-specific fields to it.\r
- */\r
-struct dmesa_visual {\r
-   GLvisual *gl_visual;\r
-   GLboolean db_flag;           /* double buffered? */\r
-   GLboolean rgb_flag;          /* RGB mode? */\r
-   GLuint depth;                /* bits per pixel (1, 8, 24, etc) */\r
-};\r
-\r
-/*\r
- * In C++ terms, this class derives from the GLframebuffer class.\r
- * Add system-specific fields to it.\r
- */\r
-struct dmesa_buffer {\r
-   GLframebuffer gl_buffer;     /* The depth, stencil, accum, etc buffers */\r
-   void *the_window;            /* your window handle, etc */\r
-\r
-   int xpos, ypos;              /* position */\r
-   int width, height;           /* size in pixels */\r
-   int bypp, stride, bytes;     /* bytes per pixel, in a line, then total */\r
-};\r
-\r
-/*\r
- * In C++ terms, this class derives from the GLcontext class.\r
- * Add system-specific fields to it.\r
- */\r
-struct dmesa_context {\r
-   GLcontext *gl_ctx;           /* the core library context */\r
-   DMesaVisual visual;\r
-   DMesaBuffer Buffer;\r
-   GLuint ClearColor;\r
-   /* etc... */\r
-};\r
-\r
-\r
-\r
-static void dmesa_update_state (GLcontext *ctx, GLuint new_state);\r
-\r
-\r
-\r
-/**********************************************************************/\r
-/*****            Read/Write pixels                               *****/\r
-/**********************************************************************/\r
-\r
-\r
-\r
-#define FLIP(y)  (c->Buffer->height - (y) - 1)\r
-#define FLIP2(y) (h - (y) - 1)\r
-\r
-\r
-\r
-static void write_rgba_span (const GLcontext *ctx, GLuint n, GLint x, GLint y,\r
-                             const GLubyte rgba[][4], const GLubyte mask[])\r
-{\r
- DMesaContext c = (DMesaContext)ctx->DriverCtx;\r
- void *b = c->Buffer->the_window;\r
- GLuint i, offset;\r
-\r
- offset = c->Buffer->width * FLIP(y) + x;\r
- if (mask) {\r
-    /* draw some pixels */\r
-    for (i=0; i<n; i++, offset++) {\r
-        if (mask[i]) {\r
-           vl_putpixel(b, offset, vl_mixrgba(rgba[i]));\r
-        }\r
-    }\r
- } else {\r
-    /* draw all pixels */\r
-    for (i=0; i<n; i++, offset++) {\r
-        vl_putpixel(b, offset, vl_mixrgba(rgba[i]));\r
-    }\r
- }\r
-}\r
-\r
-static void write_rgb_span (const GLcontext *ctx, GLuint n, GLint x, GLint y,\r
-                            const GLubyte rgb[][3], const GLubyte mask[])\r
-{\r
- DMesaContext c = (DMesaContext)ctx->DriverCtx;\r
- void *b = c->Buffer->the_window;\r
- GLuint i, offset;\r
-\r
- offset = c->Buffer->width * FLIP(y) + x;\r
- if (mask) {\r
-    /* draw some pixels */\r
-    for (i=0; i<n; i++, offset++) {\r
-        if (mask[i]) {\r
-           vl_putpixel(b, offset, vl_mixrgb(rgb[i]));\r
-        }\r
-    }\r
- } else {\r
-    /* draw all pixels */\r
-    for (i=0; i<n; i++, offset++) {\r
-        vl_putpixel(b, offset, vl_mixrgb(rgb[i]));\r
-    }\r
- }\r
-}\r
-\r
-static void write_mono_rgba_span (const GLcontext *ctx,\r
-                                  GLuint n, GLint x, GLint y,\r
-                                  const GLchan color[4], const GLubyte mask[])\r
-{\r
- DMesaContext c = (DMesaContext)ctx->DriverCtx;\r
- void *b = c->Buffer->the_window;\r
- GLuint i, offset, rgba = vl_mixrgba(color);\r
-\r
- offset = c->Buffer->width * FLIP(y) + x;\r
- if (mask) {\r
-    /* draw some pixels */\r
-    for (i=0; i<n; i++, offset++) {\r
-        if (mask[i]) {\r
-           vl_putpixel(b, offset, rgba);\r
-        }\r
-    }\r
- } else {\r
-    /* draw all pixels */\r
-    for (i=0; i<n; i++, offset++) {\r
-        vl_putpixel(b, offset, rgba);\r
-    }\r
- }\r
-}\r
-\r
-static void read_rgba_span (const GLcontext *ctx, GLuint n, GLint x, GLint y,\r
-                            GLubyte rgba[][4])\r
-{\r
- DMesaContext c = (DMesaContext)ctx->DriverCtx;\r
- void *b = c->Buffer->the_window;\r
- GLuint i, offset;\r
-\r
- offset = c->Buffer->width * FLIP(y) + x;\r
- /* read all pixels */\r
- for (i=0; i<n; i++, offset++) {\r
-     vl_getrgba(b, offset, rgba[i]);\r
- }\r
-}\r
-\r
-static void write_rgba_pixels (const GLcontext *ctx,\r
-                               GLuint n, const GLint x[], const GLint y[],\r
-                               const GLubyte rgba[][4], const GLubyte mask[])\r
-{\r
- DMesaContext c = (DMesaContext)ctx->DriverCtx;\r
- void *b = c->Buffer->the_window;\r
- GLuint i, w = c->Buffer->width, h = c->Buffer->height;\r
-\r
- if (mask) {\r
-    /* draw some pixels */\r
-    for (i=0; i<n; i++) {\r
-        if (mask[i]) {\r
-           vl_putpixel(b, FLIP2(y[i])*w + x[i], vl_mixrgba(rgba[i]));\r
-        }\r
-    }\r
- } else {\r
-    /* draw all pixels */\r
-    for (i=0; i<n; i++) {\r
-        vl_putpixel(b, FLIP2(y[i])*w + x[i], vl_mixrgba(rgba[i]));\r
-    }\r
- }\r
-}\r
-\r
-static void write_mono_rgba_pixels (const GLcontext *ctx,\r
-                                    GLuint n, const GLint x[], const GLint y[],\r
-                                    const GLchan color[4], const GLubyte mask[])\r
-{\r
- DMesaContext c = (DMesaContext)ctx->DriverCtx;\r
- void *b = c->Buffer->the_window;\r
- GLuint i, w = c->Buffer->width, h = c->Buffer->height, rgba = vl_mixrgba(color);\r
-\r
- if (mask) {\r
-    /* draw some pixels */\r
-    for (i=0; i<n; i++) {\r
-        if (mask[i]) {\r
-           vl_putpixel(b, FLIP2(y[i])*w + x[i], rgba);\r
-        }\r
-    }\r
- } else {\r
-    /* draw all pixels */\r
-    for (i=0; i<n; i++) {\r
-        vl_putpixel(b, FLIP2(y[i])*w + x[i], rgba);\r
-    }\r
- }\r
-}\r
-\r
-static void read_rgba_pixels (const GLcontext *ctx,\r
-                              GLuint n, const GLint x[], const GLint y[],\r
-                              GLubyte rgba[][4], const GLubyte mask[])\r
-{\r
- DMesaContext c = (DMesaContext)ctx->DriverCtx;\r
- void *b = c->Buffer->the_window;\r
- GLuint i, w = c->Buffer->width, h = c->Buffer->height;\r
-\r
- if (mask) {\r
-    /* read some pixels */\r
-    for (i=0; i<n; i++) {\r
-        if (mask[i]) {\r
-           vl_getrgba(b, FLIP2(y[i])*w + x[i], rgba[i]);\r
-        }\r
-    }\r
- } else {\r
-    /* read all pixels */\r
-    for (i=0; i<n; i++) {\r
-        vl_getrgba(b, FLIP2(y[i])*w + x[i], rgba[i]);\r
-    }\r
- }\r
-}\r
-\r
-\r
-\r
-/**********************************************************************/\r
-/*****                   Optimized triangle rendering             *****/\r
-/**********************************************************************/\r
-\r
-\r
-\r
-/*\r
- * flat, NON-depth-buffered, triangle.\r
- */\r
-static void tri_rgb_flat (GLcontext *ctx,\r
-                          const SWvertex *v0,\r
-                          const SWvertex *v1,\r
-                          const SWvertex *v2)\r
-{\r
- DMesaContext c = (DMesaContext)ctx->DriverCtx;\r
- void *b = c->Buffer->the_window;\r
- GLuint w = c->Buffer->width, h = c->Buffer->height;\r
-\r
-#define SETUP_CODE GLuint rgb = vl_mixrgb(v2->color);\r
-\r
-#define RENDER_SPAN(span)                                      \\r
- GLuint i, offset = FLIP2(span.y)*w + span.x;                  \\r
- for (i = 0; i < span.count; i++, offset++) {                  \\r
-     vl_putpixel(b, offset, rgb);                              \\r
- }\r
-\r
-#include "swrast/s_tritemp.h"\r
-}\r
-\r
-\r
-\r
-/*\r
- * flat, depth-buffered, triangle.\r
- */\r
-static void tri_rgb_flat_z (GLcontext *ctx,\r
-                            const SWvertex *v0,\r
-                            const SWvertex *v1,\r
-                            const SWvertex *v2)\r
-{\r
- DMesaContext c = (DMesaContext)ctx->DriverCtx;\r
- void *b = c->Buffer->the_window;\r
- GLuint w = c->Buffer->width, h = c->Buffer->height;\r
-\r
-#define INTERP_Z 1\r
-#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE\r
-#define SETUP_CODE GLuint rgb = vl_mixrgb(v2->color);\r
-\r
-#define RENDER_SPAN(span)                                      \\r
- GLuint i, offset = FLIP2(span.y)*w + span.x;                  \\r
- for (i = 0; i < span.count; i++, offset++) {                  \\r
-     const DEPTH_TYPE z = FixedToDepth(span.z);                        \\r
-     if (z < zRow[i]) {                                                \\r
-        vl_putpixel(b, offset, rgb);                           \\r
-        zRow[i] = z;                                           \\r
-     }                                                         \\r
-     span.z += span.zStep;                                     \\r
- }\r
-\r
-#include "swrast/s_tritemp.h"\r
-}\r
-\r
-\r
-\r
-/*\r
- * smooth, NON-depth-buffered, triangle.\r
- */\r
-static void tri_rgb_smooth (GLcontext *ctx,\r
-                            const SWvertex *v0,\r
-                            const SWvertex *v1,\r
-                            const SWvertex *v2)\r
-{\r
- DMesaContext c = (DMesaContext)ctx->DriverCtx;\r
- void *b = c->Buffer->the_window;\r
- GLuint w = c->Buffer->width, h = c->Buffer->height;\r
-\r
-#define INTERP_RGB 1\r
-#define RENDER_SPAN(span)                                      \\r
- GLuint i, offset = FLIP2(span.y)*w + span.x;                  \\r
- for (i = 0; i < span.count; i++, offset++) {                  \\r
-     unsigned char rgb[3];                                     \\r
-     rgb[0] = FixedToInt(span.red);                            \\r
-     rgb[1] = FixedToInt(span.green);                          \\r
-     rgb[2] = FixedToInt(span.blue);                           \\r
-     vl_putpixel(b, offset, vl_mixrgb(rgb));                   \\r
-     span.red += span.redStep;                                 \\r
-     span.green += span.greenStep;                             \\r
-     span.blue += span.blueStep;                               \\r
- }\r
-\r
-#include "swrast/s_tritemp.h"\r
-}\r
-\r
-\r
-\r
-/*\r
- * smooth, depth-buffered, triangle.\r
- */\r
-static void tri_rgb_smooth_z (GLcontext *ctx,\r
-                              const SWvertex *v0,\r
-                              const SWvertex *v1,\r
-                              const SWvertex *v2)\r
-{\r
- DMesaContext c = (DMesaContext)ctx->DriverCtx;\r
- void *b = c->Buffer->the_window;\r
- GLuint w = c->Buffer->width, h = c->Buffer->height;\r
-\r
-#define INTERP_Z 1\r
-#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE\r
-#define INTERP_RGB 1\r
-\r
-#define RENDER_SPAN(span)                                      \\r
- GLuint i, offset = FLIP2(span.y)*w + span.x;                  \\r
- for (i = 0; i < span.count; i++, offset++) {                  \\r
-     const DEPTH_TYPE z = FixedToDepth(span.z);                        \\r
-     if (z < zRow[i]) {                                                \\r
-        unsigned char rgb[3];                                  \\r
-        rgb[0] = FixedToInt(span.red);                         \\r
-        rgb[1] = FixedToInt(span.green);                       \\r
-        rgb[2] = FixedToInt(span.blue);                                \\r
-        vl_putpixel(b, offset, vl_mixrgb(rgb));                        \\r
-        zRow[i] = z;                                           \\r
-     }                                                         \\r
-     span.red += span.redStep;                                 \\r
-     span.green += span.greenStep;                             \\r
-     span.blue += span.blueStep;                               \\r
-     span.z += span.zStep;                                     \\r
- }\r
-\r
-#include "swrast/s_tritemp.h"\r
-}\r
-\r
-\r
-\r
-/*\r
- * Analyze context state to see if we can provide a fast triangle function\r
- * Otherwise, return NULL.\r
- */\r
-static swrast_tri_func dmesa_choose_tri_function (GLcontext *ctx)\r
-{\r
- const SWcontext *swrast = SWRAST_CONTEXT(ctx);\r
-\r
- if (ctx->RenderMode != GL_RENDER)  return (swrast_tri_func) NULL;\r
- if (ctx->Polygon.SmoothFlag)       return (swrast_tri_func) NULL;\r
- if (ctx->Texture._EnabledUnits)    return (swrast_tri_func) NULL;\r
-\r
- if (ctx->Light.ShadeModel==GL_SMOOTH\r
-     && swrast->_RasterMask==DEPTH_BIT\r
-     && ctx->Depth.Func==GL_LESS\r
-     && ctx->Depth.Mask==GL_TRUE\r
-     && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS\r
-     && ctx->Polygon.StippleFlag==GL_FALSE) {\r
-    return tri_rgb_smooth_z;\r
- }\r
- if (ctx->Light.ShadeModel==GL_FLAT\r
-     && swrast->_RasterMask==DEPTH_BIT\r
-     && ctx->Depth.Func==GL_LESS\r
-     && ctx->Depth.Mask==GL_TRUE\r
-     && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS\r
-     && ctx->Polygon.StippleFlag==GL_FALSE) {\r
-    return tri_rgb_flat_z;\r
- }\r
- if (swrast->_RasterMask==0   /* no depth test */\r
-     && ctx->Light.ShadeModel==GL_SMOOTH\r
-     && ctx->Polygon.StippleFlag==GL_FALSE) {\r
-    return tri_rgb_smooth;\r
- }\r
- if (swrast->_RasterMask==0   /* no depth test */\r
-     && ctx->Light.ShadeModel==GL_FLAT\r
-     && ctx->Polygon.StippleFlag==GL_FALSE) {\r
-    return tri_rgb_flat;\r
- }\r
-\r
- return (swrast_tri_func)NULL;\r
-}\r
-\r
-\r
-\r
-/* Override for the swrast triangle-selection function.  Try to use one\r
- * of our internal line functions, otherwise fall back to the\r
- * standard swrast functions.\r
- */\r
-static void dmesa_choose_tri (GLcontext *ctx)\r
-{\r
- SWcontext *swrast = SWRAST_CONTEXT(ctx);\r
-\r
- if (!(swrast->Triangle=dmesa_choose_tri_function(ctx)))\r
-    _swrast_choose_triangle(ctx);\r
-}\r
-\r
-\r
-\r
-/**********************************************************************/\r
-/*****              Miscellaneous device driver funcs             *****/\r
-/**********************************************************************/\r
-\r
-\r
-\r
-static void clear_color (GLcontext *ctx, const GLchan color[4])\r
-{\r
- const GLubyte col[4];\r
- DMesaContext c = (DMesaContext)ctx->DriverCtx;\r
- CLAMPED_FLOAT_TO_UBYTE(col[0], color[0]);\r
- CLAMPED_FLOAT_TO_UBYTE(col[1], color[1]);\r
- CLAMPED_FLOAT_TO_UBYTE(col[2], color[2]);\r
- CLAMPED_FLOAT_TO_UBYTE(col[3], color[3]);\r
- c->ClearColor = vl_mixrgba(col);\r
-}\r
-\r
-\r
-\r
-static void clear (GLcontext *ctx, GLbitfield mask, GLboolean all,\r
-                   GLint x, GLint y, GLint width, GLint height)\r
-{\r
- DMesaContext c = (DMesaContext)ctx->DriverCtx;\r
- const GLuint *colorMask = (GLuint *)&ctx->Color.ColorMask;\r
- DMesaBuffer b = c->Buffer;\r
-\r
-/*\r
- * Clear the specified region of the buffers indicated by 'mask'\r
- * using the clear color or index as specified by one of the two\r
- * functions above.\r
- * If all==GL_TRUE, clear whole buffer, else just clear region defined\r
- * by x,y,width,height\r
- */\r
-\r
- /* we can't handle color or index masking */\r
- if (*colorMask==0xffffffff) {\r
-    if (mask & DD_BACK_LEFT_BIT) {\r
-       if (all) {\r
-          vl_clear(b->the_window, b->bytes, c->ClearColor);\r
-       } else {\r
-          vl_rect(b->the_window, x, y, width, height, c->ClearColor);\r
-       }\r
-       mask &= ~DD_BACK_LEFT_BIT;\r
-    }\r
- }\r
-\r
- if (mask) {\r
-    _swrast_Clear(ctx, mask, all, x, y, width, height);\r
- }\r
-}\r
-\r
-\r
-\r
-/*\r
- * Set the current reading buffer.\r
- */\r
-static void set_read_buffer (GLcontext *ctx, GLframebuffer *buffer,\r
-                             GLenum mode)\r
-{\r
-   /*\r
-     XXX this has to be fixed\r
-   */\r
-}\r
-\r
-\r
-\r
-/*\r
- * Set the destination/draw buffer.\r
- */\r
-static void set_draw_buffer (GLcontext *ctx, GLenum mode)\r
-{\r
-   /*\r
-     XXX this has to be fixed\r
-   */\r
-}\r
-\r
-\r
-\r
-/*\r
- * Return the width and height of the current buffer.\r
- * If anything special has to been done when the buffer/window is\r
- * resized, do it now.\r
- */\r
-static void get_buffer_size (GLframebuffer *buffer, GLuint *width, GLuint *height)\r
-{\r
- DMesaBuffer b = (DMesaBuffer)buffer;\r
-\r
- *width  = b->width;\r
- *height = b->height;\r
-}\r
-\r
-\r
-\r
-static const GLubyte* get_string (GLcontext *ctx, GLenum name)\r
-{\r
- switch (name) {\r
-        case GL_RENDERER:\r
-             return (const GLubyte *)"Mesa DJGPP\0port (c) Borca Daniel 3-sep-2002";\r
-        default:\r
-             return NULL;\r
- }\r
-}\r
-\r
-\r
-\r
-/**********************************************************************/\r
-/*****              Miscellaneous device driver funcs             *****/\r
-/*****           Note that these functions are mandatory          *****/\r
-/**********************************************************************/\r
-\r
-\r
-\r
-/* OPTIONAL FUNCTION: implements glFinish if possible */\r
-static void finish (GLcontext *ctx)\r
-{\r
-/*\r
- DMesaContext c = (DMesaContext)ctx->DriverCtx;\r
-*/\r
-}\r
-\r
-\r
-\r
-/* OPTIONAL FUNCTION: implements glFlush if possible */\r
-static void flush (GLcontext *ctx)\r
-{\r
-/*\r
- DMesaContext c = (DMesaContext)ctx->DriverCtx;\r
-*/\r
-}\r
-\r
-\r
-\r
-/**********************************************************************/\r
-/**********************************************************************/\r
-\r
-\r
-\r
-#define DMESA_NEW_TRIANGLE (_NEW_POLYGON | \\r
-                            _NEW_TEXTURE | \\r
-                            _NEW_LIGHT | \\r
-                            _NEW_DEPTH | \\r
-                            _NEW_RENDERMODE | \\r
-                            _SWRAST_NEW_RASTERMASK)\r
-\r
-\r
-\r
-/* Extend the software rasterizer with our line and triangle\r
- * functions.\r
- */\r
-static void dmesa_register_swrast_functions (GLcontext *ctx)\r
-{\r
- SWcontext *swrast = SWRAST_CONTEXT(ctx);\r
-\r
- swrast->choose_triangle = dmesa_choose_tri;\r
-\r
- swrast->invalidate_triangle |= DMESA_NEW_TRIANGLE;\r
-}\r
-\r
-\r
-\r
-/* Setup pointers and other driver state that is constant for the life\r
- * of a context.\r
- */\r
-void dmesa_init_pointers (GLcontext *ctx)\r
-{\r
- TNLcontext *tnl;\r
-\r
- ctx->Driver.UpdateState = dmesa_update_state;\r
-\r
- ctx->Driver.GetString = get_string;\r
- ctx->Driver.GetBufferSize = get_buffer_size;\r
- ctx->Driver.Flush = flush;\r
- ctx->Driver.Finish = finish;\r
-    \r
- /* Software rasterizer pixel paths:\r
-  */\r
- ctx->Driver.Accum = _swrast_Accum;\r
- ctx->Driver.Bitmap = _swrast_Bitmap;\r
- ctx->Driver.Clear = clear;\r
- ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;\r
- ctx->Driver.CopyPixels = _swrast_CopyPixels;\r
- ctx->Driver.DrawPixels = _swrast_DrawPixels;\r
- ctx->Driver.ReadPixels = _swrast_ReadPixels;\r
-\r
- /* Software texture functions:\r
-  */\r
- ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;\r
- ctx->Driver.TexImage1D = _mesa_store_teximage1d;\r
- ctx->Driver.TexImage2D = _mesa_store_teximage2d;\r
- ctx->Driver.TexImage3D = _mesa_store_teximage3d;\r
- ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;\r
- ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;\r
- ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;\r
- ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;\r
-\r
- ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d;\r
- ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d;\r
- ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d;\r
- ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d;\r
- ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d;\r
- ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d;\r
-\r
- ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;\r
- ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;\r
- ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;\r
- ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;\r
- ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;\r
-\r
- /* Swrast hooks for imaging extensions:\r
-  */\r
- ctx->Driver.CopyColorTable = _swrast_CopyColorTable;\r
- ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;\r
- ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;\r
- ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;\r
-\r
- /* Statechange callbacks:\r
-  */\r
- ctx->Driver.SetDrawBuffer = set_draw_buffer;\r
- ctx->Driver.ClearColor = clear_color;\r
-\r
- /* Initialize the TNL driver interface:\r
-  */\r
- tnl = TNL_CONTEXT(ctx);\r
- tnl->Driver.RunPipeline = _tnl_run_pipeline;\r
-   \r
- /* Install swsetup for tnl->Driver.Render.*:\r
-  */\r
- _swsetup_Wakeup(ctx);\r
-}\r
-\r
-\r
-\r
-static void dmesa_update_state (GLcontext *ctx, GLuint new_state)\r
-{\r
- DMesaContext c = (DMesaContext)ctx->DriverCtx;\r
- struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);\r
-\r
- /* Initialize all the pointers in the DD struct.  Do this whenever */\r
- /* a new context is made current or we change buffers via set_buffer! */\r
-\r
- _swrast_InvalidateState(ctx, new_state);\r
- _swsetup_InvalidateState(ctx, new_state);\r
- _ac_InvalidateState(ctx, new_state);\r
- _tnl_InvalidateState(ctx, new_state);\r
-\r
- swdd->SetReadBuffer = set_read_buffer;\r
-\r
- /* RGB(A) span/pixel functions */\r
- swdd->WriteRGBASpan = write_rgba_span;\r
- swdd->WriteRGBSpan = write_rgb_span;\r
- swdd->WriteMonoRGBASpan = write_mono_rgba_span;\r
- swdd->WriteRGBAPixels = write_rgba_pixels;\r
- swdd->WriteMonoRGBAPixels = write_mono_rgba_pixels;\r
- swdd->ReadRGBASpan = read_rgba_span;\r
- swdd->ReadRGBAPixels = read_rgba_pixels;\r
-}\r
-\r
-\r
-\r
-/**********************************************************************/\r
-/*****               DMesa Public API Functions                   *****/\r
-/**********************************************************************/\r
-\r
-\r
-\r
-/*\r
- * The exact arguments to this function will depend on your window system\r
- */\r
-DMesaVisual DMesaCreateVisual (GLint width, GLint height, GLint colDepth,\r
-                               GLboolean dbFlag, GLint depthSize,\r
-                               GLint stencilSize,\r
-                               GLint accumSize)\r
-{\r
- DMesaVisual v;\r
- GLint redBits, greenBits, blueBits, alphaBits;\r
-\r
- int refresh;\r
- char *var = getenv("DMESA_REFRESH");\r
- if ((var == NULL) || ((refresh=atoi(var)) == 0)) {\r
-    refresh = 60;\r
- }\r
-\r
- if (!dbFlag) {\r
-    return NULL;\r
- }\r
- alphaBits = 0;\r
- switch (colDepth) {\r
-        case 15:\r
-             redBits = 5;\r
-             greenBits = 5;\r
-             blueBits = 5;\r
-             break;\r
-        case 16:\r
-             redBits = 5;\r
-             greenBits = 6;\r
-             blueBits = 5;\r
-             break;\r
-        case 32:\r
-             alphaBits = 8;\r
-        case 24:\r
-             redBits = 8;\r
-             greenBits = 8;\r
-             blueBits = 8;\r
-             break;\r
-        default:\r
-             return NULL;\r
- }\r
-\r
- if (vl_video_init(width, height, colDepth, refresh) != 0) {\r
-    return NULL;\r
- }\r
-\r
- if ((v=(DMesaVisual)calloc(1, sizeof(struct dmesa_visual)))!=NULL) {\r
-    /* Create core visual */\r
-    v->gl_visual = _mesa_create_visual(colDepth>8,             /* rgb */\r
-                                       dbFlag,\r
-                                       GL_FALSE,               /* stereo */\r
-                                       redBits,\r
-                                       greenBits,\r
-                                       blueBits,\r
-                                       alphaBits,\r
-                                       0,                      /* indexBits */\r
-                                       depthSize,\r
-                                       stencilSize,\r
-                                       accumSize,              /* accumRed */\r
-                                       accumSize,              /* accumGreen */\r
-                                       accumSize,              /* accumBlue */\r
-                                       alphaBits?accumSize:0,  /* accumAlpha */\r
-                                       1);                     /* numSamples */\r
-\r
-    v->depth = colDepth;\r
-    v->db_flag = dbFlag;\r
- }\r
-\r
- return v;\r
-}\r
-\r
-\r
-\r
-void DMesaDestroyVisual (DMesaVisual v)\r
-{\r
- vl_video_exit();\r
- _mesa_destroy_visual(v->gl_visual);\r
- free(v);\r
-}\r
-\r
-\r
-\r
-DMesaBuffer DMesaCreateBuffer (DMesaVisual visual,\r
-                               GLint xpos, GLint ypos,\r
-                               GLint width, GLint height)\r
-{\r
- DMesaBuffer b;\r
-\r
- if ((b=(DMesaBuffer)calloc(1, sizeof(struct dmesa_buffer)))!=NULL) {\r
-\r
-    _mesa_initialize_framebuffer(&b->gl_buffer,\r
-                                 visual->gl_visual,\r
-                                 visual->gl_visual->depthBits > 0,\r
-                                 visual->gl_visual->stencilBits > 0,\r
-                                 visual->gl_visual->accumRedBits > 0,\r
-                                 visual->gl_visual->alphaBits > 0);\r
-    b->xpos = xpos;\r
-    b->ypos = ypos;\r
-    b->width = width;\r
-    b->height = height;\r
-    b->bypp = (visual->depth+7)/8;\r
- }\r
-\r
- return b;\r
-}\r
-\r
-\r
-\r
-void DMesaDestroyBuffer (DMesaBuffer b)\r
-{\r
- free(b->the_window);\r
- _mesa_free_framebuffer_data(&b->gl_buffer);\r
- free(b);\r
-}\r
-\r
-\r
-\r
-DMesaContext DMesaCreateContext (DMesaVisual visual,\r
-                                 DMesaContext share)\r
-{\r
- DMesaContext c;\r
- GLboolean direct = GL_FALSE;\r
-\r
- if ((c=(DMesaContext)calloc(1, sizeof(struct dmesa_context)))!=NULL) {\r
-    c->gl_ctx = _mesa_create_context(visual->gl_visual,\r
-                                     share ? share->gl_ctx : NULL,\r
-                                     (void *)c, direct);\r
-\r
-    _mesa_enable_sw_extensions(c->gl_ctx);\r
-    _mesa_enable_1_3_extensions(c->gl_ctx);\r
-\r
-   /* you probably have to do a bunch of other initializations here. */\r
-    c->visual = visual;\r
-\r
-   /* Initialize the software rasterizer and helper modules.\r
-    */\r
-    _swrast_CreateContext(c->gl_ctx);\r
-    _ac_CreateContext(c->gl_ctx);\r
-    _tnl_CreateContext(c->gl_ctx);\r
-    _swsetup_CreateContext(c->gl_ctx);\r
-    dmesa_init_pointers(c->gl_ctx);\r
-    dmesa_register_swrast_functions(c->gl_ctx);\r
- }\r
-\r
- return c;\r
-}\r
-\r
-\r
-\r
-void DMesaDestroyContext (DMesaContext c)\r
-{\r
- _mesa_destroy_context(c->gl_ctx);\r
- free(c);\r
-}\r
-\r
-\r
-\r
-GLboolean DMesaViewport (DMesaBuffer b,\r
-                         GLint xpos, GLint ypos,\r
-                         GLint width, GLint height)\r
-{\r
- void *new_window;\r
-\r
- if ((new_window=vl_sync_buffer(b->the_window, xpos, ypos, width, height))==NULL) {\r
-    return GL_FALSE;\r
- } else {\r
-    b->the_window = new_window;\r
-    b->xpos = xpos;\r
-    b->ypos = ypos;\r
-    b->width = width;\r
-    b->height = height;\r
-    b->stride = width * b->bypp;\r
-    b->bytes = b->stride * height;\r
-    return GL_TRUE;\r
- }\r
-}\r
-\r
-\r
-\r
-/*\r
- * Make the specified context and buffer the current one.\r
- */\r
-GLboolean DMesaMakeCurrent (DMesaContext c, DMesaBuffer b)\r
-{\r
- if (c&&b) {\r
-    if (!DMesaViewport(b, b->xpos, b->ypos, b->width, b->height)) {\r
-       return GL_FALSE;\r
-    }\r
-\r
-    c->Buffer = b;\r
-\r
-    dmesa_update_state(c->gl_ctx, 0);\r
-    _mesa_make_current(c->gl_ctx, &b->gl_buffer);\r
-    if (c->gl_ctx->Viewport.Width==0) {\r
-       /* initialize viewport to window size */\r
-       _mesa_Viewport(0, 0, b->width, b->height);\r
-    }\r
- } else {\r
-    /* Detach */\r
-    _mesa_make_current(NULL, NULL);\r
- }\r
-\r
- return GL_TRUE;\r
-}\r
-\r
-\r
-\r
-void DMesaSwapBuffers (DMesaBuffer b)\r
-{\r
- /* copy/swap back buffer to front if applicable */\r
- GET_CURRENT_CONTEXT(ctx);\r
- _mesa_swapbuffers(ctx);\r
- vl_flip(b->the_window, b->stride, b->height);\r
-}\r
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.3
+ * 
+ * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * DOS/DJGPP device driver for Mesa
+ *
+ *  Author: Daniel Borca
+ *  Email : dborca@users.sourceforge.net
+ *  Web   : http://www.geocities.com/dborca
+ */
+
+
+#include "context.h"
+#include "imports.h"
+#include "mtypes.h"
+
+#include "video.h"
+
+#include "GL/osmesa.h"
+#include "GL/dmesa.h"
+
+
+/*
+ * This has nothing to do with Mesa Visual structure.
+ * We keep this one around for backwards compatibility,
+ * and to store video mode data for DMesaCreateContext.
+ */
+struct dmesa_visual {
+    GLenum format;             /* OSMesa framebuffer format */
+    GLint depthBits;
+    GLint stencilBits;
+    GLint accumBits;
+};
+
+/*
+ * This has nothing to do with Mesa Buffer structure.
+ * We keep this one around for backwards compatibility,
+ * and to store various data.
+ */
+struct dmesa_buffer {
+    int xpos, ypos;              /* position */
+    int width, height;           /* size in pixels */
+    GLenum type;
+    void *the_window;            /* your window handle, etc */
+};
+
+/*
+ * This has nothing to do with Mesa Context structure.
+ * We keep this one around for backwards compatibility,
+ * and to store real off-screen context.
+ */
+struct dmesa_context {
+    OSMesaContext osmesa;
+    DMesaBuffer buffer;
+};
+
+
+static DMesaContext ctx;
+
+
+/****************************************************************************
+ * DMesa Public API Functions
+ ***************************************************************************/
+
+/*
+ * The exact arguments to this function will depend on your window system
+ */
+DMesaVisual
+DMesaCreateVisual (GLint width,
+                   GLint height,
+                   GLint colDepth,
+                   GLint refresh,
+                   GLboolean dbFlag,
+                   GLboolean rgbFlag,
+                   GLint alphaSize,
+                   GLint depthSize,
+                   GLint stencilSize,
+                   GLint accumSize)
+{
+    DMesaVisual visual;
+    GLenum format;
+    int fbbits;
+
+    if (dbFlag) {
+       return NULL;
+    }
+
+    if (!rgbFlag) {
+       format = OSMESA_COLOR_INDEX;
+       fbbits = 8;
+    } else if (alphaSize) {
+       format = OSMESA_BGRA;
+       fbbits = 32;
+    } else if (colDepth == 15 || colDepth == 16) {
+       format = OSMESA_RGB_565;
+       fbbits = 16;
+    } else {
+       format = OSMESA_BGR;
+       fbbits = 24;
+    }
+
+    if ((visual = (DMesaVisual)CALLOC_STRUCT(dmesa_visual)) == NULL) {
+       return NULL;
+    }
+
+    if (vl_video_init(width, height, colDepth, rgbFlag, refresh, fbbits) <= 0) {
+       FREE(visual);
+       return NULL;
+    }
+
+    visual->format = format;
+    visual->depthBits = depthSize;
+    visual->stencilBits = stencilSize;
+    visual->accumBits = accumSize;
+    return visual;
+}
+
+
+void
+DMesaDestroyVisual (DMesaVisual visual)
+{
+   vl_video_exit();
+   FREE(visual);
+}
+
+
+DMesaBuffer
+DMesaCreateBuffer (DMesaVisual visual,
+                   GLint xpos, GLint ypos,
+                   GLint width, GLint height)
+{
+    DMesaBuffer buffer;
+    GLenum type;
+    int bytesPerPixel;
+
+    switch (visual->format) {
+       case OSMESA_COLOR_INDEX:
+           bytesPerPixel = 1;
+           type = CHAN_TYPE;
+           break;
+       case OSMESA_RGB_565:
+           bytesPerPixel = 2;
+           type = GL_UNSIGNED_SHORT_5_6_5;
+           break;
+       case OSMESA_BGR:
+           bytesPerPixel = 3;
+           type = CHAN_TYPE;
+           break;
+       default:
+           bytesPerPixel = 4;
+           type = CHAN_TYPE;
+    }
+
+    if ((buffer = (DMesaBuffer)CALLOC_STRUCT(dmesa_buffer)) != NULL) {
+       buffer->xpos = xpos;
+       buffer->ypos = ypos;
+       buffer->width = width;
+       buffer->height = height;
+       buffer->type = type;
+       buffer->the_window = MALLOC(width * height * bytesPerPixel + 1);
+       if (buffer->the_window == NULL) {
+           FREE(buffer);
+           buffer = NULL;
+       }
+    }
+
+    return buffer;
+}
+
+
+void
+DMesaDestroyBuffer (DMesaBuffer buffer)
+{
+    FREE(buffer->the_window);
+    FREE(buffer);
+}
+
+
+DMesaContext
+DMesaCreateContext (DMesaVisual visual, DMesaContext share)
+{
+    DMesaContext dmesa;
+    if ((dmesa = (DMesaContext)CALLOC_STRUCT(dmesa_context)) != NULL) {
+       dmesa->osmesa = OSMesaCreateContextExt(
+                               visual->format,
+                               visual->depthBits,
+                               visual->stencilBits,
+                               visual->accumBits,
+                               (share != NULL) ? share->osmesa : NULL);
+       if (dmesa->osmesa == NULL) {
+           FREE(dmesa);
+           dmesa = NULL;
+       }
+    }
+    return dmesa;
+}
+
+
+void
+DMesaDestroyContext (DMesaContext dmesa)
+{
+    OSMesaDestroyContext(dmesa->osmesa);
+    FREE(dmesa);
+}
+
+
+GLboolean
+DMesaMoveBuffer (GLint xpos, GLint ypos)
+{
+    const DMesaContext dmesa = DMesaGetCurrentContext();
+    DMesaBuffer b = dmesa->buffer;
+
+    if (vl_sync_buffer(&b->the_window, xpos, ypos, b->width, b->height) == 0) {
+       b->xpos = xpos;
+       b->ypos = ypos;
+       return GL_TRUE;
+    }
+
+    return GL_FALSE;
+}
+
+
+GLboolean
+DMesaResizeBuffer (GLint width, GLint height)
+{
+    const DMesaContext dmesa = DMesaGetCurrentContext();
+    DMesaBuffer b = dmesa->buffer;
+
+    if (vl_sync_buffer(&b->the_window, b->xpos, b->ypos, width, height) == 0) {
+       b->width = width;
+       b->height = height;
+       return GL_TRUE;
+    }
+
+    return GL_FALSE;
+}
+
+
+GLboolean
+DMesaMakeCurrent (DMesaContext dmesa, DMesaBuffer buffer)
+{
+    if (dmesa == NULL || buffer == NULL) {
+       ctx = NULL;
+       return GL_TRUE;
+    }
+    if (OSMesaMakeCurrent(dmesa->osmesa, buffer->the_window,
+                         buffer->type,
+                         buffer->width, buffer->height) &&
+       vl_sync_buffer(&buffer->the_window, buffer->xpos, buffer->ypos, buffer->width, buffer->height) == 0) {
+       OSMesaPixelStore(OSMESA_Y_UP, GL_FALSE);
+       dmesa->buffer = buffer;
+       ctx = dmesa;
+       return GL_TRUE;
+    }
+    return GL_FALSE;
+}
+
+
+void
+DMesaSwapBuffers (DMesaBuffer buffer)
+{
+    /* copy/swap back buffer to front if applicable */
+    GET_CURRENT_CONTEXT(ctx);
+    _mesa_notifySwapBuffers(ctx);
+    vl_flip();
+    (void)buffer;
+}
+
+
+void
+DMesaSetCI (int ndx, GLfloat red, GLfloat green, GLfloat blue)
+{
+    vl_setCI(ndx, red, green, blue);
+}
+
+
+DMesaContext
+DMesaGetCurrentContext (void)
+{
+   return ctx;
+}
+
+
+DMesaBuffer
+DMesaGetCurrentBuffer (void)
+{
+    const DMesaContext dmesa = DMesaGetCurrentContext();
+
+    if (dmesa != NULL) {
+       return dmesa->buffer;
+    }
+
+    return NULL;
+}
+
+
+DMesaProc
+DMesaGetProcAddress (const char *name)
+{
+   DMesaProc p = (DMesaProc)_glapi_get_proc_address(name);
+
+   /* TODO: handle DMesa* namespace
+   if (p == NULL) {
+   }
+   */
+
+   return p;
+}
+
+
+int
+DMesaGetIntegerv (GLenum pname, GLint *params)
+{
+    switch (pname) {
+       case DMESA_GET_SCREEN_SIZE:
+           vl_get(VL_GET_SCREEN_SIZE, params);
+           break;
+       case DMESA_GET_DRIVER_CAPS:
+           params[0] = 0;
+           break;
+       case DMESA_GET_VIDEO_MODES:
+           return vl_get(VL_GET_VIDEO_MODES, params);
+       case DMESA_GET_BUFFER_ADDR: {
+           const DMesaContext dmesa = DMesaGetCurrentContext();
+           if (dmesa != NULL) {
+               DMesaBuffer b = dmesa->buffer;
+               if (b != NULL) {
+                   params[0] = (GLint)b->the_window;
+               }
+           }
+           break;
+       }
+       default:
+           return -1;
+    }
+
+    return 0;
+}