Release 0.6

Tue Jan  4 13:01:33 1994  David Metcalfe <david@prism.demon.co.uk>

        * [window/caret.c]
        Modified code to use system timer.

Jan 9, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte)

	* [windows/win.c]
	Windows create if required new XLIB MenuBar & CaptionBar.

	* [windows/defwnd.c]
	WM_CALCSIZE Move & Resize caption, menubar & scrollbars.
	(I'm not sure it's the good place for it, but it work...)

	* [loader/resource.c]
	optimize in FindResourceByNumber, make lseek() if next type ...

	* [controls/scroll.c]
	scrollbar buttons are now using system resources bitmaps.

	* [controls/caption.c] - new file ...
	captionbar showing title, close button with SysMenu,
	and other buttons using system resources bitmaps.

	* [controls/menu.c]
	New functions: SetMenuItemBitmaps() with 'glues',
	Make new version of LoadMenu() & ParseMenu(),
	( put #define USE_POPUPMENU ).
	Implementation of MenuBar functions.
	
	* [sysres.dll]
	New bitmaps for system such OBM_CLOSE, OBM_MINIMIZE, OBM_UPARROWI.
	New SYSMENU menu, it don't work yet ! :-((

Tue Jan 11 05:27:45 1994  julliard@di.epfl.ch (Alexandre Julliard

	* [memory/atom.c]
	Fixed a bug that could cause atoms to be case-sensitive.

	* [misc/rect.c]
	Bug fix in SubtractRect().

	* [objects/clipping.c]
	Bug fix when setting the clip mask to an empty region.

	* [windows/dce.c]
	Bug fix in ReleaseDC().

	* [windows/dialog.c]
	Call AdjustWindowRectEx() before creating the dialog window.
	Added support for DS_MODALFRAME style.

	* [windows/event.c]
	Cleaned up event handling and removed old Xt stuff.
	Moved double-click handling to windows/message.c

	* [windows/focus.c]
	Bug fix: only set the X focus when the window is viewable.

	* [windows/graphics.c]
	Rewritten DrawReliefRect() to use brush instead of pen, and
	to use the system colors.

	* [windows/message.c]
	Implemented WM_NCHITTEST message sending, and non-client
	mouse messages.
	Cleaned up double-click handling, and removed the Xt code.

	* [windows/nonclient.c]  (New file)
	Implemented AdjustWindowRect().
	Implemented WM_NCCALCSIZE, WM_NCHITTEST and WM_NCPAINT handling.

	* [windows/painting.c]
	Added sending of the WM_NCPAINT message in BeginPaint().

	* [windows/sysmetrics.c] [include/sysmetrics.h]  (New files)
	Implemented system metrics.

	* [windows/win.c]
	Bug fix in setting the parent and owner in CreateWindow().
	Removed the Xt code.

	* [windows/winpos.c]
	Added sending of the WM_NCPAINT message in SetWindowPos().
	Removed the Xt code.
diff --git a/ChangeLog b/ChangeLog
index 151f65b..5c2f747 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,90 @@
+Tue Jan  4 13:01:33 1994  David Metcalfe <david@prism.demon.co.uk>
+
+        * [window/caret.c]
+        Modified code to use system timer.
+
+Jan 9, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte)
+
+	* [windows/win.c]
+	Windows create if required new XLIB MenuBar & CaptionBar.
+
+	* [windows/defwnd.c]
+	WM_CALCSIZE Move & Resize caption, menubar & scrollbars.
+	(I'm not sure it's the good place for it, but it work...)
+
+	* [loader/resource.c]
+	optimize in FindResourceByNumber, make lseek() if next type ...
+
+	* [controls/scroll.c]
+	scrollbar buttons are now using system resources bitmaps.
+
+	* [controls/caption.c] - new file ...
+	captionbar showing title, close button with SysMenu,
+	and other buttons using system resources bitmaps.
+
+	* [controls/menu.c]
+	New functions: SetMenuItemBitmaps() with 'glues',
+	Make new version of LoadMenu() & ParseMenu(),
+	( put #define USE_POPUPMENU ).
+	Implementation of MenuBar functions.
+	
+	* [sysres.dll]
+	New bitmaps for system such OBM_CLOSE, OBM_MINIMIZE, OBM_UPARROWI.
+	New SYSMENU menu, it don't work yet ! :-((
+
+Tue Jan 11 05:27:45 1994  julliard@di.epfl.ch (Alexandre Julliard
+
+	* [memory/atom.c]
+	Fixed a bug that could cause atoms to be case-sensitive.
+
+	* [misc/rect.c]
+	Bug fix in SubtractRect().
+
+	* [objects/clipping.c]
+	Bug fix when setting the clip mask to an empty region.
+
+	* [windows/dce.c]
+	Bug fix in ReleaseDC().
+
+	* [windows/dialog.c]
+	Call AdjustWindowRectEx() before creating the dialog window.
+	Added support for DS_MODALFRAME style.
+
+	* [windows/event.c]
+	Cleaned up event handling and removed old Xt stuff.
+	Moved double-click handling to windows/message.c
+
+	* [windows/focus.c]
+	Bug fix: only set the X focus when the window is viewable.
+
+	* [windows/graphics.c]
+	Rewritten DrawReliefRect() to use brush instead of pen, and
+	to use the system colors.
+
+	* [windows/message.c]
+	Implemented WM_NCHITTEST message sending, and non-client
+	mouse messages.
+	Cleaned up double-click handling, and removed the Xt code.
+
+	* [windows/nonclient.c]  (New file)
+	Implemented AdjustWindowRect().
+	Implemented WM_NCCALCSIZE, WM_NCHITTEST and WM_NCPAINT handling.
+
+	* [windows/painting.c]
+	Added sending of the WM_NCPAINT message in BeginPaint().
+
+	* [windows/sysmetrics.c] [include/sysmetrics.h]  (New files)
+	Implemented system metrics.
+
+	* [windows/win.c]
+	Bug fix in setting the parent and owner in CreateWindow().
+	Removed the Xt code.
+
+	* [windows/winpos.c]
+	Added sending of the WM_NCPAINT message in SetWindowPos().
+	Removed the Xt code.
+
+----------------------------------------------------------------------
 Sun Jan  2 12:38:53 1994  David Metcalfe <david@prism.demon.co.uk>
 
 	* [windows/class.c]
@@ -101,7 +188,6 @@
 
 	* loader/wine.c: Added support for relocation types 5 and 6.
 
-----------------------------------------------------------------------
 Mon Dec 27 11:06:03 1993  Erik Bos (erik@trashcan.hacktic.nl)
 
 	* [misc/comm.c]
diff --git a/Makefile b/Makefile
index 1f7221c..21c7cab 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 ######################################################################
 # These variables are inherited by the sub-makefiles
-DEBUGOPTS=-DUSE_XLIB
+DEBUGOPTS=
 COPTS=-O2 -m486
 INCLUDE_DIR=include
 LDFLAGS=
diff --git a/README b/README
index 1b090d4..52863a7 100644
--- a/README
+++ b/README
@@ -41,6 +41,14 @@
 Have a nice game of solitaire, but be careful.  Emulation isn't perfect.
 So, occassionally it will crash.
 
+WHAT'S NEW with version 0.6: (see ChangeLog for details)
+	- Working towards elimination of Xt-dependent code.  Thanks to
+	  Alexandre and Martin.
+	- Other bug fixes.
+	- I added a rudimentary spy facility which can be turned
+ 	  on from the wine.ini file.  See the sample wine.ini
+	  for details
+
 WHAT'S NEW with version 0.5: (see ChangeLog for details)
 	- Working towards elimination of Xt-dependent code.
 	- StretchBlt()
diff --git a/controls/Makefile b/controls/Makefile
index 2f4c081..520a112 100644
--- a/controls/Makefile
+++ b/controls/Makefile
@@ -1,6 +1,7 @@
 CFLAGS=$(COPTS) $(DEBUGOPTS) -I$(INCLUDE_DIR)
 
-OBJS=menu.o widgets.o button.o scroll.o listbox.o combo.o static.o \
+OBJS = menu.o caption.o widgets.o button.o \
+	scroll.o listbox.o combo.o static.o \
 	SmeMenuButto.o WinLabel.o WinCommand.o \
 	WinMenuButto.o
 
diff --git a/controls/caption.c b/controls/caption.c
new file mode 100644
index 0000000..68283a7
--- /dev/null
+++ b/controls/caption.c
@@ -0,0 +1,296 @@
+/*
+ * Interface code to CAPTION widget
+ *
+ * Copyright  Martin Ayotte, 1994
+ *
+ */
+
+/*
+#define DEBUG_CAPTION
+*/
+
+static char Copyright[] = "Copyright Martin Ayotte, 1994";
+
+#include <X11/Intrinsic.h>
+#include <X11/StringDefs.h>
+#include "windows.h"
+#include "caption.h"
+#include "heap.h"
+#include "win.h"
+#include <sys/types.h>
+#include <dirent.h>
+#include <sys/stat.h>
+
+HBITMAP hStdClose = (HBITMAP)NULL;
+HBITMAP hStdCloseD = (HBITMAP)NULL;
+HBITMAP hStdMinim = (HBITMAP)NULL;
+HBITMAP hStdMinimD = (HBITMAP)NULL;
+HBITMAP hStdMaxim = (HBITMAP)NULL;
+HBITMAP hStdMaximD = (HBITMAP)NULL;
+HMENU hStdSysMenu = (HMENU)NULL;
+
+LPHEADCAPTION CaptionBarGetWindowAndStorage(HWND hWnd, WND **wndPtr);
+LPHEADCAPTION CaptionBarGetStorageHeader(HWND hWnd);
+void SetMenuLogicalParent(HMENU hMenu, HWND hWnd);
+
+
+/***********************************************************************
+ *           CaptionBarWndProc
+ */
+LONG CaptionBarWndProc( HWND hWnd, WORD message, WORD wParam, LONG lParam )
+{    
+    WORD	wRet;
+    short	x, y;
+    short	width, height;
+    WND  	*wndPtr;
+    LPHEADCAPTION lphs;
+    PAINTSTRUCT	ps;
+    HDC		hDC;
+    HDC		hMemDC;
+    BITMAP	bm;
+    RECT 	rect;
+    char	str[128];
+    switch(message)
+    {
+    case WM_CREATE:
+	wndPtr = WIN_FindWndPtr(hWnd);
+	lphs = (LPHEADCAPTION)malloc(sizeof(HEADCAPTION));
+	if (lphs == 0) {
+	    printf("Bad Memory Alloc on CAPTIONBAR !\n");
+	    return 0;
+	    }
+	memset(lphs, 0, sizeof(HEADCAPTION));
+#ifdef DEBUG_CAPTION
+ 	printf("CreateCaptionBarStruct %lX !\n", lphs);
+#endif
+	*((LPHEADCAPTION *)&wndPtr->wExtra[1]) = lphs;
+	if (hStdClose == (HBITMAP)NULL) 
+	    hStdClose = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_CLOSE));
+	lphs->hClose = hStdClose;
+	if (hStdMinim == (HBITMAP)NULL) 
+	    hStdMinim = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_REDUCE));
+	lphs->hMinim = hStdMinim;
+	if (hStdMaxim == (HBITMAP)NULL) 
+	    hStdMaxim = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_RESTORE));
+	lphs->hMaxim = hStdMaxim;
+	if (hStdCloseD == (HBITMAP)NULL) 
+	    hStdCloseD = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_CLOSE));
+	if (hStdMinimD == (HBITMAP)NULL) 
+	    hStdMinimD = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_REDUCED));
+	if (hStdMaximD == (HBITMAP)NULL) 
+	    hStdMaximD = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_RESTORED));
+	if (hStdSysMenu == (HBITMAP)NULL) 
+	    hStdSysMenu = LoadMenu((HINSTANCE)NULL, "SYSMENU");
+	lphs->hSysMenu = hStdSysMenu;
+ 	printf("CaptionBar SYSMENU %04X !\n", lphs->hSysMenu);
+	if (lphs->hSysMenu == 0) lphs->hSysMenu = CreatePopupMenu();
+	AppendMenu(lphs->hSysMenu, MF_STRING, 9999, "About &Wine ...");
+	GetClientRect(hWnd, &rect);
+	CopyRect(&lphs->rectClose, &rect);
+	CopyRect(&lphs->rectMaxim, &rect);
+	lphs->rectClose.right = lphs->rectClose.left +
+		 lphs->rectClose.bottom + lphs->rectClose.top;
+	lphs->rectMaxim.left = lphs->rectMaxim.right -
+		 lphs->rectMaxim.bottom + lphs->rectMaxim.top;
+	CopyRect(&lphs->rectMinim, &lphs->rectMaxim);
+	if (lphs->hMaxim != 0) {
+	    lphs->rectMinim.left = lphs->rectMaxim.bottom + lphs->rectMaxim.top;
+	    lphs->rectMinim.right = lphs->rectMaxim.bottom + lphs->rectMaxim.top;
+	    }
+	if (lphs->hClose == 0) lphs->rectClose.right = lphs->rectClose.left;
+	printf("CAPTION Close.right=%d Maxim.left=%d Minim.left=%d !\n",
+	    lphs->rectClose.right, lphs->rectMaxim.left, lphs->rectMinim.left);
+	return 0;
+    case WM_DESTROY:
+	lphs = CaptionBarGetWindowAndStorage(hWnd, &wndPtr);
+	if (lphs == 0) return 0;
+#ifdef DEBUG_CAPTION
+        printf("CaptionBar WM_DESTROY %lX !\n", lphs);
+#endif
+	DestroyMenu(lphs->hSysMenu);
+	free(lphs);
+	*((LPHEADCAPTION *)&wndPtr->wExtra[1]) = 0;
+	return 0;
+    case WM_COMMAND:
+#ifdef DEBUG_CAPTION
+    	printf("CaptionBar WM_COMMAND %04X %08X !\n", wParam, lParam);
+#endif
+	lphs = CaptionBarGetWindowAndStorage(hWnd, &wndPtr);
+    	if (wParam == 9999) {
+	    printf("CaptionBar Show 'About Wine ...' !\n");
+	    }
+	SendMessage(wndPtr->hwndParent, message, wParam, lParam);
+	break;
+    case WM_SIZE:
+	lphs = CaptionBarGetWindowAndStorage(hWnd, &wndPtr);
+	width  = LOWORD(lParam);
+	height = HIWORD(lParam);
+	if (lphs->hClose != 0)
+	    SetRect(&lphs->rectClose, 0, 0, height, height);
+	if (lphs->hMinim != 0) {
+	    if (lphs->hMaxim != 0)
+		SetRect(&lphs->rectMinim, width - 2 * height, 0, 
+				width - height, height);
+	    else
+		SetRect(&lphs->rectMinim, width - height, 0, width, height);
+	    }
+	if (lphs->hMaxim != 0)
+	    SetRect(&lphs->rectMaxim, width - height, 0, width, height);
+	break;
+    case WM_LBUTTONDOWN:
+	lphs = CaptionBarGetWindowAndStorage(hWnd, &wndPtr);
+	SetCapture(hWnd);
+	x = LOWORD(lParam);
+	y = HIWORD(lParam);
+	hDC = GetDC(hWnd);
+	if (x > lphs->rectClose.left && x < lphs->rectClose.right) {
+	    lphs->hClose = hStdCloseD;
+	    InvalidateRect(hWnd, &lphs->rectClose, TRUE);
+	    UpdateWindow(hWnd);
+	    }
+	if (x > lphs->rectMinim.left && x < lphs->rectMinim.right) {
+	    lphs->hMinim = hStdMinimD;
+	    InvalidateRect(hWnd, &lphs->rectMinim, TRUE);
+	    UpdateWindow(hWnd);
+	    }
+	if (x > lphs->rectMaxim.left && x < lphs->rectMaxim.right &&
+	    lphs->hMaxim != 0) {
+	    lphs->hMaxim = hStdMaximD;
+	    InvalidateRect(hWnd, &lphs->rectMaxim, TRUE);
+	    UpdateWindow(hWnd);
+	    }
+	ReleaseDC(hWnd, hDC);
+	break;
+    case WM_LBUTTONUP:
+	lphs = CaptionBarGetWindowAndStorage(hWnd, &wndPtr);
+	ReleaseCapture();
+#ifdef DEBUG_CAPTION
+        printf("CaptionBar WM_LBUTTONUP %lX !\n", lParam);
+#endif
+	x = LOWORD(lParam);
+	y = HIWORD(lParam);
+	if (x > lphs->rectClose.left && x < lphs->rectClose.right) {
+	    lphs->hClose = hStdClose;
+	    InvalidateRect(hWnd, &lphs->rectClose, TRUE);
+	    UpdateWindow(hWnd);
+	    TrackPopupMenu(lphs->hSysMenu, TPM_LEFTBUTTON, 0, -20, 
+		0, wndPtr->hwndParent, (LPRECT)NULL);
+	    SetMenuLogicalParent(lphs->hSysMenu, hWnd);
+	    printf("CAPTION Pop the SYSMENU !\n");
+	    break;
+	    }
+	if (x > lphs->rectMinim.left && x < lphs->rectMinim.right) {
+	    SendMessage(wndPtr->hwndParent, WM_SYSCOMMAND, SC_MINIMIZE, 0L);
+	    lphs->hMinim = hStdMinim;
+	    InvalidateRect(hWnd, &lphs->rectMinim, TRUE);
+	    UpdateWindow(hWnd);
+	    printf("CAPTION Minimize Window !\n");
+	    break;
+	    }
+	if (x > lphs->rectMaxim.left && x < lphs->rectMaxim.right) {
+	    lphs->hMaxim = hStdMaxim;
+	    InvalidateRect(hWnd, &lphs->rectMaxim, TRUE);
+	    UpdateWindow(hWnd);
+	    SendMessage(wndPtr->hwndParent, WM_SYSCOMMAND, SC_MAXIMIZE, 0L);
+	    printf("CAPTION Maximize Window !\n");
+	    break;
+	    }
+	break;
+
+    case WM_LBUTTONDBLCLK:
+	lphs = CaptionBarGetWindowAndStorage(hWnd, &wndPtr);
+#ifdef DEBUG_CAPTION
+        printf("CaptionBar WM_LBUTTONDBLCLK %lX !\n", lParam);
+#endif
+	x = LOWORD(lParam);
+	y = HIWORD(lParam);
+	if (x > lphs->rectClose.left && x < lphs->rectClose.right) {
+	    SendMessage(wndPtr->hwndParent, WM_SYSCOMMAND, SC_CLOSE, 0L);
+	    printf("CAPTION DoubleClick Close Window !\n");
+	    break;
+	    }
+	break;
+
+    case WM_KEYDOWN:
+    case WM_KEYUP:
+    case WM_CHAR:
+	lphs = CaptionBarGetWindowAndStorage(hWnd, &wndPtr);
+	return(SendMessage(wndPtr->hwndParent, message, wParam, lParam));
+
+    case WM_PAINT:
+	GetWindowRect(hWnd, &rect);
+#ifdef DEBUG_CAPTION
+ 	printf("CaptionBar WM_PAINT left=%d top=%d right=%d bottom=%d !\n",
+ 		rect.left, rect.top, rect.right, rect.bottom);
+#endif
+	lphs = CaptionBarGetWindowAndStorage(hWnd, &wndPtr);
+	hDC = BeginPaint(hWnd, &ps);
+	hMemDC = CreateCompatibleDC(hDC);
+	if (lphs->hClose != 0) {
+	    GetObject(lphs->hClose, sizeof(BITMAP), (LPSTR)&bm);
+	    SelectObject(hMemDC, lphs->hClose);
+	    BitBlt(hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
+	    }
+	if (lphs->hMinim != 0) {
+	    GetObject(lphs->hMinim, sizeof(BITMAP), (LPSTR)&bm);
+	    SelectObject(hMemDC, lphs->hMinim);
+	    BitBlt(hDC, lphs->rectMinim.left, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
+	    }
+	if (lphs->hMaxim != 0) {
+	    GetObject(lphs->hMaxim, sizeof(BITMAP), (LPSTR)&bm);
+	    SelectObject(hMemDC, lphs->hMaxim);
+	    BitBlt(hDC, lphs->rectMaxim.left, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
+	    }
+	DeleteDC(hMemDC);
+	GetClientRect(hWnd, &rect);
+	FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH));
+	rect.left = lphs->rectClose.right;
+	rect.right = lphs->rectMinim.left;
+#ifdef DEBUG_CAPTION
+ 	printf("CaptionBar WM_PAINT left=%d top=%d right=%d bottom=%d !\n",
+ 		rect.left, rect.top, rect.right, rect.bottom);
+#endif
+	FillRect(hDC, &rect, GetStockObject(GRAY_BRUSH));
+	if (GetWindowTextLength(wndPtr->hwndParent) > 0) {
+	    GetWindowText(wndPtr->hwndParent, str, sizeof(str));
+	    width = GetTextExtent(hDC, str, strlen(str));
+	    DrawText(hDC, str, -1, &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
+	    }
+	EndPaint(hWnd, &ps);
+	break;
+    default:
+	return DefWindowProc( hWnd, message, wParam, lParam );
+    }
+return(0);
+}
+
+
+
+LPHEADCAPTION CaptionBarGetWindowAndStorage(HWND hWnd, WND **wndPtr)
+{
+    WND  *Ptr;
+    LPHEADCAPTION lphs;
+    *(wndPtr) = Ptr = WIN_FindWndPtr(hWnd);
+    if (Ptr == 0) {
+    	printf("Bad Window handle on CaptionBar !\n");
+    	return 0;
+    	}
+    lphs = *((LPHEADCAPTION *)&Ptr->wExtra[1]);
+    return lphs;
+}
+
+
+LPHEADCAPTION CaptionBarGetStorageHeader(HWND hWnd)
+{
+    WND  *wndPtr;
+    LPHEADCAPTION lphs;
+    wndPtr = WIN_FindWndPtr(hWnd);
+    if (wndPtr == 0) {
+    	printf("Bad Window handle on CaptionBar !\n");
+    	return 0;
+    	}
+    lphs = *((LPHEADCAPTION *)&wndPtr->wExtra[1]);
+    return lphs;
+}
+
+
diff --git a/controls/menu.c b/controls/menu.c
index c1cd758..4a01b2f 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -1,7 +1,11 @@
 static char RCSId[] = "$Id$";
 static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
+static char Copyright2[] = "Copyright  Martin Ayotte, 1993";
 
+/*
 #define DEBUG_MENU
+*/
+#define USE_POPUPMENU
 
 #include <X11/Intrinsic.h>
 #include <X11/StringDefs.h>
@@ -17,6 +21,9 @@
 #include "bitmaps/check_bitmap"
 #include "bitmaps/nocheck_bitmap"
 
+HBITMAP hStdCheck = 0;
+HBITMAP hStdMnArrow = 0;
+
 static LPMENUBAR firstMenu = NULL;
 static MENUITEM *parentItem;
 static MENUITEM *siblingItem;
@@ -27,9 +34,19 @@
 
 LPPOPUPMENU PopupMenuGetStorageHeader(HWND hwnd);
 LPPOPUPMENU PopupMenuGetWindowAndStorage(HWND hwnd, WND **wndPtr);
+void StdDrawMenuBar(HWND hwnd);
 void StdDrawPopupMenu(HWND hwnd);
-LPMENUITEM PopupMenuFindItem(HWND hwnd, int x, int y, WORD *lpRet);
+LPMENUITEM MenuFindItem(HWND hwnd, int x, int y, WORD *lpRet);
+LPMENUITEM MenuFindItemBySelKey(HWND hwnd, WORD key, WORD *lpRet);
+void PopupMenuCalcSize(HWND hwnd);
+void MenuBarCalcSize(HWND hwnd);
 LPMENUITEM GetMenuItemPtr(LPPOPUPMENU menu, WORD nPos);
+WORD GetSelectionKey(LPSTR str);
+LPSTR GetShortCutString(LPSTR str);
+WORD GetShortCutPos(LPSTR str);
+BOOL HideAllSubPopupMenu(LPPOPUPMENU menu);
+WORD * ParseMenuResource(WORD *first_item, int level, HMENU hMenu);
+void SetMenuLogicalParent(HMENU hMenu, HWND hWnd);
 
 /***********************************************************************
  *           PopupMenuWndProc
@@ -40,7 +57,7 @@
     WORD	wRet;
     short	x, y;
     WND  	*wndPtr;
-    LPPOPUPMENU lppop;
+    LPPOPUPMENU lppop, lppop2;
     LPMENUITEM	lpitem, lpitem2;
     HMENU	hSubMenu;
     RECT	rect;
@@ -53,12 +70,30 @@
 #endif
 	createStruct = (CREATESTRUCT *)lParam;
      	lppop = (LPPOPUPMENU)createStruct->lpCreateParams;
-     	if (lppop == 0) break;
+     	if (lppop == NULL) break;
 	wndPtr = WIN_FindWndPtr(hwnd);
 	*((LPPOPUPMENU *)&wndPtr->wExtra[1]) = lppop;
 #ifdef DEBUG_MENU
         printf("PopupMenu WM_CREATE lppop=%08X !\n", lppop);
 #endif
+/*
+	if (lppop->BarFlags == 0) {
+	    PopupMenuCalcSize(hwnd);
+	    printf("PopupMenu WM_CREATE Width=%d Height=%d !\n", 
+			lppop->Width, lppop->Height);
+	    SetWindowPos(hwnd, 0, 0, 0, lppop->Width + 2, lppop->Height, 
+		SWP_NOZORDER | SWP_NOMOVE);
+	    }
+	else {
+	    MenuBarCalcSize(hwnd);
+	    SetWindowPos(hwnd, 0, 0, -16, lppop->Width, lppop->Height, 
+		SWP_NOZORDER);
+	    }
+*/
+	if (hStdCheck == (HBITMAP)NULL) 
+	    hStdCheck = LoadBitmap((HANDLE)NULL, (LPSTR)OBM_CHECK);
+	if (hStdMnArrow == (HBITMAP)NULL) 
+	    hStdMnArrow = LoadBitmap((HANDLE)NULL, (LPSTR)OBM_MNARROW);
 	return 0;
     case WM_DESTROY:
 	lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
@@ -66,29 +101,56 @@
         printf("PopupMenu WM_DESTROY %lX !\n", lppop);
 #endif
 	return 0;
-	
+    case WM_COMMAND:
+	lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
+#ifdef DEBUG_MENU
+    	printf("PopupMenu // push to lower parent WM_COMMAND !\n");
+#endif
+	if (lppop->hWndParent != (HWND)NULL)
+	    SendMessage(lppop->hWndParent, WM_COMMAND, wParam, lParam);
+	else 
+	    SendMessage(lppop->ownerWnd, WM_COMMAND, wParam, lParam);
+	if (lppop->BarFlags == 0) ShowWindow(hwnd, SW_HIDE);
+    	break;
+    case WM_SHOWWINDOW:
+	lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
+    	if (wParam == 0) {
+	    HideAllSubPopupMenu(lppop);
+#ifdef DEBUG_MENU
+    	printf("PopupMenu WM_SHOWWINDOW -> HIDE!\n");
+#endif
+	    break;
+	    }
+	lppop->FocusedItem = (WORD)-1;
+	if (lppop->BarFlags == 0) {
+	    PopupMenuCalcSize(hwnd);
+#ifdef DEBUG_MENU
+	    printf("PopupMenu WM_SHOWWINDOW Width=%d Height=%d !\n", 
+			lppop->Width, lppop->Height);
+#endif
+	    SetWindowPos(hwnd, 0, 0, 0, lppop->Width + 2, lppop->Height, 
+		SWP_NOZORDER | SWP_NOMOVE);
+	    }
+	else {
+	    MenuBarCalcSize(hwnd);
+#ifdef DEBUG_MENU
+	    printf("MenuBarMenu WM_SHOWWINDOW Width=%d Height=%d !\n", 
+			lppop->Width, lppop->Height);
+#endif
+	    SetWindowPos(hwnd, 0, 0, -16, lppop->Width, lppop->Height, 
+		SWP_NOZORDER);
+	    }
+    	break;
     case WM_LBUTTONDOWN:
 	lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
 	SetCapture(hwnd);
-	lpitem = PopupMenuFindItem(hwnd, LOWORD(lParam), HIWORD(lParam), &wRet);
+	lpitem = MenuFindItem(hwnd, LOWORD(lParam), HIWORD(lParam), &wRet);
+#ifdef DEBUG_MENU
 	printf("PopupMenu WM_LBUTTONDOWN wRet=%d lpitem=%08X !\n", wRet, lpitem);
