diff --git a/dlls/gdi/driver.c b/dlls/gdi/driver.c
index 228ccab1e7047727cf996681d1011895e5ac4c37..12f72fa218e28d8c5ffcc5dda76135f8949cc508 100644
--- a/dlls/gdi/driver.c
+++ b/dlls/gdi/driver.c
@@ -69,15 +69,14 @@ static struct graphics_driver *create_driver( HMODULE module )
     GET_FUNC(ArcTo);
     GET_FUNC(BeginPath);
     GET_FUNC(BitBlt);
-    GET_FUNC(BitmapBits);
     GET_FUNC(ChoosePixelFormat);
     GET_FUNC(Chord);
     GET_FUNC(CloseFigure);
     GET_FUNC(CreateBitmap);
     GET_FUNC(CreateDC);
     GET_FUNC(CreateDIBSection);
+    GET_FUNC(DeleteBitmap);
     GET_FUNC(DeleteDC);
-    GET_FUNC(DeleteObject);
     GET_FUNC(DescribePixelFormat);
     GET_FUNC(DeviceCapabilities);
     GET_FUNC(Ellipse);
@@ -95,6 +94,7 @@ static struct graphics_driver *create_driver( HMODULE module )
     GET_FUNC(FillRgn);
     GET_FUNC(FlattenPath);
     GET_FUNC(FrameRgn);
+    GET_FUNC(GetBitmapBits);
     GET_FUNC(GetCharWidth);
     GET_FUNC(GetDCOrgEx);
     GET_FUNC(GetDIBColorTable);
@@ -137,6 +137,7 @@ static struct graphics_driver *create_driver( HMODULE module )
     GET_FUNC(SelectFont);
     GET_FUNC(SelectPalette);
     GET_FUNC(SelectPen);
+    GET_FUNC(SetBitmapBits);
     GET_FUNC(SetBkColor);
     GET_FUNC(SetBkMode);
     GET_FUNC(SetDIBColorTable);
diff --git a/dlls/gdi/enhmfdrv/init.c b/dlls/gdi/enhmfdrv/init.c
index 67af154b817ce5e213d57da39ebb9df4e30a4811..a50243429ad5d9dccd624e3baabc8dd6f45b3d92 100644
--- a/dlls/gdi/enhmfdrv/init.c
+++ b/dlls/gdi/enhmfdrv/init.c
@@ -37,15 +37,14 @@ static const DC_FUNCTIONS EMFDRV_Funcs =
     NULL,                            /* pArcTo */
     EMFDRV_BeginPath,                /* pBeginPath */
     NULL,                            /* pBitBlt */
-    NULL,                            /* pBitmapBits */
     NULL,                            /* pChoosePixelFormat */
     EMFDRV_Chord,                    /* pChord */
     EMFDRV_CloseFigure,              /* pCloseFigure */
     NULL,                            /* pCreateBitmap */
     NULL,                            /* pCreateDC */
     NULL,                            /* pCreateDIBSection */
+    NULL,                            /* pDeleteBitmap */
     NULL,                            /* pDeleteDC */
-    NULL,                            /* pDeleteObject */
     NULL,                            /* pDescribePixelFormat */
     NULL,                            /* pDeviceCapabilities */
     EMFDRV_Ellipse,                  /* pEllipse */
@@ -63,6 +62,7 @@ static const DC_FUNCTIONS EMFDRV_Funcs =
     EMFDRV_FillRgn,                  /* pFillRgn */
     EMFDRV_FlattenPath,              /* pFlattenPath */
     EMFDRV_FrameRgn,                 /* pFrameRgn */
+    NULL,                            /* pGetBitmapBits */
     NULL,                            /* pGetCharWidth */
     NULL,                            /* pGetDCOrgEx */
     NULL,                            /* pGetDIBColorTable */
@@ -105,6 +105,7 @@ static const DC_FUNCTIONS EMFDRV_Funcs =
     EMFDRV_SelectFont,               /* pSelectFont */
     NULL,                            /* pSelectPalette */
     EMFDRV_SelectPen,                /* pSelectPen */
+    NULL,                            /* pSetBitmapBits */
     EMFDRV_SetBkColor,               /* pSetBkColor */
     EMFDRV_SetBkMode,                /* pSetBkMode */
     NULL,                            /* pSetDIBColorTable */
diff --git a/dlls/gdi/mfdrv/init.c b/dlls/gdi/mfdrv/init.c
index 387dbeb6af378ad0a9b11448c1da47e8504419bd..cb6fd19d24225f43f48a20500111996a4e5f6083 100644
--- a/dlls/gdi/mfdrv/init.c
+++ b/dlls/gdi/mfdrv/init.c
@@ -38,15 +38,14 @@ static const DC_FUNCTIONS MFDRV_Funcs =
     NULL,                            /* pArcTo */
     MFDRV_BeginPath,                 /* pBeginPath */
     MFDRV_BitBlt,                    /* pBitBlt */
-    NULL,                            /* pBitmapBits */
     NULL,                            /* pChoosePixelFormat */
     MFDRV_Chord,                     /* pChord */
     MFDRV_CloseFigure,               /* pCloseFigure */
     NULL,                            /* pCreateBitmap */
     NULL,                            /* pCreateDC */
     NULL,                            /* pCreateDIBSection */
+    NULL,                            /* pDeleteBitmap */
     NULL,                            /* pDeleteDC */
-    NULL,                            /* pDeleteObject */
     NULL,                            /* pDescribePixelFormat */
     NULL,                            /* pDeviceCapabilities */
     MFDRV_Ellipse,                   /* pEllipse */
@@ -64,6 +63,7 @@ static const DC_FUNCTIONS MFDRV_Funcs =
     MFDRV_FillRgn,                   /* pFillRgn */
     MFDRV_FlattenPath,               /* pFlattenPath */
     MFDRV_FrameRgn,                  /* pFrameRgn */
+    NULL,                            /* pGetBitmapBits */
     NULL,                            /* pGetCharWidth */
     NULL,                            /* pGetDCOrgEx */
     NULL,                            /* pGetDIBColorTable */
@@ -106,6 +106,7 @@ static const DC_FUNCTIONS MFDRV_Funcs =
     MFDRV_SelectFont,                /* pSelectFont */
     NULL,                            /* pSelectPalette */
     MFDRV_SelectPen,                 /* pSelectPen */
+    NULL,                            /* pSetBitmapBits */
     MFDRV_SetBkColor,                /* pSetBkColor */
     MFDRV_SetBkMode,                 /* pSetBkMode */
     NULL,                            /* pSetDIBColorTable */
diff --git a/dlls/gdi/win16drv/init.c b/dlls/gdi/win16drv/init.c
index c9b6a0f4fca1273df14607965fc13c293c67cea3..0550337ae92709cd219687f00dc9564e2caf0fba 100644
--- a/dlls/gdi/win16drv/init.c
+++ b/dlls/gdi/win16drv/init.c
@@ -65,15 +65,14 @@ static const DC_FUNCTIONS WIN16DRV_Funcs =
     NULL,                            /* pArcTo */
     NULL,                            /* pBeginPath */
     NULL,                            /* pBitBlt */
-    NULL,                            /* pBitmapBits */
     NULL,                            /* pChoosePixelFormat */
     NULL,                            /* pChord */
     NULL,                            /* pCloseFigure */
     NULL,                            /* pCreateBitmap */
     WIN16DRV_CreateDC,               /* pCreateDC */
     NULL,                            /* pCreateDIBSection */
+    NULL,                            /* pDeleteBitmap */
     NULL,                            /* pDeleteDC */
-    NULL,                            /* pDeleteObject */
     NULL,                            /* pDescribePixelFormat */
     WIN16DRV_DeviceCapabilities,     /* pDeviceCapabilities */
     WIN16DRV_Ellipse,                /* pEllipse */
@@ -91,6 +90,7 @@ static const DC_FUNCTIONS WIN16DRV_Funcs =
     NULL,                            /* pFillRgn */
     NULL,                            /* pFlattenPath */
     NULL,                            /* pFrameRgn */
+    NULL,                            /* pGetBitmapBits */
     WIN16DRV_GetCharWidth,           /* pGetCharWidth */
     NULL,                            /* pGetDCOrgEx */
     NULL,                            /* pGetDIBColorTable */
@@ -133,6 +133,7 @@ static const DC_FUNCTIONS WIN16DRV_Funcs =
     WIN16DRV_SelectFont,             /* pSelectFont */
     NULL,                            /* pSelectPalette */
     WIN16DRV_SelectPen,              /* pSelectPen */
+    NULL,                            /* pSetBitmapBits */
     NULL,                            /* pSetBkColor */
     NULL,                            /* pSetBkMode */
     NULL,                            /* pSetDIBColorTable */
diff --git a/dlls/ttydrv/bitmap.c b/dlls/ttydrv/bitmap.c
index 53b4a2b5c5a131459474618391614f899f714b5b..d8b980d5f8b248e1ebe305ab5b98231231de7176 100644
--- a/dlls/ttydrv/bitmap.c
+++ b/dlls/ttydrv/bitmap.c
@@ -22,7 +22,6 @@
 
 #include <string.h>
 
-#include "bitmap.h"
 #include "gdi.h"
 #include "ttydrv.h"
 #include "winbase.h"
@@ -30,147 +29,24 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(ttydrv);
 
-/**********************************************************************/
-
-extern const DC_FUNCTIONS *TTYDRV_DC_Funcs;  /* hack */
-
-static LONG TTYDRV_DC_GetBitmapBits(BITMAPOBJ *bitmap, void *bits, LONG count);
-static LONG TTYDRV_DC_SetBitmapBits(BITMAPOBJ *bitmap, void *bits, LONG count);
-
-/***********************************************************************
- *		TTYDRV_DC_AllocBitmap
- */
-TTYDRV_PHYSBITMAP *TTYDRV_DC_AllocBitmap(BITMAPOBJ *bitmap)
-{
-  TTYDRV_PHYSBITMAP *physBitmap;
-  
-  if(!(physBitmap = HeapAlloc(GetProcessHeap(), 0, sizeof(TTYDRV_PHYSBITMAP)))) {
-    ERR("Can't alloc TTYDRV_PHYSBITMAP\n");
-    return NULL;
-  }
-
-  bitmap->physBitmap = physBitmap;
-  bitmap->funcs = TTYDRV_DC_Funcs;
-
-  return physBitmap;
-}
-
-/***********************************************************************
- *           TTYDRV_DC_BitmapBits
- */
-LONG TTYDRV_DC_BitmapBits(HBITMAP hbitmap, void *bits, LONG count, WORD flags)
-{
-  BITMAPOBJ *bitmap;
-  LONG result;
-
-  if(!(bitmap = (BITMAPOBJ *) GDI_GetObjPtr(hbitmap, BITMAP_MAGIC)))
-    return FALSE;
-  
-  if(flags == DDB_GET)
-    result = TTYDRV_DC_GetBitmapBits(bitmap, bits, count);
-  else if(flags == DDB_SET)
-    result = TTYDRV_DC_SetBitmapBits(bitmap, bits, count);
-  else {
-    ERR("Unknown flags value %d\n", flags);
-    result = 0;
-  }
-  
-  GDI_ReleaseObj(hbitmap);
-  return result;
-}
-
-/***********************************************************************
- *		TTYDRV_DC_CreateBitmap
- */
-BOOL TTYDRV_DC_CreateBitmap(HBITMAP hbitmap)
-{
-  TTYDRV_PHYSBITMAP *physBitmap;
-  BITMAPOBJ *bitmap;
-
-  TRACE("(0x%04x)\n", hbitmap);
-
-  if(!(bitmap = (BITMAPOBJ *) GDI_GetObjPtr(hbitmap, BITMAP_MAGIC)))
-    return FALSE;
-  
-  if(!(physBitmap = TTYDRV_DC_AllocBitmap(bitmap))) {
-    GDI_ReleaseObj(hbitmap);
-    return FALSE;
-  }
- 
-  /* Set bitmap bits */
-  if(bitmap->bitmap.bmBits) { 
-    TTYDRV_DC_BitmapBits(hbitmap, bitmap->bitmap.bmBits,
-			 bitmap->bitmap.bmHeight * bitmap->bitmap.bmWidthBytes,
-			 DDB_SET );
-  }
-
-  GDI_ReleaseObj(hbitmap);
-  
-  return TRUE;
-}
 
 /***********************************************************************
- *		TTYDRV_DC_BITMAP_DeleteObject
+ *           GetBitmapBits   (TTYDRV.@)
  */
-BOOL TTYDRV_DC_BITMAP_DeleteObject(HBITMAP hbitmap, BITMAPOBJ *bitmap)
+LONG TTYDRV_GetBitmapBits(HBITMAP hbitmap, void *bits, LONG count)
 {
-  TRACE("(0x%04x, %p)\n", hbitmap, bitmap);
-
-  HeapFree(GetProcessHeap(), 0, bitmap->physBitmap);
-  bitmap->physBitmap = NULL;
-  bitmap->funcs = NULL;
-
-  return TRUE;
-}
-
-/***********************************************************************
- *		TTYDRV_DC_GetBitmapBits
- */
-static LONG TTYDRV_DC_GetBitmapBits(BITMAPOBJ *bitmap, void *bits, LONG count)
-{
-  FIXME("(%p, %p, %ld): stub\n", bitmap, bits, count);
-
-  memset(bits, 0, count);
-
-  return count;
+    FIXME("(%x, %p, %ld): stub\n", hbitmap, bits, count);
+    memset(bits, 0, count);
+    return count;
 }
 
 /***********************************************************************
- *		SelectBitmap   (TTYDRV.@)
+ *           SetBitmapBits   (TTYDRV.@)
  */
