Added GetDeviceCaps to the DC driver interface. Removed devCaps
pointer in the generic DC structure.

diff --git a/dlls/gdi/driver.c b/dlls/gdi/driver.c
index db1591f..b8a7d95 100644
--- a/dlls/gdi/driver.c
+++ b/dlls/gdi/driver.c
@@ -80,6 +80,7 @@
     GET_FUNC(FrameRgn);
     GET_FUNC(GetCharWidth);
     GET_FUNC(GetDCOrgEx);
+    GET_FUNC(GetDeviceCaps);
     GET_FUNC(GetDeviceGammaRamp);
     GET_FUNC(GetPixel);
     GET_FUNC(GetPixelFormat);
diff --git a/dlls/ttydrv/dc.c b/dlls/ttydrv/dc.c
index 0f9797d..a9dafb8 100644
--- a/dlls/ttydrv/dc.c
+++ b/dlls/ttydrv/dc.c
@@ -35,31 +35,6 @@
   TTYDRV_PALETTE_IsDark
 };
 
-/* FIXME: Adapt to the TTY driver. Copied from the X11 driver */
-
-DeviceCaps TTYDRV_DC_DevCaps = {
-/* version */		0, 
-/* technology */	DT_RASDISPLAY,
-/* size, resolution */	0, 0, 0, 0, 0, 
-/* device objects */	1, 16 + 6, 16, 0, 0, 100, 0,	
-/* curve caps */	CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES |
-			CC_WIDE | CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT,
-/* line caps */		LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
-			LC_STYLED | LC_WIDESTYLED | LC_INTERIORS,
-/* polygon caps */	PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON |
-			PC_SCANLINE | PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS,
-/* text caps */		0,
-/* regions */		CP_REGION,
-/* raster caps */	RC_BITBLT | RC_BANDING | RC_SCALING | RC_BITMAP64 |
-			RC_DI_BITMAP | RC_DIBTODEV | RC_BIGFONT | RC_STRETCHBLT | RC_STRETCHDIB | RC_DEVBITS,
-/* aspects */		36, 36, 51,
-/* pad1 */		{ 0 },
-/* log pixels */	0, 0, 
-/* pad2 */		{ 0 },
-/* palette size */	0,
-/* ..etc */		0, 0
-};
-
 const DC_FUNCTIONS *TTYDRV_DC_Funcs = NULL;  /* hack */
 
 /**********************************************************************
@@ -70,30 +45,9 @@
   BITMAP_Driver = &TTYDRV_BITMAP_Driver;
   PALETTE_Driver = &TTYDRV_PALETTE_Driver;
 
-  TTYDRV_DC_DevCaps.version = 0x300;
-  TTYDRV_DC_DevCaps.horzSize = 0;    /* FIXME: Screen width in mm */
-  TTYDRV_DC_DevCaps.vertSize = 0;    /* FIXME: Screen height in mm */
-  TTYDRV_DC_DevCaps.horzRes = 640;   /* FIXME: Screen width in pixel */
-  TTYDRV_DC_DevCaps.vertRes = 480;   /* FIXME: Screen height in pixel */
-  TTYDRV_DC_DevCaps.bitsPixel = 1;   /* FIXME: Bits per pixel */
-  TTYDRV_DC_DevCaps.sizePalette = 256; /* FIXME: ??? */
-  
-  /* Resolution will be adjusted during the font init */
-  
-  TTYDRV_DC_DevCaps.logPixelsX = (int) (TTYDRV_DC_DevCaps.horzRes * 25.4 / TTYDRV_DC_DevCaps.horzSize);
-  TTYDRV_DC_DevCaps.logPixelsY = (int) (TTYDRV_DC_DevCaps.vertRes * 25.4 / TTYDRV_DC_DevCaps.vertSize);
- 
   return TTYDRV_PALETTE_Initialize();
 }
 
-/**********************************************************************
- *	     TTYDRV_GDI_Finalize
- */
-void TTYDRV_GDI_Finalize(void)
-{
-    TTYDRV_PALETTE_Finalize();
-}
-
 /***********************************************************************
  *	     TTYDRV_DC_CreateDC
  */
@@ -117,8 +71,6 @@
   }
   physDev = (TTYDRV_PDEVICE *) dc->physDev;
   
-  dc->devCaps = &TTYDRV_DC_DevCaps;
-
   if(dc->flags & DC_MEMORY){
     physDev->window = NULL;
     physDev->cellWidth = 1;
@@ -165,15 +117,90 @@
   return TRUE;
 }
 
+
 /***********************************************************************
- *           TTYDRV_DC_Escape
+ *           GetDeviceCaps    (TTYDRV.@)
  */
-INT TTYDRV_DC_Escape(DC *dc, INT nEscape, INT cbInput,
-		     SEGPTR lpInData, SEGPTR lpOutData)
+INT TTYDRV_GetDeviceCaps( DC *dc, INT cap )
 {
-  return 0;
+    switch(cap)
+    {
+    case DRIVERVERSION:
+        return 0x300;
+    case TECHNOLOGY:
+        return DT_RASDISPLAY;
+    case HORZSIZE:
+        return 0;    /* FIXME: Screen width in mm */
+    case VERTSIZE:
+        return 0;    /* FIXME: Screen height in mm */
+    case HORZRES:
+        return 640;  /* FIXME: Screen width in pixel */
+    case VERTRES:
+        return 480;  /* FIXME: Screen height in pixel */
+    case BITSPIXEL:
+        return 1;    /* FIXME */
+    case PLANES:
+        return 1;
+    case NUMBRUSHES:
+        return 16 + 6;
+    case NUMPENS:
+        return 16;
+    case NUMMARKERS:
+        return 0;
+    case NUMFONTS:
+        return 0;
+    case NUMCOLORS:
+        return 100;
+    case PDEVICESIZE:
+        return sizeof(TTYDRV_PDEVICE);
+    case CURVECAPS:
+        return (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE |
+                CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT);
+    case LINECAPS:
+        return (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
+                LC_STYLED | LC_WIDESTYLED | LC_INTERIORS);
+    case POLYGONALCAPS:
+        return (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON |
+                PC_SCANLINE | PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS);
+    case TEXTCAPS:
+        return 0;
+    case CLIPCAPS:
+        return CP_REGION;
+    case RASTERCAPS:
+        return (RC_BITBLT | RC_BANDING | RC_SCALING | RC_BITMAP64 | RC_DI_BITMAP |
+                RC_DIBTODEV | RC_BIGFONT | RC_STRETCHBLT | RC_STRETCHDIB | RC_DEVBITS);
+    case ASPECTX:
+    case ASPECTY:
+        return 36;
+    case ASPECTXY:
+        return 51;
+    case LOGPIXELSX:
+    case LOGPIXELSY:
+        return 72;  /* FIXME */
+    case SIZEPALETTE:
+        return 256;  /* FIXME */
+    case NUMRESERVED:
+        return 0;
+    case COLORRES:
+        return 0;
+    case PHYSICALWIDTH:
+    case PHYSICALHEIGHT:
+    case PHYSICALOFFSETX:
+    case PHYSICALOFFSETY:
+    case SCALINGFACTORX:
+    case SCALINGFACTORY:
+    case VREFRESH:
+    case DESKTOPVERTRES:
+    case DESKTOPHORZRES:
+    case BTLALIGNMENT:
+        return 0;
+    default:
+        FIXME("(%04x): unsupported capability %d, will return 0\n", dc->hSelf, cap );
+        return 0;
+    }
 }
 
+
 /***********************************************************************
  *		TTYDRV_DC_SetDeviceClipping
  */
diff --git a/dlls/ttydrv/palette.c b/dlls/ttydrv/palette.c
index c7e06e1..0ec9006 100644
--- a/dlls/ttydrv/palette.c
+++ b/dlls/ttydrv/palette.c
@@ -16,14 +16,14 @@
 
 /**********************************************************************/
 
-extern DeviceCaps TTYDRV_DC_DevCaps;
-
 extern PALETTEENTRY *COLOR_sysPal;
 extern int COLOR_gapStart;
 extern int COLOR_gapEnd;
 extern int COLOR_gapFilled;
 extern int COLOR_max;
 
