Moved DC origin into device-specific structure.
Fixed handling of DC origin in X11 driver.

diff --git a/dlls/gdi/driver.c b/dlls/gdi/driver.c
index 20b33b1..ea03910 100644
--- a/dlls/gdi/driver.c
+++ b/dlls/gdi/driver.c
@@ -143,6 +143,7 @@
     GET_FUNC(SetBitmapBits);
     GET_FUNC(SetBkColor);
     GET_FUNC(SetBkMode);
+    GET_FUNC(SetDCOrg);
     GET_FUNC(SetDIBColorTable);
     GET_FUNC(SetDIBits);
     GET_FUNC(SetDIBitsToDevice);
diff --git a/dlls/gdi/enhmfdrv/init.c b/dlls/gdi/enhmfdrv/init.c
index 84249df..dac3027 100644
--- a/dlls/gdi/enhmfdrv/init.c
+++ b/dlls/gdi/enhmfdrv/init.c
@@ -111,6 +111,7 @@
     NULL,                            /* pSetBitmapBits */
     EMFDRV_SetBkColor,               /* pSetBkColor */
     EMFDRV_SetBkMode,                /* pSetBkMode */
+    NULL,                            /* pSetDCOrg */
     NULL,                            /* pSetDIBColorTable */
     NULL,                            /* pSetDIBits */
     NULL,                            /* pSetDIBitsToDevice */
diff --git a/dlls/gdi/mfdrv/init.c b/dlls/gdi/mfdrv/init.c
index e2457b9..b67d505 100644
--- a/dlls/gdi/mfdrv/init.c
+++ b/dlls/gdi/mfdrv/init.c
@@ -111,6 +111,7 @@
     NULL,                            /* pSetBitmapBits */
     MFDRV_SetBkColor,                /* pSetBkColor */
     MFDRV_SetBkMode,                 /* pSetBkMode */
+    NULL,                            /* pSetDCOrg */
     NULL,                            /* pSetDIBColorTable */
     NULL,                            /* pSetDIBits */
     MFDRV_SetDIBitsToDevice,         /* pSetDIBitsToDevice */
diff --git a/dlls/gdi/win16drv/graphics.c b/dlls/gdi/win16drv/graphics.c
index f3dd7d9..321c48f 100644
--- a/dlls/gdi/win16drv/graphics.c
+++ b/dlls/gdi/win16drv/graphics.c
@@ -36,10 +36,10 @@
     DC *dc = physDev->dc;
     POINT16 points[2];
 
-    points[0].x = dc->DCOrgX + XLPTODP( dc, dc->CursPosX );
-    points[0].y = dc->DCOrgY + YLPTODP( dc, dc->CursPosY );
-    points[1].x = dc->DCOrgX + XLPTODP( dc, x );
-    points[1].y = dc->DCOrgY + YLPTODP( dc, y );
+    points[0].x = physDev->org.x + XLPTODP( dc, dc->CursPosX );
+    points[0].y = physDev->org.y + YLPTODP( dc, dc->CursPosY );
+    points[1].x = physDev->org.x + XLPTODP( dc, x );
+    points[1].y = physDev->org.y + YLPTODP( dc, y );
     bRet = PRTDRV_Output(physDev->segptrPDEVICE,
                          OS_POLYLINE, 2, points,
                          physDev->PenInfo,
@@ -63,8 +63,8 @@
     BOOL bRet = 0;
     POINT16 points[2];
 
-    TRACE("In WIN16DRV_Rectangle, x %d y %d DCOrgX %d y %d\n",
-           left, top, dc->DCOrgX, dc->DCOrgY);
+    TRACE("In WIN16DRV_Rectangle, x %d y %d DCOrgX %ld y %ld\n",
+           left, top, physDev->org.x, physDev->org.y);
     TRACE("In WIN16DRV_Rectangle, VPortOrgX %d y %d\n",
            dc->vportOrgX, dc->vportOrgY);
     points[0].x = XLPTODP(dc, left);
@@ -163,7 +163,8 @@
     BOOL bRet = 0;
     POINT16 points[2];
 
-    TRACE("In WIN16DRV_Ellipse, x %d y %d DCOrgX %d y %d\n", left, top, dc->DCOrgX, dc->DCOrgY);
+    TRACE("In WIN16DRV_Ellipse, x %d y %d DCOrgX %ld y %ld\n",
+          left, top, physDev->org.x, physDev->org.y);
     TRACE("In WIN16DRV_Ellipse, VPortOrgX %d y %d\n", dc->vportOrgX, dc->vportOrgY);
     points[0].x = XLPTODP(dc, left);
     points[0].y = YLPTODP(dc, top);
@@ -178,11 +179,3 @@
                          win16drv_SegPtr_DrawMode, dc->hClipRgn);
     return bRet;
 }