-HBITMAP TTYDRV_SelectBitmap(TTYDRV_PDEVICE *physDev, HBITMAP hbitmap)
+LONG TTYDRV_SetBitmapBits(HBITMAP hbitmap, const void *bits, LONG count)
 {
-  DC *dc = physDev->dc;
-  BITMAPOBJ *bitmap;
-
-  TRACE("(%p, 0x%04x)\n", dc, hbitmap);
-
-  if (!(bitmap = GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return 0;
-  /* Assure that the bitmap device dependent */
-  if(!bitmap->physBitmap && !TTYDRV_DC_CreateBitmap(hbitmap))
-  {
-      GDI_ReleaseObj( hbitmap );
-      return 0;
-  }
-
-  if(bitmap->funcs != dc->funcs) {
-    ERR("Trying to select a non-TTY DDB into a TTY DC\n");
-    GDI_ReleaseObj( hbitmap );
-    return 0;
-  }
-
-  GDI_ReleaseObj( hbitmap );
-  return hbitmap;
-}
-
-/***********************************************************************
- *		TTYDRV_DC_SetBitmapBits
- */
-static LONG TTYDRV_DC_SetBitmapBits(BITMAPOBJ *bitmap, void *bits, LONG count)
-{
-  FIXME("(%p, %p, %ld): semistub\n", bitmap, bits, count);
-
-  return count;
+    FIXME("(%x, %p, %ld): stub\n", hbitmap, bits, count);
+    return count;
 }
 
 /***********************************************************************
diff --git a/dlls/ttydrv/dc.c b/dlls/ttydrv/dc.c
index e30cfd12e94361509ea43a4b2b4ae51304b860b2..f4d2c25cfe6c03d71e63adea96fc114e23cf5c43 100644
--- a/dlls/ttydrv/dc.c
+++ b/dlls/ttydrv/dc.c
@@ -27,9 +27,6 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(ttydrv);
 
-/**********************************************************************/
-
-const DC_FUNCTIONS *TTYDRV_DC_Funcs = NULL;  /* hack */
 
 /**********************************************************************
  *	     TTYDRV_GDI_Initialize
@@ -51,8 +48,6 @@ BOOL TTYDRV_DC_CreateDC(DC *dc, LPCSTR driver, LPCSTR device,
     dc, debugstr_a(driver), debugstr_a(device), 
     debugstr_a(output), initData);
 
-  if (!TTYDRV_DC_Funcs) TTYDRV_DC_Funcs = dc->funcs;  /* hack */
-
   dc->physDev = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
 			  sizeof(TTYDRV_PDEVICE));  
   if(!dc->physDev) {
@@ -67,8 +62,6 @@ BOOL TTYDRV_DC_CreateDC(DC *dc, LPCSTR driver, LPCSTR device,
     physDev->window = NULL;
     physDev->cellWidth = 1;
     physDev->cellHeight = 1;
-
-    TTYDRV_DC_CreateBitmap(dc->hBitmap);
   } else {
     physDev->window = root_window;
     physDev->cellWidth = cell_width;
diff --git a/dlls/ttydrv/objects.c b/dlls/ttydrv/objects.c
index 33571bd11afe02dae8157dd6ad676dc384d9c724..999bf9b984117014c2bbb68a87d2f5973f5d84da 100644
--- a/dlls/ttydrv/objects.c
+++ b/dlls/ttydrv/objects.c
@@ -27,11 +27,6 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(ttydrv);
 
-/**********************************************************************/
-
-extern BOOL TTYDRV_DC_BITMAP_DeleteObject(HBITMAP hbitmap, BITMAPOBJ *bitmap);
-
-
 /***********************************************************************
  *		SelectFont   (TTYDRV.@)
  */
@@ -41,34 +36,3 @@ HFONT TTYDRV_SelectFont(TTYDRV_PDEVICE *physDev, HFONT hfont)
 
   return TRUE; /* Use device font */
 }
-
-/***********************************************************************
- *           TTYDRV_DC_DeleteObject
- */
-BOOL TTYDRV_DC_DeleteObject(HGDIOBJ handle)
-{
-  GDIOBJHDR *ptr = GDI_GetObjPtr(handle, MAGIC_DONTCARE);
-  BOOL result;
-  
-  if(!ptr) return FALSE;
-     
-  switch(GDIMAGIC(ptr->wMagic))
-  {
-    case BITMAP_MAGIC:
-      result = TTYDRV_DC_BITMAP_DeleteObject(handle, (BITMAPOBJ *) ptr);
-      break;
-    case BRUSH_MAGIC:
-    case FONT_MAGIC:
-    case PEN_MAGIC:
-    case REGION_MAGIC:
-      result = TRUE;
-      break;
-    default:
-      ERR("handle (0x%04x) has unknown magic (0x%04x)\n", handle, GDIMAGIC(ptr->wMagic));
-      result = FALSE;
-  }
-
-  GDI_ReleaseObj(handle);
-
-  return result;
-}
diff --git a/dlls/ttydrv/ttydrv.h b/dlls/ttydrv/ttydrv.h
index 7e24df963f439278ead76c1b381db57c68b9f312..19dc93df4c18d9eb88e5cd4a943294f92168784e 100644
--- a/dlls/ttydrv/ttydrv.h
+++ b/dlls/ttydrv/ttydrv.h
@@ -67,10 +67,6 @@ typedef struct {
   int cellHeight;
 } TTYDRV_PDEVICE;
 
-typedef struct {
-  int dummy; /* FIXME: Remove later */
-} TTYDRV_PHYSBITMAP;
-
 extern BOOL TTYDRV_GDI_Initialize(void);
 
 /* TTY GDI bitmap driver */
@@ -78,14 +74,10 @@ extern BOOL TTYDRV_GDI_Initialize(void);
 extern HBITMAP TTYDRV_BITMAP_CreateDIBSection(TTYDRV_PDEVICE *physDev, BITMAPINFO *bmi, UINT usage, LPVOID *bits, HANDLE section, DWORD offset);
 extern void TTYDRV_BITMAP_DeleteDIBSection(struct tagBITMAPOBJ *bmp);
 
-extern BOOL TTYDRV_DC_CreateBitmap(HBITMAP hbitmap);
-
 extern BOOL TTYDRV_DC_Arc(TTYDRV_PDEVICE *physDev, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend);
 extern LONG TTYDRV_DC_BitmapBits(HBITMAP hbitmap, void *bits, LONG count, WORD flags);
-extern BOOL TTYDRV_DC_CreateBitmap(HBITMAP hbitmap);
 extern BOOL TTYDRV_DC_CreateDC(DC *dc, LPCSTR driver, LPCSTR device, LPCSTR output, const DEVMODEA *initData);
 extern BOOL TTYDRV_DC_DeleteDC(TTYDRV_PDEVICE *physDev);
-extern BOOL TTYDRV_DC_DeleteObject(HGDIOBJ handle);
 extern BOOL TTYDRV_DC_BitBlt(TTYDRV_PDEVICE *physDevDst, INT xDst, INT yDst, INT width, INT height, TTYDRV_PDEVICE *physDevSrc, INT xSrc, INT ySrc, DWORD rop);
 extern BOOL TTYDRV_DC_Chord(TTYDRV_PDEVICE *physDev, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend);
 extern BOOL TTYDRV_DC_Ellipse(TTYDRV_PDEVICE *physDev, INT left, INT top, INT right, INT bottom);
diff --git a/dlls/ttydrv/ttydrv.spec b/dlls/ttydrv/ttydrv.spec
index 5d379cbe48ffccf9710c2e5e37f970ddc8029d7b..c935f92ee432b313514902893691a3ecbc6569d9 100644
--- a/dlls/ttydrv/ttydrv.spec
+++ b/dlls/ttydrv/ttydrv.spec
@@ -5,15 +5,13 @@ init	TTYDRV_Init
 
 @ cdecl Arc(ptr long long long long long long long long) TTYDRV_DC_Arc
 @ cdecl BitBlt(ptr long long long long ptr long long long) TTYDRV_DC_BitBlt
-@ cdecl BitmapBits(long ptr long long) TTYDRV_DC_BitmapBits
 @ cdecl Chord(ptr long long long long long long long long) TTYDRV_DC_Chord
-@ cdecl CreateBitmap(long) TTYDRV_DC_CreateBitmap
 @ cdecl CreateDC(ptr str str str ptr) TTYDRV_DC_CreateDC
 @ cdecl DeleteDC(ptr) TTYDRV_DC_DeleteDC
-@ cdecl DeleteObject(long) TTYDRV_DC_DeleteObject
 @ cdecl Ellipse(ptr long long long long) TTYDRV_DC_Ellipse
 @ cdecl ExtFloodFill(ptr long long long long) TTYDRV_DC_ExtFloodFill
 @ cdecl ExtTextOut(ptr long long long ptr ptr long ptr) TTYDRV_DC_ExtTextOut
+@ cdecl GetBitmapBits(long ptr long) TTYDRV_GetBitmapBits
 @ cdecl GetCharWidth(ptr long long ptr) TTYDRV_DC_GetCharWidth
 @ cdecl GetDeviceCaps(ptr long) TTYDRV_GetDeviceCaps
 @ cdecl GetPixel(ptr long long) TTYDRV_DC_GetPixel
@@ -29,8 +27,8 @@ init	TTYDRV_Init
 @ cdecl Polyline(ptr ptr long) TTYDRV_DC_Polyline
 @ cdecl Rectangle(ptr long long long long) TTYDRV_DC_Rectangle
 @ cdecl RoundRect(ptr long long long long long long) TTYDRV_DC_RoundRect
-@ cdecl SelectBitmap(ptr long) TTYDRV_SelectBitmap
 @ cdecl SelectFont(ptr long) TTYDRV_SelectFont
+@ cdecl SetBitmapBits(long ptr long) TTYDRV_SetBitmapBits
 @ cdecl SetDIBitsToDevice(ptr long long long long long long long long ptr ptr long) TTYDRV_DC_SetDIBitsToDevice
 @ cdecl SetPixel(ptr long long long) TTYDRV_DC_SetPixel
 @ cdecl StretchBlt(ptr long long long long ptr long long long long long) TTYDRV_DC_StretchBlt
diff --git a/dlls/x11drv/Makefile.in b/dlls/x11drv/Makefile.in
index 8fd24025ea3d368f2089b94724ca23130a15fb0b..a6c892aacaab3ed8445de349a01fd271b050eb3b 100644
--- a/dlls/x11drv/Makefile.in
+++ b/dlls/x11drv/Makefile.in
@@ -17,7 +17,6 @@ C_SRCS = \
 	$(TOPOBJDIR)/graphics/x11drv/dib.c \
 	$(TOPOBJDIR)/graphics/x11drv/graphics.c \
 	$(TOPOBJDIR)/graphics/x11drv/init.c \
-	$(TOPOBJDIR)/graphics/x11drv/objects.c \
 	$(TOPOBJDIR)/graphics/x11drv/opengl.c \
 	$(TOPOBJDIR)/graphics/x11drv/palette.c \
 	$(TOPOBJDIR)/graphics/x11drv/pen.c \
diff --git a/dlls/x11drv/window.c b/dlls/x11drv/window.c
index eebb6f6917adbe90699d6e1bc9e9aab1275d40e0..b90bce9648b661b4c27f0fa9b56710b6f0c43cfa 100644
--- a/dlls/x11drv/window.c
+++ b/dlls/x11drv/window.c
@@ -275,9 +275,6 @@ static void set_icon_hints( Display *display, WND *wndPtr, XWMHints *hints )
 
         GetIconInfo(hIcon, &ii);
 
-        X11DRV_CreateBitmap(ii.hbmMask);
-        X11DRV_CreateBitmap(ii.hbmColor);
-
         GetObjectA(ii.hbmMask, sizeof(bmMask), &bmMask);
         rcMask.top    = 0;
         rcMask.left   = 0;
@@ -287,6 +284,7 @@ static void set_icon_hints( Display *display, WND *wndPtr, XWMHints *hints )
         hDC = CreateCompatibleDC(0);
         hbmOrig = SelectObject(hDC, ii.hbmMask);
         InvertRect(hDC, &rcMask);
+        SelectObject(hDC, ii.hbmColor);  /* force the color bitmap to x11drv mode too */
         SelectObject(hDC, hbmOrig);
         DeleteDC(hDC);
 
diff --git a/dlls/x11drv/x11drv.spec b/dlls/x11drv/x11drv.spec
index c45306cecc0520d636ffe029f3484e266cff32d3..7cdf10cf1c23fee67382fdcb393067a45e969c7f 100644
--- a/dlls/x11drv/x11drv.spec
+++ b/dlls/x11drv/x11drv.spec
@@ -5,20 +5,20 @@ init	X11DRV_Init
 
 @ cdecl Arc(ptr long long long long long long long long) X11DRV_Arc
 @ cdecl BitBlt(ptr long long long long ptr long long long) X11DRV_BitBlt
-@ cdecl BitmapBits(long ptr long long) X11DRV_BitmapBits
 @ cdecl ChoosePixelFormat(ptr ptr) X11DRV_ChoosePixelFormat
 @ cdecl Chord(ptr long long long long long long long long) X11DRV_Chord
-@ cdecl CreateBitmap(long) X11DRV_CreateBitmap
+@ cdecl CreateBitmap(ptr long) X11DRV_CreateBitmap
 @ cdecl CreateDC(ptr str str str ptr) X11DRV_CreateDC
 @ cdecl CreateDIBSection(ptr ptr long ptr long long long) X11DRV_DIB_CreateDIBSection
+@ cdecl DeleteBitmap(long) X11DRV_DeleteBitmap
 @ cdecl DeleteDC(ptr) X11DRV_DeleteDC
-@ cdecl DeleteObject(long) X11DRV_DeleteObject
 @ cdecl DescribePixelFormat(ptr long long ptr) X11DRV_DescribePixelFormat
 @ cdecl Ellipse(ptr long long long long) X11DRV_Ellipse
 @ cdecl EnumDeviceFonts(ptr ptr ptr long) X11DRV_EnumDeviceFonts
 @ cdecl ExtEscape(ptr long long ptr long ptr) X11DRV_ExtEscape
 @ cdecl ExtFloodFill(ptr long long long long) X11DRV_ExtFloodFill
 @ cdecl ExtTextOut(ptr long long long ptr ptr long ptr) X11DRV_ExtTextOut
+@ cdecl GetBitmapBits(long ptr long) X11DRV_GetBitmapBits
 @ cdecl GetCharWidth(ptr long long ptr) X11DRV_GetCharWidth
 @ cdecl GetDCOrgEx(ptr ptr) X11DRV_GetDCOrgEx
 @ cdecl GetDIBColorTable(ptr long long ptr) X11DRV_GetDIBColorTable
@@ -43,6 +43,7 @@ init	X11DRV_Init
 @ cdecl SelectBrush(ptr long) X11DRV_SelectBrush
 @ cdecl SelectFont(ptr long) X11DRV_SelectFont
 @ cdecl SelectPen(ptr long) X11DRV_SelectPen
+@ cdecl SetBitmapBits(long ptr long) X11DRV_SetBitmapBits
 @ cdecl SetBkColor(ptr long) X11DRV_SetBkColor
 @ cdecl SetDIBColorTable(ptr long long ptr) X11DRV_SetDIBColorTable
 @ cdecl SetDIBits(ptr long long long ptr ptr long) X11DRV_SetDIBits
diff --git a/graphics/mapping.c b/graphics/mapping.c
index 9018bdb9d706498a645299213318924068cdc3b5..143873389202a9af7e94873608b521a7feb08659 100644
--- a/graphics/mapping.c
+++ b/graphics/mapping.c
@@ -53,7 +53,7 @@ void MAPPING_FixIsotropic( DC * dc )
  */
 BOOL16 WINAPI DPtoLP16( HDC16 hdc, LPPOINT16 points, INT16 count )
 {
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    DC * dc = DC_GetDCPtr( hdc );
     if (!dc) return FALSE;
 
     while (count--)
@@ -72,7 +72,7 @@ BOOL16 WINAPI DPtoLP16( HDC16 hdc, LPPOINT16 points, INT16 count )
  */
 BOOL WINAPI DPtoLP( HDC hdc, LPPOINT points, INT count )
 {
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    DC * dc = DC_GetDCPtr( hdc );
     if (!dc) return FALSE;
 
     while (count--)
@@ -91,7 +91,7 @@ BOOL WINAPI DPtoLP( HDC hdc, LPPOINT points, INT count )
  */
 BOOL16 WINAPI LPtoDP16( HDC16 hdc, LPPOINT16 points, INT16 count )
 {
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    DC * dc = DC_GetDCPtr( hdc );
     if (!dc) return FALSE;
 
     while (count--)
@@ -110,7 +110,7 @@ BOOL16 WINAPI LPtoDP16( HDC16 hdc, LPPOINT16 points, INT16 count )
  */
 BOOL WINAPI LPtoDP( HDC hdc, LPPOINT points, INT count )
 {
-    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    DC * dc = DC_GetDCPtr( hdc );
     if (!dc) return FALSE;
 
     while (count--)
diff --git a/graphics/painting.c b/graphics/painting.c
index e43db113121fba075dfb0f73c04aa83ca46f84e3..e75ca264742a22b21d361a7d699c3963ad722cfd 100644
--- a/graphics/painting.c
+++ b/graphics/painting.c
@@ -28,7 +28,6 @@
 #include "winerror.h"
 #include "gdi.h"
 #include "bitmap.h"
-#include "region.h"
 #include "path.h"
 #include "wine/debug.h"
 
diff --git a/graphics/x11drv/bitmap.c b/graphics/x11drv/bitmap.c
index 41e030021e5c571b98e4cb10d5015f0922584db5..9902e81b174a11e31de12e07fcab11af7305d939 100644
--- a/graphics/x11drv/bitmap.c
+++ b/graphics/x11drv/bitmap.c
@@ -38,6 +38,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(x11drv);
 
   /* GCs used for B&W and color bitmap operations */
 GC BITMAP_monoGC = 0, BITMAP_colorGC = 0;
+Pixmap BITMAP_stock_pixmap;   /* pixmap for the default stock bitmap */
 
 extern const DC_FUNCTIONS *X11DRV_DC_Funcs;  /* hack */
 
@@ -51,13 +52,10 @@ BOOL X11DRV_BITMAP_Init(void)
       /* Create the necessary GCs */
 
     wine_tsx11_lock();
-    if ((tmpPixmap = XCreatePixmap( gdi_display, root_window, 1, 1, 1 )))
-    {
-        BITMAP_monoGC = XCreateGC( gdi_display, tmpPixmap, 0, NULL );
-        XSetGraphicsExposures( gdi_display, BITMAP_monoGC, False );
-        XSetSubwindowMode( gdi_display, BITMAP_monoGC, IncludeInferiors );
-        XFreePixmap( gdi_display, tmpPixmap );
-    }
+    BITMAP_stock_pixmap = XCreatePixmap( gdi_display, root_window, 1, 1, 1 );
+    BITMAP_monoGC = XCreateGC( gdi_display, BITMAP_stock_pixmap, 0, NULL );
+    XSetGraphicsExposures( gdi_display, BITMAP_monoGC, False );
+    XSetSubwindowMode( gdi_display, BITMAP_monoGC, IncludeInferiors );
 
     if (screen_depth != 1)
     {
@@ -83,22 +81,10 @@ HBITMAP X11DRV_SelectBitmap( X11DRV_PDEVICE *physDev, HBITMAP hbitmap )
 
     if (!(bmp = GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return 0;
 
-    if(!bmp->physBitmap)
-    {
-        if(!X11DRV_CreateBitmap(hbitmap))
-        {
-            GDI_ReleaseObj( hbitmap );
-            return 0;
-        }
-    }
-
-    if(bmp->funcs != dc->funcs) {
-        WARN("Trying to select non-X11 DDB into an X11 dc\n");
-        GDI_ReleaseObj( hbitmap );
-	return 0;
-    }
-
-    physDev->drawable = (Pixmap)bmp->physBitmap;
+    if (hbitmap == GetStockObject(DEFAULT_BITMAP))
+        physDev->drawable = BITMAP_stock_pixmap;
+    else
+        physDev->drawable = (Pixmap)bmp->physBitmap;
 
       /* Change GC depth if needed */
 
@@ -118,16 +104,13 @@ HBITMAP X11DRV_SelectBitmap( X11DRV_PDEVICE *physDev, HBITMAP hbitmap )
 
 
 /****************************************************************************
- *
- *	  X11DRV_CreateBitmap
+ *	  CreateBitmap   (X11DRV.@)
  *
  * Create a device dependent X11 bitmap
  *
  * Returns TRUE on success else FALSE
- *
  */
-
-BOOL X11DRV_CreateBitmap( HBITMAP hbitmap )
+BOOL X11DRV_CreateBitmap( X11DRV_PDEVICE *physDev, HBITMAP hbitmap )
 {
     BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
 
@@ -149,6 +132,12 @@ BOOL X11DRV_CreateBitmap( HBITMAP hbitmap )
         GDI_ReleaseObj( hbitmap );
 	return FALSE;
     }
+    if (hbitmap == GetStockObject(DEFAULT_BITMAP))
+    {
+        ERR( "called for stock bitmap, please report\n" );
+        GDI_ReleaseObj( hbitmap );
+        return FALSE;
+    }
 
     TRACE("(%08x) %dx%d %d bpp\n", hbitmap, bmp->bitmap.bmWidth,
 	  bmp->bitmap.bmHeight, bmp->bitmap.bmBitsPixel);
@@ -162,12 +151,10 @@ BOOL X11DRV_CreateBitmap( HBITMAP hbitmap )
 	GDI_ReleaseObj( hbitmap );
 	return FALSE;
     }
-    bmp->funcs = X11DRV_DC_Funcs;
 
     if (bmp->bitmap.bmBits) /* Set bitmap bits */
-	X11DRV_BitmapBits( hbitmap, bmp->bitmap.bmBits,
-			   bmp->bitmap.bmHeight * bmp->bitmap.bmWidthBytes,
-			   DDB_SET );
+        X11DRV_SetBitmapBits( hbitmap, bmp->bitmap.bmBits,
+                              bmp->bitmap.bmHeight * bmp->bitmap.bmWidthBytes );
 
     GDI_ReleaseObj( hbitmap );
     return TRUE;
@@ -175,19 +162,21 @@ BOOL X11DRV_CreateBitmap( HBITMAP hbitmap )
 
 
 /***********************************************************************
- *           X11DRV_GetBitmapBits
+ *           GetBitmapBits   (X11DRV.@)
  * 
  * RETURNS
  *    Success: Number of bytes copied
  *    Failure: 0
  */
-static LONG X11DRV_GetBitmapBits(BITMAPOBJ *bmp, void *buffer, LONG count)
+LONG X11DRV_GetBitmapBits( HBITMAP hbitmap, void *buffer, LONG count )
 {
+    BITMAPOBJ *bmp = GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
     LONG old_height, height;
     XImage *image;
     LPBYTE tbuf, startline;
     int	h, w;
 
+    if (!bmp) return 0;
     TRACE("(bmp=%p, buffer=%p, count=0x%lx)\n", bmp, buffer, count);
 
     wine_tsx11_lock();
@@ -296,27 +285,30 @@ static LONG X11DRV_GetBitmapBits(BITMAPOBJ *bmp, void *buffer, LONG count)
     }
     XDestroyImage( image );
     wine_tsx11_unlock();
+    GDI_ReleaseObj( hbitmap );
     return count;
 }
 
 
 
 /******************************************************************************
- *             X11DRV_SetBitmapBits
+ *             SetBitmapBits   (X11DRV.@)
  *
  * RETURNS
  *    Success: Number of bytes used in setting the bitmap bits
  *    Failure: 0
  */
-static LONG X11DRV_SetBitmapBits(BITMAPOBJ *bmp, void *bits, LONG count)
+LONG X11DRV_SetBitmapBits( HBITMAP hbitmap, const void *bits, LONG count )
 {
+    BITMAPOBJ *bmp = GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
     LONG height;
     XImage *image;
-    LPBYTE sbuf, startline;
+    const BYTE *sbuf, *startline;
     int	w, h;
 
+    if (!bmp) return 0;
     TRACE("(bmp=%p, bits=%p, count=0x%lx)\n", bmp, bits, count);
-    
+
     height = count / bmp->bitmap.bmWidthBytes;
 
     wine_tsx11_lock();
@@ -327,6 +319,7 @@ static LONG X11DRV_SetBitmapBits(BITMAPOBJ *bmp, void *bits, LONG count)
         WARN("No memory to create image data.\n");
         XDestroyImage( image );
         wine_tsx11_unlock();
+        GDI_ReleaseObj( hbitmap );
         return 0;
     }
     
@@ -415,44 +408,20 @@ static LONG X11DRV_SetBitmapBits(BITMAPOBJ *bmp, void *bits, LONG count)
                image, 0, 0, 0, 0, bmp->bitmap.bmWidth, height );
     XDestroyImage( image ); /* frees image->data too */
     wine_tsx11_unlock();
-    return count;
-}
-
-/***********************************************************************
- *           X11DRV_BitmapBits
- */
-LONG X11DRV_BitmapBits(HBITMAP hbitmap, void *bits, LONG count, WORD flags)
-{
-    BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
-    LONG ret;
-    if(!bmp) {
-        WARN("Bad bitmap handle %08x\n", hbitmap);
-	return FALSE;
-    }
-
-    if(flags == DDB_GET)
-        ret = X11DRV_GetBitmapBits(bmp, bits, count);
-    else if(flags == DDB_SET)
-        ret = X11DRV_SetBitmapBits(bmp, bits, count);
-    else {
-        ERR("Unknown flags value %d\n", flags);
-	ret = 0;
-    }
     GDI_ReleaseObj( hbitmap );
-    return ret;
+    return count;
 }
 
 /***********************************************************************
- *           X11DRV_BITMAP_DeleteObject
+ *           DeleteBitmap   (X11DRV.@)
  */
-BOOL X11DRV_BITMAP_DeleteObject( HBITMAP hbitmap )
+BOOL X11DRV_DeleteBitmap( HBITMAP hbitmap )
 {
     BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
     if (bmp)
     {
-        TSXFreePixmap( gdi_display, (Pixmap)bmp->physBitmap );
+        if (bmp->physBitmap) TSXFreePixmap( gdi_display, (Pixmap)bmp->physBitmap );
         bmp->physBitmap = NULL;
-        bmp->funcs = NULL;
         if (bmp->dib) X11DRV_DIB_DeleteDIBSection( bmp );
         GDI_ReleaseObj( hbitmap );
     }
diff --git a/graphics/x11drv/brush.c b/graphics/x11drv/brush.c
index aa8ccc7e3e2ce5e3365ecdb9d80a305810724c4c..abe72d609e569d4bd41858f7add38c67005696fb 100644
--- a/graphics/x11drv/brush.c
+++ b/graphics/x11drv/brush.c
@@ -184,14 +184,7 @@ static BOOL BRUSH_SelectPatternBrush( X11DRV_PDEVICE *physDev, HBITMAP hbitmap )
     BITMAPOBJ * bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
     if (!bmp) return FALSE;
 
-   if(!bmp->physBitmap)
-        if(!X11DRV_CreateBitmap(hbitmap))
-	    goto done;
-
-    if(bmp->funcs != dc->funcs) {
-        WARN("Trying to select non-X11 DDB into an X11 dc\n");
-	goto done;
-    }
+    if(!bmp->physBitmap) goto done;
 
     if ((dc->bitsPerPixel == 1) && (bmp->bitmap.bmBitsPixel != 1))
     {
@@ -269,7 +262,7 @@ HBRUSH X11DRV_SelectBrush( X11DRV_PDEVICE *physDev, HBRUSH hbrush )
 	
       case BS_PATTERN:
 	TRACE("BS_PATTERN\n");
-	BRUSH_SelectPatternBrush( physDev, (HBRUSH16)logbrush.lbHatch );
+	if (!BRUSH_SelectPatternBrush( physDev, (HBITMAP)logbrush.lbHatch )) return 0;
 	break;
 
       case BS_DIBPATTERN:
diff --git a/graphics/x11drv/dib.c b/graphics/x11drv/dib.c
index 4981add446ed514316859ff306a7909e34460723..d3624370a5c88faf68fd2aade8bb8c796f8f2d67 100644
--- a/graphics/x11drv/dib.c
+++ b/graphics/x11drv/dib.c
@@ -4872,10 +4872,6 @@ INT X11DRV_SetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
        default: break;
   }
 
-  /* HACK for now */
-  if(!bmp->physBitmap)
-    X11DRV_CreateBitmap(hbitmap);
-
   descr.bits      = bits;
   descr.image     = NULL;
   descr.palentry  = NULL;
@@ -4975,11 +4971,6 @@ INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
           break;
   }
 
-  /* Hack for now */
-  if(!bmp->physBitmap)
-    X11DRV_CreateBitmap(hbitmap);
-
-
   descr.physDev   = physDev;
   descr.palentry  = palette->logpalette.palPalEntry;
   descr.bits      = bits;
@@ -5744,13 +5735,7 @@ HBITMAP X11DRV_DIB_CreateDIBSection(
       if (res)
 	{
 	  bmp = (BITMAPOBJ *) GDI_GetObjPtr(res, BITMAP_MAGIC);
-	  if (bmp)
-	    {
-	      bmp->dib = (DIBSECTION *) dib;
-	      /* HACK for now */
-	      if(!bmp->physBitmap)
-		X11DRV_CreateBitmap(res); 
-	    }
+	  if (bmp) bmp->dib = (DIBSECTION *) dib;
 	}
     }
   
diff --git a/graphics/x11drv/init.c b/graphics/x11drv/init.c
index ceca915ca85e8db57eb9af9bab9f9d43ee413a49..72b57627280cb207c4fa10993704c8ce8d965e92 100644
--- a/graphics/x11drv/init.c
+++ b/graphics/x11drv/init.c
@@ -46,7 +46,6 @@ PALETTE_DRIVER X11DRV_PALETTE_Driver =
 
 Display *gdi_display;  /* display to use for all GDI functions */
 
-
 /* a few dynamic device caps */
 static int log_pixels_x;  /* pixels per logical inch in x direction */
 static int log_pixels_y;  /* pixels per logical inch in y direction */
@@ -116,21 +115,11 @@ BOOL X11DRV_CreateDC( DC *dc, LPCSTR driver, LPCSTR device,
 
     if (dc->flags & DC_MEMORY)
     {
-        BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC );
-	if (!bmp) 
-	{
-	    HeapFree( GetProcessHeap(), 0, physDev );
-	    return FALSE;
-        }
-        if (!bmp->physBitmap) X11DRV_CreateBitmap( dc->hBitmap );
-        physDev->drawable  = (Pixmap)bmp->physBitmap;
-        physDev->gc        = TSXCreateGC( gdi_display, physDev->drawable, 0, NULL );
-        GDI_ReleaseObj( dc->hBitmap );
+        physDev->drawable  = BITMAP_stock_pixmap;
     }
     else
     {
         physDev->drawable  = root_window;
-        physDev->gc        = TSXCreateGC( gdi_display, physDev->drawable, 0, NULL );
         dc->bitsPerPixel   = screen_depth;
     }
 
@@ -138,6 +127,7 @@ BOOL X11DRV_CreateDC( DC *dc, LPCSTR driver, LPCSTR device,
     physDev->used_visuals = 0;
 
     wine_tsx11_lock();
+    physDev->gc = XCreateGC( gdi_display, physDev->drawable, 0, NULL );
     XSetGraphicsExposures( gdi_display, physDev->gc, False );
     XSetSubwindowMode( gdi_display, physDev->gc, IncludeInferiors );
     XFlush( gdi_display );
diff --git a/graphics/x11drv/objects.c b/graphics/x11drv/objects.c
deleted file mode 100644
index ecc8ff0a87ee55af39c2356237276870ae89a37a..0000000000000000000000000000000000000000
--- a/graphics/x11drv/objects.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * GDI objects
- *
- * Copyright 1993 Alexandre Julliard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "x11drv.h"
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(gdi);
-
-
-/***********************************************************************
- *           X11DRV_DeleteObject
- */
-BOOL X11DRV_DeleteObject( HGDIOBJ handle )
-{
-    switch(GetObjectType( handle ))
-    {
-    case OBJ_BITMAP:
-        return X11DRV_BITMAP_DeleteObject( handle );
-    default:
-        ERR("Shouldn't be here!\n");
-        break;
-    }
-    return FALSE;
-}
diff --git a/include/bitmap.h b/include/bitmap.h
index 5eb5355e8704b605d4c9ab2dca2c3c5cd95f37f4..166df6a80ad6c3410194ab01516a51b0564e9c9f 100644
--- a/include/bitmap.h
+++ b/include/bitmap.h
@@ -23,13 +23,6 @@
 
 #include "gdi.h"
 
-/* Flags used for BitmapBits. We only use the first two at the moment */
-
-#define DDB_SET			1
-#define DDB_GET			2
-#define DDB_COPY		4
-#define DDB_SETWITHFILLER	8
-
 /* DIB Section sync state */
 enum { DIB_Status_None, DIB_Status_InSync, DIB_Status_GdiMod, DIB_Status_AppMod, DIB_Status_AuxMod };
 
@@ -47,11 +40,9 @@ typedef struct tagBITMAPOBJ
 } BITMAPOBJ;
 
   /* objects/bitmap.c */
-extern INT16   BITMAP_GetObject16( BITMAPOBJ * bmp, INT16 count, LPVOID buffer );
-extern INT   BITMAP_GetObject( BITMAPOBJ * bmp, INT count, LPVOID buffer );
-extern BOOL  BITMAP_DeleteObject( HBITMAP16 hbitmap, BITMAPOBJ * bitmap );
 extern INT   BITMAP_GetWidthBytes( INT width, INT depth );
 extern HBITMAP BITMAP_CopyBitmap( HBITMAP hbitmap );
+extern BOOL BITMAP_SetOwnerDC( HBITMAP hbitmap, DC *dc );
 
   /* objects/dib.c */
 extern int DIB_GetDIBWidthBytes( int width, int depth );
diff --git a/include/brush.h b/include/brush.h
deleted file mode 100644
index 996067c017e67ab5f550e09c0db5f2f4e625d51c..0000000000000000000000000000000000000000
--- a/include/brush.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * GDI brush definitions
- *
- * Copyright 1994 Alexandre Julliard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef __WINE_BRUSH_H
-#define __WINE_BRUSH_H
-
-#include "gdi.h"
-
-  /* GDI logical brush object */
-typedef struct
-{
-    GDIOBJHDR   header;
-    LOGBRUSH  logbrush;
-} BRUSHOBJ;
-
-#define NB_HATCH_STYLES  6
-
-extern INT16 BRUSH_GetObject16( BRUSHOBJ * brush, INT16 count, LPSTR buffer );
-extern INT BRUSH_GetObject( BRUSHOBJ * brush, INT count, LPSTR buffer );
-extern BOOL BRUSH_DeleteObject( HBRUSH16 hbrush, BRUSHOBJ * brush );
-
-#endif  /* __WINE_BRUSH_H */
diff --git a/include/font.h b/include/font.h
index 19c6de6fe4f96a7bf9b21c75d1ba5f3ca5d16dbe..8ec8100440d5a7368238aecaf22a7a9ef346df04 100644
--- a/include/font.h
+++ b/include/font.h
@@ -70,9 +70,6 @@ typedef struct {
 #define FONTCACHE 	32	/* dynamic font cache size */
 
 extern BOOL FONT_Init( UINT16* pTextCaps );
-extern INT16  FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer );
-extern INT  FONT_GetObjectA( FONTOBJ * font, INT count, LPSTR buffer );
-extern INT  FONT_GetObjectW( FONTOBJ * font, INT count, LPSTR buffer );
 extern void FONT_LogFontATo16( const LOGFONTA* font32, LPLOGFONT16 font16 );
 extern void FONT_LogFontWTo16( const LOGFONTW* font32, LPLOGFONT16 font16 );
 extern void FONT_LogFont16ToA( const LOGFONT16* font16, LPLOGFONTA font32 );
diff --git a/include/gdi.h b/include/gdi.h
index d7ffe88f8cccc3502301edd81070b1b741e5a328..9fd05503cd0f69085a0bd74730caf208d455a35b 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -52,11 +52,22 @@
 
 #define GDIMAGIC(magic) ((magic) & ~(OBJECT_PRIVATE|OBJECT_NOSYSTEM))
 
+struct gdi_obj_funcs
+{
+    HGDIOBJ (*pSelectObject)( HGDIOBJ handle, void *obj, HDC hdc );
+    INT     (*pGetObject16)( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
+    INT     (*pGetObjectA)( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
+    INT     (*pGetObjectW)( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
+    BOOL    (*pUnrealizeObject)( HGDIOBJ handle, void *obj );
+    BOOL    (*pDeleteObject)( HGDIOBJ handle, void *obj );
+};
+
 typedef struct tagGDIOBJHDR
 {
     HANDLE16    hNext;
     WORD        wMagic;
     DWORD       dwCount;
+    const struct gdi_obj_funcs *funcs;
 } GDIOBJHDR;
 
 
@@ -147,15 +158,14 @@ typedef struct tagDC_FUNCS
     BOOL     (*pArcTo)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
     BOOL     (*pBeginPath)(PHYSDEV);
     BOOL     (*pBitBlt)(PHYSDEV,INT,INT,INT,INT,PHYSDEV,INT,INT,DWORD);
-    LONG     (*pBitmapBits)(HBITMAP,void*,LONG,WORD);
     INT      (*pChoosePixelFormat)(PHYSDEV,const PIXELFORMATDESCRIPTOR *);
     BOOL     (*pChord)(PHYSDEV,INT,INT,INT,INT,INT,INT,INT,INT);
     BOOL     (*pCloseFigure)(PHYSDEV);
-    BOOL     (*pCreateBitmap)(HBITMAP);
+    BOOL     (*pCreateBitmap)(PHYSDEV,HBITMAP);
     BOOL     (*pCreateDC)(DC *,LPCSTR,LPCSTR,LPCSTR,const DEVMODEA*);
     HBITMAP  (*pCreateDIBSection)(PHYSDEV,BITMAPINFO *,UINT,LPVOID *,HANDLE,DWORD,DWORD);
+    BOOL     (*pDeleteBitmap)(HBITMAP);
     BOOL     (*pDeleteDC)(PHYSDEV);
-    BOOL     (*pDeleteObject)(HGDIOBJ);
     INT      (*pDescribePixelFormat)(PHYSDEV,INT,UINT,PIXELFORMATDESCRIPTOR *);
     DWORD    (*pDeviceCapabilities)(LPSTR,LPCSTR,LPCSTR,WORD,LPSTR,LPDEVMODEA);
     BOOL     (*pEllipse)(PHYSDEV,INT,INT,INT,INT);
@@ -173,6 +183,7 @@ typedef struct tagDC_FUNCS
     BOOL     (*pFillRgn)(PHYSDEV,HRGN,HBRUSH);
     BOOL     (*pFlattenPath)(PHYSDEV);
     BOOL     (*pFrameRgn)(PHYSDEV,HRGN,HBRUSH,INT,INT);
+    LONG     (*pGetBitmapBits)(HBITMAP,void*,LONG);
     BOOL     (*pGetCharWidth)(PHYSDEV,UINT,UINT,LPINT);
     BOOL     (*pGetDCOrgEx)(PHYSDEV,LPPOINT);
     UINT     (*pGetDIBColorTable)(PHYSDEV,UINT,UINT,RGBQUAD*);
@@ -215,6 +226,7 @@ typedef struct tagDC_FUNCS
     HFONT    (*pSelectFont)(PHYSDEV,HFONT);
     HPALETTE (*pSelectPalette)(PHYSDEV,HPALETTE,BOOL);
     HPEN     (*pSelectPen)(PHYSDEV,HPEN);
+    LONG     (*pSetBitmapBits)(HBITMAP,const void*,LONG);
     COLORREF (*pSetBkColor)(PHYSDEV,COLORREF);
     INT      (*pSetBkMode)(PHYSDEV,INT);
     UINT     (*pSetDIBColorTable)(PHYSDEV,UINT,UINT,const RGBQUAD*);
@@ -560,7 +572,7 @@ static inline INT INTERNAL_YDSTOWS(DC *dc, INT height)
   /* GDI local heap */
 
 extern BOOL GDI_Init(void);
-extern void *GDI_AllocObject( WORD, WORD, HGDIOBJ * );
+extern void *GDI_AllocObject( WORD, WORD, HGDIOBJ *, const struct gdi_obj_funcs *funcs );
 extern void *GDI_ReallocObject( WORD, HGDIOBJ, void *obj );
 extern BOOL GDI_FreeObject( HGDIOBJ, void *obj );
 extern void *GDI_GetObjPtr( HGDIOBJ, WORD );
@@ -586,6 +598,10 @@ extern void CLIPPING_UpdateGCRegion( DC * dc );
 /* objects/enhmetafile.c */
 extern HENHMETAFILE EMF_Create_HENHMETAFILE(ENHMETAHEADER *emh, BOOL on_disk );
 
+/* region.c */
+extern HRGN REGION_CropRgn( HRGN hDst, HRGN hSrc, const RECT *lpRect, const POINT *lpPt );
+extern BOOL REGION_FrameRgn( HRGN dest, HRGN src, INT x, INT y );
+
 #define WINE_GGO_GRAY16_BITMAP 0x7f
 
 #endif  /* __WINE_GDI_H */
diff --git a/include/palette.h b/include/palette.h
index 1c024269740367cc060a008edd1d324ddfd9d48e..9702c56b9cdba290c9abedab3dd7aefcf6857e08 100644
--- a/include/palette.h
+++ b/include/palette.h
@@ -43,11 +43,5 @@ typedef struct tagPALETTE_DRIVER
 extern PALETTE_DRIVER *PALETTE_Driver;
 
 extern HPALETTE16 PALETTE_Init(void);
-extern int PALETTE_GetObject( PALETTEOBJ * palette, int count, LPSTR buffer );
-extern BOOL PALETTE_DeleteObject( HPALETTE16 hpalette, PALETTEOBJ *palette );
-extern BOOL PALETTE_UnrealizeObject( HPALETTE16 hpalette, PALETTEOBJ *palette);
-     
-extern HPALETTE16 WINAPI CreateHalftonePalette16(HDC16 hdc);
-extern HPALETTE WINAPI CreateHalftonePalette(HDC hdc);
 
 #endif /* __WINE_PALETTE_H */
diff --git a/include/pen.h b/include/pen.h
deleted file mode 100644
index 75a73bbd211f8c79ca389cadd4c73bd377be9d75..0000000000000000000000000000000000000000
--- a/include/pen.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * GDI pen definitions
- *
- * Copyright 1994 Alexandre Julliard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef __WINE_PEN_H
-#define __WINE_PEN_H
-
-#include "gdi.h"
-
-  /* GDI logical pen object */
-typedef struct
-{
-    GDIOBJHDR   header;
-    LOGPEN    logpen;
-} PENOBJ;
-
-extern INT16 PEN_GetObject16( PENOBJ * pen, INT16 count, LPSTR buffer );
-extern INT PEN_GetObject( PENOBJ * pen, INT count, LPSTR buffer );
-
-#endif  /* __WINE_PEN_H */
diff --git a/include/region.h b/include/region.h
deleted file mode 100644
index 682cb2c59913cf57eb17f2db594cfb8a4cb4ccd5..0000000000000000000000000000000000000000
--- a/include/region.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * GDI region definitions
- *
- * Copyright 1998 Huw Davies
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef __WINE_REGION_H
-#define __WINE_REGION_H
-
-#include "gdi.h"
-#include "windef.h"
-#include "wingdi.h"
-
-struct _RGNOBJ;
-
-extern BOOL REGION_DeleteObject( HRGN hrgn, struct _RGNOBJ * obj );
-extern HRGN REGION_CropRgn( HRGN hDst, HRGN hSrc, const RECT *lpRect, const POINT *lpPt );
-extern BOOL REGION_FrameRgn( HRGN dest, HRGN src, INT x, INT y );
-
-#endif  /* __WINE_REGION_H */
-
-
diff --git a/include/wine/wingdi16.h b/include/wine/wingdi16.h
index 91d7c8400b6ecc4fb49720ba8b86ccd10afc8222..2e9769690fc176b765b8562cd3ef6b9d13dbfd34 100644
--- a/include/wine/wingdi16.h
+++ b/include/wine/wingdi16.h
@@ -355,6 +355,7 @@ HRGN16      WINAPI CreateEllipticRgnIndirect16(const RECT16 *);
 HFONT16     WINAPI CreateFont16(INT16,INT16,INT16,INT16,INT16,BYTE,BYTE,BYTE,
                                 BYTE,BYTE,BYTE,BYTE,BYTE,LPCSTR);
 HFONT16     WINAPI CreateFontIndirect16(const LOGFONT16*);
+HPALETTE16  WINAPI CreateHalftonePalette16(HDC16);
 HBRUSH16    WINAPI CreateHatchBrush16(INT16,COLORREF);
 HDC16       WINAPI CreateIC16(LPCSTR,LPCSTR,LPCSTR,const DEVMODEA*);
 HDC16       WINAPI CreateMetaFile16(LPCSTR);
diff --git a/include/x11drv.h b/include/x11drv.h
index b5bd9f486afe1adcd9f9b089b0541911418ed14d..3e6cd7b8ca916bb083861a67d449664eb36379e6 100644
--- a/include/x11drv.h
+++ b/include/x11drv.h
@@ -97,6 +97,7 @@ typedef struct
 
   /* GCs used for B&W and color bitmap operations */
 extern GC BITMAP_monoGC, BITMAP_colorGC;
+extern Pixmap BITMAP_stock_pixmap;   /* pixmap for the default stock bitmap */
 
 #define BITMAP_GC(bmp) \
   (((bmp)->bitmap.bmBitsPixel == 1) ? BITMAP_monoGC : BITMAP_colorGC)
@@ -110,6 +111,7 @@ extern BOOL X11DRV_BitBlt( X11DRV_PDEVICE *physDevDst, INT xDst, INT yDst,
                              INT xSrc, INT ySrc, DWORD rop );
 extern BOOL X11DRV_EnumDeviceFonts( X11DRV_PDEVICE *physDev, LPLOGFONTW plf,
 				    DEVICEFONTENUMPROC dfeproc, LPARAM lp );
+extern LONG X11DRV_GetBitmapBits( HBITMAP hbitmap, void *bits, LONG count );
 extern BOOL X11DRV_GetCharWidth( X11DRV_PDEVICE *physDev, UINT firstChar,
                                    UINT lastChar, LPINT buffer );
 extern BOOL X11DRV_GetDCOrgEx( X11DRV_PDEVICE *physDev, LPPOINT lpp );
@@ -157,20 +159,13 @@ extern BOOL X11DRV_ExtFloodFill( X11DRV_PDEVICE *physDev, INT x, INT y,
 extern BOOL X11DRV_ExtTextOut( X11DRV_PDEVICE *physDev, INT x, INT y,
 				 UINT flags, const RECT *lprect,
 				 LPCWSTR str, UINT count, const INT *lpDx );
-extern BOOL X11DRV_CreateBitmap( HBITMAP hbitmap );
-extern BOOL X11DRV_DeleteObject( HGDIOBJ handle );
-extern LONG X11DRV_BitmapBits( HBITMAP hbitmap, void *bits, LONG count,
-			       WORD flags );
+extern LONG X11DRV_SetBitmapBits( HBITMAP hbitmap, const void *bits, LONG count );
 extern INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest,
 				       INT yDest, DWORD cx, DWORD cy,
 				       INT xSrc, INT ySrc,
 				       UINT startscan, UINT lines,
 				       LPCVOID bits, const BITMAPINFO *info,
 				       UINT coloruse );
-extern INT X11DRV_DeviceBitmapBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap,
-				      WORD fGet, UINT startscan,
-				      UINT lines, LPSTR bits,
-				      LPBITMAPINFO info, UINT coloruse );
 extern BOOL X11DRV_GetDeviceGammaRamp( X11DRV_PDEVICE *physDev, LPVOID ramp );
 extern BOOL X11DRV_SetDeviceGammaRamp( X11DRV_PDEVICE *physDev, LPVOID ramp );
 
@@ -187,7 +182,6 @@ extern BOOL X11DRV_SwapBuffers(X11DRV_PDEVICE *physDev);
 
 extern BOOL X11DRV_BITMAP_Init(void);
 extern void X11DRV_FONT_Init( int *log_pixels_x, int *log_pixels_y );
-extern BOOL X11DRV_BITMAP_DeleteObject( HBITMAP hbitmap );
 
 struct tagBITMAPOBJ;
 extern XImage *X11DRV_BITMAP_GetXImage( const struct tagBITMAPOBJ *bmp );
diff --git a/objects/bitmap.c b/objects/bitmap.c
index 57ee54cb5c9a41989e5cbf9daed9d5997b790587..7b5e0a9183f7b76b1b3b26e7c0ea8ea788e39d52 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -32,6 +32,21 @@
 WINE_DEFAULT_DEBUG_CHANNEL(bitmap);
 
 
+static HGDIOBJ BITMAP_SelectObject( HGDIOBJ handle, void *obj, HDC hdc );
+static INT BITMAP_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
+static INT BITMAP_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
+static BOOL BITMAP_DeleteObject( HGDIOBJ handle, void *obj );
+
+static const struct gdi_obj_funcs bitmap_funcs =
+{
+    BITMAP_SelectObject,  /* pSelectObject */
+    BITMAP_GetObject16,   /* pGetObject16 */
+    BITMAP_GetObject,     /* pGetObjectA */
+    BITMAP_GetObject,     /* pGetObjectW */
+    NULL,                 /* pUnrealizeObject */
+    BITMAP_DeleteObject   /* pDeleteObject */
+};
+
 /***********************************************************************
  *           BITMAP_GetWidthBytes
  *
@@ -138,7 +153,8 @@ HBITMAP WINAPI CreateBitmap( INT width, INT height, UINT planes,
     if (width < 0) width = -width;
 
       /* Create the BITMAPOBJ */
-    if (!(bmp = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC, &hbitmap ))) return 0;
+    if (!(bmp = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC, &hbitmap, &bitmap_funcs )))
+        return 0;
 
     TRACE("%dx%d, %d colors returning %08x\n", width, height,
 	  1 << (planes*bpp), hbitmap);
@@ -203,8 +219,12 @@ HBITMAP WINAPI CreateCompatibleBitmap( HDC hdc, INT width, INT height)
 	   hbmpRet = CreateBitmap( 1, 1, 1, 1, NULL );
 	else 
 	   hbmpRet = CreateBitmap( width, height, 1, dc->bitsPerPixel, NULL );
-	if(dc->funcs->pCreateBitmap)
-	    dc->funcs->pCreateBitmap( hbmpRet );
+
+        if (!BITMAP_SetOwnerDC( hbmpRet, dc ))
+        {
+            DeleteObject( hbmpRet );
+            hbmpRet = 0;
+        }
     }
     TRACE("\t\t%04x\n", hbmpRet);
     GDI_ReleaseObj(hdc);
@@ -291,16 +311,16 @@ LONG WINAPI GetBitmapBits(
           hbitmap, count, bits, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
           1 << bmp->bitmap.bmBitsPixel, height );
 
-    if(bmp->funcs) { 
-
+    if(bmp->funcs)
+    {
         TRACE("Calling device specific BitmapBits\n");
-	if(bmp->funcs->pBitmapBits)
-	    ret = bmp->funcs->pBitmapBits(hbitmap, bits, count, DDB_GET);
-	else {
-	    ERR("BitmapBits == NULL??\n");
-	    ret = 0;
-	}	
-
+        if(bmp->funcs->pGetBitmapBits)
+            ret = bmp->funcs->pGetBitmapBits(hbitmap, bits, count);
+        else
+        {
+            memset( bits, 0, count );
+            ret = count;
+        }
     } else {
 
         if(!bmp->bitmap.bmBits) {
@@ -362,13 +382,10 @@ LONG WINAPI SetBitmapBits(
     if(bmp->funcs) {
 
         TRACE("Calling device specific BitmapBits\n");
-	if(bmp->funcs->pBitmapBits)
-	    ret = bmp->funcs->pBitmapBits(hbitmap, (void *) bits, count, DDB_SET);
-	else {
-	    ERR("BitmapBits == NULL??\n");
-	    ret = 0;
-	}
-	
+        if(bmp->funcs->pSetBitmapBits)
+            ret = bmp->funcs->pSetBitmapBits(hbitmap, bits, count);
+        else
+            ret = 0;
     } else {
 
         if(!bmp->bitmap.bmBits) /* Alloc enough for entire bitmap */
@@ -414,13 +431,105 @@ HBITMAP BITMAP_CopyBitmap(HBITMAP hbitmap)
     return res;
 }
 
+
+/***********************************************************************
+ *           BITMAP_SetOwnerDC
+ *
+ * Set the type of DC that owns the bitmap. This is used when the
+ * bitmap is selected into a device to initialize the bitmap function
+ * table.
+ */
+BOOL BITMAP_SetOwnerDC( HBITMAP hbitmap, DC *dc )
+{
+    BITMAPOBJ *bitmap;
+    BOOL ret;
+
+    /* never set the owner of the stock bitmap since it can be selected in multiple DCs */
+    if (hbitmap == GetStockObject(DEFAULT_BITMAP)) return TRUE;
+
+    if (!(bitmap = GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return FALSE;
+
+    ret = TRUE;
+    if (!bitmap->funcs)  /* not owned by a DC yet */
+    {
+        if (dc->funcs->pCreateBitmap) ret = dc->funcs->pCreateBitmap( dc->physDev, hbitmap );
+        if (ret) bitmap->funcs = dc->funcs;
+    }
+    else if (bitmap->funcs != dc->funcs)
+    {
+        FIXME( "Trying to select bitmap %x in different DC type\n", hbitmap );
+        ret = FALSE;
+    }
+    GDI_ReleaseObj( hbitmap );
+    return ret;
+}
+
+
+/***********************************************************************
+ *           BITMAP_SelectObject
+ */
+static HGDIOBJ BITMAP_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
+{
+    HGDIOBJ ret = handle;
+    BITMAPOBJ *bitmap = obj;
+    DC *dc = DC_GetDCPtr( hdc );
+
+    if (!dc) return 0;
+    if (!(dc->flags & DC_MEMORY))
+    {
+        GDI_ReleaseObj( hdc );
+        return 0;
+    }
+    if (handle == dc->hBitmap) goto done;  /* nothing to do */
+
+    if (bitmap->header.dwCount && (handle != GetStockObject(DEFAULT_BITMAP)))
+    {
+        WARN( "Bitmap already selected in another DC\n" );
+        GDI_ReleaseObj( hdc );
+        return 0;
+    }
+
+    if (!bitmap->funcs && !BITMAP_SetOwnerDC( handle, dc ))
+    {
+        GDI_ReleaseObj( hdc );
+        return 0;
+    }
+
+    if (dc->funcs->pSelectBitmap) ret = dc->funcs->pSelectBitmap( dc->physDev, handle );
+
+    if (ret)
+    {
+        dc->hBitmap            = ret;
+        dc->totalExtent.left   = 0;
+        dc->totalExtent.top    = 0;
+        dc->totalExtent.right  = bitmap->bitmap.bmWidth;
+        dc->totalExtent.bottom = bitmap->bitmap.bmHeight;
+        dc->flags &= ~DC_DIRTY;
+        SetRectRgn( dc->hVisRgn, 0, 0, bitmap->bitmap.bmWidth, bitmap->bitmap.bmHeight);
+        CLIPPING_UpdateGCRegion( dc );
+
+        if (dc->bitsPerPixel != bitmap->bitmap.bmBitsPixel)
+        {
+            /* depth changed, reinitialize the DC */
+            dc->bitsPerPixel = bitmap->bitmap.bmBitsPixel;
+            DC_InitDC( dc );
+        }
+    }
+ done:
+    GDI_ReleaseObj( hdc );
+    return ret;
+}
+
+
 /***********************************************************************
  *           BITMAP_DeleteObject
  */
-BOOL BITMAP_DeleteObject( HBITMAP16 hbitmap, BITMAPOBJ * bmp )
+static BOOL BITMAP_DeleteObject( HGDIOBJ handle, void *obj )
 {
-    if (bmp->funcs && bmp->funcs->pDeleteObject)
-        bmp->funcs->pDeleteObject( hbitmap );
+    BITMAPOBJ * bmp = obj;
+
+    if (bmp->funcs && bmp->funcs->pDeleteBitmap)
+        bmp->funcs->pDeleteBitmap( handle );
 
     if( bmp->bitmap.bmBits )
         HeapFree( GetProcessHeap(), 0, bmp->bitmap.bmBits );
@@ -452,15 +561,17 @@ BOOL BITMAP_DeleteObject( HBITMAP16 hbitmap, BITMAPOBJ * bmp )
             for (i = 0; i < count; i++) FreeSelector16(sel + (i << __AHSHIFT));
         }
     }
-    return GDI_FreeObject( hbitmap, bmp );
+    return GDI_FreeObject( handle, obj );
 }
 
 
 /***********************************************************************
  *           BITMAP_GetObject16
  */
-INT16 BITMAP_GetObject16( BITMAPOBJ * bmp, INT16 count, LPVOID buffer )
+static INT BITMAP_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
 {
+    BITMAPOBJ *bmp = obj;
+
     if (bmp->dib)
     {
         if ( count <= sizeof(BITMAP16) )
@@ -503,8 +614,10 @@ INT16 BITMAP_GetObject16( BITMAPOBJ * bmp, INT16 count, LPVOID buffer )
 /***********************************************************************
  *           BITMAP_GetObject
  */
-INT BITMAP_GetObject( BITMAPOBJ * bmp, INT count, LPVOID buffer )
+static INT BITMAP_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
 {
+    BITMAPOBJ *bmp = obj;
+
     if (bmp->dib)
     {
 	if (count < sizeof(DIBSECTION))
diff --git a/objects/brush.c b/objects/brush.c
index ac747f7274b545f91aa6c938aaabef7dde16d562..16e107b3533b4d66e1951e1f85ee7bd56d084ae5 100644
--- a/objects/brush.c
+++ b/objects/brush.c
@@ -24,15 +24,36 @@
 
 #include "winbase.h"
 #include "wingdi.h"
-
 #include "wine/wingdi16.h"
 #include "bitmap.h"
-#include "brush.h"
-
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(gdi);
 
+/* GDI logical brush object */
+typedef struct
+{
+    GDIOBJHDR header;
+    LOGBRUSH  logbrush;
+} BRUSHOBJ;
+
+#define NB_HATCH_STYLES  6
+
+static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, void *obj, HDC hdc );
+static INT BRUSH_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
+static INT BRUSH_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
+static BOOL BRUSH_DeleteObject( HGDIOBJ handle, void *obj );
+
+static const struct gdi_obj_funcs brush_funcs =
+{
+    BRUSH_SelectObject,  /* pSelectObject */
+    BRUSH_GetObject16,   /* pGetObject16 */
+    BRUSH_GetObject,     /* pGetObjectA */
+    BRUSH_GetObject,     /* pGetObjectW */
+    NULL,                /* pUnrealizeObject */
+    BRUSH_DeleteObject   /* pDeleteObject */
+};
+
 static HGLOBAL16 dib_copy(BITMAPINFO *info, UINT coloruse)
 {
     BITMAPINFO  *newInfo;
@@ -128,7 +149,8 @@ HBRUSH16 WINAPI CreateBrushIndirect16( const LOGBRUSH16 * brush )
     BRUSHOBJ * brushPtr;
     HBRUSH hbrush;
 
-    if (!(brushPtr = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC, &hbrush ))) return 0;
+    if (!(brushPtr = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC, &hbrush, &brush_funcs )))
+        return 0;
     brushPtr->logbrush.lbStyle = brush->lbStyle;
     brushPtr->logbrush.lbColor = brush->lbColor;
     brushPtr->logbrush.lbHatch = brush->lbHatch;
@@ -158,7 +180,8 @@ HBRUSH WINAPI CreateBrushIndirect( const LOGBRUSH * brush )
     BOOL success;
     BRUSHOBJ * brushPtr;
     HBRUSH hbrush;
-    if (!(brushPtr = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC, &hbrush ))) return 0;
+    if (!(brushPtr = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC, &hbrush, &brush_funcs )))
+        return 0;
     brushPtr->logbrush.lbStyle = brush->lbStyle;
     brushPtr->logbrush.lbColor = brush->lbColor;
     brushPtr->logbrush.lbHatch = brush->lbHatch;
@@ -218,7 +241,7 @@ HBRUSH WINAPI CreatePatternBrush( HBITMAP hbitmap )
     TRACE("%04x\n", hbitmap );
 
     logbrush.lbHatch = hbitmap;
-        return CreateBrushIndirect( &logbrush );
+    return CreateBrushIndirect( &logbrush );
 }
 
 
@@ -236,7 +259,7 @@ HBRUSH16 WINAPI CreateDIBPatternBrush16( HGLOBAL16 hbitmap, UINT16 coloruse )
     logbrush.lbHatch = hbitmap;
 
     return CreateBrushIndirect16( &logbrush );
-    }
+}
 
 
 /***********************************************************************
@@ -373,11 +396,36 @@ BOOL WINAPI FixBrushOrgEx( HDC hdc, INT x, INT y, LPPOINT oldorg )
 }
 
 
+/***********************************************************************
+ *           BRUSH_SelectObject
+ */
+static HGDIOBJ BRUSH_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
+{
+    BRUSHOBJ *brush = obj;
+    HGDIOBJ ret;
+    DC *dc = DC_GetDCPtr( hdc );
+
+    if (!dc) return 0;
+
+    if (brush->logbrush.lbStyle == BS_PATTERN)
+        BITMAP_SetOwnerDC( (HBITMAP)brush->logbrush.lbHatch, dc );
+
+    ret = dc->hBrush;
+    if (dc->funcs->pSelectBrush) handle = dc->funcs->pSelectBrush( dc->physDev, handle );
+    if (handle) dc->hBrush = handle;
+    else ret = 0;
+    GDI_ReleaseObj( hdc );
+    return ret;
+}
+
+
 /***********************************************************************
  *           BRUSH_DeleteObject
  */
-BOOL BRUSH_DeleteObject( HBRUSH16 hbrush, BRUSHOBJ * brush )
+static BOOL BRUSH_DeleteObject( HGDIOBJ handle, void *obj )
 {
+    BRUSHOBJ *brush = obj;
+
     switch(brush->logbrush.lbStyle)
     {
       case BS_PATTERN:
@@ -387,15 +435,16 @@ BOOL BRUSH_DeleteObject( HBRUSH16 hbrush, BRUSHOBJ * brush )
 	  GlobalFree16( (HGLOBAL16)brush->logbrush.lbHatch );
 	  break;
     }
-    return GDI_FreeObject( hbrush, brush );
+    return GDI_FreeObject( handle, obj );
 }
 
 
 /***********************************************************************
  *           BRUSH_GetObject16
  */
-INT16 BRUSH_GetObject16( BRUSHOBJ * brush, INT16 count, LPSTR buffer )
+static INT BRUSH_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
 {
+    BRUSHOBJ *brush = obj;
     LOGBRUSH16 logbrush;
 
     logbrush.lbStyle = brush->logbrush.lbStyle;
@@ -410,8 +459,10 @@ INT16 BRUSH_GetObject16( BRUSHOBJ * brush, INT16 count, LPSTR buffer )
 /***********************************************************************
  *           BRUSH_GetObject
  */
-INT BRUSH_GetObject( BRUSHOBJ * brush, INT count, LPSTR buffer )
+static INT BRUSH_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
 {
+    BRUSHOBJ *brush = obj;
+
     if (count > sizeof(brush->logbrush)) count = sizeof(brush->logbrush);
     memcpy( buffer, &brush->logbrush, count );
     return count;
diff --git a/objects/dc.c b/objects/dc.c
index 06cd6eb0913babb400655cd5871e67babf8be02e..6a0e78831b371ae48efad312ce47878155a38e53 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -37,6 +37,18 @@ WINE_DEFAULT_DEBUG_CHANNEL(dc);
 extern WORD CALLBACK GDI_CallTo16_word_wwll(FARPROC16,WORD,WORD,LONG,LONG);
 /* ### stop build ### */
 
+static BOOL DC_DeleteObject( HGDIOBJ handle, void *obj );
+
+static const struct gdi_obj_funcs dc_funcs =
+{
+    NULL,             /* pSelectObject */
+    NULL,             /* pGetObject16 */
+    NULL,             /* pGetObjectA */
+    NULL,             /* pGetObjectW */
+    NULL,             /* pUnrealizeObject */
+    DC_DeleteObject   /* pDeleteObject */
+};
+
 /***********************************************************************
  *           DC_AllocDC
  */
@@ -45,7 +57,7 @@ DC *DC_AllocDC( const DC_FUNCTIONS *funcs )
     HDC hdc;
     DC *dc;
 
-    if (!(dc = GDI_AllocObject( sizeof(*dc), DC_MAGIC, &hdc ))) return NULL;
+    if (!(dc = GDI_AllocObject( sizeof(*dc), DC_MAGIC, &hdc, &dc_funcs ))) return NULL;
 
     dc->hSelf               = hdc;
     dc->funcs               = funcs;
@@ -162,6 +174,17 @@ DC *DC_GetDCUpdate( HDC hdc )
     return dc;
 }
 
+
+/***********************************************************************
+ *           DC_DeleteObject
+ */
+static BOOL DC_DeleteObject( HGDIOBJ handle, void *obj )
+{
+    GDI_ReleaseObj( handle );
+    return DeleteDC( handle );
+}
+
+
 /***********************************************************************
  *           DC_InitDC
  *
@@ -254,7 +277,7 @@ HDC16 WINAPI GetDCState16( HDC16 hdc )
     HGDIOBJ handle;
     
     if (!(dc = DC_GetDCPtr( hdc ))) return 0;
-    if (!(newdc = GDI_AllocObject( sizeof(DC), DC_MAGIC, &handle )))
+    if (!(newdc = GDI_AllocObject( sizeof(DC), DC_MAGIC, &handle, &dc_funcs )))
     {
       GDI_ReleaseObj( hdc );
       return 0;
@@ -347,7 +370,7 @@ void WINAPI SetDCState16( HDC16 hdc, HDC16 hdcs )
     DC *dc, *dcs;
 
     if (!(dc = DC_GetDCUpdate( hdc ))) return;
-    if (!(dcs = GDI_GetObjPtr( hdcs, DC_MAGIC )))
+    if (!(dcs = DC_GetDCPtr( hdcs )))
     {
       GDI_ReleaseObj( hdc );
       return;
@@ -461,7 +484,7 @@ INT WINAPI SaveDC( HDC hdc )
       GDI_ReleaseObj( hdc );
       return 0;
     }
-    dcs = GDI_GetObjPtr( hdcs, DC_MAGIC );
+    dcs = DC_GetDCPtr( hdcs );
 
     /* Copy path. The reason why path saving / restoring is in SaveDC/
      * RestoreDC and not in GetDCState/SetDCState is that the ...DCState
@@ -531,7 +554,7 @@ BOOL WINAPI RestoreDC( HDC hdc, INT level )
     while (dc->saveLevel >= level)
     {
 	HDC16 hdcs = dc->header.hNext;
-	if (!(dcs = GDI_GetObjPtr( hdcs, DC_MAGIC )))
+	if (!(dcs = DC_GetDCPtr( hdcs )))
 	{
 	  GDI_ReleaseObj( hdc );
 	  return FALSE;
@@ -779,7 +802,7 @@ BOOL WINAPI DeleteDC( HDC hdc )
     {
 	DC * dcs;
 	HDC16 hdcs = dc->header.hNext;
-	if (!(dcs = GDI_GetObjPtr( hdcs, DC_MAGIC ))) break;
+	if (!(dcs = DC_GetDCPtr( hdcs ))) break;
 	dc->header.hNext = dcs->header.hNext;
 	dc->saveLevel--;
         if (dcs->hClipRgn) DeleteObject( dcs->hClipRgn );
diff --git a/objects/dib.c b/objects/dib.c
index 39c5c59caf97aee11bce8972d8c501f8caf3cba5..e4962efb526bf1b46140b1ffdc3fe636508d1d15 100644
--- a/objects/dib.c
+++ b/objects/dib.c
@@ -264,15 +264,29 @@ INT WINAPI SetDIBits( HDC hdc, HBITMAP hbitmap, UINT startscan,
 		      UINT coloruse )
 {
     DC *dc;
+    BITMAPOBJ *bitmap;
     INT result = 0;
 
-    /* Check parameters */
-    if (!(dc = DC_GetDCUpdate( hdc ))) return 0;
+    if (!(bitmap = GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return 0;
+
+    if (!(dc = DC_GetDCUpdate( hdc )))
+    {
+        if (coloruse == DIB_RGB_COLORS) FIXME( "shouldn't require a DC for DIB_RGB_COLORS\n" );
+        GDI_ReleaseObj( hbitmap );
+        return 0;
+    }
 
-    if (dc->funcs->pSetDIBits)
-        result = dc->funcs->pSetDIBits(dc->physDev, hbitmap, startscan, lines, bits, info, coloruse);
+    if (!bitmap->funcs && !BITMAP_SetOwnerDC( hbitmap, dc )) goto done;
 
+    if (bitmap->funcs && bitmap->funcs->pSetDIBits)
+        result = bitmap->funcs->pSetDIBits( dc->physDev, hbitmap, startscan, lines,
+                                            bits, info, coloruse );
+    else
+        result = lines;
+
+ done:
     GDI_ReleaseObj( hdc );
+    GDI_ReleaseObj( hbitmap );
     return result;
 }
 
@@ -721,14 +735,18 @@ INT WINAPI GetDIBits(
             }
         }
         /* Otherwise, get bits from the XImage */
-        else if (!dc->funcs->pGetDIBits ||
-                 !dc->funcs->pGetDIBits(dc->physDev, hbitmap, startscan, lines, bits, info, coloruse))
+        else
         {
-	    GDI_ReleaseObj( hdc );
-	    GDI_ReleaseObj( hbitmap );
-
-	    return 0;
-	}
+            if (!bmp->funcs && !BITMAP_SetOwnerDC( hbitmap, dc )) lines = 0;
+            else
+            {
+                if (bmp->funcs && bmp->funcs->pGetDIBits)
+                    lines = bmp->funcs->pGetDIBits( dc->physDev, hbitmap, startscan,
+                                                    lines, bits, info, coloruse );
+                else
+                    lines = 0;  /* FIXME: should copy from bmp->bitmap.bmBits */
+            }
+        }
     }
     else if( info->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) ) 
     {
@@ -790,6 +808,7 @@ HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header,
     int height;
     WORD bpp;
     WORD compr;
+    DC *dc;
 
     if (DIB_GetBitmapInfo( header, &width, &height, &bpp, &compr ) == -1) return 0;
     if (height < 0) height = -height;
@@ -862,15 +881,24 @@ HBITMAP WINAPI CreateDIBitmap( HDC hdc, const BITMAPINFOHEADER *header,
 
     /* Now create the bitmap */
 
+    if (!(dc = DC_GetDCPtr( hdc ))) return 0;
+
     if (fColor)
         handle = CreateBitmap( width, height, GetDeviceCaps( hdc, PLANES ),
                                GetDeviceCaps( hdc, BITSPIXEL ), NULL );
     else handle = CreateBitmap( width, height, 1, 1, NULL );
 
-    if (!handle) return 0;
+    if (handle)
+    {
+        if (init == CBM_INIT) SetDIBits( hdc, handle, 0, height, bits, data, coloruse );
+        else if (!BITMAP_SetOwnerDC( handle, dc ))
+        {
+            DeleteObject( handle );
+            handle = 0;
+        }
+    }
 
-    if (init == CBM_INIT)
-        SetDIBits( hdc, handle, 0, height, bits, data, coloruse );
+    GDI_ReleaseObj( hdc );
     return handle;
 }
 
diff --git a/objects/enhmetafile.c b/objects/enhmetafile.c
index 5cc7cce2c1adb96423baa21d29b6631fce602ba3..065d1f1e9e11ce7c5266bb8fb5923fa0233c600d 100644
--- a/objects/enhmetafile.c
+++ b/objects/enhmetafile.c
@@ -60,7 +60,7 @@ HENHMETAFILE EMF_Create_HENHMETAFILE(ENHMETAHEADER *emh, BOOL on_disk )
 {
     HENHMETAFILE hmf = 0;
     ENHMETAFILEOBJ *metaObj = GDI_AllocObject( sizeof(ENHMETAFILEOBJ),
-                                               ENHMETAFILE_MAGIC, &hmf );
+                                               ENHMETAFILE_MAGIC, &hmf, NULL );
     if (metaObj)
     {
         metaObj->emh = emh;
diff --git a/objects/font.c b/objects/font.c
index e250bc4084b812d11ab5c02c101d8603d1bc05eb..e26bdaae0eb7924cda80840609017ef090215375 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -32,6 +32,22 @@
 WINE_DEFAULT_DEBUG_CHANNEL(font);
 WINE_DECLARE_DEBUG_CHANNEL(gdi);
 
+static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc );
+static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
+static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
+static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
+static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj );
+
+static const struct gdi_obj_funcs font_funcs =
+{
+    FONT_SelectObject,  /* pSelectObject */
+    FONT_GetObject16,   /* pGetObject16 */
+    FONT_GetObjectA,    /* pGetObjectA */
+    FONT_GetObjectW,    /* pGetObjectW */
+    NULL,               /* pUnrealizeObject */
+    FONT_DeleteObject   /* pDeleteObject */
+};
+
 #define ENUM_UNICODE	0x00000001
 #define ENUM_CALLED     0x00000002
 
@@ -472,7 +488,7 @@ HFONT WINAPI CreateFontIndirectW( const LOGFONTW *plf )
     if (plf)
     {
         FONTOBJ* fontPtr;
-	if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC, &hFont )))
+	if ((fontPtr = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC, &hFont, &font_funcs )))
 	{
 	    memcpy( &fontPtr->logfont, plf, sizeof(LOGFONTW) );
 
@@ -600,11 +616,52 @@ HFONT WINAPI CreateFontW( INT height, INT width, INT esc,
 }
 
 
+/***********************************************************************
+ *           FONT_SelectObject
+ *
+ * If the driver supports vector fonts we create a gdi font first and
+ * then call the driver to give it a chance to supply its own device
+ * font.  If the driver wants to do this it returns TRUE and we can
+ * delete the gdi font, if the driver wants to use the gdi font it
+ * should return FALSE, to signal an error return GDI_ERROR.  For
+ * drivers that don't support vector fonts they must supply their own
+ * font.
+ */
+static HGDIOBJ FONT_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
+{
+    HGDIOBJ ret = 0;
+    DC *dc = DC_GetDCPtr( hdc );
+
+    if (!dc) return 0;
+
+    if (dc->hFont != handle || dc->gdiFont == NULL)
+    {
+        if(GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_VA_ABLE)
+            dc->gdiFont = WineEngCreateFontInstance(dc, handle);
+    }
+
+    if (dc->funcs->pSelectFont) ret = dc->funcs->pSelectFont( dc->physDev, handle );
+
+    if (ret && dc->gdiFont) dc->gdiFont = 0;
+
+    if (ret == GDI_ERROR)
+        ret = 0; /* SelectObject returns 0 on error */
+    else
+    {
+        ret = dc->hFont;
+        dc->hFont = handle;
+    }
+    GDI_ReleaseObj( hdc );
+    return ret;
+}
+
+
 /***********************************************************************
  *           FONT_GetObject16
  */
-INT16 FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer )
+static INT FONT_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
 {
+    FONTOBJ *font = obj;
     LOGFONT16 lf16;
 
     FONT_LogFontWTo16( &font->logfont, &lf16 );
@@ -617,8 +674,9 @@ INT16 FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer )
 /***********************************************************************
  *           FONT_GetObjectA
  */