+static int palette_size = 256;  /* FIXME */
+
 extern const PALETTEENTRY COLOR_sysPalTemplate[NB_RESERVED_COLORS]; 
 
 /***********************************************************************
@@ -35,20 +35,20 @@
 
   TRACE("(void)\n");
 
-  COLOR_sysPal = (PALETTEENTRY *) HeapAlloc(GetProcessHeap(), 0, sizeof(PALETTEENTRY) * TTYDRV_DC_DevCaps.sizePalette);
+  COLOR_sysPal = (PALETTEENTRY *) HeapAlloc(GetProcessHeap(), 0, sizeof(PALETTEENTRY) * palette_size);
   if(COLOR_sysPal == NULL) {
     WARN("No memory to create system palette!\n");
     return FALSE;
   }
 
-  for(i=0; i < TTYDRV_DC_DevCaps.sizePalette; i++ ) {
+  for(i=0; i < palette_size; i++ ) {
     const PALETTEENTRY *src;
     PALETTEENTRY *dst = &COLOR_sysPal[i];
 
     if(i < NB_RESERVED_COLORS/2) {
       src = &COLOR_sysPalTemplate[i];
-    } else if(i >= TTYDRV_DC_DevCaps.sizePalette - NB_RESERVED_COLORS/2) {
-      src = &COLOR_sysPalTemplate[NB_RESERVED_COLORS + i - TTYDRV_DC_DevCaps.sizePalette];
+    } else if(i >= palette_size - NB_RESERVED_COLORS/2) {
+      src = &COLOR_sysPalTemplate[NB_RESERVED_COLORS + i - palette_size];
     } else {
       PALETTEENTRY pe = { 0, 0, 0, 0 };
       src = &pe;
@@ -74,15 +74,6 @@
 }
 
 /***********************************************************************
- *	     TTYDRV_PALETTE_Finalize
- *
- */
-void TTYDRV_PALETTE_Finalize(void)
-{
-  TRACE("(void)\n");
-}
-
-/***********************************************************************
  *           TTYDRV_PALETTE_SetMapping
  */
 int TTYDRV_PALETTE_SetMapping(
diff --git a/dlls/ttydrv/ttydrv.h b/dlls/ttydrv/ttydrv.h
index 91bcdcb..03c771d 100644
--- a/dlls/ttydrv/ttydrv.h
+++ b/dlls/ttydrv/ttydrv.h
@@ -40,7 +40,6 @@
  */
 
 extern BOOL TTYDRV_GDI_Initialize(void);
-extern void TTYDRV_GDI_Finalize(void);
 
 /* TTY GDI bitmap driver */
 
@@ -109,8 +108,6 @@
 extern struct tagPALETTE_DRIVER TTYDRV_PALETTE_Driver;
 
 extern BOOL TTYDRV_PALETTE_Initialize(void);
-extern void TTYDRV_PALETTE_Finalize(void);
-
 extern int TTYDRV_PALETTE_SetMapping(struct tagPALETTEOBJ *palPtr, UINT uStart, UINT uNum, BOOL mapOnly);
 extern int TTYDRV_PALETTE_UpdateMapping(struct tagPALETTEOBJ *palPtr);
 extern BOOL TTYDRV_PALETTE_IsDark(int pixel);
diff --git a/dlls/ttydrv/ttydrv.spec b/dlls/ttydrv/ttydrv.spec
index 1e2bf6b..65e3f9c 100644
--- a/dlls/ttydrv/ttydrv.spec
+++ b/dlls/ttydrv/ttydrv.spec
@@ -20,10 +20,10 @@
 @ cdecl DeleteDC(ptr) TTYDRV_DC_DeleteDC
 @ cdecl DeleteObject(long) TTYDRV_DC_DeleteObject
 @ cdecl Ellipse(ptr long long long long) TTYDRV_DC_Ellipse
-@ cdecl Escape(ptr long long long long) TTYDRV_DC_Escape
 @ cdecl ExtFloodFill(ptr long long long long) TTYDRV_DC_ExtFloodFill
 @ cdecl ExtTextOut(ptr long long long ptr ptr long ptr) TTYDRV_DC_ExtTextOut
 @ cdecl GetCharWidth(ptr long long ptr) TTYDRV_DC_GetCharWidth
+@ cdecl GetDeviceCaps(ptr long) TTYDRV_GetDeviceCaps
 @ cdecl GetPixel(ptr long long) TTYDRV_DC_GetPixel
 @ cdecl GetTextExtentPoint(ptr ptr long ptr) TTYDRV_DC_GetTextExtentPoint
 @ cdecl GetTextMetrics(ptr ptr) TTYDRV_DC_GetTextMetrics
diff --git a/dlls/ttydrv/ttydrv_main.c b/dlls/ttydrv/ttydrv_main.c
index c98f8da..3014990 100644
--- a/dlls/ttydrv/ttydrv_main.c
+++ b/dlls/ttydrv/ttydrv_main.c
@@ -49,8 +49,6 @@
  */
 static void process_detach(void)
 {
-    TTYDRV_GDI_Finalize();
-
 #ifdef WINE_CURSES
     if (root_window) endwin();
 #endif  /* WINE_CURSES */
diff --git a/dlls/wineps/escape.c b/dlls/wineps/escape.c
index 8cdfab5..2004d96 100644
--- a/dlls/wineps/escape.c
+++ b/dlls/wineps/escape.c
@@ -26,8 +26,8 @@
 	    physDev->job.banding = TRUE;
             r->left   = 0;
             r->top    = 0;
-            r->right  = dc->devCaps->horzRes;
-            r->bottom = dc->devCaps->vertRes;
+            r->right  = physDev->horzRes;
+            r->bottom = physDev->vertRes;
 	    TRACE("NEXTBAND returning %d,%d - %d,%d\n", r->left,
 		  r->top, r->right, r->bottom );
 	    return 1;
@@ -154,8 +154,8 @@
 		TRACE("Found '%s' for paper size %u\n", page->FullName,
 		    	pdev->Devmode->dmPublic.u1.s1.dmPaperSize);
 		
-		p->x = page->PaperDimension->x * dc->devCaps->logPixelsX / 72;
-		p->y = page->PaperDimension->y * dc->devCaps->logPixelsY / 72;
+		p->x = page->PaperDimension->x * physDev->logPixelsX / 72;
+		p->y = page->PaperDimension->y * physDev->logPixelsY / 72;
 		
 		TRACE("%fx%f PostScript points = %ix%i device units\n", 
 		    	page->PaperDimension->x, page->PaperDimension->y,
@@ -168,7 +168,7 @@
 	    	    pdev->Devmode->dmPublic.u1.s1.dmPaperWidth != 0)
 	    {
 		p->x = (pdev->Devmode->dmPublic.u1.s1.dmPaperWidth *
-		    	dc->devCaps->logPixelsX) / 254;
+		    	physDev->logPixelsX) / 254;
 		TRACE("dmPaperWidth = %i device units\n", p->x);
 	    }
 	    
@@ -176,7 +176,7 @@
 	    	    pdev->Devmode->dmPublic.u1.s1.dmPaperLength != 0)
 	    {
 	    	p->y = (pdev->Devmode->dmPublic.u1.s1.dmPaperLength *
-		    	dc->devCaps->logPixelsY) / 254;
+		    	physDev->logPixelsY) / 254;
 		TRACE("dmPaperLength = %i device units\n", p->y);
 	    }
 			
diff --git a/dlls/wineps/font.c b/dlls/wineps/font.c
index 77d70e3..fb0ef5f 100644
--- a/dlls/wineps/font.c
+++ b/dlls/wineps/font.c
@@ -105,8 +105,8 @@
 	    
     tm->tmCharSet = ANSI_CHARSET;   	/* FIXME */
     tm->tmOverhang = 0;
-    tm->tmDigitizedAspectX = dc->devCaps->logPixelsY;
-    tm->tmDigitizedAspectY = dc->devCaps->logPixelsX;
+    tm->tmDigitizedAspectX = physDev->logPixelsY;
+    tm->tmDigitizedAspectY = physDev->logPixelsX;
     
     /*
      *	This is kludgy.  font->scale is used in several places in the driver
@@ -456,11 +456,8 @@
     	NEWTEXTMETRICEXW *pTM, ENUMLOGFONTEXW *pLF, INT16 size)
 
 {
-    DC *dc = DC_GetDCPtr( hdc );
     float scale = size / (pafm->FullAscender - pafm->Descender);
 
-    if (!dc) return FALSE;
-
     memset( pLF, 0, sizeof(*pLF) );
     memset( pTM, 0, sizeof(*pTM) );
 
@@ -488,14 +485,13 @@
     ptm->tmDescent = -pafm->Descender * scale;
     ptm->tmInternalLeading = (pafm->FullAscender - pafm->Ascender) * scale;
     ptm->tmMaxCharWidth = pafm->CharWidths[77] * scale;
-    ptm->tmDigitizedAspectX = dc->devCaps->logPixelsY;
-    ptm->tmDigitizedAspectY = dc->devCaps->logPixelsX;
+    /* FIXME: X and Y are swapped here, is this on purpose? */
+    ptm->tmDigitizedAspectX = GetDeviceCaps( hdc, LOGPIXELSY );
+    ptm->tmDigitizedAspectY = GetDeviceCaps( hdc, LOGPIXELSX );
 
     *(INT*)&ptm->tmFirstChar = 32;
 
-    GDI_ReleaseObj( hdc );
     /* return font type */
-
     return DEVICE_FONTTYPE;
 #undef ptm
 }
diff --git a/dlls/wineps/init.c b/dlls/wineps/init.c
index 88c8ee2..a5c0830 100644
--- a/dlls/wineps/init.c
+++ b/dlls/wineps/init.c
@@ -24,46 +24,6 @@
 
 DEFAULT_DEBUG_CHANNEL(psdrv);
 
