Release 940420

Wed Apr 20 14:53:35 1994  Bob Amstadt  (bob@pooh)

	* [tools/build.c] [if1632/call.S] [if1632/Imakefile]
	Fixed bug for non-Linux systems.

Apr 18, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte)

	* [windows/win.c]
	Bug fixed in CreateWindowEx() : Now use SetMenu() for menubar setup.
	New empty stub for function SetSysModalWindow().

	* [misc/exec.c]
	New empty stub for function ExitWindows().

	* [objects/font.c]
	New empty stub for function EnumFonts().

	* New file [misc/property.c]
	New functions RemoveProp(), GetProp(), SetProp() & EnumProps().

	* New file [misc/shell.c]
	New empty stubs for function RegisterShellProc(), 
			ShellExecute() & ShellProc().

	* New files [loader/task.c] & [include/task.h]
	Move functions GetWindowTask(), GetNumTask(), EnumTaskWindows()
		from 'loader/library.c'.

	* [if1632/user.c] [if1632/kernel.c]
	Put Atoms functions entries.

	* [controls/combo.c]
	New functions DirDlgSelectComboBox() & DirDlgListComboBox().

	* [controls/listbox.c]
	New functions DirDlgSelect() & DirDlgList().

Sun Apr 17 20:57:59 1994  Erik Bos (erik@trashcan.hacktic.nl)

	* [objects/test.c]
	GrayString() added.

	* [if1632/callback.c]
	CallGrayStringProc() added.

	* [if1632/relay.c] [if1632/mmsystem.spec]
	Added.

	* [if1632/kernel.spec] [if1632/user.spec]
	Added forgotten specs for atom functions.

Tue Apr 12 00:05:31 1994  Bob Amstadt  (bob@pooh)

	* misc/spy.c (SpyInit): Added more message types

	* [windows/mdi.c] [include/mdi.h]
	Maximizing and restoring child windows.
	Tiling of child windows.

Mon Apr 11 20:48:28 1994  Alexandre Julliard  (julliard@lamisun.epfl.ch)

	* [windows/winpos.c]
	Revert focus and activation to previous window when hiding a window.

	* [windows/syscolor.c]
	Implemented system color objects (brushes and pens created at
	SetSysColor() time for better performance).

	* [windows/graphics.c] [windows/nonclient.c] [controls/button.c]
	Changed painting code to use system color objects.

	* [windows/message.c]
	New function MSG_InternalGetMessage() for internal messages
	loops (e.g. for dialogs or menus).

	* [windows/hook.c] [include/hook.h]  (New files)
	Beginning of the window hooks implementation.

	* [windows/dialog.c]
	Use new function MSG_InternalGetMessage() in DialogBox().

	* [if1632/callback.c]
	Added function CallHookProc().

Apr 11, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte)

	* [windows/event.c]
	Bug fix : WM_CHARs are sent to focused window like WM_KEY???.

	* [misc/exec.c]
	Nothing much more than a stub for LoadModule(), I saw there a lot
		to be done in that corner, I will come back later ...

	* [loader/library.c]
	New functions GetWindowTask(), GetNumTask(), EnumTaskWindows() 
			and associated modules & tasks linked-lists.
	(it's only an 'emerging bud', more to come next weeks).

	* [loader/wine.c]
	Use LoadLibrary() instead of LoadImage() for 'sysres.dll'.

	* [control/menu.c]
	You can now click outside menu region without problem.
	Keyboard navig more smootly, even if a child has the focus.
	Bug fix in InsertItem(), (bad linklist when insert point not found).
	change Realloc for Free & Alloc in ModifyItem().
	MF_STRING now set BLACK_PEN to fix bug of bad color of the underscores 
		done by DrawText(), (maybe it should done in DrawText() itself ?).

Sun Apr 10 14:06:08 1994  Erik Bos (erik@trashcan.hacktic.nl)

	* [misc/profile.c]
	.INI files will now be stored in / loaded from the windows dir
	if no path is supplied.

	* [if1632/kernel.spec]
	Fixed GetDriveType's prototype.

	* [if1632/winsock.spec] [include/winsock.h] [misc/winsocket.c]
	Fixed prototypes: winsock uses a word as socket handle not an int.

	* [misc/winsocket.c]
	Added heap allocation for returned structures.
	Added non-blocking WSAAsyncGetXbyY() functions as blocking ones.

	* [loader/wine.c]
	Added IsDLLLoaded(), used in LoadImage() to prevent loading
	a dll multiple times.
	Directory is added to wine's path when a fullpath is supplied when
	starting wine.
	LoadImage(): DLL filename used instead DLL's own internal name,
	fixes 'Bad DLL name' errors.

Sat Apr  9 08:26:03 1994  David Metcalfe <david@prism.demon.co.uk>

	* [controls/edit.c] [controls/widgets.c]
	First release of edit control.
diff --git a/objects/font.c b/objects/font.c
index 382976b..b346d8a 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -348,6 +348,16 @@
 }
 
 