-INT FONT_GetObjectA( FONTOBJ *font, INT count, LPSTR buffer )
+static INT FONT_GetObjectA( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
 {
+    FONTOBJ *font = obj;
     LOGFONTA lfA;
 
     FONT_LogFontWToA( &font->logfont, &lfA );
@@ -627,17 +685,29 @@ INT FONT_GetObjectA( FONTOBJ *font, INT count, LPSTR buffer )
     memcpy( buffer, &lfA, count );
     return count;
 }
+
 /***********************************************************************
  *           FONT_GetObjectW
  */
-INT FONT_GetObjectW( FONTOBJ *font, INT count, LPSTR buffer )
+static INT FONT_GetObjectW( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
 {
+    FONTOBJ *font = obj;
     if (count > sizeof(LOGFONTW)) count = sizeof(LOGFONTW);
     memcpy( buffer, &font->logfont, count );
     return count;
 }
 
 
+/***********************************************************************
+ *           FONT_DeleteObject
+ */
+static BOOL FONT_DeleteObject( HGDIOBJ handle, void *obj )
+{
+    WineEngDestroyFontInstance( handle );
+    return GDI_FreeObject( handle, obj );
+}
+
+
 /***********************************************************************
  *              FONT_EnumInstance16
  *
diff --git a/objects/gdiobj.c b/objects/gdiobj.c
index dbdb9452356f97991554c6c4f687901fce5c074d..45fcf9e0ebd08cefb22f551e0663ec8bc06fa368 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -31,12 +31,9 @@
 #include "wine/winbase16.h"
 
 #include "bitmap.h"
-#include "brush.h"
 #include "font.h"
 #include "local.h"
 #include "palette.h"
-#include "pen.h"
-#include "region.h"
 #include "wine/debug.h"
 #include "gdi.h"
 
@@ -59,8 +56,8 @@ static const LOGBRUSH LtGrayBrush = { BS_SOLID, RGB(192,192,192), 0 };
 static const LOGBRUSH GrayBrush   = { BS_SOLID, RGB(128,128,128), 0 };
 
 /* This is BS_HATCHED, for 1 bitperpixel. This makes the spray work in pbrush */
-/* NB_HATCH_STYLES is an index into HatchBrushes */
-static const LOGBRUSH DkGrayBrush = { BS_HATCHED, RGB(0,0,0), NB_HATCH_STYLES };
+/* See HatchBrushes in x11drv for the HS_DIAGCROSS+1 hack */
+static const LOGBRUSH DkGrayBrush = { BS_HATCHED, RGB(0,0,0), (HS_DIAGCROSS+1) };
 
 static const LOGPEN WhitePen = { PS_SOLID, { 0, 0 }, RGB(255,255,255) };
 static const LOGPEN BlackPen = { PS_SOLID, { 0, 0 }, RGB(0,0,0) };
@@ -676,7 +673,7 @@ inline static GDIOBJHDR *alloc_large_heap( WORD size, HGDIOBJ *handle )
 /***********************************************************************
  *           GDI_AllocObject
  */
-void *GDI_AllocObject( WORD size, WORD magic, HGDIOBJ *handle )
+void *GDI_AllocObject( WORD size, WORD magic, HGDIOBJ *handle, const struct gdi_obj_funcs *funcs )
 {
     GDIOBJHDR *obj;
 
@@ -704,6 +701,7 @@ void *GDI_AllocObject( WORD size, WORD magic, HGDIOBJ *handle )
     obj->hNext   = 0;
     obj->wMagic  = magic|OBJECT_NOSYSTEM;
     obj->dwCount = 0;
+    obj->funcs   = funcs;
 
     TRACE_SEC( *handle, "enter" );
     return obj;
@@ -746,6 +744,7 @@ BOOL GDI_FreeObject( HGDIOBJ handle, void *ptr )
     GDIOBJHDR *object = ptr;
 
     object->wMagic = 0;  /* Mark it as invalid */
+    object->funcs  = NULL;
     if (handle & 2)  /* GDI heap handle */
     {
         LOCAL_Unlock( GDI_HeapSel, handle );
@@ -837,17 +836,6 @@ void GDI_CheckNotLock(void)
 }
 
 
-/***********************************************************************
- *           FONT_DeleteObject
- *
- */
-static BOOL FONT_DeleteObject(HGDIOBJ hfont, FONTOBJ *fontobj)
-{
-    WineEngDestroyFontInstance( hfont );
-    return GDI_FreeObject( hfont, fontobj );
-}
-
-
 /***********************************************************************
  *           DeleteObject    (GDI.69)
  *           SysDeleteObject (GDI.605)
@@ -890,23 +878,11 @@ BOOL WINAPI DeleteObject( HGDIOBJ obj )
 
       /* Delete object */
 
-    switch(GDIMAGIC(header->wMagic))
-    {
-      case PEN_MAGIC:     return GDI_FreeObject( obj, header );
-      case BRUSH_MAGIC:   return BRUSH_DeleteObject( obj, (BRUSHOBJ*)header );
-      case FONT_MAGIC:    return FONT_DeleteObject( obj, (FONTOBJ*)header );
-      case PALETTE_MAGIC: return PALETTE_DeleteObject(obj,(PALETTEOBJ*)header);
-      case BITMAP_MAGIC:  return BITMAP_DeleteObject( obj, (BITMAPOBJ*)header);
-      case REGION_MAGIC:  return REGION_DeleteObject( obj, (struct _RGNOBJ*)header );
-      case DC_MAGIC:
-          GDI_ReleaseObj( obj );
-          return DeleteDC(obj);
-      case 0 :
-        WARN("Already deleted\n");
-        break;
-      default:
-        WARN("Unknown magic number (%04x)\n",GDIMAGIC(header->wMagic));
-    }
+    if (header->funcs &&
+        header->funcs->pDeleteObject &&
+        header->funcs->pDeleteObject( obj, header ))
+        return TRUE;
+
     GDI_ReleaseObj( obj );
     return FALSE;
 }
@@ -944,25 +920,12 @@ INT16 WINAPI GetObject16( HANDLE16 handle, INT16 count, LPVOID buffer )
     if (!count) return 0;
 
     if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0;
-    
-    switch(GDIMAGIC(ptr->wMagic))
-      {
-      case PEN_MAGIC:
-	result = PEN_GetObject16( (PENOBJ *)ptr, count, buffer );
-	break;
-      case BRUSH_MAGIC: 
-	result = BRUSH_GetObject16( (BRUSHOBJ *)ptr, count, buffer );
-	break;
-      case BITMAP_MAGIC: 
-	result = BITMAP_GetObject16( (BITMAPOBJ *)ptr, count, buffer );
-	break;
-      case FONT_MAGIC:
-	result = FONT_GetObject16( (FONTOBJ *)ptr, count, buffer );
-	break;
-      case PALETTE_MAGIC:
-	result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
-	break;
-      }
+
+    if (ptr->funcs && ptr->funcs->pGetObject16)
+        result = ptr->funcs->pGetObject16( handle, ptr, count, buffer );
+    else
+        SetLastError( ERROR_INVALID_HANDLE );
+
     GDI_ReleaseObj( handle );
     return result;
 }
@@ -980,39 +943,11 @@ INT WINAPI GetObjectA( HANDLE handle, INT count, LPVOID buffer )
 
     if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0;
 
-    switch(GDIMAGIC(ptr->wMagic))
-    {
-      case PEN_MAGIC:
-	  result = PEN_GetObject( (PENOBJ *)ptr, count, buffer );
-	  break;
-      case BRUSH_MAGIC: 
-	  result = BRUSH_GetObject( (BRUSHOBJ *)ptr, count, buffer );
-	  break;
-      case BITMAP_MAGIC: 
-	  result = BITMAP_GetObject( (BITMAPOBJ *)ptr, count, buffer );
-	  break;
-      case FONT_MAGIC:
-	  result = FONT_GetObjectA( (FONTOBJ *)ptr, count, buffer );
-	  break;
-      case PALETTE_MAGIC:
-	  result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
-	  break;
-
-      case REGION_MAGIC:
-      case DC_MAGIC:
-      case DISABLED_DC_MAGIC:
-      case META_DC_MAGIC:
-      case METAFILE_MAGIC:
-      case METAFILE_DC_MAGIC:
-      case ENHMETAFILE_MAGIC:
-      case ENHMETAFILE_DC_MAGIC:
-          FIXME("Magic %04x not implemented\n", GDIMAGIC(ptr->wMagic) );
-          break;
+    if (ptr->funcs && ptr->funcs->pGetObjectA)
+        result = ptr->funcs->pGetObjectA( handle, ptr, count, buffer );
+    else
+        SetLastError( ERROR_INVALID_HANDLE );
 
-      default:
-          ERR("Invalid GDI Magic %04x\n", GDIMAGIC(ptr->wMagic));
-          break;
-    }
     GDI_ReleaseObj( handle );
     return result;
 }