-
-
-
-
-
-
-
-
diff --git a/dlls/gdi/win16drv/init.c b/dlls/gdi/win16drv/init.c
index cb6c39d..225512f 100644
--- a/dlls/gdi/win16drv/init.c
+++ b/dlls/gdi/win16drv/init.c
@@ -50,7 +50,7 @@
 LPDRAWMODE 	win16drv_DrawModeP;
 
 
-static BOOL WIN16DRV_CreateDC( DC *dc, LPCSTR driver, LPCSTR device,
+static BOOL WIN16DRV_CreateDC( DC *dc, PHYSDEV *pdev, LPCSTR driver, LPCSTR device,
                                  LPCSTR output, const DEVMODEA* initData );
 static INT WIN16DRV_GetDeviceCaps( PHYSDEV dev, INT cap );
 static INT WIN16DRV_ExtEscape( PHYSDEV dev, INT escape, INT in_count, LPCVOID in_data,
@@ -139,6 +139,7 @@
     NULL,                            /* pSetBitmapBits */
     NULL,                            /* pSetBkColor */
     NULL,                            /* pSetBkMode */
+    NULL,                            /* pSetDCOrg */
     NULL,                            /* pSetDIBColorTable */
     NULL,                            /* pSetDIBits */
     NULL,                            /* pSetDIBitsToDevice */
@@ -240,8 +241,8 @@
     lpDrawMode->eMiterLimit     = 1;
 }
 
-BOOL WIN16DRV_CreateDC( DC *dc, LPCSTR driver, LPCSTR device, LPCSTR output,
-                          const DEVMODEA* initData )
+BOOL WIN16DRV_CreateDC( DC *dc, PHYSDEV *pdev, LPCSTR driver, LPCSTR device, LPCSTR output,
+                        const DEVMODEA* initData )
 {
     LOADED_PRINTER_DRIVER *pLPD;
     WORD wRet;
@@ -254,9 +255,10 @@
 
     physDev = (WIN16DRV_PDEVICE *)HeapAlloc( GetProcessHeap(), 0, sizeof(*physDev) );
     if (!physDev) return FALSE;
-    dc->physDev = (PHYSDEV)physDev;
+    *pdev = (PHYSDEV)physDev;
     physDev->hdc = dc->hSelf;
     physDev->dc = dc;
+    physDev->org.x = physDev->org.y = 0;
 
     pLPD = LoadPrinterDriver(driver);
     if (pLPD == NULL)
diff --git a/dlls/gdi/win16drv/win16drv.h b/dlls/gdi/win16drv/win16drv.h
index 6880a76..26aa201 100644
--- a/dlls/gdi/win16drv/win16drv.h
+++ b/dlls/gdi/win16drv/win16drv.h
@@ -207,6 +207,7 @@
     LPLOGPEN16		PenInfo;        /* Current pen realized by printer driver */
     HDC                 hdc;
     DC                 *dc;
+    POINT               org;            /* Device origin */
     DeviceCaps          DevCaps;        /* Device caps */
 } WIN16DRV_PDEVICE;
 
@@ -300,4 +301,3 @@
 extern LPDRAWMODE 	win16drv_DrawModeP;
 
 #endif  /* __WINE_WIN16DRV_H */
-
diff --git a/dlls/ttydrv/dc.c b/dlls/ttydrv/dc.c
index 95f9efd..6b17ad2 100644
--- a/dlls/ttydrv/dc.c
+++ b/dlls/ttydrv/dc.c
@@ -39,7 +39,7 @@
 /***********************************************************************
  *	     TTYDRV_DC_CreateDC
  */
-BOOL TTYDRV_DC_CreateDC(DC *dc, LPCSTR driver, LPCSTR device,
+BOOL TTYDRV_DC_CreateDC(DC *dc, TTYDRV_PDEVICE **pdev, LPCSTR driver, LPCSTR device,
 			LPCSTR output, const DEVMODEA *initData)
 {
   TTYDRV_PDEVICE *physDev;
@@ -48,15 +48,14 @@
     dc, debugstr_a(driver), debugstr_a(device),
     debugstr_a(output), initData);
 
-  dc->physDev = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
-			  sizeof(TTYDRV_PDEVICE));
-  if(!dc->physDev) {
+  physDev = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TTYDRV_PDEVICE));
+  if(!physDev) {
     ERR("Can't allocate physDev\n");
     return FALSE;
   }
