Release 980517

Sun May 17 16:23:56 1998  Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de>

	* [file/profile.c]
	Fix the return value of PROFILE_GetSection

	* [misc/crtdll.c]
	Do _getdrive, fix _chdrive.

	* [misc/commdlg.c]
	First cut at ChooseColor[WA].

	* [misc/network.c]
	Do something sensible for WNetGetDirectoryType16.

Sun May 17 10:21:35 1998  Andreas Mohr <100.30936@germany.net>

	* [controls/menu.c]
	Fixed disabled sub menus with MF_BYPOSITION that were not disabled.

	* [misc/crtdll.c] [relay32/crtdll.spec] [include/winerror.h]
	Implemented fscanf, fsetpos, _access, _fpreset (thanks to Uwe Bonnes),
	and _ltoa. 

	* [loader/task.c]
	MakeProcInstance: must use CURRENT_DS if hInst == NULL.

	* [misc/shell.c]
	SHELL_GetResourceTable, InternalExtractIcon: fixed broken .ICO handling

	* [windows/winpos.c]
	DeferWindowPos: removed "same parent" requirement.
	Which doc states that this is required ?

Sat May 16 20:08:11 1998  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [loader/module.c] [loader/ne/module.c]
	More NE module cleanups.

	* [loader/task.c]
	Fixed SwitchStackBack().

Fri May 15 10:04:27 1998  Marcus Meissner <marcus@jet.franken.de>

	* [configure.in][inlcude/acconfig.h]
	Fixed broken OSS check, added check for working sigaltstack,
	fixed broken statfs checks on some linux systems.

	* [files/directory.c][loader/pe_image.c][relay32/builtin.c]
	  [loader/module.c]
	Added handling of win32 module pathnames.

	* [relay32/wnaspi32.spec]
	New file.

	* [misc/lzexpand.c]
	LZCopy auto-decompresses LZ compressed files, even if they are not
	specially flagged. Fixes some InstallShield problems.

	* [misc/registry.c]
	Some fixes for RegQueryInfoKey (reference program monkey.exe
	from Win32 SDK works now better). Probably still has faults.

Fri May 15 08:58:58 1998  Martin Boehme <boehme@informatik.mu-luebeck.de>

	* [graphics/mapping.c] [include/dc.h] [include/gdi.h] [objects/dc.c]
	Reworked the way world transformations and mapping modes are handled
	so that both of these transformations can be computed in a single
	step.

	* [graphics/painting.c] [graphics/path.c] [include/path.h]
	More GDI path support.

	* [graphics/x11drv/graphics.c]
	Fixed the return value of GRAPH_DrawArc for the zero height /
	zero width case to reflect Windows' behaviour.

	* [include/windows.h] [relay32/gdi32.spec] [objects/dc.c]
	Implemented ModifyWorldTransform and CombineTransform.