@@ -1029,27 +964,11 @@ INT WINAPI GetObjectW( HANDLE handle, INT count, LPVOID buffer )
 
     if (!(ptr = GDI_GetObjPtr( handle, MAGIC_DONTCARE ))) return 0;
 
-    switch(GDIMAGIC(ptr->wMagic))
-    {
-      case PEN_MAGIC:
-	  result = PEN_GetObject( (PENOBJ *)ptr, count, buffer );
-	  break;
-      case BRUSH_MAGIC: 
-	  result = BRUSH_GetObject( (BRUSHOBJ *)ptr, count, buffer );
-	  break;
-      case BITMAP_MAGIC: 
-	  result = BITMAP_GetObject( (BITMAPOBJ *)ptr, count, buffer );
-	  break;
-      case FONT_MAGIC:
-	  result = FONT_GetObjectW( (FONTOBJ *)ptr, count, buffer );
-	  break;
-      case PALETTE_MAGIC:
-	  result = PALETTE_GetObject( (PALETTEOBJ *)ptr, count, buffer );
-	  break;
-      default:
-          FIXME("Magic %04x not implemented\n", GDIMAGIC(ptr->wMagic) );
-          break;
-    }
+    if (ptr->funcs && ptr->funcs->pGetObjectW)
+        result = ptr->funcs->pGetObjectW( handle, ptr, count, buffer );
+    else
+        SetLastError( ERROR_INVALID_HANDLE );
+
     GDI_ReleaseObj( handle );
     return result;
 }
