Index: wine/dlls/ttydrv/bitmap.c
===================================================================
RCS file: /home/wine/wine/dlls/ttydrv/bitmap.c,v
retrieving revision 1.2
diff -u -u -r1.2 bitmap.c
--- wine/dlls/ttydrv/bitmap.c	2000/08/19 21:38:55	1.2
+++ wine/dlls/ttydrv/bitmap.c	2000/10/27 19:20:19
@@ -23,6 +23,10 @@
 TTYDRV_PHYSBITMAP *TTYDRV_DC_AllocBitmap(BITMAPOBJ *bitmap)
 {
   TTYDRV_PHYSBITMAP *physBitmap;
+  const DC_FUNCTIONS *logfuncs;
+  const DC_FUNCTIONS *sclfuncs;
+  const DC_FUNCTIONS *offfuncs;
+  const DC_FUNCTIONS *devfuncs;
   
   if(!(physBitmap = HeapAlloc(GetProcessHeap(), 0, sizeof(TTYDRV_PHYSBITMAP)))) {
     ERR("Can't alloc TTYDRV_PHYSBITMAP\n");
@@ -30,8 +34,16 @@
   }
 
   bitmap->physBitmap = physBitmap;
-  bitmap->funcs = DRIVER_FindDriver("DISPLAY");
 
+  if(!DRIVER_FindDriver("DISPLAY", &logfuncs, &sclfuncs, &offfuncs, &devfuncs)) {
+    return NULL;
+  }
+
+  bitmap->logfuncs = logfuncs;
+  bitmap->sclfuncs = sclfuncs;
+  bitmap->offfuncs = offfuncs;
+  bitmap->devfuncs = devfuncs;
+
   return physBitmap;
 }
 
@@ -131,7 +143,7 @@
   if(!bitmap->physBitmap && !TTYDRV_DC_CreateBitmap(hbitmap))
     return 0;
 
-  if(bitmap->funcs != dc->funcs) {
+  if(bitmap->logfuncs != dc->logfuncs) {
     ERR("Trying to select a non-TTY DDB into a TTY DC\n");
     return 0;
   }
Index: wine/dlls/ttydrv/dc.c
===================================================================
RCS file: /home/wine/wine/dlls/ttydrv/dc.c,v
retrieving revision 1.2
diff -u -u -r1.2 dc.c
--- wine/dlls/ttydrv/dc.c	2000/08/19 21:38:55	1.2
+++ wine/dlls/ttydrv/dc.c	2000/10/27 19:20:20
@@ -182,7 +182,7 @@
   if(!TTYDRV_PALETTE_Initialize())
     return FALSE;
 
-  return DRIVER_RegisterDriver( "DISPLAY", &TTYDRV_DC_Driver );
+  return DRIVER_RegisterDriver( "DISPLAY", &TTYDRV_DC_Driver, NULL );
 }
 
 /**********************************************************************
Index: wine/dlls/wineps/init.c
===================================================================
RCS file: /home/wine/wine/dlls/wineps/init.c,v
retrieving revision 1.4
diff -u -u -r1.4 init.c
--- wine/dlls/wineps/init.c	2000/10/24 02:22:16	1.4
+++ wine/dlls/wineps/init.c	2000/10/27 19:20:20
@@ -244,9 +244,9 @@
 		PSDRV_DefaultFont = CreateFontIndirectA(&DefaultLogFont);
 		/* Register driver as "WINEPS", "WINEPS.DLL" and "WINEPS.DRV"
 		   to allow an easy configuring for users */
-		DRIVER_RegisterDriver( "WINEPS", &PSDRV_Funcs );
-		DRIVER_RegisterDriver( "WINEPS.DLL", &PSDRV_Funcs );
-		DRIVER_RegisterDriver( "WINEPS.DRV", &PSDRV_Funcs );
+		DRIVER_RegisterDriver( "WINEPS", &PSDRV_Funcs, NULL );
+		DRIVER_RegisterDriver( "WINEPS.DLL", &PSDRV_Funcs, NULL );
+		DRIVER_RegisterDriver( "WINEPS.DRV", &PSDRV_Funcs, NULL );
 	    }
 	break;
 	case DLL_PROCESS_DETACH:
Index: wine/graphics/Makefile.in
===================================================================
RCS file: /home/wine/wine/graphics/Makefile.in,v
retrieving revision 1.9
diff -u -u -r1.9 Makefile.in
--- wine/graphics/Makefile.in	2000/09/29 00:28:27	1.9
+++ wine/graphics/Makefile.in	2000/10/27 19:20:21
@@ -12,9 +12,12 @@
 	env.c \
 	escape.c \
 	fontengine.c \
+	log2dev.c \
 	mapping.c \
 	painting.c \
-	path.c
+	off2dev.c \
+	path.c \
+	scl2dev.c
 
 all: $(MODULE).o
 
Index: wine/graphics/driver.c
===================================================================
RCS file: /home/wine/wine/graphics/driver.c,v
retrieving revision 1.9
diff -u -u -r1.9 driver.c
--- wine/graphics/driver.c	2000/02/16 22:47:26	1.9
+++ wine/graphics/driver.c	2000/10/27 19:20:21
@@ -9,13 +9,20 @@
 #include "heap.h"
 #include "debugtools.h"
 
-DEFAULT_DEBUG_CHANNEL(driver)
+DEFAULT_DEBUG_CHANNEL(driver);
 
