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/graphics/ddraw.c b/graphics/ddraw.c
index 92c118f..66df804 100644
--- a/graphics/ddraw.c
+++ b/graphics/ddraw.c
@@ -144,7 +144,7 @@
 	};
 	for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
 		if (flags[i].mask & flagmask)
-			DUMP("%s ",i,flags[i].name);
+			DUMP("%s ",flags[i].name);
 	DUMP("\n");
 }
 
@@ -184,7 +184,7 @@
 	};
 	for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
 		if (flags[i].mask & flagmask)
-			DUMP("%s ",i,flags[i].name);
+			DUMP("%s ",flags[i].name);
 }
 
 static void _dump_DDSCAPS(DWORD flagmask) {
@@ -231,7 +231,7 @@
 	DUMP("\n");
 }
 
-static void _dump_DDCAPS(DWORD flagmask) {
+void _dump_DDCAPS(DWORD flagmask) {
 	int	i;
 	const struct {
 		DWORD	mask;
@@ -302,7 +302,7 @@
 	};
 	for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
 		if (flags[i].mask & flagmask)
-			DUMP("%s ",i,flags[i].name);
+			DUMP("%s ",flags[i].name);
 	DUMP("\n");
 }
 
@@ -1031,6 +1031,29 @@
 		this->palents[i].peBlue = palent[i-start].peBlue;
 		this->palents[i].peGreen = palent[i-start].peGreen;
 	}
+
+/* Insomnia's (Stea Greene's) Mods Start Here */
+/* FIXME: Still should free individual cells, but this fixes loss of */
+/*        unchange sections of old palette */
+
+	for (i=0;i<start;i++) {
+		xc.red = this->palents[i].peRed<<8;
+		xc.blue = this->palents[i].peBlue<<8;
+		xc.green = this->palents[i].peGreen<<8;
+		xc.flags = DoRed|DoBlue|DoGreen;
+		xc.pixel = i;
+		TSXStoreColor(display,this->cm,&xc);
+	}
+	for (i=end;i<256;i++) {
+		xc.red = this->palents[i].peRed<<8;
+		xc.blue = this->palents[i].peBlue<<8;
+		xc.green = this->palents[i].peGreen<<8;
+		xc.flags = DoRed|DoBlue|DoGreen;
+		xc.pixel = i;
+		TSXStoreColor(display,this->cm,&xc);
+	}
+/* End Insomnia's Mods */
+
 	XF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
 	return 0;
 }