-/* Default entries for devcaps */
-
-static DeviceCaps PSDRV_DevCaps = {
-/* version */		0, 
-/* technology */	DT_RASPRINTER,
-/* horzSize */		210,
-/* vertSize */		297,
-/* horzRes */		4961,
-/* vertRes */		7016, 
-/* bitsPixel */		1,
-/* planes */		1,
-/* numBrushes */	-1,
-/* numPens */		10,
-/* numMarkers */	0,
-/* numFonts */		39,
-/* numColors */		0xffff,
-/* pdeviceSize */	0,	
-/* curveCaps */		CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES |
-			CC_WIDE | CC_STYLED | CC_WIDESTYLED | CC_INTERIORS |
-			CC_ROUNDRECT,
-/* lineCaps */		LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
-			LC_STYLED | LC_WIDESTYLED | LC_INTERIORS,
-/* polygoalnCaps */	PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON |
-			PC_SCANLINE | PC_WIDE | PC_STYLED | PC_WIDESTYLED |
-			PC_INTERIORS,
-/* textCaps */		TC_CR_ANY, /* psdrv 0x59f7 */
-/* clipCaps */		CP_RECTANGLE,
-/* rasterCaps */	RC_BITBLT | RC_BITMAP64 | RC_GDI20_OUTPUT |
-			RC_DIBTODEV | RC_STRETCHBLT |
-			RC_STRETCHDIB, /* psdrv 0x6e99 */
-/* aspectX */		600,
-/* aspectY */		600,
-/* aspectXY */		848,
-/* pad1 */		{ 0 },
-/* logPixelsX */	600,
-/* logPixelsY */	600, 
-/* pad2 */		{ 0 },
-/* palette size */	0,
-/* ..etc */		0, 0 };
-
 static PSDRV_DEVMODEA DefaultDevmode = 
 {
   { /* dmPublic */
@@ -173,7 +133,6 @@
 {
     PSDRV_PDEVICE *physDev;
     PRINTERINFO *pi;
-    DeviceCaps *devCaps;
     PAGESIZE *page;
     INT width = 0, height = 0;
 
@@ -216,82 +175,56 @@
         PSDRV_MergeDevmodes(physDev->Devmode, (PSDRV_DEVMODEA *)initData, pi);
     }
 
-    
-    devCaps = HeapAlloc( PSDRV_Heap, 0, sizeof(PSDRV_DevCaps) );
-    memcpy(devCaps, &PSDRV_DevCaps, sizeof(PSDRV_DevCaps));
-
-    /* Are aspect[XY] and logPixels[XY] correct? */
-    /* Need to handle different res in x and y => fix ppd */
-    devCaps->aspectX = devCaps->logPixelsX = 
-				physDev->pi->ppd->DefaultResolution;
-    devCaps->aspectY = devCaps->logPixelsY = 
-				physDev->pi->ppd->DefaultResolution;
-    devCaps->aspectXY = (int)hypot( (double)devCaps->aspectX, 
-				    (double)devCaps->aspectY );
-
+    physDev->logPixelsX = physDev->pi->ppd->DefaultResolution;
+    physDev->logPixelsY = physDev->pi->ppd->DefaultResolution;
 
     for(page = pi->ppd->PageSizes; page; page = page->next) {
         if(page->WinPage == physDev->Devmode->dmPublic.u1.s1.dmPaperSize)
 	    break;
     }
+
     if(!page) {
         FIXME("Can't find page\n");
 	physDev->PageSize.left = 0;
 	physDev->PageSize.right = 0;
 	physDev->PageSize.bottom = 0;
         physDev->PageSize.top = 0;
-    } else if(page->ImageableArea) { /* PageSize is in device units */
-        physDev->PageSize.left = page->ImageableArea->llx *
-	  devCaps->logPixelsX / 72;
-       physDev->PageSize.right = page->ImageableArea->urx *
-	  devCaps->logPixelsX / 72;
-       physDev->PageSize.bottom = page->ImageableArea->lly *
-	  devCaps->logPixelsY / 72;
-       physDev->PageSize.top = page->ImageableArea->ury *
-	  devCaps->logPixelsY / 72;
+    } else if(page->ImageableArea) {  /* PageSize is in device units */
+        physDev->PageSize.left = page->ImageableArea->llx * physDev->logPixelsX / 72;
+        physDev->PageSize.right = page->ImageableArea->urx * physDev->logPixelsX / 72;
+        physDev->PageSize.bottom = page->ImageableArea->lly * physDev->logPixelsY / 72;
+        physDev->PageSize.top = page->ImageableArea->ury * physDev->logPixelsY / 72;
     } else {
         physDev->PageSize.left = physDev->PageSize.bottom = 0;
-	physDev->PageSize.right = page->PaperDimension->x *
-	  devCaps->logPixelsX / 72;
-	physDev->PageSize.top = page->PaperDimension->y *
-	  devCaps->logPixelsY / 72;
+        physDev->PageSize.right = page->PaperDimension->x * physDev->logPixelsX / 72;
+        physDev->PageSize.top = page->PaperDimension->y * physDev->logPixelsY / 72;
     }
-    TRACE("PageSize = (%d,%d - %d,%d)\n", physDev->PageSize.left, physDev->PageSize.bottom, physDev->PageSize.right, physDev->PageSize.top);
+    TRACE("PageSize = (%d,%d - %d,%d)\n",physDev->PageSize.left, physDev->PageSize.bottom, physDev->PageSize.right, physDev->PageSize.top);
 
     /* these are in device units */
     width = physDev->PageSize.right - physDev->PageSize.left;
     height = physDev->PageSize.top - physDev->PageSize.bottom;
 
     if(physDev->Devmode->dmPublic.u1.s1.dmOrientation == DMORIENT_PORTRAIT) {
-        devCaps->horzRes = width;
-	devCaps->vertRes = height;
+        physDev->horzRes = width;
+        physDev->vertRes = height;
     } else {
-        devCaps->horzRes = height;
-	devCaps->vertRes = width;
+        physDev->horzRes = height;
+        physDev->vertRes = width;
     }
 
     /* these are in mm */
-    devCaps->horzSize = (devCaps->horzRes * 25.4) / devCaps->logPixelsX;
-    devCaps->vertSize = (devCaps->vertRes * 25.4) / devCaps->logPixelsY;
+    physDev->horzSize = (physDev->horzRes * 25.4) / physDev->logPixelsX;
+    physDev->vertSize = (physDev->vertRes * 25.4) / physDev->logPixelsY;
 
     TRACE("devcaps: horzSize = %dmm, vertSize = %dmm, "
 	  "horzRes = %d, vertRes = %d\n",
-	  devCaps->horzSize, devCaps->vertSize,
-	  devCaps->horzRes, devCaps->vertRes);
-
-    if(physDev->pi->ppd->ColorDevice) {
-        devCaps->bitsPixel = 8;
-	devCaps->numColors = 256;
-	/* FIXME are these values OK? */
-    }
+	  physDev->horzSize, physDev->vertSize,
+	  physDev->horzRes, physDev->vertRes);
 
     /* etc */
 
-    dc->devCaps = devCaps;
-
-    dc->hVisRgn = CreateRectRgn(0, 0, dc->devCaps->horzRes,
-    			    dc->devCaps->vertRes);
-    
+    dc->hVisRgn = CreateRectRgn(0, 0, physDev->horzRes, physDev->vertRes);
     dc->hFont = PSDRV_DefaultFont;
 
     if (!output) output = "LPT1:";  /* HACK */
@@ -313,7 +246,6 @@
 
     HeapFree( PSDRV_Heap, 0, physDev->Devmode );
     HeapFree( PSDRV_Heap, 0, physDev->job.output );
-    HeapFree( PSDRV_Heap, 0, (void *)dc->devCaps );
     HeapFree( PSDRV_Heap, 0, physDev );
     dc->physDev = NULL;
 
@@ -321,6 +253,108 @@
 }
 
 
+/***********************************************************************
+ *           GetDeviceCaps    (WINEPS.@)
+ */
+INT PSDRV_GetDeviceCaps( DC *dc, INT cap )
+{
+    PSDRV_PDEVICE *physDev = dc->physDev;
+    POINT pt;
+
+    switch(cap)
+    {
+    case DRIVERVERSION:
+        return 0;
+    case TECHNOLOGY:
+        return DT_RASPRINTER;
+    case HORZSIZE:
+        return physDev->horzSize;
+    case VERTSIZE:
+        return physDev->vertSize;
+    case HORZRES:
+        return physDev->horzRes;
+    case VERTRES:
+        return physDev->vertRes;
+    case BITSPIXEL:
+        return (physDev->pi->ppd->ColorDevice ? 8 : 1);
+    case PLANES:
+        return 1;
+    case NUMBRUSHES:
+        return -1;
+    case NUMPENS:
+        return 10;
+    case NUMMARKERS:
+        return 0;
+    case NUMFONTS:
+        return 39;
+    case NUMCOLORS:
+        return (physDev->pi->ppd->ColorDevice ? 256 : -1);
+    case PDEVICESIZE:
+        return sizeof(PSDRV_PDEVICE);
+    case CURVECAPS:
+        return (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE |
+                CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT);
+    case LINECAPS:
+        return (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
+                LC_STYLED | LC_WIDESTYLED | LC_INTERIORS);
+    case POLYGONALCAPS:
+        return (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON | PC_SCANLINE |
+                PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS);
+    case TEXTCAPS:
+        return TC_CR_ANY; /* psdrv 0x59f7 */
+    case CLIPCAPS:
+        return CP_RECTANGLE;
+    case RASTERCAPS:
+        return (RC_BITBLT | RC_BITMAP64 | RC_GDI20_OUTPUT | RC_DIBTODEV |
+                RC_STRETCHBLT | RC_STRETCHDIB); /* psdrv 0x6e99 */
+    /* Are aspect[XY] and logPixels[XY] correct? */
+    /* Need to handle different res in x and y => fix ppd */
+    case ASPECTX:
+    case ASPECTY:
+        return physDev->pi->ppd->DefaultResolution;
+    case ASPECTXY:
+        return (int)hypot( (double)physDev->pi->ppd->DefaultResolution,
+                           (double)physDev->pi->ppd->DefaultResolution );
+    case LOGPIXELSX:
+        return physDev->logPixelsX;
+    case LOGPIXELSY:
+        return physDev->logPixelsY;
+    case SIZEPALETTE:
+        return 0;
+    case NUMRESERVED:
+        return 0;
+    case COLORRES:
+        return 0;
+    case PHYSICALWIDTH:
+        if (Escape(dc->hSelf, GETPHYSPAGESIZE, 0, NULL, &pt) > 0) return pt.x;
+        return 0;
+    case PHYSICALHEIGHT:
+        if (Escape(dc->hSelf, GETPHYSPAGESIZE, 0, NULL, &pt) > 0) return pt.y;
+        return 0;
+    case PHYSICALOFFSETX:
+        if(Escape(dc->hSelf, GETPRINTINGOFFSET, 0, NULL, &pt) > 0) return pt.x;
+        return 0;
+    case PHYSICALOFFSETY:
+        if (Escape(dc->hSelf, GETPRINTINGOFFSET, 0, NULL, &pt) > 0) return pt.y;
+        return 0;
+    case SCALINGFACTORX:
+        if (Escape(dc->hSelf, GETSCALINGFACTOR, 0, NULL, &pt) > 0) return pt.x;
+        return 0;
+    case SCALINGFACTORY:
+        if (Escape(dc->hSelf, GETSCALINGFACTOR, 0, NULL, &pt) > 0) return pt.y;
+        return 0;
+    case VREFRESH:
+    case DESKTOPVERTRES:
+    case DESKTOPHORZRES:
+    case BTLALIGNMENT:
+        return 0;
+    default:
+        FIXME("(%04x): unsupported capability %d, will return 0\n", dc->hSelf, cap );
+        return 0;
+    }
+}
+
+
 /**********************************************************************
  *		PSDRV_FindPrinterInfo
  */
diff --git a/dlls/wineps/ps.c b/dlls/wineps/ps.c
index 64e27b0..44d8f20 100644
--- a/dlls/wineps/ps.c
+++ b/dlls/wineps/ps.c
@@ -314,10 +314,10 @@
     
     /* BBox co-ords are in default user co-ord system so urx < ury even in
        landscape mode */