+/***********************************************************************
+ *           SetMapperFlags    (GDI.349)
+ */
+DWORD SetMapperFlags(HDC hDC, DWORD dwFlag)
+{
+    printf("SetmapperFlags(%04X, %08X) // Empty Stub !\n", hDC, dwFlag); 
+    return 0L;
+}
+
+ 
 /***********************************************************************/
 
 #define CI_NONEXISTCHAR(cs) (((cs)->width == 0) && \
@@ -379,16 +389,6 @@
 
 
 /***********************************************************************
- *           SetMapperFlags    (GDI.349)
- */
-DWORD SetMapperFlags(HDC hDC, DWORD dwFlag)
-{
-    printf("SetmapperFlags(%04X, %08X) // Empty Stub !\n", hDC, dwFlag); 
-    return 0L;
-}
-
- 
-/***********************************************************************
  *           GetCharWidth    (GDI.350)
  */
 BOOL GetCharWidth(HDC hdc, WORD wFirstChar, WORD wLastChar, LPINT lpBuffer)
@@ -415,6 +415,22 @@
     {
 	CI_GET_CHAR_INFO(xfont, i, def, cs);
 	*(lpBuffer + j) = cs->width;
+	if (*(lpBuffer + j) < 0)
+	    *(lpBuffer + j) = 0;
     }
     return TRUE;
 }