-	if (lpitem != NULL) {
-	    lppop->FocusedItem = wRet;
-	    if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
-		((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
-	        hDC = GetDC(hwnd);
-	        InvertRect(hDC, &lpitem->rect);
-		ReleaseDC(hwnd, hDC);
-		}
-	    }
-	break;
-    case WM_LBUTTONUP:
-	lppop = PopupMenuGetStorageHeader(hwnd);
-	ReleaseCapture();
-	lpitem = PopupMenuFindItem(hwnd, LOWORD(lParam), HIWORD(lParam), &wRet);
-	printf("PopupMenu WM_LBUTTONUP wRet=%d lpitem=%08X !\n", wRet, lpitem);
+#endif
 	if (lpitem != NULL) {
 	    if (lppop->FocusedItem != (WORD)-1) {
+		HideAllSubPopupMenu(lppop);
 		lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem);
 		if (((lpitem2->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
 		    ((lpitem2->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
@@ -97,32 +159,79 @@
 		    ReleaseDC(hwnd, hDC);
 		    }
 		}
+	    lppop->FocusedItem = wRet;
+	    if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
+		((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
+	        hDC = GetDC(hwnd);
+	        InvertRect(hDC, &lpitem->rect);
+		ReleaseDC(hwnd, hDC);
+		}
 	    if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
 		hSubMenu = (HMENU)lpitem->item_id;
-		printf("ShowSubmenu hSubMenu=%04X !\n", hSubMenu);
+		lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu);
+		if (lppop2 == NULL) break;
+		lppop2->hWndParent = hwnd;
 		GetClientRect(hwnd, &rect);
-		x = rect.right;
-		GetWindowRect(hwnd, &rect);
-		x += rect.left;
-		TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, 
-			x, rect.top + HIWORD(lParam), 
+		if (lppop->BarFlags != 0) {
+		    y = rect.bottom - rect.top;
+		    TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, 
+			lpitem->rect.left, 0, 
 			0, lppop->ownerWnd, (LPRECT)NULL);
+		    }
+		else {
+		    x = rect.right;
+		    GetWindowRect(hwnd, &rect);
+		    x += rect.left;
+		    TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, 
+			x, lpitem->rect.top,
+			0, lppop->ownerWnd, (LPRECT)NULL);
+		    }
+		break;
+		}
+	    }
+	break;
+    case WM_LBUTTONUP:
+	lppop = PopupMenuGetStorageHeader(hwnd);
+	ReleaseCapture();
+	lpitem = MenuFindItem(hwnd, LOWORD(lParam), HIWORD(lParam), &wRet);
+#ifdef DEBUG_MENU
+	printf("PopupMenu WM_LBUTTONUP wRet=%d lpitem=%08X !\n", wRet, lpitem);
+#endif
+	if (lpitem != NULL) {
+	    if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
 		break;
 		}
 	    if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
 		((lpitem->item_flags & MF_POPUP) != MF_POPUP)) {
-		SendMessage(lppop->ownerWnd, WM_COMMAND, lpitem->item_id, 0L);
+	    	ShowWindow(lppop->hWnd, SW_HIDE);
+		if (lppop->hWndParent != (HWND)NULL)
+		    SendMessage(lppop->hWndParent, WM_COMMAND, 
+					lpitem->item_id, 0L);
+		else 
+		    SendMessage(lppop->ownerWnd, WM_COMMAND, 
+					lpitem->item_id, 0L);
+#ifdef DEBUG_MENU
 		printf("PopupMenu // SendMessage WM_COMMAND wParam=%d !\n", 
 			lpitem->item_id);
-	    	ShowWindow(lppop->hWnd, SW_HIDE);
+#endif
 	    	break;
 		}
 	    }
+	if (lppop->FocusedItem != (WORD)-1) {
+	    HideAllSubPopupMenu(lppop);
+	    lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem);
+	    if (((lpitem2->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
+		((lpitem2->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
+	        hDC = GetDC(hwnd);
+	        InvertRect(hDC, &lpitem2->rect);
+		ReleaseDC(hwnd, hDC);
+		}
+	    }
 	break;
     case WM_MOUSEMOVE:
         if ((wParam & MK_LBUTTON) != 0) {
 	    lppop = PopupMenuGetStorageHeader(hwnd);
-	    lpitem = PopupMenuFindItem(hwnd, LOWORD(lParam), HIWORD(lParam), &wRet);
+	    lpitem = MenuFindItem(hwnd, LOWORD(lParam), HIWORD(lParam), &wRet);
 	    if ((lpitem != NULL) && (lppop->FocusedItem != wRet)) {
 		lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem);
 		hDC = GetDC(hwnd);
@@ -130,9 +239,27 @@
 		    ((lpitem2->item_flags & MF_STRING) == MF_STRING)) {
 		    InvertRect(hDC, &lpitem2->rect);
 		    }
+		if ((lpitem2->item_flags & MF_POPUP) == MF_POPUP) {
+		    HideAllSubPopupMenu(lppop);
+		    }
 		lppop->FocusedItem = wRet;
-		printf("PopupMenu WM_MOUSEMOVE wRet=%d lpitem=%08X !\n", wRet, lpitem);
-		InvertRect(hDC, &lpitem->rect);
+		if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
+		    ((lpitem->item_flags & MF_STRING) == MF_STRING)) {
+		    InvertRect(hDC, &lpitem->rect);
+		    }
+		if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
+		    hSubMenu = (HMENU)lpitem->item_id;
+		    lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu);
+		    if (lppop2 == NULL) break;
+		    if (lppop->BarFlags != 0) {
+			lppop2->hWndParent = hwnd;
+			GetClientRect(hwnd, &rect);
+			y = rect.bottom - rect.top;
+			TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, 
+				lpitem->rect.left, 0, 
+				0, lppop->ownerWnd, (LPRECT)NULL);
+			}
+		    }
 		ReleaseDC(hwnd, hDC);
 		}
             }
@@ -140,13 +267,203 @@
 
     case WM_KEYDOWN:
     case WM_KEYUP:
-    case WM_CHAR:
+	if (lParam < 0L) break;
 	lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
-	return(SendMessage(wndPtr->hwndParent, message, wParam, lParam));
-
+	if (lppop->FocusedItem == (WORD)-1) {
+	    if (wParam == VK_UP || wParam == VK_DOWN || 
+		wParam == VK_LEFT || wParam == VK_RIGHT) {
+		hDC = GetDC(hwnd);
+		lppop->FocusedItem = 0;
+		lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
+		if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
+		    ((lpitem->item_flags & MF_STRING) == MF_STRING)) {
+		    InvertRect(hDC, &lpitem->rect);
+		    }
+		ReleaseDC(hwnd, hDC);
+		}
+	    break;
+	    }
+	switch(wParam) {
+	    case VK_UP:
+		if (lppop->BarFlags != 0) break;
+		if (lppop->FocusedItem < 1) break;
+		lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
+		if ((lpitem->item_flags & MF_POPUP) == MF_POPUP)
+		    HideAllSubPopupMenu(lppop);
+		hDC = GetDC(hwnd);
+		if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
+		    ((lpitem->item_flags & MF_STRING) == MF_STRING)) {
+		    InvertRect(hDC, &lpitem->rect);
+		    }
+		lppop->FocusedItem--;
+		lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
+		if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
+		    ((lpitem->item_flags & MF_STRING) == MF_STRING)) {
+		    InvertRect(hDC, &lpitem->rect);
+		    }
+		ReleaseDC(hwnd, hDC);
+		break;
+	    case VK_DOWN:
+		if (lppop->BarFlags != 0) goto ProceedSPACE;
+		if (lppop->FocusedItem >= lppop->nItems - 1) break;
+		lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
+		if ((lpitem->item_flags & MF_POPUP) == MF_POPUP)
+		    HideAllSubPopupMenu(lppop);
+		hDC = GetDC(hwnd);
+		if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
+		    ((lpitem->item_flags & MF_STRING) == MF_STRING)) {
+		    InvertRect(hDC, &lpitem->rect);
+		    }
+		lppop->FocusedItem++;
+		lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
+		if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
+		    ((lpitem->item_flags & MF_STRING) == MF_STRING)) {
+		    InvertRect(hDC, &lpitem->rect);
+		    }
+		ReleaseDC(hwnd, hDC);
+		break;
+	    case VK_LEFT:
+		if (lppop->BarFlags == 0) {
+		    if (lppop->hWndParent != 0) 
+			SendMessage(lppop->hWndParent, WM_KEYDOWN, wParam, lParam);
+		    break;
+		    }
+		if (lppop->FocusedItem < 1) break;
+		lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
+		if ((lpitem->item_flags & MF_POPUP) == MF_POPUP)
+		    HideAllSubPopupMenu(lppop);
+		hDC = GetDC(hwnd);
+		if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
+		    ((lpitem->item_flags & MF_STRING) == MF_STRING)) {
+		    InvertRect(hDC, &lpitem->rect);
+		    }
+		lppop->FocusedItem--;
+		lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
+		if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
+		    ((lpitem->item_flags & MF_STRING) == MF_STRING)) {
+		    InvertRect(hDC, &lpitem->rect);
+		    }
+		ReleaseDC(hwnd, hDC);
+		break;
+	    case VK_RIGHT:
+		if (lppop->BarFlags == 0) {
+		    if (lppop->hWndParent != 0) 
+			SendMessage(lppop->hWndParent, WM_KEYDOWN, wParam, lParam);
+		    break;
+		    }
+		if (lppop->FocusedItem >= lppop->nItems - 1) break;
+		lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
+		if ((lpitem->item_flags & MF_POPUP) == MF_POPUP)
+		    HideAllSubPopupMenu(lppop);
+		hDC = GetDC(hwnd);
+		if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
+		    ((lpitem->item_flags & MF_STRING) == MF_STRING)) {
+		    InvertRect(hDC, &lpitem->rect);
+		    }
+		lppop->FocusedItem++;
+		lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
+		if (((lpitem->item_flags & MF_POPUP) == MF_POPUP) ||
+		    ((lpitem->item_flags & MF_STRING) == MF_STRING)) {
+		    InvertRect(hDC, &lpitem->rect);
+		    }
+		ReleaseDC(hwnd, hDC);
+		break;
+	    case VK_RETURN:
+	    case VK_SPACE:
+ProceedSPACE:
+		printf("PopupMenu VK_SPACE !\n");
+		lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
+		if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
+		    hSubMenu = (HMENU)lpitem->item_id;
+		    lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu);
+		    if (lppop2 == NULL) break;
+		    lppop2->hWndParent = hwnd;
+		    GetClientRect(hwnd, &rect);
+		    if (lppop->BarFlags != 0) {
+			y = rect.bottom - rect.top;
+			TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, 
+				lpitem->rect.left, 0, 
+				0, lppop->ownerWnd, (LPRECT)NULL);
+			}
+		    else {
+			x = rect.right;
+			GetWindowRect(hwnd, &rect);
+			x += rect.left;
+			TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, 
+				x, lpitem->rect.top,
+				0, lppop->ownerWnd, (LPRECT)NULL);
+			}
+		    break;
+		    }
+		if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
+		    ((lpitem->item_flags & MF_POPUP) != MF_POPUP)) {
+		    ShowWindow(lppop->hWnd, SW_HIDE);
+		    if (lppop->hWndParent != (HWND)NULL)
+			SendMessage(lppop->hWndParent, WM_COMMAND, 
+					lpitem->item_id, 0L);
+		    else 
+			SendMessage(lppop->ownerWnd, WM_COMMAND, 
+					lpitem->item_id, 0L);
+#ifdef DEBUG_MENU
+		    printf("PopupMenu // SendMessage WM_COMMAND wParam=%d !\n", 
+				lpitem->item_id);
+#endif
+		   }
+		break;
+	    }
+	break;
+    case WM_CHAR:
+	if (lParam < 0L) break;
+	lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
+	if (wParam == VK_ESCAPE) {
+	    if (lppop->hWndParent != 0) {
+		lppop2 = PopupMenuGetWindowAndStorage(
+			lppop->hWndParent, &wndPtr);
+		HideAllSubPopupMenu(lppop2);
+		break;
+		}
+	    if (lppop->FocusedItem != (WORD)-1) {
+		lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem);
+		hDC = GetDC(hwnd);
+		if (((lpitem2->item_flags & MF_POPUP) == MF_POPUP) ||
+		    ((lpitem2->item_flags & MF_STRING) == MF_STRING)) {
+		    InvertRect(hDC, &lpitem2->rect);
+		    }
+		ReleaseDC(hwnd, hDC);
+		lppop->FocusedItem = (WORD)-1;
+		}
+	    }
+	if (wParam >= 'a' && wParam <= 'z') wParam -= 'a' - 'A';
+	lpitem = MenuFindItemBySelKey(hwnd, wParam, &wRet);
+	if (lpitem != NULL) {
+	    printf("Found  wRet=%d !\n", wRet);
+	    if (lppop->FocusedItem != (WORD)-1) {
+		lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem);
+		if ((lpitem2->item_flags & MF_POPUP) == MF_POPUP)
+		    HideAllSubPopupMenu(lppop);
+		hDC = GetDC(hwnd);
+		if (((lpitem2->item_flags & MF_POPUP) == MF_POPUP) ||
+		    ((lpitem2->item_flags & MF_STRING) == MF_STRING)) {
+		    InvertRect(hDC, &lpitem2->rect);
+		    }
+		ReleaseDC(hwnd, hDC);
+		}
+	    lppop->FocusedItem = wRet;
+	    goto ProceedSPACE;
+	    }
+	break;
     case WM_PAINT:
-        printf("PopupMenu WM_PAINT !\n");
-	StdDrawPopupMenu(hwnd);
+	lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
+	if (lppop->BarFlags != 0) {
+	    MenuBarCalcSize(hwnd);
+	    printf("PopupMenu WM_PAINT Width=%d Height=%d !\n", 
+			lppop->Width, lppop->Height);
+	    StdDrawMenuBar(hwnd);
+	    }
+	else{
+	    PopupMenuCalcSize(hwnd);
+	    StdDrawPopupMenu(hwnd);
+	    }
 	break;
     default:
 	return DefWindowProc( hwnd, message, wParam, lParam );
@@ -184,6 +501,14 @@
 }
 
 
+void SetMenuLogicalParent(HMENU hMenu, HWND hWnd)
+{
+    LPPOPUPMENU lppop;
+    lppop = (LPPOPUPMENU)GlobalLock(hMenu);
+    lppop->hWndParent = hWnd;
+}
+
+
 void StdDrawPopupMenu(HWND hwnd)
 {
     WND 	*wndPtr;
@@ -195,9 +520,11 @@
     HWND	hWndParent;
     HDC 	hDC, hMemDC;
     RECT 	rect, rect2, rect3;
+    DWORD	OldTextColor;
+    HFONT	hOldFont;
     HBITMAP	hBitMap;
     BITMAP	bm;
-    UINT  	i;
+    UINT  	i, x;
     hDC = BeginPaint( hwnd, &ps );
     if (!IsWindowVisible(hwnd)) {
 	EndPaint( hwnd, &ps );
@@ -205,55 +532,82 @@
 	}
     lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
     if (lppop == NULL) goto EndOfPaint;
-    hBrush = SendMessage(lppop->ownerWnd, WM_CTLCOLOR, (WORD)hDC,
-		    MAKELONG(hwnd, CTLCOLOR_LISTBOX));
-    if (hBrush == (HBRUSH)NULL)  hBrush = GetStockObject(WHITE_BRUSH);
+    hBrush = GetStockObject(WHITE_BRUSH);
     GetClientRect(hwnd, &rect);
     GetClientRect(hwnd, &rect2);
     FillRect(hDC, &rect, hBrush);
+    FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH));
     if (lppop->nItems == 0) goto EndOfPaint;
-    lpitem = lppop->firstItem->next;
+    lpitem = lppop->firstItem;
     if (lpitem == NULL) goto EndOfPaint;
     for(i = 0; i < lppop->nItems; i++) {
 	if ((lpitem->item_flags & MF_SEPARATOR) == MF_SEPARATOR) {
-	    rect2.bottom = rect2.top + 3;
-	    CopyRect(&lpitem->rect, &rect2);
-	    hOldPen = SelectObject(hDC, GetStockObject(BLACK_PEN));
+	    CopyRect(&rect2, &lpitem->rect);
+    	    hOldPen = SelectObject(hDC, GetStockObject(BLACK_PEN));
 	    MoveTo(hDC, rect2.left, rect2.top + 1);
 	    LineTo(hDC, rect2.right, rect2.top + 1);
 	    SelectObject(hDC, hOldPen);
-	    rect2.top += 3;
 	    }
 	if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) {
-	    hBitMap = (HBITMAP)LOWORD(lpitem->item_text);
-	    rect2.bottom = rect2.top + bm.bmHeight;
-	    CopyRect(&lpitem->rect, &rect2);
+	    hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text);
+	    CopyRect(&rect2, &lpitem->rect);
 	    hMemDC = CreateCompatibleDC(hDC);
 	    SelectObject(hMemDC, hBitMap);
 	    GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
 	    BitBlt(hDC, rect2.left, rect2.top,
 		bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
 	    DeleteDC(hMemDC);
-	    rect2.top += bm.bmHeight;
 	    }
 	if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) &&
 	    ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
 	    ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
-	    rect2.bottom = rect2.top + 15;
-	    CopyRect(&lpitem->rect, &rect2);
-	    TextOut(hDC, rect2.left + 5, rect2.top + 2, 
-		(char *)lpitem->item_text, strlen((char *)lpitem->item_text));
-	    rect2.top += 15;
+	    hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
+	    if ((lpitem->item_flags & MF_DISABLED) == MF_DISABLED)
+		OldTextColor = SetTextColor(hDC, 0x00C0C0C0L);
+	    else
+		OldTextColor = SetTextColor(hDC, 0x00000000L);
+	    CopyRect(&rect3, &lpitem->rect);
+	    InflateRect(&rect3, 0, -2);
+	    if ((x = GetShortCutPos(lpitem->item_text)) != (WORD)-1) {
+		DrawText(hDC, lpitem->item_text, x, &rect3, 
+		    DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+		DrawText(hDC, &lpitem->item_text[x], -1, &rect3, 
+		    DT_RIGHT | DT_VCENTER | DT_SINGLELINE);
+		} 
+	    else
+		DrawText(hDC, lpitem->item_text, -1, &rect3, 
+		    DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+	    SetTextColor(hDC, OldTextColor);
+	    SelectObject(hDC, hOldFont);
+	    CopyRect(&rect2, &lpitem->rect);
 	    }
 	if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) {
 	    CopyRect(&rect3, &rect2);
 	    rect3.left = rect3.right - rect3.bottom + rect3.top;
-	    InvertRect(hDC, &rect3);
+	    hMemDC = CreateCompatibleDC(hDC);
+	    if (lpitem->hCheckBit == 0)
+		SelectObject(hMemDC, hStdCheck);
+	    else
+		SelectObject(hMemDC, lpitem->hCheckBit);
+	    GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm);
+	    BitBlt(hDC, rect3.left, rect3.top,
+		bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
+	    DeleteDC(hMemDC);
+	    printf("StdDrawPopupMenu // MF_CHECKED hStdCheck=%04X !\n", hStdCheck);
+	    }
+	else {
+	    if (lpitem->hUnCheckBit != 0)
+		SelectObject(hMemDC, lpitem->hUnCheckBit);
 	    }
 	if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
 	    CopyRect(&rect3, &rect2);
 	    rect3.left = rect3.right - rect3.bottom + rect3.top;
-	    FillRect(hDC, &rect3, GetStockObject(BLACK_BRUSH));
+	    hMemDC = CreateCompatibleDC(hDC);
+	    SelectObject(hMemDC, hStdMnArrow);
+	    GetObject(hStdMnArrow, sizeof(BITMAP), (LPSTR)&bm);
+	    BitBlt(hDC, rect3.left, rect3.top,
+		bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
+	    DeleteDC(hMemDC);
 	    }
 	if (lpitem->next == NULL) goto EndOfPaint;
 	lpitem = (LPMENUITEM)lpitem->next;
@@ -264,50 +618,244 @@
 
 
 
-LPMENUITEM PopupMenuFindItem(HWND hwnd, int x, int y, WORD *lpRet)
+void StdDrawMenuBar(HWND hwnd)
 {
     WND 	*wndPtr;
     LPPOPUPMENU lppop;
     LPMENUITEM 	lpitem;
-    RECT 	rect, rect2;
+    PAINTSTRUCT ps;
+    HBRUSH 	hBrush;
+    HPEN	hOldPen;
+    HWND	hWndParent;
+    HDC 	hDC, hMemDC;
+    RECT 	rect, rect2, rect3;
+    HFONT	hOldFont;
     HBITMAP	hBitMap;
     BITMAP	bm;
-    UINT  	i;
+    UINT  	i, textwidth;
+    hDC = BeginPaint( hwnd, &ps );
+    if (!IsWindowVisible(hwnd)) {
+	EndPaint( hwnd, &ps );
+	return;
+	}
+    hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
     lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
-    if (lppop == NULL) return NULL;
+    if (lppop == NULL) goto EndOfPaint;
+    hBrush = GetStockObject(WHITE_BRUSH);
     GetClientRect(hwnd, &rect);
-    if (lppop->nItems == 0) return NULL;
-    lpitem = lppop->firstItem->next;
-    if (lpitem == NULL) return NULL;
+    FillRect(hDC, &rect, hBrush);
+    FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH));
+    if (lppop->nItems == 0) goto EndOfPaint;
+    lpitem = lppop->firstItem;
+    if (lpitem == NULL) goto EndOfPaint;
     for(i = 0; i < lppop->nItems; i++) {
-	if (y < rect2.top) return NULL;
-	if ((lpitem->item_flags & MF_SEPARATOR) == MF_SEPARATOR) {
-	    rect2.bottom = rect2.top + 3;
-	    rect2.top += 3;
-	    }
 	if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) {
-	    hBitMap = (HBITMAP)LOWORD(lpitem->item_text);
+	    hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text);
+	    CopyRect(&rect2, &lpitem->rect);
+	    hMemDC = CreateCompatibleDC(hDC);
+	    SelectObject(hMemDC, hBitMap);
 	    GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
-	    rect2.bottom = rect2.top + bm.bmHeight;
-	    rect2.top += bm.bmHeight;
+	    BitBlt(hDC, rect2.left, rect2.top,
+		bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
+	    DeleteDC(hMemDC);
 	    }
 	if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) &&
 	    ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
 	    ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
-	    rect2.bottom = rect2.top + 15;
-	    rect2.top += 15;
+	    CopyRect(&rect2, &lpitem->rect);
+	    DrawText(hDC, lpitem->item_text, -1, &rect2, 
+	    	DT_LEFT | DT_VCENTER | DT_SINGLELINE);
 	    }
-	if (y < rect2.bottom) {
+	if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) {
+	    CopyRect(&rect3, &rect2);
+	    rect3.left = rect3.right - rect3.bottom + rect3.top;
+	    hMemDC = CreateCompatibleDC(hDC);
+	    SelectObject(hMemDC, hStdCheck);
+	    GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
+	    BitBlt(hDC, rect3.left, rect3.top,
+		bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
+	    DeleteDC(hMemDC);
+	    }
+	if (lpitem->next == NULL) goto EndOfPaint;
+	lpitem = (LPMENUITEM)lpitem->next;
+    }
+EndOfPaint:
+    SelectObject(hDC, hOldFont);
+    EndPaint( hwnd, &ps );
+}
+
+
+
+LPMENUITEM MenuFindItem(HWND hwnd, int x, int y, WORD *lpRet)
+{
+    WND 	*wndPtr;
+    LPPOPUPMENU lppop;
+    LPMENUITEM 	lpitem;
+    UINT  	i;
+    lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
+    if (lppop == NULL) return NULL;
+    if (lppop->nItems == 0) return NULL;
+    lpitem = lppop->firstItem;
+    for(i = 0; i < lppop->nItems; i++) {
+	if (lpitem == NULL) return NULL;
+#ifdef DEBUG_MENUFINDITEM
+	printf("FindItem // left=%d top=%d right=%d bottom=%d\n",
+		lpitem->rect.left, lpitem->rect.top, 
+		lpitem->rect.right, lpitem->rect.bottom);
+#endif
+	if (x > lpitem->rect.left && x < lpitem->rect.right && 
+	    y > lpitem->rect.top && y < lpitem->rect.bottom) {
 	    if (lpRet != NULL) *lpRet = i;
 	    return lpitem;
 	    }
-	if (lpitem->next == NULL) return NULL;
 	lpitem = (LPMENUITEM)lpitem->next;
     }
     return NULL;
 }
 
 
+LPMENUITEM MenuFindItemBySelKey(HWND hwnd, WORD key, WORD *lpRet)
+{
+    WND 	*wndPtr;
+    LPPOPUPMENU lppop;
+    LPMENUITEM 	lpitem;
+    UINT  	i;
+    lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
+    if (lppop == NULL) return NULL;
+    if (lppop->nItems == 0) return NULL;
+    lpitem = lppop->firstItem;
+    for(i = 0; i < lppop->nItems; i++) {
+	if (lpitem == NULL) return NULL;
+#ifdef DEBUG_MENUFINDITEM
+	printf("FindItemBySelKey // key=%d lpitem->sel_key=%d\n",
+		key, lpitem->sel_key);
+#endif
+	if (key == lpitem->sel_key) {
+	    if (lpRet != NULL) *lpRet = i;
+	    return lpitem;
+	    }
+	lpitem = (LPMENUITEM)lpitem->next;
+    }
+    return NULL;
+}
+
+
+void PopupMenuCalcSize(HWND hwnd)
+{
+    WND 	*wndPtr;
+    LPPOPUPMENU lppop;
+    LPMENUITEM 	lpitem;
+    HDC		hDC;
+    RECT 	rect;
+    HBITMAP	hBitMap;
+    BITMAP	bm;
+    HFONT	hOldFont;
+    UINT  	i, OldWidth, TempWidth;
+    DWORD	dwRet;
+    lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
+    if (lppop == NULL) return;
+    if (lppop->nItems == 0) return;
+    hDC = GetDC(hwnd);
+    lppop->Width = 20;
+    hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
+CalcAGAIN:
+    OldWidth = lppop->Width;
+    SetRect(&rect, 1, 1, OldWidth, 0);
+    lpitem = lppop->firstItem;
+    for(i = 0; i < lppop->nItems; i++) {
+	if (lpitem == NULL) break;
+	rect.right = rect.left + lppop->Width;
+	if ((lpitem->item_flags & MF_SEPARATOR) == MF_SEPARATOR) {
+	    rect.bottom = rect.top + 3;
+	    }
+	if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) {
+	    hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text);
+	    GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
+	    rect.bottom = rect.top + bm.bmHeight;
+	    lppop->Width = max(lppop->Width, bm.bmWidth);
+	    }
+	if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) &&
+	    ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
+	    ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
+	    dwRet = GetTextExtent(hDC, (char *)lpitem->item_text, 
+		strlen((char *)lpitem->item_text));
+	    rect.bottom = rect.top + HIWORD(dwRet);
+	    InflateRect(&rect, 0, 2);
+	    TempWidth = LOWORD(dwRet);
+	    if (GetShortCutPos(lpitem->item_text) != (WORD)-1)
+	        TempWidth += 15;
+	    lppop->Width = max(lppop->Width, TempWidth);
+	    }
+	CopyRect(&lpitem->rect, &rect);
+	rect.top = rect.bottom;
+	lpitem = (LPMENUITEM)lpitem->next;
+	}
+    if (OldWidth < lppop->Width) goto CalcAGAIN;
+    lppop->Height = rect.bottom;
+#ifdef DEBUG_MENUCALC
+    printf("PopupMenuCalcSize w=%d h=%d !\n", 
+    	lppop->Width, lppop->Height);
+#endif
+    SelectObject(hDC, hOldFont);
+    ReleaseDC(0, hDC);
+}
+
+
+
+void MenuBarCalcSize(HWND hwnd)
+{
+    WND 	*wndPtr;
+    LPPOPUPMENU lppop;
+    LPMENUITEM 	lpitem;
+    HDC		hDC;
+    RECT 	rect;
+    HBITMAP	hBitMap;
+    BITMAP	bm;
+    HFONT	hOldFont;
+    UINT  	i, OldHeight;
+    DWORD	dwRet;
+    lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
+    if (lppop == NULL) return;
+    if (lppop->nItems == 0) return;
+    hDC = GetDC(hwnd);
+    hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
+    lppop->Height = 10;
+CalcAGAIN:
+    OldHeight = lppop->Height;
+    SetRect(&rect, 1, 1, 0, OldHeight);
+    lpitem = lppop->firstItem;
+    for(i = 0; i < lppop->nItems; i++) {
+	if (lpitem == NULL) break;
+	rect.bottom = rect.top + lppop->Height;
+	if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) {
+	    hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text);
+	    GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
+	    rect.right = rect.left + bm.bmWidth;
+	    lppop->Height = max(lppop->Height, bm.bmHeight);
+	    }
+	if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) &&
+	    ((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
+	    ((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
+	    dwRet = GetTextExtent(hDC, (char *)lpitem->item_text, 
+		strlen((char *)lpitem->item_text));
+	    rect.right = rect.left + LOWORD(dwRet) + 10;
+	    lppop->Height = max(lppop->Height, HIWORD(dwRet) + 10);
+	    }
+	CopyRect(&lpitem->rect, &rect);
+	rect.left = rect.right;
+	lpitem = (LPMENUITEM)lpitem->next;
+	}
+    if (OldHeight < lppop->Height) goto CalcAGAIN;
+    lppop->Width = rect.right;
+#ifdef DEBUG_MENUCALC
+    printf("MenuBarCalcSize w=%d h=%d !\n", 
+    	lppop->Width, lppop->Height);
+#endif
+    SelectObject(hDC, hOldFont);
+    ReleaseDC(hwnd, hDC);
+}
+
+
 
 LPMENUITEM GetMenuItemPtr(LPPOPUPMENU menu, WORD nPos)
 {
@@ -316,14 +864,106 @@
     if (menu == NULL) return NULL;
     lpitem = menu->firstItem;
     for (i = 0; i < menu->nItems; i++) {
-    	if (lpitem->next == NULL) return NULL;
-    	lpitem = (LPMENUITEM)lpitem->next;
+    	if (lpitem == NULL) return NULL;
     	if (i == nPos) return(lpitem);
+    	lpitem = (LPMENUITEM)lpitem->next;
     	}
     return NULL;
 }
 
 
+WORD GetSelectionKey(LPSTR str)
+{
+    int		i;
+    WORD	sel_key;
+    for (i = 0; i < strlen(str); i++) {
+	if (str[i] == '&' && str[i + 1] != '&') 
+	    {
+	    sel_key = str[i + 1];
+	    if (sel_key >= 'a' && sel_key <= 'z') sel_key -= 'a' - 'A';
+#ifdef DEBUG_MENU
+	    printf("GetSelectionKey // %04X\n", sel_key);
+#endif
+	    return sel_key;
+	    }
+	}
+#ifdef DEBUG_MENU
+    printf("GetSelectionKey NULL \n");
+#endif
+    return 0;
+}
+
+
+
+LPSTR GetShortCutString(LPSTR str)
+{
+    int		i;
+    LPSTR	str2;
+    for (i = 0; i < strlen(str); i++) {
+	if (str[i] == '\t' && str[i + 1] != '\t') 
+	    {
+	    str2 = &str[i + 1];
+#ifdef DEBUG_MENU
+	    printf("GetShortCutString // '%s' \n", str2);
+#endif
+	    return str2;
+	    }
+	}
+#ifdef DEBUG_MENU
+    printf("GetShortCutString NULL \n");
+#endif
+    return NULL;
+}
+
+
+
+WORD GetShortCutPos(LPSTR str)
+{
+    int		i;
+    for (i = 0; i < strlen(str); i++) {
+	if (str[i] == '\t' && str[i + 1] != '\t') 
+	    {
+#ifdef DEBUG_MENU
+	    printf("GetShortCutPos = %d \n", i);
+#endif
+	    return i;
+	    }
+	}
+#ifdef DEBUG_MENU
+    printf("GetShortCutString NULL \n");
+#endif
+    return -1;
+}
+
+
+
+BOOL HideAllSubPopupMenu(LPPOPUPMENU menu)
+{
+    LPPOPUPMENU submenu;
+    LPMENUITEM 	lpitem;
+    BOOL	someClosed = FALSE;
+    int		i;
+    if (menu == NULL) return;
+    lpitem = menu->firstItem;
+    for (i = 0; i < menu->nItems; i++) {
+    	if (lpitem == NULL) return;
+    	if (lpitem->item_flags & MF_POPUP) {
+	    submenu = (LPPOPUPMENU) GlobalLock((HMENU)lpitem->item_id);
+	    if (submenu != NULL) {
+		if (IsWindowVisible(submenu->hWnd)) {
+		    ShowWindow(submenu->hWnd, SW_HIDE);
+		    someClosed = TRUE;
+		    }
+	    	}
+    	    }
+    	lpitem = (LPMENUITEM)lpitem->next;
+    	}
+    return someClosed;
+}
+
+
+#ifdef USE_XTMENU
+
 /**********************************************************************
  *					MENU_CheckWidget
  */
@@ -802,7 +1442,8 @@
     else
 	return MF_CHECKED;
 }