Tue May 14 18:03:46 1998  Eric Kohl <ekohl@abo.rhein-zeitung.de>

	* [controls/commctrl.c][relay32/comctl32.spec]
	  [controls/*.c][include/*.h]
	Implemented InitCommonControlsEx (dll version 4.72 compatible).
	InitCommonControls calls ImageCommonControlsEx.
	Registering code of the common controls had to be changed
	(see XXXX_Register functions).

	* [controls/status.c][include/commctrl.h][include/status.h]
	Implemented most new features and fixed the look and feel.

	* [contols/commctrl.c][include/commctrl.h][relay32/comctl32.spec]
	Implemented MenuHelp (incomplete).

	* [controls/status.c][controls/progress.c]
	Changed allocation strategy for control specific memory.

	* [controls/header.c][include/header.h][include/commctrl.h]
	First implementation of header control.

	* [windows/defwnd.c][windows/syscolors.c]
	Fixed default control colors for Win95 look.

	* [windows/nonclient.c]
	Fixed off by one error for Win95 look. Top border of child windows
	should be visible.

	* [misc/imagelist.h]
	Improved documentation and fixed some bugs.

Thu May 14 15:42:21 1998  Robert Wilhelm  <robert@physiol.med.tu-muenchen.de>

	* [relay32/crtdll.spec]
	Added hypot,j0,j1,jn and ceil.

Wed May 13 19:10:10 1998  Pascal Cuoq <pcuoq@ens-lyon.fr>

	* [controls/listbox.c]
	Item height is now exactly font height.
	Wine listboxes now behave like Windows' when they are 
	created without WS_VSCROLL but the program subsequently 
	calls ShowScrollBar or SetScrollInfo.

Wed May 13 18:33:01 1998  Ulrich Weigand <weigand@informatik.uni-erlangen.de>

	* [relay32/relay386.c]
	Restore ES also in the non-debug case.

	* [windows/event.c]
	Bugfix: Blocking TSXNextEvent could deadlock Wine.

	* [win32/process.c] [windows/message.c]
	Silly stubs for MsgWaitForMultipleObjects / PostThreadMessage
	that make some programs run better.

	* [windows/winproc.c]
	WINPROC_MapMsg32Ato16/16To32A: added WM_NOTIFY.  

        * [win32/kernel32.c]
	Added 16->32 thunking and improved 32->16 thunking functions.

	* [tools/build.c]
	Added new variant of CallFrom16 stub for use with Win95 thunks.

	* [if1632/kernel.spec] [if1632/builtin.c] [win32/kernel32.c]
	Added a few undocumented KERNEL functions.

	* [loader/ne/module.c] [loader/ne/segment.c]
	Call DllEntryPoint for 16-bit DLLs with subsystem >= 4.0.

	* [win32/kernel32.spec] [win32/wow32.spec] [win32/ordinals.c]
	Use names from the Oct 94 beta release for undoc. functions.

Wed May 13 14:18:26 1998  Matthew Becker <mbecker@glasscity.net>

	* [misc/registry.c]
	Code cleanup.

	* [misc/cpu.c]
	Commented out the registry puts temporarily.

	* [programs/regtest/*]
	New registry testing program.

Tue May 12 22:54:03 1998  Michael Mess <michael@kawo2.rwth-aachen.de>

	* [multimedia/audio.c]
	ioctl's do not commute in /dev/dsp initialization.

Tue May 12 20:11:42 1998  Karl Garrison <karlos@eznet.net>

	* [win32/console.c]
	Implemented SetConsoleTextAttribute, FillConsoleOutputCharacter.
	Improved cursor positioning.
	This allows for text colors in an xterm, rxvt, or console.

Tue May 12 17:57:52 1998  Petter Reinholdtsen <pere@td.org.uit.no>

	* [Makefile.in]
	Create prefix/{bin|lib} directories if missing during install.

Sun May 10 19:37:51 1998  Jan Willamowius <jan@janhh.shnet.org>

	* [multimedia/mmio.c]
	Have mmioSetBuffer return success (0), so Corel Draw 4
	keeps working. (IO is still unbuffered)

Wed May  6 16:57:55 1998  James Juran <jrj120@psu.edu>

        * [Makefile.in] [Make.rules.in]
	Changed "make clean" to remove `textedit` backup files (*%)

	* [controls/menu.c][graphics/x11drv/xfont.c][include/libres.h]
	  [loader/main.c][loader/ne/module.c][scheduler/synchro.c]
	  [win32/time.c][windows/winpos.c][include/windows.h]
	Fixed miscellaneous compilation warnings.

	* [misc/main.c][miscemu/main.c][include/main.h]
	Moved prototypes to new include file main.h, various cleanups.

Tue May  5 21:05:06 1998  Morten Welinder  <terra@diku.dk>

	* [misc/winsock.c]
	Don't refer to __FreeBSD__ when HAVE_STRERROR is meant.

	* [misc/debugstr.c]
	For debug_dumpstrSend, send strings to stderr.

Tue May  5 21:47:40 1998  Huw D M Davies <h.davies1@physics.oxford.ac.uk>

	* [objects/region.c]
	Fix for REGION_RegionOp() if newReg is one of the source regions.

Tue May  5 18:27:32 1998  Jim Peterson <jspeter@roanoke.infi.net>

	* [misc/main.c]
	Add '-h/-help' option and print WINE_RELEASE_INFO with usage message.

	* [misc/spy.c]
	Realign trace messages.

Tue May  5 15:46:47 1998  Donnie V. Savage <dsavage@cisco.com>

	* [graphics/ddraw.c]
	Fixed compile warnings

	* [misc/winsock.c]
	Warnings should not be errors.

Tue May  5 13:40:42 1998  Jim Peterson <jspeter@roanoke.infi.net>

	* [*/*]
	Remove many warnings through explicit casts, added #include's,
	and corrected printf formats.

Tue May  5 05:18:12 1998  Insomnia (Stea Greene) <insomnia@core.binghamton.edu>

	* [graphics/ddraw.c]
	Kept unchanged portion of old palette when changing only a few
	palette entries.  Really should only deallocate the changed cells.
	This make StarCraft work almost perfectly (sound overflows still
	cause static).

