Moved parts of the DC initialisation and bitmap selection out of the
drivers into the common code.

diff --git a/dlls/gdi/win16drv/init.c b/dlls/gdi/win16drv/init.c
index 78068b2..7966952 100644
--- a/dlls/gdi/win16drv/init.c
+++ b/dlls/gdi/win16drv/init.c
@@ -271,7 +271,6 @@
     wRet = PRTDRV_Enable(&physDev->DevCaps, GETGDIINFO, device, driver, output,NULL); 
 
     /* Add this to the DC */
-    dc->hVisRgn = CreateRectRgn(0, 0, physDev->DevCaps.horzRes, physDev->DevCaps.vertRes);
     dc->bitsPerPixel = physDev->DevCaps.bitsPixel;
     
     TRACE("Got devcaps width %d height %d bits %d planes %d\n",
diff --git a/dlls/ttydrv/bitmap.c b/dlls/ttydrv/bitmap.c
index 04969e2..53b4a2b 100644
--- a/dlls/ttydrv/bitmap.c
+++ b/dlls/ttydrv/bitmap.c
@@ -145,9 +145,6 @@
 
   TRACE("(%p, 0x%04x)\n", dc, hbitmap);
 
-  if(!(dc->flags & DC_MEMORY)) 
-    return 0;
-
   if (!(bitmap = GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return 0;
   /* Assure that the bitmap device dependent */
   if(!bitmap->physBitmap && !TTYDRV_DC_CreateBitmap(hbitmap))
@@ -162,25 +159,6 @@
     return 0;
   }
 
-  dc->totalExtent.left   = 0;
-  dc->totalExtent.top    = 0;
-  dc->totalExtent.right  = bitmap->bitmap.bmWidth;
-  dc->totalExtent.bottom = bitmap->bitmap.bmHeight;
-
-  /* FIXME: Should be done in the common code instead */
-  if(dc->hVisRgn) {
-    SetRectRgn(dc->hVisRgn, 0, 0,
-	       bitmap->bitmap.bmWidth, bitmap->bitmap.bmHeight);
-  } else { 
-    HRGN hrgn;
-
-    if(!(hrgn = CreateRectRgn(0, 0, bitmap->bitmap.bmWidth, bitmap->bitmap.bmHeight)))
-    {
-        GDI_ReleaseObj( hbitmap );
-        return 0;
-    }
-    dc->hVisRgn = hrgn;
-  }
   GDI_ReleaseObj( hbitmap );
   return hbitmap;
 }
diff --git a/dlls/ttydrv/dc.c b/dlls/ttydrv/dc.c
index acbac12..e30cfd1 100644
--- a/dlls/ttydrv/dc.c
+++ b/dlls/ttydrv/dc.c
@@ -21,8 +21,6 @@
 #include "config.h"
 
 #include "gdi.h"
-#include "bitmap.h"
-#include "palette.h"
 #include "ttydrv.h"
 #include "winbase.h"
 #include "wine/debug.h"
@@ -48,7 +46,6 @@
 			LPCSTR output, const DEVMODEA *initData)
 {
   TTYDRV_PDEVICE *physDev;
-  BITMAPOBJ *bmp;
 
   TRACE("(%p, %s, %s, %s, %p)\n",
     dc, debugstr_a(driver), debugstr_a(device), 
@@ -72,28 +69,12 @@
     physDev->cellHeight = 1;
 
     TTYDRV_DC_CreateBitmap(dc->hBitmap);
-    bmp = (BITMAPOBJ *) GDI_GetObjPtr(dc->hBitmap, BITMAP_MAGIC);
-				   
-    dc->bitsPerPixel = bmp->bitmap.bmBitsPixel;
-    
-    dc->totalExtent.left   = 0;
-    dc->totalExtent.top    = 0;
-    dc->totalExtent.right  = bmp->bitmap.bmWidth;
-    dc->totalExtent.bottom = bmp->bitmap.bmHeight;
-    dc->hVisRgn            = CreateRectRgnIndirect( &dc->totalExtent );
-    
-    GDI_ReleaseObj( dc->hBitmap );
   } else {
     physDev->window = root_window;
     physDev->cellWidth = cell_width;
     physDev->cellHeight = cell_height;
-    
-    dc->bitsPerPixel       = 1;
-    dc->totalExtent.left   = 0;
-    dc->totalExtent.top    = 0;
-    dc->totalExtent.right  = cell_width * screen_cols;
-    dc->totalExtent.bottom = cell_height * screen_rows;
-    dc->hVisRgn            = CreateRectRgnIndirect( &dc->totalExtent );    
+
+    dc->bitsPerPixel = 1;
   }
 
   return TRUE;
@@ -128,9 +109,9 @@
     case VERTSIZE:
         return 0;    /* FIXME: Screen height in mm */
     case HORZRES:
-        return 640;  /* FIXME: Screen width in pixel */
+        return cell_width * screen_cols;
     case VERTRES:
-        return 480;  /* FIXME: Screen height in pixel */
+        return cell_height * screen_rows;
     case BITSPIXEL:
         return 1;    /* FIXME */
     case PLANES:
diff --git a/dlls/ttydrv/wnd.c b/dlls/ttydrv/wnd.c
index 4734e95..949f751 100644
--- a/dlls/ttydrv/wnd.c
+++ b/dlls/ttydrv/wnd.c
@@ -134,23 +134,6 @@
 
 
 /***********************************************************************
- *           DCE_OffsetVisRgn
- *
- * Change region from DC-origin relative coordinates to screen coords.
- */
-
-static void DCE_OffsetVisRgn( HDC hDC, HRGN hVisRgn )
-{
-    DC *dc;
-    if (!(dc = DC_GetDCPtr( hDC ))) return;
-
-    OffsetRgn( hVisRgn, dc->DCOrgX, dc->DCOrgY );
-
-    GDI_ReleaseObj( hDC );
-}
-
-
-/***********************************************************************
  *           DCE_GetVisRect
  *
  * Calculate the visible rectangle of a window (i.e. the client or
@@ -388,25 +371,28 @@
     DC *dc;
     BOOL updateVisRgn;
     HRGN hrgnVisible = 0;
+    POINT org;
 
     if (!wndPtr) return FALSE;
 
+    if(flags & DCX_WINDOW)
+    {
+        org.x = wndPtr->rectWindow.left;
+        org.y = wndPtr->rectWindow.top;
+    }
+    else
+    {
+        org.x = wndPtr->rectClient.left;
+        org.y = wndPtr->rectClient.top;
+    }
+
     if (!(dc = DC_GetDCPtr( hdc )))
     {
         WIN_ReleaseWndPtr( wndPtr );
         return FALSE;
     }
-
-    if(flags & DCX_WINDOW)
-    {
-        dc->DCOrgX = wndPtr->rectWindow.left;
-        dc->DCOrgY = wndPtr->rectWindow.top;
-    }
-    else
-    {
-        dc->DCOrgX = wndPtr->rectClient.left;
-        dc->DCOrgY = wndPtr->rectClient.top;
-    }
+    dc->DCOrgX = org.x;
+    dc->DCOrgY = org.y;
     updateVisRgn = (dc->flags & DC_DIRTY) != 0;
     GDI_ReleaseObj( hdc );
 
@@ -433,7 +419,7 @@
                 else
                     OffsetRgn( hrgnVisible, -wndPtr->rectClient.left,
                                -wndPtr->rectClient.top );
-                DCE_OffsetVisRgn( hdc, hrgnVisible );
+                OffsetRgn( hrgnVisible, org.x, org.y );
             }
             else
                 hrgnVisible = CreateRectRgn( 0, 0, 0, 0 );
@@ -442,7 +428,7 @@
         else
         {
             hrgnVisible = DCE_GetVisRgn( hwnd, flags, 0, 0 );
-            DCE_OffsetVisRgn( hdc, hrgnVisible );
+            OffsetRgn( hrgnVisible, org.x, org.y );
         }
         SelectVisRgn16( hdc, hrgnVisible );
     }
@@ -457,7 +443,7 @@
 
         SaveVisRgn16( hdc );
         CombineRgn( hrgnVisible, hrgn, 0, RGN_COPY );
-        DCE_OffsetVisRgn( hdc, hrgnVisible );
+        OffsetRgn( hrgnVisible, org.x, org.y );
         CombineRgn( hrgnVisible, InquireVisRgn16( hdc ), hrgnVisible,
                       (flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF );
         SelectVisRgn16( hdc, hrgnVisible );
diff --git a/dlls/wineps/init.c b/dlls/wineps/init.c
index 7aaa66f..20f39a2 100644
--- a/dlls/wineps/init.c
+++ b/dlls/wineps/init.c
@@ -285,7 +285,6 @@
     }
 
     PSDRV_UpdateDevCaps(physDev);
-    dc->hVisRgn = CreateRectRgn(0, 0, physDev->horzRes, physDev->vertRes);
     dc->hFont = PSDRV_DefaultFont;
     return TRUE;
 }
diff --git a/graphics/x11drv/bitmap.c b/graphics/x11drv/bitmap.c
index b0d23aa..41e0300 100644
--- a/graphics/x11drv/bitmap.c
+++ b/graphics/x11drv/bitmap.c
@@ -79,20 +79,10 @@
 HBITMAP X11DRV_SelectBitmap( X11DRV_PDEVICE *physDev, HBITMAP hbitmap )
 {
     BITMAPOBJ *bmp;
-    HRGN hrgn;
     DC *dc = physDev->dc;
 
-    if (!(dc->flags & DC_MEMORY)) return 0;
-    if (hbitmap == dc->hBitmap) return hbitmap;  /* nothing to do */
     if (!(bmp = GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return 0;
 
-    if (bmp->header.dwCount && (hbitmap != GetStockObject(DEFAULT_BITMAP)))
-    {
-        WARN( "Bitmap already selected in another DC\n" );
-        GDI_ReleaseObj( hbitmap );
-        return 0;
-    }
-
     if(!bmp->physBitmap)
     {
         if(!X11DRV_CreateBitmap(hbitmap))
@@ -108,22 +98,7 @@
 	return 0;
     }
 
-    if (!(hrgn = CreateRectRgn(0, 0, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight)))
-    {
-        GDI_ReleaseObj( hbitmap );
-        return 0;
-    }
-
-    dc->totalExtent.left   = 0;
-    dc->totalExtent.top    = 0;
-    dc->totalExtent.right  = bmp->bitmap.bmWidth;
-    dc->totalExtent.bottom = bmp->bitmap.bmHeight;
-
     physDev->drawable = (Pixmap)bmp->physBitmap;
-    dc->hBitmap     = hbitmap;
-
-    SelectVisRgn16( dc->hSelf, hrgn );
-    DeleteObject( hrgn );
 
       /* Change GC depth if needed */
 
@@ -136,8 +111,6 @@
         XSetSubwindowMode( gdi_display, physDev->gc, IncludeInferiors );
         XFlush( gdi_display );
         wine_tsx11_unlock();
-	dc->bitsPerPixel = bmp->bitmap.bmBitsPixel;
-        DC_InitDC( dc );
     }
     GDI_ReleaseObj( hbitmap );
     return hbitmap;
diff --git a/graphics/x11drv/init.c b/graphics/x11drv/init.c
index 1db4948..ceca915 100644
--- a/graphics/x11drv/init.c
+++ b/graphics/x11drv/init.c
@@ -125,34 +125,18 @@
         if (!bmp->physBitmap) X11DRV_CreateBitmap( dc->hBitmap );
         physDev->drawable  = (Pixmap)bmp->physBitmap;
         physDev->gc        = TSXCreateGC( gdi_display, physDev->drawable, 0, NULL );
-        dc->bitsPerPixel       = bmp->bitmap.bmBitsPixel;
-        dc->totalExtent.left   = 0;
-        dc->totalExtent.top    = 0;
-        dc->totalExtent.right  = bmp->bitmap.bmWidth;
-        dc->totalExtent.bottom = bmp->bitmap.bmHeight;
         GDI_ReleaseObj( dc->hBitmap );
     }
     else
     {
         physDev->drawable  = root_window;
         physDev->gc        = TSXCreateGC( gdi_display, physDev->drawable, 0, NULL );
-        dc->bitsPerPixel       = screen_depth;
-        dc->totalExtent.left   = 0;
-        dc->totalExtent.top    = 0;
-        dc->totalExtent.right  = screen_width;
-        dc->totalExtent.bottom = screen_height;
+        dc->bitsPerPixel   = screen_depth;
     }
 
     physDev->current_pf   = 0;
     physDev->used_visuals = 0;
 
-    if (!(dc->hVisRgn = CreateRectRgnIndirect( &dc->totalExtent )))
-    {
-        TSXFreeGC( gdi_display, physDev->gc );
-	HeapFree( GetProcessHeap(), 0, physDev );
-        return FALSE;
-    }
-
     wine_tsx11_lock();
     XSetGraphicsExposures( gdi_display, physDev->gc, False );
     XSetSubwindowMode( gdi_display, physDev->gc, IncludeInferiors );
diff --git a/objects/dc.c b/objects/dc.c
index 460cf78..06cd6eb 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -605,6 +605,12 @@
         return 0;
     }
 