-
+
+
 /**********************************************************************
  *					LoadMenu
  */
@@ -867,12 +1508,36 @@
     return GlobalHandleFromPointer(menu->firstItem);
 }
 
+#endif
+
 
 /**********************************************************************
  *			CheckMenuItem		[USER.154]
  */
 BOOL CheckMenuItem(HMENU hMenu, WORD wItemID, WORD wFlags)
 {
+    WND		*wndPtr;
+    LPPOPUPMENU	menu;
+    LPMENUITEM 	lpitem;
+    int		i;
+#ifdef DEBUG_MENU
+    printf("CheckMenuItem (%04X, %04X, %04X) !\n", hMenu, wItemID, wFlags);
+#endif
+    menu = (LPPOPUPMENU) GlobalLock(hMenu);
+    if (menu == NULL) return FALSE;
+    lpitem = menu->firstItem;
+    for (i = 0; i < menu->nItems; i++) {
+    	if (lpitem == NULL) break;
+    	if (i == wItemID) {
+	    if (wFlags && MF_CHECKED)
+		lpitem->item_flags |= MF_CHECKED;
+	    else
+		lpitem->item_flags &= ((WORD)-1 ^ MF_CHECKED);
+	    return(TRUE);
+	    }
+    	lpitem = (LPMENUITEM)lpitem->next;
+    	}
+    return FALSE;
 }
 
 
@@ -881,6 +1546,28 @@
  */
 BOOL EnableMenuItem(HMENU hMenu, WORD wItemID, WORD wFlags)
 {
+    WND		*wndPtr;
+    LPPOPUPMENU	menu;
+    LPMENUITEM 	lpitem;
+    int		i;
+#ifdef DEBUG_MENU
+    printf("EnableMenuItem (%04X, %04X, %04X) !\n", hMenu, wItemID, wFlags);
+#endif
+    menu = (LPPOPUPMENU) GlobalLock(hMenu);
+    if (menu == NULL) return FALSE;
+    lpitem = menu->firstItem;
+    for (i = 0; i < menu->nItems; i++) {
+    	if (lpitem == NULL) break;
+    	if (i == wItemID) {
+	    if (wFlags && MF_DISABLED)
+		lpitem->item_flags |= MF_DISABLED;
+	    else
+		lpitem->item_flags &= ((WORD)-1 ^ MF_DISABLED);
+	    return(TRUE);
+	    }
+    	lpitem = (LPMENUITEM)lpitem->next;
+    	}
+    return FALSE;
 }
 
 
@@ -902,7 +1589,8 @@
     if (menu == NULL) return FALSE;
     lpitem = menu->firstItem;
     for (i = 0; i < menu->nItems; i++) {
-    	if (lpitem->next == NULL) break;
+    	if (lpitem == NULL) break;
+    	if (i == nPos) break;
     	lpitem = (LPMENUITEM)lpitem->next;
 	printf("InsertMenu // during loop items !\n");
     	}
@@ -910,14 +1598,17 @@
     hNewItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM));
     if (hNewItem == 0) return FALSE;
     lpitem2 = (LPMENUITEM)GlobalLock(hNewItem);
-    if (lpitem2 == 0) {
+    if (lpitem2 == NULL) {
 	GlobalFree(hNewItem);
 	return FALSE;
 	}
     lpitem2->item_flags = wFlags;
     lpitem2->item_id = wItemID;
-    if ((wFlags & MF_STRING) == MF_STRING) {
+    if (((wFlags & MF_BITMAP) != MF_BITMAP) &&
+	((wFlags & MF_MENUBREAK) != MF_MENUBREAK) &&
+	((wFlags & MF_STRING) != MF_SEPARATOR)) {
 	lpitem2->item_text = lpNewItem;
+	lpitem2->sel_key = GetSelectionKey(lpitem2->item_text);
 	}
     else
 	lpitem2->item_text = lpNewItem;
@@ -952,32 +1643,41 @@
     menu = (LPPOPUPMENU) GlobalLock(hMenu);
     if (menu == NULL) return FALSE;
     lpitem = menu->firstItem;
-    while (lpitem->next != NULL) {
-    	lpitem = (LPMENUITEM)lpitem->next;
-	printf("AppendMenu // during loop items !\n");
-    	}
-    printf("AppendMenu // after loop items !\n");
+    if (lpitem != NULL) {
+	while (lpitem->next != NULL) {
+	    lpitem = (LPMENUITEM)lpitem->next;
+	    }
+	}
     hNewItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM));
     if (hNewItem == 0) return FALSE;
     lpitem2 = (LPMENUITEM)GlobalLock(hNewItem);
-    if (lpitem2 == 0) {
+    if (lpitem2 == NULL) {
 	GlobalFree(hNewItem);
 	return FALSE;
 	}
     lpitem2->item_flags = wFlags;
     lpitem2->item_id = wItemID;
-    if ((wFlags & MF_STRING) == MF_STRING) {
+    if (((wFlags & MF_BITMAP) != MF_BITMAP) &&
+	((wFlags & MF_MENUBREAK) != MF_MENUBREAK) &&
+	((wFlags & MF_STRING) != MF_SEPARATOR)) {
 	lpitem2->item_text = lpNewItem;
+	lpitem2->sel_key = GetSelectionKey(lpitem2->item_text);
+	lpitem2->shortcut = GetShortCutString(lpitem2->item_text);
 	}
     else
 	lpitem2->item_text = lpNewItem;
-    lpitem->next = lpitem2;
+    if (lpitem == NULL)
+    	menu->firstItem = lpitem2;
+    else
+    	lpitem->next = lpitem2;
     lpitem2->prev = lpitem;
     lpitem2->next = NULL;
     lpitem2->child = NULL;
     lpitem2->parent = NULL;
     lpitem2->w = NULL;
     lpitem2->menu_w = NULL;
+    lpitem2->hCheckBit = (HBITMAP)NULL;
+    lpitem2->hUnCheckBit = (HBITMAP)NULL;
     menu->nItems++;
     return TRUE;
 }
@@ -999,14 +1699,14 @@
     if (menu == NULL) return FALSE;
     lpitem = menu->firstItem;
     for (i = 0; i < menu->nItems; i++) {
-    	if (lpitem->next == NULL) break;
-    	lpitem = (LPMENUITEM)lpitem->next;
+    	if (lpitem == NULL) break;
     	if (i == nPos) {
     	    lpitem->prev->next = lpitem->next;
     	    lpitem->next->prev = lpitem->prev;
     	    GlobalFree(HIWORD(lpitem));
     	    return(TRUE);
 	    }
+    	lpitem = (LPMENUITEM)lpitem->next;
 	printf("RemoveMenu // during loop items !\n");
     	}
     printf("RemoveMenu // after loop items !\n");
@@ -1031,11 +1731,28 @@
  */
 BOOL ModifyMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewItem)
 {
+    WND		*wndPtr;
+    LPPOPUPMENU	menu;
+    LPMENUITEM 	lpitem;
+    int		i;
 #ifdef DEBUG_MENU
     printf("ModifyMenu (%04X, %04X, %04X, %04X, %08X) !\n",
 	hMenu, nPos, wFlags, wItemID, lpNewItem);
 #endif
-    return TRUE;
+    menu = (LPPOPUPMENU) GlobalLock(hMenu);
+    if (menu == NULL) return FALSE;
+    lpitem = menu->firstItem;
+    for (i = 0; i < menu->nItems; i++) {
+    	if (lpitem == NULL) break;
+    	if (i == nPos) {
+    	    lpitem->item_flags = wFlags;
+    	    lpitem->item_id    = wItemID;
+    	    lpitem->item_text  = lpNewItem;
+    	    return(TRUE);
+	    }
+    	lpitem = (LPMENUITEM)lpitem->next;
+    	}
+    return FALSE;
 }
 
 
@@ -1056,52 +1773,92 @@
 	GlobalFree(hMenu);
 	return 0;
  	}
-    hItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM));
-    if (hItem == 0) {
-	GlobalFree(hMenu);
-	return 0;
-	}
     menu->nItems 	  = 0;
-    menu->firstItem       = (LPMENUITEM)GlobalLock(hItem);
+    menu->firstItem       = NULL;
     menu->ownerWnd	  = 0;
     menu->hWnd		  = 0;
-
-    menu->firstItem->next 	= NULL;
-    menu->firstItem->prev 	= NULL;
-    menu->firstItem->child 	= NULL;
-    menu->firstItem->parent 	= NULL;
-    menu->firstItem->item_flags	= 0;
-    menu->firstItem->item_id 	= 0;
-    menu->firstItem->item_text 	= NULL;
-    menu->firstItem->w 		= NULL;
-    menu->firstItem->menu_w 	= NULL;
+    menu->hWndParent	  = 0;
+    menu->MouseFlags	  = 0;
+    menu->BarFlags	  = 0;
+    menu->Width = 100;
+    menu->Height = 0;
     return hMenu;
 }
 
 
 /**********************************************************************
- *			TrackPopupMenu		[USER.414]
+ *			TrackPopupMenu		[USER.416]
  */
 BOOL TrackPopupMenu(HMENU hMenu, WORD wFlags, short x, short y,
 	short nReserved, HWND hWnd, LPRECT lpRect)
 {
     WND		*wndPtr;
-    LPPOPUPMENU	menu;
+    LPPOPUPMENU	lppop;
 #ifdef DEBUG_MENU
     printf("TrackPopupMenu (%04X, %04X, %d, %d, %04X, %04X, %08X) !\n",
 	hMenu, wFlags, x, y, nReserved, hWnd, lpRect);
 #endif
+    lppop = (LPPOPUPMENU) GlobalLock(hMenu);
+    if (lppop == NULL) return FALSE;
+    wndPtr = WIN_FindWndPtr(hWnd);
+    lppop->ownerWnd = hWnd;
+    if (lppop->hWnd == (HWND)NULL) {
+        lppop->hWnd = CreateWindow("POPUPMENU", "", WS_CHILD | WS_VISIBLE,
+        	x, y, lppop->Width, lppop->Height, hWnd, 0, 
+        	wndPtr->hInstance, (LPSTR)lppop);
+        }
+    else {
+    	ShowWindow(lppop->hWnd, SW_SHOW);
+    	}
+    if (lppop->BarFlags == 0) {
+	PopupMenuCalcSize(lppop->hWnd);
+#ifdef DEBUG_MENU
+	printf("TrackPopupMenu // x=%d y=%d Width=%d Height=%d\n", 
+		x, y, lppop->Width, lppop->Height); 
+#endif
+	SetWindowPos(lppop->hWnd, 0, x, y, lppop->Width + 2, lppop->Height, 
+		SWP_NOZORDER);
+	}
+    else {
+	MenuBarCalcSize(lppop->hWnd);
+#ifdef DEBUG_MENU
+	printf("TrackMenuBar // x=%d y=%d Width=%d Height=%d\n", 
+		x, y, lppop->Width, lppop->Height); 
+#endif
+	SetWindowPos(lppop->hWnd, 0, 0, -16, lppop->Width, lppop->Height, 
+		SWP_NOZORDER);
+	}
+    return TRUE;
+}
+
+
+/**********************************************************************
+ *			SetMenuItemBitmaps	[USER.418]
+ */
+BOOL SetMenuItemBitmaps(HMENU hMenu, WORD nPos, WORD wFlags,
+		HBITMAP hNewCheck, HBITMAP hNewUnCheck)
+{
+    WND		*wndPtr;
+    LPPOPUPMENU	menu;
+    LPMENUITEM 	lpitem;
+    int		i;
+#ifdef DEBUG_MENU
+    printf("SetMenuItemBitmaps (%04X, %04X, %04X, %04X, %08X) !\n",
+	hMenu, nPos, wFlags, hNewCheck, hNewUnCheck);
+#endif
     menu = (LPPOPUPMENU) GlobalLock(hMenu);
     if (menu == NULL) return FALSE;
-    wndPtr = WIN_FindWndPtr(hWnd);
-    menu->ownerWnd = hWnd;
-    if (menu->hWnd == NULL) {
-        menu->hWnd = CreateWindow("POPUPMENU", "", WS_CHILD | WS_VISIBLE,
-        	x, y, 100, 150, hWnd, 0, wndPtr->hInstance, (LPSTR)menu);
-        }
-    else 
-    	ShowWindow(menu->hWnd, SW_SHOW);
-    return TRUE;
+    lpitem = menu->firstItem;
+    for (i = 0; i < menu->nItems; i++) {
+    	if (lpitem == NULL) break;
+    	if (i == nPos) {
+    	    lpitem->hCheckBit   = hNewCheck;
+     	    lpitem->hUnCheckBit = hNewUnCheck;
+    	    return(TRUE);
+	    }
+    	lpitem = (LPMENUITEM)lpitem->next;
+    	}
+    return FALSE;
 }
 
 
@@ -1112,37 +1869,25 @@
 {
     HANDLE	hItem;
     HMENU	hMenu;
-    LPMENUBAR	menu;
+    LPPOPUPMENU menu;
 #ifdef DEBUG_MENU
-    printf("CreateMenu !\n");
+    printf("CreatePopupMenu !\n");
 #endif
-    hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUBAR));
-    menu = (LPMENUBAR) GlobalLock(hMenu);
+    hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(POPUPMENU));
+    menu = (LPPOPUPMENU) GlobalLock(hMenu);
     if (menu == NULL) {
 	GlobalFree(hMenu);
 	return 0;
  	}
-    hItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM));
-    if (hItem == 0) {
-	GlobalFree(hMenu);
-	return 0;
-	}
-    menu->menuDescription = 0;
     menu->nItems 	  = 0;
-    menu->parentWidget    = NULL;
-    menu->firstItem       = (LPMENUITEM) GlobalLock(hItem);
+    menu->firstItem       = NULL;
     menu->ownerWnd	  = 0;
-    menu->menuBarWidget   = NULL;
-
-    menu->firstItem->next 	= NULL;
-    menu->firstItem->prev 	= NULL;
-    menu->firstItem->child 	= NULL;
-    menu->firstItem->parent 	= NULL;
-    menu->firstItem->item_flags	= 0;
-    menu->firstItem->item_id 	= 0;
-    menu->firstItem->item_text 	= NULL;
-    menu->firstItem->w 		= NULL;
-    menu->firstItem->menu_w 	= NULL;
+    menu->hWnd		  = 0;
+    menu->hWndParent	  = 0;
+    menu->MouseFlags	  = 0;
+    menu->BarFlags	  = TRUE;
+    menu->Width = 100;
+    menu->Height = 0;
     return hMenu;
 }
 
@@ -1162,7 +1907,7 @@
     if (lppop == NULL) return FALSE;
     if (lppop->hWnd) DestroyWindow (lppop->hWnd);
     lpitem = lppop->firstItem;
-    while (lpitem->next != NULL) {
+    while (lpitem != NULL) {
 #ifdef DEBUG_MENU
 	printf("DestroyMenu (%04X) // during loop items !\n", hMenu);
 #endif
@@ -1179,3 +1924,89 @@
 }
 
 
+#ifdef USE_POPUPMENU
+
+
+/**********************************************************************
+ *			DrawMenuBar		[USER.152]
+ */
+void DrawMenuBar(HWND hWnd)
+{
+    WND		*wndPtr;
+#ifdef DEBUG_MENU
+    printf("DrawMenuBar (%04X)\n", hWnd);
+#endif
+    wndPtr = WIN_FindWndPtr(hWnd);
+    if (wndPtr != NULL && wndPtr->hWndMenuBar != 0) {
+	InvalidateRect(wndPtr->hWndMenuBar, NULL, TRUE);
+	UpdateWindow(wndPtr->hWndMenuBar);
+	}
+}
+
+
+/**********************************************************************
+ *			LoadMenu		[USER.152]
+ */
+HMENU LoadMenu(HINSTANCE instance, char *menu_name)
+{
+    HMENU     		hMenu;
+    HANDLE		hMenu_desc;
+    MENU_HEADER 	*menu_desc;
+
+#ifdef DEBUG_MENU
+    printf("LoadMenu: instance %02x, menu '%s'\n",
+	   instance, menu_name);
+#endif
+    if (menu_name == NULL || 
+	(hMenu_desc = RSC_LoadMenu(instance, menu_name)) == 0 ||
+	(menu_desc = (MENU_HEADER *) GlobalLock(hMenu_desc)) == NULL)
+    {
+	return 0;
+    }
+    hMenu = CreateMenu();
+    ParseMenuResource((WORD *) (menu_desc + 1), 0, hMenu);
+    
+    return hMenu;
+}
+
+
+WORD * ParseMenuResource(WORD *first_item, int level, HMENU hMenu)
+{
+    WORD 	*item;
+    WORD 	*next_item;
+    HMENU	hSubMenu;
+    int   	i;
+
+    level++;
+    next_item = first_item;
+    i = 0;
+    do
+    {
+	i++;
+	item = next_item;
+	if (*item & MF_POPUP)
+	{
+	    MENU_POPUPITEM *popup_item = (MENU_POPUPITEM *) item;
+	    next_item = (WORD *) (popup_item->item_text + 
+				  strlen(popup_item->item_text) + 1);
+	    hSubMenu = CreatePopupMenu();
+	    next_item = ParseMenuResource(next_item, level, hSubMenu);
+	    AppendMenu(hMenu, popup_item->item_flags, 
+	    	hSubMenu, popup_item->item_text);
+	}
+	else
+	{
+	    MENU_NORMALITEM *normal_item = (MENU_NORMALITEM *) item;
+	    next_item = (WORD *) (normal_item->item_text + 
+				  strlen(normal_item->item_text) + 1);
+	    AppendMenu(hMenu, normal_item->item_flags, 
+	    	normal_item->item_id, normal_item->item_text);
+	}
+    }
+    while (!(*item & MF_END));
+
+    return next_item;
+}
+
+#endif
+
diff --git a/controls/scroll.c b/controls/scroll.c
index 9cfa550..439be8d 100644
--- a/controls/scroll.c
+++ b/controls/scroll.c
@@ -21,6 +21,15 @@
 #include <dirent.h>
 #include <sys/stat.h>
 
+HBITMAP hUpArrow = 0;
+HBITMAP hDnArrow = 0;
+HBITMAP hLfArrow = 0;
+HBITMAP hRgArrow = 0;
+HBITMAP hUpArrowD = 0;
+HBITMAP hDnArrowD = 0;
+HBITMAP hLfArrowD = 0;
+HBITMAP hRgArrowD = 0;
+
 LPHEADSCROLL ScrollBarGetWindowAndStorage(HWND hwnd, WND **wndPtr);
 LPHEADSCROLL ScrollBarGetStorageHeader(HWND hwnd);
 void StdDrawScrollBar(HWND hwnd);
@@ -34,9 +43,13 @@
 {    
     WORD	wRet;
     short	x, y;
+    short	width, height;
     WND  	*wndPtr;
     LPHEADSCROLL lphs;
-    RECT rect;
+    LPDRAWITEMSTRUCT lpdis;
+    HDC		hMemDC;
+    BITMAP	bm;
+    RECT 	rect;
     static RECT rectsel;
     switch(message)
     {
@@ -45,6 +58,22 @@
 #ifdef DEBUG_SCROLL
         printf("ScrollBar Creation up=%X down=%X!\n", lphs->hWndUp, lphs->hWndDown);
 #endif
+	if (hUpArrow == (HBITMAP)NULL) 
+	    hUpArrow = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_UPARROWI));
+	if (hDnArrow == (HBITMAP)NULL) 
+	    hDnArrow = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_DNARROWI));
+	if (hLfArrow == (HBITMAP)NULL) 
+	    hLfArrow = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_LFARROWI));
+	if (hRgArrow == (HBITMAP)NULL) 
+	    hRgArrow = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_RGARROWI));
+	if (hUpArrowD == (HBITMAP)NULL) 
+	    hUpArrowD = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_UPARROWD));
+	if (hDnArrowD == (HBITMAP)NULL) 
+	    hDnArrowD = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_DNARROWD));
+	if (hLfArrowD == (HBITMAP)NULL) 
+	    hLfArrowD = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_LFARROWD));
+	if (hRgArrowD == (HBITMAP)NULL) 
+	    hRgArrowD = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_RGARROWD));
 	return 0;
     case WM_DESTROY:
 	lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr);
@@ -129,15 +158,6 @@
 	ReleaseCapture();
 	break;
 
-    case WM_KEYDOWN:
-    case WM_KEYUP:
-    case WM_CHAR:
-	lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr);
-	return(SendMessage(wndPtr->hwndParent, message, wParam, lParam));
-
-    case WM_PAINT:
-	StdDrawScrollBar(hwnd);
-	break;
     case WM_MOUSEMOVE:
         if ((wParam & MK_LBUTTON) != 0) {
 	    lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr);
@@ -150,12 +170,88 @@
 	    x = (y * (lphs->MaxVal - lphs->MinVal) / 
 	    		lphs->MaxPix) + lphs->MinVal;
 #ifdef DEBUG_SCROLL
-	    printf("WM_MOUSEMOVE val=%d pix=%d\n", x, y);
+	    printf("Scroll WM_MOUSEMOVE val=%d pix=%d\n", x, y);
 #endif
             SendMessage(wndPtr->hwndParent, lphs->Direction, 
             		SB_THUMBTRACK, MAKELONG(x, hwnd));
 	    }
 	break;
+    case WM_KEYDOWN:
+    case WM_KEYUP:
+    case WM_CHAR:
+	lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr);
+	return(SendMessage(wndPtr->hwndParent, message, wParam, lParam));
+
+    case WM_SIZE:
+	lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr);
+	width  = LOWORD(lParam);
+	height = HIWORD(lParam);
+	if (lphs->Direction == WM_VSCROLL) {
+	    MoveWindow(lphs->hWndUp, 0, 0, width, width, TRUE);
+	    MoveWindow(lphs->hWndDown, 0, height - width, width, width, TRUE);
+	    }
+	else {
+	    MoveWindow(lphs->hWndUp, 0, 0, height, height, TRUE);
+	    MoveWindow(lphs->hWndDown, width - height, 0, height, height, TRUE);
+	    }
+	break;
+    case WM_DRAWITEM:
+#ifdef DEBUG_SCROLL
+	    printf("Scroll WM_DRAWITEM w=%04X l=%08X\n", wParam, lParam);
+#endif
+        lpdis = (LPDRAWITEMSTRUCT)lParam;
+	if (lpdis->CtlType == ODT_BUTTON && lpdis->itemAction == ODA_DRAWENTIRE) {
+	    hMemDC = CreateCompatibleDC(lpdis->hDC);
+	    if (lpdis->CtlID == 1) {
+		GetObject(hUpArrow, sizeof(BITMAP), (LPSTR)&bm);
+		SelectObject(hMemDC, hUpArrow);
+		BitBlt(lpdis->hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
+		}
+	    if (lpdis->CtlID == 2) {
+		GetObject(hDnArrow, sizeof(BITMAP), (LPSTR)&bm);
+		SelectObject(hMemDC, hDnArrow);
+		BitBlt(lpdis->hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
+		}
+	    if (lpdis->CtlID == 3) {
+		GetObject(hLfArrow, sizeof(BITMAP), (LPSTR)&bm);
+		SelectObject(hMemDC, hLfArrow);
+		BitBlt(lpdis->hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
+		}
+	    if (lpdis->CtlID == 4) {
+		GetObject(hRgArrow, sizeof(BITMAP), (LPSTR)&bm);
+		SelectObject(hMemDC, hRgArrow);
+		BitBlt(lpdis->hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
+		}
+	    DeleteDC(hMemDC);
+	    }
+	if (lpdis->CtlType == ODT_BUTTON && lpdis->itemAction == ODA_SELECT) {
+	    hMemDC = CreateCompatibleDC(lpdis->hDC);
+	    if (lpdis->CtlID == 1) {
+		GetObject(hUpArrowD, sizeof(BITMAP), (LPSTR)&bm);
+		SelectObject(hMemDC, hUpArrowD);
+		BitBlt(lpdis->hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
+		}
+	    if (lpdis->CtlID == 2) {
+		GetObject(hDnArrowD, sizeof(BITMAP), (LPSTR)&bm);
+		SelectObject(hMemDC, hDnArrowD);
+		BitBlt(lpdis->hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
+		}
+	    if (lpdis->CtlID == 3) {
+		GetObject(hLfArrowD, sizeof(BITMAP), (LPSTR)&bm);
+		SelectObject(hMemDC, hLfArrowD);
+		BitBlt(lpdis->hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
+		}
+	    if (lpdis->CtlID == 4) {
+		GetObject(hRgArrowD, sizeof(BITMAP), (LPSTR)&bm);
+		SelectObject(hMemDC, hRgArrowD);
+		BitBlt(lpdis->hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
+		}
+	    DeleteDC(hMemDC);
+	    }
+	break;
+    case WM_PAINT:
+	StdDrawScrollBar(hwnd);
+	break;
     default:
 	return DefWindowProc( hwnd, message, wParam, lParam );
     }
@@ -274,10 +370,10 @@
 	lphs->MaxPix = height - 3 * width;
 	lphs->Direction = WM_VSCROLL;
 	lphs->hWndUp = CreateWindow("BUTTON", "", 
-        	WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
+        	WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,
         	0, 0, width, width, hwnd, 1, wndPtr->hInstance, 0L);
 	lphs->hWndDown = CreateWindow("BUTTON", "", 
-        	WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
+        	WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,
         	0, height - width, width, width, hwnd, 2,
         	wndPtr->hInstance, 0L);
 	}
@@ -286,11 +382,11 @@
 	lphs->MaxPix = width - 3 * height;
 	lphs->Direction = WM_HSCROLL;
 	lphs->hWndUp = CreateWindow("BUTTON", "", 
-        	WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
-        	0, 0, height, height, hwnd, 0, wndPtr->hInstance, 0L);
+        	WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,
+        	0, 0, height, height, hwnd, 3, wndPtr->hInstance, 0L);
 	lphs->hWndDown = CreateWindow("BUTTON", "", 
-        	WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
-        	width - height, 0, height, height, hwnd, 0,
+        	WS_CHILD | WS_VISIBLE | BS_OWNERDRAW,
+        	width - height, 0, height, height, hwnd, 4,
         	wndPtr->hInstance, 0L);
 	}
     if (lphs->MaxPix < 1)  lphs->MaxPix = 1;
diff --git a/controls/widgets.c b/controls/widgets.c
index c88ac44..02d10b4 100644
--- a/controls/widgets.c
+++ b/controls/widgets.c
@@ -17,6 +17,7 @@
 LONG ListBoxWndProc  ( HWND hwnd, WORD message, WORD wParam, LONG lParam );
 LONG ComboBoxWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam );
 LONG PopupMenuWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam );
+LONG CaptionBarWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam );
 
 
 static WNDCLASS WIDGETS_BuiltinClasses[] =
@@ -33,6 +34,8 @@
       0, 0, 0, 0, NULL, "COMBOBOX" },
     { CS_GLOBALCLASS, (LONG(*)())PopupMenuWndProc, 0, 8,
       0, 0, 0, 0, NULL, "POPUPMENU" },
+    { CS_GLOBALCLASS, (LONG(*)())CaptionBarWndProc, 0, 8,
+      0, 0, 0, 0, NULL, "CAPTION" },
     { CS_GLOBALCLASS, (LONG(*)())DefDlgProc, 0, DLGWINDOWEXTRA,
       0, 0, 0, 0, NULL, DIALOG_CLASS_NAME }
 };