@@ -1136,86 +1055,6 @@ HANDLE WINAPI GetCurrentObject(HDC hdc,UINT type)
     }
     return ret;
 }
-/***********************************************************************
- *           FONT_SelectObject
- *
- * If the driver supports vector fonts we create a gdi font first and
- * then call the driver to give it a chance to supply its own device
- * font.  If the driver wants to do this it returns TRUE and we can
- * delete the gdi font, if the driver wants to use the gdi font it
- * should return FALSE, to signal an error return GDI_ERROR.  For
- * drivers that don't support vector fonts they must supply their own
- * font.
- */
-static HGDIOBJ FONT_SelectObject(DC *dc, HGDIOBJ hFont)
-{
-    HGDIOBJ ret = FALSE;
-
-    if(dc->hFont != hFont || dc->gdiFont == NULL) {
-	if(GetDeviceCaps(dc->hSelf, TEXTCAPS) & TC_VA_ABLE)
-	    dc->gdiFont = WineEngCreateFontInstance(dc, hFont);
-    }
-
-    if(dc->funcs->pSelectFont)
-        ret = dc->funcs->pSelectFont(dc->physDev, hFont);
-
-    if(ret && dc->gdiFont) {
-	dc->gdiFont = 0;
-    }
-
-    if(ret == GDI_ERROR)
-        ret = FALSE; /* SelectObject returns FALSE on error */
-    else {
-        ret = dc->hFont;
-	dc->hFont = hFont;
-    }
-
-    return ret;
-}
-
-
-/***********************************************************************
- *           select_bitmap
- */
-static HGDIOBJ select_bitmap( DC *dc, HBITMAP handle )
-{
-    BITMAPOBJ *bitmap;
-    HGDIOBJ ret = handle;
-
-    if (!(dc->flags & DC_MEMORY)) return 0;
-    if (handle == dc->hBitmap) return handle;  /* nothing to do */
-    if (!(bitmap = GDI_GetObjPtr( handle, BITMAP_MAGIC ))) return 0;
-
-    if (bitmap->header.dwCount && (handle != GetStockObject(DEFAULT_BITMAP)))
-    {
-        WARN( "Bitmap already selected in another DC\n" );
-        GDI_ReleaseObj( handle );
-        return 0;
-    }
-
-    if (dc->funcs->pSelectBitmap) ret = dc->funcs->pSelectBitmap( dc->physDev, handle );
-
-    if (ret)
-    {
-        dc->hBitmap            = ret;
-        dc->totalExtent.left   = 0;
-        dc->totalExtent.top    = 0;
-        dc->totalExtent.right  = bitmap->bitmap.bmWidth;
-        dc->totalExtent.bottom = bitmap->bitmap.bmHeight;
-        dc->flags &= ~DC_DIRTY;
-        SetRectRgn( dc->hVisRgn, 0, 0, bitmap->bitmap.bmWidth, bitmap->bitmap.bmHeight);
-        CLIPPING_UpdateGCRegion( dc );
-
-        if (dc->bitsPerPixel != bitmap->bitmap.bmBitsPixel)
-        {
-            /* depth changed, reinitialize the DC */
-            dc->bitsPerPixel = bitmap->bitmap.bmBitsPixel;
-            DC_InitDC( dc );
-        }
-    }
-    GDI_ReleaseObj( handle );
-    return ret;
-}
 
 
 /***********************************************************************
@@ -1233,45 +1072,21 @@ HGDIOBJ16 WINAPI SelectObject16( HDC16 hdc, HGDIOBJ16 handle )
 HGDIOBJ WINAPI SelectObject( HDC hdc, HGDIOBJ handle )
 {
     HGDIOBJ ret = 0;
-    DC * dc = DC_GetDCPtr( hdc );
-    if (!dc) return 0;
-    TRACE("hdc=%04x %04x\n", hdc, handle );
+    GDIOBJHDR *header = GDI_GetObjPtr( handle, MAGIC_DONTCARE );
+    if (!header) return 0;
 
-    /* Fonts get a rather different treatment so we'll handle them
-       separately */
-    switch(GetObjectType( handle ))
-    {
-    case OBJ_BITMAP:
-        ret = dc->hBitmap;
-        handle = select_bitmap( dc, handle );
-        if (!handle) 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);
-        break;
-    case OBJ_REGION:
-        GDI_ReleaseObj( hdc );
-        return (HGDIOBJ)SelectClipRgn( hdc, handle );
-    }
-    GDI_ReleaseObj( hdc );
+    TRACE("hdc=%04x %04x\n", hdc, handle );
 
