Changed the GDI driver interface to pass an opaque PHYSDEV pointer
instead of a DC structure.
Removed some direct accesses to the DC structure from the drivers.
Got rid the bitmap driver.

diff --git a/objects/bitmap.c b/objects/bitmap.c
index 41a1248..6ef032d 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -25,13 +25,12 @@
 #include "wine/winbase16.h"
 #include "gdi.h"
 #include "bitmap.h"
+#include "selectors.h"
 #include "wine/debug.h"
 #include "wine/winuser16.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(bitmap);
 
-BITMAP_DRIVER *BITMAP_Driver = NULL;
-
 
 /***********************************************************************
  *           BITMAP_GetWidthBytes
@@ -426,12 +425,30 @@
     if( bmp->bitmap.bmBits )
         HeapFree( GetProcessHeap(), 0, bmp->bitmap.bmBits );
 
-    DIB_DeleteDIBSection( bmp );
+    if (bmp->dib)
+    {
+        DIBSECTION *dib = bmp->dib;
 
+        if (dib->dsBm.bmBits)
+        {
+            if (dib->dshSection)
+            {
+                SYSTEM_INFO SystemInfo;
+                GetSystemInfo( &SystemInfo );
+                UnmapViewOfFile( (char *)dib->dsBm.bmBits -
+                                 (dib->dsOffset % SystemInfo.dwAllocationGranularity) );
+            }
+            else if (!dib->dsOffset)
+                VirtualFree(dib->dsBm.bmBits, 0L, MEM_RELEASE );
+        }
+        HeapFree(GetProcessHeap(), 0, dib);
+        bmp->dib = NULL;
+        if (bmp->segptr_bits) SELECTOR_FreeBlock( SELECTOROF(bmp->segptr_bits) );
+    }
     return GDI_FreeObject( hbitmap, bmp );
 }
 
-	
+
 /***********************************************************************
  *           BITMAP_GetObject16
  */
diff --git a/objects/clipping.c b/objects/clipping.c
index ccf695b..54138dc 100644
--- a/objects/clipping.c
+++ b/objects/clipping.c
@@ -50,7 +50,7 @@
         CombineRgn( dc->hGCClipRgn, dc->hVisRgn, 0, RGN_COPY );
     else
         CombineRgn(dc->hGCClipRgn, dc->hClipRgn, dc->hVisRgn, RGN_AND);
-    if (dc->funcs->pSetDeviceClipping) dc->funcs->pSetDeviceClipping( dc );
+    if (dc->funcs->pSetDeviceClipping) dc->funcs->pSetDeviceClipping( dc->physDev );
 }
 
 
@@ -170,7 +170,7 @@
     TRACE("%04x %d,%d\n", hdc, x, y );
 
     if(dc->funcs->pOffsetClipRgn)