Mon May  4 15:04:57 1998  Alexander V. Lukyanov <lav@long.yar.ru>

	* [misc/lstr.c]
	FormatMessage: terminate string on %0, undo linefeed strip.
diff --git a/objects/dc.c b/objects/dc.c
index 6c71c18..f608b09 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -100,50 +100,52 @@
  */
 static void DC_Init_DC_INFO( WIN_DC_INFO *win_dc_info )
 {
-    win_dc_info->flags           = 0;
-    win_dc_info->devCaps         = NULL;
-    win_dc_info->hClipRgn        = 0;
-    win_dc_info->hVisRgn         = 0;
-    win_dc_info->hGCClipRgn      = 0;
-    win_dc_info->hPen            = STOCK_BLACK_PEN;
-    win_dc_info->hBrush          = STOCK_WHITE_BRUSH;
-    win_dc_info->hFont           = STOCK_SYSTEM_FONT;
-    win_dc_info->hBitmap         = 0;
-    win_dc_info->hFirstBitmap    = 0;
-    win_dc_info->hDevice         = 0;
-    win_dc_info->hPalette        = STOCK_DEFAULT_PALETTE;
-    win_dc_info->ROPmode         = R2_COPYPEN;
-    win_dc_info->polyFillMode    = ALTERNATE;
-    win_dc_info->stretchBltMode  = BLACKONWHITE;
-    win_dc_info->relAbsMode      = ABSOLUTE;
-    win_dc_info->backgroundMode  = OPAQUE;
-    win_dc_info->backgroundColor = RGB( 255, 255, 255 );
-    win_dc_info->textColor       = RGB( 0, 0, 0 );
-    win_dc_info->backgroundPixel = 0;
-    win_dc_info->textPixel       = 0;
-    win_dc_info->brushOrgX       = 0;
-    win_dc_info->brushOrgY       = 0;
-    win_dc_info->textAlign       = TA_LEFT | TA_TOP | TA_NOUPDATECP;
-    win_dc_info->charExtra       = 0;
-    win_dc_info->breakTotalExtra = 0;
-    win_dc_info->breakCount      = 0;
-    win_dc_info->breakExtra      = 0;
-    win_dc_info->breakRem        = 0;
-    win_dc_info->bitsPerPixel    = 1;
-    win_dc_info->MapMode         = MM_TEXT;
-    win_dc_info->GraphicsMode    = GM_COMPATIBLE;
-    win_dc_info->DCOrgX          = 0;
-    win_dc_info->DCOrgY          = 0;
-    win_dc_info->CursPosX        = 0;
-    win_dc_info->CursPosY        = 0;
-    win_dc_info->ArcDirection    = AD_COUNTERCLOCKWISE;
-    win_dc_info->UseWorldXform   = FALSE;
-    win_dc_info->WorldXform.eM11 = 1.0f;
-    win_dc_info->WorldXform.eM12 = 0.0f;
-    win_dc_info->WorldXform.eM21 = 0.0f;
-    win_dc_info->WorldXform.eM22 = 1.0f;
-    win_dc_info->WorldXform.eDx  = 0.0f;
-    win_dc_info->WorldXform.eDy  = 0.0f;
+    win_dc_info->flags               = 0;
+    win_dc_info->devCaps             = NULL;
+    win_dc_info->hClipRgn            = 0;
+    win_dc_info->hVisRgn             = 0;
+    win_dc_info->hGCClipRgn          = 0;
+    win_dc_info->hPen                = STOCK_BLACK_PEN;
+    win_dc_info->hBrush              = STOCK_WHITE_BRUSH;
+    win_dc_info->hFont               = STOCK_SYSTEM_FONT;
+    win_dc_info->hBitmap             = 0;
+    win_dc_info->hFirstBitmap        = 0;
+    win_dc_info->hDevice             = 0;
+    win_dc_info->hPalette            = STOCK_DEFAULT_PALETTE;
+    win_dc_info->ROPmode             = R2_COPYPEN;
+    win_dc_info->polyFillMode        = ALTERNATE;
+    win_dc_info->stretchBltMode      = BLACKONWHITE;
+    win_dc_info->relAbsMode          = ABSOLUTE;
+    win_dc_info->backgroundMode      = OPAQUE;
+    win_dc_info->backgroundColor     = RGB( 255, 255, 255 );
+    win_dc_info->textColor           = RGB( 0, 0, 0 );
+    win_dc_info->backgroundPixel     = 0;
+    win_dc_info->textPixel           = 0;
+    win_dc_info->brushOrgX           = 0;
+    win_dc_info->brushOrgY           = 0;
+    win_dc_info->textAlign           = TA_LEFT | TA_TOP | TA_NOUPDATECP;
+    win_dc_info->charExtra           = 0;
+    win_dc_info->breakTotalExtra     = 0;
+    win_dc_info->breakCount          = 0;
+    win_dc_info->breakExtra          = 0;
+    win_dc_info->breakRem            = 0;
+    win_dc_info->bitsPerPixel        = 1;
+    win_dc_info->MapMode             = MM_TEXT;
+    win_dc_info->GraphicsMode        = GM_COMPATIBLE;
+    win_dc_info->DCOrgX              = 0;
+    win_dc_info->DCOrgY              = 0;
+    win_dc_info->CursPosX            = 0;
+    win_dc_info->CursPosY            = 0;
+    win_dc_info->ArcDirection        = AD_COUNTERCLOCKWISE;
+    win_dc_info->xformWorld2Wnd.eM11 = 1.0f;
+    win_dc_info->xformWorld2Wnd.eM12 = 0.0f;
+    win_dc_info->xformWorld2Wnd.eM21 = 0.0f;
+    win_dc_info->xformWorld2Wnd.eM22 = 1.0f;
+    win_dc_info->xformWorld2Wnd.eDx  = 0.0f;
+    win_dc_info->xformWorld2Wnd.eDy  = 0.0f;
+    win_dc_info->xformWorld2Vport    = win_dc_info->xformWorld2Wnd;
+    win_dc_info->xformVport2World    = win_dc_info->xformWorld2Wnd;
+    win_dc_info->vport2WorldValid    = TRUE;
 
     PATH_InitGdiPath(&win_dc_info->path);
 }