-    llx = physDev->PageSize.left * 72.0 / dc->devCaps->logPixelsX;
-    lly = physDev->PageSize.bottom * 72.0 / dc->devCaps->logPixelsY;
-    urx = physDev->PageSize.right * 72.0 / dc->devCaps->logPixelsX;
-    ury = physDev->PageSize.top * 72.0 / dc->devCaps->logPixelsY;
+    llx = physDev->PageSize.left * 72.0 / physDev->logPixelsX;
+    lly = physDev->PageSize.bottom * 72.0 / physDev->logPixelsY;
+    urx = physDev->PageSize.right * 72.0 / physDev->logPixelsX;
+    ury = physDev->PageSize.top * 72.0 / physDev->logPixelsY;
 
     if(physDev->Devmode->dmPublic.u1.s1.dmOrientation == DMORIENT_LANDSCAPE) {
 	orient = "Landscape";
@@ -461,7 +461,7 @@
     }
 
     sprintf(buf, psnewpage, name, physDev->job.PageNo,
-	    dc->devCaps->logPixelsX, dc->devCaps->logPixelsY,
+	    physDev->logPixelsX, physDev->logPixelsY,
 	    xtrans, ytrans, rotation);
 
     if( WriteSpool16( physDev->job.hJob, buf, strlen(buf) ) != 
diff --git a/dlls/wineps/psdrv.h b/dlls/wineps/psdrv.h
index 8aa1f35..dc1601d 100644
--- a/dlls/wineps/psdrv.h
+++ b/dlls/wineps/psdrv.h
@@ -258,6 +258,12 @@
     PSDRV_DEVMODEA	*Devmode;
     PRINTERINFO		*pi;
     RECT                PageSize;      /* Imageable area in device co-ords */
+    int                 horzRes;       /* device caps */
+    int                 vertRes;
+    int                 horzSize;
+    int                 vertSize;
+    int                 logPixelsX;
+    int                 logPixelsY;
 } PSDRV_PDEVICE;
 
 typedef struct {
diff --git a/dlls/wineps/wineps.spec b/dlls/wineps/wineps.spec
index 2b3f515..6bcfb1b 100644
--- a/dlls/wineps/wineps.spec
+++ b/dlls/wineps/wineps.spec
@@ -27,6 +27,7 @@
 @ cdecl ExtDeviceMode(ptr long ptr ptr ptr ptr ptr long) PSDRV_ExtDeviceMode
 @ cdecl ExtTextOut(ptr long long long ptr ptr long ptr) PSDRV_ExtTextOut
 @ cdecl GetCharWidth(ptr long long ptr) PSDRV_GetCharWidth
+@ cdecl GetDeviceCaps(ptr long) PSDRV_GetDeviceCaps
 @ cdecl GetTextExtentPoint(ptr ptr long ptr) PSDRV_GetTextExtentPoint
 @ cdecl GetTextMetrics(ptr ptr) PSDRV_GetTextMetrics
 @ cdecl LineTo(ptr long long) PSDRV_LineTo
diff --git a/dlls/x11drv/x11drv.spec b/dlls/x11drv/x11drv.spec
index 54d3365..05210d9 100644
--- a/dlls/x11drv/x11drv.spec
+++ b/dlls/x11drv/x11drv.spec
@@ -31,6 +31,7 @@
 @ cdecl ExtTextOut(ptr long long long ptr ptr long ptr) X11DRV_ExtTextOut
 @ cdecl GetCharWidth(ptr long long ptr) X11DRV_GetCharWidth
 @ cdecl GetDCOrgEx(ptr ptr) X11DRV_GetDCOrgEx
+@ cdecl GetDeviceCaps(ptr long) X11DRV_GetDeviceCaps
 @ cdecl GetDeviceGammaRamp(ptr ptr) X11DRV_GetDeviceGammaRamp
 @ cdecl GetPixel(ptr long long) X11DRV_GetPixel
 @ cdecl GetPixelFormat(ptr) X11DRV_GetPixelFormat
diff --git a/graphics/enhmetafiledrv/init.c b/graphics/enhmetafiledrv/init.c
index d5750db..7ed115b 100644
--- a/graphics/enhmetafiledrv/init.c
+++ b/graphics/enhmetafiledrv/init.c
@@ -51,6 +51,7 @@
     EMFDRV_FrameRgn,                 /* pFrameRgn */
     NULL,                            /* pGetCharWidth */
     NULL,                            /* pGetDCOrgEx */
+    NULL,                            /* pGetDeviceCaps */
     NULL,                            /* pGetDeviceGammaRamp */
     NULL, /* no implementation */    /* pGetPixel */
     NULL,                            /* pGetPixelFormat */
diff --git a/graphics/mapping.c b/graphics/mapping.c
index e83dead..c55229b 100644
--- a/graphics/mapping.c
+++ b/graphics/mapping.c
@@ -17,10 +17,10 @@
  */
 void MAPPING_FixIsotropic( DC * dc )
 {
-    double xdim = (double)dc->vportExtX * dc->devCaps->horzSize /
-	          (dc->devCaps->horzRes * dc->wndExtX);
-    double ydim = (double)dc->vportExtY * dc->devCaps->vertSize /
-	          (dc->devCaps->vertRes * dc->wndExtY);
+    double xdim = (double)dc->vportExtX * GetDeviceCaps( dc->hSelf, HORZSIZE ) /
+                  (GetDeviceCaps( dc->hSelf, HORZRES ) * dc->wndExtX);
+    double ydim = (double)dc->vportExtY * GetDeviceCaps( dc->hSelf, VERTSIZE ) /
+                  (GetDeviceCaps( dc->hSelf, VERTRES ) * dc->wndExtY);
     if (xdim > ydim)
     {
 	dc->vportExtX = dc->vportExtX * fabs( ydim / xdim );
@@ -30,7 +30,7 @@
     {
 	dc->vportExtY = dc->vportExtY * fabs( xdim / ydim );
 	if (!dc->vportExtY) dc->vportExtY = 1;
-    }	
+    }
 }
 
 
@@ -124,6 +124,8 @@
 INT WINAPI SetMapMode( HDC hdc, INT mode )
 {
     INT prevMode;
+    INT horzSize, vertSize, horzRes, vertRes;
+
     DC * dc = DC_GetDCPtr( hdc );
     if (!dc) return 0;
     if (dc->funcs->pSetMapMode)
@@ -133,58 +135,55 @@
     }
 
     TRACE("%04x %d\n", hdc, mode );
-    
+
     prevMode = dc->MapMode;
+    horzSize = GetDeviceCaps( hdc, HORZSIZE );
+    vertSize = GetDeviceCaps( hdc, VERTSIZE );
+    horzRes  = GetDeviceCaps( hdc, HORZRES );
+    vertRes  = GetDeviceCaps( hdc, VERTRES );
     switch(mode)
     {
-      case MM_TEXT:
-	  dc->wndExtX   = 1;
-	  dc->wndExtY   = 1;
-	  dc->vportExtX = 1;
-	  dc->vportExtY = 1;
-	  break;
-	  
-      case MM_LOMETRIC:
-      case MM_ISOTROPIC:
-	  dc->wndExtX   = dc->devCaps->horzSize;
-	  dc->wndExtY   = dc->devCaps->vertSize;
-	  dc->vportExtX = dc->devCaps->horzRes / 10;
-	  dc->vportExtY = dc->devCaps->vertRes / -10;
-	  break;
-	  
-      case MM_HIMETRIC:
-	  dc->wndExtX   = dc->devCaps->horzSize * 10;
-	  dc->wndExtY   = dc->devCaps->vertSize * 10;
-	  dc->vportExtX = dc->devCaps->horzRes / 10;
-	  dc->vportExtY = dc->devCaps->vertRes / -10;
-	  break;
-	  
-      case MM_LOENGLISH:
-	  dc->wndExtX   = dc->devCaps->horzSize;
-	  dc->wndExtY   = dc->devCaps->vertSize;
-	  dc->vportExtX = 254L * dc->devCaps->horzRes / 1000;
-	  dc->vportExtY = -254L * dc->devCaps->vertRes / 1000;
-	  break;	  
-	  
-      case MM_HIENGLISH:
-	  dc->wndExtX   = dc->devCaps->horzSize * 10;
-	  dc->wndExtY   = dc->devCaps->vertSize * 10;
-	  dc->vportExtX = 254L * dc->devCaps->horzRes / 1000;
-	  dc->vportExtY = -254L * dc->devCaps->vertRes / 1000;
-	  break;
-	  
-      case MM_TWIPS:
-	  dc->wndExtX   = 144L * dc->devCaps->horzSize / 10;
-	  dc->wndExtY   = 144L * dc->devCaps->vertSize / 10;
-	  dc->vportExtX = 254L * dc->devCaps->horzRes / 1000;
-	  dc->vportExtY = -254L * dc->devCaps->vertRes / 1000;
-	  break;
-	  
-      case MM_ANISOTROPIC:
-	  break;
-
-      default:
-	  goto done;
+    case MM_TEXT:
+        dc->wndExtX   = 1;
+        dc->wndExtY   = 1;
+        dc->vportExtX = 1;
+        dc->vportExtY = 1;
+        break;
+    case MM_LOMETRIC:
+    case MM_ISOTROPIC:
+        dc->wndExtX   = horzSize;
+        dc->wndExtY   = vertSize;
+        dc->vportExtX = horzRes / 10;
+        dc->vportExtY = vertRes / -10;
+        break;
+    case MM_HIMETRIC:
+        dc->wndExtX   = horzSize * 10;
+        dc->wndExtY   = vertSize * 10;
+        dc->vportExtX = horzRes / 10;
+        dc->vportExtY = vertRes / -10;
+        break;
+    case MM_LOENGLISH:
+        dc->wndExtX   = horzSize;
+        dc->wndExtY   = vertSize;
+        dc->vportExtX = 254L * horzRes / 1000;
+        dc->vportExtY = -254L * vertRes / 1000;
+        break;
+    case MM_HIENGLISH:
+        dc->wndExtX   = horzSize * 10;
+        dc->wndExtY   = vertSize * 10;
+        dc->vportExtX = 254L * horzRes / 1000;
+        dc->vportExtY = -254L * vertRes / 1000;
+        break;
+    case MM_TWIPS:
+        dc->wndExtX   = 144L * horzSize / 10;
+        dc->wndExtY   = 144L * vertSize / 10;
+        dc->vportExtX = 254L * horzRes / 1000;
+        dc->vportExtY = -254L * vertRes / 1000;
+        break;
+    case MM_ANISOTROPIC:
+        break;
+    default:
+        goto done;
     }
     dc->MapMode = mode;
     DC_UpdateXforms( dc );
diff --git a/graphics/metafiledrv/init.c b/graphics/metafiledrv/init.c
index 758ba1e..3f2ffe3 100644
--- a/graphics/metafiledrv/init.c
+++ b/graphics/metafiledrv/init.c
@@ -52,6 +52,7 @@
     MFDRV_FrameRgn,                  /* pFrameRgn */
     NULL,                            /* pGetCharWidth */
     NULL,                            /* pGetDCOrgEx */
+    NULL,                            /* pGetDeviceCaps */
     NULL,                            /* pGetDeviceGammaRamp */
     NULL, /* no implementation */    /* pGetPixel */
     NULL,                            /* pGetPixelFormat */
diff --git a/graphics/win16drv/init.c b/graphics/win16drv/init.c
index f84982e..935f2cc 100644
--- a/graphics/win16drv/init.c
+++ b/graphics/win16drv/init.c
@@ -39,6 +39,7 @@
 
 static BOOL WIN16DRV_CreateDC( DC *dc, LPCSTR driver, LPCSTR device,
                                  LPCSTR output, const DEVMODEA* initData );
+static INT WIN16DRV_GetDeviceCaps( DC *dc, INT cap );
 static INT WIN16DRV_Escape( DC *dc, INT nEscape, INT cbInput, 
                               SEGPTR lpInData, SEGPTR lpOutData );
 
@@ -78,6 +79,7 @@
     NULL,                            /* pFrameRgn */
     WIN16DRV_GetCharWidth,           /* pGetCharWidth */
     NULL,                            /* pGetDCOrgEx */
+    WIN16DRV_GetDeviceCaps,          /* pGetDeviceCaps */
     NULL,                            /* pGetDeviceGammaRamp */
     NULL,                            /* pGetPixel */
     NULL,                            /* pGetPixelFormat */
@@ -198,7 +200,6 @@
 {
     LOADED_PRINTER_DRIVER *pLPD;
     WORD wRet;
-    DeviceCaps *printerDevCaps;
     int nPDEVICEsize;
     PDEVICE_HEADER *pPDH;
     WIN16DRV_PDEVICE *physDev;
@@ -238,32 +239,25 @@
     TRACE("windevCreateDC pLPD 0x%p\n", pLPD);
 
     /* Now Get the device capabilities from the printer driver */
-    
-    printerDevCaps = (DeviceCaps *) calloc(1, sizeof(DeviceCaps));
-    if(printerDevCaps == NULL) {
-        ERR("No memory to read the device capabilities!\n");
-        HeapFree( GetProcessHeap(), 0, physDev );
-        return FALSE;
-    }
-
+    memset( &physDev->DevCaps, 0, sizeof(physDev->DevCaps) );
     if(!output) output = "LPT1:";
+
     /* Get GDIINFO which is the same as a DeviceCaps structure */
-    wRet = PRTDRV_Enable(printerDevCaps, GETGDIINFO, device, driver, output,NULL); 
+    wRet = PRTDRV_Enable(&physDev->DevCaps, GETGDIINFO, device, driver, output,NULL); 
 
     /* Add this to the DC */
-    dc->devCaps = printerDevCaps;
-    dc->hVisRgn = CreateRectRgn(0, 0, dc->devCaps->horzRes, dc->devCaps->vertRes);
-    dc->bitsPerPixel = dc->devCaps->bitsPixel;
+    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",
-	  dc->devCaps->horzRes, dc->devCaps->vertRes, 
-	  dc->devCaps->bitsPixel, dc->devCaps->planes);
+	  physDev->DevCaps.horzRes, physDev->DevCaps.vertRes, 
+	  physDev->DevCaps.bitsPixel, physDev->DevCaps.planes);
 
     /* Now we allocate enough memory for the PDEVICE structure */
     /* The size of this varies between printer drivers */
     /* This PDEVICE is used by the printer DRIVER not by the GDI so must */
     /* be accessable from 16 bit code */