@@ -1248,7 +1271,6 @@
 	LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
 ) {
 	int	i,*depths,depcount;
-	char	buf[200];
 
 	TRACE(ddraw, "(%p)->(%ld,%ld,%ld)\n",
 		      this, width, height, depth);
diff --git a/graphics/mapping.c b/graphics/mapping.c
index 0600e94..52eb7a3 100644
--- a/graphics/mapping.c
+++ b/graphics/mapping.c
@@ -56,35 +56,13 @@
  */
 BOOL32 WINAPI DPtoLP32( HDC32 hdc, LPPOINT32 points, INT32 count )
 {
-    FLOAT determinant=1.0, x, y;
-    
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     if (!dc) return FALSE;
 
-    if (dc->w.UseWorldXform)
-    {
-        determinant = dc->w.WorldXform.eM11*dc->w.WorldXform.eM22 -
-            dc->w.WorldXform.eM12*dc->w.WorldXform.eM21;
-        if (determinant > -1e-12 && determinant < 1e-12)
-            return FALSE;
-    }
-
     while (count--)
     {
-	if (dc->w.UseWorldXform)
-	{
-            x = (FLOAT)XDPTOLP( dc, points->x ) - dc->w.WorldXform.eDx;
-	    y = (FLOAT)YDPTOLP( dc, points->y ) - dc->w.WorldXform.eDy;
-	    points->x = (INT32)( (x*dc->w.WorldXform.eM22 -
-	       y*dc->w.WorldXform.eM21) / determinant );
-	    points->y = (INT32)( (-x*dc->w.WorldXform.eM12 +
-	       y*dc->w.WorldXform.eM11) / determinant );
-	}
-	else
-	{
-	    points->x = XDPTOLP( dc, points->x );
-	    points->y = YDPTOLP( dc, points->y );
-	}
+        if (!INTERNAL_DPTOLP( dc, points ))
+	    return FALSE;
         points++;
     }
     return TRUE;
@@ -114,30 +92,12 @@
  */
 BOOL32 WINAPI LPtoDP32( HDC32 hdc, LPPOINT32 points, INT32 count )
 {
-    FLOAT x, y;
-
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     if (!dc) return FALSE;
 
     while (count--)
     {
-	if (dc->w.UseWorldXform)
-	{
-	    x = (FLOAT)points->x * dc->w.WorldXform.eM11 +
-	    	(FLOAT)points->y * dc->w.WorldXform.eM21 +
-		dc->w.WorldXform.eDx;
-	    y = (FLOAT)points->x * dc->w.WorldXform.eM12 +
-	        (FLOAT)points->y * dc->w.WorldXform.eM22 +
-		dc->w.WorldXform.eDy;
-	    points->x = XLPTODP( dc, (INT32)x );
-	    points->y = YLPTODP( dc, (INT32)y );
-	    
-	}
-	else
-	{
-	    points->x = XLPTODP( dc, points->x );
-	    points->y = YLPTODP( dc, points->y );
-	}
+	INTERNAL_LPTODP( dc, points );
         points++;
     }
     return TRUE;
@@ -230,6 +190,7 @@
 	  return prevMode;
     }
     dc->w.MapMode = mode;
+    DC_UpdateXforms( dc );
     return prevMode;
 }
 
@@ -277,6 +238,7 @@
     dc->vportExtX = x;
     dc->vportExtY = y;
     if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
+    DC_UpdateXforms( dc );
     return TRUE;
 }
 
@@ -320,6 +282,7 @@
     }
     dc->vportOrgX = x;
     dc->vportOrgY = y;
+    DC_UpdateXforms( dc );
     return TRUE;
 }
 
@@ -366,6 +329,7 @@
     dc->wndExtX = x;
     dc->wndExtY = y;
     if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
+    DC_UpdateXforms( dc );
     return TRUE;
 }
 
@@ -408,6 +372,7 @@
     }
     dc->wndOrgX = x;
     dc->wndOrgY = y;
+    DC_UpdateXforms( dc );
     return TRUE;
 }
 
@@ -451,6 +416,7 @@
     }
     dc->vportOrgX += x;
     dc->vportOrgY += y;
+    DC_UpdateXforms( dc );
     return TRUE;
 }
 
@@ -494,6 +460,7 @@
     }
     dc->wndOrgX += x;
     dc->wndOrgY += y;
+    DC_UpdateXforms( dc );
     return TRUE;
 }
 
@@ -548,6 +515,7 @@
     if (dc->vportExtX == 0) dc->vportExtX = 1;
     if (dc->vportExtY == 0) dc->vportExtY = 1;
     if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
+    DC_UpdateXforms( dc );
     return TRUE;
 }
 
@@ -602,5 +570,6 @@
     if (dc->wndExtX == 0) dc->wndExtX = 1;
     if (dc->wndExtY == 0) dc->wndExtY = 1;
     if (dc->w.MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
+    DC_UpdateXforms( dc );
     return TRUE;
 }
diff --git a/graphics/metafiledrv/init.c b/graphics/metafiledrv/init.c
index 77ecba5..a789159 100644
--- a/graphics/metafiledrv/init.c
+++ b/graphics/metafiledrv/init.c
@@ -270,7 +270,7 @@
 				   HDC32 hdc /* Metafile DC to close */
 )
 {
-  return CloseMetaFile32(hdc);
+  return CloseMetaFile16(hdc);
 }
 
 