+extern const DC_FUNCTIONS LOG2DEV_DC_Funcs;
+extern const DC_FUNCTIONS SCL2DEV_DC_Funcs;
+extern const DC_FUNCTIONS OFF2DEV_DC_Funcs;
+
 typedef struct tagGRAPHICS_DRIVER
 {
     struct tagGRAPHICS_DRIVER *next;
     LPSTR                      name;
-    const DC_FUNCTIONS        *funcs;
+    const DC_FUNCTIONS        *logfuncs;
+    const DC_FUNCTIONS        *sclfuncs;
+    const DC_FUNCTIONS        *offfuncs;
+    const DC_FUNCTIONS        *devfuncs;
 } GRAPHICS_DRIVER;
 
 static GRAPHICS_DRIVER *firstDriver = NULL;
@@ -24,11 +31,107 @@
 /**********************************************************************
  *	     DRIVER_RegisterDriver
  */
-BOOL DRIVER_RegisterDriver( LPCSTR name, const DC_FUNCTIONS *funcs )
+BOOL DRIVER_RegisterDriver( LPCSTR name, const DC_FUNCTIONS *logfuncs, const DC_FUNCTIONS *devfuncs )
 {
     GRAPHICS_DRIVER *driver = HeapAlloc( GetProcessHeap(), 0, sizeof(*driver) );
     if (!driver) return FALSE;
-    driver->funcs = funcs;
+
+    if (logfuncs || devfuncs) {
+        driver->logfuncs = HeapAlloc( GetProcessHeap(), 0, sizeof(DC_FUNCTIONS) );
+        driver->sclfuncs = HeapAlloc( GetProcessHeap(), 0, sizeof(DC_FUNCTIONS) );
+        driver->offfuncs = HeapAlloc( GetProcessHeap(), 0, sizeof(DC_FUNCTIONS) );
+    } else {
+        driver->logfuncs = NULL;
+        driver->sclfuncs = NULL;
+        driver->offfuncs = NULL;
+    }
+
+    if (devfuncs) {
+        driver->devfuncs = HeapAlloc( GetProcessHeap(), 0, sizeof(DC_FUNCTIONS) );
+    } else {
+        driver->devfuncs = NULL;
+    }
+
+    if (devfuncs) {
+        int offset;
+        for (offset = 0; offset < sizeof(DC_FUNCTIONS); offset += sizeof(void *))
+	{
+	    void *log2devfunc, *scl2devfunc, *off2devfunc;
+	    void *logfunc, *devfunc;
+	    void **plogfunc, **psclfunc, **pofffunc, **pdevfunc;
+	
+	    log2devfunc = *((void **) ((char *) &LOG2DEV_DC_Funcs + offset));
+	    scl2devfunc = *((void **) ((char *) &SCL2DEV_DC_Funcs + offset));
+	    off2devfunc = *((void **) ((char *) &OFF2DEV_DC_Funcs + offset));
+	    
+	    logfunc = logfuncs?(*((void **) ((char *) logfuncs + offset))):NULL;
+	    devfunc = *((void **) ((char *) devfuncs + offset));
+
+	    plogfunc = (void **) ((char *) driver->logfuncs + offset);
+	    psclfunc = (void **) ((char *) driver->sclfuncs + offset);
+	    pofffunc = (void **) ((char *) driver->offfuncs + offset);
+	    pdevfunc = (void **) ((char *) driver->devfuncs + offset);
+
+	    if (!logfunc && devfunc) {
+	        void *fallbackfunc;
+	      
+		/* Use the least wrong function if
+		 * the right one isn't available.
+		 */
+		if (scl2devfunc) {
+		    fallbackfunc = scl2devfunc;
+		} else if (off2devfunc) {
+		    fallbackfunc = off2devfunc;
+		} else {
+		    fallbackfunc = NULL;
+		}
+		
+		if (log2devfunc) {
+		    *plogfunc = log2devfunc;
+		    fallbackfunc = log2devfunc;
+		} else {
+		    *plogfunc = fallbackfunc;
+		}
+		
+		if (scl2devfunc) {
+		    *psclfunc = scl2devfunc;
+		    fallbackfunc = scl2devfunc;
+		} else {
+		    *psclfunc = fallbackfunc;
+		}
+		
+		if (off2devfunc) {
+		    *pofffunc = off2devfunc;
+		} else {
+		    *pofffunc = fallbackfunc;
+		}
+	    } else {
+	        *plogfunc = logfunc;
+	        *psclfunc = logfunc;
+	        *pofffunc = logfunc;
+	    }
+
+	    *pdevfunc = devfunc;
+	}
+    } else if (logfuncs) {
+        int offset;
+        for (offset = 0; offset < sizeof(DC_FUNCTIONS); offset += sizeof(void *))
+	{
+	    void *logfunc;
+	    void **plogfunc, **psclfunc, **pofffunc;
+
+	    logfunc = *((void **) ((char *) logfuncs + offset));
+
+	    plogfunc = (void **) ((char *) driver->logfuncs + offset);
+	    psclfunc = (void **) ((char *) driver->sclfuncs + offset);
+	    pofffunc = (void **) ((char *) driver->offfuncs + offset);
+
+	    *plogfunc = logfunc;
+	    *psclfunc = logfunc;
+	    *pofffunc = logfunc;
+	}
+    }
+
     if (name)
     {
         driver->name  = HEAP_strdupA( GetProcessHeap(), 0, name );
@@ -52,17 +155,45 @@
 /**********************************************************************
  *	     DRIVER_FindDriver
  */
-const DC_FUNCTIONS *DRIVER_FindDriver( LPCSTR name )
+BOOL DRIVER_FindDriver( LPCSTR name, 
+			const DC_FUNCTIONS **plogfuncs,
+			const DC_FUNCTIONS **psclfuncs,
+			const DC_FUNCTIONS **pofffuncs,
+			const DC_FUNCTIONS **pdevfuncs )
 {
     GRAPHICS_DRIVER *driver = firstDriver;
 
     TRACE(": %s\n", name);
     while (driver && name)
     {
-        if (!strcasecmp( driver->name, name )) return driver->funcs;
+        if (!strcasecmp( driver->name, name ))
+	{
+	    if(plogfuncs) { *plogfuncs = driver->logfuncs; }
+	    if(psclfuncs) { *psclfuncs = driver->sclfuncs; }
+	    if(pofffuncs) { *pofffuncs = driver->offfuncs; }
+	    if(pdevfuncs) { *pdevfuncs = driver->devfuncs; }
+
+	    return TRUE;
+        }
         driver = driver->next;
+    }
+
+    if (genericDriver) 
+    {
+        if(plogfuncs) { *plogfuncs = genericDriver->logfuncs; }
+        if(psclfuncs) { *psclfuncs = genericDriver->sclfuncs; }
+        if(pofffuncs) { *pofffuncs = genericDriver->offfuncs; }
+        if(pdevfuncs) { *pdevfuncs = genericDriver->devfuncs; }
+
+	return TRUE;
     }
-    return genericDriver ? genericDriver->funcs : NULL;
+
+    if(plogfuncs) { *plogfuncs = NULL; }
+    if(psclfuncs) { *psclfuncs = NULL; }
+    if(pofffuncs) { *pofffuncs = NULL; }
+    if(pdevfuncs) { *pdevfuncs = NULL; }
+
+    return FALSE;
 }
 
 
@@ -80,6 +211,10 @@
             {
                 GRAPHICS_DRIVER *driver = *ppDriver;
                 (*ppDriver) = driver->next;
+                HeapFree( GetProcessHeap(), 0, (LPVOID) driver->logfuncs );
+                HeapFree( GetProcessHeap(), 0, (LPVOID) driver->sclfuncs );
+                HeapFree( GetProcessHeap(), 0, (LPVOID) driver->offfuncs );
+                HeapFree( GetProcessHeap(), 0, (LPVOID) driver->devfuncs );
                 HeapFree( GetProcessHeap(), 0, driver->name );
                 HeapFree( GetProcessHeap(), 0, driver );
                 return TRUE;
@@ -91,6 +226,10 @@
     else
     {
         if (!genericDriver) return FALSE;
+	HeapFree( GetProcessHeap(), 0, (LPVOID) genericDriver->logfuncs );
+	HeapFree( GetProcessHeap(), 0, (LPVOID) genericDriver->sclfuncs );
+	HeapFree( GetProcessHeap(), 0, (LPVOID) genericDriver->offfuncs );
+	HeapFree( GetProcessHeap(), 0, (LPVOID) genericDriver->devfuncs );
         HeapFree( GetProcessHeap(), 0, genericDriver );
         genericDriver = NULL;
         return TRUE;
@@ -177,7 +316,7 @@
 	  lpdmInput, lpszProfile, fwMode );
 
     if(!DRIVER_GetDriverName( lpszDevice, buf, sizeof(buf) )) return -1;
-    funcs = DRIVER_FindDriver( buf );
+    if(!DRIVER_FindDriver( buf, &funcs, NULL, NULL, NULL )) return -1;
     if(!funcs || !funcs->pExtDeviceMode) return -1;
     return funcs->pExtDeviceMode(buf, hwnd, lpdmOutput, lpszDevice, lpszPort,
 				 lpdmInput, lpszProfile, fwMode);
@@ -215,7 +354,7 @@
 
 
     if(!DRIVER_GetDriverName( lpszDevice, buf, sizeof(buf) )) return -1;
-    funcs = DRIVER_FindDriver( buf );
+    if(!DRIVER_FindDriver( buf, &funcs, NULL, NULL, NULL )) return -1;
     if(!funcs || !funcs->pDeviceCapabilities) return -1;
     return funcs->pDeviceCapabilities( buf, lpszDevice, lpszPort,
 				       fwCapability, lpszOutput, lpdm);
Index: wine/graphics/enhmetafiledrv/init.c
===================================================================
RCS file: /home/wine/wine/graphics/enhmetafiledrv/init.c,v
retrieving revision 1.13
diff -u -u -r1.13 init.c
--- wine/graphics/enhmetafiledrv/init.c	2000/08/19 21:38:55	1.13
+++ wine/graphics/enhmetafiledrv/init.c	2000/10/27 19:20:21
@@ -254,7 +254,7 @@
 
     TRACE("'%s'\n", debugstr_w(filename) );
 
-    if (!(dc = DC_AllocDC( &EMFDRV_Funcs ))) return 0;
+    if (!(dc = DC_AllocDC( &EMFDRV_Funcs, NULL, NULL, NULL ))) return 0;
     dc->header.wMagic = ENHMETAFILE_DC_MAGIC;
 
     physDev = (EMFDRV_PDEVICE *)HeapAlloc(GetProcessHeap(),0,sizeof(*physDev));
Index: wine/graphics/metafiledrv/init.c
===================================================================
RCS file: /home/wine/wine/graphics/metafiledrv/init.c,v
retrieving revision 1.25
diff -u -u -r1.25 init.c
--- wine/graphics/metafiledrv/init.c	2000/08/19 21:38:55	1.25
+++ wine/graphics/metafiledrv/init.c	2000/10/27 19:20:22
@@ -127,7 +127,7 @@
     DC *dc;
     METAFILEDRV_PDEVICE *physDev;
     
-    if (!(dc = DC_AllocDC( &MFDRV_Funcs ))) return NULL;
+    if (!(dc = DC_AllocDC( &MFDRV_Funcs, NULL, NULL, NULL ))) return NULL;
     dc->header.wMagic = METAFILE_DC_MAGIC;
 
     physDev = (METAFILEDRV_PDEVICE *)HeapAlloc(GetProcessHeap(),0,sizeof(*physDev));
Index: wine/graphics/win16drv/init.c
===================================================================
RCS file: /home/wine/wine/graphics/win16drv/init.c,v
retrieving revision 1.26
diff -u -u -r1.26 init.c
--- wine/graphics/win16drv/init.c	2000/08/06 02:41:17	1.26
+++ wine/graphics/win16drv/init.c	2000/10/27 19:20:23
@@ -152,7 +152,7 @@
  */
 BOOL WIN16DRV_Init(void)
 {
-    return DRIVER_RegisterDriver( NULL /* generic driver */, &WIN16DRV_Funcs );
+    return DRIVER_RegisterDriver( NULL /* generic driver */, &WIN16DRV_Funcs, NULL );
         
 }
 
Index: wine/graphics/x11drv/bitmap.c
===================================================================
RCS file: /home/wine/wine/graphics/x11drv/bitmap.c,v
retrieving revision 1.23
diff -u -u -r1.23 bitmap.c
--- wine/graphics/x11drv/bitmap.c	2000/08/19 21:38:55	1.23
+++ wine/graphics/x11drv/bitmap.c	2000/10/27 19:20:25
@@ -79,7 +79,7 @@
         if(!X11DRV_CreateBitmap(hbitmap))
 	    return 0;
 
-    if(bmp->funcs != dc->funcs) {
+    if(bmp->logfuncs != dc->logfuncs) {
         WARN("Trying to select non-X11 DDB into an X11 dc\n");
 	return 0;
     }
@@ -145,7 +145,19 @@
 
 BOOL X11DRV_CreateBitmap( HBITMAP hbitmap )
 {
-    BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
+    const DC_FUNCTIONS *logfuncs;
+    const DC_FUNCTIONS *sclfuncs;
+    const DC_FUNCTIONS *offfuncs;
+    const DC_FUNCTIONS *devfuncs;
+
+    BITMAPOBJ *bmp;
+
+    if(!DRIVER_FindDriver("DISPLAY", &logfuncs, &sclfuncs, &offfuncs, &devfuncs)) {
+        ERR("No DISPLAY driver\n");
+        return FALSE;
+    }
+
+    bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC );
 
     if(!bmp) {
         WARN("Bad bitmap handle %08x\n", hbitmap);
@@ -179,8 +191,14 @@
 	GDI_ReleaseObj( hbitmap );
 	return FALSE;
     }
-    bmp->funcs = &X11DRV_DC_Funcs;
+        
+    bmp->logfuncs = logfuncs;
+    bmp->sclfuncs = sclfuncs;
+    bmp->offfuncs = offfuncs;
+    bmp->devfuncs = devfuncs;
 
+    bmp->funcs = bmp->devfuncs; /* FIXME: Is this really oorrect? */
+
     if (bmp->bitmap.bmBits) /* Set bitmap bits */
 	X11DRV_BitmapBits( hbitmap, bmp->bitmap.bmBits,
 			   bmp->bitmap.bmHeight * bmp->bitmap.bmWidthBytes,
@@ -487,6 +505,11 @@
     TSXFreePixmap( display, (Pixmap)bmp->physBitmap );
     bmp->physBitmap = NULL;
     bmp->funcs = NULL;
+    bmp->logfuncs = NULL;
+    bmp->sclfuncs = NULL;
+    bmp->offfuncs = NULL;
+    bmp->devfuncs = NULL;
+
     return TRUE;
 }
 
@@ -499,6 +522,10 @@
  */
 HBITMAP X11DRV_BITMAP_CreateBitmapHeaderFromPixmap(Pixmap pixmap)
 {
+    const DC_FUNCTIONS *logfuncs;
+    const DC_FUNCTIONS *sclfuncs;
+    const DC_FUNCTIONS *offfuncs;
+    const DC_FUNCTIONS *devfuncs;
     HBITMAP hBmp = 0;
     BITMAPOBJ *pBmp = NULL;
     Window root;
@@ -506,6 +533,11 @@
     unsigned border_width; /* Unused */
     unsigned int depth, width, height;
 
+    if(!DRIVER_FindDriver("DISPLAY", &logfuncs, &sclfuncs, &offfuncs, &devfuncs)) {
+        ERR("No DISPLAY driver\n");
+        return 0;
+    }
+
     /* Get the Pixmap dimensions and bit depth */
     if ( 0 == TSXGetGeometry(display, pixmap, &root, &x, &y, &width, &height,
                              &border_width, &depth) )
@@ -521,8 +553,14 @@
     hBmp = CreateBitmap( width, height, 1, depth, NULL );
 
     pBmp = (BITMAPOBJ *)GDI_GetObjPtr( hBmp, BITMAP_MAGIC );
-    
-    pBmp->funcs = &X11DRV_DC_Funcs;
+
+    pBmp->logfuncs = logfuncs;
+    pBmp->sclfuncs = sclfuncs;
+    pBmp->offfuncs = offfuncs;
+    pBmp->devfuncs = devfuncs;
+
+    pBmp->funcs = pBmp->devfuncs; /* FIXME: Is this really oorrect? */
+
     pBmp->physBitmap = (void *)pixmap;
     GDI_ReleaseObj( hBmp );
 
@@ -568,6 +606,10 @@
          */
         pBmp->physBitmap = NULL;
         pBmp->funcs = NULL;
+	pBmp->logfuncs = NULL;
+	pBmp->sclfuncs = NULL;
+	pBmp->offfuncs = NULL;
+	pBmp->devfuncs = NULL;
     }
     DeleteObject(hBmp);  
 
Index: wine/graphics/x11drv/brush.c
===================================================================
RCS file: /home/wine/wine/graphics/x11drv/brush.c,v
retrieving revision 1.15
diff -u -u -r1.15 brush.c
--- wine/graphics/x11drv/brush.c	2000/08/19 21:38:55	1.15
+++ wine/graphics/x11drv/brush.c	2000/10/27 19:20:26
@@ -181,7 +181,7 @@
         if(!X11DRV_CreateBitmap(hbitmap))
 	    goto done;
 
-    if(bmp->funcs != dc->funcs) {
+    if(bmp->logfuncs != dc->logfuncs) {
         WARN("Trying to select non-X11 DDB into an X11 dc\n");
 	goto done;
     }
Index: wine/graphics/x11drv/dib.c
===================================================================
RCS file: /home/wine/wine/graphics/x11drv/dib.c,v
retrieving revision 1.56
diff -u -u -r1.56 dib.c
--- wine/graphics/x11drv/dib.c	2000/10/13 20:21:45	1.56
+++ wine/graphics/x11drv/dib.c	2000/10/27 19:20:30
@@ -3647,6 +3647,10 @@
         /* Clear the physBitmap to prevent the Pixmap from being deleted by DeleteObject */
         pBmp->physBitmap = NULL;
         pBmp->funcs = NULL;
+        pBmp->logfuncs = NULL;
+        pBmp->sclfuncs = NULL;
+        pBmp->offfuncs = NULL;
+        pBmp->devfuncs = NULL;
     }
     GDI_ReleaseObj( hBmp );
     DeleteObject(hBmp);  
@@ -3700,6 +3704,10 @@
     /* clear the physBitmap so that we can steal its pixmap */
     pBmp->physBitmap = NULL;
     pBmp->funcs = NULL;
+    pBmp->logfuncs = NULL;
+    pBmp->sclfuncs = NULL;
+    pBmp->offfuncs = NULL;
+    pBmp->devfuncs = NULL;
 
     /* Delete the DDB we created earlier now that we have stolen its pixmap */
     GDI_ReleaseObj( hBmp );
Index: wine/graphics/x11drv/init.c
===================================================================
RCS file: /home/wine/wine/graphics/x11drv/init.c,v
retrieving revision 1.28
diff -u -u -r1.28 init.c
--- wine/graphics/x11drv/init.c	2000/08/20 18:48:24	1.28
+++ wine/graphics/x11drv/init.c	2000/10/27 19:20:32
@@ -27,7 +27,10 @@
 static INT X11DRV_Escape( DC *dc, INT nEscape, INT cbInput,
                             SEGPTR lpInData, SEGPTR lpOutData );
 
-const DC_FUNCTIONS X11DRV_DC_Funcs =
+/***********************************************************************
+ *              X11DRV_DC_LogFuncs
+ */
+const DC_FUNCTIONS X11DRV_DC_LogFuncs =
 {
     NULL,                            /* pAbortDoc */
     NULL,                            /* pAbortPath */
@@ -127,6 +130,8 @@
     NULL                             /* pWidenPath */
 };
 
+/**********************************************************************/
+
 BITMAP_DRIVER X11DRV_BITMAP_Driver =
 {
   X11DRV_DIB_SetDIBits,
@@ -134,6 +139,8 @@
   X11DRV_DIB_DeleteDIBSection
 };
 
+/**********************************************************************/
+
 PALETTE_DRIVER X11DRV_PALETTE_Driver =
 {
   X11DRV_PALETTE_SetMapping,
@@ -141,6 +148,112 @@
   X11DRV_PALETTE_IsDark
 };
 
+/***********************************************************************
+ *		X11DRV_DC_DevFuncs
+ */
+const DC_FUNCTIONS X11DRV_DC_DevFuncs =
+{
+    NULL,                            /* pAbortDoc */
+    NULL,                            /* pAbortPath */
+    NULL,                            /* pAngleArc */
+    X11DRV_Arc,                      /* pArc */
+    NULL,                            /* pArcTo */
+    NULL,                            /* pBeginPath */
+    X11DRV_BitBlt,                   /* pBitBlt */
+    X11DRV_BitmapBits,               /* pBitmapBits */
+    X11DRV_ChoosePixelFormat,        /* pChoosePixelFormat */
+    X11DRV_Chord,                    /* pChord */
+    NULL,                            /* pCloseFigure */
+    X11DRV_CreateBitmap,             /* pCreateBitmap */
+    X11DRV_CreateDC,                 /* pCreateDC */
+    X11DRV_DIB_CreateDIBSection,     /* pCreateDIBSection */
+    X11DRV_DIB_CreateDIBSection16,   /* pCreateDIBSection16 */
+    X11DRV_DeleteDC,                 /* pDeleteDC */
+    X11DRV_DeleteObject,             /* pDeleteObject */
+    X11DRV_DescribePixelFormat,      /* pDescribePixelFormat */
+    NULL,                            /* pDeviceCapabilities */
+    X11DRV_Ellipse,                  /* pEllipse */
+    NULL,                            /* pEndDoc */
+    NULL,                            /* pEndPage */
+    NULL,                            /* pEndPath */
+    X11DRV_EnumDeviceFonts,          /* pEnumDeviceFonts */
+    X11DRV_Escape,                   /* pEscape */
+    NULL,                            /* pExcludeClipRect */
+    NULL,                            /* pExtDeviceMode */
+    X11DRV_ExtFloodFill,             /* pExtFloodFill */
+    X11DRV_ExtTextOut,               /* pExtTextOut */
+    NULL,                            /* pFillPath */
+    NULL,                            /* pFillRgn */
+    NULL,                            /* pFlattenPath */
+    NULL,                            /* pFrameRgn */
+    X11DRV_GetCharWidth,             /* pGetCharWidth */
+    X11DRV_GetDCOrgEx,               /* pGetDCOrgEx */
+    X11DRV_GetPixel,                 /* pGetPixel */
+    X11DRV_GetPixelFormat,           /* pGetPixelFormat */
+    X11DRV_GetTextExtentPoint,       /* pGetTextExtentPoint */
+    X11DRV_GetTextMetrics,           /* pGetTextMetrics */
+    NULL,                            /* pIntersectClipRect */
+    NULL,                            /* pInvertRgn */
+    X11DRV_LineTo,                   /* pLineTo */
+    NULL,                            /* pMoveToEx */
+    NULL,                            /* pOffsetClipRgn */
+    NULL,                            /* pOffsetViewportOrg (optional) */
+    NULL,                            /* pOffsetWindowOrg (optional) */
+    X11DRV_PaintRgn,                 /* pPaintRgn */
+    X11DRV_PatBlt,                   /* pPatBlt */
+    X11DRV_Pie,                      /* pPie */
+    NULL,                            /* pPolyBezier */
+    NULL,                            /* pPolyBezierTo */
+    NULL,                            /* pPolyDraw */
+    X11DRV_PolyPolygon,              /* pPolyPolygon */
+    X11DRV_PolyPolyline,             /* pPolyPolyline */
+    X11DRV_Polygon,                  /* pPolygon */
+    X11DRV_Polyline,                 /* pPolyline */
+    NULL,                            /* pPolylineTo */
+    NULL,                            /* pRealizePalette */
+    X11DRV_Rectangle,                /* pRectangle */
+    NULL,                            /* pRestoreDC */
+    X11DRV_RoundRect,                /* pRoundRect */
+    NULL,                            /* pSaveDC */
+    NULL,                            /* pScaleViewportExt (optional) */
+    NULL,                            /* pScaleWindowExt (optional) */
+    NULL,                            /* pSelectClipPath */
+    NULL,                            /* pSelectClipRgn */
+    X11DRV_SelectObject,             /* pSelectObject */
+    NULL,                            /* pSelectPalette */
+    X11DRV_SetBkColor,               /* pSetBkColor */
+    NULL,                            /* pSetBkMode */
+    X11DRV_SetDeviceClipping,        /* pSetDeviceClipping */
+    X11DRV_SetDIBitsToDevice,        /* pSetDIBitsToDevice */
+    NULL,                            /* pSetMapMode (optional) */
+    NULL,                            /* pSetMapperFlags */
+    X11DRV_SetPixel,                 /* pSetPixel */
+    X11DRV_SetPixelFormat,           /* pSetPixelFormat */
+    NULL,                            /* pSetPolyFillMode */
+    NULL,                            /* pSetROP2 */
+    NULL,                            /* pSetRelAbs */
+    NULL,                            /* pSetStretchBltMode */
+    NULL,                            /* pSetTextAlign */
+    NULL,                            /* pSetTextCharacterExtra */
+    X11DRV_SetTextColor,             /* pSetTextColor */
+    NULL,                            /* pSetTextJustification */
+    NULL,                            /* pSetViewportExt (optional) */
+    NULL,                            /* pSetViewportOrg (optional) */
+    NULL,                            /* pSetWindowExt (optional) */
+    NULL,                            /* pSetWindowOrg (optional) */
+    NULL,                            /* pStartDoc */
+    NULL,                            /* pStartPage */
+    X11DRV_StretchBlt,               /* pStretchBlt */
+    NULL,                            /* pStretchDIBits */
+    NULL,                            /* pStrokeAndFillPath */
+    NULL,                            /* pStrokePath */
+    X11DRV_SwapBuffers,              /* pSwapBuffers */
+    NULL                             /* pWidenPath */
+};
+
+/***********************************************************************
+ *              X11DRV_DevCaps
+ */
 DeviceCaps X11DRV_DevCaps = {
 /* version */		0, 
 /* technology */	DT_RASDISPLAY,
@@ -217,7 +330,7 @@
 
     if (!X11DRV_FONT_Init( &X11DRV_DevCaps )) return FALSE;
 
-    return DRIVER_RegisterDriver( "DISPLAY", &X11DRV_DC_Funcs );
+    return DRIVER_RegisterDriver( "DISPLAY", &X11DRV_DC_LogFuncs, &X11DRV_DC_DevFuncs );
 }
 
 /**********************************************************************
Index: wine/graphics/x11drv/oembitmap.c
===================================================================
RCS file: /home/wine/wine/graphics/x11drv/oembitmap.c,v
retrieving revision 1.17
diff -u -u -r1.17 oembitmap.c
--- wine/graphics/x11drv/oembitmap.c	2000/10/19 20:23:35	1.17
+++ wine/graphics/x11drv/oembitmap.c	2000/10/27 19:20:33
@@ -328,11 +328,20 @@
 static HBITMAP16 OBM_MakeBitmap( WORD width, WORD height,
                                  WORD bpp, Pixmap pixmap )
 {
+    const DC_FUNCTIONS *logfuncs;
+    const DC_FUNCTIONS *sclfuncs;
+    const DC_FUNCTIONS *offfuncs;
+    const DC_FUNCTIONS *devfuncs;
     HBITMAP hbitmap;
     BITMAPOBJ * bmpObjPtr;
 
     if (!pixmap) return 0;
 
+    if(!DRIVER_FindDriver("DISPLAY", &logfuncs, &sclfuncs, &offfuncs, &devfuncs)) {
+        ERR_(bitmap)("No DISPLAY driver\n");
+        return 0;
+    }
+
     if (!(bmpObjPtr = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC, &hbitmap ))) return 0;
     bmpObjPtr->size.cx = width;
     bmpObjPtr->size.cy = height;
@@ -344,8 +353,14 @@
     bmpObjPtr->bitmap.bmBitsPixel  = bpp;
     bmpObjPtr->bitmap.bmBits       = NULL;
     bmpObjPtr->dib                 = NULL;
+
+    bmpObjPtr->logfuncs = logfuncs;
+    bmpObjPtr->sclfuncs = sclfuncs;
+    bmpObjPtr->offfuncs = offfuncs;
+    bmpObjPtr->devfuncs = devfuncs;
+
+    bmpObjPtr->funcs = bmpObjPtr->devfuncs; /* FIXME: Is this really oorrect? */
 
-    bmpObjPtr->funcs = &X11DRV_DC_Funcs;
     bmpObjPtr->physBitmap = (void *)pixmap;
 
     GDI_ReleaseObj( hbitmap );
Index: wine/include/bitmap.h
===================================================================
RCS file: /home/wine/wine/include/bitmap.h,v
retrieving revision 1.19
diff -u -u -r1.19 bitmap.h
--- wine/include/bitmap.h	2000/06/03 20:45:20	1.19
+++ wine/include/bitmap.h	2000/10/27 19:20:33
@@ -24,7 +24,11 @@
     GDIOBJHDR   header;
     BITMAP      bitmap;
     SIZE        size;   /* For SetBitmapDimension() */
-    const struct tagDC_FUNCS *funcs; /* DC function table */
+    const struct tagDC_FUNCS *funcs; /*DC logical (current) function table */
+    const struct tagDC_FUNCS *logfuncs; /* DC logical (world) function table */
+    const struct tagDC_FUNCS *sclfuncs; /* DC logical (scale) function table */
+    const struct tagDC_FUNCS *offfuncs; /* DC logical (offset) function table */
+    const struct tagDC_FUNCS *devfuncs; /* DC device function table */
     void	*physBitmap; /* ptr to device specific data */
     /* For device-independent bitmaps: */
     DIBSECTION *dib;
Index: wine/include/dc.h
===================================================================
RCS file: /home/wine/wine/include/dc.h,v
retrieving revision 1.5
diff -u -u -r1.5 dc.h
--- wine/include/dc.h	2000/08/19 21:38:55	1.5
+++ wine/include/dc.h	2000/10/27 19:20:33
@@ -14,7 +14,7 @@
 #define CLIP_EXCLUDE	0x0002
 #define CLIP_KEEPRGN	0x0004
 
-extern DC * DC_AllocDC( const DC_FUNCTIONS *funcs );
+extern DC *DC_AllocDC( const DC_FUNCTIONS *logfuncs, const DC_FUNCTIONS *sclfuncs, const DC_FUNCTIONS *offfuncs, const DC_FUNCTIONS *devfuncs );
 extern DC * DC_GetDCPtr( HDC hdc );
 extern DC * DC_GetDCUpdate( HDC hdc );
 extern void DC_InitDC( DC * dc );
Index: wine/include/gdi.h
===================================================================
RCS file: /home/wine/wine/include/gdi.h,v
retrieving revision 1.36
diff -u -u -r1.36 gdi.h
--- wine/include/gdi.h	2000/09/16 20:53:52	1.36
+++ wine/include/gdi.h	2000/10/27 19:20:33
@@ -151,7 +151,11 @@
 {
     GDIOBJHDR    header;
     HDC          hSelf;            /* Handle to this DC */
-    const struct tagDC_FUNCS *funcs; /* DC function table */
+    const struct tagDC_FUNCS *funcs; /*DC logical (current) function table */
+    const struct tagDC_FUNCS *logfuncs; /* DC logical (world) function table */
+    const struct tagDC_FUNCS *sclfuncs; /* DC logical (scale) function table */
+    const struct tagDC_FUNCS *offfuncs; /* DC logical (offset) function table */
+    const struct tagDC_FUNCS *devfuncs; /* DC device function table */
     void         *physDev;         /* Physical device (driver-specific) */
     INT          saveLevel;
     DWORD        dwHookData;
@@ -459,8 +463,8 @@
 extern void *GDI_GetObjPtr( HGDIOBJ, WORD );
 extern void GDI_ReleaseObj( HGDIOBJ );
 
-extern BOOL DRIVER_RegisterDriver( LPCSTR name, const DC_FUNCTIONS *funcs );
-extern const DC_FUNCTIONS *DRIVER_FindDriver( LPCSTR name );
+extern BOOL DRIVER_RegisterDriver( LPCSTR name, const DC_FUNCTIONS *logfuncs, const DC_FUNCTIONS *devfuncs );
+BOOL DRIVER_FindDriver( LPCSTR name, const DC_FUNCTIONS **logfuncs, const DC_FUNCTIONS **sclfuncs, const DC_FUNCTIONS **offfuncs, const DC_FUNCTIONS **devfuncs );
 extern BOOL DRIVER_UnregisterDriver( LPCSTR name );
 extern BOOL DRIVER_GetDriverName( LPCSTR device, LPSTR driver, DWORD size );
 
Index: wine/include/x11drv.h
===================================================================
RCS file: /home/wine/wine/include/x11drv.h,v
retrieving revision 1.61
diff -u -u -r1.61 x11drv.h
--- wine/include/x11drv.h	2000/10/25 21:34:32	1.61
+++ wine/include/x11drv.h	2000/10/27 19:20:34
@@ -87,8 +87,6 @@
 
 /* Wine driver X11 functions */
 
-extern const DC_FUNCTIONS X11DRV_DC_Funcs;
-
 extern BOOL X11DRV_BitBlt( struct tagDC *dcDst, INT xDst, INT yDst,
                              INT width, INT height, struct tagDC *dcSrc,
                              INT xSrc, INT ySrc, DWORD rop );
Index: wine/objects/bitmap.c
===================================================================
RCS file: /home/wine/wine/objects/bitmap.c,v
retrieving revision 1.35
diff -u -u -r1.35 bitmap.c
--- wine/objects/bitmap.c	2000/08/19 21:38:56	1.35
+++ wine/objects/bitmap.c	2000/10/27 19:20:35
@@ -138,6 +138,10 @@
     bmp->bitmap.bmBits = NULL;
 
     bmp->funcs = NULL;
+    bmp->logfuncs = NULL;
+    bmp->sclfuncs = NULL;
+    bmp->offfuncs = NULL;
+    bmp->devfuncs = NULL;
     bmp->physBitmap = NULL;
     bmp->dib = NULL;
 
Index: wine/objects/dc.c
===================================================================
RCS file: /home/wine/wine/objects/dc.c,v
retrieving revision 1.46
diff -u -u -r1.46 dc.c
--- wine/objects/dc.c	2000/10/13 20:22:59	1.46
+++ wine/objects/dc.c	2000/10/27 19:20:36
@@ -81,14 +81,23 @@
 /***********************************************************************
  *           DC_AllocDC
  */
-DC *DC_AllocDC( const DC_FUNCTIONS *funcs )
+DC *DC_AllocDC( const DC_FUNCTIONS *logfuncs, const DC_FUNCTIONS *sclfuncs,
+		const DC_FUNCTIONS *offfuncs, const DC_FUNCTIONS *devfuncs )
 {
     HDC hdc;
     DC *dc;
 
     if (!(dc = GDI_AllocObject( sizeof(DC), DC_MAGIC, &hdc ))) return NULL;
     dc->hSelf      = hdc;
-    dc->funcs      = funcs;
+    if(devfuncs) {
+        dc->funcs = devfuncs;
+    } else {
+        dc->funcs = logfuncs;
+    }
+    dc->logfuncs   = logfuncs;
+    dc->sclfuncs   = sclfuncs;
+    dc->offfuncs   = offfuncs;
+    dc->devfuncs   = devfuncs;
     dc->physDev    = NULL;
     dc->saveLevel  = 0;
     dc->dwHookData = 0L;
@@ -236,6 +245,20 @@
     /* Create inverse of world-to-viewport transformation */
     dc->w.vport2WorldValid = DC_InvertXform( &dc->w.xformWorld2Vport,
         &dc->w.xformVport2World );
+
+    if(dc->w.GraphicsMode != GM_COMPATIBLE) { /* FIXME: Not optimal, but will do for now */
+        dc->funcs = dc->logfuncs;
+    } else if(dc->wndExtX != dc->vportExtX || dc->wndExtY != dc->vportExtY) {
+        dc->funcs = dc->sclfuncs;
+    } else if(dc->wndOrgX != dc->vportOrgX || dc->wndOrgY != dc->vportOrgY) {
+        dc->funcs = dc->offfuncs;
+    } else {
+        if(dc->devfuncs) {
+	    dc->funcs = dc->devfuncs;
+	} else {
+	    dc->funcs = dc->logfuncs;
+	}
+    }
 }
 
 
@@ -550,14 +573,17 @@
 {
     HDC hdc;
     DC * dc;
-    const DC_FUNCTIONS *funcs;
+    const DC_FUNCTIONS *logfuncs;
+    const DC_FUNCTIONS *sclfuncs;
+    const DC_FUNCTIONS *offfuncs;
+    const DC_FUNCTIONS *devfuncs;
     char buf[300];
 
     if (!device || !DRIVER_GetDriverName( device, buf, sizeof(buf) ))
         strcpy(buf, driver);
 
-    if (!(funcs = DRIVER_FindDriver( buf ))) return 0;
-    if (!(dc = DC_AllocDC( funcs ))) return 0;
+    if (!DRIVER_FindDriver( buf, &logfuncs, &sclfuncs, &offfuncs, &devfuncs )) return 0;
+    if (!(dc = DC_AllocDC( logfuncs, sclfuncs, offfuncs, devfuncs ))) return 0;
     dc->w.flags = 0;
 
     TRACE("(driver=%s, device=%s, output=%s): returning %04x\n",
@@ -654,12 +680,21 @@
 HDC WINAPI CreateCompatibleDC( HDC hdc )
 {
     DC *dc, *origDC;
-    const DC_FUNCTIONS *funcs;
-
-    if ((origDC = (DC *)GDI_GetObjPtr( hdc, DC_MAGIC ))) funcs = origDC->funcs;
-    else funcs = DRIVER_FindDriver( "DISPLAY" );
+    const DC_FUNCTIONS *logfuncs;
+    const DC_FUNCTIONS *sclfuncs;
+    const DC_FUNCTIONS *offfuncs;
+    const DC_FUNCTIONS *devfuncs;
+
+    if ((origDC = (DC *)GDI_GetObjPtr( hdc, DC_MAGIC ))) {
+        logfuncs = origDC->logfuncs;
+        sclfuncs = origDC->sclfuncs;
+        offfuncs = origDC->offfuncs;
+        devfuncs = origDC->devfuncs;
+    } else if(!DRIVER_FindDriver( "DISPLAY", &logfuncs, &sclfuncs, &offfuncs, &devfuncs )) {
+        return 0;
+    }
 
-    if (!funcs || !(dc = DC_AllocDC( funcs )))
+    if (!(dc = DC_AllocDC( logfuncs, sclfuncs, offfuncs, devfuncs )))
     {
         if (origDC) GDI_ReleaseObj( hdc );
         return 0;