diff --git a/debugger/info.c b/debugger/info.c
index 063447a..87aec59 100644
--- a/debugger/info.c
+++ b/debugger/info.c
@@ -172,7 +172,7 @@
 		pnt = (char *) addr;
 		for(i=0; i<count; i++) 
 		{
-			fprintf(stderr," %w", *pnt++);
+			fprintf(stderr," %02.2x", (*pnt++) & 0xff);
 			if ((i % 32) == 7) {
 				fprintf(stderr,"\n");
 				print_address((unsigned int) pnt, stderr);
diff --git a/if1632/relay.c b/if1632/relay.c
index d6ad335..fba4f52 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -19,6 +19,8 @@
 #include "prototypes.h"
 #include "dlls.h"
 
+/* #define DEBUG_RELAY */
+
 #define N_BUILTINS	8
 
 struct dll_name_table_entry_s dll_builtin_table[N_BUILTINS] =
@@ -99,14 +101,6 @@
 	       IF1632_Saved16_esp, IF1632_Saved16_ebp,
 	       IF1632_Saved16_ss);
 
-	if (strcmp("GetMessage", dll_p->export_name) == 0 &&
-	    seg_off == 0x00972526 &&
-	    *ret_addr == 0x004700cd &&
-	    IF1632_Saved16_esp == 0x2526 &&
-	    IF1632_Saved16_ebp == 0x2534 &&
-	    IF1632_Saved16_ss  == 0x0097)
-	    printf("ACK!!\n");
-
 #ifdef DEBUG_STACK
 	stack_p = (unsigned short *) seg_off;
 	for (i = 0; i < 24; i++, stack_p++)
diff --git a/if1632/user.spec b/if1632/user.spec
index 86682f1..24c3e24 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -120,6 +120,7 @@
 155 pascal EnableMenuItem(word word word) EnableMenuItem(1 2 3)
 157 pascal GetMenu(word) GetMenu(1)
 158 pascal SetMenu(word word) SetMenu(1 2)
+160 pascal DrawMenuBar(word) DrawMenuBar(1)
 163 pascal CreateCaret(word word word word) CreateCaret(1 2 3 4)
 164 pascal DestroyCaret() DestroyCaret()
 165 pascal SetCaretPos(word word) SetCaretPos(1 2)
@@ -206,6 +207,8 @@
 415 pascal CreatePopupMenu() CreatePopupMenu()
 416 pascal TrackPopupMenu(word word word word word word ptr) 
 	   TrackPopupMenu(1 2 3 4 5 6 7)
+418 pascal SetMenuItemBitmaps(word word word word word) 
+	   SetMenuItemBitmaps(1 2 3 4 5)
 420 pascal wsprintf(ptr ptr) wsprintf(1 2)
 421 pascal wvsprintf(ptr ptr ptr) wvsprintf(1 2 3)
 430 pascal lstrcmp(ptr ptr) lstrcmp(1 2)
@@ -220,6 +223,7 @@
 452 pascal CreateWindowEx(long ptr ptr long s_word s_word s_word s_word 
 	                  word word word ptr) 
 	   CreateWindowEx(1 2 3 4 5 6 7 8 9 10 11 12)
+454 pascal AdjustWindowRectEx(ptr long word long) AdjustWindowRectEx(1 2 3 4)
 457 pascal DestroyIcon(word) DestroyIcon(1)
 458 pascal DestroyCursor(word) DestroyCursor(1)
 471 pascal lstrcmpi(ptr ptr) lstrcmpi(1 2)
diff --git a/include/caption.h b/include/caption.h
new file mode 100644
index 0000000..0c951c3
--- /dev/null
+++ b/include/caption.h
@@ -0,0 +1,17 @@
+/*
+ *   Caption Bar definitions
+ */
+
+
+typedef struct tagHEADCAPTION {
+    HBITMAP	hClose;
+    HBITMAP	hMinim;
+    HBITMAP	hMaxim;
+    HMENU	hSysMenu;
+    RECT	rectClose;
+    RECT	rectMinim;
+    RECT	rectMaxim;
+} HEADCAPTION;
+typedef HEADCAPTION FAR* LPHEADCAPTION;
+
+
diff --git a/include/gdi.h b/include/gdi.h
index aade98d..b077135 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -282,7 +282,10 @@
 extern BOOL GDI_FreeObject( HANDLE );
 extern GDIOBJHDR * GDI_GetObjPtr( HANDLE, WORD );
 
-extern Display * XT_display;
-extern Screen * XT_screen;
+extern Display * XT_display;  /* Will be removed */
+extern Screen * XT_screen;    /* Will be removed */
+
+extern Display * display;
+extern Screen * screen;
 
 #endif  /* GDI_H */
diff --git a/include/menu.h b/include/menu.h
index edc0bec..fa74240 100644
--- a/include/menu.h
+++ b/include/menu.h
@@ -13,7 +13,6 @@
 #include <X11/Xaw/Command.h>
 #include <X11/Xaw/Box.h>
 
-#include "windows.h"
 
 typedef struct tagMENUITEM
 {
@@ -23,7 +22,9 @@
     struct tagMENUITEM *parent;
     WORD	item_flags;
     WORD	item_id;
-    char       *item_text;
+    WORD	sel_key;
+    char	*shortcut;
+    char	*item_text;
     Widget	w;
     Widget	menu_w;
     char	menu_name[10];
@@ -46,11 +47,15 @@
 typedef struct tagPOPUPMENU
 {
     HWND	hWnd;			/* PopupMenu window handle	  */
+    HWND	hWndParent;		/* Parent opupMenu window handle  */
     HWND	ownerWnd;		/* Owner window			  */
     WORD	nItems;    		/* Number of items on menu	  */
     MENUITEM   *firstItem;
     WORD	FocusedItem;
     WORD	MouseFlags;
+    WORD	BarFlags;
+    WORD	Width;
+    WORD	Height;
 } POPUPMENU, *LPPOPUPMENU;
 
 typedef struct
diff --git a/include/sysmetrics.h b/include/sysmetrics.h
new file mode 100644
index 0000000..186d213
--- /dev/null
+++ b/include/sysmetrics.h
@@ -0,0 +1,55 @@
+/*
+ * System metrics definitions
+ *
+ * Copyright 1994 Alexandre Julliard
+ */
+
+#ifndef SYSMETRICS_H
+#define SYSMETRICS_H
+
+#include "windows.h"
+
+
+  /* Constant system metrics */
+#define SYSMETRICS_CXVSCROLL         16
+#define SYSMETRICS_CYHSCROLL         16
+#define SYSMETRICS_CYCAPTION         20
+#define SYSMETRICS_CXBORDER           1
+#define SYSMETRICS_CYBORDER           1
+#define SYSMETRICS_CXDLGFRAME         4
+#define SYSMETRICS_CYDLGFRAME         4
+#define SYSMETRICS_CYVTHUMB          16
+#define SYSMETRICS_CXHTHUMB          16
+#define SYSMETRICS_CXICON            32
+#define SYSMETRICS_CYICON            32
+#define SYSMETRICS_CXCURSOR          32
+#define SYSMETRICS_CYCURSOR          32
+#define SYSMETRICS_CYMENU            18
+#define SYSMETRICS_CYVSCROLL         16
+#define SYSMETRICS_CXHSCROLL         16
+#define SYSMETRICS_CXMIN            100
+#define SYSMETRICS_CYMIN             28
+#define SYSMETRICS_CXSIZE            18
+#define SYSMETRICS_CYSIZE            18
+#define SYSMETRICS_CXMINTRACK       100
+#define SYSMETRICS_CYMINTRACK        28
+#define SYSMETRICS_CXICONSPACING     20
+#define SYSMETRICS_CYICONSPACING     20
+
+  /* Some non-constant system metrics */
+#define SYSMETRICS_CXSCREEN            sysMetrics[SM_CXSCREEN]
+#define SYSMETRICS_CYSCREEN            sysMetrics[SM_CYSCREEN]
+#define SYSMETRICS_CXFULLSCREEN        sysMetrics[SM_CXFULLSCREEN]
+#define SYSMETRICS_CYFULLSCREEN        sysMetrics[SM_CYFULLSCREEN]
+#define SYSMETRICS_SWAPBUTTON          sysMetrics[SM_SWAPBUTTON]
+#define SYSMETRICS_CXFRAME             sysMetrics[SM_CXFRAME]
+#define SYSMETRICS_CYFRAME             sysMetrics[SM_CYFRAME]
+#define SYSMETRICS_CXDOUBLECLK         sysMetrics[SM_CXDOUBLECLK]
+#define SYSMETRICS_CYDOUBLECLK         sysMetrics[SM_CYDOUBLECLK]
+#define SYSMETRICS_MENUDROPALIGNMENT   sysMetrics[SM_MENUDROPALIGNMENT]
+
+
+extern short sysMetrics[SM_CMETRICS];
+
+
+#endif
diff --git a/include/win.h b/include/win.h
index b90675d..8bb8d57 100644
--- a/include/win.h
+++ b/include/win.h
@@ -7,7 +7,7 @@
 #ifndef WIN_H
 #define WIN_H
 
-#include <X11/Intrinsic.h>
+#include <X11/Xlib.h>
 
 #include "windows.h"
 #include "menu.h"
@@ -40,11 +40,10 @@
     WORD         wIDmenu;        /* ID or hmenu (from CreateWindow) */
     HANDLE       hText;          /* Handle of window text */
     WORD         flags;          /* Misc. flags */
-    Widget       shellWidget;    /* For top-level windows */
-    Widget       winWidget;      /* For all windows */
-    Widget       compositeWidget;/* For top-level windows */
     Window       window;         /* X window */
     LPMENUBAR	 menuBarPtr;	 /* Menu bar */
+    HWND	 hWndMenuBar;	 /* Menu bar */
+    HWND	 hWndCaption;	 /* Caption bar */
     WORD         wExtra[1];      /* Window extra bytes */
 } WND;
 
@@ -54,6 +53,7 @@
 #define WIN_GOT_SIZEMSG         0x04  /* WM_SIZE has been sent to the window */
 #define WIN_OWN_DC              0x08  /* Win class has style CS_OWNDC */
 #define WIN_CLASS_DC            0x10  /* Win class has style CS_CLASSDC */
+#define WIN_DOUBLE_CLICKS       0x20  /* Win class has style CS_DBLCLKS */
 
   /* Window functions */
 WND *WIN_FindWndPtr( HWND hwnd );
diff --git a/include/windows.h b/include/windows.h
index ae37d54..7cfecdc 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -238,6 +238,49 @@
 #define WVR_REDRAW          (WVR_HREDRAW | WVR_VREDRAW)
 #define WVR_VALIDRECTS      0x0400
 
+  /* WM_NCHITTEST return codes */
+#define HTERROR             (-2)
+#define HTTRANSPARENT       (-1)
+#define HTNOWHERE           0
+#define HTCLIENT            1
+#define HTCAPTION           2
+#define HTSYSMENU           3
+#define HTSIZE              4
+#define HTMENU              5
+#define HTHSCROLL           6
+#define HTVSCROLL           7
+#define HTMINBUTTON         8
+#define HTMAXBUTTON         9
+#define HTLEFT              10
+#define HTRIGHT             11
+#define HTTOP               12
+#define HTTOPLEFT           13
+#define HTTOPRIGHT          14
+#define HTBOTTOM            15
+#define HTBOTTOMLEFT        16
+#define HTBOTTOMRIGHT       17
+#define HTBORDER            18
+#define HTGROWBOX           HTSIZE
+#define HTREDUCE            HTMINBUTTON
+#define HTZOOM              HTMAXBUTTON
+
+  /* WM_SYSCOMMAND parameters */
+#define SC_SIZE         0xf000
+#define SC_MOVE         0xf010
+#define SC_MINIMIZE     0xf020
+#define SC_MAXIMIZE     0xf030
+#define SC_NEXTWINDOW   0xf040
+#define SC_PREVWINDOW   0xf050
+#define SC_CLOSE        0xf060
+#define SC_VSCROLL      0xf070
+#define SC_HSCROLL      0xf080
+#define SC_MOUSEMENU    0xf090
+#define SC_KEYMENU      0xf100
+#define SC_ARRANGE      0xf110
+#define SC_RESTORE      0xf120
+#define SC_TASKLIST     0xf130
+#define SC_SCREENSAVE   0xf140
+#define SC_HOTKEY       0xf150
 
   /* Dialogs */
 
@@ -794,6 +837,8 @@
 #define SM_PENWINDOWS         41
 #define SM_DBCSENABLED        42
 
+#define SM_CMETRICS           43
+
   /* Device-independent bitmaps */
 
 typedef struct { BYTE rgbBlue, rgbGreen, rgbRed, rgbReserved; } RGBQUAD;
@@ -1058,6 +1103,63 @@
 #define IDC_SIZEWE MAKEINTRESOURCE(32544)
 #define IDC_SIZENS MAKEINTRESOURCE(32545)
 
+/* OEM Resource Ordinal Numbers */
+#define OBM_CLOSE           32754
+#define OBM_UPARROW         32753
+#define OBM_DNARROW         32752
+#define OBM_RGARROW         32751
+#define OBM_LFARROW         32750
+#define OBM_REDUCE          32749
+#define OBM_ZOOM            32748
+#define OBM_RESTORE         32747
+#define OBM_REDUCED         32746
+#define OBM_ZOOMD           32745
+#define OBM_RESTORED        32744
+#define OBM_UPARROWD        32743
+#define OBM_DNARROWD        32742
+#define OBM_RGARROWD        32741
+#define OBM_LFARROWD        32740
+#define OBM_MNARROW         32739
+#define OBM_COMBO           32738
+#define OBM_UPARROWI        32737
+#define OBM_DNARROWI        32736
+#define OBM_RGARROWI        32735
+#define OBM_LFARROWI        32734
+
+#define OBM_OLD_CLOSE       32767
+#define OBM_SIZE            32766
+#define OBM_OLD_UPARROW     32765
+#define OBM_OLD_DNARROW     32764
+#define OBM_OLD_RGARROW     32763
+#define OBM_OLD_LFARROW     32762
+#define OBM_BTSIZE          32761
+#define OBM_CHECK           32760
+#define OBM_CHECKBOXES      32759
+#define OBM_BTNCORNERS      32758
+#define OBM_OLD_REDUCE      32757
+#define OBM_OLD_ZOOM        32756
+#define OBM_OLD_RESTORE     32755
+
+#define OCR_NORMAL          32512
+#define OCR_IBEAM           32513
+#define OCR_WAIT            32514
+#define OCR_CROSS           32515
+#define OCR_UP              32516
+#define OCR_SIZE            32640
+#define OCR_ICON            32641
+#define OCR_SIZENWSE        32642
+#define OCR_SIZENESW        32643
+#define OCR_SIZEWE          32644
+#define OCR_SIZENS          32645
+#define OCR_SIZEALL         32646
+#define OCR_ICOCUR          32647
+
+#define OIC_SAMPLE          32512
+#define OIC_HAND            32513
+#define OIC_QUES            32514
+#define OIC_BANG            32515
+#define OIC_NOTE            32516
+
   /* Stock GDI objects for GetStockObject() */
 
 #define WHITE_BRUSH	    0
@@ -1097,10 +1199,25 @@
 
 #define WM_NCCREATE         0x0081
 #define WM_NCDESTROY        0x0082
-#define WM_NCCALCSIZE	    0x0083
+#define WM_NCCALCSIZE       0x0083
+#define WM_NCHITTEST        0x0084
+#define WM_NCPAINT          0x0085
+#define WM_NCACTIVATE       0x0086
 
 #define WM_GETDLGCODE	    0x0087
 
+  /* Non-client mouse messages */
+#define WM_NCMOUSEMOVE      0x00a0
+#define WM_NCLBUTTONDOWN    0x00a1
+#define WM_NCLBUTTONUP      0x00a2
+#define WM_NCLBUTTONDBLCLK  0x00a3
+#define WM_NCRBUTTONDOWN    0x00a4
+#define WM_NCRBUTTONUP      0x00a5
+#define WM_NCRBUTTONDBLCLK  0x00a6
+#define WM_NCMBUTTONDOWN    0x00a7
+#define WM_NCMBUTTONUP      0x00a8
+#define WM_NCMBUTTONDBLCLK  0x00a9
+
   /* Keyboard messages */
 #define WM_KEYDOWN          0x0100
 #define WM_KEYUP            0x0101
@@ -1115,6 +1232,7 @@
 
 #define WM_INITDIALOG       0x0110 
 #define WM_COMMAND          0x0111
+#define WM_SYSCOMMAND       0x0112
 #define WM_TIMER	    0x0113
 #define WM_SYSTIMER	    0x0118
 
@@ -1166,6 +1284,14 @@
 #define PM_REMOVE	0x0001
 #define PM_NOYIELD	0x0002
 
+#define WM_SHOWWINDOW       0x0018
+
+/* WM_SHOWWINDOW wParam codes */
+#define SW_PARENTCLOSING    1
+#define SW_OTHERMAXIMIZED   2
+#define SW_PARENTOPENING    3
+#define SW_OTHERRESTORED    4
+
 enum { SW_HIDE, SW_SHOWNORMAL, SW_NORMAL, SW_SHOWMINIMIZED, SW_SHOWMAXIMIZED,
 	SW_MAXIMIZE, SW_SHOWNOACTIVATE, SW_SHOW, SW_MINIMIZE,
 	SW_SHOWMINNOACTIVE, SW_SHOWNA, SW_RESTORE };
@@ -1284,9 +1410,7 @@
 #define DT_NOPREFIX 2048
 #define DT_INTERNAL 4096
 
-
-
-
+/* Window Styles */
 #define WS_OVERLAPPED 0x00000000L
 #define WS_POPUP 0x80000000L
 #define WS_CHILD 0x40000000L
@@ -2022,7 +2146,7 @@
 Fa(WORD,GetRelAbs,HDC,a)
 Fa(WORD,GetROP2,HDC,a)
 Fa(WORD,GetStretchBltMode,HDC,a)
-Fa(int,GetSystemMetrics,short,a)
+Fa(int,GetSystemMetrics,WORD,a)
 Fa(int,GetWindowTextLength,HWND,a)
 Fa(int,RestoreVisRgn,HDC,a)
 Fa(int,SaveDC,HDC,a)
@@ -2347,7 +2471,7 @@
 Fd(int,MessageBox,HWND,a,LPSTR,b,LPSTR,c,WORD,d)
 Fd(int,SetScrollPos,HWND,a,int,b,int,c,BOOL,d)
 Fd(int,SetVoiceNote,int,a,int,b,int,c,int,d)
-Fd(void,AdjustWindowRectEx,LPRECT,a,LONG,b,BOOL,c,DWORD,d)
+Fd(void,AdjustWindowRectEx,LPRECT,a,DWORD,b,BOOL,c,DWORD,d)
 Fd(void,AnimatePalette,HPALETTE,a,WORD,b,WORD,c,LPPALETTEENTRY,d)
 Fd(void,CheckRadioButton,HWND,a,WORD,b,WORD,c,WORD,d)
 Fd(void,CreateCaret,HWND,a,HBITMAP,b,short,c,short,d)
diff --git a/include/wineopts.h b/include/wineopts.h
new file mode 100644
index 0000000..6f3e66b
--- /dev/null
+++ b/include/wineopts.h
@@ -0,0 +1,11 @@
+/* WINEOPTS.H
+ */
+
+#ifndef WINEOPTS_H
+#define WINEOPTS_H
+
+#include <stdio.h>
+
+FILE *SpyFp;
+
+#endif /* WINEOPTS_H */
diff --git a/loader/resource.c b/loader/resource.c
index 9d97305..da059d1 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -153,6 +153,7 @@
     if (read(ResourceFd, &size_shift, sizeof(size_shift)) != 
 	sizeof(size_shift))
     {
+    	printf("FindResourceByNumber (%s) bad block size !\n", resource_id);
 	return -1;
     }
     
@@ -160,40 +161,38 @@
      * Find resource.
      */
     typeinfo.type_id = 0xffff;
-    while (typeinfo.type_id != 0)
-    {
+    while (typeinfo.type_id != 0) {
 	if (read(ResourceFd, &typeinfo, sizeof(typeinfo)) !=
-	    sizeof(typeinfo))
-	{
+	    sizeof(typeinfo)) {
+	    printf("FindResourceByNumber (%X) bad typeinfo size !\n", resource_id);
 	    return -1;
-	}
-	if (typeinfo.type_id != 0)
-	{
-	    for (i = 0; i < typeinfo.count; i++)
-	    {
-		if (read(ResourceFd, &nameinfo, sizeof(nameinfo)) != 
-		    sizeof(nameinfo))
-		{
-		    return -1;
-		}
-
-#if defined(DEBUG_RESOURCE) && defined(VERBOSE_DEBUG)
-		if (type_id == typeinfo.type_id)
-		{
-		    printf("FindResource: type id = %d, resource id = %x\n",
-			   type_id, nameinfo.id);
-		}
+	    }
+#ifdef DEBUG_RESOURCE
+	printf("FindResourceByNumber type=%X count=%d\n", 
+			typeinfo.type_id, typeinfo.count);
 #endif
-		if ((type_id == -1 || typeinfo.type_id == type_id) &&
-		    nameinfo.id == resource_id)
-		{
+	if (typeinfo.type_id == 0) break;
+	if (typeinfo.type_id == type_id || type_id == -1) {
+	    for (i = 0; i < typeinfo.count; i++) {
+		if (read(ResourceFd, &nameinfo, sizeof(nameinfo)) != 
+		    sizeof(nameinfo)) {
+		    printf("FindResourceByNumber (%X) bad nameinfo size !\n", resource_id);
+		    return -1;
+		    }
+#ifdef DEBUG_RESOURCE
+		printf("FindResource: search type=%X id=%X // type=%X id=%X\n",
+			type_id, resource_id, typeinfo.type_id, nameinfo.id);
+#endif
+		if (nameinfo.id == resource_id) {
 		    memcpy(result_p, &nameinfo, sizeof(nameinfo));
 		    return size_shift;
-		}
+		    }
+	        }
 	    }
-	}
-    }
-    
+	else {
+	    lseek(ResourceFd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR);
+	    }
+        }
     return -1;
 }
 
@@ -243,7 +242,7 @@
 	    return -1;
 	}
 #ifdef DEBUG_RESOURCE
-	printf("FindResourceByName typeinfo.type_id=%d type_id=%d\n",
+	printf("FindResourceByName typeinfo.type_id=%X type_id=%X\n",
 			typeinfo.type_id, type_id);
 #endif
 	if (typeinfo.type_id == 0) break;
@@ -269,7 +268,7 @@
 		lseek(ResourceFd, old_pos, SEEK_SET);
 		name[nbytes] = '\0';
 #ifdef DEBUG_RESOURCE
-		printf("FindResourceByName type_id=%d name='%s' resource_name='%s'\n", 
+		printf("FindResourceByName type_id=%X name='%s' resource_name='%s'\n", 
 				typeinfo.type_id, name, resource_name);
 #endif
 		if (strcasecmp(name, resource_name) == 0)
@@ -281,7 +280,7 @@
 	}
 	else {
 	    lseek(ResourceFd, (typeinfo.count * sizeof(nameinfo)), SEEK_CUR);
-	}
+	    }
     }
     return -1;
 }
@@ -681,9 +680,6 @@
     printf("LoadBitmap: instance = %04x, name = %08x\n",
 	   instance, bmp_name);
 #endif
-    printf("LoadBitmap: instance = %04x, name = %08x\n",
-	   instance, bmp_name);
-    
     if (instance == (HANDLE)NULL)  instance = hSysRes;
     if (!(hdc = GetDC(GetDesktopWindow()))) return 0;
 
@@ -706,7 +702,6 @@
     else if (*lp == sizeof(BITMAPINFOHEADER))
 	hbitmap = ConvertInfoBitmap( hdc, (BITMAPINFO *) lp );
     else hbitmap = 0;
-printf("LoadBitmap %04X\n", hbitmap);
     GlobalFree(rsc_mem);
     ReleaseDC( 0, hdc );
     return hbitmap;
diff --git a/loader/wine.c b/loader/wine.c
index 60b606b..48c5e2b 100644
--- a/loader/wine.c
+++ b/loader/wine.c
@@ -21,6 +21,9 @@
 #include "dlls.h"
 #include "wine.h"
 #include "windows.h"
+#include "wineopts.h"
+
+/* #define DEBUG_FIXUP */
 
 extern int CallToInit16(unsigned long csip, unsigned long sssp, 
 			unsigned short ds);
@@ -46,6 +49,8 @@
 static char *Extensions[] = { "dll", "exe", NULL };
 static char *WinePath = NULL;
 
+FILE *SpyFp = NULL;
+
 /**********************************************************************
  *					DebugPrintString
  */
@@ -110,6 +115,19 @@
     unsigned int status;
     char buffer[256];
 
+    /*
+     * search file
+     */
+    if (FindFile(buffer, sizeof(buffer), modulename, Extensions, WindowsPath)
+    	==NULL)
+    {
+	
+
+    	fprintf(stderr,"LoadImage: I can't find %s !\n",modulename);
+	return (HINSTANCE) NULL;
+    }
+    fprintf(stderr,"LoadImage: loading %s (%s)\n", modulename, buffer);
+
     /* First allocate a spot to store the info we collect, and add it to
      * our linked list.
      */
@@ -125,20 +143,6 @@
     wpnt->next = NULL;
 
     /*
-     * search file
-     */
-
-    if (FindFile(buffer, sizeof(buffer), modulename, Extensions, WindowsPath)
-    	==NULL)
-    {
-    	char temp[256];
-    	
-    	sprintf(temp,"LoadImage: I can't find %s !\n",modulename);
-    	myerror(temp);
-    }
-	fprintf(stderr,"LoadImage: loading %s (%s)\n", modulename, buffer);
-
-    /*
      * Open file for reading.
      */
     wpnt->fd = open(buffer, O_RDONLY);
@@ -251,6 +255,31 @@
 return(wpnt->hinstance);
 }
 
+/**********************************************************************
+ *					ParseArgs
+ */
+void
+ParseArgs(int argc, char **argv)
+{
+    if (argc < 2)
+    {
+	fprintf(stderr, "usage: %s [-spy FILENAME] FILENAME\n", argv[0]);
+	exit(1);
+    }
+
+    Argc = argc - 1;
+    
+    for (Argv = argv + 1; **Argv == '-' && Argc > 0; Argv++)
+    {
+	if (strcmp(*Argv, "-spy") == 0)
+	{
+	    if (strcmp(*(++Argv), "-") == 0)
+		SpyFp = stdout;
+	    else
+		SpyFp = fopen(*Argv, "a");
+	}
+    }
+}
 
 /**********************************************************************
  *					main
@@ -260,6 +289,7 @@
 	int segment;
 	char *p;
 	char *sysresname;
+	char filename[100];
 	char syspath[256];
 	char exe_path[256];
 #ifdef WINESTAT
@@ -269,15 +299,8 @@
 	int cs_reg, ds_reg, ss_reg, ip_reg, sp_reg;
 	int i;
 	int rv;
-	
-	Argc = argc - 1;
-	Argv = argv + 1;
-	
-	if (argc < 2)
-	{
-		fprintf(stderr, "usage: %s FILENAME\n", argv[0]);
-		exit(1);
-	}
+
+	ParseArgs(argc, argv);
 
 	p = getenv("WINEPATH");
 	WinePath = malloc(256 + strlen(p));
@@ -285,27 +308,17 @@
 	strcat(WinePath, ";");
 	strcat(WinePath, p);
 
-	LoadImage(argv[1]);
-	hSysRes = LoadImage("sysres.dll");
+	LoadImage(Argv[0]);
+
+	GetPrivateProfileString("wine", "SystemResources", "sysres.dll", 
+				filename, sizeof(filename),
+				WINE_INI);
+	hSysRes = LoadImage(filename);
 	if (hSysRes == (HINSTANCE)NULL)
  	    printf("Error Loading System Resources !!!\n");
  	else
  	    printf("System Resources Loaded // hSysRes='%04X'\n", hSysRes);
 	
-	if(ran_out) exit(1);
-#ifdef DEBUG
-	{
-	    int dummy1, dummy2;
-
-	    GetEntryDLLName("USER", "INITAPP", &dummy1, &dummy2);
-	}
-	for(i=0; i<1024; i++) {
-		int j;
-		j = GetEntryPointFromOrdinal(wine_files, i);
-		if(j == 0)  break;
-		fprintf(stderr," %d %x\n", i,  j);
-	};
-#endif
     /*
      * Fixup references.
      */
@@ -442,8 +455,10 @@
     seg = &seg_table[segment_num];
     sel = &selector_table[segment_num];
 
-    fprintf(stderr, "Segment fixups for %s, segment %d, selector %x\n", 
-	    wpnt->name, segment_num, (int) sel->base_addr >> 16);
+#ifdef DEBUG_FIXUP
+    printf("Segment fixups for %s, segment %d, selector %x\n", 
+	   wpnt->name, segment_num, (int) sel->base_addr >> 16);
+#endif
 
     if ((seg->seg_data_offset == 0) ||
 	!(seg->seg_flags & NE_SEGFLAGS_RELOC_DATA))
@@ -589,13 +604,6 @@
 		    rep->target1, rep->target2);
 	    free(rep1);
 	    return -1;
-#if 0
-	    sp = (unsigned short *) ((char *) sel->base_addr + rep->offset);
-	    fprintf(stderr, "  FIXUP ADDRESS %04.4x:%04.4x\n",
-		    (int) sel->base_addr >> 16, rep->offset);
-	    WineForceFail = 1;
-	    continue;
-#endif
 	}
 
 	/*
@@ -619,6 +627,10 @@
 	{
 	  case NE_RADDR_OFFSET16:
 	    do {
+#ifdef DEBUG_FIXUP
+		printf("    %04.4x:%04.4x:%04.4x OFFSET16\n",
+		       (unsigned long) sp >> 16, (int) sp & 0xFFFF, *sp);
+#endif
 		next_addr = *sp;
 		*sp = (unsigned short) address;
 		if (additive == 2)
@@ -631,6 +643,10 @@
 	    
 	  case NE_RADDR_POINTER32:
 	    do {
+#ifdef DEBUG_FIXUP
+		printf("    %04.4x:%04.4x:%04.4x POINTER32\n",
+		       (unsigned long) sp >> 16, (int) sp & 0xFFFF, *sp);
+#endif
 		next_addr = *sp;
 		*sp     = (unsigned short) address;
 		if (additive == 2)
@@ -644,11 +660,15 @@
 	    
 	  case NE_RADDR_SELECTOR:
 	    do {
+#ifdef DEBUG_FIXUP
+		printf("    %04.4x:%04.4x:%04.4x SELECTOR\n",
+		       (unsigned long) sp >> 16, (int) sp & 0xFFFF, *sp);
+#endif
 		next_addr = *sp;
 		*sp     = (unsigned short) selector;
 		sp = (unsigned short *) ((char *) sel->base_addr + next_addr);
-		if (rep->relocation_type == NE_RELTYPE_INT1) break;
-
+		if (rep->relocation_type == NE_RELTYPE_INT1) 
+		    break;
 	    } 
 	    while (next_addr != 0xffff && !additive);
 
diff --git a/memory/atom.c b/memory/atom.c
index 1fd5f48..ad0345e 100644
--- a/memory/atom.c
+++ b/memory/atom.c
@@ -24,6 +24,7 @@
  * integer atoms, use the "#1234" form.
  */
 