diff --git a/graphics/painting.c b/graphics/painting.c
index a142c91..4d75ddd 100644
--- a/graphics/painting.c
+++ b/graphics/painting.c
@@ -219,6 +219,10 @@
 {
     DC * dc = DC_GetDCPtr( hdc );
   
+    if(dc && PATH_IsPathOpen(dc->w.path))
+        if(!PATH_Rectangle(hdc, left, top, right, bottom))
+           return FALSE;
+
     return dc && dc->funcs->pRectangle &&
     	   dc->funcs->pRectangle(dc,left,top,right,bottom);
 }
@@ -959,7 +963,8 @@
     /* before it is displayed */
     fg = SetTextColor32(hdc, RGB(0, 0, 0));
     bg = SetBkColor32(hdc, RGB(255, 255, 255));
-    hbm = NULL; hbmsave = NULL; memdc = NULL; memdc = NULL; hbsave = NULL;
+    hbm = (HBITMAP32)NULL; hbmsave = (HBITMAP32)NULL;
+    memdc = (HDC32)NULL; hbsave = (HBRUSH32)NULL;
     retval = FALSE; /* assume failure */
     
     /* From here on we must use "goto cleanup" when something goes wrong */
diff --git a/graphics/path.c b/graphics/path.c
index a795af8..b68d286 100644
--- a/graphics/path.c
+++ b/graphics/path.c
@@ -62,15 +62,16 @@
 static BOOL32 PATH_PathToRegion(const GdiPath *pPath, INT32 nPolyFillMode,
    HRGN32 *pHrgn);
 static void   PATH_EmptyPath(GdiPath *pPath);
-static BOOL32 PATH_AddEntry(GdiPath *pPath, POINT32 point, BYTE flags);
+static BOOL32 PATH_AddEntry(GdiPath *pPath, const POINT32 *pPoint,
+   BYTE flags);
 static BOOL32 PATH_ReserveEntries(GdiPath *pPath, INT32 numEntries);
 static BOOL32 PATH_GetPathFromHDC(HDC32 hdc, GdiPath **ppPath);