-    nPDEVICEsize = dc->devCaps->pdeviceSize + sizeof(PDEVICE_HEADER);
+    nPDEVICEsize = physDev->DevCaps.pdeviceSize + sizeof(PDEVICE_HEADER);
 
     /* TTD Shouldn't really do pointer arithmetic on segment points */
     physDev->segptrPDEVICE = K32WOWGlobalLock16(GlobalAlloc16(GHND, nPDEVICEsize))+sizeof(PDEVICE_HEADER);
@@ -308,6 +302,23 @@
 
     return bRet;
 }
+
+
+/***********************************************************************
+ *           WIN16DRV_GetDeviceCaps
+ */
+static INT WIN16DRV_GetDeviceCaps( DC *dc, INT cap )
+{
+    WIN16DRV_PDEVICE *physDev = dc->physDev;
+    if (cap >= PHYSICALWIDTH || (cap % 2))
+    {
+        FIXME("(%04x): unsupported capability %d, will return 0\n", dc->hSelf, cap );
+        return 0;
+    }
+    return *((WORD *)&physDev->DevCaps + (cap / 2));
+}
+
+
 /* 
  * Escape (GDI.38)
  */
diff --git a/graphics/win16drv/text.c b/graphics/win16drv/text.c
index de289d0..98392df 100644
--- a/graphics/win16drv/text.c
+++ b/graphics/win16drv/text.c
@@ -45,8 +45,8 @@
     clipRect.left = 0;
     clipRect.top = 0;
         
-    clipRect.right = dc->devCaps->horzRes;
-    clipRect.bottom = dc->devCaps->vertRes;
+    clipRect.right = physDev->DevCaps.horzRes;
+    clipRect.bottom = physDev->DevCaps.vertRes;
     if (lprect) {
 	opaqueRect.left = lprect->left;
 	opaqueRect.top = lprect->top;
diff --git a/graphics/x11drv/init.c b/graphics/x11drv/init.c
index e77646d..9d1ee22 100644
--- a/graphics/x11drv/init.c
+++ b/graphics/x11drv/init.c
@@ -39,32 +39,18 @@
   X11DRV_PALETTE_IsDark
 };
 
-DeviceCaps X11DRV_DevCaps = {
-/* version */		0, 
-/* technology */	DT_RASDISPLAY,
-/* size, resolution */	0, 0, 0, 0, 0, 
-/* device objects */	1, -1, -1, 0, 0, -1, 1152,	
-/* curve caps */	CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES |
-			CC_WIDE | CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT,
-/* line caps */		LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
-			LC_STYLED | LC_WIDESTYLED | LC_INTERIORS,
-/* polygon caps */	PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON |
-			PC_SCANLINE | PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS,
-/* text caps */		0,
-/* regions */		CP_REGION,
-/* raster caps */	RC_BITBLT | RC_BANDING | RC_SCALING | RC_BITMAP64 |
-			RC_DI_BITMAP | RC_DIBTODEV | RC_BIGFONT | RC_STRETCHBLT | RC_STRETCHDIB | RC_DEVBITS,
-/* aspects */		36, 36, 51,
-/* pad1 */		{ 0 },
-/* log pixels */	0, 0, 
-/* pad2 */		{ 0 },
-/* palette size */	0,
-/* ..etc */		0, 0 };
-
 
 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 */
+static int horz_size;     /* horz. size of screen in millimeters */
+static int vert_size;     /* vert. size of screen in millimeters */
+static int palette_size;
+static int text_caps;
+
 /**********************************************************************
  *	     X11DRV_GDI_Initialize
  */
@@ -76,39 +62,20 @@
     BITMAP_Driver = &X11DRV_BITMAP_Driver;
     PALETTE_Driver = &X11DRV_PALETTE_Driver;
 
-    /* FIXME: colormap management should be merged with the X11DRV */
-
-    if( !X11DRV_PALETTE_Init() ) return FALSE;
+    palette_size = X11DRV_PALETTE_Init();
 
     if( !X11DRV_OBM_Init() ) return FALSE;
 
-    /* Finish up device caps */
-
-    X11DRV_DevCaps.version   = 0x300;
-    X11DRV_DevCaps.horzSize  = WidthMMOfScreen(screen) * screen_width / WidthOfScreen(screen);
-    X11DRV_DevCaps.vertSize  = HeightMMOfScreen(screen) * screen_height / HeightOfScreen(screen);
-    X11DRV_DevCaps.horzRes   = screen_width;
-    X11DRV_DevCaps.vertRes   = screen_height;
-    X11DRV_DevCaps.bitsPixel = screen_depth;
-
-    /* MSDN: Number of entries in the device's color table, if the device has
-     * a color depth of no more than 8 bits per pixel.For devices with greater
-     * color depths, -1 is returned.
-     */
-    X11DRV_DevCaps.numColors = (screen_depth>8)?-1:(1<<screen_depth);
- 
-    /* Resolution will be adjusted during the font init */
-
-    X11DRV_DevCaps.logPixelsX = (int)(X11DRV_DevCaps.horzRes * 25.4 / X11DRV_DevCaps.horzSize);
-    X11DRV_DevCaps.logPixelsY = (int)(X11DRV_DevCaps.vertRes * 25.4 / X11DRV_DevCaps.vertSize);
-
-    /* Create default bitmap */
-
     if (!X11DRV_BITMAP_Init()) return FALSE;
 
     /* Initialize fonts and text caps */
 
-    return X11DRV_FONT_Init( &X11DRV_DevCaps );
+    log_pixels_x = MulDiv( WidthOfScreen(screen), 254, WidthMMOfScreen(screen) * 10 );
+    log_pixels_y = MulDiv( HeightOfScreen(screen), 254, HeightMMOfScreen(screen) * 10 );
+    text_caps = X11DRV_FONT_Init( &log_pixels_x, &log_pixels_y );
+    horz_size = MulDiv( screen_width, 254, log_pixels_x * 10 );
+    vert_size = MulDiv( screen_height, 254, log_pixels_y * 10 );
+    return TRUE;
 }
 
 /**********************************************************************
@@ -138,7 +105,6 @@
 	return FALSE;
     }
 
-    dc->devCaps      = &X11DRV_DevCaps;
     if (dc->flags & DC_MEMORY)
     {
         BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC );
@@ -203,6 +169,99 @@
     return TRUE;
 }
 
+
+/***********************************************************************
+ *           GetDeviceCaps    (X11DRV.@)
+ */
+INT X11DRV_GetDeviceCaps( DC *dc, INT cap )
+{
+    switch(cap)
+    {
+    case DRIVERVERSION:
+        return 0x300;
+    case TECHNOLOGY:
+        return DT_RASDISPLAY;
+    case HORZSIZE:
+        return horz_size;
+    case VERTSIZE:
+        return vert_size;
+    case HORZRES:
+        return screen_width;
+    case VERTRES:
+        return screen_height;
+    case BITSPIXEL:
+        return screen_depth;
+    case PLANES:
+        return 1;
+    case NUMBRUSHES:
+        return -1;
+    case NUMPENS:
+        return -1;
+    case NUMMARKERS:
+        return 0;
+    case NUMFONTS:
+        return 0;
+    case NUMCOLORS:
+        /* MSDN: Number of entries in the device's color table, if the device has
+         * a color depth of no more than 8 bits per pixel.For devices with greater
+         * color depths, -1 is returned. */
+        return (screen_depth > 8) ? -1 : (1 << screen_depth);
+    case PDEVICESIZE:
+        return sizeof(X11DRV_PDEVICE);
+    case CURVECAPS:
+        return (CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES | CC_WIDE |
+                CC_STYLED | CC_WIDESTYLED | CC_INTERIORS | CC_ROUNDRECT);
+    case LINECAPS:
+        return (LC_POLYLINE | LC_MARKER | LC_POLYMARKER | LC_WIDE |
+                LC_STYLED | LC_WIDESTYLED | LC_INTERIORS);
+    case POLYGONALCAPS:
+        return (PC_POLYGON | PC_RECTANGLE | PC_WINDPOLYGON | PC_SCANLINE |
+                PC_WIDE | PC_STYLED | PC_WIDESTYLED | PC_INTERIORS);
+    case TEXTCAPS:
+        return text_caps;
+    case CLIPCAPS:
+        return CP_REGION;
+    case RASTERCAPS:
+        return (RC_BITBLT | RC_BANDING | RC_SCALING | RC_BITMAP64 | RC_DI_BITMAP |
+                RC_DIBTODEV | RC_BIGFONT | RC_STRETCHBLT | RC_STRETCHDIB | RC_DEVBITS |
+                (palette_size ? RC_PALETTE : 0));
+    case ASPECTX:
+    case ASPECTY:
+        return 36;
+    case ASPECTXY:
+        return 51;
+    case LOGPIXELSX:
+        return log_pixels_x;
+    case LOGPIXELSY:
+        return log_pixels_y;
+    case CAPS1:
+        FIXME("(%04x): CAPS1 is unimplemented, will return 0\n", dc->hSelf );
+        /* please see wingdi.h for the possible bit-flag values that need
+           to be returned. also, see 
+           http://msdn.microsoft.com/library/ddkdoc/win95ddk/graphcnt_1m0p.htm */
+        return 0;
+    case SIZEPALETTE:
+        return palette_size;
+    case NUMRESERVED:
+    case COLORRES:
+    case PHYSICALWIDTH:
+    case PHYSICALHEIGHT:
+    case PHYSICALOFFSETX:
+    case PHYSICALOFFSETY:
+    case SCALINGFACTORX:
+    case SCALINGFACTORY:
+    case VREFRESH:
+    case DESKTOPVERTRES:
+    case DESKTOPHORZRES:
+    case BTLALIGNMENT:
+        return 0;
+    default:
+        FIXME("(%04x): unsupported capability %d, will return 0\n", dc->hSelf, cap );
+        return 0;
+    }
+}
+
+
 /**********************************************************************
  *           X11DRV_Escape
  */