+#include <ctype.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -90,7 +91,7 @@
 {
     WORD i, hash = 0;
 
-    for (i = 0; i < len; i++) hash ^= str[i] + i;
+    for (i = 0; i < len; i++) hash ^= toupper(str[i]) + i;
     return hash % entries;
 }
 
diff --git a/misc/Makefile b/misc/Makefile
index 8cdcee9..6fa5c19 100644
--- a/misc/Makefile
+++ b/misc/Makefile
@@ -2,7 +2,7 @@
 
 OBJS=kernel.o user.o xt.o rect.o file.o sound.o emulate.o \
      keyboard.o profile.o lstr.o exec.o message.o int1a.o int21.o \
-     dos_fs.o comm.o
+     dos_fs.o comm.o spy.o
 
 default: misc.o
 
diff --git a/misc/dos_fs.c b/misc/dos_fs.c
index e072274..57aed8d 100644
--- a/misc/dos_fs.c
+++ b/misc/dos_fs.c
@@ -661,7 +661,7 @@
 
 char *WinIniFileName()
 {
-	char name[256];
+	static char name[256];
 	
 	strcpy(name,GetDirectUnixFileName(WindowsDirectory));	
 	strcat(name,"win.ini");
diff --git a/misc/lstr.c b/misc/lstr.c
index 77e178c..bd30f88 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -52,7 +52,7 @@
 /* KERNEL.90 */
 int lstrlen(LPCSTR str)
 {
-  strlen(str);
+  return strlen(str);
 }
 
 /* AnsiUpper USER.431 */
diff --git a/misc/profile.c b/misc/profile.c
index 12d12fe..f150c9c 100644
--- a/misc/profile.c
+++ b/misc/profile.c
@@ -125,7 +125,7 @@
 	    if (c == ' ' || c == '\t')
 		break;
 	    
-	    if (c == '\n' || overflow) /* Abort Definition */
+	    if (c == '\n' || c == ';' || overflow) /* Abort Definition */
 		next = CharBuffer;
 	    
 	    if (c == '=' || overflow){
diff --git a/misc/rect.c b/misc/rect.c
index 4fd7be4..6adc0a5 100644
--- a/misc/rect.c
+++ b/misc/rect.c
@@ -152,8 +152,12 @@
     *dest = *src1;
     if (IntersectRect( &tmp, src1, src2 ))
     {
-	if (EqualRect( &tmp, dest )) SetRectEmpty( src1 );
-	else if ((tmp.top == dest->top) && (tmp.bottom == dest->bottom))
+	if (EqualRect( &tmp, dest ))
+	{
+	    SetRectEmpty( dest );
+	    return FALSE;
+	}
+	if ((tmp.top == dest->top) && (tmp.bottom == dest->bottom))
 	{
 	    if (tmp.left == dest->left) dest->right = tmp.right;
 	    else if (tmp.right == dest->right) dest->left = tmp.left;
diff --git a/misc/spy.c b/misc/spy.c
new file mode 100644
index 0000000..d45ebb2
--- /dev/null
+++ b/misc/spy.c
@@ -0,0 +1,257 @@
+/* SPY.C
+ *
+ * Copyright 1994, Bob Amstadt
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "wineopts.h"
+#include "windows.h"
+#include "wine.h"
+
+#ifndef NOSPY
+
+#define SPY_MAX_MSGNUM		0x0210
+
+const char *MessageTypeNames[SPY_MAX_MSGNUM + 1] =
+{
+    "WM_NULL",			/* 0x00 */
+    "WM_CREATE",	
+    "WM_DESTROY",    
+    "WM_MOVE",
+    "WM_UNUSED0",
+    "WM_SIZE",
+    "WM_ACTIVATE",
+    "WM_SETFOCUS",
+    "WM_KILLFOCUS",
+    "WM_UNUSED1",
+    "WM_ENABLE",
+    "WM_SETREDRAW",
+    "WM_SETTEXT",
+    "WM_GETTEXT",
+    "WM_GETTEXTLENGTH",
+    "WM_PAINT",
+    "WM_CLOSE",			/* 0x10 */
+    "WM_QUERYENDSESSION",
+    "WM_QUIT",
+    "WM_QUERYOPEN",
+    "WM_ERASEBKGND",
+    "WM_SYSCOLORCHANGE",
+    "WM_ENDSESSION",
+    "WM_UNUSED2",
+    "WM_SHOWWINDOW",
+    "WM_CTLCOLOR",
+    "WM_WININICHANGE",
+    "WM_DEVMODECHANGE",
+    "WM_ACTIVATEAPP",
+    "WM_FONTCHANGE",
+    "WM_TIMECHANGE",
+    "WM_CANCELMODE",
+    "WM_SETCURSOR",		/* 0x20 */
+    "WM_MOUSEACTIVATE",
+    "WM_CHILDACTIVATE",
+    "WM_QUEUESYNC",
+    "WM_GETMINMAXINFO",
+    "WM_UNUSED3",
+    "WM_PAINTICON",
+    "WM_ICONERASEBKGND",
+    "WM_NEXTDLGCTL",
+    "WM_UNUSED4",
+    "WM_SPOOLERSTATUS",
+    "WM_DRAWITEM",
+    "WM_MEASUREITEM",
+    "WM_DELETEITEM",
+    "WM_VKEYTOITEM",
+    "WM_CHARTOITEM",
+    "WM_SETFONT",		/* 0x30 */
+    "WM_GETFONT", NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    /* 0x40 */
+    NULL, NULL, NULL, NULL, NULL, NULL,
+    "WM_WINDOWPOSCHANGING",	/* 0x0046 */
+    "WM_WINDOWPOSCHANGED",	/* 0x0047 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    /* 0x0050 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    /* 0x0060 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    /* 0x0070 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    NULL,			/* 0x0080 */
+    "WM_NCCREATE",		/* 0x0081 */
+    "WM_NCDESTROY",		/* 0x0082 */
+    "WM_NCCALCSIZE",		/* 0x0083 */
+    NULL, NULL, NULL,
+    "WM_GETDLGCODE",		/* 0x0087 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    /* 0x0090 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    /* 0x00A0 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    /* 0x00B0 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    /* 0x00C0 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    /* 0x00D0 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    /* 0x00E0 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    /* 0x00F0 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    "WM_KEYDOWN",		/* 0x0100 */
+    "WM_KEYUP",			/* 0x0101 */
+    "WM_CHAR",			/* 0x0102 */
+    "WM_DEADCHAR",		/* 0x0103 */
+    "WM_SYSKEYDOWN",		/* 0x0104 */
+    "WM_SYSKEYUP",		/* 0x0105 */
+    "WM_SYSCHAR",		/* 0x0106 */
+    "WM_SYSDEADCHAR",		/* 0x0107 */
+    "WM_KEYLAST",		/* 0x0108 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    "WM_INITDIALOG",		/* 0x0110  */
+    "WM_COMMAND",		/* 0x0111 */
+    NULL,
+    "WM_TIMER",			/* 0x0113 */
+    "WM_HSCROLL",		/* 0x0114 */
+    "WM_VSCROLL",		/* 0x0115 */
+    NULL, NULL,
+    "WM_SYSTIMER",		/* 0x0118 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    /* 0x0120 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    /* 0x0130 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    /* 0x0140 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    /* 0x0150 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    /* 0x0160 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    /* 0x0170 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    /* 0x0180 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    /* 0x0190 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    /* 0x01A0 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    /* 0x01B0 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    /* 0x01C0 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    /* 0x01D0 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    /* 0x01E0 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    /* 0x01F0 */
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+    "WM_MOUSEMOVE",		/* 0x0200 */
+    "WM_LBUTTONDOWN",		/* 0x0201 */
+    "WM_LBUTTONUP",		/* 0x0202 */
+    "WM_LBUTTONDBLCLK",		/* 0x0203 */
+    "WM_RBUTTONDOWN",		/* 0x0204 */
+    "WM_RBUTTONUP",		/* 0x0205 */
+    "WM_RBUTTONDBLCLK",		/* 0x0206 */
+    "WM_MBUTTONDOWN",		/* 0x0207 */
+    "WM_MBUTTONUP",		/* 0x0208 */
+    "WM_MBUTTONDBLCLK",		/* 0x0209 */
+    "WM_PARENTNOTIFY",		/* 0x0210 */
+};
+
+#endif /* NOSPY */
+
+/**********************************************************************
+ *					SpyMessage
+ */
+void SpyMessage(HWND hwnd, WORD msg, WORD wParam, LONG lParam)
+{
+#ifndef NOSPY
+    if (SpyFp == NULL)
+	return;
+    
+    if (msg > SPY_MAX_MSGNUM || MessageTypeNames[msg] == NULL)
+    {
+	fprintf(SpyFp, "%04.4x                  %04.4x  %04.4x  %08.8x\n",
+		hwnd, msg, wParam, lParam);
+    }
+    else
+    {
+	fprintf(SpyFp, "%04.4x  %20.20s  %04.4x  %08.8x\n",
+		hwnd, MessageTypeNames[msg], wParam, lParam);
+    }
+#endif
+}
+
+/**********************************************************************
+ *					SpyInit
+ */
+void SpyInit(void)
+{
+    char filename[100];
+
+    if (SpyFp == NULL)
+	return;
+    
+    GetPrivateProfileString("spy", "file", "", filename, sizeof(filename),
+			    WINE_INI);
+
+    if (strcasecmp(filename, "CON") == 0)
+	SpyFp = stdout;
+    else if (strlen(filename))
+	SpyFp = fopen(filename, "a");
+    else
+	SpyFp = NULL;
+}
diff --git a/misc/user.c b/misc/user.c
index 501448c..d8e0596 100644
--- a/misc/user.c
+++ b/misc/user.c
@@ -16,6 +16,7 @@
 
 extern BOOL ATOM_Init();
 extern BOOL GDI_Init();
+extern void SYSMETRICS_Init();
 
 /***********************************************************************
  *           USER_HeapInit
@@ -40,13 +41,16 @@
 {
     int queueSize;
 
+    SpyInit();
+
       /* Global atom table initialisation */
     if (!ATOM_Init()) return 0;
     
       /* GDI initialisation */
     if (!GDI_Init()) return 0;
 
-      /* Initialize system colors */
+      /* Initialize system colors and metrics*/
+    SYSMETRICS_Init();
     SYSCOLOR_Init();
     
       /* Create USER heap */
diff --git a/misc/xt.c b/misc/xt.c
index a829a5b..4458521 100644
--- a/misc/xt.c
+++ b/misc/xt.c
@@ -22,6 +22,8 @@
 
 Display * XT_display;
 Screen * XT_screen;
+Display * display;
+Screen * screen;
 XtAppContext XT_app_context;
 
 static Widget topLevelWidget;
@@ -40,6 +42,8 @@
 				       NULL );
     XT_display = XtDisplay( topLevelWidget );
     XT_screen  = XtScreen( topLevelWidget );
+    display = XtDisplay( topLevelWidget );
+    screen  = XtScreen( topLevelWidget );
     
     DOS_InitFS();
     Comm_Init();
@@ -68,32 +72,3 @@
     struct tms dummy;
     return (times(&dummy) * 1000) / HZ;
 }
-
-
-int GetSystemMetrics( short index )
-{
-    printf( "GetSystemMetrics: %d\n", index );
-    switch(index)
-    {
-      case SM_CXSCREEN:
-	return DisplayWidth( XT_display, DefaultScreen( XT_display ));
-
-      case SM_CYSCREEN:
-	return DisplayHeight( XT_display, DefaultScreen( XT_display ));
-
-      default:
-	  return 0;
-    }
-}
-
-void AdjustWindowRect( LPRECT rect, DWORD style, BOOL menu )
-{
-    printf( "AdjustWindowRect: (%d,%d)-(%d,%d) %d %d\n", rect->left, rect->top,
-	   rect->right, rect->bottom, style, menu );
-#ifdef USE_XLIB
-    rect->right += 8;
-    rect->bottom += 34;
-#endif
-}
-
-
diff --git a/objects/brush.c b/objects/brush.c
index 11a430b..582349e 100644
--- a/objects/brush.c
+++ b/objects/brush.c
@@ -8,8 +8,6 @@
 
 #include "gdi.h"
 
-extern Display * XT_display;
-extern Screen * XT_screen;
 
 #define NB_HATCH_STYLES  6
 
diff --git a/objects/clipping.c b/objects/clipping.c
index 5776eb8..7504b12 100644
--- a/objects/clipping.c
+++ b/objects/clipping.c
@@ -20,15 +20,22 @@
     if (dc->w.hGCClipRgn)
     {
 	RGNOBJ *obj = (RGNOBJ *) GDI_GetObjPtr(dc->w.hGCClipRgn, REGION_MAGIC);
-	XSetClipMask( XT_display, dc->u.x.gc, obj->region.pixmap );
-	XSetClipOrigin( XT_display, dc->u.x.gc,
-		        dc->w.DCOrgX + obj->region.box.left,
-		        dc->w.DCOrgY + obj->region.box.top );
+	if (obj->region.pixmap)
+	{
+	    XSetClipMask( display, dc->u.x.gc, obj->region.pixmap );
+	    XSetClipOrigin( display, dc->u.x.gc,
+			    dc->w.DCOrgX + obj->region.box.left,
+			    dc->w.DCOrgY + obj->region.box.top );
+	}
+	else  /* Clip everything */
+	{
+	    XSetClipRectangles( display, dc->u.x.gc, 0, 0, NULL, 0, 0 );
+	}
     }
     else
     {
-	XSetClipMask( XT_display, dc->u.x.gc, None );
-	XSetClipOrigin( XT_display, dc->u.x.gc, dc->w.DCOrgX, dc->w.DCOrgY );
+	XSetClipMask( display, dc->u.x.gc, None );
+	XSetClipOrigin( display, dc->u.x.gc, dc->w.DCOrgX, dc->w.DCOrgY );
     }
 }
 
diff --git a/objects/dib.c b/objects/dib.c
index 735e449..15e3d09 100644
--- a/objects/dib.c
+++ b/objects/dib.c
@@ -44,7 +44,7 @@
     XImage * image;
     int bytesPerLine = (bmp->biWidth * bmp->biBitCount + 31) / 32 * 4;
     
-    image = XCreateImage( XT_display, DefaultVisualOfScreen( XT_screen ),
+    image = XCreateImage( display, DefaultVisualOfScreen( screen ),
 			  bmp->biBitCount, ZPixmap, 0, bmpData,
 			  bmp->biWidth, bmp->biHeight, 32, bytesPerLine );
     if (!image) return 0;
diff --git a/objects/font.c b/objects/font.c
index 10bc76b..8345e0b 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -11,9 +11,6 @@
 #include <X11/Xatom.h>
 #include "gdi.h"
 
-extern Display * XT_display;
-extern Screen * XT_screen;
-
 
 /***********************************************************************
  *           FONT_MatchFont
diff --git a/objects/gdiobj.c b/objects/gdiobj.c
index cc539a4..1b98fc8 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -8,8 +8,6 @@
 
 #include "gdi.h"
 
-extern Display * XT_display;
-extern Screen * XT_screen;
 
 MDESC *GDI_Heap = NULL;
 
diff --git a/objects/linedda.c b/objects/linedda.c
index 6d8a1cfe..e61290d 100644
--- a/objects/linedda.c
+++ b/objects/linedda.c
@@ -7,7 +7,7 @@
 static char Copyright[] = "Copyright  Bob Amstadt, 1993";
 
 #include <stdlib.h>
-#include "win.h"
+#include "windows.h"
 
 /**********************************************************************
  *		LineDDA		(GDI.100)
diff --git a/objects/palette.c b/objects/palette.c
index 511cf3f..f107a61 100644
--- a/objects/palette.c
+++ b/objects/palette.c
@@ -18,9 +18,6 @@
 
 #include "gdi.h"
 
-extern Display * XT_display;
-extern Screen * XT_screen;
-
 extern Colormap COLOR_WinColormap;
 
 GDIOBJHDR * PALETTE_systemPalette;
@@ -36,7 +33,7 @@
     HPALETTE hpalette;
     LOGPALETTE * palPtr;
 
-    size = DefaultVisual( XT_display, DefaultScreen(XT_display) )->map_entries;
+    size = DefaultVisual( display, DefaultScreen(display) )->map_entries;
     palPtr = malloc( sizeof(LOGPALETTE) + (size-1)*sizeof(PALETTEENTRY) );
     if (!palPtr) return FALSE;
     palPtr->palVersion = 0x300;
@@ -46,7 +43,7 @@
     for (i = 0; i < size; i++)
     {
 	color.pixel = i;
-	XQueryColor( XT_display, COLOR_WinColormap, &color );
+	XQueryColor( display, COLOR_WinColormap, &color );
 	palPtr->palPalEntry[i].peRed   = color.red >> 8;
 	palPtr->palPalEntry[i].peGreen = color.green >> 8;
 	palPtr->palPalEntry[i].peBlue  = color.blue >> 8;
@@ -132,7 +129,7 @@
     palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
     if (!palPtr) return 0;
 
-    if ((COLOR_WinColormap != DefaultColormapOfScreen(XT_screen)) &&
+    if ((COLOR_WinColormap != DefaultColormapOfScreen(screen)) &&
 	(hpalette == STOCK_DEFAULT_PALETTE))
     {
 	if ((color & 0xffffff) == 0) return 0;  /* Entry 0 is black */
diff --git a/objects/pen.c b/objects/pen.c
index fa49ef3..a0a7ad7 100644
--- a/objects/pen.c
+++ b/objects/pen.c
@@ -8,9 +8,6 @@
 
 #include "gdi.h"
 
-extern Display * XT_display;
-extern Screen * XT_screen;
-
 
 /***********************************************************************
  *           CreatePen    (GDI.61)
diff --git a/objects/text.c b/objects/text.c
index 07aef58..787b0f7 100644
--- a/objects/text.c
+++ b/objects/text.c
@@ -6,15 +6,8 @@
 
 static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
 
-#include <X11/Intrinsic.h>
-#include <X11/StringDefs.h>
-#include <X11/Core.h>
-#include <X11/Shell.h>
 #include <X11/Xatom.h>
 
-#include "message.h"
-#include "callback.h"
-#include "win.h"
 #include "gdi.h"
 
 #define TAB     9
@@ -224,8 +217,8 @@
 
 	if (flags & DT_SINGLELINE)
 	{
-	    if (flags & DT_VCENTER) y = (rect->top + rect->bottom - 
-					 size.cy) / 2;
+	    if (flags & DT_VCENTER) y = rect->top + 
+	    	(rect->bottom - rect->top) / 2 - size.cy / 2;
 	    else if (flags & DT_BOTTOM) y = rect->bottom - size.cy;
 	}
 
diff --git a/sysres.dll b/sysres.dll
index 38c7ca9..0a61ba9 100755
--- a/sysres.dll
+++ b/sysres.dll
Binary files differ
diff --git a/test/widget.exe b/test/widget.exe
index ea5dc2f..95413e0 100755
--- a/test/widget.exe
+++ b/test/widget.exe
Binary files differ
diff --git a/windows/Makefile b/windows/Makefile
index 30570a1..8ac8efa 100644
--- a/windows/Makefile
+++ b/windows/Makefile
@@ -2,7 +2,8 @@
 
 OBJS=class.o dc.o dce.o event.o message.o win.o timer.o graphics.o \
     	clipping.o mapping.o painting.o keyboard.o utility.o syscolor.o \
-	defwnd.o defdlg.o dialog.o focus.o scroll.o caret.o winpos.o
+	defwnd.o defdlg.o dialog.o focus.o scroll.o caret.o winpos.o \
+	sysmetrics.o nonclient.o
 
 default: windows.o
 
diff --git a/windows/caret.c b/windows/caret.c
index eb78dc8..566e321 100644
--- a/windows/caret.c
+++ b/windows/caret.c
@@ -6,12 +6,8 @@
 
 static char Copyright[] = "Copyright  David Metcalfe, 1993";
 
-#include <X11/Intrinsic.h>
-
 #include "windows.h"
 
-extern XtAppContext XT_app_context;
-
 typedef struct
 {
     HWND          hwnd;
@@ -23,49 +19,46 @@
     short         height;
     COLORREF      color;
     WORD          timeout;
-    XtIntervalId  xtid;
+    WORD          timerid;
 } CARET;
 
 static CARET Caret;
 static BOOL LockCaret;
 
-static void CARET_Callback(XtPointer data, XtIntervalId *xtid);
-static void CARET_HideCaret(CARET *pCaret);
+static WORD CARET_Callback(HWND hwnd, WORD msg, WORD timerid, LONG ctime);
+static void CARET_HideCaret();
 
 
 /*****************************************************************
  *               CARET_Callback
  */
 
-static void CARET_Callback(XtPointer data, XtIntervalId *xtid)
+static WORD CARET_Callback(HWND hwnd, WORD msg, WORD timerid, LONG ctime)
 {
-    CARET *pCaret = (CARET *)data;
     HDC hdc;
     HBRUSH hBrush;
     HRGN rgn;
 
 #ifdef DEBUG_CARET
-    printf("CARET_Callback: LockCaret=%d, hidden=%d, on=%d\n",
-	   LockCaret, pCaret->hidden, pCaret->on);
+    printf("CARET_Callback: id=%d: LockCaret=%d, hidden=%d, on=%d\n",
+	   timerid, LockCaret, Caret.hidden, Caret.on);
 #endif
-    if (!LockCaret && (!pCaret->hidden || pCaret->on))
+    if (!LockCaret && (!Caret.hidden || Caret.on))
     {
-	pCaret->on = (pCaret->on ? FALSE : TRUE);
-	hdc = GetDC(pCaret->hwnd);
-	hBrush = CreateSolidBrush(pCaret->color);
+	Caret.on = (Caret.on ? FALSE : TRUE);
+	hdc = GetDC(Caret.hwnd);
+	hBrush = CreateSolidBrush(Caret.color);
 	SelectObject(hdc, (HANDLE)hBrush);
 	SetROP2(hdc, R2_XORPEN);
-	rgn = CreateRectRgn(pCaret->x, pCaret->y, 
-			    pCaret->x + pCaret->width,
-			    pCaret->y + pCaret->height);
+	rgn = CreateRectRgn(Caret.x, Caret.y, 
+			    Caret.x + Caret.width,
+			    Caret.y + Caret.height);
 	FillRgn(hdc, rgn, hBrush);
 	DeleteObject((HANDLE)rgn);
 	DeleteObject((HANDLE)hBrush);
-	ReleaseDC(pCaret->hwnd, hdc);
+	ReleaseDC(Caret.hwnd, hdc);
     }
-
-    pCaret->xtid = XtAppAddTimeOut(XT_app_context, pCaret->timeout,
-				   CARET_Callback, pCaret);
+    return 0;
 }
 
 
@@ -73,24 +66,24 @@
  *               CARET_HideCaret
  */
 
-static void CARET_HideCaret(CARET *pCaret)
+static void CARET_HideCaret()
 {
     HDC hdc;
     HBRUSH hBrush;
     HRGN rgn;
 
-    pCaret->on = FALSE;
-    hdc = GetDC(pCaret->hwnd);
-    hBrush = CreateSolidBrush(pCaret->color);
+    Caret.on = FALSE;
+    hdc = GetDC(Caret.hwnd);
+    hBrush = CreateSolidBrush(Caret.color);
     SelectObject(hdc, (HANDLE)hBrush);
     SetROP2(hdc, R2_XORPEN);
-    rgn = CreateRectRgn(pCaret->x, pCaret->y, 
-			pCaret->x + pCaret->width,
-			pCaret->y + pCaret->height);
+    rgn = CreateRectRgn(Caret.x, Caret.y, 
+			Caret.x + Caret.width,
+			Caret.y + Caret.height);
     FillRgn(hdc, rgn, hBrush);
     DeleteObject((HANDLE)rgn);
     DeleteObject((HANDLE)hBrush);
-    ReleaseDC(pCaret->hwnd, hdc);
+    ReleaseDC(Caret.hwnd, hdc);
 }
 
 
@@ -102,6 +95,7 @@
 {
     if (!hwnd) return;
 
+
     /* if cursor already exists, destroy it */
 /*    if (Caret.hwnd)
 	DestroyCaret();
@@ -131,8 +125,11 @@
     Caret.timeout = 750;
     LockCaret = FALSE;
 
-    Caret.xtid = XtAppAddTimeOut(XT_app_context, Caret.timeout,
-				 CARET_Callback, &Caret);
+    Caret.timerid = SetSystemTimer(NULL, 0, Caret.timeout, CARET_Callback);
+
+#ifdef DEBUG_CARET
+    printf("CreateCaret: hwnd=%d, timerid=%d\n", hwnd, Caret.timerid);
+#endif
 }
    
 
@@ -144,10 +141,14 @@
 {
 /*    if (!Caret.hwnd) return;
 */
-    XtRemoveTimeOut(Caret.xtid);
+#ifdef DEBUG_CARET
+    printf("DestroyCaret: timerid\n", Caret.timerid);
+#endif
+
+    KillSystemTimer(NULL, Caret.timerid);
 
     if (Caret.on)
-	CARET_HideCaret(&Caret);
+	CARET_HideCaret();
 
     Caret.hwnd = 0;          /* cursor marked as not existing */
 }
@@ -171,7 +172,7 @@
 
     LockCaret = TRUE;
     if (Caret.on)
-	CARET_HideCaret(&Caret);
+	CARET_HideCaret();
 
     Caret.x = x;
     Caret.y = y;
@@ -189,7 +190,7 @@
 
     LockCaret = TRUE;
     if (Caret.on)
-	CARET_HideCaret(&Caret);
+	CARET_HideCaret();
 
     ++Caret.hidden;
     LockCaret = FALSE;
@@ -221,7 +222,9 @@
 {
     if (!Caret.hwnd) return;
 
+    KillSystemTimer(NULL, Caret.timerid);
     Caret.timeout = msecs;
+    Caret.timerid = SetSystemTimer(NULL, 0, Caret.timeout, CARET_Callback);
 }
 
 
diff --git a/windows/dce.c b/windows/dce.c
index 7b24f1d..5aef283 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -15,8 +15,7 @@
 
 #define NB_DCE    5  /* Number of DCEs created at startup */
 
-extern Display * XT_display;
-extern Screen * XT_screen;
+extern Display * display;
 
 static HANDLE firstDCE = 0;
 static HDC defaultDCstate = 0;
@@ -159,11 +158,11 @@
 	    IntersectVisRect( hdc, 0, 0, dc->w.DCSizeX, dc->w.DCSizeY );
 	}	
     }
-    else dc->u.x.drawable = DefaultRootWindow( XT_display );
+    else dc->u.x.drawable = DefaultRootWindow( display );
 
     if (flags & DCX_CLIPCHILDREN)
-	XSetSubwindowMode( XT_display, dc->u.x.gc, ClipByChildren );
-    else XSetSubwindowMode( XT_display, dc->u.x.gc, IncludeInferiors);
+	XSetSubwindowMode( display, dc->u.x.gc, ClipByChildren );
+    else XSetSubwindowMode( display, dc->u.x.gc, IncludeInferiors);
 
     if ((flags & DCX_INTERSECTRGN) || (flags & DCX_EXCLUDERGN))
     {
@@ -216,7 +215,7 @@
 int ReleaseDC( HWND hwnd, HDC hdc )
 {
     HANDLE hdce;
-    DCE * dce;
+    DCE * dce = NULL;
     
 #ifdef DEBUG_DC
     printf( "ReleaseDC: %d %d\n", hwnd, hdc );
@@ -227,11 +226,12 @@
 	if (!(dce = (DCE *) USER_HEAP_ADDR( hdce ))) return 0;
 	if (dce->inUse && (dce->hdc == hdc)) break;
     }
+    if (!hdce) return 0;
 
     if (dce->type == DCE_CACHE_DC)
     {
 	SetDCState( dce->hdc, defaultDCstate );
 	dce->inUse = FALSE;
     }
-    return (hdce != 0);
+    return 1;
 }
diff --git a/windows/defwnd.c b/windows/defwnd.c
index e2f9a39..dc75bc1 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -6,17 +6,19 @@
 
 static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
 
-#ifndef USE_XLIB
-#include <X11/Intrinsic.h>
-#include <X11/Shell.h>
-#endif
 
 #include "windows.h"
 #include "win.h"
 #include "class.h"
 #include "user.h"
 
-extern Display * XT_display;
+extern Display * display;
+
+extern LONG NC_HandleNCPaint( HWND hwnd, HRGN hrgn );
+extern LONG NC_HandleNCCalcSize( HWND hwnd, NCCALCSIZE_PARAMS *params );
+extern LONG NC_HandleNCHitTest( HWND hwnd, POINT pt );
+extern LONG NC_HandleNCMouseMsg(HWND hwnd, WORD msg, WORD wParam, LONG lParam);
+
 
 /***********************************************************************
  *           DefWindowProc   (USER.107)
@@ -26,6 +28,7 @@
     CLASS * classPtr;
     LPSTR textPtr;
     int len;
+    int tempwidth, tempheight;
     WND * wndPtr = WIN_FindWndPtr( hwnd );
     
 #ifdef DEBUG_MESSAGE
@@ -51,40 +54,19 @@
 	}
 
     case WM_NCCALCSIZE:
-	{
-#ifdef USE_XLIB
-	    NCCALCSIZE_PARAMS *params = (NCCALCSIZE_PARAMS *)lParam;
-	    if (wndPtr->dwStyle & WS_CHILD)
-	    {
-		if (wndPtr->dwStyle & WS_BORDER)
-		{
-		    params->rgrc[0].left   += 1; /* SM_CXBORDER */
-		    params->rgrc[0].top    += 1; /* SM_CYBORDER */
-		    params->rgrc[0].right  -= 1; /* SM_CXBORDER */
-		    params->rgrc[0].bottom -= 1; /* SM_CYBORDER */
-		}
-	    }
-	    else
-	    {
-		params->rgrc[0].left   += 4; /* SM_CXFRAME */
-		params->rgrc[0].top    += 30; /* SM_CYFRAME+SM_CYCAPTION */
-		params->rgrc[0].right  -= 4; /* SM_CXFRAME */
-		params->rgrc[0].bottom -= 4; /* SM_CYFRAME */
-		if (wndPtr->dwStyle & WS_VSCROLL)
-		{
-		    params->rgrc[0].right -= 16; /* SM_CXVSCROLL */
-		}
-		if (wndPtr->dwStyle & WS_HSCROLL)
-		{
-		    params->rgrc[0].bottom += 16;  /* SM_CYHSCROLL */
-		}
-	    }
-#endif
-	    return 0;
-	}
-	
-    case WM_CREATE:
-	return 0;
+	return NC_HandleNCCalcSize( hwnd, (NCCALCSIZE_PARAMS *)lParam );
+
+    case WM_NCPAINT:
+	return NC_HandleNCPaint( hwnd, (HRGN)wParam );
+
+    case WM_NCHITTEST:
+	return NC_HandleNCHitTest( hwnd, MAKEPOINT(lParam) );
+
+    case WM_NCLBUTTONDOWN:
+    case WM_NCLBUTTONUP:
+    case WM_NCLBUTTONDBLCLK:
+    case WM_NCMOUSEMOVE:
+	return NC_HandleNCMouseMsg( hwnd, msg, wParam, lParam );
 
     case WM_NCDESTROY:
 	{
@@ -188,18 +170,42 @@
 					    strlen((LPSTR)lParam) + 1);
 	    textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText);
 	    strcpy(textPtr, (LPSTR)lParam);