+
+
+/*************************************************************************
+ *				EnumFonts			[GDI.70]
+ */
+int EnumFonts(HDC hDC, LPSTR lpFaceName, FARPROC lpFontFunc, LPSTR lpData)
+{
+	printf("EMPTY STUB !!! EnumFonts(%04X, %08X, %08X, %08X)\n", 
+						hDC, lpFaceName, lpFontFunc, lpData);
+	return -1;
+}
+
+
+
diff --git a/objects/metafile.c b/objects/metafile.c
new file mode 100644
index 0000000..903cfa7
--- /dev/null
+++ b/objects/metafile.c
@@ -0,0 +1,444 @@
+/*
+ * Metafile functions
+ *
+ * Copyright  David W. Metcalfe, 1994
+ */
+
+static char Copyright[] = "Copyright  David W. Metcalfe, 1994";
+
+#include "windows.h"
+#include "gdi.h"
+#include "metafile.h"
+#include "prototypes.h"
+
+#define DEBUG_METAFILE
+
+/******************************************************************
+ *         CreateMetafile         GDI.125
+ */
+HANDLE CreateMetaFile(LPSTR lpFilename)
+{
+    DC *dc;
+    HANDLE handle;
+    METAFILE *mf;
+    METAHEADER *mh;
+
+#ifdef DEBUG_METAFILE
+    printf("CreateMetaFile: %s\n", lpFilename);
+#endif
+
+    handle = GDI_AllocObject(sizeof(DC), METAFILE_DC_MAGIC);
+    if (!handle) return 0;
+    dc = (DC *)GDI_HEAP_ADDR(handle);
+
+    if (!(dc->w.hMetaFile = GlobalAlloc(GMEM_MOVEABLE, sizeof(METAFILE))))
+	return 0;
+    mf = (METAFILE *)GlobalLock(dc->w.hMetaFile);
+    if (!(mf->hMetaHdr = GlobalAlloc(GMEM_MOVEABLE, sizeof(METAHEADER))))
+    {
+	GlobalFree(dc->w.hMetaFile);
+	return 0;
+    }
+    mh = (METAHEADER *)GlobalLock(mf->hMetaHdr);
+
+    mf->wMagic = METAFILE_MAGIC;
+    mh->mtHeaderSize = MFHEADERSIZE / 2;
+    mh->mtVersion = MFVERSION;
+    mh->mtSize = MFHEADERSIZE / 2;
+    mh->mtNoObjects = 0;
+    mh->mtMaxRecord = 0;
+    mh->mtNoParameters = 0;
+
+    if (lpFilename)          /* disk based metafile */
+    {
+	mh->mtType = 1;
+	strcpy(mf->Filename, lpFilename);
+	mf->hFile = _lcreat(lpFilename, 0);
+	if (_lwrite(mf->hFile, (char *)mh, MFHEADERSIZE) == -1)
+	{
+	    GlobalFree(mf->hMetaHdr);
+	    GlobalFree(dc->w.hMetaFile);
+	    return 0;
+	}
+    }
+    else                     /* memory based metafile */
+	mh->mtType = 0;
+
+    GlobalUnlock(mf->hMetaHdr);
+    GlobalUnlock(dc->w.hMetaFile);
+    return handle;
+}
+
+
+/******************************************************************
+ *         CloseMetafile         GDI.126
+ */
+HMETAFILE CloseMetaFile(HDC hdc)
+{
+    DC *dc;
+    METAFILE *mf;
+    METAHEADER *mh;
+    HMETAFILE hmf;
+    char buffer[15];
+    METARECORD *mr = (METARECORD *)&buffer;
+
+#ifdef DEBUG_METAFILE
+    printf("CloseMetaFile\n");
+#endif
+
+    dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
+    if (!dc) return 0;
+    mf = (METAFILE *)GlobalLock(dc->w.hMetaFile);
+    mh = (METAHEADER *)GlobalLock(mf->hMetaHdr);
+
+    /* Construct the end of metafile record - this is undocumented
+     * but is created by MS Windows 3.1.
+     */
+    mr->rdSize = 3;
+    mr->rdFunction = META_EOF;
+    MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
+
+    if (mh->mtType == 1)        /* disk based metafile */
+    {
+	if (_llseek(mf->hFile, 0L, 0) == -1)
+	{
+	    GlobalFree(mf->hMetaHdr);
+	    GlobalFree(dc->w.hMetaFile);
+	    return 0;
+	}
+	if (_lwrite(mf->hFile, (char *)mh, MFHEADERSIZE) == -1)
+	{
+	    GlobalFree(mf->hMetaHdr);
+	    GlobalFree(dc->w.hMetaFile);
+	    return 0;
+	}
+	_lclose(mf->hFile);
+    }
+
+    GlobalUnlock(mf->hMetaHdr);
+    hmf = dc->w.hMetaFile;
+    GDI_FreeObject(hdc);
+    return hmf;
+}
+
+
+/******************************************************************
+ *         DeleteMetafile         GDI.127
+ */
+BOOL DeleteMetaFile(HMETAFILE hmf)
+{
+    METAFILE *mf = (METAFILE *)GlobalLock(hmf);
+
+    if (mf->wMagic != METAFILE_MAGIC)
+	return FALSE;
+
+    GlobalFree(mf->hMetaHdr);
+    GlobalFree(hmf);
+    return TRUE;
+}
+
+
+/******************************************************************
+ *         MF_WriteRecord
+ */
+BOOL MF_WriteRecord(HMETAFILE hmf, METARECORD *mr, WORD rlen)
+{
+    DWORD len;
+    METAFILE *mf = (METAFILE *)GlobalLock(hmf);
+    METAHEADER *mh = (METAHEADER *)GlobalLock(mf->hMetaHdr);
+
+    if (mh->mtType == 0)          /* memory based metafile */
+    {
+	len = mh->mtSize * 2 + rlen;
+	GlobalUnlock(mf->hMetaHdr);
+	mf->hMetaHdr = GlobalReAlloc(mf->hMetaHdr, len, GMEM_MOVEABLE);
+	mh = (METAHEADER *)GlobalLock(mf->hMetaHdr);
+	memcpy(mh + mh->mtSize * 2, mr, rlen);
+    }
+    else if (mh->mtType == 1)     /* disk based metafile */
+    {
+	if (_lwrite(mf->hFile, (char *)mr, rlen) == -1)
+	{
+	    GlobalUnlock(mf->hMetaHdr);
+	    return FALSE;
+	}
+    }
+    else
+    {
+	GlobalUnlock(mf->hMetaHdr);
+	return FALSE;
+    }
+
+    mh->mtSize += rlen / 2;
+    mh->mtMaxRecord = max(mh->mtMaxRecord, rlen / 2);
+    GlobalUnlock(mf->hMetaHdr);
+    return TRUE;
+}
+
+
+/******************************************************************
+ *         MF_MetaParam1
+ */
+BOOL MF_MetaParam1(DC *dc, short func, short param1)
+{
+    char buffer[8];
+    METARECORD *mr = (METARECORD *)&buffer;
+
+    mr->rdSize = 4;
+    mr->rdFunction = func;
+    *(mr->rdParam) = param1;
+    return MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
+}
+
+
+/******************************************************************
+ *         MF_MetaParam2
+ */
+BOOL MF_MetaParam2(DC *dc, short func, short param1, short param2)
+{
+    char buffer[10];
+    METARECORD *mr = (METARECORD *)&buffer;
+
+    mr->rdSize = 5;
+    mr->rdFunction = func;
+    *(mr->rdParam) = param2;
+    *(mr->rdParam + 1) = param1;
+    return MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
+}
+
+
+/******************************************************************
+ *         MF_MetaParam4
+ */
+BOOL MF_MetaParam4(DC *dc, short func, short param1, short param2, 
+		   short param3, short param4)
+{
+    char buffer[14];
+    METARECORD *mr = (METARECORD *)&buffer;
+
+    mr->rdSize = 7;
+    mr->rdFunction = func;
+    *(mr->rdParam) = param4;
+    *(mr->rdParam + 1) = param3;
+    *(mr->rdParam + 2) = param2;
+    *(mr->rdParam + 3) = param1;
+    return MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
+}
+
+
+/******************************************************************
+ *         MF_MetaParam6
+ */
+BOOL MF_MetaParam6(DC *dc, short func, short param1, short param2, 
+		   short param3, short param4, short param5, short param6)
+{
+    char buffer[18];
+    METARECORD *mr = (METARECORD *)&buffer;
+
+    mr->rdSize = 9;
+    mr->rdFunction = func;
+    *(mr->rdParam) = param6;
+    *(mr->rdParam + 1) = param5;
+    *(mr->rdParam + 2) = param4;
+    *(mr->rdParam + 3) = param3;
+    *(mr->rdParam + 4) = param2;
+    *(mr->rdParam + 5) = param1;
+    return MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
+}
+
+
+/******************************************************************
+ *         MF_MetaParam8
+ */
+BOOL MF_MetaParam8(DC *dc, short func, short param1, short param2, 
+		   short param3, short param4, short param5,
+		   short param6, short param7, short param8)
+{
+    char buffer[22];
+    METARECORD *mr = (METARECORD *)&buffer;
+
+    mr->rdSize = 11;
+    mr->rdFunction = func;
+    *(mr->rdParam) = param8;
+    *(mr->rdParam + 1) = param7;
+    *(mr->rdParam + 2) = param6;
+    *(mr->rdParam + 3) = param5;
+    *(mr->rdParam + 4) = param4;
+    *(mr->rdParam + 5) = param3;
+    *(mr->rdParam + 6) = param2;
+    *(mr->rdParam + 7) = param1;
+    return MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
+}
+
+
+/******************************************************************
+ *         MF_CreateBrushIndirect
+ */
+BOOL MF_CreateBrushIndirect(DC *dc, LOGBRUSH *logbrush)
+{
+    char buffer[sizeof(METARECORD) - 2 + sizeof(LOGBRUSH)];
+    METARECORD *mr = (METARECORD *)&buffer;
+    METAFILE *mf = (METAFILE *)GlobalLock(dc->w.hMetaFile);
+    METAHEADER *mh = (METAHEADER *)GlobalLock(mf->hMetaHdr);
+
+#ifdef DEBUG_METAFILE
+    printf("MF_CreateBrushIndirect\n");
+#endif
+    mr->rdSize = (sizeof(METARECORD) + sizeof(LOGBRUSH) - 2) / 2;
+    mr->rdFunction = META_CREATEBRUSHINDIRECT;
+    memcpy(&(mr->rdParam), logbrush, sizeof(LOGBRUSH));
+    if (!MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2))
+	return FALSE;
+
+    mr->rdSize = sizeof(METARECORD) / 2;
+    mr->rdFunction = META_SELECTOBJECT;
+    *(mr->rdParam) = mh->mtNoObjects++;
+    return MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
+}
+
+
+/******************************************************************
+ *         MF_CreatePatternBrush
+ */
+BOOL MF_CreatePatternBrush(DC *dc, LOGBRUSH *logbrush)
+{
+    DWORD len, bmSize, biSize;
+    HANDLE hmr;
+    METARECORD *mr;
+    BITMAPOBJ *bmp;
+    BITMAPINFO *info;
+    char buffer[sizeof(METARECORD)];
+    METAFILE *mf = (METAFILE *)GlobalLock(dc->w.hMetaFile);
+    METAHEADER *mh = (METAHEADER *)GlobalLock(mf->hMetaHdr);
+
+    switch (logbrush->lbStyle)
+    {
+    case BS_PATTERN:
+	bmp = (BITMAPOBJ *)GDI_GetObjPtr(logbrush->lbHatch, BITMAP_MAGIC);
+	if (!bmp) return FALSE;
+	len = sizeof(METARECORD) + sizeof(BITMAPINFOHEADER) + 
+	      (bmp->bitmap.bmHeight * bmp->bitmap.bmWidthBytes) + 2;
+	if (!(hmr = GlobalAlloc(GMEM_MOVEABLE, len)))
+	    return FALSE;
+	mr = (METARECORD *)GlobalLock(hmr);
+	memset(mr, 0, len);
+	mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
+	mr->rdSize = len / 2;
+	*(mr->rdParam) = logbrush->lbStyle;
+	memcpy(mr->rdParam + (sizeof(BITMAPINFOHEADER) / 2) + 2, 
+	       bmp->bitmap.bmBits, 
+	       bmp->bitmap.bmHeight * bmp->bitmap.bmWidthBytes);
+	break;
+
+    case BS_DIBPATTERN:
+	info = (BITMAPINFO *)GlobalLock(logbrush->lbHatch);
+	bmSize = info->bmiHeader.biSizeImage;
+	if (!bmSize)
+	    bmSize = (info->bmiHeader.biWidth * info->bmiHeader.biBitCount 
+		    + 31) / 32 * 8 * info->bmiHeader.biHeight;
+	biSize = DIB_BitmapInfoSize(info, LOWORD(logbrush->lbColor)); 
+	len = sizeof(METARECORD) + biSize + bmSize + 2;
+	if (!(hmr = GlobalAlloc(GMEM_MOVEABLE, len)))
+	    return FALSE;
+	mr = (METARECORD *)GlobalLock(hmr);
+	memset(mr, 0, len);
+	mr->rdFunction = META_DIBCREATEPATTERNBRUSH;
+	mr->rdSize = len / 2;
+	*(mr->rdParam) = logbrush->lbStyle;
+	*(mr->rdParam + 1) = LOWORD(logbrush->lbColor);
+	memcpy(mr->rdParam + 2, info, biSize + bmSize);
+	break;
+    }
+    if (!MF_WriteRecord(dc->w.hMetaFile, mr, len))
+    {
+	GlobalFree(hmr);
+	return FALSE;
+    }
+
+    GlobalFree(hmr);
+    mr = (METARECORD *)&buffer;
+    mr->rdSize = sizeof(METARECORD) / 2;
+    mr->rdFunction = META_SELECTOBJECT;
+    (WORD)(*(mr->rdParam)) = mh->mtNoObjects++;
+    return MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
+}
+
+
+/******************************************************************
+ *         MF_CreatePenIndirect
+ */
+BOOL MF_CreatePenIndirect(DC *dc, LOGPEN *logpen)
+{
+    char buffer[sizeof(METARECORD) - 2 + sizeof(LOGPEN)];
+    METARECORD *mr = (METARECORD *)&buffer;
+    METAFILE *mf = (METAFILE *)GlobalLock(dc->w.hMetaFile);
+    METAHEADER *mh = (METAHEADER *)GlobalLock(mf->hMetaHdr);
+
+#ifdef DEBUG_METAFILE
+    printf("MF_CreatePenIndirect\n");
+#endif
+    mr->rdSize = (sizeof(METARECORD) + sizeof(LOGPEN) - 2) / 2;
+    mr->rdFunction = META_CREATEPENINDIRECT;
+    memcpy(&(mr->rdParam), logpen, sizeof(LOGPEN));
+    if (!MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2))
+	return FALSE;
+
+    mr->rdSize = sizeof(METARECORD) / 2;
+    mr->rdFunction = META_SELECTOBJECT;
+    (WORD)(*(mr->rdParam)) = mh->mtNoObjects++;
+    return MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
+}
+
+
+/******************************************************************
+ *         MF_TextOut
+ */
+BOOL MF_TextOut(DC *dc, short x, short y, LPSTR str, short count)
+{
+    BOOL rc;
+    DWORD len;
+    HANDLE hmr;
+    METARECORD *mr;
+
+    len = sizeof(METARECORD) + count + 4;
+    if (!(hmr = GlobalAlloc(GMEM_MOVEABLE, len)))
+	return FALSE;
+    mr = (METARECORD *)GlobalLock(hmr);
+    memset(mr, 0, len);
+
+    mr->rdSize = len / 2;
+    mr->rdFunction = META_TEXTOUT;
+    *(mr->rdParam) = count;
+    memcpy(mr->rdParam + 1, str, count);
+    *(mr->rdParam + (count / 2) + 1) = y;
+    *(mr->rdParam + (count / 2) + 2) = x;
+    rc = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
+    GlobalFree(hmr);
+    return rc;
+}
+
+
+/******************************************************************
+ *         MF_MetaPoly - implements Polygon and Polyline
+ */
+BOOL MF_MetaPoly(DC *dc, short func, LPPOINT pt, short count)
+{
+    BOOL rc;
+    DWORD len;
+    HANDLE hmr;
+    METARECORD *mr;
+
+    len = sizeof(METARECORD) + (count * 4); 
+    if (!(hmr = GlobalAlloc(GMEM_MOVEABLE, len)))
+	return FALSE;
+    mr = (METARECORD *)GlobalLock(hmr);
+    memset(mr, 0, len);
+
+    mr->rdSize = len / 2;
+    mr->rdFunction = func;
+    *(mr->rdParam) = count;
+    memcpy(mr->rdParam + 1, pt, count * 4);
+    rc = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
+    GlobalFree(hmr);
+    return rc;
+}
diff --git a/objects/text.c b/objects/text.c
index a900baa..ae01b20 100644
--- a/objects/text.c
+++ b/objects/text.c
@@ -7,7 +7,7 @@
 static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
 
 #include <X11/Xatom.h>