-  physDev = (TTYDRV_PDEVICE *) dc->physDev;
+  *pdev = physDev;
   physDev->hdc = dc->hSelf;
-  physDev->dc = dc;
+  physDev->org.x = physDev->org.y = 0;
 
   if(dc->flags & DC_MEMORY){
     physDev->window = NULL;
@@ -80,7 +79,6 @@
 {
     TRACE("(%x)\n", physDev->hdc);
 
-    physDev->dc->physDev = NULL;
     HeapFree( GetProcessHeap(), 0, physDev );
     return TRUE;
 }
@@ -167,3 +165,25 @@
         return 0;
     }
 }
+
+
+/***********************************************************************
+ *           GetDCOrgEx    (TTYDRV.@)
+ */
+BOOL TTYDRV_GetDCOrgEx( TTYDRV_PDEVICE *physDev, LPPOINT pt )
+{
+    *pt = physDev->org;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           SetDCOrg    (TTYDRV.@)
+ */
+DWORD TTYDRV_SetDCOrg( TTYDRV_PDEVICE *physDev, INT x, INT y )
+{
+    DWORD ret = MAKELONG( physDev->org.x, physDev->org.y );
+    physDev->org.x = x;
+    physDev->org.y = y;
+    return ret;
+}
diff --git a/dlls/ttydrv/graphics.c b/dlls/ttydrv/graphics.c
index afe08d4..9f60694 100644
--- a/dlls/ttydrv/graphics.c
+++ b/dlls/ttydrv/graphics.c
@@ -84,17 +84,22 @@
 {
 #ifdef WINE_CURSES
   INT row1, col1, row2, col2;
-  DC *dc = physDev->dc;
+  POINT pt[2];
 
   TRACE("(%x, %d, %d)\n", physDev->hdc, x, y);
 
   if(!physDev->window)
     return FALSE;
 
-  row1 = (dc->DCOrgY + XLPTODP(dc, dc->CursPosY)) / physDev->cellHeight;
-  col1 = (dc->DCOrgX + XLPTODP(dc, dc->CursPosX)) / physDev->cellWidth;
-  row2 = (dc->DCOrgY + XLPTODP(dc, y)) / physDev->cellHeight;
-  col2 = (dc->DCOrgX + XLPTODP(dc, x)) / physDev->cellWidth;
+  GetCurrentPositionEx( physDev->hdc, &pt[0] );
+  pt[1].x = x;
+  pt[1].y = y;
+  LPtoDP( physDev->hdc, pt, 2 );
+
+  row1 = (physDev->org.y + pt[0].y) / physDev->cellHeight;
+  col1 = (physDev->org.x + pt[0].x) / physDev->cellWidth;
+  row2 = (physDev->org.y + pt[1].y) / physDev->cellHeight;
+  col2 = (physDev->org.x + pt[1].x) / physDev->cellWidth;
 
   if(row1 > row2) {
     INT tmp = row1;
@@ -190,17 +195,22 @@
 {
 #ifdef WINE_CURSES
   INT row1, col1, row2, col2;
-  DC *dc = physDev->dc;
+  RECT rect;
 
   TRACE("(%x, %d, %d, %d, %d)\n", physDev->hdc, left, top, right, bottom);
 
   if(!physDev->window)
     return FALSE;
 
-  row1 = (dc->DCOrgY + XLPTODP(dc, top)) / physDev->cellHeight;
-  col1 = (dc->DCOrgX + XLPTODP(dc, left)) / physDev->cellWidth;
-  row2 = (dc->DCOrgY + XLPTODP(dc, bottom)) / physDev->cellHeight;
-  col2 = (dc->DCOrgX + XLPTODP(dc, right)) / physDev->cellWidth;
+  rect.left   = left;
+  rect.top    = top;
+  rect.right  = right;
+  rect.bottom = bottom;
+  LPtoDP( physDev->hdc, (POINT *)&rect, 2 );
+  row1 = (physDev->org.y + rect.top) / physDev->cellHeight;
+  col1 = (physDev->org.x + rect.left) / physDev->cellWidth;
+  row2 = (physDev->org.y + rect.bottom) / physDev->cellHeight;
+  col2 = (physDev->org.x + rect.right) / physDev->cellWidth;
 
   if(row1 > row2) {
     INT tmp = row1;
@@ -259,15 +269,18 @@
 {
 #ifdef WINE_CURSES
   INT row, col;
-  DC *dc = physDev->dc;
+  POINT pt;
 
   TRACE("(%x, %d, %d, 0x%08lx)\n", physDev->hdc, x, y, color);
 
   if(!physDev->window)
     return FALSE;
 
-  row = (dc->DCOrgY + XLPTODP(dc, y)) / physDev->cellHeight;
-  col = (dc->DCOrgX + XLPTODP(dc, x)) / physDev->cellWidth;
+  pt.x = x;
+  pt.y = y;
+  LPtoDP( physDev->hdc, &pt, 1 );
+  row = (physDev->org.y + pt.y) / physDev->cellHeight;
+  col = (physDev->org.x + pt.x) / physDev->cellWidth;
 
   mvwaddch(physDev->window, row, col, ACS_BULLET);
   wrefresh(physDev->window);
@@ -328,7 +341,8 @@
   INT row, col;
   LPSTR ascii;
   DWORD len;
-  DC *dc = physDev->dc;
+  POINT pt;
+  UINT text_align = GetTextAlign( physDev->hdc );
 
   TRACE("(%x, %d, %d, 0x%08x, %p, %s, %d, %p)\n",
         physDev->hdc, x, y, flags, lpRect, debugstr_wn(str, count), count, lpDx);
@@ -336,17 +350,14 @@
   if(!physDev->window)
     return FALSE;
 
+  pt.x = x;
+  pt.y = y;
   /* FIXME: Is this really correct? */
-  if(dc->textAlign & TA_UPDATECP) {
-    x = dc->CursPosX;
-    y = dc->CursPosY;
-  }
+  if(text_align & TA_UPDATECP) GetCurrentPositionEx( physDev->hdc, &pt );
 
-  x = XLPTODP(dc, x);
-  y = YLPTODP(dc, y);
-
-  row = (dc->DCOrgY + y) / physDev->cellHeight;
-  col = (dc->DCOrgX + x) / physDev->cellWidth;
+  LPtoDP( physDev->hdc, &pt, 1 );
+  row = (physDev->org.y + pt.y) / physDev->cellHeight;
+  col = (physDev->org.x + pt.x) / physDev->cellWidth;
   len = WideCharToMultiByte( CP_ACP, 0, str, count, NULL, 0, NULL, NULL );
   ascii = HeapAlloc( GetProcessHeap(), 0, len );
   WideCharToMultiByte( CP_ACP, 0, str, count, ascii, len, NULL, NULL );
@@ -354,9 +365,12 @@
   HeapFree( GetProcessHeap(), 0, ascii );
   wrefresh(physDev->window);
 
-  if(dc->textAlign & TA_UPDATECP) {
-    dc->CursPosX += count * physDev->cellWidth;
-    dc->CursPosY += physDev->cellHeight;
+  if(text_align & TA_UPDATECP)
+  {
+      pt.x += count * physDev->cellWidth;
+      pt.y += physDev->cellHeight;
+      DPtoLP( physDev->hdc, &pt, 1 );
+      MoveToEx( physDev->hdc, pt.x, pt.y, NULL );
   }
 
   return TRUE;
diff --git a/dlls/ttydrv/ttydrv.h b/dlls/ttydrv/ttydrv.h
index cc817a0..f3ed8bb 100644
--- a/dlls/ttydrv/ttydrv.h
+++ b/dlls/ttydrv/ttydrv.h
@@ -61,7 +61,7 @@
 
 typedef struct {
   HDC hdc;
-  DC *dc;
+  POINT org;
   WINDOW *window;
   int cellWidth;
   int cellHeight;
@@ -76,7 +76,6 @@
 
 extern BOOL TTYDRV_DC_Arc(TTYDRV_PDEVICE *physDev, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend);
 extern LONG TTYDRV_DC_BitmapBits(HBITMAP hbitmap, void *bits, LONG count, WORD flags);
-extern BOOL TTYDRV_DC_CreateDC(DC *dc, LPCSTR driver, LPCSTR device, LPCSTR output, const DEVMODEA *initData);
 extern BOOL TTYDRV_DC_DeleteDC(TTYDRV_PDEVICE *physDev);
 extern BOOL TTYDRV_DC_BitBlt(TTYDRV_PDEVICE *physDevDst, INT xDst, INT yDst, INT width, INT height, TTYDRV_PDEVICE *physDevSrc, INT xSrc, INT ySrc, DWORD rop);
 extern BOOL TTYDRV_DC_Chord(TTYDRV_PDEVICE *physDev, INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend);
diff --git a/dlls/ttydrv/ttydrv.spec b/dlls/ttydrv/ttydrv.spec
index 0565004..28c15ac 100644
--- a/dlls/ttydrv/ttydrv.spec
+++ b/dlls/ttydrv/ttydrv.spec
@@ -6,13 +6,14 @@
 @ cdecl Arc(ptr long long long long long long long long) TTYDRV_DC_Arc
 @ cdecl BitBlt(ptr long long long long ptr long long long) TTYDRV_DC_BitBlt
 @ cdecl Chord(ptr long long long long long long long long) TTYDRV_DC_Chord
-@ cdecl CreateDC(ptr str str str ptr) TTYDRV_DC_CreateDC
+@ cdecl CreateDC(ptr ptr str str str ptr) TTYDRV_DC_CreateDC
 @ cdecl DeleteDC(ptr) TTYDRV_DC_DeleteDC
 @ cdecl Ellipse(ptr long long long long) TTYDRV_DC_Ellipse
 @ cdecl ExtFloodFill(ptr long long long long) TTYDRV_DC_ExtFloodFill
 @ cdecl ExtTextOut(ptr long long long ptr ptr long ptr) TTYDRV_DC_ExtTextOut
 @ cdecl GetBitmapBits(long ptr long) TTYDRV_GetBitmapBits
 @ cdecl GetCharWidth(ptr long long ptr) TTYDRV_DC_GetCharWidth
+@ cdecl GetDCOrgEx(ptr ptr) TTYDRV_GetDCOrgEx
 @ cdecl GetDeviceCaps(ptr long) TTYDRV_GetDeviceCaps
 @ cdecl GetPixel(ptr long long) TTYDRV_DC_GetPixel
 @ cdecl GetSystemPaletteEntries(ptr long long ptr) TTYDRV_GetSystemPaletteEntries
@@ -30,6 +31,7 @@
 @ cdecl RoundRect(ptr long long long long long long) TTYDRV_DC_RoundRect
 @ cdecl SelectFont(ptr long) TTYDRV_SelectFont
 @ cdecl SetBitmapBits(long ptr long) TTYDRV_SetBitmapBits
+@ cdecl SetDCOrg(ptr long long) TTYDRV_SetDCOrg
 @ cdecl SetDIBitsToDevice(ptr long long long long long long long long ptr ptr long) TTYDRV_DC_SetDIBitsToDevice
 @ cdecl SetPixel(ptr long long long) TTYDRV_DC_SetPixel
 @ cdecl StretchBlt(ptr long long long long ptr long long long long long) TTYDRV_DC_StretchBlt
diff --git a/dlls/ttydrv/wnd.c b/dlls/ttydrv/wnd.c
index 7915d30..96e5d34 100644
--- a/dlls/ttydrv/wnd.c
+++ b/dlls/ttydrv/wnd.c
@@ -45,7 +45,7 @@
     HWND hwndLinkAfter;
 
 #ifdef WINE_CURSES
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
+    WND *wndPtr = WIN_GetPtr( hwnd );
     WINDOW *window;
     INT cellWidth=8, cellHeight=8; /* FIXME: Hardcoded */
 
@@ -70,7 +70,7 @@
         }
         wndPtr->pDriverData = window;
     }
-    WIN_ReleaseWndPtr( wndPtr );
+    WIN_ReleasePtr( wndPtr );
 #else /* defined(WINE_CURSES) */
     FIXME("(%x): stub\n", hwnd);
 #endif /* defined(WINE_CURSES) */
@@ -117,14 +117,14 @@
 BOOL TTYDRV_DestroyWindow( HWND hwnd )
 {
 #ifdef WINE_CURSES
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
+    WND *wndPtr = WIN_GetPtr( hwnd );
     WINDOW *window = wndPtr->pDriverData;
 
     TRACE("(%x)\n", hwnd);
 
     if (window && window != root_window) delwin(window);
     wndPtr->pDriverData = NULL;
-    WIN_ReleaseWndPtr( wndPtr );
+    WIN_ReleasePtr( wndPtr );
 #else /* defined(WINE_CURSES) */
     FIXME("(%x): stub\n", hwnd);
 #endif /* defined(WINE_CURSES) */
@@ -367,8 +367,6 @@
 BOOL TTYDRV_GetDC( HWND hwnd, HDC hdc, HRGN hrgn, DWORD flags )
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    DC *dc;
-    BOOL updateVisRgn;
     HRGN hrgnVisible = 0;
     POINT org;
 
@@ -385,17 +383,9 @@
         org.y = wndPtr->rectClient.top;
     }
 
-    if (!(dc = DC_GetDCPtr( hdc )))
-    {
-        WIN_ReleaseWndPtr( wndPtr );
-        return FALSE;
-    }
-    dc->DCOrgX = org.x;
-    dc->DCOrgY = org.y;
-    updateVisRgn = (dc->flags & DC_DIRTY) != 0;
-    GDI_ReleaseObj( hdc );
+    SetDCOrg16( hdc, org.x, org.y );
 
-    if (updateVisRgn)
+    if (SetHookFlags16( hdc, DCHF_VALIDATEVISRGN ))  /* DC was dirty */
     {
         if (flags & DCX_PARENTCLIP)
         {
@@ -418,7 +408,6 @@
                 else
                     OffsetRgn( hrgnVisible, -wndPtr->rectClient.left,
                                -wndPtr->rectClient.top );
-                OffsetRgn( hrgnVisible, org.x, org.y );
             }
             else
                 hrgnVisible = CreateRectRgn( 0, 0, 0, 0 );
@@ -678,7 +667,6 @@
  */
 static UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect )
 {
-    WND *wndPtr;
     UINT swpFlags = 0;
     WINDOWPLACEMENT wpl;
 
@@ -691,11 +679,8 @@
     /* If I glark this right, yields an immutable window*/
     swpFlags = SWP_NOSIZE | SWP_NOMOVE;
 
-    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
-
     /*cmd handling goes here.  see dlls/x1drv/winpos.c*/
 
-    WIN_ReleaseWndPtr( wndPtr );
     return swpFlags;
 }
 
diff --git a/dlls/wineps/init.c b/dlls/wineps/init.c
index a2d6083..e28be99 100644
--- a/dlls/wineps/init.c
+++ b/dlls/wineps/init.c
@@ -229,7 +229,7 @@
 /**********************************************************************
  *	     PSDRV_CreateDC
  */
-BOOL PSDRV_CreateDC( DC *dc, LPCSTR driver, LPCSTR device,
+BOOL PSDRV_CreateDC( DC *dc, PSDRV_PDEVICE **pdev, LPCSTR driver, LPCSTR device,
                      LPCSTR output, const DEVMODEA* initData )
 {
     PSDRV_PDEVICE *physDev;
@@ -238,9 +238,9 @@
     /* If no device name was specified, retrieve the device name
      * from the DEVMODE structure from the DC's physDev.
      * (See CreateCompatibleDC) */
-    if ( !device && dc->physDev )
+    if ( !device && *pdev )
     {
-        physDev = (PSDRV_PDEVICE *)dc->physDev;
+        physDev = *pdev;
         device = physDev->Devmode->dmPublic.dmDeviceName;
     }
     pi = PSDRV_FindPrinterInfo(device);
@@ -257,7 +257,7 @@
     physDev = (PSDRV_PDEVICE *)HeapAlloc( PSDRV_Heap, HEAP_ZERO_MEMORY,
 					             sizeof(*physDev) );
     if (!physDev) return FALSE;
-    dc->physDev = (PHYSDEV)physDev;
+    *pdev = physDev;
     physDev->hdc = dc->hSelf;
     physDev->dc = dc;
 
@@ -300,7 +300,6 @@
 
     HeapFree( PSDRV_Heap, 0, physDev->Devmode );
     HeapFree( PSDRV_Heap, 0, physDev->job.output );
-    physDev->dc->physDev = NULL;
     HeapFree( PSDRV_Heap, 0, physDev );
 
     return TRUE;
diff --git a/dlls/wineps/wineps.spec b/dlls/wineps/wineps.spec
index 4b2fbfe..62db307 100644
--- a/dlls/wineps/wineps.spec
+++ b/dlls/wineps/wineps.spec
@@ -5,7 +5,7 @@
 
 @ cdecl Arc(ptr long long long long long long long long) PSDRV_Arc
 @ cdecl Chord(ptr long long long long long long long long) PSDRV_Chord
-@ cdecl CreateDC(ptr str str str ptr) PSDRV_CreateDC
+@ cdecl CreateDC(ptr ptr str str str ptr) PSDRV_CreateDC
 @ cdecl DeleteDC(ptr) PSDRV_DeleteDC
 @ cdecl DeviceCapabilities(ptr ptr ptr long ptr ptr) PSDRV_DeviceCapabilities
 @ cdecl Ellipse(ptr long long long long) PSDRV_Ellipse
diff --git a/dlls/x11drv/winpos.c b/dlls/x11drv/winpos.c
index 78c6628..c4be59f 100644
--- a/dlls/x11drv/winpos.c
+++ b/dlls/x11drv/winpos.c
@@ -426,7 +426,7 @@
     X11DRV_WND_DATA *data = win->pDriverData;
     Drawable drawable;
     BOOL visible;
-    POINT org;
+    POINT org, drawable_org;
     int mode = IncludeInferiors;
 
     /* don't clip siblings if using parent clip region */
@@ -466,7 +466,9 @@
             org.x = win->rectWindow.left - win->rectClient.left;
             org.y = win->rectWindow.top - win->rectClient.top;
         }
+        drawable_org = org;
         MapWindowPoints( hwnd, parent, &org, 1 );
+        MapWindowPoints( hwnd, 0, &drawable_org, 1 );
         /* have to use the parent so that we include siblings */
         if (parent) drawable = X11DRV_get_client_window( parent );
         else drawable = root_window;
@@ -478,23 +480,28 @@
             drawable = data->icon_window ? data->icon_window : data->whole_window;
             org.x = 0;
             org.y = 0;
+            drawable_org = org;
         }
         else if (flags & DCX_WINDOW)
         {
             drawable = data->whole_window;
             org.x = win->rectWindow.left - data->whole_rect.left;
             org.y = win->rectWindow.top - data->whole_rect.top;
+            drawable_org.x = data->whole_rect.left - win->rectClient.left;
+            drawable_org.y = data->whole_rect.top - win->rectClient.top;
         }
         else
         {
             drawable = data->client_window;
             org.x = 0;
             org.y = 0;
+            drawable_org = org;
             if (flags & DCX_CLIPCHILDREN) mode = ClipByChildren;  /* can use X11 clipping */
         }
+        MapWindowPoints( hwnd, 0, &drawable_org, 1 );
     }
 
-    X11DRV_SetDrawable( hdc, drawable, mode, org.x, org.y );
+    X11DRV_SetDrawable( hdc, drawable, mode, &org, &drawable_org );
 
     if (flags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN) ||
         SetHookFlags16( hdc, DCHF_VALIDATEVISRGN ))  /* DC was dirty */
@@ -509,9 +516,6 @@
             if (flags & (DCX_EXCLUDERGN | DCX_INTERSECTRGN))
                 CombineRgn( visRgn, visRgn, hrgn,
                             (flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF );
-
-            /* make it relative to the drawable origin */
-            OffsetRgn( visRgn, org.x, org.y );
         }
         else visRgn = CreateRectRgn( 0, 0, 0, 0 );
 
diff --git a/dlls/x11drv/x11drv.spec b/dlls/x11drv/x11drv.spec
index 8da676a..d9022b9 100644
--- a/dlls/x11drv/x11drv.spec
+++ b/dlls/x11drv/x11drv.spec
@@ -8,7 +8,7 @@
 @ cdecl ChoosePixelFormat(ptr ptr) X11DRV_ChoosePixelFormat
 @ cdecl Chord(ptr long long long long long long long long) X11DRV_Chord
 @ cdecl CreateBitmap(ptr long) X11DRV_CreateBitmap
-@ cdecl CreateDC(ptr str str str ptr) X11DRV_CreateDC
+@ cdecl CreateDC(ptr ptr str str str ptr) X11DRV_CreateDC
 @ cdecl CreateDIBSection(ptr ptr long ptr long long long) X11DRV_DIB_CreateDIBSection
 @ cdecl DeleteBitmap(long) X11DRV_DeleteBitmap
 @ cdecl DeleteDC(ptr) X11DRV_DeleteDC
@@ -49,6 +49,7 @@
 @ cdecl SelectPen(ptr long) X11DRV_SelectPen
 @ cdecl SetBitmapBits(long ptr long) X11DRV_SetBitmapBits
 @ cdecl SetBkColor(ptr long) X11DRV_SetBkColor
+@ cdecl SetDCOrg(ptr long long) X11DRV_SetDCOrg
 @ cdecl SetDIBColorTable(ptr long long ptr) X11DRV_SetDIBColorTable
 @ cdecl SetDIBits(ptr long long long ptr ptr long) X11DRV_SetDIBits
 @ cdecl SetDIBitsToDevice(ptr long long long long long long long long ptr ptr long) X11DRV_SetDIBitsToDevice
diff --git a/dlls/x11drv/xrender.c b/dlls/x11drv/xrender.c
index 96a1a30..b29b2b9 100644
--- a/dlls/x11drv/xrender.c
+++ b/dlls/x11drv/xrender.c
@@ -637,7 +637,7 @@
     if(flags & ETO_OPAQUE) {
         TSXSetForeground( gdi_display, physDev->gc, physDev->backgroundPixel );
 	TSXFillRectangle( gdi_display, physDev->drawable, physDev->gc,
-			  dc->DCOrgX + rc.left, dc->DCOrgY + rc.top,
+			  physDev->org.x + rc.left, physDev->org.y + rc.top,
 			  rc.right - rc.left, rc.bottom - rc.top );
     }
 
@@ -735,7 +735,8 @@
     {
         wine_tsx11_lock();
         pXRenderSetPictureClipRectangles( gdi_display, physDev->xrender->pict,
-                                          0, 0, (XRectangle *)data->Buffer, data->rdh.nCount );
+                                          physDev->org.x, physDev->org.y,
+                                          (XRectangle *)data->Buffer, data->rdh.nCount );
         wine_tsx11_unlock();
         HeapFree( GetProcessHeap(), 0, data );
     }
@@ -746,7 +747,7 @@
 	       y - tm.tmAscent < rc.top || y + tm.tmDescent >= rc.bottom) {
 	        TSXSetForeground( gdi_display, physDev->gc, physDev->backgroundPixel );
 		TSXFillRectangle( gdi_display, physDev->drawable, physDev->gc,
-				  dc->DCOrgX + x, dc->DCOrgY + y - tm.tmAscent,
+				  physDev->org.x + x, physDev->org.y + y - tm.tmAscent,
 				  width, tm.tmAscent + tm.tmDescent );
 	    }
 	}
@@ -809,8 +810,8 @@
     }
 
 
