updated some printfs, added comment about sched_yield
[mesa.git] / src / mesa / drivers / beos / GLView.cpp
index 37f2fd5dae2f9f321087adda7f9c2c40b76f4714..45473a8ef279d47f5f6399261e91d157dc84d45c 100644 (file)
@@ -1,10 +1,8 @@
-/* $Id: GLView.cpp,v 1.7 2002/10/17 14:25:30 brianp Exp $ */
-
 /*
  * Mesa 3-D graphics library
- * Version:  4.1
+ * Version:  6.1
  * 
- * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
+ * 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"),
  */
 
 
-#include "glheader.h"
-
 #include <assert.h>
 #include <stdio.h>
 
 extern "C" {
 
+#include "glheader.h"
+#include "version.h"
+#include "buffers.h"
+#include "bufferobj.h"
 #include "context.h"
 #include "colormac.h"
 #include "depth.h"
 #include "extensions.h"
 #include "macros.h"
 #include "matrix.h"
-#include "mem.h"
-#include "mmath.h"
 #include "mtypes.h"
 #include "texformat.h"
+#include "texobj.h"
+#include "teximage.h"
 #include "texstore.h"
 #include "array_cache/acache.h"
 #include "swrast/swrast.h"
@@ -55,24 +55,43 @@ extern "C" {
 #include "tnl/t_context.h"
 #include "tnl/t_pipeline.h"
 
+#include "drivers/common/driverfuncs.h"
+
 }      // extern "C"
 
+#include <interface/Screen.h>
 #include <GLView.h>
 
 // BeOS component ordering for B_RGBA32 bitmap format
-#define BE_RCOMP 2
-#define BE_GCOMP 1
-#define BE_BCOMP 0
-#define BE_ACOMP 3
+#if B_HOST_IS_LENDIAN
+       #define BE_RCOMP 2
+       #define BE_GCOMP 1
+       #define BE_BCOMP 0
+       #define BE_ACOMP 3
 
-#define PACK_B_RGBA32(color) (color[BCOMP] | (color[GCOMP] << 8) | \
+       #define PACK_B_RGBA32(color) (color[BCOMP] | (color[GCOMP] << 8) | \
                                                        (color[RCOMP] << 16) | (color[ACOMP] << 24))
 
-#define PACK_B_RGB32(color) (color[BCOMP] | (color[GCOMP] << 8) | \
-                                                       (color[RCOMP] << 16) | 0xFF000000)
+       #define PACK_B_RGB32(color) (color[BCOMP] | (color[GCOMP] << 8) | \
+                                                       (color[RCOMP] << 16) | 0xFF000000)
+#else
+       // Big Endian B_RGBA32 bitmap format
+       #define BE_RCOMP 1
+       #define BE_GCOMP 2
+       #define BE_BCOMP 3
+       #define BE_ACOMP 0
+
+       #define PACK_B_RGBA32(color) (color[ACOMP] | (color[RCOMP] << 8) | \
+                                                       (color[GCOMP] << 16) | (color[BCOMP] << 24))
+
+       #define PACK_B_RGB32(color) ((color[RCOMP] << 8) | (color[GCOMP] << 16) | \
+                                                       (color[BCOMP] << 24) | 0xFF000000)
+#endif
 
 #define FLIP(coord) (LIBGGI_MODE(ggi_ctx->ggi_visual)->visible.y-(coord) - 1) 
 
+const char * color_space_name(color_space space);
+
 //
 // This object hangs off of the BGLView object.  We have to use
 // Be's BGLView class as-is to maintain binary compatibility (we