-    if (ret && ret != handle)
+    if (header->funcs && header->funcs->pSelectObject)
     {
-        inc_ref_count( handle );
-        dec_ref_count( ret );
+        ret = header->funcs->pSelectObject( handle, header, hdc );
+        if (ret && ret != handle && (INT)ret > COMPLEXREGION)
+        {
+            inc_ref_count( handle );
+            dec_ref_count( ret );
+        }
     }
+    GDI_ReleaseObj( handle );
     return ret;
 }
 
@@ -1300,16 +1115,9 @@ BOOL WINAPI UnrealizeObject( HGDIOBJ obj )
 
       /* Unrealize object */
 
-    switch(GDIMAGIC(header->wMagic))
-    {
-    case PALETTE_MAGIC: 
-        result = PALETTE_UnrealizeObject( obj, (PALETTEOBJ *)header );
-	break;
+    if (header->funcs && header->funcs->pUnrealizeObject)
+        result = header->funcs->pUnrealizeObject( obj, header );
 
-    case BRUSH_MAGIC:
-        /* Windows resets the brush origin. We don't need to. */
-        break;
-    }
     GDI_ReleaseObj( obj );
     return result;
 }
diff --git a/objects/metafile.c b/objects/metafile.c
index 0a4b877c27c938369498c986200c1fc1f9c06480..2953e982e99b8bb0aa0808a69440e865d8b958f5 100644
--- a/objects/metafile.c
+++ b/objects/metafile.c
@@ -105,7 +105,7 @@ static int MF_AddHandle(HANDLETABLE16 *ht, WORD htlen, HGDIOBJ16 hobj)
 HMETAFILE MF_Create_HMETAFILE(METAHEADER *mh)
 {
     HMETAFILE hmf = 0;
-    METAFILEOBJ *metaObj = GDI_AllocObject( sizeof(METAFILEOBJ), METAFILE_MAGIC, &hmf );
+    METAFILEOBJ *metaObj = GDI_AllocObject( sizeof(METAFILEOBJ), METAFILE_MAGIC, &hmf, NULL );
     if (metaObj)
     {
     metaObj->mh = mh;
diff --git a/objects/palette.c b/objects/palette.c
index 32dac056fdf4ad5a25ec31d59034bbde013f9ef0..e577f5766d512afdba2ce6e20faa963695d5c3e3 100644
--- a/objects/palette.c
+++ b/objects/palette.c
@@ -38,6 +38,20 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(palette);
 
+static INT PALETTE_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
+static BOOL PALETTE_UnrealizeObject( HGDIOBJ handle, void *obj );
+static BOOL PALETTE_DeleteObject( HGDIOBJ handle, void *obj );
+
+static const struct gdi_obj_funcs palette_funcs =
+{
+    NULL,                     /* pSelectObject */
+    PALETTE_GetObject,        /* pGetObject16 */
+    PALETTE_GetObject,        /* pGetObjectA */
+    PALETTE_GetObject,        /* pGetObjectW */
+    PALETTE_UnrealizeObject,  /* pUnrealizeObject */
+    PALETTE_DeleteObject      /* pDeleteObject */
+};
+
 PALETTE_DRIVER *PALETTE_Driver = NULL;
 
 /* Pointers to USER implementation of SelectPalette/RealizePalette */
@@ -47,8 +61,8 @@ FARPROC pfnRealizePalette = NULL;
 
 static UINT SystemPaletteUse = SYSPAL_STATIC;  /* currently not considered */
 
-static HPALETTE16 hPrimaryPalette = 0; /* used for WM_PALETTECHANGED */
-static HPALETTE16 hLastRealizedPalette = 0; /* UnrealizeObject() needs it */
+static HPALETTE hPrimaryPalette = 0; /* used for WM_PALETTECHANGED */
+static HPALETTE hLastRealizedPalette = 0; /* UnrealizeObject() needs it */
 
 
 /***********************************************************************
@@ -132,7 +146,7 @@ HPALETTE WINAPI CreatePalette(
     size = sizeof(LOGPALETTE) + (palette->palNumEntries - 1) * sizeof(PALETTEENTRY);
 
     if (!(palettePtr = GDI_AllocObject( size + sizeof(int*) +sizeof(GDIOBJHDR),
-                                        PALETTE_MAGIC, &hpalette ))) return 0;
+                                        PALETTE_MAGIC, &hpalette, &palette_funcs ))) return 0;
     memcpy( &palettePtr->logpalette, palette, size );
     PALETTE_ValidateFlags(palettePtr->logpalette.palPalEntry, 
 			  palettePtr->logpalette.palNumEntries);
@@ -658,8 +672,10 @@ COLORREF WINAPI GetNearestColor(
 /***********************************************************************
  *           PALETTE_GetObject
  */
-int PALETTE_GetObject( PALETTEOBJ * palette, int count, LPSTR buffer )
+static INT PALETTE_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
 {
+    PALETTEOBJ *palette = obj;
+
     if (count > sizeof(WORD)) count = sizeof(WORD);
     memcpy( buffer, &palette->logpalette.palNumEntries, count );
     return count;
@@ -669,14 +685,16 @@ int PALETTE_GetObject( PALETTEOBJ * palette, int count, LPSTR buffer )
 /***********************************************************************
  *           PALETTE_UnrealizeObject
  */
-BOOL PALETTE_UnrealizeObject( HPALETTE16 hpalette, PALETTEOBJ *palette )
+static BOOL PALETTE_UnrealizeObject( HGDIOBJ handle, void *obj )
 {
+    PALETTEOBJ *palette = obj;
+
     if (palette->mapping)
     {
         HeapFree( GetProcessHeap(), 0, palette->mapping );
         palette->mapping = NULL;
     }
-    if (hLastRealizedPalette == hpalette) hLastRealizedPalette = 0;
+    if (hLastRealizedPalette == handle) hLastRealizedPalette = 0;
     return TRUE;
 }
 
@@ -684,11 +702,13 @@ BOOL PALETTE_UnrealizeObject( HPALETTE16 hpalette, PALETTEOBJ *palette )
 /***********************************************************************
  *           PALETTE_DeleteObject
  */
-BOOL PALETTE_DeleteObject( HPALETTE16 hpalette, PALETTEOBJ *palette )
+static BOOL PALETTE_DeleteObject( HGDIOBJ handle, void *obj )
 {
+    PALETTEOBJ *palette = obj;
+
     HeapFree( GetProcessHeap(), 0, palette->mapping );
-    if (hLastRealizedPalette == hpalette) hLastRealizedPalette = 0;
-    return GDI_FreeObject( hpalette, palette );
+    if (hLastRealizedPalette == handle) hLastRealizedPalette = 0;
+    return GDI_FreeObject( handle, obj );
 }
 
 
diff --git a/objects/pen.c b/objects/pen.c
index fe5be3ce5d7cfd8896aebe5f5f326f8f5fdca54f..9e73a133c870fcc187547f563bde3a4b46d0ecc5 100644
--- a/objects/pen.c
+++ b/objects/pen.c
@@ -24,15 +24,33 @@
 
 #include "windef.h"
 #include "wingdi.h"
-
 #include "wine/wingdi16.h"
-#include "pen.h"
-
+#include "gdi.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(gdi);
 
+  /* GDI logical pen object */
+typedef struct
+{
+    GDIOBJHDR   header;
+    LOGPEN    logpen;
+} PENOBJ;
+
 
+static HGDIOBJ PEN_SelectObject( HGDIOBJ handle, void *obj, HDC hdc );
+static INT PEN_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
+static INT PEN_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer );
+
+static const struct gdi_obj_funcs pen_funcs =
+{
+    PEN_SelectObject,  /* pSelectObject */
+    PEN_GetObject16,   /* pGetObject16 */
+    PEN_GetObject,     /* pGetObjectA */
+    PEN_GetObject,     /* pGetObjectW */
+    NULL,              /* pUnrealizeObject */
+    GDI_FreeObject     /* pDeleteObject */
+};
 
 /***********************************************************************
  *           CreatePen    (GDI.61)
@@ -79,7 +97,7 @@ HPEN16 WINAPI CreatePenIndirect16( const LOGPEN16 * pen )
     HPEN hpen;
 
     if (pen->lopnStyle > PS_INSIDEFRAME) return 0;
-    if (!(penPtr = GDI_AllocObject( sizeof(PENOBJ), PEN_MAGIC, &hpen ))) return 0;
+    if (!(penPtr = GDI_AllocObject( sizeof(PENOBJ), PEN_MAGIC, &hpen, &pen_funcs ))) return 0;
     penPtr->logpen.lopnStyle = pen->lopnStyle;
     penPtr->logpen.lopnColor = pen->lopnColor;
     CONV_POINT16TO32( &pen->lopnWidth, &penPtr->logpen.lopnWidth );
@@ -96,7 +114,7 @@ HPEN WINAPI CreatePenIndirect( const LOGPEN * pen )
     PENOBJ * penPtr;
     HPEN hpen;
 
-    if (!(penPtr = GDI_AllocObject( sizeof(PENOBJ), PEN_MAGIC, &hpen ))) return 0;
+    if (!(penPtr = GDI_AllocObject( sizeof(PENOBJ), PEN_MAGIC, &hpen, &pen_funcs ))) return 0;
     penPtr->logpen.lopnStyle = pen->lopnStyle;
     penPtr->logpen.lopnWidth = pen->lopnWidth;
     penPtr->logpen.lopnColor = pen->lopnColor;
@@ -123,7 +141,7 @@ HPEN WINAPI ExtCreatePen( DWORD style, DWORD width,
 	if (brush->lbHatch)
 	    FIXME("Hatches not implemented\n");
 
-    if (!(penPtr = GDI_AllocObject( sizeof(PENOBJ), PEN_MAGIC, &hpen ))) return 0;
+    if (!(penPtr = GDI_AllocObject( sizeof(PENOBJ), PEN_MAGIC, &hpen, &pen_funcs ))) return 0;
     penPtr->logpen.lopnStyle = style & ~PS_TYPE_MASK; 
     
     /* PS_USERSTYLE workaround */   
@@ -139,12 +157,33 @@ HPEN WINAPI ExtCreatePen( DWORD style, DWORD width,
     return hpen;
 }
 
+
+/***********************************************************************
+ *           PEN_SelectObject
+ */
+static HGDIOBJ PEN_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
+{
+    HGDIOBJ ret;
+    DC *dc = DC_GetDCPtr( hdc );
+
+    if (!dc) return 0;
+    ret = dc->hPen;
+    if (dc->funcs->pSelectPen) handle = dc->funcs->pSelectPen( dc->physDev, handle );
+    if (handle) dc->hPen = handle;
+    else ret = 0;
+    GDI_ReleaseObj( hdc );
+    return ret;
+}
+
+
 /***********************************************************************
  *           PEN_GetObject16
  */
-INT16 PEN_GetObject16( PENOBJ * pen, INT16 count, LPSTR buffer )
+static INT PEN_GetObject16( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
 {
+    PENOBJ *pen = obj;
     LOGPEN16 logpen;
+
     logpen.lopnStyle = pen->logpen.lopnStyle;
     logpen.lopnColor = pen->logpen.lopnColor;
     CONV_POINT32TO16( &pen->logpen.lopnWidth, &logpen.lopnWidth );
@@ -157,10 +196,11 @@ INT16 PEN_GetObject16( PENOBJ * pen, INT16 count, LPSTR buffer )
 /***********************************************************************
  *           PEN_GetObject
  */
-INT PEN_GetObject( PENOBJ * pen, INT count, LPSTR buffer )
+static INT PEN_GetObject( HGDIOBJ handle, void *obj, INT count, LPVOID buffer )
 {
+    PENOBJ *pen = obj;
+
     if (count > sizeof(pen->logpen)) count = sizeof(pen->logpen);
     memcpy( buffer, &pen->logpen, count );
     return count;
 }
-
diff --git a/objects/region.c b/objects/region.c
index 102ddd88f61a8130a8c11f0a07d0b0c683a59bdb..ea220e11035ba266dbd847cdd31af4e4162cfe02 100644
--- a/objects/region.c
+++ b/objects/region.c
@@ -98,9 +98,8 @@ SOFTWARE.
 #include <string.h>
 #include "windef.h"
 #include "wingdi.h"
-#include "wine/debug.h"
-#include "region.h"
 #include "gdi.h"
+#include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(region);
 
@@ -112,13 +111,26 @@ typedef struct {
 } WINEREGION;
 
   /* GDI logical region object */
-typedef struct _RGNOBJ
+typedef struct
 {
     GDIOBJHDR   header;
     WINEREGION  *rgn;
 } RGNOBJ;
 
 
+static HGDIOBJ REGION_SelectObject( HGDIOBJ handle, void *obj, HDC hdc );
+static BOOL REGION_DeleteObject( HGDIOBJ handle, void *obj );
+
+static const struct gdi_obj_funcs region_funcs =
+{
+    REGION_SelectObject,  /* pSelectObject */
+    NULL,                 /* pGetObject16 */
+    NULL,                 /* pGetObjectA */
+    NULL,                 /* pGetObjectW */
+    NULL,                 /* pUnrealizeObject */
+    REGION_DeleteObject   /* pDeleteObject */
+};
+
 /*  1 if two RECTs overlap.
  *  0 if two RECTs do not overlap.
  */
@@ -501,7 +513,7 @@ static HRGN REGION_CreateRegion( INT n )
     HRGN hrgn;
     RGNOBJ *obj;
 
-    if(!(obj = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC, &hrgn ))) return 0;
+    if(!(obj = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC, &hrgn, &region_funcs ))) return 0;
     if(!(obj->rgn = REGION_AllocWineRegion(n))) {
         GDI_FreeObject( hrgn, obj );
         return 0;
@@ -510,7 +522,6 @@ static HRGN REGION_CreateRegion( INT n )
     return hrgn;
 }
 
-
 /***********************************************************************
  *           REGION_DestroyWineRegion
  */
@@ -518,18 +529,27 @@ static void REGION_DestroyWineRegion( WINEREGION* pReg )
 {
     HeapFree( GetProcessHeap(), 0, pReg->rects );
     HeapFree( GetProcessHeap(), 0, pReg );
-    return;
 }
 
 /***********************************************************************
  *           REGION_DeleteObject
  */
-BOOL REGION_DeleteObject( HRGN hrgn, RGNOBJ * obj )
+static BOOL REGION_DeleteObject( HGDIOBJ handle, void *obj )
 {
-    TRACE(" %04x\n", hrgn );
+    RGNOBJ *rgn = obj;
 
-    REGION_DestroyWineRegion( obj->rgn );
-    return GDI_FreeObject( hrgn, obj );
+    TRACE(" %04x\n", handle );
+
+    REGION_DestroyWineRegion( rgn->rgn );
+    return GDI_FreeObject( handle, obj );
+}
+
+/***********************************************************************
+ *           REGION_SelectObject
+ */
+static HGDIOBJ REGION_SelectObject( HGDIOBJ handle, void *obj, HDC hdc )
+{
+    return (HGDIOBJ)SelectClipRgn( hdc, handle );
 }
 
 /***********************************************************************
@@ -3151,7 +3171,8 @@ HRGN REGION_CropRgn( HRGN hDst, HRGN hSrc, const RECT *lpRect, const POINT *lpPt
 	    }
 	    else if( hDst == 0 )
 	    {
-		if (!(objDst = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC, &hDst )))
+		if (!(objDst = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC,
+                                                &hDst, &region_funcs )))
 		{
 fail:
 		    if( rgnDst->rects )
diff --git a/windows/painting.c b/windows/painting.c
index 9dc25b5004c598906600a0f9c2db0bbaa93f7be9..b7ae05b8bce7288b21e505c8d244f82640446aa5 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -25,7 +25,7 @@
 #include "wine/winuser16.h"
 #include "wine/unicode.h"
 #include "wine/server.h"
-#include "region.h"
+#include "gdi.h"
 #include "user.h"
 #include "win.h"
 #include "queue.h"