-    TRACE("Writing %s at %d,%d\n", debugstr_wn(wstr,count), dc->DCOrgX + x,
-	  dc->DCOrgY + y);
+    TRACE("Writing %s at %ld,%ld\n", debugstr_wn(wstr,count),
+          physDev->org.x + x, physDev->org.y + y);
 
     wine_tsx11_lock();
     if(!lpDx)
@@ -819,7 +820,7 @@
 				   physDev->xrender->pict,
 				   physDev->xrender->cacheEntry->font_format,
 				   physDev->xrender->cacheEntry->glyphset,
-				   0, 0, dc->DCOrgX + x, dc->DCOrgY + y,
+				   0, 0, physDev->org.x + x, physDev->org.y + y,
 				   glyphs, count);
 
     else {
@@ -830,8 +831,8 @@
 				       physDev->xrender->pict,
 				       physDev->xrender->cacheEntry->font_format,
 				       physDev->xrender->cacheEntry->glyphset,
-				       0, 0, dc->DCOrgX + x + xoff,
-				       dc->DCOrgY + y + yoff,
+				       0, 0, physDev->org.x + x + xoff,
+				       physDev->org.y + y + yoff,
 				       glyphs + idx, 1);
 	    offset += INTERNAL_XWSTODS(dc, lpDx[idx]);
 	    xoff = offset * cosEsc;