-#ifdef USE_XLIB
-	    XStoreName( XT_display, wndPtr->window, textPtr );
-#else
-	    if (wndPtr->shellWidget)
-		XtVaSetValues( wndPtr->shellWidget, XtNtitle, textPtr, NULL );
-#endif
+	    XStoreName( display, wndPtr->window, textPtr );
 	    return (0L);
 	}
     case WM_SETCURSOR:
 	if (wndPtr->hCursor != (HCURSOR)NULL)
 	    SetCursor(wndPtr->hCursor);
 	return 0L;
+    case WM_SYSCOMMAND:
+	switch (wParam)
+	    {
+	    case SC_CLOSE:
+		ShowWindow(hwnd, SW_MINIMIZE);
+		printf("defdwndproc WM_SYSCOMMAND SC_CLOSE !\n");
+	        return SendMessage( hwnd, WM_CLOSE, 0, 0 );
+	    case SC_RESTORE:
+		ShowWindow(hwnd, SW_RESTORE);
+		break;
+	    case SC_MINIMIZE:
+		ShowWindow(hwnd, SW_MINIMIZE);
+		printf("defdwndproc WM_SYSCOMMAND SC_MINIMIZE !\n");
+		break;
+	    case SC_MAXIMIZE:
+		ShowWindow(hwnd, SW_MAXIMIZE);
+		break;
+	    }
+    	break;    	
+    case WM_SYSKEYDOWN:
+    	if (wParam == VK_MENU) {
+    	    printf("VK_MENU Pressed // hMenu=%04X !\n", GetMenu(hwnd));
+    	    }
+    	break;    	
+    case WM_SYSKEYUP:
+    	if (wParam == VK_MENU) {
+    	    printf("VK_MENU Released // hMenu=%04X !\n", GetMenu(hwnd));
+    	    }
+    	break;    	
     }
     return 0;
 }
diff --git a/windows/dialog.c b/windows/dialog.c
index 83a0389..6316e34 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -184,11 +184,13 @@
     HMENU hMenu;
     HFONT hFont = 0;
     HWND hwnd;
+    RECT rect;
     WND * wndPtr;
     int i;
     DLGTEMPLATE template;
     DLGCONTROLHEADER * header;
     DIALOGINFO * dlgInfo;
+    DWORD exStyle = 0;
     WORD xUnit = xBaseUnit;
     WORD yUnit = yBaseUnit;
 
@@ -229,7 +231,7 @@
 	    HFONT oldFont;
 	    HDC hdc;
 
-	    hdc = GetDC(GetDesktopWindow());
+	    hdc = GetDC(0);
 	    oldFont = SelectObject( hdc, hFont );
 	    GetTextMetrics( hdc, &tm );
 	    SelectObject( hdc, oldFont );
@@ -241,14 +243,19 @@
     
       /* Create dialog main window */
 
-    hwnd = CreateWindow( template.className, template.caption,
-			 template.header->style,
-			 template.header->x * xUnit / 4,
-			 template.header->y * yUnit / 8,
-			 template.header->cx * xUnit / 4,
-			 template.header->cy * yUnit / 8,
-			 owner, hMenu, hInst,
-			 NULL );
+    rect.left = rect.top = 0;
+    rect.right = template.header->cx * xUnit / 4;
+    rect.bottom = template.header->cy * yUnit / 8;
+    if (template.header->style & DS_MODALFRAME) exStyle |= WS_EX_DLGMODALFRAME;
+    AdjustWindowRectEx( &rect, template.header->style, hMenu, exStyle );
+
+    hwnd = CreateWindowEx( exStyle, template.className, template.caption,
+			   template.header->style,
+			   rect.left + template.header->x * xUnit / 4,
+			   rect.top + template.header->y * yUnit / 8,
+			   rect.right - rect.left, rect.bottom - rect.top,
+			   owner, hMenu, hInst,
+			   NULL );
     if (!hwnd)
     {
 	if (hFont) DeleteObject( hFont );
diff --git a/windows/event.c b/windows/event.c
index 5f3aa3d..b2de49f 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -6,33 +6,23 @@
 
 static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
 
-#include <X11/Intrinsic.h>
-#include <X11/StringDefs.h>
-#include <X11/Core.h>
+#include <X11/Xlib.h>
 
 #include "windows.h"
 #include "win.h"
 #include "class.h"
+#include "message.h"
 
 
 #define NB_BUTTONS      3     /* Windows can handle 3 buttons */
-static WORD dblclick_time = 300; /* Max. time for a double click (milliseconds) */
 
-extern Display * XT_display;
-
-  /* Event handlers */
-static void EVENT_expose();
-static void EVENT_key();
-static void EVENT_mouse_motion();
-static void EVENT_mouse_button();
-static void EVENT_structure();
-static void EVENT_focus_change();
-static void EVENT_enter_notify();
+extern Display * display;
 
   /* X context to associate a hwnd to an X window */
 static XContext winContext = 0;
 
   /* State variables */
+static WORD ALTKeyState;
 static HWND captureWnd = 0;
 Window winHasCursor = 0;
 extern HWND hWndFocus;
@@ -118,6 +108,17 @@
 };
 #endif
 
+  /* Event handlers */
+static void EVENT_key( HWND hwnd, XKeyEvent *event );
+static void EVENT_ButtonPress( HWND hwnd, XButtonEvent *event );
+static void EVENT_ButtonRelease( HWND hwnd, XButtonEvent *event );
+static void EVENT_MotionNotify( HWND hwnd, XMotionEvent *event );
+static void EVENT_EnterNotify( HWND hwnd, XCrossingEvent *event );
+static void EVENT_FocusIn( HWND hwnd, XFocusChangeEvent *event );
+static void EVENT_FocusOut( HWND hwnd, XFocusChangeEvent *event );
+static void EVENT_Expose( HWND hwnd, XExposeEvent *event );
+static void EVENT_ConfigureNotify( HWND hwnd, XConfigureEvent *event );
+
 
 /***********************************************************************
  *           EVENT_ProcessEvent
@@ -128,117 +129,72 @@
 {
     HWND hwnd;
     XPointer ptr;
-    Boolean cont_dispatch = TRUE;
     
-    XFindContext( XT_display, ((XAnyEvent *)event)->window, winContext, &ptr );
-    hwnd = (HWND)ptr & 0xffff;
+    XFindContext( display, ((XAnyEvent *)event)->window, winContext, &ptr );
+    hwnd = (HWND) (int)ptr;
 
 #ifdef DEBUG_EVENT
-    printf( "Got event %s for hwnd %d\n", 
-	    event_names[event->type], hwnd );
+    printf( "Got event %s for hwnd %d\n", event_names[event->type], hwnd );
 #endif
 
     switch(event->type)
     {
-        case Expose:
-	    EVENT_expose( 0, hwnd, event, &cont_dispatch );
-	    break;
+    case KeyPress:
+    case KeyRelease:
+	EVENT_key( hwnd, (XKeyEvent*)event );
+	break;
+	
+    case ButtonPress:
+	EVENT_ButtonPress( hwnd, (XButtonEvent*)event );
+	break;
 
-	case KeyPress:
-	case KeyRelease:
-	    EVENT_key( 0, hwnd, event, &cont_dispatch );
-	    break;
+    case ButtonRelease:
+	EVENT_ButtonRelease( hwnd, (XButtonEvent*)event );
+	break;
 
-	case MotionNotify:
-	    EVENT_mouse_motion( 0, hwnd, event, &cont_dispatch );
-	    break;
+    case MotionNotify:
+	EVENT_MotionNotify( hwnd, (XMotionEvent*)event );
+	break;
 
-	case ButtonPress:
-	case ButtonRelease:
-	    EVENT_mouse_button( 0, hwnd, event, &cont_dispatch );
-	    break;
+    case EnterNotify:
+	EVENT_EnterNotify( hwnd, (XCrossingEvent*)event );
+	break;
 
-	case CirculateNotify:
-	case ConfigureNotify:
-	case MapNotify:
-	case UnmapNotify:
-	    EVENT_structure( 0, hwnd, event, &cont_dispatch );
-	    break;
+    case FocusIn:
+	EVENT_FocusIn( hwnd, (XFocusChangeEvent*)event );
+	break;
 
-	case FocusIn:
-	case FocusOut:
-	    EVENT_focus_change( 0, hwnd, event, &cont_dispatch );
-	    break;
+    case FocusOut:
+	EVENT_FocusOut( hwnd, (XFocusChangeEvent*)event );
+	break;
 
-	case EnterNotify:
-	    EVENT_enter_notify( 0, hwnd, event, &cont_dispatch );
-	    break;
+    case Expose:
+	EVENT_Expose( hwnd, (XExposeEvent*)event );
+	break;
+
+    case ConfigureNotify:
+	EVENT_ConfigureNotify( hwnd, (XConfigureEvent*)event );
+	break;
 
 #ifdef DEBUG_EVENT
-	default:
-	    printf( "Unprocessed event %s for hwnd %d\n", 
-		    event_names[event->type], hwnd );
-	    break;
-#endif
+    default:    
+	printf( "Unprocessed event %s for hwnd %d\n",
+	        event_names[event->type], hwnd );
+	break;
+#endif	
     }
 }
 
 
 /***********************************************************************
- *           EVENT_AddHandlers
+ *           EVENT_RegisterWindow
  *
- * Add the event handlers to the given window
+ * Associate an X window to a HWND.
  */
-#ifdef USE_XLIB
-void EVENT_AddHandlers( Window w, int hwnd )
+void EVENT_RegisterWindow( Window w, HWND hwnd )
 {
     if (!winContext) winContext = XUniqueContext();
-    XSaveContext( XT_display, w, winContext, (XPointer)hwnd );
-}
-#else
-void EVENT_AddHandlers( Widget w, int hwnd )
-{
-    XtAddEventHandler(w, ExposureMask, FALSE,
-		      EVENT_expose, (XtPointer)hwnd );
-    XtAddEventHandler(w, KeyPressMask | KeyReleaseMask, FALSE, 
-		      EVENT_key, (XtPointer)hwnd );
-    XtAddEventHandler(w, PointerMotionMask, FALSE,
-		      EVENT_mouse_motion, (XtPointer)hwnd );
-    XtAddEventHandler(w, ButtonPressMask | ButtonReleaseMask, FALSE,
-		      EVENT_mouse_button, (XtPointer)hwnd );
-    XtAddEventHandler(w, StructureNotifyMask, FALSE,
-		      EVENT_structure, (XtPointer)hwnd );
-    XtAddEventHandler(w, FocusChangeMask, FALSE,
-		      EVENT_focus_change, (XtPointer)hwnd );
-    XtAddEventHandler(w, EnterWindowMask, FALSE,
-		      EVENT_enter_notify, (XtPointer)hwnd );
-}
-#endif
-
-
-/***********************************************************************
- *           EVENT_RemoveHandlers
- *
- * Remove the event handlers of the given window
- */
-void EVENT_RemoveHandlers( Widget w, int hwnd )
-{
-#ifndef USE_XLIB
-    XtRemoveEventHandler(w, ExposureMask, FALSE,
-			 EVENT_expose, (XtPointer)hwnd );
-    XtRemoveEventHandler(w, KeyPressMask | KeyReleaseMask, FALSE, 
-			 EVENT_key, (XtPointer)hwnd );
-    XtRemoveEventHandler(w, PointerMotionMask, FALSE,
-			 EVENT_mouse_motion, (XtPointer)hwnd );
-    XtRemoveEventHandler(w, ButtonPressMask | ButtonReleaseMask, FALSE,
-			 EVENT_mouse_button, (XtPointer)hwnd );
-    XtRemoveEventHandler(w, StructureNotifyMask, FALSE,
-			 EVENT_structure, (XtPointer)hwnd );
-    XtRemoveEventHandler(w, FocusChangeMask, FALSE,
-			 EVENT_focus_change, (XtPointer)hwnd );
-    XtRemoveEventHandler(w, EnterWindowMask, FALSE,
-			 EVENT_enter_notify, (XtPointer)hwnd );
-#endif
+    XSaveContext( display, w, winContext, (XPointer)(int)hwnd );
 }
 
 
@@ -262,12 +218,9 @@
 
 
 /***********************************************************************
- *           EVENT_expose
- *
- * Handle a X expose event
+ *           EVENT_Expose
  */