diff --git a/graphics/x11drv/palette.c b/graphics/x11drv/palette.c
index 40fc866..f8cdcbe 100644
--- a/graphics/x11drv/palette.c
+++ b/graphics/x11drv/palette.c
@@ -58,6 +58,8 @@
 static int X11DRV_PALETTE_Bluemax    = 0;
 static int X11DRV_PALETTE_Graymax    = 0;
 
+static int palette_size;
+
 /* First free dynamic color cell, 0 = full palette, -1 = fixed palette */
 static int           X11DRV_PALETTE_firstFree = 0; 
 static unsigned char X11DRV_PALETTE_freeList[256];
@@ -94,7 +96,7 @@
  *
  * Initialize color management.
  */
-BOOL X11DRV_PALETTE_Init(void)
+int X11DRV_PALETTE_Init(void)
 {
     int	mask, white, black;
     int monoPlane;
@@ -107,7 +109,7 @@
     for( mask = 1; !((white & mask)^(black & mask)); mask <<= 1 )
 	 monoPlane++;
     X11DRV_PALETTE_PaletteFlags = (white & mask) ? X11DRV_PALETTE_WHITESET : 0;
-    X11DRV_DevCaps.sizePalette = visual->map_entries;
+    palette_size = visual->map_entries;
 
     switch(visual->class)
     {
@@ -141,7 +143,7 @@
 	        X11DRV_PALETTE_PaletteFlags |= (X11DRV_PALETTE_PRIVATE | X11DRV_PALETTE_WHITESET);
 
 		monoPlane = 1;
-		for( white = X11DRV_DevCaps.sizePalette - 1; !(white & 1); white >>= 1 )
+		for( white = palette_size - 1; !(white & 1); white >>= 1 )
 		     monoPlane++;
 
 	        if( root_window != DefaultRootWindow(gdi_display) )
@@ -174,7 +176,7 @@
 	depths=TSXListDepths(gdi_display,DefaultScreen(gdi_display),&nrofdepths);
 	if ((nrofdepths==2) && ((depths[0]==4) || depths[1]==4)) {
 	    monoPlane = 1;
-	    for( white = X11DRV_DevCaps.sizePalette - 1; !(white & 1); white >>= 1 )
+	    for( white = palette_size - 1; !(white & 1); white >>= 1 )
 	        monoPlane++;
     	    X11DRV_PALETTE_PaletteFlags = (white & mask) ? X11DRV_PALETTE_WHITESET : 0;
             X11DRV_PALETTE_PaletteXColormap = TSXCreateColormap(gdi_display, root_window,
@@ -210,14 +212,11 @@
     X11DRV_PALETTE_FillDefaultColors();
 
     if( X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_VIRTUAL ) 
-	X11DRV_DevCaps.sizePalette = 0;
+        palette_size = 0;
     else
-    {
-	X11DRV_DevCaps.rasterCaps |= RC_PALETTE;
-	X11DRV_DevCaps.sizePalette = visual->map_entries;
-    }
+        palette_size = visual->map_entries;
 
-    return TRUE;
+    return palette_size;
 }
 
 /***********************************************************************
@@ -268,16 +267,16 @@
     XColor color;
     int i; 
 
-    if((COLOR_sysPal = (PALETTEENTRY*)HeapAlloc(GetProcessHeap(), 0, sizeof(PALETTEENTRY)*X11DRV_DevCaps.sizePalette)) == NULL) {
+    if((COLOR_sysPal = (PALETTEENTRY*)HeapAlloc(GetProcessHeap(), 0, sizeof(PALETTEENTRY)*palette_size)) == NULL) {
         WARN("Can not allocate system palette\n");
         return FALSE;
     }
 
-    TRACE("Building private map - %i palette entries\n", X11DRV_DevCaps.sizePalette);
+    TRACE("Building private map - %i palette entries\n", palette_size);
 
       /* Allocate system palette colors */ 
 
-    for( i=0; i < X11DRV_DevCaps.sizePalette; i++ )
+    for( i=0; i < palette_size; i++ )
     {
        if( i < NB_RESERVED_COLORS/2 )
        {
@@ -286,9 +285,9 @@
          color.blue  = COLOR_sysPalTemplate[i].peBlue * 65535 / 255;
 	 COLOR_sysPal[i] = COLOR_sysPalTemplate[i];
        }
-       else if( i >= X11DRV_DevCaps.sizePalette - NB_RESERVED_COLORS/2 )
+       else if( i >= palette_size - NB_RESERVED_COLORS/2 )
        {
-	 int j = NB_RESERVED_COLORS + i - X11DRV_DevCaps.sizePalette;
+	 int j = NB_RESERVED_COLORS + i - palette_size;
          color.red   = COLOR_sysPalTemplate[j].peRed * 65535 / 255;
          color.green = COLOR_sysPalTemplate[j].peGreen * 65535 / 255;
          color.blue  = COLOR_sysPalTemplate[j].peBlue * 65535 / 255;
@@ -303,15 +302,15 @@
 
        if (i < 8)
            X11DRV_PALETTE_mapEGAPixel[i] = color.pixel;
-       else if (i >= X11DRV_DevCaps.sizePalette - 8 )
-           X11DRV_PALETTE_mapEGAPixel[i - (X11DRV_DevCaps.sizePalette - 16)] = color.pixel;
+       else if (i >= palette_size - 8 )
+           X11DRV_PALETTE_mapEGAPixel[i - (palette_size - 16)] = color.pixel;
     }
 
     X11DRV_PALETTE_XPixelToPalette = X11DRV_PALETTE_PaletteToXPixel = NULL;
 
     COLOR_gapStart = 256; COLOR_gapEnd = -1;
 
-    X11DRV_PALETTE_firstFree = (X11DRV_DevCaps.sizePalette > NB_RESERVED_COLORS)?NB_RESERVED_COLORS/2 : -1;
+    X11DRV_PALETTE_firstFree = (palette_size > NB_RESERVED_COLORS)?NB_RESERVED_COLORS/2 : -1;
 
     return FALSE;
 }
@@ -369,7 +368,7 @@
    else if (COLOR_max < 20) COLOR_max = 20;
    TRACE("%d colors configured.\n", COLOR_max);
 
-   TRACE("Building shared map - %i palette entries\n", X11DRV_DevCaps.sizePalette);
+   TRACE("Building shared map - %i palette entries\n", palette_size);
 
    /* Be nice and allocate system colors as read-only */
 
@@ -439,7 +438,7 @@
 
    if( !(X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_FIXED) )  
      {
-	int c_min = 0, c_max = X11DRV_DevCaps.sizePalette, c_val;
+	int c_min = 0, c_max = palette_size, c_val;
 
 	TRACE("Dynamic colormap... \n");
 
@@ -447,7 +446,7 @@
 	 * X guidelines and does binary search...
 	 */
 
-	if((pixDynMapping = (unsigned long*)HeapAlloc(GetProcessHeap(), 0, sizeof(long)*X11DRV_DevCaps.sizePalette)) == NULL) {
+	if((pixDynMapping = (unsigned long*)HeapAlloc(GetProcessHeap(), 0, sizeof(long)*palette_size)) == NULL) {
 	    WARN("Out of memory while building system palette.\n");
 	    return FALSE;
         }
@@ -482,11 +481,11 @@
 	      c_min = 0;
 	    }
 
-        X11DRV_DevCaps.sizePalette = c_min + NB_RESERVED_COLORS;
+        palette_size = c_min + NB_RESERVED_COLORS;
 
 	TSXUngrabServer(gdi_display);
 
-	TRACE("adjusted size %i colorcells\n", X11DRV_DevCaps.sizePalette);
+	TRACE("adjusted size %i colorcells\n", palette_size);
      }
    else if( X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_VIRTUAL ) 
 	{
@@ -494,23 +493,23 @@
            * color translations but we have to allocate full palette 
 	   * to maintain compatibility
 	   */
-	  X11DRV_DevCaps.sizePalette = 256;
+	  palette_size = 256;
 	  TRACE("Virtual colorspace - screendepth %i\n", screen_depth);
 	}
-   else X11DRV_DevCaps.sizePalette = NB_RESERVED_COLORS;	/* system palette only - however we can alloc a bunch
+   else palette_size = NB_RESERVED_COLORS;	/* system palette only - however we can alloc a bunch
 			                 * of colors and map to them */
 
-   TRACE("Shared system palette uses %i colors.\n", X11DRV_DevCaps.sizePalette);
+   TRACE("Shared system palette uses %i colors.\n", palette_size);
 
    /* set gap to account for pixel shortage. It has to be right in the center
     * of the system palette because otherwise raster ops get screwed. */
 
-   if( X11DRV_DevCaps.sizePalette >= 256 )
+   if( palette_size >= 256 )
      { COLOR_gapStart = 256; COLOR_gapEnd = -1; }
    else
-     { COLOR_gapStart = X11DRV_DevCaps.sizePalette/2; COLOR_gapEnd = 255 - X11DRV_DevCaps.sizePalette/2; }
+     { COLOR_gapStart = palette_size/2; COLOR_gapEnd = 255 - palette_size/2; }
 
-   X11DRV_PALETTE_firstFree = ( X11DRV_DevCaps.sizePalette > NB_RESERVED_COLORS && 
+   X11DRV_PALETTE_firstFree = ( palette_size > NB_RESERVED_COLORS && 
 		      (X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_VIRTUAL || !(X11DRV_PALETTE_PaletteFlags & X11DRV_PALETTE_FIXED)) ) 
 		     ? NB_RESERVED_COLORS/2 : -1;
 
@@ -590,12 +589,12 @@
   int green, no_g, inc_g; 
   int blue, no_b, inc_b;
 
-  if (X11DRV_DevCaps.sizePalette <= NB_RESERVED_COLORS)
+  if (palette_size <= NB_RESERVED_COLORS)
   	return;
-  while (i*i*i < (X11DRV_DevCaps.sizePalette - NB_RESERVED_COLORS)) i++;
+  while (i*i*i < (palette_size - NB_RESERVED_COLORS)) i++;
   no_r = no_g = no_b = --i;
-  if ((no_r * (no_g+1) * no_b) < (X11DRV_DevCaps.sizePalette - NB_RESERVED_COLORS)) no_g++;
-  if ((no_r * no_g * (no_b+1)) < (X11DRV_DevCaps.sizePalette - NB_RESERVED_COLORS)) no_b++;
+  if ((no_r * (no_g+1) * no_b) < (palette_size - NB_RESERVED_COLORS)) no_g++;
+  if ((no_r * no_g * (no_b+1)) < (palette_size - NB_RESERVED_COLORS)) no_b++;
   inc_r = (255 - NB_COLORCUBE_START_INDEX)/no_r;
   inc_g = (255 - NB_COLORCUBE_START_INDEX)/no_g;
   inc_b = (255 - NB_COLORCUBE_START_INDEX)/no_b;
@@ -846,7 +845,7 @@
 static int X11DRV_PALETTE_LookupSystemXPixel(COLORREF col)
 {
  int            i, best = 0, diff = 0x7fffffff;
- int            size = X11DRV_DevCaps.sizePalette;
+ int            size = palette_size;
  int            r,g,b;
 
  for( i = 0; i < size && diff ; i++ )
@@ -1016,7 +1015,7 @@
 {
   int i, index, realized = 0;    
   
-  if (!X11DRV_DevCaps.sizePalette)
+  if (!palette_size)
     return 0;
 
   for( i = 0; i < 20; i++ )
diff --git a/graphics/x11drv/xfont.c b/graphics/x11drv/xfont.c
index 86a56e4..0ba633f 100644
--- a/graphics/x11drv/xfont.c
+++ b/graphics/x11drv/xfont.c
@@ -63,12 +63,10 @@
 
 static fontAlias *aliasTable = NULL;
 
-UINT16			XTextCaps = TC_OP_CHARACTER | TC_OP_STROKE |
-TC_CP_STROKE | TC_CR_ANY |
-				    TC_SA_DOUBLE | TC_SA_INTEGER | TC_SA_CONTIN |
-			 	    TC_UA_ABLE | TC_SO_ABLE | TC_RA_ABLE;
-
-			/* X11R6 adds TC_SF_X_YINDEP, maybe more... */
+static UINT XTextCaps = (TC_OP_CHARACTER | TC_OP_STROKE | TC_CP_STROKE | TC_CR_ANY |
+                         TC_SA_DOUBLE | TC_SA_INTEGER | TC_SA_CONTIN |
+                         TC_UA_ABLE | TC_SO_ABLE | TC_RA_ABLE);
+                         /* X11R6 adds TC_SF_X_YINDEP, maybe more... */
 
 static const char*	INIFontMetrics = "/cachedmetrics.";
 static const char*	INIFontSection = "Software\\Wine\\Wine\\Config\\fonts";
@@ -2300,7 +2298,7 @@
  * XFONT_Match() penalty function. We also load the point
  * resolution value (higher values result in larger fonts).
  */
-static int XFONT_GetPointResolution( DeviceCaps* pDevCaps )
+static int XFONT_GetPointResolution( int *log_pixels_x, int *log_pixels_y )
 {
     int i, j, point_resolution, num = 3; 
     int allowed_xfont_resolutions[3] = { 72, 75, 100 };
@@ -2319,9 +2317,9 @@
     }
 
     if( !point_resolution )
-	point_resolution = pDevCaps->logPixelsY;
+        point_resolution = *log_pixels_y;
     else
-	pDevCaps->logPixelsX = pDevCaps->logPixelsY = point_resolution;
+        *log_pixels_x = *log_pixels_y = point_resolution;
 
 
     /* FIXME We can only really guess at a best DefResolution
@@ -2337,18 +2335,6 @@
 	}
     }
     DefResolution = allowed_xfont_resolutions[best];
-
-    /* FIXME - do win95,nt40,... do this as well ? */
-    if (TWEAK_WineLook == WIN98_LOOK)
-    {
-	/* Lie about the screen size, so that eg MM_LOMETRIC becomes MM_logical_LOMETRIC */
-	int denom;
-	denom = pDevCaps->logPixelsX * 10;
-	pDevCaps->horzSize = (pDevCaps->horzRes * 254 + (denom>>1)) / denom;
-	denom = pDevCaps->logPixelsY * 10;
-	pDevCaps->vertSize = (pDevCaps->vertRes * 254 + (denom>>1)) / denom;
-    }
-
     return point_resolution;
 }
 
@@ -2784,7 +2770,7 @@
  *
  * Initialize font resource list and allocate font cache.
  */
-BOOL X11DRV_FONT_Init( DeviceCaps* pDevCaps )
+int X11DRV_FONT_Init( int *log_pixels_x, int *log_pixels_y )
 {
   char**    x_pattern;
   unsigned  x_checksum;
@@ -2792,7 +2778,7 @@
   char      *buffer;
   HKEY hkey;
 
-  res = XFONT_GetPointResolution( pDevCaps );
+  res = XFONT_GetPointResolution( log_pixels_x, log_pixels_y );
       
   x_pattern = TSXListFonts(gdi_display, "*", MAX_FONTS, &x_count );
 
@@ -2883,12 +2869,9 @@
 
   /* update text caps parameter */
 
-  pDevCaps->textCaps = XTextCaps;
-
   RAW_ASCENT  = TSXInternAtom(gdi_display, "RAW_ASCENT", TRUE);
   RAW_DESCENT = TSXInternAtom(gdi_display, "RAW_DESCENT", TRUE);
-  
-  return TRUE;
+  return XTextCaps;
 }
 
 /**********************************************************************
@@ -3158,7 +3141,7 @@
 	    lf.lfHeight = MIN_FONT_SIZE;
     }
     else
-	lf.lfHeight = -(DEF_POINT_SIZE * dc->devCaps->logPixelsY + (72>>1)) / 72;
+	lf.lfHeight = -(DEF_POINT_SIZE * GetDeviceCaps(dc->hSelf,LOGPIXELSY) + (72>>1)) / 72;
     
     {
 	/* Fixup aliases before passing to RealizeFont */
diff --git a/include/gdi.h b/include/gdi.h
index b18917f..1b9fba3 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -48,40 +48,6 @@
 } GDIOBJHDR;
 
 
-typedef struct tagDeviceCaps
-{
-    WORD   version;       /*   0: driver version */
-    WORD   technology;    /*   2: device technology */
-    WORD   horzSize;      /*   4: width of display in mm */
-    WORD   vertSize;      /*   6: height of display in mm */
-    WORD   horzRes;       /*   8: width of display in pixels */
-    WORD   vertRes;       /*  10: width of display in pixels */
-    WORD   bitsPixel;     /*  12: bits per pixel */
-    WORD   planes;        /*  14: color planes */
-    WORD   numBrushes;    /*  16: device-specific brushes */
-    WORD   numPens;       /*  18: device-specific pens */
-    WORD   numMarkers;    /*  20: device-specific markers */
-    WORD   numFonts;      /*  22: device-specific fonts */
-    WORD   numColors;     /*  24: size of color table */
-    WORD   pdeviceSize;   /*  26: size of PDEVICE structure */
-    WORD   curveCaps;     /*  28: curve capabilities */
-    WORD   lineCaps;      /*  30: line capabilities */
-    WORD   polygonalCaps; /*  32: polygon capabilities */
-    WORD   textCaps;      /*  34: text capabilities */
-    WORD   clipCaps;      /*  36: clipping capabilities */
-    WORD   rasterCaps;    /*  38: raster capabilities */
-    WORD   aspectX;       /*  40: relative width of device pixel */
-    WORD   aspectY;       /*  42: relative height of device pixel */
-    WORD   aspectXY;      /*  44: relative diagonal width of device pixel */
-    WORD   pad1[21];      /*  46-86: reserved */
-    WORD   logPixelsX;    /*  88: pixels / logical X inch */
-    WORD   logPixelsY;    /*  90: pixels / logical Y inch */
-    WORD   pad2[6];       /*  92-102: reserved */
-    WORD   sizePalette;   /* 104: entries in system palette */
-    WORD   numReserved;   /* 106: reserved entries */
-    WORD   colorRes;      /* 108: color resolution */    
-} DeviceCaps;
-
 typedef BOOL16 CALLBACK (*DCHOOKPROC)(HDC16,WORD,DWORD,LPARAM);
 
 typedef struct tagDC
@@ -105,8 +71,6 @@
     INT          vportExtY;
 
     int           flags;
-    const DeviceCaps *devCaps;
-
     HRGN16        hClipRgn;     /* Clip region (may be 0) */
     HRGN16        hVisRgn;      /* Visible region (must never be 0) */
     HRGN16        hGCClipRgn;   /* GC clip region (ClipRgn AND VisRgn) */
@@ -197,6 +161,7 @@
     BOOL     (*pFrameRgn)(DC*,HRGN,HBRUSH,INT,INT);
     BOOL     (*pGetCharWidth)(DC*,UINT,UINT,LPINT);
     BOOL     (*pGetDCOrgEx)(DC*,LPPOINT);
+    INT      (*pGetDeviceCaps)(DC*,INT);
     BOOL     (*pGetDeviceGammaRamp)(DC*,LPVOID);
     COLORREF (*pGetPixel)(DC*,INT,INT);
     INT      (*pGetPixelFormat)(DC*);
diff --git a/include/win16drv.h b/include/win16drv.h
index 96f00bc..18c661f 100644
--- a/include/win16drv.h
+++ b/include/win16drv.h
@@ -146,6 +146,40 @@
 #define DRVOBJ_FONT 	3   
 #define DRVOBJ_PBITMAP 	5
 
+typedef struct tagDeviceCaps
+{
+    WORD   version;       /*   0: driver version */
+    WORD   technology;    /*   2: device technology */
+    WORD   horzSize;      /*   4: width of display in mm */
+    WORD   vertSize;      /*   6: height of display in mm */
+    WORD   horzRes;       /*   8: width of display in pixels */
+    WORD   vertRes;       /*  10: width of display in pixels */
+    WORD   bitsPixel;     /*  12: bits per pixel */
+    WORD   planes;        /*  14: color planes */
+    WORD   numBrushes;    /*  16: device-specific brushes */
+    WORD   numPens;       /*  18: device-specific pens */
+    WORD   numMarkers;    /*  20: device-specific markers */
+    WORD   numFonts;      /*  22: device-specific fonts */
+    WORD   numColors;     /*  24: size of color table */
+    WORD   pdeviceSize;   /*  26: size of PDEVICE structure */
+    WORD   curveCaps;     /*  28: curve capabilities */
+    WORD   lineCaps;      /*  30: line capabilities */
+    WORD   polygonalCaps; /*  32: polygon capabilities */
+    WORD   textCaps;      /*  34: text capabilities */
+    WORD   clipCaps;      /*  36: clipping capabilities */
+    WORD   rasterCaps;    /*  38: raster capabilities */
+    WORD   aspectX;       /*  40: relative width of device pixel */
+    WORD   aspectY;       /*  42: relative height of device pixel */
+    WORD   aspectXY;      /*  44: relative diagonal width of device pixel */
+    WORD   pad1[21];      /*  46-86: reserved */
+    WORD   logPixelsX;    /*  88: pixels / logical X inch */
+    WORD   logPixelsY;    /*  90: pixels / logical Y inch */
+    WORD   pad2[6];       /*  92-102: reserved */
+    WORD   sizePalette;   /* 104: entries in system palette */
+    WORD   numReserved;   /* 106: reserved entries */
+    WORD   colorRes;      /* 108: color resolution */
+} DeviceCaps;
+
 /* Win16 printer driver physical DC */
 typedef struct
 {
@@ -155,6 +189,7 @@
     LPFONTINFO16       	FontInfo;       /* Current font realized by printer driver */
     LPLOGBRUSH16	BrushInfo;      /* Current brush realized by printer driver */
     LPLOGPEN16		PenInfo;        /* Current pen realized by printer driver */
+    DeviceCaps          DevCaps;        /* Device caps */
 } WIN16DRV_PDEVICE;
 
 /*
diff --git a/include/x11drv.h b/include/x11drv.h
index a0a7793..ff56429 100644
--- a/include/x11drv.h
+++ b/include/x11drv.h
@@ -81,8 +81,6 @@
 #define BITMAP_GC(bmp) \
   (((bmp)->bitmap.bmBitsPixel == 1) ? BITMAP_monoGC : BITMAP_colorGC)
 
-extern DeviceCaps X11DRV_DevCaps;
-
 extern unsigned int X11DRV_server_startticks;
 
 /* Wine driver X11 functions */
@@ -169,7 +167,7 @@
 /* X11 driver internal functions */
 
 extern BOOL X11DRV_BITMAP_Init(void);
-extern BOOL X11DRV_FONT_Init( struct tagDeviceCaps* );
+extern int X11DRV_FONT_Init( int *log_pixels_x, int *log_pixels_y );
 extern BOOL X11DRV_OBM_Init(void);
 
 struct tagBITMAPOBJ;
@@ -285,7 +283,7 @@
 
 extern int X11DRV_PALETTE_mapEGAPixel[16];
 
-extern BOOL X11DRV_PALETTE_Init(void);
+extern int X11DRV_PALETTE_Init(void);
 extern void X11DRV_PALETTE_Cleanup(void);
 
 extern COLORREF X11DRV_PALETTE_ToLogical(int pixel);
diff --git a/objects/dc.c b/objects/dc.c
index a85ab42..56b353d 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -48,7 +48,6 @@
     dc->vportExtX           = 1;
     dc->vportExtY           = 1;
     dc->flags               = 0;
-    dc->devCaps             = NULL;
     dc->hClipRgn            = 0;
     dc->hVisRgn             = 0;
     dc->hGCClipRgn          = 0;
@@ -247,7 +246,6 @@
     TRACE("(%04x): returning %04x\n", hdc, handle );
 
     newdc->flags            = dc->flags | DC_SAVED;
-    newdc->devCaps          = dc->devCaps;
     newdc->hPen             = dc->hPen;       
     newdc->hBrush           = dc->hBrush;     
     newdc->hFont            = dc->hFont;      
@@ -341,7 +339,6 @@
     TRACE("%04x %04x\n", hdc, hdcs );
 
     dc->flags            = dcs->flags & ~DC_SAVED;
-    dc->devCaps          = dcs->devCaps;
     dc->hDevice          = dcs->hDevice;
     dc->totalExtent      = dcs->totalExtent;
     dc->ROPmode          = dcs->ROPmode;
@@ -816,61 +813,12 @@
 {
     DC *dc;
     INT ret = 0;
-    POINT pt;
 
-    /* Device capabilities for the printer */
-    switch (cap)
+    if ((dc = DC_GetDCPtr( hdc )))
     {
-    case PHYSICALWIDTH:
-        if(Escape(hdc, GETPHYSPAGESIZE, 0, NULL, (LPVOID)&pt) > 0) ret = pt.x;
-        break;
-    case PHYSICALHEIGHT:
-        if(Escape(hdc, GETPHYSPAGESIZE, 0, NULL, (LPVOID)&pt) > 0) ret = pt.y;
-        break;
-    case PHYSICALOFFSETX:
-        if(Escape(hdc, GETPRINTINGOFFSET, 0, NULL, (LPVOID)&pt) > 0) ret = pt.x;
-        break;
-    case PHYSICALOFFSETY:
-        if(Escape(hdc, GETPRINTINGOFFSET, 0, NULL, (LPVOID)&pt) > 0) ret = pt.y;
-        break;
-    case SCALINGFACTORX:
-        if(Escape(hdc, GETSCALINGFACTOR, 0, NULL, (LPVOID)&pt) > 0) ret = pt.x;
-        break;
-    case SCALINGFACTORY:
-        if(Escape(hdc, GETSCALINGFACTOR, 0, NULL, (LPVOID)&pt) > 0) ret = pt.y;
-        break;
-    case CAPS1:
-        FIXME("(%04x,%d): DeviceCaps param CAPS1 is UNIMPLEMENTED, will yield 0!\n",
-                  hdc,cap );
-
-        /* please see wingdi.h for the possible bit-flag values that need
-           to be returned.
-
-           also, see 
-           http://msdn.microsoft.com/library/ddkdoc/win95ddk/graphcnt_1m0p.htm
-
-           the fall-through to 'default' is on purpose */
-
-
-    default:
-        if ((cap < 0) || (cap > sizeof(DeviceCaps)-sizeof(WORD))) break;
-
-        if (((cap>=46) && (cap<88)) || ((cap>=92) && (cap<104)))
-            FIXME("(%04x,%d): unsupported DeviceCaps capability, will yield 0!\n",
-                  hdc,cap );
-        if ((dc = DC_GetDCPtr( hdc )))
-        {
-            if (dc->devCaps)
-            {
-                ret = *(WORD *)(((char *)dc->devCaps) + cap);
-                if ((cap == NUMCOLORS) && (ret == 0xffff)) ret = -1;
-            }
-            GDI_ReleaseObj( hdc );
-        }
-        break;
+        if (dc->funcs->pGetDeviceCaps) ret = dc->funcs->pGetDeviceCaps( dc, cap );
+        GDI_ReleaseObj( hdc );
     }
-
-    TRACE("(%04x,%d): returning %d\n", hdc, cap, ret );
     return ret;
 }
 
diff --git a/objects/palette.c b/objects/palette.c
index c16514c..fa56997 100644
--- a/objects/palette.c
+++ b/objects/palette.c
@@ -478,26 +478,14 @@
     LPPALETTEENTRY entries) /* [out] Array receiving system-palette entries */
 {
     UINT i;
-    DC *dc;
+    INT sizePalette = GetDeviceCaps( hdc, SIZEPALETTE );
 
     TRACE("hdc=%04x,start=%i,count=%i\n", hdc,start,count);
 
-    if (!(dc = DC_GetDCPtr( hdc ))) return 0;
+    if (!entries) return sizePalette;
+    if (start >= sizePalette) return 0;
+    if (start+count >= sizePalette) count = sizePalette - start;
 
-    if (!entries)
-    {
-	count = dc->devCaps->sizePalette;
-        goto done;
-    }
-
-    if (start >= dc->devCaps->sizePalette)
-      {
-	count = 0;
-        goto done;
-      }
-
-    if (start+count >= dc->devCaps->sizePalette)
-	count = dc->devCaps->sizePalette - start;
     for (i = 0; i < count; i++)
     {
 	*(COLORREF*)(entries + i) = COLOR_GetSystemPaletteEntry( start + i );
@@ -505,8 +493,6 @@
         TRACE("\tidx(%02x) -> RGB(%08lx)\n",
                          start + i, *(COLORREF*)(entries + i) );
     }
- done:
-    GDI_ReleaseObj( hdc );
     return count;
 }
 
@@ -788,12 +774,9 @@
     HDC hDC) /* [in] Handle of device context */
 {
     HMODULE mod;
-    DC *dc;
-    int size;
+    int size = GetDeviceCaps( hDC, SIZEPALETTE );
 
-    if (!(dc = DC_GetDCPtr( hDC ))) return 0;
-    size = dc->devCaps->sizePalette;
-    GDI_ReleaseObj( hDC );
+    if (!size) return 0;
 
     mod = GetModuleHandleA("user32.dll");
     if (mod)