+    dc->totalExtent.left   = 0;
+    dc->totalExtent.top    = 0;
+    dc->totalExtent.right  = GetDeviceCaps( dc->hSelf, HORZRES );
+    dc->totalExtent.bottom = GetDeviceCaps( dc->hSelf, VERTRES );
+    dc->hVisRgn = CreateRectRgnIndirect( &dc->totalExtent );
+
     DC_InitDC( dc );
     hdc = dc->hSelf;
     GDI_ReleaseObj( hdc );
@@ -720,6 +726,12 @@
         return 0;
     }
 
+    dc->totalExtent.left   = 0;
+    dc->totalExtent.top    = 0;
+    dc->totalExtent.right  = 1;  /* default bitmap is 1x1 */
+    dc->totalExtent.bottom = 1;
+    dc->hVisRgn = CreateRectRgnIndirect( &dc->totalExtent );
+
     DC_InitDC( dc );
     GDI_ReleaseObj( dc->hSelf );
     if (origDC) GDI_ReleaseObj( hdc );
diff --git a/objects/gdiobj.c b/objects/gdiobj.c
index 6bdc166..a5f9683 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -1173,6 +1173,52 @@
     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;
+        if (dc->hVisRgn)
+            SetRectRgn( dc->hVisRgn, 0, 0, bitmap->bitmap.bmWidth, bitmap->bitmap.bmHeight);
+        else
+            dc->hVisRgn = CreateRectRgn( 0, 0, bitmap->bitmap.bmWidth, bitmap->bitmap.bmHeight );
+
+        if (dc->bitsPerPixel != bitmap->bitmap.bmBitsPixel)
+        {
+            /* depth changed, reinitialize the DC */
+            dc->bitsPerPixel = bitmap->bitmap.bmBitsPixel;
+            DC_InitDC( dc );
+        }
+    }
+    GDI_ReleaseObj( handle );
+    return ret;
+}
+
+
 /***********************************************************************
  *           SelectObject    (GDI.45)
  */
@@ -1198,9 +1244,8 @@
     {
     case OBJ_BITMAP:
         ret = dc->hBitmap;
-        if (dc->funcs->pSelectBitmap) handle = dc->funcs->pSelectBitmap( dc->physDev, handle );
-        if (handle) dc->hBitmap = handle;
-        else ret = 0;
+        handle = select_bitmap( dc, handle );
+        if (!handle) ret = 0;
         break;
     case OBJ_BRUSH:
         ret = dc->hBrush;