-static void EVENT_expose( Widget w, int hwnd, XExposeEvent *event,
-			  Boolean *cont_dispatch )
+static void EVENT_Expose( HWND hwnd, XExposeEvent *event )
 {
     RECT rect;
     WND * wndPtr = WIN_FindWndPtr( hwnd );
@@ -288,10 +241,8 @@
  *
  * Handle a X key event
  */
-static void EVENT_key( Widget w, int hwnd, XKeyEvent *event,
-		       Boolean *cont_dispatch )
+static void EVENT_key( HWND hwnd, XKeyEvent *event )
 {
-    MSG msg;
     char Str[24]; 
     XComposeStatus cs; 
     KeySym keysym;
@@ -350,25 +301,20 @@
 
     if (event->type == KeyPress)
     {
-	msg.hwnd    = hwnd;
-	msg.message = WM_KEYDOWN;
-	msg.wParam  = vkey;
+	if (vkey == VK_MENU) ALTKeyState = TRUE;
 	keylp.lp1.count = 1;
 	keylp.lp1.code = LOBYTE(event->keycode);
 	keylp.lp1.extended = (extended ? 1 : 0);
 	keylp.lp1.context = (event->state & Mod1Mask ? 1 : 0);
 	keylp.lp1.previous = (KeyDown ? 0 : 1);
 	keylp.lp1.transition = 0;
-	msg.lParam  = keylp.lp2;
 #ifdef DEBUG_KEY
-	printf("            wParam=%X, lParam=%lX\n", msg.wParam, msg.lParam);
+	printf("            wParam=%X, lParam=%lX\n", vkey, keylp.lp2 );
 #endif
-	msg.time = event->time;
-	msg.pt.x = event->x & 0xffff;
-	msg.pt.y = event->y & 0xffff;
-    
-	hardware_event( hwnd, WM_KEYDOWN, vkey, keylp.lp2,
-		        event->x & 0xffff, event->y & 0xffff, event->time, 0 );
+	hardware_event( hwnd, ALTKeyState ? WM_SYSKEYDOWN : WM_KEYDOWN, 
+		        vkey, keylp.lp2,
+		        event->x_root & 0xffff, event->y_root & 0xffff,
+		        event->time, 0 );
 	KeyDown = TRUE;
 
 	/* The key translation ought to take place in TranslateMessage().
@@ -378,218 +324,145 @@
 	 */
 	if (count == 1)                /* key has an ASCII representation */
 	{
-	    msg.hwnd    = hwnd;
-	    msg.message = WM_CHAR;
-	    msg.wParam  = (WORD)Str[0];
-	    msg.lParam  = keylp.lp2;
 #ifdef DEBUG_KEY
-	printf("WM_CHAR :   wParam=%X\n", msg.wParam);
+	    printf("WM_CHAR :   wParam=%X\n", (WORD)Str[0] );
 #endif
-	    msg.time = event->time;
-	    msg.pt.x = event->x & 0xffff;
-	    msg.pt.y = event->y & 0xffff;
 	    PostMessage( hwnd, WM_CHAR, (WORD)Str[0], keylp.lp2 );
 	}
     }
     else
     {
-	msg.hwnd    = hwnd;
-	msg.message = WM_KEYUP;
-	msg.wParam  = vkey;
+	if (vkey == VK_MENU) ALTKeyState = FALSE;
 	keylp.lp1.count = 1;
 	keylp.lp1.code = LOBYTE(event->keycode);
 	keylp.lp1.extended = (extended ? 1 : 0);
 	keylp.lp1.context = (event->state & Mod1Mask ? 1 : 0);
 	keylp.lp1.previous = 1;
 	keylp.lp1.transition = 1;
-	msg.lParam  = keylp.lp2;
 #ifdef DEBUG_KEY
-	printf("            wParam=%X, lParam=%lX\n", msg.wParam, msg.lParam);
+	printf("            wParam=%X, lParam=%lX\n", vkey, keylp.lp2 );
 #endif
-	msg.time = event->time;
-	msg.pt.x = event->x & 0xffff;
-	msg.pt.y = event->y & 0xffff;
-    
-	hardware_event( hwnd, WM_KEYUP, vkey, keylp.lp2,
-		        event->x & 0xffff, event->y & 0xffff, event->time, 0 );
+	hardware_event( hwnd, 
+		        ((ALTKeyState || vkey == VK_MENU) ? 
+			 WM_SYSKEYUP : WM_KEYUP), 
+		        vkey, keylp.lp2,
+		        event->x_root & 0xffff, event->y_root & 0xffff,
+		        event->time, 0 );
 	KeyDown = FALSE;
     }
 }
 
 
 /***********************************************************************
- *           EVENT_mouse_motion
- *
- * Handle a X mouse motion event
+ *           EVENT_MotionNotify
  */
-static void EVENT_mouse_motion( Widget w, int hwnd, XMotionEvent *event, 
-			        Boolean *cont_dispatch )
+static void EVENT_MotionNotify( HWND hwnd, XMotionEvent *event )
 {
-    WND * wndPtr = WIN_FindWndPtr( hwnd );
-    if (!wndPtr) return;
-
-      /* Position must be relative to client area */
-    event->x -= wndPtr->rectClient.left - wndPtr->rectWindow.left;
-    event->y -= wndPtr->rectClient.top - wndPtr->rectWindow.top;
-
-    hardware_event( hwnd, WM_MOUSEMOVE, EVENT_XStateToKeyState( event->state ),
-		    (event->x & 0xffff) | (event->y << 16),
-		    event->x & 0xffff, event->y & 0xffff,
+    hardware_event( hwnd, WM_MOUSEMOVE,
+		    EVENT_XStateToKeyState( event->state ), 0L,
+		    event->x_root & 0xffff, event->y_root & 0xffff,
 		    event->time, 0 );		    
 }
 
 
 /***********************************************************************
- *           EVENT_mouse_button
- *
- * Handle a X mouse button event
+ *           EVENT_ButtonPress
  */
-static void EVENT_mouse_button( Widget w, int hwnd, XButtonEvent *event,
-			        Boolean *cont_dispatch )
+static void EVENT_ButtonPress( HWND hwnd, XButtonEvent *event )
 {
-    static WORD messages[3][NB_BUTTONS] = 
-    {
-	{ WM_LBUTTONDOWN, WM_MBUTTONDOWN, WM_RBUTTONDOWN },
-	{ WM_LBUTTONUP, WM_MBUTTONUP, WM_RBUTTONUP },
-        { WM_LBUTTONDBLCLK, WM_MBUTTONDBLCLK, WM_RBUTTONDBLCLK }
-    };
-    static unsigned long lastClickTime[NB_BUTTONS] = { 0, 0, 0 };
-        
-    int buttonNum, prevTime, type;
+    static WORD messages[NB_BUTTONS] = 
+        { WM_LBUTTONDOWN, WM_MBUTTONDOWN, WM_RBUTTONDOWN };
+    int buttonNum = event->button - 1;
 
-    WND * wndPtr = WIN_FindWndPtr( hwnd );
-    if (!wndPtr) return;
-
-      /* Position must be relative to client area */
-    event->x -= wndPtr->rectClient.left - wndPtr->rectWindow.left;
-    event->y -= wndPtr->rectClient.top - wndPtr->rectWindow.top;
-
-    buttonNum = event->button-1;
-    if (buttonNum >= NB_BUTTONS) return;
-    if (event->type == ButtonRelease) type = 1;
-    else
-    {  /* Check if double-click */
-	prevTime = lastClickTime[buttonNum];
-	lastClickTime[buttonNum] = event->time;
-	if (event->time - prevTime < dblclick_time)
-	{
-	    WND * wndPtr;
-	    CLASS * classPtr;
-	    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return;
-	    if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return;
-	    type = (classPtr->wc.style & CS_DBLCLKS) ? 2 : 0;
-	}
-	else type = 0;
-    }	
-    
+    if (buttonNum >= NB_BUTTONS) return;    
     winHasCursor = event->window;
-
-    hardware_event( hwnd, messages[type][buttonNum],
-		    EVENT_XStateToKeyState( event->state ),
-		    (event->x & 0xffff) | (event->y << 16),
-		    event->x & 0xffff, event->y & 0xffff,
+    hardware_event( hwnd, messages[buttonNum],
+		    EVENT_XStateToKeyState( event->state ), 0L,
+		    event->x_root & 0xffff, event->y_root & 0xffff,
 		    event->time, 0 );		    
 }
 
 
 /***********************************************************************
- *           EVENT_structure
- *
- * Handle a X StructureNotify event
+ *           EVENT_ButtonRelease
  */
-static void EVENT_structure( Widget w, int hwnd, XEvent *event, 
- 			     Boolean *cont_dispatch )
+static void EVENT_ButtonRelease( HWND hwnd, XButtonEvent *event )
 {
-    MSG msg;
-    
-    msg.hwnd = hwnd;
-    msg.time = GetTickCount();
-    msg.pt.x = 0;
-    msg.pt.y = 0;
+    static const WORD messages[NB_BUTTONS] = 
+        { WM_LBUTTONUP, WM_MBUTTONUP, WM_RBUTTONUP };
+    int buttonNum = event->button - 1;
 
-    switch(event->type)
-    {
-      case ConfigureNotify:
-	{
-	    HANDLE handle;
-	    NCCALCSIZE_PARAMS *params;	    
-	    XConfigureEvent * evt = (XConfigureEvent *)event;
-	    WND * wndPtr = WIN_FindWndPtr( hwnd );
-	    if (!wndPtr) return;
-	    wndPtr->rectWindow.left   = evt->x;
-	    wndPtr->rectWindow.top    = evt->y;
-	    wndPtr->rectWindow.right  = evt->x + evt->width;
-	    wndPtr->rectWindow.bottom = evt->y + evt->height;
+    if (buttonNum >= NB_BUTTONS) return;    
+    winHasCursor = event->window;
+    hardware_event( hwnd, messages[buttonNum],
+		    EVENT_XStateToKeyState( event->state ), 0L,
+		    event->x_root & 0xffff, event->y_root & 0xffff,
+		    event->time, 0 );		    
+}
 
-	      /* Send WM_NCCALCSIZE message */
-	    handle = GlobalAlloc( GMEM_MOVEABLE, sizeof(*params) );
-	    params = (NCCALCSIZE_PARAMS *)GlobalLock( handle );
-	    params->rgrc[0] = wndPtr->rectWindow;
-	    params->lppos   = NULL;  /* Should be WINDOWPOS struct */
-	    SendMessage( hwnd, WM_NCCALCSIZE, FALSE, params );
-	    wndPtr->rectClient = params->rgrc[0];
-	    PostMessage( hwnd, WM_MOVE, 0,
-		             MAKELONG( wndPtr->rectClient.left,
-				       wndPtr->rectClient.top ));
-	    PostMessage( hwnd, WM_SIZE, SIZE_RESTORED,
-		   MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left,
-			    wndPtr->rectClient.bottom-wndPtr->rectClient.top));
-	    GlobalUnlock( handle );
-	    GlobalFree( handle );
-	}
-	break;
-	
-    }    
+
+/***********************************************************************
+ *           EVENT_ConfigureNotify
+ */
+static void EVENT_ConfigureNotify( HWND hwnd, XConfigureEvent *event )
+{
+    HANDLE handle;
+    NCCALCSIZE_PARAMS *params;	    
+    WND * wndPtr = WIN_FindWndPtr( hwnd );
+    if (!wndPtr) return;
+    wndPtr->rectWindow.left   = event->x;
+    wndPtr->rectWindow.top    = event->y;
+    wndPtr->rectWindow.right  = event->x + event->width;
+    wndPtr->rectWindow.bottom = event->y + event->height;
+
+      /* Send WM_NCCALCSIZE message */
+    handle = GlobalAlloc( GMEM_MOVEABLE, sizeof(*params) );
+    params = (NCCALCSIZE_PARAMS *)GlobalLock( handle );
+    params->rgrc[0] = wndPtr->rectWindow;
+    params->lppos   = NULL;  /* Should be WINDOWPOS struct */
+    SendMessage( hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)params );
+    wndPtr->rectClient = params->rgrc[0];
+    PostMessage( hwnd, WM_MOVE, 0,
+		 MAKELONG( wndPtr->rectClient.left, wndPtr->rectClient.top ));
+    PostMessage( hwnd, WM_SIZE, SIZE_RESTORED,
+		 MAKELONG( wndPtr->rectClient.right-wndPtr->rectClient.left,
+			   wndPtr->rectClient.bottom-wndPtr->rectClient.top) );
+    GlobalUnlock( handle );
+    GlobalFree( handle );
 }
 
 
 /**********************************************************************
- *              EVENT_focus_change
- *
- * Handle an X FocusChange event
+ *              EVENT_FocusIn
  */
-static void EVENT_focus_change( Widget w, int hwnd, XEvent *event, 
-			       Boolean *cont_dispatch )
+static void EVENT_FocusIn( HWND hwnd, XFocusChangeEvent *event )
 {
-    switch(event->type)
-    {
-      case FocusIn:
-	{
-	    PostMessage( hwnd, WM_SETFOCUS, hwnd, 0 );
-	    hWndFocus = hwnd;
-	}
-	break;
-	
-      case FocusOut:
-	{
-	    if (hWndFocus)
-	    {
-		PostMessage( hwnd, WM_KILLFOCUS, hwnd, 0 );
-		hWndFocus = 0;
-	    }
-	}
-    }    
+    PostMessage( hwnd, WM_SETFOCUS, hwnd, 0 );
+    hWndFocus = hwnd;
 }
 
 
 /**********************************************************************
- *              EVENT_enter_notify
- *
- * Handle an X EnterNotify event
+ *              EVENT_FocusOut
  */
-static void EVENT_enter_notify( Widget w, int hwnd, XCrossingEvent *event, 
-			       Boolean *cont_dispatch )
+static void EVENT_FocusOut( HWND hwnd, XFocusChangeEvent *event )
+{
+    if (hWndFocus)
+    {
+	PostMessage( hwnd, WM_KILLFOCUS, hwnd, 0 );
+	hWndFocus = 0;
+    }
+}
+
+
+/**********************************************************************
+ *              EVENT_EnterNotify
+ */
+static void EVENT_EnterNotify( HWND hwnd, XCrossingEvent *event )
 {
     if (captureWnd != 0) return;
-
     winHasCursor = event->window;
-
-    switch(event->type)
-    {
-      case EnterNotify:
-	PostMessage( hwnd, WM_SETCURSOR, hwnd, 0 );
-	break;
-    }    
+    PostMessage( hwnd, WM_SETCURSOR, hwnd, 0 );
 }
 
 
@@ -604,15 +477,9 @@
     if (wnd_p == NULL)
 	return 0;
     
-#ifdef USE_XLIB
-    rv = XGrabPointer(XT_display, wnd_p->window, False, 
+    rv = XGrabPointer(display, wnd_p->window, False, 
 		      ButtonPressMask | ButtonReleaseMask | ButtonMotionMask,
 		      GrabModeAsync, GrabModeSync, None, None, CurrentTime);
-#else
-    rv = XtGrabPointer(wnd_p->winWidget, False, 
-		       ButtonPressMask | ButtonReleaseMask | ButtonMotionMask,
-		       GrabModeAsync, GrabModeSync, None, None, CurrentTime);
-#endif
 
     if (rv == GrabSuccess)
     {
@@ -637,12 +504,7 @@
     if (wnd_p == NULL)
 	return;
     
-#ifdef USE_XLIB
-    XUngrabPointer( XT_display, CurrentTime );
-#else
-    XtUngrabPointer(wnd_p->winWidget, CurrentTime);
-#endif
-
+    XUngrabPointer( display, CurrentTime );
     captureWnd = 0;
 }
 
@@ -653,24 +515,3 @@
 {
     return captureWnd;
 }
- 
-/**********************************************************************
- *		SetDoubleClickTime  (USER.20)
- */
-void SetDoubleClickTime (WORD interval)
-{
-	if (interval == 0)
-		dblclick_time = 500;
-	else
-		dblclick_time = interval;
-}		
-
-/**********************************************************************
- *		GetDoubleClickTime  (USER.21)
- */
-WORD GetDoubleClickTime ()
-{
-	return ((WORD)dblclick_time);
-}		
-
-
diff --git a/windows/focus.c b/windows/focus.c
index 639b2df..a2d2b8d 100644
--- a/windows/focus.c
+++ b/windows/focus.c
@@ -27,13 +27,19 @@
 
     if (hwnd == 0)
     {
-	XSetInputFocus(XT_display, None, RevertToPointerRoot, CurrentTime);
+	XSetInputFocus(display, None, RevertToPointerRoot, CurrentTime);
     }
     else
     {
+	XWindowAttributes win_attr;
 	wndPtr = WIN_FindWndPtr(hwnd);
-	XSetInputFocus(XT_display, wndPtr->window,
-		       RevertToParent, CurrentTime);
+	
+	if (XGetWindowAttributes( display, wndPtr->window, &win_attr ))
+	{
+	    if (win_attr.map_state == IsViewable)
+		XSetInputFocus(display, wndPtr->window,
+			       RevertToParent, CurrentTime);
+	}
     }
 
     return hWndPrevFocus;
diff --git a/windows/graphics.c b/windows/graphics.c
index 9fd5d27..c5e41b5 100644
--- a/windows/graphics.c
+++ b/windows/graphics.c
@@ -7,7 +7,9 @@
 static char Copyright[] = "Copyright  Alexandre Julliard, 1993";
 
 #include <math.h>
+#include <stdlib.h>
 #include <X11/Xlib.h>
+#include <X11/Xutil.h>
 #ifndef PI
 #define PI M_PI
 #endif
@@ -413,48 +415,44 @@
 
 
 /**********************************************************************
- *          Line  (Not a MSWin Call)
- */
-void Line(HDC hDC, int X1, int Y1, int X2, int Y2)
-{
-MoveTo(hDC, X1, Y1);
-LineTo(hDC, X2, Y2);
-}
-
-
-/**********************************************************************
  *          DrawReliefRect  (Not a MSWin Call)
  */
- void DrawReliefRect(HDC hDC, RECT rect, int ThickNess, int Mode)
+void DrawReliefRect( HDC hdc, RECT rect, int thickness, BOOL pressed )
 {
-HPEN   hWHITEPen;
-HPEN   hDKGRAYPen;
-HPEN   hOldPen;
-int    OldColor;
-rect.right--;  rect.bottom--;
-hDKGRAYPen = CreatePen(PS_SOLID, 1, 0x00808080L);
-hWHITEPen = GetStockObject(WHITE_PEN);
-hOldPen = SelectObject(hDC, hWHITEPen);
-while(ThickNess > 0) {
-    if (Mode == 0)
-	SelectObject(hDC, hWHITEPen);
-    else
-	SelectObject(hDC, hDKGRAYPen);
-    Line(hDC, rect.left, rect.top, rect.right, rect.top);
-    Line(hDC, rect.left, rect.top, rect.left, rect.bottom + 1);
-    if (Mode == 0)
-	SelectObject(hDC, hDKGRAYPen);
-    else
-	SelectObject(hDC, hWHITEPen);
-    Line(hDC, rect.right, rect.bottom, rect.left, rect.bottom);
-    Line(hDC, rect.right, rect.bottom, rect.right, rect.top - 1);
-    InflateRect(&rect, -1, -1);
-    ThickNess--;
+    HBRUSH hbrushOld, hbrushShadow, hbrushHighlight;
+    int i;
+
+    hbrushShadow = CreateSolidBrush( GetSysColor(COLOR_BTNSHADOW) );
+    hbrushHighlight = CreateSolidBrush( GetSysColor(COLOR_BTNHIGHLIGHT) );
+
+    if (pressed) hbrushOld = SelectObject( hdc, hbrushShadow );
+    else hbrushOld = SelectObject( hdc, hbrushHighlight );
+
+    for (i = 0; i < thickness; i++)
+    {
+	PatBlt( hdc, rect.left + i, rect.top,
+	        1, rect.bottom - rect.top - i, PATCOPY );
+	PatBlt( hdc, rect.left, rect.top + i,
+	        rect.right - rect.left - i, 1, PATCOPY );
     }
-SelectObject(hDC, hOldPen);
-DeleteObject(hDKGRAYPen);
+
+    if (pressed) hbrushOld = SelectObject( hdc, hbrushHighlight );
+    else hbrushOld = SelectObject( hdc, hbrushShadow );
+
+    for (i = 0; i < thickness; i++)
+    {
+	PatBlt( hdc, rect.right - i - 1, rect.top + i,
+	        1, rect.bottom - rect.top - i, PATCOPY );
+	PatBlt( hdc, rect.left + i, rect.bottom - i - 1,
+	        rect.right - rect.left - i, 1, PATCOPY );
+    }
+
+    SelectObject( hdc, hbrushOld );
+    DeleteObject( hbrushShadow );
+    DeleteObject( hbrushHighlight );
 }
 
+
 /**********************************************************************
  *          Polyline  (GDI.37)
  */
diff --git a/windows/message.c b/windows/message.c
index 09b49e7..3782a27 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -17,15 +17,15 @@
 
 #include "message.h"
 #include "win.h"
-
+#include "wineopts.h"
+#include "sysmetrics.h"
 
 #define MAX_QUEUE_SIZE   120  /* Max. size of a message queue */
 
-extern BOOL TIMER_CheckTimer( DWORD *next );    /* timer.c */
-
-extern Display * XT_display;
-extern Screen * XT_screen;
-extern XtAppContext XT_app_context;
+extern BOOL TIMER_CheckTimer( DWORD *next );      /* timer.c */
+extern void EVENT_ProcessEvent( XEvent *event );  /* event.c */
+  
+extern Display * display;
 
   /* System message queue (for hardware events) */
 static HANDLE hmemSysMsgQueue = 0;
@@ -35,6 +35,10 @@
 static HANDLE hmemAppMsgQueue = 0;
 static MESSAGEQUEUE * appMsgQueue = NULL;
 
+  /* Double-click time */
+static int doubleClickSpeed = 452;
+
+
 /***********************************************************************
  *           MSG_CreateMsgQueue
  *
@@ -78,7 +82,8 @@
 /***********************************************************************
  *           MSG_CreateSysMsgQueue
  *
- * Create the system message queue. Must be called only once.
+ * Create the system message queue, and set the double-click speed.
+ * Must be called only once.
  */
 BOOL MSG_CreateSysMsgQueue( int size )
 {
@@ -86,6 +91,7 @@
     else if (size <= 0) size = 1;
     if (!(hmemSysMsgQueue = MSG_CreateMsgQueue( size ))) return FALSE;
     sysMsgQueue = (MESSAGEQUEUE *) GlobalLock( hmemSysMsgQueue );
+    doubleClickSpeed = GetProfileInt( "windows", "DoubleClickSpeed", 452 );
     return TRUE;
 }
 
@@ -99,6 +105,8 @@
 {
     int pos;
   
+    SpyMessage(msg->hwnd, msg->message, msg->wParam, msg->lParam);
+    
     if (!msgQueue) return FALSE;
     pos = msgQueue->nextFreeMessage;
 
@@ -184,6 +192,93 @@
 
 
 /***********************************************************************
+ *           MSG_TranslateMouseMsg
+ *
+ * Translate an mouse hardware event into a real mouse message.
+ * Actions performed:
+ * - Translate button down messages in double-clicks.
+ * - Send the WM_NCHITTEST message to find where the cursor is.
+ * - Translate the message into a non-client message, or translate
+ *   the coordinates to client coordinates.
+ */
+static void MSG_TranslateMouseMsg( MSG *msg )
+{
+    static DWORD lastClickTime = 0;
+    static WORD  lastClickMsg = 0;
+    static POINT lastClickPos = { 0, 0 };
+
+    LONG hittest_result = SendMessage( msg->hwnd, WM_NCHITTEST, 0,
+				       MAKELONG( msg->pt.x, msg->pt.y ) );
+
+    if ((msg->message == WM_LBUTTONDOWN) ||
+        (msg->message == WM_RBUTTONDOWN) ||
+        (msg->message == WM_MBUTTONDOWN))
+    {
+	BOOL dbl_click = FALSE;
+
+	  /* Check for double-click */
+
+	if ((msg->message == lastClickMsg) &&
+	    (msg->time - lastClickTime < doubleClickSpeed) &&
+	    (abs(msg->pt.x - lastClickPos.x) < SYSMETRICS_CXDOUBLECLK/2) &&
+	    (abs(msg->pt.y - lastClickPos.y) < SYSMETRICS_CYDOUBLECLK/2))
+	    dbl_click = TRUE;
+
+	if (dbl_click && (hittest_result == HTCLIENT))
+	{
+	    /* Check whether window wants the double click message. */
+	    WND * wndPtr = WIN_FindWndPtr( msg->hwnd );
+	    if (!wndPtr || !(wndPtr->flags & WIN_DOUBLE_CLICKS))
+		dbl_click = FALSE;
+	}
+
+	if (dbl_click) switch(msg->message)
+	{
+	    case WM_LBUTTONDOWN: msg->message = WM_LBUTTONDBLCLK; break;
+	    case WM_RBUTTONDOWN: msg->message = WM_RBUTTONDBLCLK; break;
+	    case WM_MBUTTONDOWN: msg->message = WM_MBUTTONDBLCLK; break;
+	}
+
+	lastClickTime = msg->time;
+	lastClickMsg  = msg->message;
+	lastClickPos  = msg->pt;
+    }
+
+    msg->lParam = MAKELONG( msg->pt.x, msg->pt.y );
+    if (hittest_result == HTCLIENT)
+    {
+	ScreenToClient( msg->hwnd, (LPPOINT)&msg->lParam );
+    }
+    else
+    {
+	msg->wParam = hittest_result;
+	msg->message += WM_NCLBUTTONDOWN - WM_LBUTTONDOWN;
+    }
+}
+
+
+/**********************************************************************
+ *		SetDoubleClickTime  (USER.20)
+ */
+void SetDoubleClickTime( WORD interval )
+{
+    if (interval == 0)
+	doubleClickSpeed = 500;
+    else
+	doubleClickSpeed = interval;
+}		
+
+
+/**********************************************************************
+ *		GetDoubleClickTime  (USER.21)
+ */
+WORD GetDoubleClickTime()
+{
+	return (WORD)doubleClickSpeed;
+}		
+
+
+/***********************************************************************
  *           MSG_IncPaintCount
  */
 void MSG_IncPaintCount( HANDLE hQueue )
@@ -233,6 +328,7 @@
  *           hardware_event
  *
  * Add an event to the system message queue.
+ * Note: the position is in screen coordinates.
  */
 void hardware_event( HWND hwnd, WORD message, WORD wParam, LONG lParam,
 		     WORD xPos, WORD yPos, DWORD time, DWORD extraInfo )
@@ -325,24 +421,6 @@
 }
 
 
-#ifndef USE_XLIB
-static XtIntervalId xt_timer = 0;
-
-/***********************************************************************
- *           MSG_TimerCallback
- */
-static void MSG_TimerCallback( XtPointer data, XtIntervalId * xtid )
-{
-    DWORD nextExp;
-    TIMER_CheckTimer( &nextExp );
-    if (nextExp != (DWORD)-1)
-	xt_timer = XtAppAddTimeOut( XT_app_context, nextExp,
-				    MSG_TimerCallback, NULL );
-    else xt_timer = 0;
-}
-#endif  /* USE_XLIB */
-
-
 /***********************************************************************
  *           MSG_PeekMessage
  */
@@ -351,9 +429,7 @@
 {
     int pos, mask;
     DWORD nextExp;  /* Next timer expiration time */
-#ifdef USE_XLIB
     XEvent event;
-#endif
 
     if (first || last)
     {
@@ -366,16 +442,11 @@
     }
     else mask = QS_MOUSE | QS_KEY | QS_POSTMESSAGE | QS_TIMER | QS_PAINT;
 
-#ifdef USE_XLIB
-    while (XPending( XT_display ))
+    while (XPending( display ))
     {
-	XNextEvent( XT_display, &event );
+	XNextEvent( display, &event );
 	EVENT_ProcessEvent( &event );
     }    
-#else
-    while (XtAppPending( XT_app_context ))
-	XtAppProcessEvent( XT_app_context, XtIMAll );
-#endif
 
     while(1)
     {    
@@ -432,6 +503,8 @@
 	    msgQueue->GetMessageExtraInfoVal = qmsg->extraInfo;
 
 	    if (flags & PM_REMOVE) MSG_RemoveMsg( sysMsgQueue, pos );
+	    if ((msg->message >= WM_MOUSEFIRST) &&
+		(msg->message <= WM_MOUSELAST)) MSG_TranslateMouseMsg( msg );
 	    break;
 	}
 
@@ -447,26 +520,16 @@
 
 	  /* Finally handle WM_TIMER messages */
 	if ((msgQueue->status & QS_TIMER) && (mask & QS_TIMER))
-	{
-	    BOOL posted = TIMER_CheckTimer( &nextExp );
-#ifndef USE_XLIB
-	    if (xt_timer) XtRemoveTimeOut( xt_timer );
-	    if (nextExp != (DWORD)-1)
-		xt_timer = XtAppAddTimeOut( XT_app_context, nextExp,
-					    MSG_TimerCallback, NULL );
-	    else xt_timer = 0;
-#endif
-	    if (posted) continue;  /* Restart the whole thing */
-	}
+	    if (TIMER_CheckTimer( &nextExp ))
+		continue;  /* Restart the whole search */
 
 	  /* Wait until something happens */
 	if (peek) return FALSE;
-#ifdef USE_XLIB
-	if (!XPending( XT_display ) && (nextExp != -1))
+	if (!XPending( display ) && (nextExp != -1))
 	{
 	    fd_set read_set;
 	    struct timeval timeout;
-	    int fd = ConnectionNumber(XT_display);
+	    int fd = ConnectionNumber(display);
 	    FD_ZERO( &read_set );
 	    FD_SET( fd, &read_set );
 	    timeout.tv_sec = nextExp / 1000;
@@ -474,11 +537,8 @@
 	    if (select( fd+1, &read_set, NULL, NULL, &timeout ) != 1)
 		continue;  /* On timeout or error, restart from the start */
 	}
-	XNextEvent( XT_display, &event );
+	XNextEvent( display, &event );
 	EVENT_ProcessEvent( &event );
-#else       
-	XtAppProcessEvent( XT_app_context, XtIMAll );
-#endif	
     }
 
       /* We got a message */
@@ -529,7 +589,11 @@
  */
 LONG SendMessage( HWND hwnd, WORD msg, WORD wParam, LONG lParam )
 {
-    WND * wndPtr = WIN_FindWndPtr( hwnd );
+    WND * wndPtr;
+
+    SpyMessage(hwnd, msg, wParam, lParam);
+    
+    wndPtr = WIN_FindWndPtr( hwnd );
     if (!wndPtr) return 0;
     return CallWindowProc( wndPtr->lpfnWndProc, hwnd, msg, wParam, lParam );
 }
@@ -564,7 +628,7 @@
     int painting;
     
 #ifdef DEBUG_MSG
-    printf( "Dispatch message hwnd=%08x msg=%d w=%d l=%d time=%u pt=%d,%d\n",
+    printf( "Dispatch message hwnd=%08x msg=0x%x w=%d l=%d time=%u pt=%d,%d\n",
 	    msg->hwnd, msg->message, msg->wParam, msg->lParam, 
 	    msg->time, msg->pt.x, msg->pt.y );
 #endif
@@ -587,7 +651,7 @@
     if (painting && (wndPtr->flags & WIN_NEEDS_BEGINPAINT))
     {
 #ifdef DEBUG_WIN
-	printf( "BeginPaint not called on WM_PAINT!\n" );
+	printf( "BeginPaint not called on WM_PAINT for hwnd %d!\n", msg->hwnd);
 #endif
 	wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
     }
diff --git a/windows/nonclient.c b/windows/nonclient.c
new file mode 100644
index 0000000..79f5893
--- /dev/null
+++ b/windows/nonclient.c
@@ -0,0 +1,461 @@
+/*
+ * Non-client area window functions
+ *
+ * Copyright 1994 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright  Alexandre Julliard, 1994";
+
+#include "win.h"
+#include "sysmetrics.h"
+
+
+/***********************************************************************
+ *           NC_AdjustRect
+ *
+ * Compute the size of the window rectangle from the size of the
+ * client rectangle.
+ */
+static void NC_AdjustRect( LPRECT rect, DWORD style, BOOL menu, DWORD exStyle )
+{
+    if ((style & WS_DLGFRAME) && 
+	((exStyle & WS_EX_DLGMODALFRAME) || !(style & WS_BORDER)))
+	InflateRect( rect, SYSMETRICS_CXDLGFRAME, SYSMETRICS_CYDLGFRAME );
+    else if (style & WS_THICKFRAME)
+	InflateRect( rect, SYSMETRICS_CXFRAME, SYSMETRICS_CYFRAME );
+
+    if (style & WS_BORDER)
+	InflateRect( rect, SYSMETRICS_CXBORDER, SYSMETRICS_CYBORDER );
+
+    if ((style & WS_CAPTION) == WS_CAPTION)
+	rect->top -= SYSMETRICS_CYCAPTION - 1;
+
+    if (menu) rect->top -= SYSMETRICS_CYMENU + 1;
+
+    if (style & WS_VSCROLL) rect->right  += SYSMETRICS_CXVSCROLL;
+    if (style & WS_HSCROLL) rect->bottom += SYSMETRICS_CYHSCROLL;
+}
+
+
+/***********************************************************************
+ *           AdjustWindowRect    (USER.102)
+ */
+void AdjustWindowRect( LPRECT rect, DWORD style, BOOL menu )
+{
+    AdjustWindowRectEx( rect, style, menu, 0 );
+}
+
+
+/***********************************************************************
+ *           AdjustWindowRectEx    (USER.454)
+ */
+void AdjustWindowRectEx( LPRECT rect, DWORD style, BOOL menu, DWORD exStyle )
+{
+      /* Correct the window style */
+
+    if (!(style & (WS_POPUP | WS_CHILD)))  /* Overlapped window */
+	style |= WS_CAPTION;
+    if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
+
+#ifdef DEBUG_NONCLIENT
+    printf( "AdjustWindowRectEx: (%d,%d)-(%d,%d) %08x %d %08x\n",
+      rect->left, rect->top, rect->right, rect->bottom, style, menu, exStyle );
+#endif
+
+    NC_AdjustRect( rect, style, menu, exStyle );
+}
+
+
+/***********************************************************************
+ *           NC_HandleNCCalcSize
+ *
+ * Handle a WM_NCCALCSIZE message. Called from DefWindowProc().
+ */
+LONG NC_HandleNCCalcSize( HWND hwnd, NCCALCSIZE_PARAMS *params )
+{
+    RECT tmpRect = { 0, 0, 0, 0 };
+    BOOL hasMenu;
+    WND *wndPtr = WIN_FindWndPtr( hwnd );
+    
+    if (!wndPtr) return 0;
+
+    hasMenu = (!(wndPtr->dwStyle & WS_CHILD)) && (wndPtr->wIDmenu != 0);
+
+    NC_AdjustRect( &tmpRect, wndPtr->dwStyle, hasMenu, wndPtr->dwExStyle );
+    
+    params->rgrc[0].left   -= tmpRect.left;
+    params->rgrc[0].top    -= tmpRect.top;
+    params->rgrc[0].right  -= tmpRect.right;
+    params->rgrc[0].bottom -= tmpRect.bottom;
+    return 0;
+}
+
+
+/***********************************************************************
+ *           NC_HandleNCHitTest
+ *
+ * Handle a WM_NCHITTEST message. Called from DefWindowProc().
+ */
+LONG NC_HandleNCHitTest( HWND hwnd, POINT pt )
+{
+    RECT rect;
+    WND *wndPtr = WIN_FindWndPtr( hwnd );
+    if (!wndPtr) return HTERROR;
+
+#ifdef DEBUG_NONCLIENT
+    printf( "NC_HandleNCHitTest: hwnd=%x pt=%d,%d\n", hwnd, pt.x, pt.y );
+#endif
+
+    if (hwnd == GetCapture()) return HTCLIENT;
+    GetWindowRect( hwnd, &rect );
+    if (!PtInRect( &rect, pt )) return HTNOWHERE;
+    ScreenToClient( hwnd, &pt );
+    GetClientRect( hwnd, &rect );
+    
+    if (PtInRect( &rect, pt )) return HTCLIENT;
+
+      /* Check vertical scroll bar */
+    if (wndPtr->dwStyle & WS_VSCROLL)
+    {
+	rect.right += SYSMETRICS_CXVSCROLL;
+	if (PtInRect( &rect, pt )) return HTVSCROLL;
+    }
+
+      /* Check horizontal scroll bar */
+    if (wndPtr->dwStyle & WS_HSCROLL)
+    {
+	rect.bottom += SYSMETRICS_CYHSCROLL;
+	if (PtInRect( &rect, pt ))
+	{
+	      /* Check size box */
+	    if ((wndPtr->dwStyle & WS_VSCROLL) &&
+		(pt.x >= rect.right - SYSMETRICS_CXVSCROLL)) return HTSIZE;
+	    return HTHSCROLL;
+	}
+    }
+
+      /* Check menu */
+    if ((!(wndPtr->dwStyle & WS_CHILD)) && (wndPtr->wIDmenu != 0))
+    {
+	rect.top -= SYSMETRICS_CYMENU + 1;
+	if (PtInRect( &rect, pt )) return HTMENU;
+    }
+
+      /* Check caption */
+    if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
+    {
+	rect.top -= SYSMETRICS_CYCAPTION - 1;
+	if (PtInRect( &rect, pt ))
+	{
+	      /* Check system menu */
+	    if ((wndPtr->dwStyle & WS_SYSMENU) && (pt.x <= SYSMETRICS_CXSIZE))
+		return HTSYSMENU;
+	      /* Check maximize box */
+	    if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
+		rect.right -= SYSMETRICS_CXSIZE + 1;
+	    if (pt.x >= rect.right) return HTMAXBUTTON;
+	      /* Check minimize box */
+	    if (wndPtr->dwStyle & WS_MINIMIZEBOX)
+		rect.right -= SYSMETRICS_CXSIZE + 1;
+	    if (pt.x >= rect.right) return HTMINBUTTON;
+	    return HTCAPTION;
+	}
+    }
+    
+      /* Check non-sizing border */
+    if (!(wndPtr->dwStyle & WS_THICKFRAME) ||
+	((wndPtr->dwStyle & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME))
+	return HTBORDER;
+
+      /* Check top sizing border */
+    if (pt.y < rect.top)
+    {
+	if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTTOPLEFT;
+	if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTTOPRIGHT;
+	return HTTOP;
+    }
+
+      /* Check bottom sizing border */
+    if (pt.y >= rect.bottom)
+    {
+	if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTBOTTOMLEFT;
+	if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTBOTTOMRIGHT;
+	return HTBOTTOM;
+    }
+    
+      /* Check left sizing border */
+    if (pt.x < rect.left)
+    {
+	if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPLEFT;
+	if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMLEFT;
+	return HTLEFT;
+    }
+
+      /* Check right sizing border */
+    if (pt.x >= rect.right)
+    {
+	if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPRIGHT;
+	if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMRIGHT;
+	return HTRIGHT;
+    }
+
+      /* Should never get here */
+    return HTERROR;
+}
+
+
+/***********************************************************************
+ *           NC_DrawFrame
+ *
+ * Draw a window frame inside the given rectangle, and update the rectangle.
+ * The correct pen and brush must be selected in the DC.
+ */
+static void NC_DrawFrame( HDC hdc, RECT *rect, BOOL dlgFrame )
+{
+    short width, height, tmp;
+
+    if (dlgFrame)
+    {
+	width = SYSMETRICS_CXDLGFRAME;
+	height = SYSMETRICS_CYDLGFRAME;
+    }
+    else
+    {
+	width = SYSMETRICS_CXFRAME - 1;
+	height = SYSMETRICS_CYFRAME - 1;
+    }
+
+      /* Draw frame */
+    PatBlt( hdc, rect->left, rect->top,
+	    rect->right - rect->left, height, PATCOPY );
+    PatBlt( hdc, rect->left, rect->top,
+	    width, rect->bottom - rect->top, PATCOPY );
+    PatBlt( hdc, rect->left, rect->bottom,
+	    rect->right - rect->left, -height, PATCOPY );
+    PatBlt( hdc, rect->right, rect->top,
+	    -width, rect->bottom - rect->top, PATCOPY );
+
+    if (dlgFrame)
+    {
+	InflateRect( rect, -width, -height );
+	return;
+    }
+    
+      /* Draw inner rectangle */
+    MoveTo( hdc, rect->left+width, rect->top+height );
+    LineTo( hdc, rect->right-width-1, rect->top+height );
+    LineTo( hdc, rect->right-width-1, rect->bottom-height-1 );
+    LineTo( hdc, rect->left+width, rect->bottom-height-1 );
+    LineTo( hdc, rect->left+width, rect->top+height );
+
+      /* Draw the decorations */
+    tmp = rect->top + SYSMETRICS_CYFRAME + SYSMETRICS_CYSIZE;
+    MoveTo( hdc, rect->left, tmp);
+    LineTo( hdc, rect->left+width, tmp );
+    MoveTo( hdc, rect->right-width-1, tmp );
+    LineTo( hdc, rect->right-1, tmp );
+
+    tmp = rect->bottom - 1 - SYSMETRICS_CYFRAME - SYSMETRICS_CYSIZE;
+    MoveTo( hdc, rect->left, tmp );
+    LineTo( hdc, rect->left+width, tmp );
+    MoveTo( hdc, rect->right-width-1, tmp );
+    LineTo( hdc, rect->right-1, tmp );
+
+    tmp = rect->left + SYSMETRICS_CXFRAME + SYSMETRICS_CXSIZE;
+    MoveTo( hdc, tmp, rect->top );
+    LineTo( hdc, tmp, rect->top+height );
+    MoveTo( hdc, tmp, rect->bottom-height-1 );
+    LineTo( hdc, tmp, rect->bottom-1 );
+
+    tmp = rect->right - 1 - SYSMETRICS_CXFRAME - SYSMETRICS_CYSIZE;
+    MoveTo( hdc, tmp, rect->top );
+    LineTo( hdc, tmp, rect->top+height );
+    MoveTo( hdc, tmp, rect->bottom-height-1 );
+    LineTo( hdc, tmp, rect->bottom-1 );
+
+    InflateRect( rect, -width-1, -height-1 );
+}
+
+
+/***********************************************************************
+ *           NC_DrawCaption
+ *
+ * Draw the window caption.
+ * The correct pen for the window frame must be selected in the DC.
+ */
+static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd, DWORD style )
+{
+    RECT r;
+    HBRUSH hbrushCaption, hbrushButtons;
+    char buffer[256];
+
+    hbrushButtons = CreateSolidBrush( GetSysColor( COLOR_BTNFACE ) );
+    hbrushCaption = CreateSolidBrush( GetSysColor( COLOR_ACTIVECAPTION ) );
+
+    MoveTo( hdc, rect->left, rect->bottom );
+    LineTo( hdc, rect->right-1, rect->bottom );
+
+    /* We should probably use OEM bitmaps (OBM_*) here */
+    if (style & WS_SYSMENU)
+    {
+	r = *rect;
+	r.right = r.left + SYSMETRICS_CYSIZE;
+	FillRect( hdc, &r, hbrushButtons );
+	MoveTo( hdc, r.right, r.top );
+	LineTo( hdc, r.right, r.bottom );
+	rect->left += SYSMETRICS_CXSIZE + 1;
+    }
+    if (style & WS_MAXIMIZEBOX)
+    {
+	r = *rect;
+	r.left = r.right - SYSMETRICS_CXSIZE;
+	FillRect( hdc, &r, hbrushButtons );
+	MoveTo( hdc, r.left-1, r.top );
+	LineTo( hdc, r.left-1, r.bottom );
+	DrawReliefRect( hdc, r, 2, 0 );
+	rect->right -= SYSMETRICS_CXSIZE + 1;
+    }
+    if (style & WS_MINIMIZEBOX)
+    {
+	r = *rect;
+	r.left = r.right - SYSMETRICS_CXSIZE;
+	FillRect( hdc, &r, hbrushButtons );
+	MoveTo( hdc, r.left-1, r.top );
+	LineTo( hdc, r.left-1, r.bottom );
+	DrawReliefRect( hdc, r, 2, 0 );
+	rect->right -= SYSMETRICS_CXSIZE + 1;
+    }
+
+    FillRect( hdc, rect, hbrushCaption );
+
+    if (GetWindowText( hwnd, buffer, 256 ))
+    {
+	SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) );
+	SetBkMode( hdc, TRANSPARENT );
+	DrawText( hdc, buffer, -1, rect,
+		 DT_SINGLELINE | DT_CENTER | DT_VCENTER );
+    }
+
+    DeleteObject( hbrushButtons );
+    DeleteObject( hbrushCaption );
+}
+
+
+/***********************************************************************
+ *           NC_HandleNCPaint
+ *
+ * Handle a WM_NCPAINT message. Called from DefWindowProc().
+ */
+LONG NC_HandleNCPaint( HWND hwnd, HRGN hrgn )
+{
+    HDC hdc;
+    RECT rect;
+    HBRUSH hbrushBorder = 0;
+    HPEN hpenFrame = 0;
+
+    WND *wndPtr = WIN_FindWndPtr( hwnd );
+
+#ifdef DEBUG_NONCLIENT
+    printf( "NC_HandleNCPaint: %d %d\n", hwnd, hrgn );
+#endif
+
+    if (!wndPtr || !hrgn) return 0;
+    if (!(wndPtr->dwStyle & (WS_BORDER | WS_DLGFRAME | WS_THICKFRAME)))
+	return 0;  /* Nothing to do! */
+
+    if (hrgn == 1) hdc = GetDCEx( hwnd, 0, DCX_CACHE | DCX_WINDOW );
+    else hdc = GetDCEx( hwnd, hrgn, DCX_CACHE | DCX_WINDOW | DCX_INTERSECTRGN);
+    if (!hdc) return 0;
+    if (ExcludeVisRect( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
+		        wndPtr->rectClient.top-wndPtr->rectWindow.top,
+		        wndPtr->rectClient.right-wndPtr->rectWindow.left,
+		        wndPtr->rectClient.bottom-wndPtr->rectWindow.top )
+	== NULLREGION)
+    {
+	ReleaseDC( hwnd, hdc );
+	return 0;
+    }
+
+    rect.top = rect.left = 0;
+    rect.right  = wndPtr->rectWindow.right - wndPtr->rectWindow.left;
+    rect.bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top;
+
+    hpenFrame = CreatePen( PS_SOLID, 1, GetSysColor(COLOR_WINDOWFRAME) );
+    SelectObject( hdc, hpenFrame );
+    hbrushBorder = CreateSolidBrush( GetSysColor(COLOR_ACTIVEBORDER) );
+    SelectObject( hdc, hbrushBorder );
+
+    if ((wndPtr->dwStyle & WS_BORDER) || (wndPtr->dwStyle & WS_DLGFRAME))
+    {
+	MoveTo( hdc, 0, 0 );
+	LineTo( hdc, rect.right-1, 0 );
+	LineTo( hdc, rect.right-1, rect.bottom-1 );
+	LineTo( hdc, 0, rect.bottom-1 );
+	LineTo( hdc, 0, 0 );
+	InflateRect( &rect, -1, -1 );
+    }
+
+    if ((wndPtr->dwStyle & WS_DLGFRAME) &&
+	((wndPtr->dwExStyle & WS_EX_DLGMODALFRAME) || 
+	 !(wndPtr->dwStyle & WS_BORDER))) NC_DrawFrame( hdc, &rect, TRUE );
+    else if (wndPtr->dwStyle & WS_THICKFRAME) NC_DrawFrame(hdc, &rect, FALSE);
+
+    if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
+    {
+	RECT r = rect;
+	rect.top += SYSMETRICS_CYSIZE + 1;
+	r.bottom = rect.top - 1;
+	if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)
+	{
+	    HBRUSH hbrushWindow = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
+	    HBRUSH hbrushOld = SelectObject( hdc, hbrushWindow );
+	    PatBlt( hdc, r.left, r.top, 1, r.bottom-r.top+1, PATCOPY );
+	    PatBlt( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY );
+	    PatBlt( hdc, r.left, r.top, r.right-r.left, 1, PATCOPY );
+	    r.left++;
+	    r.right--;
+	    r.top++;
+	    SelectObject( hdc, hbrushOld );
+	    DeleteObject( hbrushWindow );
+	}
+	NC_DrawCaption( hdc, &r, hwnd, wndPtr->dwStyle );
+    }
+
+    if (wndPtr->dwStyle & (WS_VSCROLL | WS_HSCROLL))
+    {
+	HBRUSH hbrushScroll = CreateSolidBrush( GetSysColor(COLOR_SCROLLBAR) );
+	HBRUSH hbrushOld = SelectObject( hdc, hbrushScroll );
+	if (wndPtr->dwStyle & WS_VSCROLL)
+	    PatBlt( hdc, rect.right - SYSMETRICS_CXVSCROLL, rect.top,
+		    SYSMETRICS_CXVSCROLL, rect.bottom-rect.top, PATCOPY );
+	if (wndPtr->dwStyle & WS_HSCROLL)
+	    PatBlt( hdc, rect.left, rect.bottom - SYSMETRICS_CYHSCROLL,
+		    rect.right-rect.left, SYSMETRICS_CYHSCROLL, PATCOPY );
+	SelectObject( hdc, hbrushOld );
+	DeleteObject( hbrushScroll );
+    }    
+
+    ReleaseDC( hwnd, hdc );
+    if (hbrushBorder) DeleteObject( hbrushBorder );
+    if (hpenFrame) DeleteObject( hpenFrame );    
+    return 0;
+}
+
+
+/***********************************************************************
+ *           NC_HandleNCMouseMsg
+ *
+ * Handle a non-client mouse message. Called from DefWindowProc().
+ */
+LONG NC_HandleNCMouseMsg( HWND hwnd, WORD msg, WORD wParam, LONG lParam )
+{
+    switch(wParam)  /* Hit test code */
+    {
+    case HTSYSMENU:
+	if (msg == WM_NCLBUTTONDBLCLK)
+	    return SendMessage( hwnd, WM_SYSCOMMAND, SC_CLOSE, lParam );
+	break;
+    }
+    return 0;
+}
+
diff --git a/windows/painting.c b/windows/painting.c
index 5a8e60a..2aeaba2 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -21,9 +21,12 @@
  */
 HDC BeginPaint( HWND hwnd, LPPAINTSTRUCT lps ) 
 {
+    HRGN hrgnUpdate;
     WND * wndPtr = WIN_FindWndPtr( hwnd );
     if (!wndPtr) return 0;
 
+    hrgnUpdate = wndPtr->hrgnUpdate;  /* Save update region */
+
     if (!(lps->hdc = GetDCEx( hwnd, wndPtr->hrgnUpdate,
 			      DCX_INTERSECTRGN | DCX_USESTYLE ))) return 0;
     GetRgnBox( InquireVisRgn(lps->hdc), &lps->rcPaint );
@@ -35,7 +38,8 @@
 	MSG_DecPaintCount( wndPtr->hmemTaskQ );
     }
     wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
-    
+
+    SendMessage( hwnd, WM_NCPAINT, hrgnUpdate, 0 );
     if (!(wndPtr->flags & WIN_ERASE_UPDATERGN)) lps->fErase = TRUE;
     else lps->fErase = !SendMessage( hwnd, WM_ERASEBKGND, lps->hdc, 0 );
     
diff --git a/windows/sysmetrics.c b/windows/sysmetrics.c
new file mode 100644
index 0000000..bea4561
--- /dev/null
+++ b/windows/sysmetrics.c
@@ -0,0 +1,81 @@
+/*
+ * System metrics functions
+ *
+ * Copyright 1994 Alexandre Julliard
+ */
+
+static char Copyright[] = "Copyright  Alexandre Julliard, 1994";
+
+#include <X11/Xlib.h>
+
+#include "sysmetrics.h"
+
+
+short sysMetrics[SM_CMETRICS];
+
+extern Display * display;
+
+/***********************************************************************
+ *           SYSMETRICS_Init
+ *
+ * Initialisation of the system metrics array.
+ */
+void SYSMETRICS_Init()
+{
+    sysMetrics[SM_CXSCREEN] = DisplayWidth( display, DefaultScreen(display) );
+    sysMetrics[SM_CYSCREEN] = DisplayHeight( display, DefaultScreen(display) );
+    sysMetrics[SM_CXVSCROLL] = SYSMETRICS_CXVSCROLL;
+    sysMetrics[SM_CYHSCROLL] = SYSMETRICS_CYHSCROLL;
+    sysMetrics[SM_CYCAPTION] = SYSMETRICS_CYCAPTION;
+    sysMetrics[SM_CXBORDER] = SYSMETRICS_CXBORDER;
+    sysMetrics[SM_CYBORDER] = SYSMETRICS_CYBORDER;
+    sysMetrics[SM_CXDLGFRAME] = SYSMETRICS_CXDLGFRAME;
+    sysMetrics[SM_CYDLGFRAME] = SYSMETRICS_CYDLGFRAME;
+    sysMetrics[SM_CYVTHUMB] = SYSMETRICS_CYVTHUMB;
+    sysMetrics[SM_CXHTHUMB] = SYSMETRICS_CXHTHUMB;
+    sysMetrics[SM_CXICON] = SYSMETRICS_CXICON;
+    sysMetrics[SM_CYICON] = SYSMETRICS_CYICON;
+    sysMetrics[SM_CXCURSOR] = SYSMETRICS_CXCURSOR;
+    sysMetrics[SM_CYCURSOR] = SYSMETRICS_CYCURSOR;
+    sysMetrics[SM_CYMENU] = SYSMETRICS_CYMENU;
+    sysMetrics[SM_CXFULLSCREEN] = sysMetrics[SM_CXSCREEN];
+    sysMetrics[SM_CYFULLSCREEN] = sysMetrics[SM_CYSCREEN] - sysMetrics[SM_CYCAPTION];
+    sysMetrics[SM_CYKANJIWINDOW] = 0;
+    sysMetrics[SM_MOUSEPRESENT] = 1;
+    sysMetrics[SM_CYVSCROLL] = SYSMETRICS_CYVSCROLL;
+    sysMetrics[SM_CXHSCROLL] = SYSMETRICS_CXHSCROLL;
+    sysMetrics[SM_DEBUG] = 0;
+    sysMetrics[SM_SWAPBUTTON] = 0;
+    sysMetrics[SM_RESERVED1] = 0;
+    sysMetrics[SM_RESERVED2] = 0;
+    sysMetrics[SM_RESERVED3] = 0;
+    sysMetrics[SM_RESERVED4] = 0;
+    sysMetrics[SM_CXMIN] = SYSMETRICS_CXMIN;
+    sysMetrics[SM_CYMIN] = SYSMETRICS_CYMIN;
+    sysMetrics[SM_CXSIZE] = SYSMETRICS_CXSIZE;
+    sysMetrics[SM_CYSIZE] = SYSMETRICS_CYSIZE;
+    sysMetrics[SM_CXFRAME] = GetProfileInt( "windows", "BorderWidth", 4 );
+    sysMetrics[SM_CYFRAME] = sysMetrics[SM_CXFRAME];
+    sysMetrics[SM_CXMINTRACK] = SYSMETRICS_CXMINTRACK;
+    sysMetrics[SM_CYMINTRACK] = SYSMETRICS_CYMINTRACK;
+    sysMetrics[SM_CXDOUBLECLK] = (GetProfileInt( "windows","DoubleClickWidth", 4) + 1) & ~1;
+    sysMetrics[SM_CYDOUBLECLK] = (GetProfileInt( "windows","DoubleClickHeight", 4) + 1) & ~1;
+    sysMetrics[SM_CXICONSPACING] = GetProfileInt( "desktop","IconSpacing", 75);
+    sysMetrics[SM_CYICONSPACING] = GetProfileInt( "desktop","IconVerticalSpacing", 72);
+    sysMetrics[SM_MENUDROPALIGNMENT] = GetProfileInt( "windows","MenuDropAlignment", 0 );
+    sysMetrics[SM_PENWINDOWS] = 0;
+    sysMetrics[SM_DBCSENABLED] = 0;
+}
+
+
+/***********************************************************************
+ *           GetSystemMetrics    (USER.179)
+ */
+int GetSystemMetrics( WORD index )
+{
+    if (index >= SM_CMETRICS) return 0;
+    else return sysMetrics[index];    
+}
+
+
+
diff --git a/windows/win.c b/windows/win.c
index 8411e48..810503c 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -15,11 +15,13 @@
 #include "win.h"
 #include "user.h"
 #include "dce.h"
+#include "sysmetrics.h"
 
-extern Display * XT_display;
-extern Screen * XT_screen;
+extern Display * display;
 extern Colormap COLOR_WinColormap;
 
+extern void EVENT_RegisterWindow( Window w, HWND hwnd );  /* event.c */
+
 static HWND firstWindow = 0;
 
 /***********************************************************************
@@ -178,17 +180,22 @@
     CREATESTRUCT *createStruct;
     HANDLE hcreateStruct;
     int wmcreate;
-    short newwidth, newheight;
+    XSetWindowAttributes win_attr;
+    Window parentWindow;
+    int x_rel, y_rel;
+    LPPOPUPMENU lpbar;
 
 #ifdef DEBUG_WIN
-    printf( "CreateWindowEx: %s %s %d,%d %dx%d %08x\n",
-	    className, windowName, x, y, width, height, style );
+    printf( "CreateWindowEx: %d '%s' '%s' %d,%d %dx%d %08x %x\n",
+	   exStyle, className, windowName, x, y, width, height, style, parent);
 #endif
 
-    if (x == CW_USEDEFAULT) x = 0;
-    if (y == CW_USEDEFAULT) y = 0;
-    if (width == CW_USEDEFAULT) width = 600;
-    if (height == CW_USEDEFAULT) height = 400;
+    if (x == CW_USEDEFAULT) x = y = 0;
+    if (width == CW_USEDEFAULT)
+    {
+	width = 600;
+	height = 400;
+    }
     if (width == 0) width = 1;
     if (height == 0) height = 1;
 
@@ -201,11 +208,18 @@
 	if (!parent) return 0;
     }
     else if (style & WS_CHILD) return 0;  /* WS_CHILD needs a parent */
-
+    
     if (!(class = CLASS_FindClassByName( className, &classPtr ))) {
 	printf("CreateWindow BAD CLASSNAME '%s' !\n", className);
 	return 0;
 	}    
+
+      /* Correct the window style */
+
+    if (!(style & (WS_POPUP | WS_CHILD)))  /* Overlapped window */
+	style |= WS_CAPTION | WS_CLIPSIBLINGS;
+    if (exStyle & WS_EX_DLGMODALFRAME) style &= ~WS_THICKFRAME;
+
       /* Create the window structure */
 
     hwnd = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(WND)+classPtr->wc.cbWndExtra);