@@ -434,6 +436,72 @@
 
 
 /***********************************************************************
+ *           DC_InvertXform
+ *
+ * Computes the inverse of the transformation xformSrc and stores it to
+ * xformDest. Returns TRUE if successful or FALSE if the xformSrc matrix
+ * is singular.
+ */
+static BOOL32 DC_InvertXform( const XFORM *xformSrc, XFORM *xformDest )
+{
+    FLOAT determinant;
+    
+    determinant = xformSrc->eM11*xformSrc->eM22 -
+        xformSrc->eM12*xformSrc->eM21;
+    if (determinant > -1e-12 && determinant < 1e-12)
+        return FALSE;
+
+    xformDest->eM11 =  xformSrc->eM22 / determinant;
+    xformDest->eM12 = -xformSrc->eM12 / determinant;
+    xformDest->eM21 = -xformSrc->eM21 / determinant;
+    xformDest->eM22 =  xformSrc->eM11 / determinant;
+    xformDest->eDx  = -xformSrc->eDx * xformDest->eM11 -
+                       xformSrc->eDy * xformDest->eM21;
+    xformDest->eDy  = -xformSrc->eDx * xformDest->eM12 -
+                       xformSrc->eDy * xformDest->eM22;
+
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           DC_UpdateXforms
+ *
+ * Updates the xformWorld2Vport, xformVport2World and vport2WorldValid
+ * fields of the specified DC by creating a transformation that
+ * represents the current mapping mode and combining it with the DC's
+ * world transform. This function should be called whenever the
+ * parameters associated with the mapping mode (window and viewport
+ * extents and origins) or the world transform change.
+ */
+void DC_UpdateXforms( DC *dc )
+{
+    XFORM xformWnd2Vport;
+    FLOAT scaleX, scaleY;
+    
+    /* Construct a transformation to do the window-to-viewport conversion */
+    scaleX = (FLOAT)dc->vportExtX / (FLOAT)dc->wndExtX;
+    scaleY = (FLOAT)dc->vportExtY / (FLOAT)dc->wndExtY;
+    xformWnd2Vport.eM11 = scaleX;
+    xformWnd2Vport.eM12 = 0.0;
+    xformWnd2Vport.eM21 = 0.0;
+    xformWnd2Vport.eM22 = scaleY;
+    xformWnd2Vport.eDx  = (FLOAT)dc->vportOrgX -
+        scaleX * (FLOAT)dc->wndOrgX;
+    xformWnd2Vport.eDy  = (FLOAT)dc->vportOrgY -
+        scaleY * (FLOAT)dc->wndOrgY;
+
+    /* Combine with the world transformation */
+    CombineTransform( &dc->w.xformWorld2Vport, &dc->w.xformWorld2Wnd,
+        &xformWnd2Vport );
+
+    /* Create inverse of world-to-viewport transformation */
+    dc->w.vport2WorldValid = DC_InvertXform( &dc->w.xformWorld2Vport,
+        &dc->w.xformVport2World );
+}
+
+
+/***********************************************************************
  *           GetDCState    (GDI.179)
  */
 HDC16 WINAPI GetDCState( HDC16 hdc )
@@ -452,50 +520,52 @@
     TRACE(dc, "(%04x): returning %04x\n", hdc, handle );
 
     memset( &newdc->u.x, 0, sizeof(newdc->u.x) );
-    newdc->w.flags           = dc->w.flags | DC_SAVED;
-    newdc->w.devCaps         = dc->w.devCaps;
-    newdc->w.hPen            = dc->w.hPen;       
-    newdc->w.hBrush          = dc->w.hBrush;     
-    newdc->w.hFont           = dc->w.hFont;      
-    newdc->w.hBitmap         = dc->w.hBitmap;    
-    newdc->w.hFirstBitmap    = dc->w.hFirstBitmap;
-    newdc->w.hDevice         = dc->w.hDevice;
-    newdc->w.hPalette        = dc->w.hPalette;   
-    newdc->w.bitsPerPixel    = dc->w.bitsPerPixel;
-    newdc->w.ROPmode         = dc->w.ROPmode;
-    newdc->w.polyFillMode    = dc->w.polyFillMode;
-    newdc->w.stretchBltMode  = dc->w.stretchBltMode;
-    newdc->w.relAbsMode      = dc->w.relAbsMode;
-    newdc->w.backgroundMode  = dc->w.backgroundMode;
-    newdc->w.backgroundColor = dc->w.backgroundColor;
-    newdc->w.textColor       = dc->w.textColor;
-    newdc->w.backgroundPixel = dc->w.backgroundPixel;
-    newdc->w.textPixel       = dc->w.textPixel;
-    newdc->w.brushOrgX       = dc->w.brushOrgX;
-    newdc->w.brushOrgY       = dc->w.brushOrgY;
-    newdc->w.textAlign       = dc->w.textAlign;
-    newdc->w.charExtra       = dc->w.charExtra;
-    newdc->w.breakTotalExtra = dc->w.breakTotalExtra;
-    newdc->w.breakCount      = dc->w.breakCount;
-    newdc->w.breakExtra      = dc->w.breakExtra;
-    newdc->w.breakRem        = dc->w.breakRem;
-    newdc->w.MapMode         = dc->w.MapMode;
-    newdc->w.GraphicsMode    = dc->w.GraphicsMode;
-    newdc->w.DCOrgX          = dc->w.DCOrgX;
-    newdc->w.DCOrgY          = dc->w.DCOrgY;
-    newdc->w.CursPosX        = dc->w.CursPosX;
-    newdc->w.CursPosY        = dc->w.CursPosY;
-    newdc->w.ArcDirection    = dc->w.ArcDirection;
-    newdc->w.UseWorldXform   = dc->w.UseWorldXform;
-    newdc->w.WorldXform      = dc->w.WorldXform;
-    newdc->wndOrgX           = dc->wndOrgX;
-    newdc->wndOrgY           = dc->wndOrgY;
-    newdc->wndExtX           = dc->wndExtX;
-    newdc->wndExtY           = dc->wndExtY;
-    newdc->vportOrgX         = dc->vportOrgX;
-    newdc->vportOrgY         = dc->vportOrgY;
-    newdc->vportExtX         = dc->vportExtX;
-    newdc->vportExtY         = dc->vportExtY;
+    newdc->w.flags            = dc->w.flags | DC_SAVED;
+    newdc->w.devCaps          = dc->w.devCaps;
+    newdc->w.hPen             = dc->w.hPen;       
+    newdc->w.hBrush           = dc->w.hBrush;     
+    newdc->w.hFont            = dc->w.hFont;      
+    newdc->w.hBitmap          = dc->w.hBitmap;    
+    newdc->w.hFirstBitmap     = dc->w.hFirstBitmap;
+    newdc->w.hDevice          = dc->w.hDevice;
+    newdc->w.hPalette         = dc->w.hPalette;   
+    newdc->w.bitsPerPixel     = dc->w.bitsPerPixel;
+    newdc->w.ROPmode          = dc->w.ROPmode;
+    newdc->w.polyFillMode     = dc->w.polyFillMode;
+    newdc->w.stretchBltMode   = dc->w.stretchBltMode;
+    newdc->w.relAbsMode       = dc->w.relAbsMode;
+    newdc->w.backgroundMode   = dc->w.backgroundMode;
+    newdc->w.backgroundColor  = dc->w.backgroundColor;
+    newdc->w.textColor        = dc->w.textColor;
+    newdc->w.backgroundPixel  = dc->w.backgroundPixel;
+    newdc->w.textPixel        = dc->w.textPixel;
+    newdc->w.brushOrgX        = dc->w.brushOrgX;
+    newdc->w.brushOrgY        = dc->w.brushOrgY;
+    newdc->w.textAlign        = dc->w.textAlign;
+    newdc->w.charExtra        = dc->w.charExtra;
+    newdc->w.breakTotalExtra  = dc->w.breakTotalExtra;
+    newdc->w.breakCount       = dc->w.breakCount;
+    newdc->w.breakExtra       = dc->w.breakExtra;
+    newdc->w.breakRem         = dc->w.breakRem;
+    newdc->w.MapMode          = dc->w.MapMode;
+    newdc->w.GraphicsMode     = dc->w.GraphicsMode;
+    newdc->w.DCOrgX           = dc->w.DCOrgX;
+    newdc->w.DCOrgY           = dc->w.DCOrgY;
+    newdc->w.CursPosX         = dc->w.CursPosX;
+    newdc->w.CursPosY         = dc->w.CursPosY;
+    newdc->w.ArcDirection     = dc->w.ArcDirection;
+    newdc->w.xformWorld2Wnd   = dc->w.xformWorld2Wnd;
+    newdc->w.xformWorld2Vport = dc->w.xformWorld2Vport;
+    newdc->w.xformVport2World = dc->w.xformVport2World;
+    newdc->w.vport2WorldValid = dc->w.vport2WorldValid;
+    newdc->wndOrgX            = dc->wndOrgX;
+    newdc->wndOrgY            = dc->wndOrgY;
+    newdc->wndExtX            = dc->wndExtX;
+    newdc->wndExtY            = dc->wndExtY;
+    newdc->vportOrgX          = dc->vportOrgX;
+    newdc->vportOrgY          = dc->vportOrgY;
+    newdc->vportExtX          = dc->vportExtX;
+    newdc->vportExtY          = dc->vportExtY;
 
     newdc->hSelf = (HDC32)handle;
     newdc->saveLevel = 0;
@@ -539,45 +609,47 @@
     }
     TRACE(dc, "%04x %04x\n", hdc, hdcs );
 