-
+#include "windows.h"
 #include "gdi.h"
 
 #define TAB     9
@@ -265,7 +265,7 @@
 	y = dc->w.CursPosY;
     }
 #ifdef DEBUG_TEXT
-    printf( "TextOut: %d,%d '%s'\n", x, y, str );
+    printf( "TextOut: %d,%d '%s', %d\n", x, y, str, count );
 #endif
     x = XLPTODP( dc, x );
     y = YLPTODP( dc, y );
@@ -381,3 +381,25 @@
     
     return TRUE;
 }
+
+/***********************************************************************
+ *		GrayString (USER.185)
+ */
+BOOL GrayString(HDC hdc, HBRUSH hbr, FARPROC gsprc, LPARAM lParam, 
+		INT cch, INT x, INT y, INT cx, INT cy)
+{
+	int s, current_color;
+
+	if (gsprc) {
+		return CallGrayStringProc(gsprc, hdc, lParam, 
+					cch ? cch : lstrlen((LPCSTR) lParam) );
+	} else {
+		current_color = GetTextColor(hdc);
+		SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT) );
+		s = TextOut(hdc, x, y, (LPSTR) lParam, 
+				cch ? cch : lstrlen((LPCSTR) lParam) );
+		SetTextColor(hdc, current_color);
+		
+		return s;
+	}
+}