@@ -217,8 +231,8 @@
     wndPtr->hwndNext   = 0;
     wndPtr->hwndChild  = 0;
     wndPtr->dwMagic    = WND_MAGIC;
-    wndPtr->hwndParent = parent;
-    wndPtr->hwndOwner  = parent;  /* What else? */
+    wndPtr->hwndParent = (style & WS_CHILD) ? parent : 0;
+    wndPtr->hwndOwner  = (style & WS_CHILD) ? 0 : parent;
     wndPtr->hClass     = class;
     wndPtr->hInstance  = instance;
     wndPtr->rectWindow.left   = x;
@@ -239,9 +253,12 @@
     wndPtr->hCursor           = 0;
     wndPtr->hWndVScroll       = 0;
     wndPtr->hWndHScroll       = 0;
+    wndPtr->hWndMenuBar       = 0;
+    wndPtr->hWndCaption       = 0;
 
     if (classPtr->wc.cbWndExtra)
 	memset( wndPtr->wExtra, 0, classPtr->wc.cbWndExtra );
+    if (classPtr->wc.style & CS_DBLCLKS) wndPtr->flags |= WIN_DOUBLE_CLICKS;
     classPtr->cWindows++;
 
       /* Get class or window DC if needed */
@@ -261,156 +278,32 @@
 
     WIN_LinkWindow( hwnd, HWND_TOP );
 
-    if (!strcasecmp(className, "COMBOBOX"))
-    {
-	height = 16;
-    }
+      /* Create the X window */
 
-#ifdef USE_XLIB
-    {
-	XSetWindowAttributes win_attr;
-	Window parentWindow;
-	int x_rel, y_rel;
-	
-	win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask |
-	                      PointerMotionMask | ButtonPressMask |
-			      ButtonReleaseMask | StructureNotifyMask |
-			      FocusChangeMask | EnterWindowMask;
-	win_attr.override_redirect = /*True*/ False;
-	win_attr.colormap = COLOR_WinColormap;
-	if (style & WS_CHILD)
-	{
-	    parentWindow = parentPtr->window;
-	    x_rel = x + parentPtr->rectClient.left-parentPtr->rectWindow.left;
-	    y_rel = y + parentPtr->rectClient.top-parentPtr->rectWindow.top;
-	}
-	else
-	{
-	    parentWindow = DefaultRootWindow( XT_display );
-	    x_rel = x;
-	    y_rel = y;
-	}
-	wndPtr->window = XCreateWindow( XT_display, parentWindow,
-				        x_rel, y_rel, width, height, 0,
-				        CopyFromParent, InputOutput,
-				        CopyFromParent,
-				        CWEventMask | CWOverrideRedirect |
-				        CWColormap, &win_attr );
-	XStoreName( XT_display, wndPtr->window, windowName );
-    }
-#else
-    /* Create the widgets */
-
+    win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask |
+	                  PointerMotionMask | ButtonPressMask |
+			  ButtonReleaseMask | StructureNotifyMask |
+			  FocusChangeMask | EnterWindowMask;
+    win_attr.override_redirect = /*True*/ False;
+    win_attr.colormap = COLOR_WinColormap;
     if (style & WS_CHILD)
     {
-	wndPtr->shellWidget = 0;
-	if (style & (WS_BORDER | WS_DLGFRAME | WS_THICKFRAME))
-	{ 
-	    int borderCol = 0;
-	    if (COLOR_WinColormap == DefaultColormapOfScreen(XT_screen))
-		borderCol = BlackPixelOfScreen(XT_screen);
-	    wndPtr->winWidget = XtVaCreateManagedWidget(className,
-						    compositeWidgetClass,
-						    parentPtr->winWidget,
-						    XtNx, x,
-						    XtNy, y,
-						    XtNwidth, width,
-						    XtNheight, height,
-						    XtNborderColor, borderCol,
-						    XtNmappedWhenManaged, FALSE,
-						    NULL );
-	}
-	else
-	{
-	    wndPtr->winWidget = XtVaCreateManagedWidget(className,
-						    compositeWidgetClass,
-						    parentPtr->winWidget,
-						    XtNx, x,
-						    XtNy, y,
-						    XtNwidth, width,
-						    XtNheight, height,
-						    XtNborderWidth, 0,
-						    XtNmappedWhenManaged, FALSE,
-						    NULL );
-	}
+	parentWindow = parentPtr->window;
+	x_rel = x + parentPtr->rectClient.left - parentPtr->rectWindow.left;
+	y_rel = y + parentPtr->rectClient.top - parentPtr->rectWindow.top;
     }
     else
     {
-	wndPtr->shellWidget = XtVaAppCreateShell(windowName, 
-						 className,
-						 topLevelShellWidgetClass,
-						 XT_display,
-						 XtNx, x,
-						 XtNy, y,
-						 XtNcolormap, COLOR_WinColormap,
-						 XtNmappedWhenManaged, FALSE,
-						 NULL );
-	wndPtr->compositeWidget = XtVaCreateManagedWidget(className,
-						    formWidgetClass,
-						    wndPtr->shellWidget,
-						    NULL );
-/*	wndPtr->winWidget = wndPtr->compositeWidget; */
-	wndPtr->winWidget = wndPtr->shellWidget;
-	if (wndPtr->wIDmenu == 0)
-	{
-	    wndPtr->menuBarPtr = 
-		    MENU_CreateMenuBar(wndPtr->compositeWidget,
-				       instance, hwnd,
-				       classPtr->wc.lpszMenuName,
-				       width);
-	    if (wndPtr->menuBarPtr)
-		    wndPtr->wIDmenu = 
-			GlobalHandleFromPointer(wndPtr->menuBarPtr->firstItem);
-	}
-	else
-	{
-	    wndPtr->menuBarPtr = MENU_UseMenu(wndPtr->compositeWidget,
-						  instance, hwnd,
-						  wndPtr->wIDmenu, width);
-	}
-
-	if (wndPtr->menuBarPtr != NULL)
-	{
-	    wndPtr->winWidget = 
-		    XtVaCreateManagedWidget(className,
-					    compositeWidgetClass,
-					    wndPtr->compositeWidget,
-					    XtNwidth, width,
-					    XtNheight, height,
-					    XtNfromVert,
-					    wndPtr->menuBarPtr->menuBarWidget,
-					    XtNvertDistance, 4,
-					    NULL );
-	}
-	else
-	{
-	    wndPtr->winWidget = 
-		    XtVaCreateManagedWidget(className,
-					compositeWidgetClass,
-					wndPtr->compositeWidget,
-					XtNwidth, width,
-					XtNheight, height,
-					NULL );
-	}
+	parentWindow = DefaultRootWindow( display );
+	x_rel = x;
+	y_rel = y;
     }
-    if (wndPtr->shellWidget) XtRealizeWidget( wndPtr->shellWidget );
-    if (wndPtr->compositeWidget) XtRealizeWidget( wndPtr->compositeWidget );
-    XtRealizeWidget( wndPtr->winWidget );
-    wndPtr->window = XtWindow( wndPtr->winWidget );
-#endif  /* USE_XLIB */
-
-    if ((style & WS_VSCROLL) == WS_VSCROLL) {
-    	newheight = height - (((style & WS_HSCROLL) == WS_HSCROLL) ? 16 : 0);
-	wndPtr->hWndVScroll = CreateWindow("SCROLLBAR", "",
-		WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SBS_VERT,
-		width - 16, 0, 16, newheight, hwnd, 2, instance, 0L);
-	}
-    if ((style & WS_HSCROLL) == WS_HSCROLL) {
-    	newwidth = width - (((style & WS_VSCROLL) == WS_VSCROLL) ? 16 : 0);
-	wndPtr->hWndHScroll = CreateWindow("SCROLLBAR", "",
-		WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SBS_HORZ,
-		0, height - 16, newwidth, 16, hwnd, 3, instance, 0L);
-	}
+    wndPtr->window = XCreateWindow(display, parentWindow,
+				   x_rel, y_rel, width, height, 0,
+				   CopyFromParent, InputOutput, CopyFromParent,
+				   CWEventMask | CWOverrideRedirect |
+				   CWColormap, &win_attr );
+    XStoreName( display, wndPtr->window, windowName );
 
       /* Send the WM_CREATE message */
 	
@@ -452,30 +345,56 @@
 
     GlobalUnlock( hcreateStruct );
     GlobalFree( hcreateStruct );
-    
+
     if (wmcreate == -1)
     {
 	  /* Abort window creation */
 
-	if (parent) parentPtr->hwndChild = wndPtr->hwndNext;
-	else firstWindow = wndPtr->hwndNext;
-#ifdef USE_XLIB
-	XDestroyWindow( XT_display, wndPtr->window );
-#else	
-	if (wndPtr->shellWidget) XtDestroyWidget( wndPtr->shellWidget );
-	else XtDestroyWidget( wndPtr->winWidget );
-#endif
+	WIN_UnlinkWindow( hwnd );
+	XDestroyWindow( display, wndPtr->window );
 	if (wndPtr->flags & WIN_OWN_DC) DCE_FreeDCE( wndPtr->hdce );
 	classPtr->cWindows--;
 	USER_HEAP_FREE( hwnd );
 	return 0;
     }
 
-#ifdef USE_XLIB    
-    EVENT_AddHandlers( wndPtr->window, hwnd );
-#else
-    EVENT_AddHandlers( wndPtr->winWidget, hwnd );
-#endif
+      /* Create scrollbars */
+
+    if (windowName != NULL) SetWindowText(hwnd, windowName);
+    if ((style & WS_CAPTION) == WS_CAPTION) {
+	wndPtr->hWndCaption = CreateWindow("CAPTION", "",
+		WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
+		0, -20, width, 20, hwnd, 1, instance, 0L);
+	}
+    if (((style & WS_CHILD) != WS_CHILD) && (wndPtr->wIDmenu != 0)) {
+	lpbar = (LPPOPUPMENU) GlobalLock(wndPtr->wIDmenu);
+	if (lpbar != NULL) {
+	    lpbar->ownerWnd = hwnd;
+	    wndPtr->hWndMenuBar = CreateWindow("POPUPMENU", "",
+		WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
+		0, 0, width, 20, hwnd, 2, instance, (LPSTR)lpbar);
+	    }
+	}
+    if ((style & WS_VSCROLL) == WS_VSCROLL)
+    {
+	wndPtr->hWndVScroll = CreateWindow("SCROLLBAR", "",
+		WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SBS_VERT,
+		wndPtr->rectClient.right-wndPtr->rectClient.left, 0,
+                SYSMETRICS_CXVSCROLL,
+		wndPtr->rectClient.bottom-wndPtr->rectClient.top,
+                hwnd, 3, instance, 0L);
+    }
+    if ((style & WS_HSCROLL) == WS_HSCROLL)
+    {
+	wndPtr->hWndHScroll = CreateWindow("SCROLLBAR", "",
+		WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SBS_HORZ,
+		0, wndPtr->rectClient.bottom-wndPtr->rectClient.top,
+                wndPtr->rectClient.right-wndPtr->rectClient.left,
+		SYSMETRICS_CYHSCROLL,
+                hwnd, 4, instance, 0L);
+    }
+
+    EVENT_RegisterWindow( wndPtr->window, hwnd );
 
     WIN_SendParentNotify( hwnd, wndPtr, WM_CREATE );
     
@@ -515,12 +434,7 @@
 
       /* Destroy the window */
 
-#ifdef USE_XLIB
-    XDestroyWindow( XT_display, wndPtr->window );
-#else
-    if (wndPtr->shellWidget) XtDestroyWidget( wndPtr->shellWidget );
-    else XtDestroyWidget( wndPtr->winWidget );
-#endif
+    XDestroyWindow( display, wndPtr->window );
     if (wndPtr->flags & WIN_OWN_DC) DCE_FreeDCE( wndPtr->hdce );
     classPtr->cWindows--;
     USER_HEAP_FREE( hwnd );
@@ -588,49 +502,7 @@
  */
 BOOL SetMenu(HWND hwnd, HMENU hmenu)
 {
-#ifdef USE_XLIB
     return FALSE;
-#else
-    WND *wndPtr;
-    wndPtr = WIN_FindWndPtr(hwnd);
-    if (wndPtr == NULL)
-	return FALSE;
-
-    if (wndPtr->dwStyle & WS_CHILD) return FALSE;
-
-    if (wndPtr->menuBarPtr != NULL)
-    {
-	XtVaSetValues(wndPtr->winWidget, XtNfromVert, NULL, NULL);
-	MENU_CollapseMenu(wndPtr->menuBarPtr);
-    }
-    
-    wndPtr->menuBarPtr = MENU_UseMenu(wndPtr->compositeWidget, 
-				      wndPtr->hInstance, hwnd, hmenu, 
-				      wndPtr->rectClient.right -
-				      wndPtr->rectClient.left);
-
-    if (wndPtr->menuBarPtr != NULL)
-    {
-	XtVaSetValues(wndPtr->winWidget, 
-		      XtNfromVert, wndPtr->menuBarPtr->menuBarWidget, 
-		      XtNvertDistance, 4,
-		      NULL);
-    }
-    else
-    {
-	if (wndPtr->wIDmenu != 0)
-	{
-	    wndPtr->menuBarPtr = MENU_UseMenu(wndPtr->compositeWidget, 
-					      wndPtr->hInstance, hwnd, 
-					      wndPtr->wIDmenu, 
-					      wndPtr->rectClient.right -
-					      wndPtr->rectClient.left);
-	}
-	return FALSE;
-    }
-
-    return TRUE;
-#endif  /* USE_XLIB */
 }
 
 
diff --git a/windows/winpos.c b/windows/winpos.c
index 0b474e2..884f411 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -8,8 +8,7 @@
 
 #include "win.h"
 
-extern Display * XT_display;
-extern Screen * XT_screen;
+extern Display * display;
 
 
 /***********************************************************************
@@ -213,10 +212,8 @@
     RECT newWindowRect, newClientRect;
     WND *wndPtr;
     int calcsize_result = 0;
-#ifdef USE_XLIB
     XWindowChanges winChanges;
     int changeMask = 0;
-#endif
 
 #ifdef DEBUG_WIN
     printf( "SetWindowPos: %d %d %d,%d %dx%d 0x%x\n",
@@ -311,7 +308,7 @@
     }
     
       /* Perform the moving and resizing */
-#ifdef USE_XLIB
+
     if (!(winPos->flags & SWP_NOMOVE))
     {
 	WND * parentPtr;
@@ -343,31 +340,28 @@
 	}
 	changeMask |= CWStackMode;
     }
-    if (changeMask) XConfigureWindow( XT_display, wndPtr->window,
+    if (changeMask) XConfigureWindow( display, wndPtr->window,
 				      changeMask, &winChanges );
-#endif
 
     if (winPos->flags & SWP_SHOWWINDOW)
     {
 	wndPtr->dwStyle |= WS_VISIBLE;
-#ifdef USE_XLIB
-	XMapWindow( XT_display, wndPtr->window );
-#else		
-	if (wndPtr->shellWidget) XtMapWidget( wndPtr->shellWidget );
-	else XtMapWidget( wndPtr->winWidget );
-#endif
+	XMapWindow( display, wndPtr->window );
     }
     else if (winPos->flags & SWP_HIDEWINDOW)
     {
 	wndPtr->dwStyle &= ~WS_VISIBLE;
-#ifdef USE_XLIB
-	XUnmapWindow( XT_display, wndPtr->window );
-#else		
-	if (wndPtr->shellWidget) XtUnmapWidget( wndPtr->shellWidget );
-	else XtUnmapWidget( wndPtr->winWidget );
-#endif	
+	XUnmapWindow( display, wndPtr->window );
     }
 
+      /* Send WM_NCPAINT message if needed */
+    if ((winPos->flags & (SWP_FRAMECHANGED | SWP_SHOWWINDOW)) ||
+	(!(winPos->flags & SWP_NOSIZE)) ||
+	(!(winPos->flags & SWP_NOMOVE)) ||
+	(!(winPos->flags & SWP_NOACTIVATE)) ||
+	(!(winPos->flags & SWP_NOZORDER)))
+	    SendMessage( hwnd, WM_NCPAINT, 1, 0L );
+
       /* Finally send the WM_WINDOWPOSCHANGED message */
     wndPtr->rectWindow = newWindowRect;
     wndPtr->rectClient = newClientRect;
diff --git a/wine.ini b/wine.ini
index d9958be..a06ea5c 100644
--- a/wine.ini
+++ b/wine.ini
@@ -1,19 +1,32 @@
 [drives]
-a=/mnt/fd0
-c=/dos
-d=/usr/windows
-e=/home/bob/Wine/work
-f=/home/bob/test
+A=/mnt/fd0
+C=/dos
+D=/usr/windows
+E=/home/bob/Wine/work
+F=/home/bob/test
 
 [wine]
-windows=c:\windows
-system=c:\windows\system
-temp=c:\temp
-path=c:\windows;c:\windows\system;e:\;e:\test;f:\
+Windows=c:\windows
+System=c:\windows\system
+Temp=c:\temp
+Path=c:\windows;c:\windows\system;e:\;e:\test;f:\
+SystemResources=sysres.dll
+; SystemResources=
 
 [serialports]
-com1=/dev/cua0
-com2=/dev/cua1
+Com1=/dev/cua0
+Com2=/dev/cua1
 
 [parallelports]
-lpt1=/dev/lp0
+Lpt1=/dev/lp0
+
+[spy]
+;;;;; Uncomment the following line to activate spying to the console ;;;;;
+;File=CON
+
+;;;;; Uncomment the following line to activate spying to the spy.log ;;;;;
+;File=spy.log
+
+;;;;; The following options are not supported yet                    ;;;;;
+;Include=
+;Exclude=