-        ret = dc->funcs->pOffsetClipRgn( dc, x, y );
+        ret = dc->funcs->pOffsetClipRgn( dc->physDev, x, y );
     else if (dc->hClipRgn) {
         ret = OffsetRgn( dc->hClipRgn, XLSTODS(dc,x), YLSTODS(dc,y));
 	CLIPPING_UpdateGCRegion( dc );
@@ -267,7 +267,7 @@
     TRACE("%04x %dx%d,%dx%d\n", hdc, left, top, right, bottom );
 
     if(dc->funcs->pExcludeClipRect)
-        ret = dc->funcs->pExcludeClipRect( dc, left, top, right, bottom );
+        ret = dc->funcs->pExcludeClipRect( dc->physDev, left, top, right, bottom );
     else {
         left   = XLPTODP( dc, left );
 	right  = XLPTODP( dc, right );
@@ -304,7 +304,7 @@
     TRACE("%04x %dx%d,%dx%d\n", hdc, left, top, right, bottom );
 
     if(dc->funcs->pIntersectClipRect)
-        ret = dc->funcs->pIntersectClipRect( dc, left, top, right, bottom );
+        ret = dc->funcs->pIntersectClipRect( dc->physDev, left, top, right, bottom );
     else {
         left   = XLPTODP( dc, left );
 	right  = XLPTODP( dc, right );
diff --git a/objects/dc.c b/objects/dc.c
index d49bc3d..091caef 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -451,7 +451,7 @@
 
     if(dc->funcs->pSaveDC)
     {
-        ret = dc->funcs->pSaveDC( dc );
+        ret = dc->funcs->pSaveDC( dc->physDev );
         GDI_ReleaseObj( hdc );
         return ret;
     }
@@ -509,7 +509,7 @@
     if(!dc) return FALSE;
     if(dc->funcs->pRestoreDC)
     {
-        success = dc->funcs->pRestoreDC( dc, level );
+        success = dc->funcs->pRestoreDC( dc->physDev, level );
         GDI_ReleaseObj( hdc );
         return success;
     }
@@ -781,7 +781,7 @@
 	SelectObject( hdc, GetStockObject(SYSTEM_FONT) );
         SelectObject( hdc, GetStockObject(DEFAULT_BITMAP) );
         funcs = dc->funcs;
-        if (dc->funcs->pDeleteDC) dc->funcs->pDeleteDC(dc);
+        if (dc->funcs->pDeleteDC) dc->funcs->pDeleteDC(dc->physDev);
     }
 
     if (dc->hClipRgn) DeleteObject( dc->hClipRgn );
@@ -847,7 +847,7 @@
 
     if ((dc = DC_GetDCPtr( hdc )))
     {
-        if (dc->funcs->pGetDeviceCaps) ret = dc->funcs->pGetDeviceCaps( dc, cap );
+        if (dc->funcs->pGetDeviceCaps) ret = dc->funcs->pGetDeviceCaps( dc->physDev, cap );
         GDI_ReleaseObj( hdc );
     }
     return ret;
@@ -870,14 +870,19 @@
 {
     COLORREF oldColor;
     DC * dc = DC_GetDCPtr( hdc );
-  
-    if (!dc) return 0x80000000;
+
+    if (!dc) return CLR_INVALID;
+    oldColor = dc->backgroundColor;
     if (dc->funcs->pSetBkColor)
-        oldColor = dc->funcs->pSetBkColor(dc, color);
-    else {
-	oldColor = dc->backgroundColor;
-	dc->backgroundColor = color;
+    {
+        color = dc->funcs->pSetBkColor(dc->physDev, color);
+        if (color == CLR_INVALID)  /* don't change it */
+        {
+            color = oldColor;
+            oldColor = CLR_INVALID;
+        }
     }
+    dc->backgroundColor = color;
     GDI_ReleaseObj( hdc );
     return oldColor;
 }
@@ -899,14 +904,19 @@
 {
     COLORREF oldColor;
     DC * dc = DC_GetDCPtr( hdc );
-  
-    if (!dc) return 0x80000000;
+
+    if (!dc) return CLR_INVALID;
+    oldColor = dc->textColor;
     if (dc->funcs->pSetTextColor)
-        oldColor = dc->funcs->pSetTextColor(dc, color);
-    else {
-	oldColor = dc->textColor;
-	dc->textColor = color;
+    {
+        color = dc->funcs->pSetTextColor(dc->physDev, color);
+        if (color == CLR_INVALID)  /* don't change it */
+        {
+            color = oldColor;
+            oldColor = CLR_INVALID;
+        }
     }
+    dc->textColor = color;
     GDI_ReleaseObj( hdc );
     return oldColor;
 }
@@ -929,7 +939,7 @@
     DC *dc = DC_GetDCPtr( hdc );
     if (!dc) return 0x0;
     if (dc->funcs->pSetTextAlign)
-        prevAlign = dc->funcs->pSetTextAlign(dc, align);
+        prevAlign = dc->funcs->pSetTextAlign(dc->physDev, align);
     else {
 	prevAlign = dc->textAlign;
 	dc->textAlign = align;
@@ -949,7 +959,7 @@
     if (!(dc = DC_GetDCPtr( hDC ))) return FALSE;
 
     lpp->x = lpp->y = 0;
-    if (dc->funcs->pGetDCOrgEx) dc->funcs->pGetDCOrgEx( dc, lpp );
+    if (dc->funcs->pGetDCOrgEx) dc->funcs->pGetDCOrgEx( dc->physDev, lpp );
     lpp->x += dc->DCOrgX;
     lpp->y += dc->DCOrgY;
     GDI_ReleaseObj( hDC );
@@ -1296,7 +1306,7 @@
     if( dc )
     {
 	if (dc->funcs->pGetDeviceGammaRamp)
-	    ret = dc->funcs->pGetDeviceGammaRamp(dc, ptr);
+	    ret = dc->funcs->pGetDeviceGammaRamp(dc->physDev, ptr);
 	GDI_ReleaseObj( hDC );
     }
     return ret;
@@ -1313,7 +1323,7 @@
     if( dc )
     {
 	if (dc->funcs->pSetDeviceGammaRamp)
-	    ret = dc->funcs->pSetDeviceGammaRamp(dc, ptr);
+	    ret = dc->funcs->pSetDeviceGammaRamp(dc->physDev, ptr);
 	GDI_ReleaseObj( hDC );
     }
     return ret;
diff --git a/objects/dcvalues.c b/objects/dcvalues.c
index 331649c..dfc0dce 100644
--- a/objects/dcvalues.c
+++ b/objects/dcvalues.c
@@ -40,7 +40,7 @@
     }
     if (!(dc = DC_GetDCPtr( hdc ))) return 0;
     if (dc->funcs->pSetBkMode)
-        ret = dc->funcs->pSetBkMode( dc, mode );
+        ret = dc->funcs->pSetBkMode( dc->physDev, mode );
     else
     {
         ret = dc->backgroundMode;
@@ -65,7 +65,7 @@
     }
     if (!(dc = DC_GetDCPtr( hdc ))) return 0;
     if (dc->funcs->pSetROP2)
-        ret = dc->funcs->pSetROP2( dc, mode );
+        ret = dc->funcs->pSetROP2( dc->physDev, mode );
     else
     {
         ret = dc->ROPmode;
@@ -90,7 +90,7 @@
     }
     if (!(dc = DC_GetDCPtr( hdc ))) return 0;
     if (dc->funcs->pSetRelAbs)
-        ret = dc->funcs->pSetRelAbs( dc, mode );
+        ret = dc->funcs->pSetRelAbs( dc->physDev, mode );
     else
     {
         ret = dc->relAbsMode;
@@ -115,7 +115,7 @@
     }
     if (!(dc = DC_GetDCPtr( hdc ))) return 0;
     if (dc->funcs->pSetPolyFillMode)
-        ret = dc->funcs->pSetPolyFillMode( dc, mode );
+        ret = dc->funcs->pSetPolyFillMode( dc->physDev, mode );
     else
     {
         ret = dc->polyFillMode;
@@ -140,7 +140,7 @@
     }
     if (!(dc = DC_GetDCPtr( hdc ))) return 0;
     if (dc->funcs->pSetStretchBltMode)
-        ret = dc->funcs->pSetStretchBltMode( dc, mode );
+        ret = dc->funcs->pSetStretchBltMode( dc->physDev, mode );
     else
     {
         ret = dc->stretchBltMode;
diff --git a/objects/dib.c b/objects/dib.c
index bbd16ce..764fbf8 100644
--- a/objects/dib.c
+++ b/objects/dib.c
@@ -173,7 +173,7 @@
 
     if(dc->funcs->pStretchDIBits)
     {
-        heightSrc = dc->funcs->pStretchDIBits(dc, xDst, yDst, widthDst,
+        heightSrc = dc->funcs->pStretchDIBits(dc->physDev, xDst, yDst, widthDst,
                                               heightDst, xSrc, ySrc, widthSrc,
                                               heightSrc, bits, info, wUsage, dwRop);
         GDI_ReleaseObj( hdc );
@@ -264,25 +264,15 @@
 		      UINT coloruse )
 {
     DC *dc;
-    BITMAPOBJ *bitmap;
-    INT result;
+    INT result = 0;
 
     /* Check parameters */
     if (!(dc = DC_GetDCUpdate( hdc ))) return 0;
 
-    if (!(bitmap = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
-    {
-        GDI_ReleaseObj( hdc );
-        return 0;
-    }
+    if (dc->funcs->pSetDIBits)
+        result = dc->funcs->pSetDIBits(dc->physDev, hbitmap, startscan, lines, bits, info, coloruse);
 
-    result = BITMAP_Driver->pSetDIBits(bitmap, dc, startscan, 
-				       lines, bits, info, 
-				       coloruse, hbitmap);
-
-    GDI_ReleaseObj( hbitmap );
     GDI_ReleaseObj( hdc );
-
     return result;
 }
 
@@ -314,7 +304,7 @@
     if (!(dc = DC_GetDCUpdate( hdc ))) return 0;
 
     if(dc->funcs->pSetDIBitsToDevice)
-        ret = dc->funcs->pSetDIBitsToDevice( dc, xDest, yDest, cx, cy, xSrc,
+        ret = dc->funcs->pSetDIBitsToDevice( dc->physDev, xDest, yDest, cx, cy, xSrc,
 					     ySrc, startscan, lines, bits,
 					     info, coloruse );
     else {
@@ -338,24 +328,16 @@
 /***********************************************************************
  *           SetDIBColorTable    (GDI32.@)
  */
-UINT WINAPI SetDIBColorTable( HDC hdc, UINT startpos, UINT entries,
-				  RGBQUAD *colors )
+UINT WINAPI SetDIBColorTable( HDC hdc, UINT startpos, UINT entries, RGBQUAD *colors )
 {
     DC * dc;
-    BITMAPOBJ * bmp;
-    UINT result;
+    UINT result = 0;
 
     if (!(dc = DC_GetDCUpdate( hdc ))) return 0;
 
-    if (!(bmp = (BITMAPOBJ*)GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC )))
-    {
-        GDI_ReleaseObj( hdc );
-        return 0;
-    }
+    if (dc->funcs->pSetDIBColorTable)
+        result = dc->funcs->pSetDIBColorTable(dc->physDev, startpos, entries, colors);
 
-    result = BITMAP_Driver->pSetDIBColorTable(bmp, dc, startpos, entries, colors);
-
-    GDI_ReleaseObj( dc->hBitmap );
     GDI_ReleaseObj( hdc );
     return result;
 }
@@ -372,24 +354,16 @@
 /***********************************************************************
  *           GetDIBColorTable    (GDI32.@)
  */
-UINT WINAPI GetDIBColorTable( HDC hdc, UINT startpos, UINT entries,
-				  RGBQUAD *colors )
+UINT WINAPI GetDIBColorTable( HDC hdc, UINT startpos, UINT entries, RGBQUAD *colors )
 {
     DC * dc;
-    BITMAPOBJ * bmp;
-    UINT result;
+    UINT result = 0;
 
     if (!(dc = DC_GetDCUpdate( hdc ))) return 0;
 
-    if (!(bmp = (BITMAPOBJ*)GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC )))
-    {
-        GDI_ReleaseObj( hdc );
-        return 0;
-    }
+    if (dc->funcs->pGetDIBColorTable)
+        result = dc->funcs->pGetDIBColorTable(dc->physDev, startpos, entries, colors);
 
-    result = BITMAP_Driver->pGetDIBColorTable(bmp, dc, startpos, entries, colors);
-
-    GDI_ReleaseObj( dc->hBitmap );
     GDI_ReleaseObj( hdc );
     return result;
 }
@@ -747,7 +721,8 @@
             }
         }
         /* Otherwise, get bits from the XImage */
-        else if(!BITMAP_Driver->pGetDIBits(bmp, dc, startscan, lines, bits, info, coloruse, hbitmap))
+        else if (!dc->funcs->pGetDIBits ||
+                 !dc->funcs->pGetDIBits(dc->physDev, hbitmap, startscan, lines, bits, info, coloruse))
         {
 	    GDI_ReleaseObj( hdc );
 	    GDI_ReleaseObj( hbitmap );
@@ -949,7 +924,7 @@
 
     if ((dc = DC_GetDCPtr( hdc )))
     {
-        hbitmap = dc->funcs->pCreateDIBSection(dc, bmi, usage, bits, section, offset, ovr_pitch);
+        hbitmap = dc->funcs->pCreateDIBSection(dc->physDev, bmi, usage, bits, section, offset, ovr_pitch);
         GDI_ReleaseObj(hdc);
     }
 
@@ -970,36 +945,6 @@
 }
 
 /***********************************************************************
- *           DIB_DeleteDIBSection
- */
-void DIB_DeleteDIBSection( BITMAPOBJ *bmp )
-{
-    if (bmp && bmp->dib)
-    {
-        DIBSECTION *dib = bmp->dib;
-
-        if (dib->dsBm.bmBits)
-        {
-            if (dib->dshSection)
-	    {
-		SYSTEM_INFO SystemInfo;
-		GetSystemInfo( &SystemInfo );
-		UnmapViewOfFile( (char *)dib->dsBm.bmBits -
-				 (dib->dsOffset % SystemInfo.dwAllocationGranularity) );
-	    }
-            else if (!dib->dsOffset)
-                VirtualFree(dib->dsBm.bmBits, 0L, MEM_RELEASE );
-        }
-
-	BITMAP_Driver->pDeleteDIBSection(bmp);
-
-        HeapFree(GetProcessHeap(), 0, dib);
-        bmp->dib = NULL;
-        if (bmp->segptr_bits) SELECTOR_FreeBlock( SELECTOROF(bmp->segptr_bits) );
-    }
-}
-
-/***********************************************************************
  *           DIB_CreateDIBFromBitmap
  *  Allocates a packed DIB and copies the bitmap data into it.
  */
diff --git a/objects/font.c b/objects/font.c
index ad0add9..924d74a 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -901,7 +901,7 @@
     DC * dc = DC_GetDCPtr( hdc );
     if (!dc) return 0;
     if (dc->funcs->pSetTextCharacterExtra)
-        prev = dc->funcs->pSetTextCharacterExtra( dc, extra );
+        prev = dc->funcs->pSetTextCharacterExtra( dc->physDev, extra );
     else
     {
         extra = (extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX;
@@ -931,7 +931,7 @@
     DC * dc = DC_GetDCPtr( hdc );
     if (!dc) return FALSE;
     if (dc->funcs->pSetTextJustification)
-        ret = dc->funcs->pSetTextJustification( dc, extra, breaks );
+        ret = dc->funcs->pSetTextJustification( dc->physDev, extra, breaks );
     else
     {
         extra = abs((extra * dc->vportExtX + dc->wndExtX / 2) / dc->wndExtX);
@@ -1080,7 +1080,7 @@
     if(dc->gdiFont)
         ret = WineEngGetTextExtentPoint(dc->gdiFont, str, count, size);
     else if(dc->funcs->pGetTextExtentPoint)
-        ret = dc->funcs->pGetTextExtentPoint( dc, str, count, size );
+        ret = dc->funcs->pGetTextExtentPoint( dc->physDev, str, count, size );
 
     GDI_ReleaseObj( hdc );
 
@@ -1233,7 +1233,7 @@
     if (dc->gdiFont)
         ret = WineEngGetTextMetrics(dc->gdiFont, metrics);
     else if (dc->funcs->pGetTextMetrics)
-        ret = dc->funcs->pGetTextMetrics( dc, metrics );
+        ret = dc->funcs->pGetTextMetrics( dc->physDev, metrics );
 
     if (ret)
     {
@@ -1533,7 +1533,7 @@
     if (dc->gdiFont)
         ret = WineEngGetCharWidth( dc->gdiFont, firstChar, lastChar, buffer );
     else if (dc->funcs->pGetCharWidth)
-        ret = dc->funcs->pGetCharWidth( dc, firstChar, lastChar, buffer);
+        ret = dc->funcs->pGetCharWidth( dc->physDev, firstChar, lastChar, buffer);
 
     if (ret)
     {
@@ -1607,7 +1607,7 @@
     DWORD ret = 0; 
     if(!dc) return 0;
     if(dc->funcs->pSetMapperFlags)
-        ret = dc->funcs->pSetMapperFlags( dc, dwFlag );
+        ret = dc->funcs->pSetMapperFlags( dc->physDev, dwFlag );
     else
         FIXME("(0x%04x, 0x%08lx): stub - harmless\n", hDC, dwFlag);
     GDI_ReleaseObj( hDC );
diff --git a/objects/gdiobj.c b/objects/gdiobj.c
index d285bfc..daaf99e 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -1156,8 +1156,8 @@
 	    dc->gdiFont = WineEngCreateFontInstance(hFont);
     }
 
-    if(dc->funcs->pSelectObject)
-        ret = dc->funcs->pSelectObject(dc, hFont);
+    if(dc->funcs->pSelectFont)
+        ret = dc->funcs->pSelectFont(dc->physDev, hFont);
 
     if(ret && dc->gdiFont) {
 	dc->gdiFont = 0;
@@ -1188,16 +1188,39 @@
 HGDIOBJ WINAPI SelectObject( HDC hdc, HGDIOBJ handle )
 {
     HGDIOBJ ret = 0;
-    DC * dc = DC_GetDCUpdate( hdc );
+    DC * dc = DC_GetDCPtr( hdc );
     if (!dc) return 0;
     TRACE("hdc=%04x %04x\n", hdc, handle );
 
     /* Fonts get a rather different treatment so we'll handle them
        separately */
-    if(GetObjectType(handle) == OBJ_FONT)
+    switch(GetObjectType( handle ))
+    {
+    case OBJ_BITMAP:
+        ret = dc->hBitmap;
+        if (dc->funcs->pSelectBitmap) handle = dc->funcs->pSelectBitmap( dc->physDev, handle );
+        if (handle) dc->hBitmap = handle;
+        else ret = 0;
+        break;
+    case OBJ_BRUSH:
+        ret = dc->hBrush;
+        if (dc->funcs->pSelectBrush) handle = dc->funcs->pSelectBrush( dc->physDev, handle );
+        if (handle) dc->hBrush = handle;
+        else ret = 0;
+        break;
+    case OBJ_PEN:
+        ret = dc->hPen;
+        if (dc->funcs->pSelectPen) handle = dc->funcs->pSelectPen( dc->physDev, handle );
+        if (handle) dc->hPen = handle;
+        else ret = 0;
+        break;
+    case OBJ_FONT:
         ret = FONT_SelectObject(dc, handle);
-    else if (dc->funcs->pSelectObject)
-        ret = dc->funcs->pSelectObject( dc, handle );
+        break;
+    case OBJ_REGION:
+        GDI_ReleaseObj( hdc );
+        return (HGDIOBJ)SelectClipRgn( hdc, handle );
+    }
     GDI_ReleaseObj( hdc );
 
     if (ret && ret != handle)
diff --git a/objects/text.c b/objects/text.c
index 26e3cd3..2692f71 100644
--- a/objects/text.c
+++ b/objects/text.c
@@ -169,7 +169,7 @@
     if (dc)
     {
 	if(dc->funcs->pExtTextOut)
-	    ret = dc->funcs->pExtTextOut(dc,x,y,flags,lprect,str,count,lpDx);
+	    ret = dc->funcs->pExtTextOut(dc->physDev,x,y,flags,lprect,str,count,lpDx);
 	GDI_ReleaseObj( hdc );
     }
     return ret;