-    dc->w.flags           = dcs->w.flags & ~DC_SAVED;
-    dc->w.devCaps         = dcs->w.devCaps;
-    dc->w.hFirstBitmap    = dcs->w.hFirstBitmap;
-    dc->w.hDevice         = dcs->w.hDevice;
-    dc->w.ROPmode         = dcs->w.ROPmode;
-    dc->w.polyFillMode    = dcs->w.polyFillMode;
-    dc->w.stretchBltMode  = dcs->w.stretchBltMode;
-    dc->w.relAbsMode      = dcs->w.relAbsMode;
-    dc->w.backgroundMode  = dcs->w.backgroundMode;
-    dc->w.backgroundColor = dcs->w.backgroundColor;
-    dc->w.textColor       = dcs->w.textColor;
-    dc->w.backgroundPixel = dcs->w.backgroundPixel;
-    dc->w.textPixel       = dcs->w.textPixel;
-    dc->w.brushOrgX       = dcs->w.brushOrgX;
-    dc->w.brushOrgY       = dcs->w.brushOrgY;
-    dc->w.textAlign       = dcs->w.textAlign;
-    dc->w.charExtra       = dcs->w.charExtra;
-    dc->w.breakTotalExtra = dcs->w.breakTotalExtra;
-    dc->w.breakCount      = dcs->w.breakCount;
-    dc->w.breakExtra      = dcs->w.breakExtra;
-    dc->w.breakRem        = dcs->w.breakRem;
-    dc->w.MapMode         = dcs->w.MapMode;
-    dc->w.GraphicsMode    = dcs->w.GraphicsMode;
-    dc->w.DCOrgX          = dcs->w.DCOrgX;
-    dc->w.DCOrgY          = dcs->w.DCOrgY;
-    dc->w.CursPosX        = dcs->w.CursPosX;
-    dc->w.CursPosY        = dcs->w.CursPosY;
-    dc->w.ArcDirection    = dcs->w.ArcDirection;
-    dc->w.UseWorldXform   = dcs->w.UseWorldXform;
-    dc->w.WorldXform      = dcs->w.WorldXform;
+    dc->w.flags            = dcs->w.flags & ~DC_SAVED;
+    dc->w.devCaps          = dcs->w.devCaps;
+    dc->w.hFirstBitmap     = dcs->w.hFirstBitmap;
+    dc->w.hDevice          = dcs->w.hDevice;
+    dc->w.ROPmode          = dcs->w.ROPmode;
+    dc->w.polyFillMode     = dcs->w.polyFillMode;
+    dc->w.stretchBltMode   = dcs->w.stretchBltMode;
+    dc->w.relAbsMode       = dcs->w.relAbsMode;
+    dc->w.backgroundMode   = dcs->w.backgroundMode;
+    dc->w.backgroundColor  = dcs->w.backgroundColor;
+    dc->w.textColor        = dcs->w.textColor;
+    dc->w.backgroundPixel  = dcs->w.backgroundPixel;
+    dc->w.textPixel        = dcs->w.textPixel;
+    dc->w.brushOrgX        = dcs->w.brushOrgX;
+    dc->w.brushOrgY        = dcs->w.brushOrgY;
+    dc->w.textAlign        = dcs->w.textAlign;
+    dc->w.charExtra        = dcs->w.charExtra;
+    dc->w.breakTotalExtra  = dcs->w.breakTotalExtra;
+    dc->w.breakCount       = dcs->w.breakCount;
+    dc->w.breakExtra       = dcs->w.breakExtra;
+    dc->w.breakRem         = dcs->w.breakRem;
+    dc->w.MapMode          = dcs->w.MapMode;
+    dc->w.GraphicsMode     = dcs->w.GraphicsMode;
+    dc->w.DCOrgX           = dcs->w.DCOrgX;
+    dc->w.DCOrgY           = dcs->w.DCOrgY;
+    dc->w.CursPosX         = dcs->w.CursPosX;
+    dc->w.CursPosY         = dcs->w.CursPosY;
+    dc->w.ArcDirection     = dcs->w.ArcDirection;
+    dc->w.xformWorld2Wnd   = dcs->w.xformWorld2Wnd;
+    dc->w.xformWorld2Vport = dcs->w.xformWorld2Vport;
+    dc->w.xformVport2World = dcs->w.xformVport2World;
+    dc->w.vport2WorldValid = dcs->w.vport2WorldValid;
 