-static BOOL32 PATH_DoArcPart(GdiPath *pPath, POINT32 corners[],
+static BOOL32 PATH_DoArcPart(GdiPath *pPath, FLOAT_POINT corners[],
    double angleStart, double angleEnd, BOOL32 addMoveTo);
-static void PATH_ScaleNormalizedPoint(POINT32 corners[], double x, double y,
-   POINT32 *pPoint);
-static void PATH_NormalizePoint(POINT32 corners[], const POINT32 *pPoint,
-   double *pX, double *pY);
+static void PATH_ScaleNormalizedPoint(FLOAT_POINT corners[], double x,
+   double y, POINT32 *pPoint);
+static void PATH_NormalizePoint(FLOAT_POINT corners[], const FLOAT_POINT
+   *pPoint, double *pX, double *pY);
 
 
 /***********************************************************************
@@ -218,6 +219,8 @@
       return FALSE;
    }
    
+   /* FIXME: Shouldn't we draw a line to the beginning of the figure? */
+   
    /* Set PT_CLOSEFIGURE on the last entry and start a new stroke */
    if(pPath->numEntriesUsed)
    {
@@ -436,7 +439,7 @@
    if(PATH_PathToRegion(pPath, GetPolyFillMode32(hdc), &hrgnPath))
    {
       hrgnClip=CreateRectRgn32(0, 0, 0, 0);
-      if(hrgnClip==NULL)
+      if(hrgnClip==(HRGN32)0)
          success=FALSE;
       else
       {
@@ -564,7 +567,6 @@
    
    /* Check that path is open */
    if(pPath->state!=PATH_Open)
-      /* FIXME: Do we have to call SetLastError? */
       return FALSE;
 
    /* Convert point to device coordinates */
@@ -580,12 +582,93 @@
       if(!GetCurrentPositionEx32(hdc, &pointCurPos) ||
          !LPtoDP32(hdc, &pointCurPos, 1))
          return FALSE;
-      if(!PATH_AddEntry(pPath, pointCurPos, PT_MOVETO))
+      if(!PATH_AddEntry(pPath, &pointCurPos, PT_MOVETO))
          return FALSE;
    }
    
    /* Add a PT_LINETO entry */
-   return PATH_AddEntry(pPath, point, PT_LINETO);
+   return PATH_AddEntry(pPath, &point, PT_LINETO);
+}
+
+/* PATH_Rectangle
+ *
+ * Should be called when a call to Rectangle is performed on a DC that has
+ * an open path. Returns TRUE if successful, else FALSE.
+ */
+BOOL32 PATH_Rectangle(HDC32 hdc, INT32 x1, INT32 y1, INT32 x2, INT32 y2)
+{
+   GdiPath *pPath;
+   POINT32 corners[2], pointTemp;
+   INT32   temp;
+
+   /* Get pointer to path */
+   if(!PATH_GetPathFromHDC(hdc, &pPath))
+      return FALSE;
+   
+   /* Check that path is open */
+   if(pPath->state!=PATH_Open)
+      return FALSE;
+
+   /* Convert points to device coordinates */
+   corners[0].x=x1;
+   corners[0].y=y1;
+   corners[1].x=x2;
+   corners[1].y=y2;
+   if(!LPtoDP32(hdc, corners, 2))
+      return FALSE;
+   
+   /* Make sure first corner is top left and second corner is bottom right */
+   if(corners[0].x>corners[1].x)
+   {
+      temp=corners[0].x;
+      corners[0].x=corners[1].x;
+      corners[1].x=temp;
+   }
+   if(corners[0].y>corners[1].y)
+   {
+      temp=corners[0].y;
+      corners[0].y=corners[1].y;
+      corners[1].y=temp;
+   }
+   
+   /* In GM_COMPATIBLE, don't include bottom and right edges */
+   if(GetGraphicsMode(hdc)==GM_COMPATIBLE)
+   {
+      corners[1].x--;
+      corners[1].y--;
+   }
+
+   /* Close any previous figure */
+   if(!CloseFigure32(hdc))
+   {
+      /* The CloseFigure call shouldn't have failed */
+      assert(FALSE);
+      return FALSE;
+   }
+
+   /* Add four points to the path */
+   pointTemp.x=corners[1].x;
+   pointTemp.y=corners[0].y;
+   if(!PATH_AddEntry(pPath, &pointTemp, PT_MOVETO))
+      return FALSE;
+   if(!PATH_AddEntry(pPath, corners, PT_LINETO))
+      return FALSE;
+   pointTemp.x=corners[0].x;
+   pointTemp.y=corners[1].y;
+   if(!PATH_AddEntry(pPath, &pointTemp, PT_LINETO))
+      return FALSE;
+   if(!PATH_AddEntry(pPath, corners+1, PT_LINETO))
+      return FALSE;
+
+   /* Close the rectangle figure */
+   if(!CloseFigure32(hdc))
+   {
+      /* The CloseFigure call shouldn't have failed */
+      assert(FALSE);
+      return FALSE;
+   }
+
+   return TRUE;
 }
 
 /* PATH_Ellipse
@@ -596,7 +679,9 @@
  */
 BOOL32 PATH_Ellipse(HDC32 hdc, INT32 x1, INT32 y1, INT32 x2, INT32 y2)
 {
-   return PATH_Arc(hdc, x1, y1, x2, y2, x1, 0, x1, 0);
+   // TODO: This should probably be revised to call PATH_AngleArc
+   // (once it exists)
+   return PATH_Arc(hdc, x1, y1, x2, y2, x1, (y1+y2)/2, x1, (y1+y2)/2);
 }
 
 /* PATH_Arc
@@ -608,16 +693,23 @@
 BOOL32 PATH_Arc(HDC32 hdc, INT32 x1, INT32 y1, INT32 x2, INT32 y2,
    INT32 xStart, INT32 yStart, INT32 xEnd, INT32 yEnd)
 {
-   GdiPath *pPath;
-   double  angleStart, angleEnd, angleStartQuadrant, angleEndQuadrant=0.0;
-           /* Initialize angleEndQuadrant to silence gcc's warning */
-   double  x, y;
-   POINT32 corners[2], pointStart, pointEnd;
-   BOOL32  start, end;
-   INT32   temp;
+   GdiPath     *pPath;
+   DC          *pDC;
+   double      angleStart, angleEnd, angleStartQuadrant, angleEndQuadrant=0.0;
+               /* Initialize angleEndQuadrant to silence gcc's warning */
+   double      x, y;
+   FLOAT_POINT corners[2], pointStart, pointEnd;
+   BOOL32      start, end;
+   INT32       temp;
 
    /* FIXME: This function should check for all possible error returns */
+   /* FIXME: Do we have to respect newStroke? */
    
+   /* Get pointer to DC */
+   pDC=DC_GetDCPtr(hdc);
+   if(pDC==NULL)
+      return FALSE;
+
    /* Get pointer to path */
    if(!PATH_GetPathFromHDC(hdc, &pPath))
       return FALSE;
@@ -626,34 +718,28 @@
    if(pPath->state!=PATH_Open)
       return FALSE;
 
+   /* FIXME: Do we have to close the current figure? */
+   
    /* Check for zero height / width */
-   /* FIXME: Should we do this before or after LPtoDP? */
+   /* FIXME: Only in GM_COMPATIBLE? */
    if(x1==x2 || y1==y2)
       return TRUE;
    
-   /* In GM_COMPATIBLE, don't include bottom and right edges */
-   if(GetGraphicsMode(hdc)==GM_COMPATIBLE)
-   {
-      /* FIXME: Should we do this before or after LPtoDP? */
-      x2--;
-      y2--;
-   }
-
    /* Convert points to device coordinates */
-   corners[0].x=x1;
-   corners[0].y=y1;
-   corners[1].x=x2;
-   corners[1].y=y2;
-   pointStart.x=xStart;
-   pointStart.y=yStart;
-   pointEnd.x=xEnd;
-   pointEnd.y=yEnd;
-   if(!LPtoDP32(hdc, corners, 2) || !LPtoDP32(hdc, &pointStart, 1) ||
-      !LPtoDP32(hdc, &pointEnd, 1))
-      return FALSE;
+   corners[0].x=(FLOAT)x1;
+   corners[0].y=(FLOAT)y1;
+   corners[1].x=(FLOAT)x2;
+   corners[1].y=(FLOAT)y2;
+   pointStart.x=(FLOAT)xStart;
+   pointStart.y=(FLOAT)yStart;
+   pointEnd.x=(FLOAT)xEnd;
+   pointEnd.y=(FLOAT)yEnd;
+   INTERNAL_LPTODP_FLOAT(pDC, corners);
+   INTERNAL_LPTODP_FLOAT(pDC, corners+1);
+   INTERNAL_LPTODP_FLOAT(pDC, &pointStart);
+   INTERNAL_LPTODP_FLOAT(pDC, &pointEnd);
 
-   /* Make sure first corner is top left and right corner is bottom right */
-   /* FIXME: Should we do this before or after LPtoDP? */
+   /* Make sure first corner is top left and second corner is bottom right */
    if(corners[0].x>corners[1].x)
    {
       temp=corners[0].x;
@@ -691,6 +777,13 @@
       }
    }
 
+   /* In GM_COMPATIBLE, don't include bottom and right edges */
+   if(GetGraphicsMode(hdc)==GM_COMPATIBLE)
+   {
+      corners[1].x--;
+      corners[1].y--;
+   }
+   
    /* Add the arc to the path with one Bezier spline per quadrant that the
     * arc spans */
    start=TRUE;
@@ -717,9 +810,9 @@
 
       /* Have we reached the last part of the arc? */
       if((GetArcDirection32(hdc)==AD_CLOCKWISE &&
-         angleEnd<=angleEndQuadrant) ||
+         angleEnd<angleEndQuadrant) ||
 	 (GetArcDirection32(hdc)==AD_COUNTERCLOCKWISE &&
-	 angleEnd>=angleEndQuadrant))
+	 angleEnd>angleEndQuadrant))
       {
 	 /* Adjust the end angle for this quadrant */
          angleEndQuadrant=angleEnd;
@@ -791,7 +884,7 @@
    /* Create a region from the strokes */
    hrgn=CreatePolyPolygonRgn32(pPath->pPoints, pNumPointsInStroke,
       numStrokes, nPolyFillMode);
-   if(hrgn==NULL)
+   if(hrgn==(HRGN32)0)
    {
       SetLastError(ERROR_NOT_ENOUGH_MEMORY);
       return FALSE;
@@ -823,10 +916,14 @@
  * or PT_BEZIERTO, optionally ORed with PT_CLOSEFIGURE. Returns TRUE if
  * successful, FALSE otherwise (e.g. if not enough memory was available).
  */
-BOOL32 PATH_AddEntry(GdiPath *pPath, POINT32 point, BYTE flags)
+BOOL32 PATH_AddEntry(GdiPath *pPath, const POINT32 *pPoint, BYTE flags)
 {
    assert(pPath!=NULL);
    
+   /* FIXME: If newStroke is true, perhaps we want to check that we're
+    * getting a PT_MOVETO
+    */
+
    /* Check that path is open */
    if(pPath->state!=PATH_Open)
       return FALSE;
@@ -836,9 +933,13 @@
       return FALSE;
 
    /* Store information in path entry */
-   pPath->pPoints[pPath->numEntriesUsed]=point;
+   pPath->pPoints[pPath->numEntriesUsed]=*pPoint;
    pPath->pFlags[pPath->numEntriesUsed]=flags;
 
+   /* If this is PT_CLOSEFIGURE, we have to start a new stroke next time */
+   if((flags & PT_CLOSEFIGURE) == PT_CLOSEFIGURE)
+      pPath->newStroke=TRUE;
+
    /* Increment entry count */
    pPath->numEntriesUsed++;
 
@@ -936,7 +1037,7 @@
  * point is added to the path; otherwise, it is assumed that the current
  * position is equal to the first control point.
  */
-static BOOL32 PATH_DoArcPart(GdiPath *pPath, POINT32 corners[],
+static BOOL32 PATH_DoArcPart(GdiPath *pPath, FLOAT_POINT corners[],
    double angleStart, double angleEnd, BOOL32 addMoveTo)
 {
    double  halfAngle, a;
@@ -950,21 +1051,30 @@
 
    /* Compute control points */
    halfAngle=(angleEnd-angleStart)/2.0;
-   a=4.0/3.0*(1-cos(halfAngle))/sin(halfAngle);
-   xNorm[0]=cos(angleStart);
-   yNorm[0]=sin(angleStart);
-   xNorm[1]=xNorm[0] - a*yNorm[0];
-   yNorm[1]=yNorm[0] + a*xNorm[0];
-   xNorm[3]=cos(angleEnd);
-   yNorm[3]=sin(angleEnd);
-   xNorm[2]=xNorm[3] + a*yNorm[3];
-   yNorm[2]=yNorm[3] - a*xNorm[3];
+   if(fabs(halfAngle)>1e-8)
+   {
+      a=4.0/3.0*(1-cos(halfAngle))/sin(halfAngle);
+      xNorm[0]=cos(angleStart);
+      yNorm[0]=sin(angleStart);
+      xNorm[1]=xNorm[0] - a*yNorm[0];
+      yNorm[1]=yNorm[0] + a*xNorm[0];
+      xNorm[3]=cos(angleEnd);
+      yNorm[3]=sin(angleEnd);
+      xNorm[2]=xNorm[3] + a*yNorm[3];
+      yNorm[2]=yNorm[3] - a*xNorm[3];
+   }
+   else
+      for(i=0; i<4; i++)
+      {
+	 xNorm[i]=cos(angleStart);
+	 yNorm[i]=sin(angleStart);
+      }
    
    /* Add starting point to path if desired */
    if(addMoveTo)
    {
       PATH_ScaleNormalizedPoint(corners, xNorm[0], yNorm[0], &point);
-      if(!PATH_AddEntry(pPath, point, PT_MOVETO))
+      if(!PATH_AddEntry(pPath, &point, PT_MOVETO))
          return FALSE;
    }
 
@@ -972,7 +1082,7 @@
    for(i=1; i<4; i++)
    {
       PATH_ScaleNormalizedPoint(corners, xNorm[i], yNorm[i], &point);
-      if(!PATH_AddEntry(pPath, point, PT_BEZIERTO))
+      if(!PATH_AddEntry(pPath, &point, PT_BEZIERTO))
          return FALSE;
    }
 
@@ -986,12 +1096,12 @@
  * coordinates (-1.0, -1.0) correspond to corners[0], the coordinates
  * (1.0, 1.0) correspond to corners[1].
  */
-static void PATH_ScaleNormalizedPoint(POINT32 corners[], double x, double y,
-   POINT32 *pPoint)
+static void PATH_ScaleNormalizedPoint(FLOAT_POINT corners[], double x,
+   double y, POINT32 *pPoint)
 {
-   pPoint->x=(INT32)floor( (double)corners[0].x +
+   pPoint->x=GDI_ROUND( (double)corners[0].x +
       (double)(corners[1].x-corners[0].x)*0.5*(x+1.0) );
-   pPoint->y=(INT32)floor( (double)corners[0].y +
+   pPoint->y=GDI_ROUND( (double)corners[0].y +
       (double)(corners[1].y-corners[0].y)*0.5*(y+1.0) );
 }
 
@@ -1000,7 +1110,8 @@
  * Normalizes a point with respect to the box whose corners are passed in
  * "corners". The normalized coordinates are stored in "*pX" and "*pY".
  */
-static void PATH_NormalizePoint(POINT32 corners[], const POINT32 *pPoint,
+static void PATH_NormalizePoint(FLOAT_POINT corners[],
+   const FLOAT_POINT *pPoint,
    double *pX, double *pY)
 {
    *pX=(double)(pPoint->x-corners[0].x)/(double)(corners[1].x-corners[0].x) *
diff --git a/graphics/win16drv/font.c b/graphics/win16drv/font.c
index 7ed9f71..fb9d1e5 100644
--- a/graphics/win16drv/font.c
+++ b/graphics/win16drv/font.c
@@ -200,8 +200,8 @@
  */
 
 
-WORD WINAPI WineEnumDFontCallback(LPLOGFONT16 lpLogFont,
-                                  LPTEXTMETRIC16 lpTextMetrics,
+WORD WINAPI WineEnumDFontCallback(LPENUMLOGFONT16 lpLogFont,
+                                  LPNEWTEXTMETRIC16 lpTextMetrics,
                                   WORD wFontType, LONG lpClientData) 
 {
     TRACE(win16drv, "In WineEnumDFontCallback plf=%p\n", lpLogFont);
diff --git a/graphics/win16drv/prtdrv.c b/graphics/win16drv/prtdrv.c
index 9a7bde1..43bb7e8 100644
--- a/graphics/win16drv/prtdrv.c
+++ b/graphics/win16drv/prtdrv.c
@@ -674,7 +674,7 @@
     if (wStyle < 0) { /* Free extra memory of given object's structure */
 	switch ( -wStyle ) {
             case DRVOBJ_PEN:    {
-                                LPLOGPEN16 DeletePen = (LPLOGPEN16)lpInObj;
+                                /* LPLOGPEN16 DeletePen = (LPLOGPEN16)lpInObj; */
 
                                 fprintf(stderr, "DRVOBJ_PEN_delete\n");
 				break;
@@ -684,8 +684,8 @@
                                 break;
 				}
             case DRVOBJ_FONT:	{
-				LPTEXTXFORM16 TextXForm
-					= (LPTEXTXFORM16)lpTextXForm;
+				/* LPTEXTXFORM16 TextXForm
+					= (LPTEXTXFORM16)lpTextXForm; */
 				fprintf(stderr, "DRVOBJ_FONT_delete\n");
                                 break;
 				}
@@ -720,7 +720,7 @@
 	    case DRVOBJ_BRUSH: {
 				LPLOGBRUSH16 InBrush  = (LPLOGBRUSH16)lpInObj;
 				LPLOGBRUSH16 OutBrush = (LPLOGBRUSH16)lpOutObj;
-                                LPPOINT16 Point = (LPPOINT16)lpTextXForm;
+                                /* LPPOINT16 Point = (LPPOINT16)lpTextXForm; */
 
 				fprintf(stderr, "DRVOBJ_BRUSH\n");
 				if (!lpOutObj) return sizeof(LOGBRUSH16);
@@ -734,8 +734,8 @@
 				}
 		               }
 	    case DRVOBJ_FONT: {
-                                LPTEXTXFORM16 TextXForm
-                                        = (LPTEXTXFORM16)lpTextXForm;
+                                /* LPTEXTXFORM16 TextXForm
+                                        = (LPTEXTXFORM16)lpTextXForm; */
                                 fprintf(stderr, "DRVOBJ_FONT\n");
 				return 0;/* DISPLAY.DRV doesn't realize fonts */
 			      }
diff --git a/graphics/wing.c b/graphics/wing.c
index da9c315..962a752 100644
--- a/graphics/wing.c
+++ b/graphics/wing.c
@@ -70,7 +70,7 @@
   __initWinG();
 
   if( __WinGOK > 0 )
-	return CreateCompatibleDC16(NULL);
+	return CreateCompatibleDC16(0);
   return (HDC16)NULL;
 }
 
diff --git a/graphics/x11drv/graphics.c b/graphics/x11drv/graphics.c
index 8442320..8874368 100644
--- a/graphics/x11drv/graphics.c
+++ b/graphics/x11drv/graphics.c
@@ -91,7 +91,7 @@
     xend   = XLPTODP( dc, xend );
     yend   = YLPTODP( dc, yend );
 
-    if ((left == right) || (top == bottom)) return FALSE;
+    if ((left == right) || (top == bottom)) return TRUE;
 
     if (left > right) { tmp=left; left=right; right=tmp; }
     if (top > bottom) { tmp=top; top=bottom; bottom=tmp; } 
diff --git a/graphics/x11drv/xfont.c b/graphics/x11drv/xfont.c
index 505f444..aaf0e20 100644
--- a/graphics/x11drv/xfont.c
+++ b/graphics/x11drv/xfont.c
@@ -460,8 +460,8 @@
      char *s;
      sprintf(h_string, "[%+f%+f%+f%+f]", h_matrix[0], h_matrix[1], h_matrix[2], h_matrix[3]);
      sprintf(point_string, "[%+f%+f%+f%+f]", point_matrix[0], point_matrix[1], point_matrix[2], point_matrix[3]);
-     while (s = strchr(h_string, '-')) *s='~';
-     while (s = strchr(point_string, '-')) *s='~';
+     while ((s = strchr(h_string, '-'))) *s='~';
+     while ((s = strchr(point_string, '-'))) *s='~';
    } else {
      sprintf(h_string, "%d", h);
      sprintf(point_string, "%d", point);