@@ -81,14 +100,19 @@ extern "C" {
 //
 class MesaDriver
 {
+friend class BGLView;
 public:
        MesaDriver();
        ~MesaDriver();
-       void Init(BGLView * bglview, GLcontext * c, GLvisual * v, GLframebuffer * b);
+       
+       void            Init(BGLView * bglview, GLcontext * c, GLvisual * v, GLframebuffer * b);
+
+       void            LockGL();
+       void            UnlockGL();
+       void            SwapBuffers() const;
+       status_t        CopyPixelsOut(BPoint source, BBitmap *dest);
+       status_t        CopyPixelsIn(BBitmap *source, BPoint dest);
 
-       void LockGL();
-       void UnlockGL();
-       void SwapBuffers() const;
        void CopySubBuffer(GLint x, GLint y, GLuint width, GLuint height) const;
        void Draw(BRect updateRect) const;
 
@@ -109,7 +133,7 @@ private:
        GLuint                  m_width;
        GLuint                  m_height;
        
-   // Mesa Device Driver functions
+   // Mesa Device Driver callback functions
    static void                 UpdateState(GLcontext *ctx, GLuint new_state);
    static void                 ClearIndex(GLcontext *ctx, GLuint index);
    static void                 ClearColor(GLcontext *ctx, const GLfloat color[4]);
@@ -127,7 +151,9 @@ private:
                              GLenum mode);
    static void                 GetBufferSize(GLframebuffer * framebuffer, GLuint *width,
                              GLuint *height);
+   static void         Error(GLcontext *ctx);
    static const GLubyte *      GetString(GLcontext *ctx, GLenum name);
+   static void          Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h);
 
    // Front-buffer functions
    static void                 WriteRGBASpanFront(const GLcontext *ctx, GLuint n,
@@ -241,27 +267,34 @@ private:
 BGLView::BGLView(BRect rect, char *name,
                  ulong resizingMode, ulong mode,
                  ulong options)
-   :BView(rect, name, resizingMode, mode | B_WILL_DRAW | B_FRAME_EVENTS) //  | B_FULL_UPDATE_ON_RESIZE)
+   : BView(rect, name, B_FOLLOW_ALL_SIDES, mode | B_WILL_DRAW | B_FRAME_EVENTS) //  | B_FULL_UPDATE_ON_RESIZE)
 {
-   const GLboolean rgbFlag = (options & BGL_RGB) == BGL_RGB;
-   const GLboolean alphaFlag = (options & BGL_ALPHA) == BGL_ALPHA;
-   const GLboolean dblFlag = (options & BGL_DOUBLE) == BGL_DOUBLE;
+       // We don't support single buffering (yet): double buffering forced.
+       options |= BGL_DOUBLE;
+
+   const GLboolean rgbFlag = ((options & BGL_INDEX) == 0);
+   const GLboolean alphaFlag = ((options & BGL_ALPHA) == BGL_ALPHA);
+   const GLboolean dblFlag = ((options & BGL_DOUBLE) == BGL_DOUBLE);
    const GLboolean stereoFlag = false;
    const GLint depth = (options & BGL_DEPTH) ? 16 : 0;
    const GLint stencil = (options & BGL_STENCIL) ? 8 : 0;
    const GLint accum = (options & BGL_ACCUM) ? 16 : 0;
    const GLint index = (options & BGL_INDEX) ? 32 : 0;
-   const GLint red = (options & BGL_RGB) ? 8 : 0;
-   const GLint green = (options & BGL_RGB) ? 8 : 0;
-   const GLint blue = (options & BGL_RGB) ? 8 : 0;
-   const GLint alpha = (options & BGL_RGB) ? 8 : 0;
+   const GLint red = rgbFlag ? 8 : 0;
+   const GLint green = rgbFlag ? 8 : 0;
+   const GLint blue = rgbFlag ? 8 : 0;
+   const GLint alpha = alphaFlag ? 8 : 0;
+
+       m_options = options | BGL_INDIRECT;
 
+   struct dd_function_table functions;
    if (!rgbFlag) {
       fprintf(stderr, "Mesa Warning: color index mode not supported\n");
    }
 
    // Allocate auxiliary data object
-   MesaDriver * md = new MesaDriver;
+   MesaDriver * md = new MesaDriver();
 
    // examine option flags and create gl_context struct
    GLvisual * visual = _mesa_create_visual( rgbFlag,
@@ -275,10 +308,29 @@ BGLView::BGLView(BRect rect, char *name,
                                             1
                                             );
 
-   // create core context
-   __GLimports imports;
-   _mesa_init_default_imports(&imports, md);
-   GLcontext * ctx = _mesa_create_context( visual, NULL, &imports);
+       // Initialize device driver function table
+       _mesa_init_driver_functions(&functions);
+
+       functions.GetString     = md->GetString;
+       functions.UpdateState   = md->UpdateState;
+       functions.GetBufferSize = md->GetBufferSize;
+       functions.Clear                 = md->Clear;
+       functions.ClearIndex    = md->ClearIndex;
+       functions.ClearColor    = md->ClearColor;
+       functions.Error                 = md->Error;
+        functions.Viewport      = md->Viewport;
+
+       // create core context
+       GLcontext *ctx = _mesa_create_context(visual, NULL, &functions, md);
+       if (! ctx) {
+         _mesa_destroy_visual(visual);
+         delete md;
+         return;
+      }
+   _mesa_enable_sw_extensions(ctx);
+   _mesa_enable_1_3_extensions(ctx);
+   _mesa_enable_1_4_extensions(ctx);
+   _mesa_enable_1_5_extensions(ctx);
 
 
    // create core framebuffer
@@ -289,10 +341,6 @@ BGLView::BGLView(BRect rect, char *name,
                                               alphaFlag
                                               );
 
-   _mesa_enable_sw_extensions(ctx);
-   _mesa_enable_1_3_extensions(ctx);
-   //_mesa_enable_1_4_extensions(ctx);
-
    /* Initialize the software rasterizer and helper modules.
     */
    _swrast_CreateContext(ctx);
@@ -305,12 +353,21 @@ BGLView::BGLView(BRect rect, char *name,
 
    // Hook aux data into BGLView object
    m_gc = md;
+
+   // some stupid applications (Quake2) don't even think about calling LockGL()
+   // before using glGetString and friends... so make sure there is at least a
+   // valid context.
+   if (!_mesa_get_current_context()) {
+      LockGL();
+      // not needed, we don't have a looper yet: UnlockLooper();
+   }
+
 }
 
 
 BGLView::~BGLView()
 {
-   printf("BGLView destructor\n");
+   // printf("BGLView destructor\n");
    MesaDriver * md = (MesaDriver *) m_gc;
    assert(md);
    delete md;
@@ -332,45 +389,63 @@ void BGLView::UnlockGL()
 
 void BGLView::SwapBuffers()
 {
-   MesaDriver * md = (MesaDriver *) m_gc;
-   assert(md);
-   md->SwapBuffers();
+       SwapBuffers(false);
 }
 
+void BGLView::SwapBuffers(bool vSync)
+{
+       MesaDriver * md = (MesaDriver *) m_gc;
+       assert(md);
+       md->SwapBuffers();
+
+       if (vSync) {
+               BScreen screen(Window());
+               screen.WaitForRetrace();
+       }
+}
 
+
+#if 0
 void BGLView::CopySubBufferMESA(GLint x, GLint y, GLuint width, GLuint height)
 {
    MesaDriver * md = (MesaDriver *) m_gc;
    assert(md);
    md->CopySubBuffer(x, y, width, height);
 }
-
+#endif
 
 BView *        BGLView::EmbeddedView()
 {
-   // XXX to do
        return NULL;
 }
 
 status_t BGLView::CopyPixelsOut(BPoint source, BBitmap *dest)
 {
-   // XXX to do
-       printf("BGLView::CopyPixelsOut() not implemented yet!\n");
-       return B_UNSUPPORTED;
-}
+       if (! dest || ! dest->Bounds().IsValid())
+               return B_BAD_VALUE;
 
+       MesaDriver * md = (MesaDriver *) m_gc;
+       assert(md);
+       return md->CopyPixelsOut(source, dest);
+}
 
 status_t BGLView::CopyPixelsIn(BBitmap *source, BPoint dest)
 {
-   // XXX to do
-       printf("BGLView::CopyPixelsIn() not implemented yet!\n");
-       return B_UNSUPPORTED;
+       if (! source || ! source->Bounds().IsValid())
+               return B_BAD_VALUE;
+
+       MesaDriver * md = (MesaDriver *) m_gc;
+       assert(md);
+       return md->CopyPixelsIn(source, dest);
 }
 
-void BGLView::ErrorCallback(unsigned long errorCode) // GLenum errorCode)
+
+void BGLView::ErrorCallback(unsigned long errorCode) // Mesa's GLenum is not ulong but uint!
 {
-   // XXX to do
-       printf("BGLView::ErrorCallback() not implemented yet!\n");
+       char msg[32];
+       sprintf(msg, "GL: Error code $%04lx.", errorCode);
+       // debugger(msg);
+       fprintf(stderr, "%s\n", msg);
        return;
 }
 
@@ -435,13 +510,11 @@ void BGLView::SetResizingMode(uint32 mode)
 
 void BGLView::Show()
 {
-//   printf("BGLView Show\n");
    BView::Show();
 }
 
 void BGLView::Hide()
 {
-//   printf("BGLView Hide\n");
    BView::Hide();
 }
 
@@ -459,17 +532,44 @@ status_t BGLView::GetSupportedSuites(BMessage *data)
 
 void BGLView::DirectConnected( direct_buffer_info *info )
 {
-   // XXX to do
+#if 0
+       if (! m_direct_connected && m_direct_connection_disabled) 
+               return; 
+
+       direct_info_locker->Lock(); 
+       switch(info->buffer_state & B_DIRECT_MODE_MASK) { 
+       case B_DIRECT_START: 
+               m_direct_connected = true;
+       case B_DIRECT_MODIFY: 
+               // Get clipping information 
+               if (m_clip_list)
+                       free(m_clip_list); 
+               m_clip_list_count = info->clip_list_count; 
+               m_clip_list = (clipping_rect *) malloc(m_clip_list_count*sizeof(clipping_rect)); 
+               if (m_clip_list) { 
+                       memcpy(m_clip_list, info->clip_list, m_clip_list_count*sizeof(clipping_rect));
+                       fBits = (uint8 *) info->bits; 
+                       fRowBytes = info->bytes_per_row; 
+                       fFormat = info->pixel_format; 
+                       fBounds = info->window_bounds; 
+                       fDirty = true; 
+               } 
+               break; 
+       case B_DIRECT_STOP: 
+               fConnected = false; 
+               break; 
+       } 
+       direct_info_locker->Unlock(); 
+#endif
 }
 
 void BGLView::EnableDirectMode( bool enabled )
 {
-   // XXX to do
+   // TODO
 }
 
 
-
-//---- private methods ----------
+//---- virtual reserved methods ----------
 
 void BGLView::_ReservedGLView1() {}
 void BGLView::_ReservedGLView2() {}
@@ -481,20 +581,21 @@ void BGLView::_ReservedGLView7() {}
 void BGLView::_ReservedGLView8() {}
 
 #if 0
+// Not implemented!!!
+
 BGLView::BGLView(const BGLView &v)
        : BView(v)
 {
    // XXX not sure how this should work
    printf("Warning BGLView::copy constructor not implemented\n");
 }
-#endif
-
 
 BGLView &BGLView::operator=(const BGLView &v)
 {
    printf("Warning BGLView::operator= not implemented\n");
        return *this;
 }
+#endif
 
 void BGLView::dither_front()
 {
@@ -564,7 +665,8 @@ MesaDriver::~MesaDriver()
    _mesa_destroy_visual(m_glvisual);
    _mesa_destroy_framebuffer(m_glframebuffer);
    _mesa_destroy_context(m_glcontext);
-
+   
+   delete m_bitmap;
 }
 
 
@@ -580,52 +682,13 @@ void MesaDriver::Init(BGLView * bglview, GLcontext * ctx, GLvisual * visual, GLf
        TNLcontext * tnl = TNL_CONTEXT(ctx);
 
        assert(md->m_glcontext == ctx );
+       assert(tnl);
+       assert(swdd);
 
-       ctx->Driver.GetString = MesaDriver::GetString;
-       ctx->Driver.UpdateState = MesaDriver::UpdateState;
-       ctx->Driver.GetBufferSize = MesaDriver::GetBufferSize;
-       ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
-
-       ctx->Driver.Accum = _swrast_Accum;
-       ctx->Driver.Bitmap = _swrast_Bitmap;
-       ctx->Driver.ClearIndex = MesaDriver::ClearIndex;
-       ctx->Driver.ClearColor = MesaDriver::ClearColor;
-       ctx->Driver.Clear = MesaDriver::Clear;
-       ctx->Driver.CopyPixels = _swrast_CopyPixels;
-       ctx->Driver.DrawPixels = _swrast_DrawPixels;
-       ctx->Driver.ReadPixels = _swrast_ReadPixels;
-
-       ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
-       ctx->Driver.TexImage1D = _mesa_store_teximage1d;
-       ctx->Driver.TexImage2D = _mesa_store_teximage2d;
-       ctx->Driver.TexImage3D = _mesa_store_teximage3d;
-       ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
-       ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
-       ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
-       ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
-
-       ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
-       ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
-       ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
-       ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
-       ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
-       ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
-       ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
-       ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
-       ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
-
-        ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d;
-        ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d;
-        ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d;
-        ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d;
-        ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d;
-        ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d;
-
-       swdd->SetBuffer = MesaDriver::SetBuffer;
-
+       // Use default TCL pipeline
        tnl->Driver.RunPipeline = _tnl_run_pipeline;
-
-       _swsetup_Wakeup(ctx);
+       swdd->SetBuffer = this->SetBuffer;
 }
 
 
@@ -640,7 +703,8 @@ void MesaDriver::LockGL()
 
 void MesaDriver::UnlockGL()
 {
-       m_bglview->UnlockLooper();
+       if (m_bglview->Looper()->IsLocked())
+               m_bglview->UnlockLooper();
    // Could call _mesa_make_current(NULL, NULL) but it would just
    // hinder performance
 }
@@ -648,11 +712,11 @@ void MesaDriver::UnlockGL()
 
 void MesaDriver::SwapBuffers() const
 {
-       // _mesa_swap_buffers();
+    _mesa_notifySwapBuffers(m_glcontext);
 
        if (m_bitmap) {
                m_bglview->LockLooper();
-               m_bglview->DrawBitmap(m_bitmap, BPoint(0, 0));
+               m_bglview->DrawBitmap(m_bitmap);
                m_bglview->UnlockLooper();
        };
 }
@@ -673,6 +737,78 @@ void MesaDriver::CopySubBuffer(GLint x, GLint y, GLuint width, GLuint height) co
    }
 }
 
+status_t MesaDriver::CopyPixelsOut(BPoint location, BBitmap *bitmap)
+{
+       color_space scs = m_bitmap->ColorSpace();
+       color_space dcs = bitmap->ColorSpace();
+
+       if (scs != dcs && (scs != B_RGBA32 || dcs != B_RGB32)) {
+               printf("CopyPixelsOut(): incompatible color space: %s != %s\n",
+                       color_space_name(scs),
+                       color_space_name(dcs));
+               return B_BAD_TYPE;
+       }
+       
+       // debugger("CopyPixelsOut()");
+       
+       BRect sr = m_bitmap->Bounds();
+       BRect dr = bitmap->Bounds();
+
+       sr = sr & dr.OffsetBySelf(location);
+       dr = sr.OffsetByCopy(-location.x, -location.y); 
+       
+       uint8 *ps = (uint8 *) m_bitmap->Bits();
+       uint8 *pd = (uint8 *) bitmap->Bits();
+       uint32 *s, *d;
+       uint32 y;
+       for (y = (uint32) sr.top; y <= (uint32) sr.bottom; y++) {
+               s = (uint32 *) (ps + y * m_bitmap->BytesPerRow());
+               s += (uint32) sr.left;
+               
+               d = (uint32 *) (pd + (y + (uint32) (dr.top - sr.top)) * bitmap->BytesPerRow());
+               d += (uint32) dr.left;
+               
+               memcpy(d, s, dr.IntegerWidth() * 4);
+       }
+       return B_OK;
+}
+
+status_t MesaDriver::CopyPixelsIn(BBitmap *bitmap, BPoint location)
+{
+       color_space scs = bitmap->ColorSpace();
+       color_space dcs = m_bitmap->ColorSpace();
+
+       if (scs != dcs && (dcs != B_RGBA32 || scs != B_RGB32)) {
+               printf("CopyPixelsIn(): incompatible color space: %s != %s\n",
+                       color_space_name(scs),
+                       color_space_name(dcs));
+               return B_BAD_TYPE;
+       }
+       
+       // debugger("CopyPixelsIn()");
+
+       BRect sr = bitmap->Bounds();
+       BRect dr = m_bitmap->Bounds();
+
+       sr = sr & dr.OffsetBySelf(location);
+       dr = sr.OffsetByCopy(-location.x, -location.y); 
+       
+       uint8 *ps = (uint8 *) bitmap->Bits();
+       uint8 *pd = (uint8 *) m_bitmap->Bits();
+       uint32 *s, *d;
+       uint32 y;
+       for (y = (uint32) sr.top; y <= (uint32) sr.bottom; y++) {
+               s = (uint32 *) (ps + y * bitmap->BytesPerRow());
+               s += (uint32) sr.left;
+               
+               d = (uint32 *) (pd + (y + (uint32) (dr.top - sr.top)) * m_bitmap->BytesPerRow());
+               d += (uint32) dr.left;
+               
+               memcpy(d, s, dr.IntegerWidth() * 4);
+       }
+       return B_OK;
+}
+
 
 void MesaDriver::Draw(BRect updateRect) const
 {
@@ -681,6 +817,13 @@ void MesaDriver::Draw(BRect updateRect) const
 }
 
 
+void MesaDriver::Error(GLcontext *ctx)
+{
+       MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
+       if (md && md->m_bglview)
+               md->m_bglview->ErrorCallback((unsigned long) ctx->ErrorValue);
+}
+
 void MesaDriver::UpdateState( GLcontext *ctx, GLuint new_state )
 {
        struct swrast_device_driver *   swdd = _swrast_GetDeviceDriverReference( ctx );
@@ -690,7 +833,7 @@ void MesaDriver::UpdateState( GLcontext *ctx, GLuint new_state )
        _ac_InvalidateState( ctx, new_state );
        _tnl_InvalidateState( ctx, new_state );
 
-       if (ctx->Color.DrawBuffer == GL_FRONT) {
+       if (ctx->Color.DrawBuffer[0] == GL_FRONT) {
       /* read/write front buffer */
       swdd->WriteRGBASpan = MesaDriver::WriteRGBASpanFront;
       swdd->WriteRGBSpan = MesaDriver::WriteRGBSpanFront;
@@ -817,7 +960,7 @@ void MesaDriver::ClearBack(GLcontext *ctx,
    assert(bitmap);
    GLuint *start = (GLuint *) bitmap->Bits();
    const GLuint *clearPixelPtr = (const GLuint *) md->m_clear_color;
-   const GLuint clearPixel = *clearPixelPtr;
+   const GLuint clearPixel = B_LENDIAN_TO_HOST_INT32(*clearPixelPtr);
 
    if (all) {
       const int numPixels = md->m_width * md->m_height;
@@ -887,11 +1030,18 @@ void MesaDriver::GetBufferSize(GLframebuffer * framebuffer, GLuint *width,
 }
 
 
+void MesaDriver::Viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+{
+   /* poll for window size change and realloc software Z/stencil/etc if needed */
+   _mesa_ResizeBuffersMESA();
+}
+
+
 const GLubyte *MesaDriver::GetString(GLcontext *ctx, GLenum name)
 {
    switch (name) {
       case GL_RENDERER:
-         return (const GLubyte *) "Mesa BGLView (software)";
+         return (const GLubyte *) "Mesa " MESA_VERSION_STRING " powered BGLView (software)";
       default:
          // Let core library handle all other cases
          return NULL;
@@ -901,7 +1051,7 @@ const GLubyte *MesaDriver::GetString(GLcontext *ctx, GLenum name)
 
 // Plot a pixel.  (0,0) is upper-left corner
 // This is only used when drawing to the front buffer.
-static void Plot(BGLView *bglview, int x, int y)
+inline void Plot(BGLView *bglview, int x, int y)
 {
    // XXX There's got to be a better way!
    BPoint p(x, y), q(x+1, y);
@@ -1036,20 +1186,23 @@ void MesaDriver::WriteMonoRGBAPixelsFront(const GLcontext *ctx, GLuint n,
 void MesaDriver::WriteCI32SpanFront( const GLcontext *ctx, GLuint n, GLint x, GLint y,
                              const GLuint index[], const GLubyte mask[] )
 {
-   // XXX to do
+       printf("WriteCI32SpanFront() not implemented yet!\n");
+   // TODO
 }
 
 void MesaDriver::WriteCI8SpanFront( const GLcontext *ctx, GLuint n, GLint x, GLint y,
                             const GLubyte index[], const GLubyte mask[] )
 {
-   // XXX to do
+       printf("WriteCI8SpanFront() not implemented yet!\n");
+   // TODO
 }
 
 void MesaDriver::WriteMonoCISpanFront( const GLcontext *ctx, GLuint n,
                                     GLint x, GLint y,
                                     GLuint colorIndex, const GLubyte mask[] )
 {
-   // XXX to do
+       printf("WriteMonoCISpanFront() not implemented yet!\n");
+   // TODO
 }
 
 
@@ -1057,14 +1210,16 @@ void MesaDriver::WriteCI32PixelsFront( const GLcontext *ctx, GLuint n,
                                     const GLint x[], const GLint y[],
                                     const GLuint index[], const GLubyte mask[] )
 {
-   // XXX to do
+       printf("WriteCI32PixelsFront() not implemented yet!\n");
+   // TODO
 }
 
 void MesaDriver::WriteMonoCIPixelsFront( const GLcontext *ctx, GLuint n,
                                       const GLint x[], const GLint y[],
                                       GLuint colorIndex, const GLubyte mask[] )
 {
-   // XXX to do
+       printf("WriteMonoCIPixelsFront() not implemented yet!\n");
+   // TODO
 }
 
 
@@ -1072,7 +1227,7 @@ void MesaDriver::ReadCI32SpanFront( const GLcontext *ctx,
                                  GLuint n, GLint x, GLint y, GLuint index[] )
 {
        printf("ReadCI32SpanFront() not implemented yet!\n");
-  // XXX to do
+  // TODO
 }
 
 
@@ -1080,7 +1235,7 @@ void MesaDriver::ReadRGBASpanFront( const GLcontext *ctx, GLuint n,
                                  GLint x, GLint y, GLubyte rgba[][4] )
 {
        printf("ReadRGBASpanFront() not implemented yet!\n");
-   // XXX to do
+   // TODO
 }
 
 
@@ -1089,7 +1244,7 @@ void MesaDriver::ReadCI32PixelsFront( const GLcontext *ctx,
                                    GLuint indx[], const GLubyte mask[] )
 {
        printf("ReadCI32PixelsFront() not implemented yet!\n");
-   // XXX to do
+   // TODO
 }
 
 
@@ -1098,7 +1253,7 @@ void MesaDriver::ReadRGBAPixelsFront( const GLcontext *ctx,
                                    GLubyte rgba[][4], const GLubyte mask[] )
 {
        printf("ReadRGBAPixelsFront() not implemented yet!\n");
-   // XXX to do
+   // TODO
 }
 
 
@@ -1112,12 +1267,6 @@ void MesaDriver::WriteRGBASpanBack(const GLcontext *ctx, GLuint n,
        MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
        BBitmap *bitmap = md->m_bitmap;
 
-       static bool already_called = false;
-       if (! already_called) {
-               printf("WriteRGBASpanBack() called.\n");
-               already_called = true;
-       }
-
        assert(bitmap);
 
        int row = md->m_bottom - y;
@@ -1148,12 +1297,6 @@ void MesaDriver::WriteRGBSpanBack(const GLcontext *ctx, GLuint n,
        MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
        BBitmap *bitmap = md->m_bitmap;
 
-       static bool already_called = false;
-       if (! already_called) {
-               printf("WriteRGBSpanBack() called.\n");
-               already_called = true;
-       }
-
        assert(bitmap);
 
        int row = md->m_bottom - y;
@@ -1185,12 +1328,6 @@ void MesaDriver::WriteMonoRGBASpanBack(const GLcontext *ctx, GLuint n,
        MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
        BBitmap *bitmap = md->m_bitmap;
 
-       static bool already_called = false;
-       if (! already_called) {
-               printf("WriteMonoRGBASpanBack() called.\n");
-               already_called = true;
-       }
-
        assert(bitmap);
 
        int row = md->m_bottom - y;
@@ -1220,12 +1357,6 @@ void MesaDriver::WriteRGBAPixelsBack(const GLcontext *ctx,
    MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
    BBitmap *bitmap = md->m_bitmap;
 
-       static bool already_called = false;
-       if (! already_called) {
-               printf("WriteRGBAPixelsBack() called.\n");
-               already_called = true;
-       }
-
        assert(bitmap);
 #if 0
        while(n--) {
@@ -1273,12 +1404,6 @@ void MesaDriver::WriteMonoRGBAPixelsBack(const GLcontext *ctx, GLuint n,
        MesaDriver *md = (MesaDriver *) ctx->DriverCtx;
        BBitmap *bitmap = md->m_bitmap;
 
-       static bool already_called = false;
-       if (! already_called) {
-               printf("WriteMonoRGBAPixelsBack() called.\n");
-               already_called = true;
-       }
-
        assert(bitmap);
 
        uint32 pixel_color = PACK_B_RGBA32(color);
@@ -1318,21 +1443,24 @@ void MesaDriver::WriteCI32SpanBack( const GLcontext *ctx, GLuint n,
                                  GLint x, GLint y,
                                  const GLuint index[], const GLubyte mask[] )
 {
-   // XXX to do
+       printf("WriteCI32SpanBack() not implemented yet!\n");
+   // TODO
 }
 
 void MesaDriver::WriteCI8SpanBack( const GLcontext *ctx, GLuint n,
                                 GLint x, GLint y,
                                 const GLubyte index[], const GLubyte mask[] )
 {
-   // XXX to do
+       printf("WriteCI8SpanBack() not implemented yet!\n");
+  // TODO
 }
 
 void MesaDriver::WriteMonoCISpanBack( const GLcontext *ctx, GLuint n,
                                    GLint x, GLint y,
                                    GLuint colorIndex, const GLubyte mask[] )
 {
-   // XXX to do
+       printf("WriteMonoCISpanBack() not implemented yet!\n");
+   // TODO
 }
 
 
@@ -1340,21 +1468,24 @@ void MesaDriver::WriteCI32PixelsBack( const GLcontext *ctx, GLuint n,
                                    const GLint x[], const GLint y[],
                                    const GLuint index[], const GLubyte mask[] )
 {
-   // XXX to do
+       printf("WriteCI32PixelsBack() not implemented yet!\n");
+   // TODO
 }
 
 void MesaDriver::WriteMonoCIPixelsBack( const GLcontext *ctx, GLuint n,
                                      const GLint x[], const GLint y[],
                                      GLuint colorIndex, const GLubyte mask[] )
 {
-   // XXX to do
+       printf("WriteMonoCIPixelsBack() not implemented yet!\n");
+   // TODO
 }
 
 
 void MesaDriver::ReadCI32SpanBack( const GLcontext *ctx,
                                 GLuint n, GLint x, GLint y, GLuint index[] )
 {
-   // XXX to do
+       printf("ReadCI32SpanBack() not implemented yet!\n");
+   // TODO
 }
 
 
@@ -1382,7 +1513,8 @@ void MesaDriver::ReadCI32PixelsBack( const GLcontext *ctx,
                                    GLuint n, const GLint x[], const GLint y[],
                                    GLuint indx[], const GLubyte mask[] )
 {
-   // XXX to do
+       printf("ReadCI32PixelsBack() not implemented yet!\n");
+   // TODO
 }
 
 
@@ -1417,5 +1549,27 @@ void MesaDriver::ReadRGBAPixelsBack( const GLcontext *ctx,
    };
 }
 
+const char * color_space_name(color_space space)
+{
+#define C2N(a) case a: return #a
+
+       switch (space) {
+       C2N(B_RGB24);
+       C2N(B_RGB32);
+       C2N(B_RGBA32);
+       C2N(B_RGB32_BIG);
+       C2N(B_RGBA32_BIG);
+       C2N(B_GRAY8);
+       C2N(B_GRAY1);
+       C2N(B_RGB16);
+       C2N(B_RGB15);
+       C2N(B_RGBA15);
+       C2N(B_CMAP8);
+       default:
+               return "Unknown!";
+       };
+
+#undef C2N
+};