-    dc->wndOrgX           = dcs->wndOrgX;
-    dc->wndOrgY           = dcs->wndOrgY;
-    dc->wndExtX           = dcs->wndExtX;
-    dc->wndExtY           = dcs->wndExtY;
-    dc->vportOrgX         = dcs->vportOrgX;
-    dc->vportOrgY         = dcs->vportOrgY;
-    dc->vportExtX         = dcs->vportExtX;
-    dc->vportExtY         = dcs->vportExtY;
+    dc->wndOrgX            = dcs->wndOrgX;
+    dc->wndOrgY            = dcs->wndOrgY;
+    dc->wndExtX            = dcs->wndExtX;
+    dc->wndExtY            = dcs->wndExtY;
+    dc->vportOrgX          = dcs->vportOrgX;
+    dc->vportOrgY          = dcs->vportOrgY;
+    dc->vportExtX          = dcs->vportExtX;
+    dc->vportExtY          = dcs->vportExtY;
 
     if (!(dc->w.flags & DC_MEMORY)) dc->w.bitsPerPixel = dcs->w.bitsPerPixel;
     SelectClipRgn32( hdc, dcs->w.hClipRgn );
@@ -1208,21 +1280,17 @@
 
 /***********************************************************************
  *           GetWorldTransform    (GDI32.244)
- * FIXME
- *	Check that SetLastError is being called correctly
  */
 BOOL32 WINAPI GetWorldTransform( HDC32 hdc, LPXFORM xform )
 {
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     
     if (!dc)
-        /* FIXME: Call SetLastError? */
         return FALSE;
     if (!xform)
-        /* FIXME: Call SetLastError? */
 	return FALSE;
 
-    *xform = dc->w.WorldXform;
+    *xform = dc->w.xformWorld2Wnd;
     
     return TRUE;
 }
@@ -1248,16 +1316,125 @@
     if (dc->w.GraphicsMode!=GM_ADVANCED)
        return FALSE;
 
-    dc->w.WorldXform = *xform;
-
-    /* We only have to use the new world transform if it's not the
-     * identity transformation
-     */
-    dc->w.UseWorldXform=
-       (xform->eM11!=1.0f || xform->eM12!=0.0f ||
-        xform->eM21!=0.0f || xform->eM22!=1.0f ||
-        xform->eDx!=0.0f  || xform->eDy!=0.0f);
+    dc->w.xformWorld2Wnd = *xform;
     
+    DC_UpdateXforms( dc );
+
+    return TRUE;
+}
+
+
+/****************************************************************************
+ * ModifyWorldTransform [GDI32.253]
+ * Modifies the world transformation for a device context.
+ *
+ * PARAMS
+ *    hdc   [I] Handle to device context
+ *    xform [I] XFORM structure that will be used to modify the world
+ *              transformation
+ *    iMode [I] Specifies in what way to modify the world transformation
+ *              Possible values:
+ *              MWT_IDENTITY
+ *                 Resets the world transformation to the identity matrix.
+ *                 The parameter xform is ignored.
+ *              MWT_LEFTMULTIPLY
+ *                 Multiplies xform into the world transformation matrix from
+ *                 the left.
+ *              MWT_RIGHTMULTIPLY
+ *                 Multiplies xform into the world transformation matrix from
+ *                 the right.
+ *
+ * RETURNS STD
+ */
+BOOL32 WINAPI ModifyWorldTransform( HDC32 hdc, const XFORM *xform,
+    DWORD iMode )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    
+    /* Check for illegal parameters */
+    if (!dc)
+    {
+        SetLastError( ERROR_INVALID_HANDLE );
+        return FALSE;
+    }
+    if (!xform)
+	return FALSE;
+    
+    /* Check that graphics mode is GM_ADVANCED */
+    if (dc->w.GraphicsMode!=GM_ADVANCED)
+       return FALSE;
+       
+    switch (iMode)
+    {
+        case MWT_IDENTITY:
+	    dc->w.xformWorld2Wnd.eM11 = 1.0f;
+	    dc->w.xformWorld2Wnd.eM12 = 0.0f;
+	    dc->w.xformWorld2Wnd.eM21 = 0.0f;
+	    dc->w.xformWorld2Wnd.eM22 = 1.0f;
+	    dc->w.xformWorld2Wnd.eDx  = 0.0f;
+	    dc->w.xformWorld2Wnd.eDy  = 0.0f;
+	    break;
+        case MWT_LEFTMULTIPLY:
+	    CombineTransform( &dc->w.xformWorld2Wnd, xform,
+	        &dc->w.xformWorld2Wnd );
+	    break;
+	case MWT_RIGHTMULTIPLY:
+	    CombineTransform( &dc->w.xformWorld2Wnd, &dc->w.xformWorld2Wnd,
+	        xform );
+	    break;
+        default:
+	    return FALSE;
+    }
+
+    DC_UpdateXforms( dc );
+
+    return TRUE;
+}
+
+
+/****************************************************************************
+ * CombineTransform [GDI32.20]
+ * Combines two transformation matrices.
+ *
+ * PARAMS
+ *    xformResult [O] Stores the result of combining the two matrices
+ *    xform1      [I] Specifies the first matrix to apply
+ *    xform2      [I] Specifies the second matrix to apply
+ *
+ * REMARKS
+ *    The same matrix can be passed in for more than one of the parameters.
+ *
+ * RETURNS STD
+ */
+BOOL32 WINAPI CombineTransform( LPXFORM xformResult, const XFORM *xform1,
+    const XFORM *xform2 )
+{
+    XFORM xformTemp;
+    
+    /* Check for illegal parameters */
+    if (!xformResult || !xform1 || !xform2)
+        return FALSE;
+
+    /* Create the result in a temporary XFORM, since xformResult may be
+     * equal to xform1 or xform2 */
+    xformTemp.eM11 = xform1->eM11 * xform2->eM11 +
+                     xform1->eM12 * xform2->eM21;
+    xformTemp.eM12 = xform1->eM11 * xform2->eM12 +
+                     xform1->eM12 * xform2->eM22;
+    xformTemp.eM21 = xform1->eM21 * xform2->eM11 +
+                     xform1->eM22 * xform2->eM21;
+    xformTemp.eM22 = xform1->eM21 * xform2->eM12 +
+                     xform1->eM22 * xform2->eM22;
+    xformTemp.eDx  = xform1->eDx  * xform2->eM11 +
+                     xform1->eDy  * xform2->eM21 +
+                     xform2->eDx;
+    xformTemp.eDy  = xform1->eDx  * xform2->eM12 +
+                     xform1->eDy  * xform2->eM22 +
+                     xform2->eDy;
+
+    /* Copy the result to xformResult */
+    *xformResult = xformTemp;
+
     return TRUE;
 }