Release 940510

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

	* [controls/scroll.c]
	Make thumbtrack button disappear if scroll box ratio < 3:1.
	Make arrow buttons rectangular if scroll box ratio < 2:1.
	Add code for SBS_TOPALIGN, SBS_BOTTOMALIGN, 
				SBS_LEFTALIGN & SBS_RIGHTALIGN.
	Bug fix in NC_CreateScrollBars(), no more bigbutt in calendar.exe... :-)

	* [loader/library.c] [loader/task.c] [misc/exec.c]
	Continue playing around trying to get a second task running.

	* [windows/mdi.c]
	Change OBM_CLOSE for OBM_OLD_CLOSE, a smaller dot button when maximized.

	* [everywhere]
	Adding previous works of the Apr 25, 94.

Tue May 10 18:09:14 1994 Erik Bos (erik@trashcan.hacktic.nl)

	* [if1632/mmsystem.spec] [misc/mmsystem.c] [include/mmsystem.h]
	Added Martin's mmsystem.dll stubs.

	* [misc/sound.c]
	Added remaining stubs for sound.dll.

	* [if1632/shell.spec] [misc/shell.c]
	Fixed prototypes (I found them in BC 4) and added ShellAbout()
	and AboutDlgProc().
diff --git a/ChangeLog b/ChangeLog
index 87a97a5..ed79d40 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,35 @@
 ----------------------------------------------------------------------
+May 9, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte)
+
+	* [controls/scroll.c]
+	Make thumbtrack button disappear if scroll box ratio < 3:1.
+	Make arrow buttons rectangular if scroll box ratio < 2:1.
+	Add code for SBS_TOPALIGN, SBS_BOTTOMALIGN, 
+				SBS_LEFTALIGN & SBS_RIGHTALIGN.
+	Bug fix in NC_CreateScrollBars(), no more bigbutt in calendar.exe... :-)
+
+	* [loader/library.c] [loader/task.c] [misc/exec.c]
+	Continue playing around trying to get a second task running.
+
+	* [windows/mdi.c]
+	Change OBM_CLOSE for OBM_OLD_CLOSE, a smaller dot button when maximized.
+
+	* [everywhere]
+	Adding previous works of the Apr 25, 94.
+
+Tue May 10 18:09:14 1994 Erik Bos (erik@trashcan.hacktic.nl)
+
+	* [if1632/mmsystem.spec] [misc/mmsystem.c] [include/mmsystem.h]
+	Added Martin's mmsystem.dll stubs.
+
+	* [misc/sound.c]
+	Added remaining stubs for sound.dll.
+
+	* [if1632/shell.spec] [misc/shell.c]
+	Fixed prototypes (I found them in BC 4) and added ShellAbout()
+	and AboutDlgProc().
+
+----------------------------------------------------------------------
 May 1, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte)
 
 	* [loader/signal.c]
@@ -39,7 +70,42 @@
 	path when given a simple file name.  Fixed GetSetProfile to allow
 	enumerating all key names when KeyName is null.
 
+Apr 25, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte)
+
+	* [objects/bitblt.c]
+	Add protection to BitBlt() & StretchBlt() for width or height = 0.
+
+	* [windows/nonclient.c]
+	Avoid painting in NC_DoNCPaint() if IsWindowVisible().
+	Simplify NC_TrackMouseMenuBar() because code moved to MenuFocusLoop().
+
+	* [windows/win.c]
+	CreateWindowEx() & DestroyWindow() now call respectively
+		AddWindowToTask() & RemoveWindowFromTask().
+	New empty stub for function AnyPopup().
+
+	* [loader/library.c]
+	Bug Fix : GetModuleFileName() now return full path filename.
+
+	* [include/menu.h] [controls/menu.c]
+	Add hText handle and remove obsolete MENUITEM struct members.
+	Add a ReleaseCapture() in SetMenu() when menubar changed while captured.
+	Add MenuMouseMove() MenuButtonUp() in function MenuFocusLoop().
+
+	* [misc/file.c]
+	GetTempFilename() now create a file.
+	_lcreate() use unix open (name, mode, perm), with perm=O666.
+
+	* [if1632/relay.c]
+	Remove temporarly builtin SHELL.DLL, Add MMSYSTEM.DLL in builtin list.
+
+	* New file [misc/mmsystem.c]
+	* New file [include/mmsystem.h]
+	* New file [if1632/mmsystem.spec]
+	Many, many empty stubs ... :-)
+
 ----------------------------------------------------------------------
+
 Wed Apr 20 14:53:35 1994  Bob Amstadt  (bob@pooh)
 
 	* [tools/build.c] [if1632/call.S] [if1632/Imakefile]
@@ -68,8 +134,6 @@
 	Move functions GetWindowTask(), GetNumTask(), EnumTaskWindows()
 		from 'loader/library.c'.
 
-	* [loader/library.c]
-
 	* [if1632/user.c] [if1632/kernel.c]
 	Put Atoms functions entries.
 
diff --git a/Imakefile b/Imakefile
index 89039f0..5f12665 100644
--- a/Imakefile
+++ b/Imakefile
@@ -1,7 +1,7 @@
 #include "autoconf.h"
 #include "Wine.tmpl"
 
-#if defined(i386FreeBsd)
+#if defined(i386FreeBsd) || defined(FreeBSDArchitecture)
 MAKE = gmake
 CC = gcc -D__FreeBSD__
 #endif
@@ -77,7 +77,7 @@
 #ifdef i386BsdArchitecture
 SYSLIBS = -ll -lm -li386 -lgnumalloc
 #endif
-#ifdef i386FreeBsd
+#if defined(i386FreeBsd) || defined(FreeBSDArchitecture)
 SYSLIBS = -ll -lm -lgnumalloc
 #endif
 #ifdef LinuxArchitecture
diff --git a/README b/README
index 668a0c6..40aadbc 100644
--- a/README
+++ b/README
@@ -171,6 +171,12 @@
 
 7. WHAT'S NEW
 
+WHAT'S NEW with Wine-940510: (see ChangeLog for details)
+	- debugger improvements
+	- mmsystem
+	- ShellAbout() and AboutDlgProc()
+	- and many many bug fixes!
+
 WHAT'S NEW with Wine-940505: (see ChangeLog for details)
 	- faster color_stretch()
 	- SetSysMenu(), GetCursor(), GetDesktopWindow()
diff --git a/controls/combo.c b/controls/combo.c
index 06fac4c..48d0519 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -5,6 +5,7 @@
  *
  */
 
+#define DEBUG_COMBO
 /*
 #define DEBUG_COMBO
 */
@@ -66,7 +67,8 @@
 		lphc = ComboGetStorageHeader(hwnd);
 		if (lphc == NULL) return 0;
 		if (wndPtr->dwStyle & CBS_SIMPLE)
-			lphc->hWndEdit = CreateWindow("EDIT", "", 
+/*			lphc->hWndEdit = CreateWindow("EDIT", "", */
+			lphc->hWndEdit = CreateWindow("STATIC", "", 
 				WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | SS_LEFT,
 				0, 0, width - bm.bmHeight, bm.bmHeight, 
 				hwnd, 1, wndPtr->hInstance, 0L);
@@ -114,7 +116,7 @@
 				    y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
 				    if (y != LB_ERR) {
 				    	SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str);
-				    	SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str);
+				    	SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str); 
 				    	}
 				    SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu,
 					        	MAKELONG(hwnd, CBN_SELCHANGE));
@@ -136,20 +138,26 @@
 		ReleaseDC(hwnd, hDC);
 		wndPtr = WIN_FindWndPtr(hwnd);
 		lphc = ComboGetStorageHeader(hwnd);
+		if (lphc == NULL) return 0;
 		lphc->dwState = lphc->dwState ^ CB_SHOWDROPDOWN;
 		if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN) {
 		    ShowWindow(lphc->hWndLBox, SW_SHOW);
 		    SetFocus(lphc->hWndLBox);
 			}
 		else {
-		    SetFocus(lphc->hWndEdit);
+			printf("before Combo Restore Focus !\n");
+			SetFocus(lphc->hWndEdit);
+			printf("before Combo List Hide !\n");
 			ShowWindow(lphc->hWndLBox, SW_HIDE);
+			printf("before Combo List GetCurSel !\n");
 			y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
 			if (y != LB_ERR) {
+				printf("before Combo List GetText !\n");
 				SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str);
 				SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str);
+				}
+			printf("End of Combo List Hide !\n");
 			}
-	    }
 		break;
     case WM_LBUTTONUP:
 		printf("Combo WM_LBUTTONUP wParam=%x lParam=%lX !\n", wParam, lParam);
@@ -163,6 +171,7 @@
    case WM_KEYDOWN:
 		wndPtr = WIN_FindWndPtr(hwnd);
 		lphc = ComboGetStorageHeader(hwnd);
+		if (lphc == NULL) return 0;
 		y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
 		count = SendMessage(lphc->hWndLBox, LB_GETCOUNT, 0, 0L);
 		printf("COMBOBOX // GetKeyState(VK_MENU)=%d\n", GetKeyState(VK_MENU));
@@ -214,13 +223,16 @@
 		GetClientRect(hwnd, &rect);
 		hDC = BeginPaint(hwnd, &paintstruct);
 		hMemDC = CreateCompatibleDC(hDC);
-		GetObject(hComboBit, sizeof(BITMAP), (LPSTR)&bm);
-		SelectObject(hMemDC, hComboBit);
-		BitBlt(hDC, rect.right - bm.bmWidth, 0, 
-		bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
+		if (hMemDC != 0 && hComboBit != 0) {
+			GetObject(hComboBit, sizeof(BITMAP), (LPSTR)&bm);
+			SelectObject(hMemDC, hComboBit);
+			BitBlt(hDC, rect.right - bm.bmWidth, 0, 
+			bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
+			}
 		DeleteDC(hMemDC);
 		EndPaint(hwnd, &paintstruct);
 		lphc = ComboGetStorageHeader(hwnd);
+		if (lphc == NULL) return 0;
 		InvalidateRect(lphc->hWndEdit, NULL, TRUE);
 		UpdateWindow(lphc->hWndEdit);
 		if ((lphc->dwState & CB_SHOWDROPDOWN) == CB_SHOWDROPDOWN) {
@@ -230,10 +242,12 @@
 		break;
 	case WM_SETFOCUS:
 		lphc = ComboGetStorageHeader(hwnd);
+		if (lphc == NULL) return 0;
 		SetFocus(lphc->hWndEdit);
 		break;
 	case WM_KILLFOCUS:
 		lphc = ComboGetStorageHeader(hwnd);
+		if (lphc == NULL) return 0;
 		ShowWindow(lphc->hWndLBox, SW_HIDE);
 		y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
 		if (y != LB_ERR) {
@@ -246,62 +260,76 @@
 		printf("CB_ADDSTRING '%s' !\n", (LPSTR)lParam);
 #endif
 		lphc = ComboGetStorageHeader(hwnd);
+		if (lphc == NULL) return 0;
 		return(SendMessage(lphc->hWndLBox, LB_ADDSTRING, wParam, lParam));
     case CB_GETLBTEXT:
 		printf("CB_GETLBTEXT #%u !\n", wParam);
 		lphc = ComboGetStorageHeader(hwnd);
+		if (lphc == NULL) return 0;
 		return(SendMessage(lphc->hWndLBox, LB_GETTEXT, wParam, lParam));
     case CB_GETLBTEXTLEN:
 		printf("CB_GETLBTEXTLEN !\n");
 		lphc = ComboGetStorageHeader(hwnd);
+		if (lphc == NULL) return 0;
 		return(SendMessage(lphc->hWndLBox, LB_GETTEXTLEN, wParam, lParam));
     case CB_INSERTSTRING:
 		printf("CB_INSERTSTRING '%s' !\n", (LPSTR)lParam);
 		lphc = ComboGetStorageHeader(hwnd);
+		if (lphc == NULL) return 0;
 		return(SendMessage(lphc->hWndLBox, LB_INSERTSTRING, wParam, lParam));
 	case CB_DELETESTRING:
 		printf("CB_DELETESTRING #%u !\n", wParam);
 		lphc = ComboGetStorageHeader(hwnd);
+		if (lphc == NULL) return 0;
 		return(SendMessage(lphc->hWndLBox, LB_DELETESTRING, wParam, 0L));
 	case CB_RESETCONTENT:
 		printf("CB_RESETCONTENT !\n");
 		lphc = ComboGetStorageHeader(hwnd);
+		if (lphc == NULL) return 0;
 		return(SendMessage(lphc->hWndLBox, LB_RESETCONTENT, 0, 0L));
     case CB_DIR:
 		printf("ComboBox CB_DIR !\n");
 		lphc = ComboGetStorageHeader(hwnd);
+		if (lphc == NULL) return 0;
 		return(SendMessage(lphc->hWndLBox, LB_DIR, wParam, lParam));
 	case CB_FINDSTRING:
 		lphc = ComboGetStorageHeader(hwnd);
 		return(SendMessage(lphc->hWndLBox, LB_FINDSTRING, wParam, lParam));
 	case CB_GETCOUNT:
 		lphc = ComboGetStorageHeader(hwnd);
+		if (lphc == NULL) return 0;
 		return(SendMessage(lphc->hWndLBox, LB_GETCOUNT, 0, 0L));
 	case CB_GETCURSEL:
 		printf("ComboBox CB_GETCURSEL !\n");
 		lphc = ComboGetStorageHeader(hwnd);
+		if (lphc == NULL) return 0;
 		return(SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L));
     case CB_SETCURSEL:
 		printf("ComboBox CB_SETCURSEL wParam=%X !\n", wParam);
 		lphc = ComboGetStorageHeader(hwnd);
+		if (lphc == NULL) return 0;
 		return(SendMessage(lphc->hWndLBox, LB_SETCURSEL, wParam, 0L));
 	case CB_GETEDITSEL:
 		printf("ComboBox CB_GETEDITSEL !\n");
 		lphc = ComboGetStorageHeader(hwnd);
+		if (lphc == NULL) return 0;
 /*        return(SendMessage(lphc->hWndEdit, EM_GETSEL, 0, 0L)); */
 		break;
 	case CB_SETEDITSEL:
 		printf("ComboBox CB_SETEDITSEL lParam=%lX !\n", lParam);
 		lphc = ComboGetStorageHeader(hwnd);
+		if (lphc == NULL) return 0;
 /*        return(SendMessage(lphc->hWndEdit, EM_SETSEL, 0, lParam)); */
 		break;
 	case CB_SELECTSTRING:
 		printf("ComboBox CB_SELECTSTRING !\n");
 		lphc = ComboGetStorageHeader(hwnd);
+		if (lphc == NULL) return 0;
 		break;
 	case CB_SHOWDROPDOWN:
 		printf("ComboBox CB_SHOWDROPDOWN !\n");
 		lphc = ComboGetStorageHeader(hwnd);
+		if (lphc == NULL) return 0;
 		lphc->dwState = lphc->dwState | CB_SHOWDROPDOWN;
 		if (wParam != 0) {
 			ShowWindow(lphc->hWndLBox, SW_SHOW);
@@ -316,16 +344,19 @@
     case CB_GETITEMDATA:
 		printf("ComboBox CB_GETITEMDATA wParam=%X !\n", wParam);
 		lphc = ComboGetStorageHeader(hwnd);
+		if (lphc == NULL) return 0;
 		return(SendMessage(lphc->hWndLBox, LB_GETITEMDATA, wParam, 0L));
         break;
     case CB_SETITEMDATA:
 		printf("ComboBox CB_SETITEMDATA wParam=%X lParam=%lX !\n", wParam, lParam);
 		lphc = ComboGetStorageHeader(hwnd);
+		if (lphc == NULL) return 0;
 		return(SendMessage(lphc->hWndLBox, LB_SETITEMDATA, wParam, lParam));
         break;
     case CB_LIMITTEXT:
 		printf("ComboBox CB_LIMITTEXT !\n");
 		lphc = ComboGetStorageHeader(hwnd);
+		if (lphc == NULL) return 0;
 /*        return(SendMessage(lphc->hWndEdit, EM_LIMITTEXT, wParam, 0L)); */
         break;
 
@@ -390,6 +421,7 @@
 			hDlg, lpPathSpec, nIDLBox, nIDStat, wType);
 	hWnd = GetDlgItem(hDlg, nIDLBox);
 	lphc = ComboGetStorageHeader(hWnd);
+	if (lphc == NULL) return 0;
 	SendMessage(lphc->hWndLBox, LB_RESETCONTENT, 0, 0L);
 	return SendMessage(lphc->hWndLBox, LB_DIR, wType, (DWORD)lpPathSpec);
 }
diff --git a/controls/listbox.c b/controls/listbox.c
index 70a6c54..cb5f14c 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -72,6 +72,7 @@
 #ifdef DEBUG_LISTBOX
 		printf("ListBox WM_CREATE %lX !\n", lphl);
 #endif
+		if (lphl == NULL) return 0;
 		createStruct = (CREATESTRUCT *)lParam;
 		if (HIWORD(createStruct->lpCreateParams) != 0)
 			lphl->hWndLogicParent = (HWND)HIWORD(createStruct->lpCreateParams);
@@ -91,7 +92,7 @@
 		return 0;
 	case WM_DESTROY:
 		lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-		if (lphl == 0) return 0;
+		if (lphl == NULL) return 0;
 		ListBoxResetContent(hwnd);
 		free(lphl);
 		*((LPHEADLIST *)&wndPtr->wExtra[1]) = 0;
@@ -189,7 +190,7 @@
 		SetFocus(hwnd);
 		SetCapture(hwnd);
 		lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
-	        if (lphl == NULL) return 0;
+		if (lphl == NULL) return 0;
 		lphl->PrevFocused = lphl->ItemFocused;
 	        y = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam));
 		if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) {
@@ -225,6 +226,7 @@
 			y = HIWORD(lParam);
 			if (y < 4) {
 				lphl = ListBoxGetStorageHeader(hwnd);
+				if (lphl == NULL) return 0;
 				if (lphl->FirstVisible > 1) {
 					lphl->FirstVisible--;
 					if (wndPtr->dwStyle & WS_VSCROLL)
@@ -237,6 +239,7 @@
 			GetClientRect(hwnd, &rect);
 			if (y > (rect.bottom - 4)) {
 				lphl = ListBoxGetStorageHeader(hwnd);
+				if (lphl == NULL) return 0;
 				if (lphl->FirstVisible < lphl->ItemsCount) {
 					lphl->FirstVisible++;
 					if (wndPtr->dwStyle & WS_VSCROLL)
@@ -248,6 +251,8 @@
 				}
 			if ((y > 0) && (y < (rect.bottom - 4))) {
 				if ((y < rectsel.top) || (y > rectsel.bottom)) {
+					lphl = ListBoxGetStorageHeader(hwnd);
+					if (lphl == NULL) return 0;
 					wRet = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam));
 					if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) {
 						lphl->ItemFocused = wRet;
@@ -722,7 +727,10 @@
 	MEASUREITEMSTRUCT *measure;
 	HANDLE hTemp = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(MEASUREITEMSTRUCT));
 	measure = (MEASUREITEMSTRUCT *) USER_HEAP_ADDR(hTemp);
-	if (measure == NULL) return;
+	if (measure == NULL) {
+		printf("ListBoxAskMeasure() // Bad allocation of Measure struct !\n");
+		return;
+		}
 	measure->CtlType = ODT_LISTBOX;
 	measure->CtlID = wndPtr->wIDmenu;
 	measure->itemID = lpls->dis.itemID;
@@ -747,6 +755,10 @@
     if (lphl == NULL) return LB_ERR;
     hTemp = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(LISTSTRUCT));
     lplsnew = (LPLISTSTRUCT) USER_HEAP_ADDR(hTemp);
+    if (lplsnew == NULL) {
+		printf("ListBoxAddString() // Bad allocation of new item !\n");
+		return LB_ERRSPACE;
+		}
     lpls = lphl->lpFirst;
     if (lpls != NULL) {
 	while(lpls->lpNext != NULL) {
@@ -822,6 +834,10 @@
 		}
 	hTemp = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(LISTSTRUCT));
 	lplsnew = (LPLISTSTRUCT) USER_HEAP_ADDR(hTemp);
+    if (lplsnew == NULL) {
+		printf("ListBoxAddString() // Bad allocation of new item !\n");
+		return LB_ERRSPACE;
+		}
 	ListBoxDefaultItem(hwnd, wndPtr, lphl, lplsnew);
 	lplsnew->hMem = hTemp;
 	lpls->lpNext = lplsnew;
@@ -981,9 +997,8 @@
     lphl->ItemFocused = 0;
     lphl->PrevFocused = 0;
     if ((wndPtr->dwStyle && LBS_NOTIFY) != 0)
-	SendMessage(wndPtr->hwndParent, WM_COMMAND, 
+	SendMessage(lphl->hWndLogicParent, WM_COMMAND, 
     	    wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE));
-
     if (wndPtr->dwStyle & WS_VSCROLL)
 	SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, TRUE);
     if ((wndPtr->dwStyle & WS_HSCROLL) && lphl->ItemsPerColumn != 0)
@@ -1007,7 +1022,7 @@
     UINT	i;
     lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
     if (lphl == NULL) return LB_ERR;
-    lphl->ItemFocused = LB_ERR;
+    lphl->ItemFocused = LB_ERR; 
     if (wIndex >= lphl->ItemsCount) return LB_ERR;
     lpls = lphl->lpFirst;
     if (lpls == NULL) return LB_ERR;
@@ -1023,7 +1038,7 @@
     }
     lphl->ItemFocused = wIndex;
     if ((wndPtr->dwStyle && LBS_NOTIFY) != 0)
-	SendMessage(wndPtr->hwndParent, WM_COMMAND, 
+	SendMessage(lphl->hWndLogicParent, WM_COMMAND, 
     	    wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE));
     return LB_ERR;
 }
@@ -1183,6 +1198,10 @@
 	LPHEADLIST lphl, LPLISTSTRUCT lpls)
 {
     RECT	rect;
+	if (wndPtr == NULL || lphl == NULL || lpls == NULL) {
+		printf("ListBoxDefaultItem() // Bad Pointers !\n");
+		return FALSE;
+		}
     GetClientRect(hwnd, &rect);
     SetRect(&lpls->dis.rcItem, 0, 0, rect.right, lphl->StdItemHeight);
     lpls->dis.CtlType = lphl->DrawCtlType;
@@ -1193,6 +1212,7 @@
     lpls->dis.hwndItem = hwnd;
     lpls->dis.hDC = 0;
     lpls->dis.itemData = 0;
+	return TRUE;
 }
 
 
diff --git a/controls/menu.c b/controls/menu.c
index 00cc095..9ef90f41 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -408,8 +408,6 @@
 	LPPOPUPMENU lppop2;
 	if (lppop == NULL) return;
 	lpitem = MenuFindItem(lppop, x, y, &wRet);
-	printf("MenuButtonDown hWnd=%04X x=%d y=%d // wRet=%d lpitem=%08X !\n", 
-											hWnd, x, y, wRet, lpitem);
 #ifdef DEBUG_MENU
 	printf("MenuButtonDown hWnd=%04X x=%d y=%d // wRet=%d lpitem=%08X !\n", 
 											hWnd, x, y, wRet, lpitem);
@@ -449,6 +447,10 @@
 					0, lppop->ownerWnd, (LPRECT)NULL);
 				}
 			GlobalUnlock(hSubMenu);
+			return TRUE;
+			}
+		if (lppop->BarFlag && !MenuHasFocus) {
+			MenuFocusLoop(hWnd, lppop);
 			}
 		return TRUE;
 		}
@@ -506,7 +508,8 @@
 	LPMENUITEM	lpitem, lpitem2;
 	LPPOPUPMENU lppop2;
 	WORD	wRet;
-	if ((wParam & MK_LBUTTON) != 0) {
+/*	if ((wParam & MK_LBUTTON) != 0) { */
+	if (GetKeyState(VK_LBUTTON)	!= 0) {
 		lpitem = MenuFindItem(lppop, x, y, &wRet);
 #ifdef DEBUG_MENU
 		printf("MenuMouseMove // x=%d y=%d // wRet=%d lpitem=%08X !\n", 
@@ -1319,12 +1322,13 @@
 		GlobalUnlock(hMenu);
 		return FALSE;
 		}
+	lpitem2->hItem = hNewItem;
 	lpitem2->item_flags = wFlags;
 	lpitem2->item_id = wItemID;
 	if (!(wFlags & (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK | 
 		MF_MENUBREAK | MF_SEPARATOR))) {
-/*		lpitem2->item_text = GlobalQuickAlloc(strlen(lpNewItem) + 1); */
-		lpitem2->item_text = GlobalLock(GlobalAlloc(GMEM_MOVEABLE, strlen(lpNewItem) + 1));
+		lpitem2->hText = GlobalAlloc(GMEM_MOVEABLE, strlen(lpNewItem) + 1);
+		lpitem2->item_text = GlobalLock(lpitem2->hText);
 		if (lpitem2->item_text != NULL)
 			strcpy(lpitem2->item_text, lpNewItem);
 		else {
@@ -1347,8 +1351,6 @@
 		if (lpitem2->next != NULL) lpitem2->next->prev = lpitem2;
 		lpitem->next = lpitem2;
 		}
-	lpitem2->child = NULL;
-	lpitem2->parent = NULL;
 	menu->nItems++;
 	GlobalUnlock(hMenu);
 	return TRUE;
@@ -1386,6 +1388,7 @@
 		return FALSE;
 		}
 	lpitem2 = (LPMENUITEM)GlobalLock(hNewItem);
+	lpitem2->hItem = hNewItem;
 	if (lpitem2 == NULL) {
 		GlobalFree(hNewItem);
 		GlobalUnlock(hMenu);
@@ -1395,8 +1398,8 @@
 	lpitem2->item_id = wItemID;
 	if (!(wFlags & (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK | 
 		MF_MENUBREAK | MF_SEPARATOR))) {
-/*        lpitem2->item_text = GlobalQuickAlloc(strlen(lpNewItem) + 1); */
-		lpitem2->item_text = GlobalLock(GlobalAlloc(GMEM_MOVEABLE, strlen(lpNewItem) + 1));
+		lpitem2->hText = GlobalAlloc(GMEM_MOVEABLE, strlen(lpNewItem) + 1);
+		lpitem2->item_text = GlobalLock(lpitem2->hText);
 		if (lpitem2->item_text != NULL)
 			strcpy(lpitem2->item_text, lpNewItem);
 		else {
@@ -1414,8 +1417,6 @@
 		lpitem->next = lpitem2;
 	lpitem2->prev = lpitem;
 	lpitem2->next = NULL;
-	lpitem2->child = NULL;
-	lpitem2->parent = NULL;
 	lpitem2->hCheckBit = (HBITMAP)NULL;
 	lpitem2->hUnCheckBit = (HBITMAP)NULL;
 	menu->nItems++;
@@ -1447,9 +1448,10 @@
 			if (!(lpitem->item_flags & 
 				(MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK | 
 				MF_MENUBREAK | MF_SEPARATOR))) {
-				GlobalFree((HANDLE)lpitem->item_text);
+				GlobalUnlock(lpitem->hText);
+				GlobalFree(lpitem->hText);
 				}
-			GlobalFree(lpitem);
+			GlobalFree(lpitem->hItem);
 			GlobalUnlock(hMenu);
 			return TRUE;
 			}
@@ -1485,11 +1487,12 @@
 		if (!(lpitem->item_flags & 
 			(MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK | 
 			MF_MENUBREAK | MF_SEPARATOR))) {
-			GlobalFree((HANDLE)lpitem->item_text);
+			GlobalUnlock(lpitem->hText);
+			GlobalFree(lpitem->hText);
 			}
 		if (lpitem->prev) lpitem->prev->next = lpitem->next;
 		if (lpitem->next) lpitem->next->prev = lpitem->prev;
-		GlobalFree(lpitem);
+		GlobalFree(lpitem->hItem);
 		GlobalUnlock(hMenu);
 		return TRUE;
 		}
@@ -1522,9 +1525,10 @@
 			if (!(lpitem->item_flags & 
 				(MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK | 
 				MF_MENUBREAK | MF_SEPARATOR))) {
-				GlobalFree((HANDLE)lpitem->item_text);
-/*				lpitem->item_text = GlobalQuickAlloc(strlen(lpNewItem) + 1); */
-				lpitem->item_text = GlobalLock(GlobalAlloc(GMEM_MOVEABLE, strlen(lpNewItem) + 1));
+				GlobalUnlock(lpitem->hText);
+				GlobalFree(lpitem->hText);
+				lpitem->hText = GlobalAlloc(GMEM_MOVEABLE, strlen(lpNewItem) + 1);
+				lpitem->item_text = GlobalLock(lpitem->hText);
 				printf("ModifyMenu %08X %08X '%s') !\n",
 					lpitem->item_text, lpNewItem, lpNewItem);
 				if (lpitem->item_text != NULL)
@@ -1689,13 +1693,26 @@
 				HideAllSubPopupMenu(lpmenu);
 				break;
 				}
+			ScreenToClient(hWnd, &msg.pt);
+			msg.pt.y += lpmenu->rect.bottom;
 			switch(msg.message) {
+				case WM_LBUTTONDOWN:
+				case WM_NCLBUTTONDOWN:
+				    SetCapture(hWnd);
+				    MenuButtonDown(hWnd, lpmenu, msg.pt.x, msg.pt.y);
+				    break;
+				case WM_LBUTTONUP:
+				case WM_NCLBUTTONUP:
+				    MenuButtonUp(hWnd, lpmenu, msg.pt.x, msg.pt.y);
+				    ReleaseCapture();
+				    break;
+				case WM_MOUSEMOVE:
+				case WM_NCMOUSEMOVE:
+				    MenuMouseMove(hWnd, lpmenu, msg.wParam, msg.pt.x, msg.pt.y);
+				    break;
 				case WM_KEYDOWN:
 				case WM_KEYUP:
 				case WM_CHAR:
-				case WM_LBUTTONDOWN:
-				case WM_LBUTTONUP:
-				case WM_MOUSEMOVE:
 					PopupMenuWndProc(hWnd, msg.message, msg.wParam, msg.lParam);
 				default:
 					DispatchMessage(&msg);
@@ -1967,12 +1984,15 @@
 		return FALSE;
 		}
 	lpmenu->ownerWnd = hWnd;
+	printf("SetMenu(%04X, %04X) // %04X\n", hWnd, hMenu, lpmenu->ownerWnd);
 	ResetHiliteFlags(lpmenu);
+	if (GetCapture() == hWnd) ReleaseCapture();
 	GlobalUnlock(hMenu);
 	return TRUE;
 }
 
 
+
 /**********************************************************************
  *			GetSubMenu		[USER.159]
  */
diff --git a/controls/scroll.c b/controls/scroll.c
index 1d05ee3..af1d12d 100644
--- a/controls/scroll.c
+++ b/controls/scroll.c
@@ -47,97 +47,115 @@
  */
 LONG ScrollBarWndProc( HWND hWnd, WORD message, WORD wParam, LONG lParam )
 {    
-    WORD	wRet;
-    short	x, y;
-    short	width, height;
-    WND  	*wndPtr;
-    LPHEADSCROLL lphs;
-    PAINTSTRUCT ps;
-    HDC		hDC;
-    BITMAP	bm;
-    RECT 	rect, rect2;
-    static RECT rectsel;
-    switch(message)
-    {
+	WORD	wRet;
+	short	x, y;
+	short	width, height;
+	WND  	*wndPtr;
+	LPHEADSCROLL lphs;
+	PAINTSTRUCT ps;
+	HDC		hDC;
+	BITMAP	bm;
+	RECT 	rect, rect2;
+	LPCREATESTRUCT lpCreat;
+	static RECT rectsel;
+	switch(message) {
     case WM_CREATE:
-	CreateScrollBarStruct(hWnd);
+		lpCreat = (LPCREATESTRUCT)lParam;
+		if (lpCreat->style & SBS_VERT) {
+			if (lpCreat->style & SBS_LEFTALIGN)
+				SetWindowPos(hWnd, 0, 0, 0, 16, lpCreat->cy, 
+								SWP_NOZORDER | SWP_NOMOVE);
+			if (lpCreat->style & SBS_RIGHTALIGN)
+				SetWindowPos(hWnd, 0, lpCreat->x + lpCreat->cx - 16, 
+						lpCreat->y, 16, lpCreat->cy, SWP_NOZORDER);
+			}
+		if (lpCreat->style & SBS_HORZ) {
+			if (lpCreat->style & SBS_TOPALIGN)
+				SetWindowPos(hWnd, 0, 0, 0, lpCreat->cx, 16,
+								SWP_NOZORDER | SWP_NOMOVE);
+			if (lpCreat->style & SBS_BOTTOMALIGN)
+				SetWindowPos(hWnd, 0, lpCreat->x, 
+						lpCreat->y + lpCreat->cy - 16, 
+						lpCreat->cx, 16, SWP_NOZORDER);
+			}
+		CreateScrollBarStruct(hWnd);
 #ifdef DEBUG_SCROLL
-        printf("ScrollBar Creation !\n");
+		printf("ScrollBar Creation !\n");
 #endif
-	return 0;
-    case WM_DESTROY:
-	lphs = ScrollBarGetWindowAndStorage(hWnd, &wndPtr);
-	if (lphs == 0) return 0;
+		return 0;
+	case WM_DESTROY:
+		lphs = ScrollBarGetWindowAndStorage(hWnd, &wndPtr);
+		if (lphs == 0) return 0;
 #ifdef DEBUG_SCROLL
-        printf("ScrollBar WM_DESTROY %lX !\n", lphs);
+		printf("ScrollBar WM_DESTROY %lX !\n", lphs);
 #endif
-	free(lphs);
-	*((LPHEADSCROLL *)&wndPtr->wExtra[1]) = 0;
-	return 0;
+		free(lphs);
+		*((LPHEADSCROLL *)&wndPtr->wExtra[1]) = 0;
+		return 0;
 	
-    case WM_LBUTTONDOWN:
-	SetCapture(hWnd);
-	ScrollBarButtonDown(hWnd, SB_CTL, LOWORD(lParam), HIWORD(lParam));
-	break;
-    case WM_LBUTTONUP:
-	ReleaseCapture();
-	ScrollBarButtonUp(hWnd, SB_CTL, LOWORD(lParam), HIWORD(lParam));
-	break;
+	case WM_LBUTTONDOWN:
+		SetCapture(hWnd);
+		ScrollBarButtonDown(hWnd, SB_CTL, LOWORD(lParam), HIWORD(lParam));
+		break;
+	case WM_LBUTTONUP:
+		ReleaseCapture();
+		ScrollBarButtonUp(hWnd, SB_CTL, LOWORD(lParam), HIWORD(lParam));
+		break;
 
-    case WM_MOUSEMOVE:
-	ScrollBarMouseMove(hWnd, SB_CTL, wParam, LOWORD(lParam), HIWORD(lParam));
-	break;
-    case WM_KEYDOWN:
-    case WM_KEYUP:
-    case WM_CHAR:
-	lphs = ScrollBarGetWindowAndStorage(hWnd, &wndPtr);
-	return(SendMessage(wndPtr->hwndParent, message, wParam, lParam));
+	case WM_MOUSEMOVE:
+		ScrollBarMouseMove(hWnd, SB_CTL, wParam, LOWORD(lParam), HIWORD(lParam));
+		break;
+	case WM_KEYDOWN:
+	case WM_KEYUP:
+	case WM_CHAR:
+		lphs = ScrollBarGetWindowAndStorage(hWnd, &wndPtr);
+		return(SendMessage(wndPtr->hwndParent, message, wParam, lParam));
 
     case WM_TIMER:
 #ifdef DEBUG_SCROLL
-        printf("ScrollBar WM_TIMER wParam=%X lParam=%lX !\n", wParam, lParam);
+		printf("ScrollBar WM_TIMER wParam=%X lParam=%lX !\n", wParam, lParam);
 #endif
-	lphs = ScrollBarGetWindowAndStorage(hWnd, &wndPtr);
-	KillTimer(hWnd, wParam);
-	switch(lphs->ButtonDown) {
-	    case 0:
-		lphs->TimerPending = FALSE;
+		lphs = ScrollBarGetWindowAndStorage(hWnd, &wndPtr);
+		KillTimer(hWnd, wParam);
+		switch(lphs->ButtonDown) {
+			case 0:
+				lphs->TimerPending = FALSE;
+				return 0;
+			case 1:
+			case 3:
+				SendMessage(wndPtr->hwndParent, lphs->Direction, 
+				SB_LINEUP, MAKELONG(0, hWnd));
+				break;
+			case 2:
+			case 4:
+				SendMessage(wndPtr->hwndParent, lphs->Direction, 
+				SB_LINEDOWN, MAKELONG(0, hWnd));
+				break;
+			case 5:
+				SendMessage(wndPtr->hwndParent, lphs->Direction, 
+				SB_PAGEUP, MAKELONG(0, hWnd));
+				break;
+			case 6:
+				SendMessage(wndPtr->hwndParent, lphs->Direction, 
+				SB_PAGEDOWN, MAKELONG(0, hWnd));
+				break;
+			}
+		SetTimer(hWnd, 1, 100, NULL);
 		return 0;
-	    case 1:
-	    case 3:
-		SendMessage(wndPtr->hwndParent, lphs->Direction, 
-			SB_LINEUP, MAKELONG(0, hWnd));
-		break;
-	    case 2:
-	    case 4:
-		SendMessage(wndPtr->hwndParent, lphs->Direction, 
-			SB_LINEDOWN, MAKELONG(0, hWnd));
-		break;
-	    case 5:
-		SendMessage(wndPtr->hwndParent, lphs->Direction, 
-			SB_PAGEUP, MAKELONG(0, hWnd));
-		break;
-	    case 6:
-		SendMessage(wndPtr->hwndParent, lphs->Direction, 
-			SB_PAGEDOWN, MAKELONG(0, hWnd));
-		break;
-	    }
-	SetTimer(hWnd, 1, 100, NULL);
-	return 0;
 
-    case WM_PAINT:
-	hDC = BeginPaint(hWnd, &ps);
-	lphs = ScrollBarGetStorageHeader(hWnd);
-	if (lphs != NULL) {
-	    GetClientRect(hWnd, &rect);
-	    StdDrawScrollBar(hWnd, hDC, SB_CTL, &rect, lphs);
-	    }
-	EndPaint(hWnd, &ps);
-	break;
-    default:
-	return DefWindowProc( hWnd, message, wParam, lParam );
-    }
-return(0);
+	case WM_PAINT:
+		hDC = BeginPaint(hWnd, &ps);
+		lphs = ScrollBarGetStorageHeader(hWnd);
+		if (lphs != NULL) {
+			GetClientRect(hWnd, &rect);
+			StdDrawScrollBar(hWnd, hDC, SB_CTL, &rect, lphs);
+			}
+		EndPaint(hWnd, &ps);
+		break;
+	default:
+		return DefWindowProc( hWnd, message, wParam, lParam );
+	}
+	return(0);
 }
 
 
@@ -174,50 +192,42 @@
 #endif
 	if (lphs->Direction == WM_VSCROLL) {
 		width = rect.right - rect.left;
-		if (y < (lphs->CurPix + width)) {
-			if (y < width) {
-				lphs->ButtonDown = 1;
-				CopyRect(&rect2, &rect);
-				rect2.bottom = rect2.top + width;
-				InvalidateRect(lphs->hWndOwner, &rect2, TRUE);
+		if (y <= lphs->rectUp.bottom) {
+			lphs->ButtonDown = 1;
+			InvalidateRect(lphs->hWndOwner, &lphs->rectUp, TRUE); 
 #ifdef DEBUG_SCROLL
-				printf("ScrollBarButtonDown send SB_LINEUP\n");
+			printf("ScrollBarButtonDown send SB_LINEUP\n");
 #endif
-				SendMessage(hWndParent, lphs->Direction, 
-									SB_LINEUP, dwOwner);
-				}
-			else {
-				lphs->ButtonDown = 5;
-#ifdef DEBUG_SCROLL
-				printf("ScrollBarButtonDown send SB_PAGEUP\n");
-#endif
-				SendMessage(hWndParent, lphs->Direction, 
-									SB_PAGEUP, dwOwner);
-				}
+			SendMessage(hWndParent, lphs->Direction, 
+								SB_LINEUP, dwOwner);
 			}
-		if (y > (lphs->CurPix + (width << 1))) {
-			if (y > (rect.bottom - rect.top - width)) {
-				lphs->ButtonDown = 2;
-				CopyRect(&rect2, &rect);
-				rect2.top = rect2.bottom - width;
-				InvalidateRect(lphs->hWndOwner, &rect2, TRUE);
+		if (y >= lphs->rectDown.top) {
+			lphs->ButtonDown = 2;
+			InvalidateRect(lphs->hWndOwner, &lphs->rectDown, TRUE); 
 #ifdef DEBUG_SCROLL
-				printf("ScrollBarButtonDown send SB_LINEDOWN\n");
+			printf("ScrollBarButtonDown send SB_LINEDOWN\n");
 #endif
-				SendMessage(hWndParent, lphs->Direction, 
-								SB_LINEDOWN, dwOwner);
-				}
-			else {
-				lphs->ButtonDown = 6;
-#ifdef DEBUG_SCROLL
-				printf("ScrollBarButtonDown send SB_PAGEDOWN\n");
-#endif
-				SendMessage(hWndParent, lphs->Direction, 
-								SB_PAGEDOWN, dwOwner);
-				}
+			SendMessage(hWndParent, lphs->Direction, 
+							SB_LINEDOWN, dwOwner);
 			}
-		if ((y > (lphs->CurPix + width)) &&
-		(y < (lphs->CurPix + (width << 1)))) {
+		if (y > lphs->rectUp.bottom && y < (lphs->CurPix + width)) {
+			lphs->ButtonDown = 5;
+#ifdef DEBUG_SCROLL
+			printf("ScrollBarButtonDown send SB_PAGEUP\n");
+#endif
+			SendMessage(hWndParent, lphs->Direction, 
+								SB_PAGEUP, dwOwner);
+			}
+		if (y < lphs->rectDown.top && y > (lphs->CurPix + (width << 1))) {
+			lphs->ButtonDown = 6;
+#ifdef DEBUG_SCROLL
+			printf("ScrollBarButtonDown send SB_PAGEDOWN\n");
+#endif
+			SendMessage(hWndParent, lphs->Direction, 
+							SB_PAGEDOWN, dwOwner);
+			}
+		if (lphs->MaxPix > 0 && y > (lphs->CurPix + width) &&
+			y < (lphs->CurPix + (width << 1))) {
 			lphs->ThumbActive = TRUE;
 #ifdef DEBUG_SCROLL
 			printf("THUMB DOWN !\n");
@@ -226,50 +236,42 @@
 		}
 	else {
 		height = rect.bottom - rect.top;
-		if (x < (lphs->CurPix + height)) {
-			if (x < height) {
-				lphs->ButtonDown = 3;
-				CopyRect(&rect2, &rect);
-				rect2.right = rect2.left + height;
-				InvalidateRect(lphs->hWndOwner, &rect2, TRUE);
+		if (x <= lphs->rectUp.right) {
+			lphs->ButtonDown = 3;
+			InvalidateRect(lphs->hWndOwner, &lphs->rectUp, TRUE); 
 #ifdef DEBUG_SCROLL
-				printf("ScrollBarButtonDown send SB_LINEUP\n");
+			printf("ScrollBarButtonDown send SB_LINEUP\n");
 #endif
-				SendMessage(hWndParent, lphs->Direction, 
-									SB_LINEUP, dwOwner);
-				}
-			else {
-				lphs->ButtonDown = 5;
-#ifdef DEBUG_SCROLL
-				printf("ScrollBarButtonDown send SB_PAGEUP\n");
-#endif
-				SendMessage(hWndParent, lphs->Direction, 
-									SB_PAGEUP, dwOwner);
-				}
+			SendMessage(hWndParent, lphs->Direction, 
+								SB_LINEUP, dwOwner);
 			}
-		if (x > (lphs->CurPix + (height << 1))) {
-			if (x > (rect.right - rect.left - height)) {
-				lphs->ButtonDown = 4;
-				CopyRect(&rect2, &rect);
-				rect2.left = rect2.right - height;
-				InvalidateRect(lphs->hWndOwner, &rect2, TRUE);
+		if (x >= lphs->rectDown.left) {
+			lphs->ButtonDown = 4;
+			InvalidateRect(lphs->hWndOwner, &lphs->rectDown, TRUE); 
 #ifdef DEBUG_SCROLL
-				printf("ScrollBarButtonDown send SB_LINEDOWN\n");
+			printf("ScrollBarButtonDown send SB_LINEDOWN\n");
 #endif
-				SendMessage(hWndParent, lphs->Direction, 
-								SB_LINEDOWN, dwOwner);
-				}
-			else {
-				lphs->ButtonDown = 6;
-#ifdef DEBUG_SCROLL
-				printf("ScrollBarButtonDown send SB_PAGEDOWN\n");
-#endif
-				SendMessage(hWndParent, lphs->Direction, 
-								SB_PAGEDOWN, dwOwner);
-				}
+			SendMessage(hWndParent, lphs->Direction, 
+							SB_LINEDOWN, dwOwner);
 			}
-		if ((x > (lphs->CurPix + height)) &&
-		(x < (lphs->CurPix + (height << 1)))) {
+		if (x > lphs->rectUp.right && x < (lphs->CurPix + height)) {
+			lphs->ButtonDown = 5;
+#ifdef DEBUG_SCROLL
+			printf("ScrollBarButtonDown send SB_PAGEUP\n");
+#endif
+			SendMessage(hWndParent, lphs->Direction, 
+								SB_PAGEUP, dwOwner);
+			}
+		if (x < lphs->rectDown.left && x > (lphs->CurPix + (height << 1))) {
+			lphs->ButtonDown = 6;
+#ifdef DEBUG_SCROLL
+			printf("ScrollBarButtonDown send SB_PAGEDOWN\n");
+#endif
+			SendMessage(hWndParent, lphs->Direction, 
+							SB_PAGEDOWN, dwOwner);
+			}
+		if (lphs->MaxPix > 0 && x > (lphs->CurPix + height) &&
+			x < (lphs->CurPix + (height << 1))) {
 			lphs->ThumbActive = TRUE;
 #ifdef DEBUG_SCROLL
 			printf("THUMB DOWN !\n");
@@ -298,8 +300,8 @@
 	lphs->ThumbActive = FALSE;
 	if (lphs->ButtonDown != 0) {
 		lphs->ButtonDown = 0;
-		GetClientRect(lphs->hWndOwner, &rect);
 		if (nBar == SB_CTL) {
+			GetClientRect(lphs->hWndOwner, &rect);
 			InvalidateRect(lphs->hWndOwner, &rect, TRUE);
 			UpdateWindow(lphs->hWndOwner);
 			}
@@ -384,100 +386,118 @@
 
 void StdDrawScrollBar(HWND hWnd, HDC hDC, int nBar, LPRECT lprect, LPHEADSCROLL lphs)
 {
-    HWND	hWndParent;
-    HBRUSH 	hBrush;
-    HDC 	hMemDC;
-    BITMAP	bm;
-    RECT 	rect;
-    UINT  	i, w, h, siz;
-    char	C[128];
-    if (lphs == NULL) return;
+	HWND	hWndParent;
+	HBRUSH 	hBrush;
+	HDC 	hMemDC;
+	BITMAP	bm;
+	RECT 	rect;
+	UINT  	i, w, w2, h, h2, siz;
+	char	C[128];
+	if (lphs == NULL) return;
 #ifdef DEBUG_SCROLL
-    if (lphs->Direction == WM_VSCROLL)
-        printf("StdDrawScrollBar Vertical left=%d top=%d right=%d bottom=%d !\n", 
-        	lprect->left, lprect->top, lprect->right, lprect->bottom);
-    else
-        printf("StdDrawScrollBar Horizontal left=%d top=%d right=%d bottom=%d !\n", 
-        	lprect->left, lprect->top, lprect->right, lprect->bottom);
+	printf("StdDrawScrollBar nBar=%04X !\n", nBar);
+	if (lphs->Direction == WM_VSCROLL)
+		printf("StdDrawScrollBar Vertical left=%d top=%d right=%d bottom=%d !\n", 
+			lprect->left, lprect->top, lprect->right, lprect->bottom);
+	else
+		printf("StdDrawScrollBar Horizontal left=%d top=%d right=%d bottom=%d !\n", 
+			lprect->left, lprect->top, lprect->right, lprect->bottom);
 #endif
-    if (nBar == SB_CTL)
-	hWndParent = GetParent(hWnd);
-    else
-	hWndParent = lphs->hWndOwner;
-    hBrush = SendMessage(hWndParent, WM_CTLCOLOR, (WORD)hDC,
-			MAKELONG(hWnd, CTLCOLOR_SCROLLBAR));
-    if (hBrush == (HBRUSH)NULL)  hBrush = GetStockObject(LTGRAY_BRUSH);
-    CopyRect(&lphs->rect, lprect);
-    CopyRect(&rect, lprect);
-    w = rect.right - rect.left;
-    h = rect.bottom - rect.top;
-    if (lphs->Direction == WM_VSCROLL)
-	lphs->MaxPix = h - 3 * w;
-    else
-	lphs->MaxPix = w - 3 * h;
-    if (lphs->MaxVal != lphs->MinVal)
+	if (nBar == SB_CTL)
+		hWndParent = GetParent(hWnd);
+	else
+		hWndParent = lphs->hWndOwner;
+	hBrush = SendMessage(hWndParent, WM_CTLCOLOR, (WORD)hDC,
+					MAKELONG(hWnd, CTLCOLOR_SCROLLBAR));
+	if (hBrush == (HBRUSH)NULL)  hBrush = GetStockObject(LTGRAY_BRUSH);
+	CopyRect(&lphs->rect, lprect);
+	CopyRect(&lphs->rectUp, lprect);
+	CopyRect(&lphs->rectDown, lprect);
+	CopyRect(&rect, lprect);
+	w = rect.right - rect.left;
+	h = rect.bottom - rect.top;
+	if (w == 0 || h == 0) return;
+	if (lphs->Direction == WM_VSCROLL) {
+		if (h > 3 * w)
+			lphs->MaxPix = h - 3 * w;
+		else
+			lphs->MaxPix = 0;
+		if (h > 2 * w)
+			h2 = w;
+		else
+			h2 = (h - 4) / 2;
+		lphs->rectUp.bottom = h2;
+		lphs->rectDown.top = rect.bottom - h2;
+		}
+	else {
+		if (w > 3 * h)
+			lphs->MaxPix = w - 3 * h;
+		else
+			lphs->MaxPix = 0;
+		if (w > 2 * h)
+			w2 = h;
+		else
+			w2 = (w - 4) / 2;
+		lphs->rectUp.right = w2;
+		lphs->rectDown.left = rect.right - w2;
+		}
+	if (lphs->MaxVal != lphs->MinVal)
 	lphs->CurPix = lphs->MaxPix * (abs((short)lphs->CurVal) - abs(lphs->MinVal)) / 
     		(abs(lphs->MaxVal) - abs(lphs->MinVal));
-    if (lphs->CurPix > lphs->MaxPix)  lphs->CurPix = lphs->MaxPix;
-    hMemDC = CreateCompatibleDC(hDC);
-    if (lphs->Direction == WM_VSCROLL) {
-	GetObject(hUpArrow, sizeof(BITMAP), (LPSTR)&bm);
-	if (lphs->ButtonDown == 1)
-	    SelectObject(hMemDC, hUpArrowD);
-	else
-	    SelectObject(hMemDC, hUpArrow);
-	StretchBlt(hDC, rect.left, rect.top, w, w, hMemDC, 
+	if (lphs->CurPix > lphs->MaxPix)  lphs->CurPix = lphs->MaxPix;
+	hMemDC = CreateCompatibleDC(hDC);
+	if (lphs->Direction == WM_VSCROLL) {
+		GetObject(hUpArrow, sizeof(BITMAP), (LPSTR)&bm);
+		if (lphs->ButtonDown == 1)
+			SelectObject(hMemDC, hUpArrowD);
+		else
+			SelectObject(hMemDC, hUpArrow);
+		StretchBlt(hDC, rect.left, rect.top, w, h2, hMemDC, 
 			0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
-	GetObject(hDnArrow, sizeof(BITMAP), (LPSTR)&bm);
-	if (lphs->ButtonDown == 2)
-	    SelectObject(hMemDC, hDnArrowD);
-	else
-	    SelectObject(hMemDC, hDnArrow);
-	StretchBlt(hDC, rect.left, rect.bottom - w, w, w, hMemDC, 
+		GetObject(hDnArrow, sizeof(BITMAP), (LPSTR)&bm);
+		if (lphs->ButtonDown == 2)
+			SelectObject(hMemDC, hDnArrowD);
+		else
+			SelectObject(hMemDC, hDnArrow);
+		StretchBlt(hDC, rect.left, rect.bottom - h2, w, h2, hMemDC, 
 			0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
-	rect.top += w;
-	rect.bottom -= w;
-	}
-    else {
-	GetObject(hLfArrow, sizeof(BITMAP), (LPSTR)&bm);
-	if (lphs->ButtonDown == 3)
-	    SelectObject(hMemDC, hLfArrowD);
-	else
-	    SelectObject(hMemDC, hLfArrow);
-	StretchBlt(hDC, rect.left, rect.top, h, h, hMemDC, 
+		rect.top += h2;
+		rect.bottom -= h2;
+		}
+	else {
+		GetObject(hLfArrow, sizeof(BITMAP), (LPSTR)&bm);
+		if (lphs->ButtonDown == 3)
+			SelectObject(hMemDC, hLfArrowD);
+		else
+			SelectObject(hMemDC, hLfArrow);
+		StretchBlt(hDC, rect.left, rect.top, w2, h, hMemDC, 
 			0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
-	GetObject(hRgArrow, sizeof(BITMAP), (LPSTR)&bm);
-	if (lphs->ButtonDown == 4)
-	    SelectObject(hMemDC, hRgArrowD);
-	else
-	    SelectObject(hMemDC, hRgArrow);
-	StretchBlt(hDC, rect.right - h, rect.top, h, h, hMemDC, 
+		GetObject(hRgArrow, sizeof(BITMAP), (LPSTR)&bm);
+		if (lphs->ButtonDown == 4)
+			SelectObject(hMemDC, hRgArrowD);
+		else
+			SelectObject(hMemDC, hRgArrow);
+		StretchBlt(hDC, rect.right - w2, rect.top, w2, h, hMemDC, 
 			0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
-	rect.left += h;
-	rect.right -= h;
-	}
-    DeleteDC(hMemDC);
-    FillRect(hDC, &rect, hBrush);
-    if (lphs->Direction == WM_VSCROLL)
-	SetRect(&rect, rect.left, rect.top + lphs->CurPix, 
-		rect.left + w, rect.top + lphs->CurPix + w);
-    else
-	SetRect(&rect, rect.left + lphs->CurPix, rect.top, 
-		rect.left + lphs->CurPix + h, rect.top + h);
-/*
-    if (lphs->Direction == WM_VSCROLL)
-	SetRect(&rect, rect.left, rect.top + lphs->CurPix + w, 
-		rect.left + w, rect.top + lphs->CurPix + (w << 1));
-    else
-	SetRect(&rect, rect.left + lphs->CurPix + h, rect.top, 
-		rect.left + lphs->CurPix + (h << 1), rect.top + h);
-*/
-    FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH));
-    InflateRect(&rect, -1, -1);
-    FillRect(hDC, &rect, GetStockObject(LTGRAY_BRUSH));
-    DrawReliefRect(hDC, rect, 2, 0);
-    InflateRect(&rect, -3, -3);
-    DrawReliefRect(hDC, rect, 1, 1);
+		rect.left += w2;
+		rect.right -= w2;
+		}
+	DeleteDC(hMemDC);
+	FillRect(hDC, &rect, hBrush);
+	if (lphs->MaxPix != 0) {
+		if (lphs->Direction == WM_VSCROLL)
+			SetRect(&rect, rect.left, rect.top + lphs->CurPix, 
+				rect.left + w, rect.top + lphs->CurPix + h2);
+		else
+			SetRect(&rect, rect.left + lphs->CurPix, rect.top, 
+				rect.left + lphs->CurPix + w2, rect.top + h);
+		FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH));
+		InflateRect(&rect, -1, -1);
+		FillRect(hDC, &rect, GetStockObject(LTGRAY_BRUSH));
+		DrawReliefRect(hDC, rect, 2, 0);
+		InflateRect(&rect, -3, -3);
+		DrawReliefRect(hDC, rect, 1, 1);
+		}
 }
 
 
@@ -508,75 +528,88 @@
 
 LPHEADSCROLL AllocScrollBar(DWORD dwStyle, int width, int height)
 {
-    LPHEADSCROLL lphs;
-    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));
-    lphs = (LPHEADSCROLL)malloc(sizeof(HEADSCROLL));
-    if (lphs == 0) {
-    	printf("Bad Memory Alloc on ScrollBar !\n");
-    	return NULL;
-    	}
-    lphs->ThumbActive = FALSE;
-    lphs->TimerPending = FALSE;
-    lphs->ButtonDown = 0;
-    lphs->MinVal = 0;
-    lphs->MaxVal = 100;
-    lphs->CurVal = 0;
-    lphs->CurPix = 0;
-    if (dwStyle & WS_VSCROLL) {
-	lphs->MaxPix = height - 3 * width;
-	lphs->Direction = WM_VSCROLL;
-	}
-    else {
-	lphs->MaxPix = width - 3 * height;
-	lphs->Direction = WM_HSCROLL;
-	}
-    if (lphs->MaxPix < 1)  lphs->MaxPix = 1;
-    return lphs;
+	LPHEADSCROLL lphs;
+	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));
+	lphs = (LPHEADSCROLL)malloc(sizeof(HEADSCROLL));
+	if (lphs == 0) {
+		printf("Bad Memory Alloc on ScrollBar !\n");
+		return NULL;
+		}
+	lphs->ThumbActive = FALSE;
+	lphs->TimerPending = FALSE;
+	lphs->ButtonDown = 0;
+	lphs->MinVal = 0;
+	lphs->MaxVal = 100;
+	lphs->CurVal = 0;
+	lphs->CurPix = 0;
+	SetRect(&lphs->rect, 0, 0, width, height);
+	if (dwStyle & WS_VSCROLL) {
+		if (height > 3 * width)
+			lphs->MaxPix = height - 3 * width;
+		else
+			lphs->MaxPix = 0;
+		lphs->Direction = WM_VSCROLL;
+		}
+	else {
+		if (width > 3 * height)
+			lphs->MaxPix = width - 3 * height;
+		else
+			lphs->MaxPix = 0;
+		lphs->Direction = WM_HSCROLL;
+		}
+	if (lphs->MaxPix < 1)  lphs->MaxPix = 1;
+	return lphs;
 }
 
 
 void NC_CreateScrollBars(HWND hWnd)
 {
-    RECT	rect;
-    int		width, height;
-    WND  	*wndPtr;
-    LPHEADSCROLL lphs;
-    wndPtr = WIN_FindWndPtr(hWnd);
-    width = wndPtr->rectClient.right - wndPtr->rectClient.left;
-    height = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
-    if (wndPtr->dwStyle & WS_VSCROLL) {
-	if (wndPtr->dwStyle & WS_HSCROLL) height -= SYSMETRICS_CYHSCROLL;
-	lphs = AllocScrollBar(WS_VSCROLL, SYSMETRICS_CXVSCROLL, height);
+	RECT	rect;
+	int		width, height;
+	WND  	*wndPtr;
+	LPHEADSCROLL lphs;
+	wndPtr = WIN_FindWndPtr(hWnd);
+	GetWindowRect(hWnd, &rect);
+	width = rect.right - rect.left;
+	height = rect.bottom - rect.top;
+	if (wndPtr->dwStyle & WS_VSCROLL) {
+		if (wndPtr->dwStyle & WS_HSCROLL) height -= SYSMETRICS_CYHSCROLL;
+		lphs = AllocScrollBar(WS_VSCROLL, SYSMETRICS_CXVSCROLL, height);
 #ifdef DEBUG_SCROLL
-        printf("NC_CreateScrollBars Vertical %lX !\n", lphs);
+		printf("NC_CreateScrollBars Vertical %lX !\n", lphs);
 #endif
-	lphs->hWndOwner = hWnd;
-	wndPtr->VScroll = lphs;
-	}
-    if (wndPtr->dwStyle & WS_HSCROLL) {
-	if (wndPtr->dwStyle & WS_VSCROLL) width -= SYSMETRICS_CYVSCROLL;
-	lphs = AllocScrollBar(WS_HSCROLL, width, SYSMETRICS_CYHSCROLL);
+		lphs->rect.left = width - SYSMETRICS_CYVSCROLL;
+		lphs->rect.right = width;
+		lphs->hWndOwner = hWnd;
+		wndPtr->VScroll = lphs;
+		if (wndPtr->dwStyle & WS_HSCROLL) height += SYSMETRICS_CYHSCROLL;
+		}
+	if (wndPtr->dwStyle & WS_HSCROLL) {
+		if (wndPtr->dwStyle & WS_VSCROLL) width -= SYSMETRICS_CYVSCROLL;
+		lphs = AllocScrollBar(WS_HSCROLL, width, SYSMETRICS_CYHSCROLL);
 #ifdef DEBUG_SCROLL
-        printf("NC_CreateScrollBars Horizontal %lX !\n", lphs);
+		printf("NC_CreateScrollBars Horizontal %lX !\n", lphs);
 #endif
-	lphs->hWndOwner = hWnd;
-	wndPtr->HScroll = lphs;
-	}
+		lphs->rect.top = height - SYSMETRICS_CYHSCROLL;
+		lphs->rect.bottom = height;
+		lphs->hWndOwner = hWnd;
+		wndPtr->HScroll = lphs;
+		}
 }
 
 
diff --git a/debugger/Imakefile b/debugger/Imakefile
index 2e481f0..5958e7d 100644
--- a/debugger/Imakefile
+++ b/debugger/Imakefile
@@ -1,18 +1,21 @@
 #include "../Wine.tmpl"
 
 #define IHavSubDirs
-#define PassCDebugFlags 'CDEBUGFLAGS=$(CDEBUGFLAGS)' 'CC=$(CC)'
+#define PassCDebugFlags 'CDEBUGFLAGS=$(CDEBUGFLAGS)' 'CC=$(CC)' 'MAKE=$(MAKE)'
 
 MODULE = debugger
 
 SUBDIRS = readline
 
+DEFINES = -DUSE_READLINE
+
 /* Quick and dirt hack, since i386 is defined as 1. sigh */
 #define temp i386
 #undef i386
 
 SRCS = \
 	dbg.tab.c \
+	break.c \
 	hash.c \
 	lex.yy.c \
 	info.c \
@@ -20,6 +23,7 @@
 
 OBJS = \
 	dbg.tab.o \
+	break.o \
 	hash.o \
 	lex.yy.o \
 	info.o \
diff --git a/debugger/dbg.y b/debugger/dbg.y
index a627962..7dea72f 100644
--- a/debugger/dbg.y
+++ b/debugger/dbg.y
@@ -9,6 +9,8 @@
  */
 
 #include <stdio.h>
+#include <signal.h>
+
 #define YYSTYPE int
 
 #include "regpos.h"
@@ -24,12 +26,17 @@
 %token CONT
 %token QUIT
 %token HELP
+%token BACKTRACE
 %token INFO
 %token STACK
 %token REG
 %token REGS
 %token NUM
+%token ENABLE
+%token DISABLE
+%token BREAK
 %token SET
+%token MODE
 %token PRINT
 %token IDENTIFIER
 %token NO_SYMBOL
@@ -49,12 +56,17 @@
 	| CONT '\n'        { return; };
 	| SYMBOLFILE IDENTIFIER '\n' { read_symboltable($2); };
 	| DEFINE IDENTIFIER expr '\n'  { add_hash($2, $3); };
+	| MODE NUM	   { mode_command($2); };
+	| ENABLE NUM	   { enable_break($2); };
+	| DISABLE NUM	   { disable_break($2); };
+	| BREAK '*' expr   { add_break($3); };
 	| x_command
+	| BACKTRACE '\n'   { dbg_bt(); };
 	| print_command
 	| deposit_command
 
 deposit_command:
-	SET REG '=' expr '\n' { regval[$2] = $4; }
+	SET REG '=' expr '\n' { if(regval) regval[$2] = $4; else application_not_running();}
 	| SET '*' expr '=' expr '\n' { *((unsigned int *) $3) = $5; }
 	| SET symbol '=' expr '\n' { *((unsigned int *) $2) = $4; }
 
@@ -83,7 +95,7 @@
 			        }; 
 
  expr:  NUM			{ $$ = $1;	}
-	| REG			{ $$ = regval[$1]; }
+	| REG			{ if(regval) $$ = regval[$1]; else application_not_running();}
 	| symbol   		{ $$ = *((unsigned int *) $1); }
 	| expr '+' NUM		{ $$ = $1 + $3; }
 	| expr '-' NUM		{ $$ = $1 - $3; };
@@ -92,6 +104,7 @@
 	
  infocmd: INFO REGS { info_reg(); }
 	| INFO STACK  { info_stack(); };
+	| INFO BREAK  { info_break(); };
 
 
 %%
@@ -103,10 +116,25 @@
 #endif
 }
 
+void mode_command(int newmode)
+{
+  if(newmode == 16){
+    dbg_mask = 0xffff;
+    dbg_mode = 16;
+    return;
+  }
+  if(newmode == 32){ 
+    dbg_mask = 0xffffffff;
+    dbg_mode = 32;
+    return;
+  }
+  fprintf(stderr,"Invalid mode (use 16 or 32)\n");
+}
+
 static int loaded_symbols = 0;
 
 void
-wine_debug(int * regs)
+wine_debug(int signal, int * regs)
 {
 	int i;
 #ifdef YYDEBUG
@@ -143,13 +171,31 @@
 	};
 #endif
 
+	/* Remove the breakpoints from memory... */
+	insert_break(0);
+
+	/* If we stopped on a breakpoint, report this fact */
+	if(signal == SIGTRAP)
+	  {
+	    unsigned int addr;
+	    addr = SC_EIP(dbg_mask);
+	    if((addr & 0xffff0000) == 0 && dbg_mode == 16)
+	      addr |= SC_CS << 16;
+	    fprintf(stderr,"Stopped on breakpoint %d\n", get_bpnum(addr));
+	  }
+
 	/* Show where we crashed */
-	examine_memory(SC_EIP(dbg_mask), 1, 'i');
+	if(regval)
+	  examine_memory(SC_EIP(dbg_mask), 1, 'i');
 
 	issue_prompt();
 
 	yyparse();
 	flush_symbols();
+
+	/* Re-insert the breakpoints from memory... */
+	insert_break(1);
+
 	fprintf(stderr,"Returning to Wine...\n");
 
 }
diff --git a/debugger/debug.l b/debugger/debug.l
index 005c556..90effe0 100644
--- a/debugger/debug.l
+++ b/debugger/debug.l
@@ -58,7 +58,7 @@
 		}
 
 {DIGIT}+   {
-		sscanf(yytext, "%lx", &yylval);
+		sscanf(yytext, "%ld", &yylval);
 		return NUM;
 		}
 
@@ -74,14 +74,25 @@
 $esi		{ yylval = RN_ESI; return REG;}
 $edi		{ yylval = RN_EDI; return REG;}
 
+$es		{ yylval = RN_ES;  return REG;}
+$ds		{ yylval = RN_DS;  return REG;}
+$cs		{ yylval = RN_CS;  return REG;}
+$ss		{ yylval = RN_SS;  return REG;}
+
 info|inf|in		{ return INFO; }
 
+break|brea|bre          { return BREAK; }
+enable|enabl|enab|ena   { return ENABLE;}
+disable|disabl|disab|disa|dis { return DISABLE; }
+
 quit|qui|qu 	{ return QUIT; }
 
 help|hel|he	{ return HELP; }
 
 set|se		{ return SET; }
 
+bt		{ return BACKTRACE; }
+
 cont|con|co		{ return CONT; }
 
 symbolfile|symbolfil|symbolfi|symbolf|symbol|symbo|symb { return SYMBOLFILE; }
@@ -89,6 +100,8 @@
 define|defin|defi|def|de        { return DEFINE; }
 print|prin|pri|pr		{ return PRINT; }
 
+mode				{ return MODE; }
+
 regs|reg|re	{ return REGS; }
 
 stack|stac|sta|st     	{ return STACK; }
diff --git a/debugger/info.c b/debugger/info.c
index 87aec59..0a98d89 100644
--- a/debugger/info.c
+++ b/debugger/info.c
@@ -16,6 +16,11 @@
 /* THese three helper functions eliminate the need for patching the
 module from gdb for disassembly of code */
 
+void application_not_running()
+{
+  fprintf(stderr,"Application not running\n");
+}
+
 void read_memory(char * memaddr, char * buffer, int len){
 	memcpy(buffer, memaddr, len);
 }
@@ -36,6 +41,12 @@
 
 
 void info_reg(){
+
+	  if(!regval) {
+	    application_not_running();
+	    return 0;
+	  }
+
 	fprintf(stderr,"Register dump:\n");
 	/* First get the segment registers out of the way */
 	fprintf(stderr," CS:%4.4x SS:%4.4x DS:%4.4x ES:%4.4x GS:%4.4x FS:%4.4x\n", 
@@ -60,6 +71,10 @@
 	unsigned int * dump;
 	int i;
 
+	if(!regval) {
+	  application_not_running();
+	  return 0;
+	}
 
 	fprintf(stderr,"Stack dump:\n");
 	dump = (int*) SC_EIP(dbg_mask);
@@ -192,11 +207,15 @@
 "The commands accepted by the Wine debugger are a small subset",
 "of the commands that gdb would accept.  The commands currently",
 "are:\n",
-"  info reg",
-"  info stack",
+"  info [reg,stack,break]",
+"  break <addr>",
+"  enable bpnum",
+"  disable bpnum",
 "  help",
 "  quit",
 "  print <expr>",
+"  bt",
+"  mode [16,32]",
 "  symbolfile <filename>",
 "  define <identifier> <expr>",
 "  x <expr>",
@@ -228,3 +247,52 @@
 	while(helptext[i]) fprintf(stderr,"%s\n", helptext[i++]);
 }
 
+
+struct frame{
+  union{
+    struct {
+      unsigned short saved_bp;
+      unsigned short saved_ip;
+      unsigned short saved_cs;
+    } win16;
+    struct {
+      unsigned long saved_bp;
+      unsigned long saved_ip;
+      unsigned short saved_cs;
+    } win32;
+  } u;
+};
+
+
+void dbg_bt(){
+  struct frame * frame;
+  unsigned short cs;
+  int frameno = 0;
+
+  if(!regval) {
+    application_not_running();
+    return 0;
+  }
+
+  fprintf(stderr,"Backtrace:\n");
+  fprintf(stderr,"%d: %4.4x:%4.4x\n", frameno++, SC_CS, SC_EIP(dbg_mask));
+  cs = SC_CS;
+
+  frame = (struct frame *) ((SC_EBP(dbg_mask) & ~1) | (SC_SS << 16));
+  while((cs & 3) == 3) {
+    /* See if in 32 bit mode or not.  Assume GDT means 32 bit. */
+    if ((cs & 7) != 7) {
+      cs = frame->u.win32.saved_cs;
+      fprintf(stderr,"%d %4.4x:%4.4x\n", frameno++, cs, 
+	      frame->u.win32.saved_ip);
+      frame = (struct frame *) frame->u.win32.saved_bp;
+    } else {
+      cs = frame->u.win16.saved_cs;
+      fprintf(stderr,"%d %4.4x:%4.4x\n", frameno++, cs, 
+	      frame->u.win16.saved_ip);
+      frame = (struct frame *) ((frame->u.win16.saved_bp & ~1) |
+				(SC_SS << 16));
+    }
+  }
+}
+
diff --git a/if1632/Imakefile b/if1632/Imakefile
index 72d1b09..d1ff205 100644
--- a/if1632/Imakefile
+++ b/if1632/Imakefile
@@ -12,6 +12,7 @@
 	dll_gdi.o \
 	dll_kernel.o \
 	dll_keyboard.o \
+	dll_mmsystem.o \
 	dll_shell.o \
 	dll_sound.o \
 	dll_stress.o \
@@ -35,6 +36,7 @@
 MakeDllFromSpec(kernel,$(TOP)/$(MODULE))
 MakeDllFromSpec(keyboard,$(TOP)/$(MODULE))
 MakeDllFromSpec(shell,$(TOP)/$(MODULE))
+MakeDllFromSpec(mmsystem,$(TOP)/$(MODULE))
 MakeDllFromSpec(sound,$(TOP)/$(MODULE))
 MakeDllFromSpec(stress,$(TOP)/$(MODULE))
 MakeDllFromSpec(unixlib,$(TOP)/$(MODULE))
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index 327e37c..0744f78 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -31,7 +31,7 @@
 25  pascal GlobalCompact(long) GlobalCompact(1)
 #26 GLOBALFREEALL
 #28 GLOBALMASTERHANDLE
-29  pascal Yield() Yield()
+29  return Yield 0 0
 30  pascal WaitEvent(word) KERNEL_WaitEvent(1)
 #31 POSTEVENT
 #32 SETPRIORITY
@@ -119,7 +119,7 @@
 #114 __AHINCR
 115 pascal OutputDebugString(ptr) OutputDebugString(1)
 #116 INITLIB
-117 pascal OldYield() Yield()
+117 return OldYield 0 0
 #118 GETTASKQUEUEDS
 #119 GETTASKQUEUEES
 #120 UNDEFDYNLINK
@@ -147,7 +147,7 @@
 #139 DOSIGNAL
 #140 SETSIGHANDLER
 #141 INITTASK1
-150 pascal DirectedYield() Yield()
+150 return DirectedYield 2 0
 #151 WINOLDAPCALL
 152 pascal GetNumTasks() GetNumTasks()
 154 return GlobalNotify 4 0
diff --git a/if1632/pop.h b/if1632/pop.h
deleted file mode 100644
index ff2d961..0000000
--- a/if1632/pop.h
+++ /dev/null
@@ -1,16 +0,0 @@
-	add	$8,%esp
-	popw	%es
-	add	$2,%esp
-	popw	%ds
-	add	$2,%esp
-	popl	%edi
-	popl	%esi
-	popl	%ebp
-	add	$4,%esp
-	popl	%ebx
-	popl	%edx
-	popl	%ecx
-	popl	%eax
-	add	$16,%esp
-	popfl
-	add	$20,%esp
diff --git a/if1632/relay.c b/if1632/relay.c
index 2189855..f5b08b0 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -24,7 +24,7 @@
 
 #define DEBUG_RELAY /* */
 
-#define N_BUILTINS	10
+#define N_BUILTINS	11
 
 struct dll_name_table_entry_s dll_builtin_table[N_BUILTINS] =
 {
@@ -37,7 +37,8 @@
     { "SOUND",   SOUND_table,    20, 7 },
     { "KEYBOARD",KEYBOARD_table,137, 8 },
     { "WINSOCK", WINSOCK_table, 155, 9 },
-    { "STRESS",  STRESS_table,   15,10 },
+    { "STRESS",  STRESS_table,   15, 10},
+    { "MMSYSTEM",MMSYSTEM_table,1023,11},
 };
 
 unsigned short *Stack16Frame;
diff --git a/if1632/shell.spec b/if1632/shell.spec
index 062a9f6..52499e3 100644
--- a/if1632/shell.spec
+++ b/if1632/shell.spec
@@ -13,6 +13,7 @@
   2 pascal RegCreateKey() RegCreateKey()
   3 pascal RegCloseKey() RegCloseKey()
   4 pascal RegDeleteKey() RegDeleteKey()
+  9 pascal DragAcceptFiles() DragAcceptFiles()
  20 pascal ShellExecute(ptr) ShellExecute(1) 
 102 pascal RegisterShellHook(ptr) RegisterShellHook(1)
 103 pascal ShellHookProc() ShellHookProc()
@@ -21,7 +22,6 @@
 # 33   9  0136  ABOUTDLGPROC exported, shared data
 # 34  10  021a  EXTRACTICON exported, shared data
 # 21   4  1154  FINDEXECUTABLE exported, shared data
-#  9   6  0052  DRAGACCEPTFILES exported, shared data
 #100   4  0550  HERETHARBETYGARS exported, shared data
 # 38   5  0000  FINDENVIRONMENTSTRING exported, shared data
 #  7   2  14dc  REGENUMKEY exported, shared data
diff --git a/if1632/sound.spec b/if1632/sound.spec
index be0a2f4..9ce9349 100644
--- a/if1632/sound.spec
+++ b/if1632/sound.spec
@@ -15,3 +15,10 @@
 8    pascal  SETVOICESOUND(word long word) SetVoiceSound(1 2 3)
 9    pascal  STARTSOUND() StartSound()
 10   pascal  STOPSOUND() StopSound()
+11   pascal  WAITSOUNDSTATE(word) WaitSoundState(1)
+12   pascal  SYNCALLVOICES() SyncAllVoices()
+13   pascal  COUNTVOICENOTES(word) CountVoiceNotes(1)
+14   pascal  GETTHRESHOLDEVENT() GetThresholdEvent()
+15   pascal  GETTHRESHOLDSTATUS() GetThresholdStatus()
+16   pascal  SETVOICETHRESHOLD(word word) SetVoiceThreshold(1 2)
+17   pascal  DOBEEP() DoBeep()
diff --git a/if1632/user.spec b/if1632/user.spec
index 1c4129d..a2aa4bd 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -54,7 +54,7 @@
 49  pascal IsWindowVisible(word) IsWindowVisible(1)
 50  pascal FindWindow(ptr ptr) FindWindow(1 2)
 #51 BEAR51
-#52 ANYPOPUP
+52  pascal AnyPopup() AnyPopup()
 53  pascal DestroyWindow(word) DestroyWindow(1)
 54  pascal EnumWindows(ptr long) EnumWindows(1 2)
 55  pascal EnumChildWindows(word ptr long) EnumChildWindows(1 2 3)
@@ -317,7 +317,7 @@
 325 pascal PaintRect(word word word word ptr) PaintRect(1 2 3 4 5)
 #326 GETCONTROLBRUSH
 #331 ENABLEHARDWAREINPUT
-332 pascal UserYield() Yield()
+332 return UserYield 0 0
 #333 ISUSERIDLE
 334 pascal GetQueueStatus(word) GetQueueStatus(1)
 335 pascal GetInputState() GetInputState()
diff --git a/include/dlls.h b/include/dlls.h
index 19a2dfb..9c59b48 100644
--- a/include/dlls.h
+++ b/include/dlls.h
@@ -59,6 +59,7 @@
 extern struct dll_table_entry_s GDI_table[];
 extern struct dll_table_entry_s UNIXLIB_table[];
 extern struct dll_table_entry_s WIN87EM_table[];
+extern struct dll_table_entry_s MMSYSTEM_table[];
 extern struct dll_table_entry_s SHELL_table[];
 extern struct dll_table_entry_s SOUND_table[];
 extern struct dll_table_entry_s KEYBOARD_table[];
diff --git a/include/menu.h b/include/menu.h
index c5f513a..c877618 100644
--- a/include/menu.h
+++ b/include/menu.h
@@ -12,14 +12,12 @@
 {
     struct tagMENUITEM *next;
     struct tagMENUITEM *prev;
-    struct tagMENUITEM *child;
-    struct tagMENUITEM *parent;
+	HANDLE	hItem;	
     WORD	item_flags;
     WORD	item_id;
     WORD	sel_key;
-    char	*shortcut;
     char	*item_text;
-    char	menu_name[10];
+	HANDLE	hText;	
     RECT	rect;
     HBITMAP	hCheckBit;
     HBITMAP	hUnCheckBit;
diff --git a/include/options.h b/include/options.h
index ae38f73..da5b598 100644
--- a/include/options.h
+++ b/include/options.h
@@ -16,6 +16,7 @@
     int    synchronous;
     short  cmdShow;
     int    relay_debug;
+    int    debug;
 };
 
 extern struct options Options;
diff --git a/include/scroll.h b/include/scroll.h
index 2804a46..76e94f5 100644
--- a/include/scroll.h
+++ b/include/scroll.h
@@ -10,6 +10,8 @@
     short	MaxPix;
     short	CurPix;
     RECT	rect;
+    RECT	rectUp;
+    RECT	rectDown;
     BOOL	ThumbActive;
     BOOL	TimerPending;
     WORD	ButtonDown;
diff --git a/include/wine.h b/include/wine.h
index 69505e6..92e0f9b 100644
--- a/include/wine.h
+++ b/include/wine.h
@@ -65,6 +65,15 @@
 };
 #endif
 
+#ifdef linux
+#define WINE_DATA_SELECTOR 0x2b
+#define WINE_CODE_SELECTOR 0x23
+#endif
+#if defined(__NetBSD__) || defined(__FreeBSD__)
+#define WINE_DATA_SELECTOR 0x27
+#define WINE_CODE_SELECTOR 0x1f
+#endif
+
 #if defined(__NetBSD__) || defined(__FreeBSD__)
 #include <signal.h>
 #define sigcontext_struct sigcontext
diff --git a/loader/library.c b/loader/library.c
index 4e60f1d..cede6ec 100644
--- a/loader/library.c
+++ b/loader/library.c
@@ -3,6 +3,10 @@
  */
 static char Copyright[] = "Copyright  Martin Ayotte, 1994";
 
+/*
+#define DEBUG_MODULE
+*/
+
 #ifndef WINELIB
 #include <stdio.h>
 #include <stdlib.h>
@@ -31,7 +35,7 @@
 static LPMODULEENTRY lpModList = NULL;
 
 extern struct  w_files * wine_files;
-#define N_BUILTINS	10
+#define N_BUILTINS	11
 extern struct dll_name_table_entry_s dll_builtin_table[N_BUILTINS];
 
 
@@ -43,6 +47,7 @@
 	register struct w_files *w = wine_files;
 	int 	i;
  	printf("GetModuleHandle('%s');\n", lpModuleName);
+ 	printf("GetModuleHandle // searching in loaded modules\n");
 	while (w) {
 /*		printf("GetModuleHandle // '%s' \n", w->name);  */
 		if (strcmp(w->name, lpModuleName) == 0) {
@@ -52,7 +57,9 @@
 			}
 		w = w->next;
 		}
+ 	printf("GetModuleHandle // searching in builtin libraries\n");
     for (i = 0; i < N_BUILTINS; i++) {
+		if (dll_builtin_table[i].dll_name == NULL) break;
 		if (strcmp(dll_builtin_table[i].dll_name, lpModuleName) == 0) {
 			printf("GetModuleHandle('%s') return %04X \n", 
 							lpModuleName, 0xFF00 + i);
@@ -83,12 +90,17 @@
 int GetModuleFileName(HANDLE hModule, LPSTR lpFileName, short nSize)
 {
     struct w_files *w;
+	LPSTR		str;
     printf("GetModuleFileName(%04X, %08X, %d);\n", hModule, lpFileName, nSize);
     if (lpFileName == NULL) return 0;
+	if (nSize < 1) return 0;
     w = GetFileInfo(hModule);
     if (w == NULL) return 0;
-    if (nSize > strlen(w->name)) nSize = strlen(w->name) + 1;
-    strncpy(lpFileName, w->name, nSize);
+	str = w->filename;
+	if (str[0] == '/') str++;
+    if (nSize > strlen(str)) nSize = strlen(str) + 1;
+    strncpy(lpFileName, str, nSize);
+	ToDos(lpFileName);
     printf("GetModuleFileName copied '%s' return %d \n", lpFileName, nSize);
     return nSize - 1;
 }
@@ -100,43 +112,59 @@
 HANDLE LoadLibrary(LPSTR libname)
 {
     HANDLE hModule;
-	LPMODULEENTRY lpMod = lpModList;
-	LPMODULEENTRY lpNewMod;
+    LPMODULEENTRY lpMod = lpModList;
+    LPMODULEENTRY lpNewMod;
+
+    if (FindDLLTable(libname))
+    {
+	return WINE_CODE_SELECTOR;
+    }
+
     printf("LoadLibrary '%s'\n", libname);
-	if (lpMod != NULL) {
-		while (TRUE) {
-			if (strcmp(libname, lpMod->FileName) == 0) {
-				lpMod->Count++;
-			    printf("LoadLibrary // already loaded hInst=%04X\n", lpMod->hInst);
-				return lpMod->hInst;
-				}
-			if (lpMod->lpNextModule == NULL) break;
-			lpMod = lpMod->lpNextModule;
-			}
-		}
-	hModule = GlobalAlloc(GMEM_MOVEABLE, sizeof(MODULEENTRY));
-	lpNewMod = (LPMODULEENTRY) GlobalLock(hModule);	
+    if (lpMod != NULL) 
+    {
+	while (TRUE) 
+	{
+	    if (strcmp(libname, lpMod->FileName) == 0) 
+	    {
+		lpMod->Count++;
+		printf("LoadLibrary // already loaded hInst=%04X\n", 
+		       lpMod->hInst);
+		return lpMod->hInst;
+	    }
+	    if (lpMod->lpNextModule == NULL) break;
+	    lpMod = lpMod->lpNextModule;
+	}
+    }
+
+    hModule = GlobalAlloc(GMEM_MOVEABLE, sizeof(MODULEENTRY));
+    lpNewMod = (LPMODULEENTRY) GlobalLock(hModule);	
 #ifdef DEBUG_LIBRARY
     printf("LoadLibrary // creating new module entry %08X\n", lpNewMod);
 #endif
-	if (lpNewMod == NULL) return 0;
-	if (lpModList == NULL) {
-		lpModList = lpNewMod;
-		lpNewMod->lpPrevModule = NULL;
-		}
-	else {
-		lpMod->lpNextModule = lpNewMod;
-		lpNewMod->lpPrevModule = lpMod;
-		}
-	lpNewMod->lpNextModule = NULL;
-	lpNewMod->hModule = hModule;
-	lpNewMod->ModuleName = NULL;
-	lpNewMod->FileName = (LPSTR) malloc(strlen(libname));
-	if (lpNewMod->FileName != NULL)	strcpy(lpNewMod->FileName, libname);
-	lpNewMod->hInst = LoadImage(libname, DLL);
-	lpNewMod->Count = 1;
+    if (lpNewMod == NULL) 
+	return 0;
+    if (lpModList == NULL) 
+    {
+	lpModList = lpNewMod;
+	lpNewMod->lpPrevModule = NULL;
+    }
+    else 
+    {
+	lpMod->lpNextModule = lpNewMod;
+	lpNewMod->lpPrevModule = lpMod;
+    }
+
+    lpNewMod->lpNextModule = NULL;
+    lpNewMod->hModule = hModule;
+    lpNewMod->ModuleName = NULL;
+    lpNewMod->FileName = (LPSTR) malloc(strlen(libname));
+    if (lpNewMod->FileName != NULL)	
+	strcpy(lpNewMod->FileName, libname);
+    lpNewMod->hInst = LoadImage(libname, DLL);
+    lpNewMod->Count = 1;
     printf("LoadLibrary returned Library hInst=%04X\n", lpNewMod->hInst);
-	GlobalUnlock(hModule);	
+    GlobalUnlock(hModule);	
     return lpNewMod->hInst;
 }
 
@@ -219,10 +247,11 @@
 			strncpy(C, cpnt, len);
 			C[len] = '\0';
 #ifdef DEBUG_MODULE
-			printf("pointing Function '%s' !\n", C);
+			printf("pointing Function '%s' ordinal=%d !\n", 
+				C, *((unsigned short *)(cpnt +  len)));
 #endif
 			if (strncmp(cpnt, proc_name, len) ==  0) {
-				ordinal =  *((unsigned short *)  (cpnt +  len));
+				ordinal =  *((unsigned short *)(cpnt +  len));
 				break;
 				}
 			cpnt += len + 2;
diff --git a/loader/resource.c b/loader/resource.c
index 4ff3c28..dbd7d92 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -890,9 +890,14 @@
 	p += *p + 1;
     
     i = MIN(buflen - 1, *p);
-    memcpy(buffer, p + 1, i);
-    buffer[i] = '\0';
-
+	if (i > 0) {
+		memcpy(buffer, p + 1, i);
+		buffer[i] = '\0';
+		}
+	else {
+		printf("LoadString // I dont know why , but caller give buflen=%d *p=%d !\n", buflen, *p);
+		printf("LoadString // and try to obtain string '%s'\n", p + 1);
+		}
     GlobalFree(hmem);
 
 #ifdef DEBUG_RESOURCE
diff --git a/loader/signal.c b/loader/signal.c
index f00a348..92aecd5 100644
--- a/loader/signal.c
+++ b/loader/signal.c
@@ -56,8 +56,15 @@
 
 	/* First take care of a few preliminaries */
 #ifdef linux
-    if(signal != SIGSEGV) 
+    if(signal != SIGSEGV && signal != SIGTRAP) 
 	exit(1);
+
+    /* And back up over the int3 instruction. */
+    if(signal == SIGTRAP) {
+      scp->sc_eip--;
+      goto oops;
+    };
+
     if((scp->sc_cs & 7) != 7)
     {
 #endif
@@ -168,7 +175,7 @@
 	XFlush(display);
     fprintf(stderr,"In win_fault %x:%x\n", scp->sc_cs, scp->sc_eip);
 #ifdef linux
-    wine_debug(scp);  /* Enter our debugger */
+    wine_debug(signal, scp);  /* Enter our debugger */
 #else
     fprintf(stderr,"Stack: %x:%x\n", scp->sc_ss, scp->sc_esp);
     dump = (int*) scp;
@@ -192,6 +199,7 @@
 	segv_act.sa_restorer = 
 		(void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3);
 	wine_sigaction(SIGSEGV, &segv_act, NULL);
+	wine_sigaction(SIGTRAP, &segv_act, NULL); /* For breakpoints */
 #endif
 #if defined(__NetBSD__) || defined(__FreeBSD__)
         struct sigstack ss;
diff --git a/loader/task.c b/loader/task.c
index 46bb89b..980ddc7 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -3,6 +3,10 @@
  */
 static char Copyright[] = "Copyright  Martin Ayotte, 1994";
 
+/*
+#define DEBUG_TASK
+*/
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -14,7 +18,6 @@
 static int nTaskCount = 0;
 
 
-
 /**********************************************************************
  *				GetCurrentTask	[KERNEL.36]
  */
@@ -22,15 +25,18 @@
 {
 	LPTASKENTRY lpTask = lpTaskList;
 	int pid = getpid();
+#ifdef DEBUG_TASK
 	printf("GetCurrentTask() // unix_pid=%08X !\n", pid);
+#endif
 	if (lpTask == NULL) return 0;
 	while (TRUE) {
-		printf("GetCurrentTask() // searching lpTask->unix_pid=%08 !\n", lpTask->unix_pid);
 		if (lpTask->unix_pid == pid) break;
 		if (lpTask->lpNextTask == NULL) return 0;
 		lpTask = lpTask->lpNextTask;
 		}
+#ifdef DEBUG_TASK
 	printf("GetCurrentTask() returned hTask=%04X !\n", lpTask->hTask);
+#endif
 	return lpTask->hTask;
 }
 
@@ -50,7 +56,27 @@
  */
 HTASK GetWindowTask(HWND hWnd)
 {
+	HWND 	*wptr;
+	int		count;
+	LPTASKENTRY lpTask = lpTaskList;
 	printf("GetWindowTask(%04X) !\n", hWnd);
+	while (lpTask != NULL) {
+		wptr = lpTask->lpWndList;
+		if (wptr != NULL) {
+			count = 0;
+			while (++count < MAXWIN_PER_TASK) {
+				printf("GetWindowTask // searching %04X %04X !\n",
+										lpTask->hTask, *(wptr));
+				if (*(wptr) == hWnd) {
+					printf("GetWindowTask(%04X) found hTask=%04X !\n", 
+												hWnd, lpTask->hTask);
+					return lpTask->hTask;
+					}
+				wptr++;
+				}
+			}
+		lpTask = lpTask->lpNextTask;
+		}
 	return 0;
 }
 
@@ -60,8 +86,34 @@
  */
 BOOL EnumTaskWindows(HANDLE hTask, FARPROC lpEnumFunc, LONG lParam)
 {
+	HWND 	*wptr, hWnd;
+	BOOL	bRet;
+	int		count = 0;
+	LPTASKENTRY lpTask = lpTaskList;
 	printf("EnumTaskWindows(%04X, %08X, %08X) !\n", hTask, lpEnumFunc, lParam);
-	return FALSE;
+	while (TRUE) {
+		if (lpTask->hTask == hTask) break;
+		if (lpTask == NULL) {
+			printf("EnumTaskWindows // hTask=%04X not found !\n", hTask);
+			return FALSE;
+			}
+		lpTask = lpTask->lpNextTask;
+		}
+	printf("EnumTaskWindows // found hTask=%04X !\n", hTask);
+	wptr = lpTask->lpWndList;
+	if (wptr == NULL) return FALSE;
+	while ((hWnd = *(wptr++)) != 0) {
+		if (++count >= MAXWIN_PER_TASK) return FALSE;
+		printf("EnumTaskWindows // hWnd=%04X count=%d !\n", hWnd, count);
+#ifdef WINELIB
+		if (lpEnumFunc != NULL)	bRet = (*lpEnumFunc)(hWnd, lParam); 
+#else
+		if (lpEnumFunc != NULL)	
+			bRet = CallBack16(lpEnumFunc, 2, lParam, (int) hWnd);
+#endif
+		if (bRet == 0) break;
+		}
+	return TRUE;
 }
 
 
@@ -96,15 +148,18 @@
 	lpNewTask->lpNextTask = NULL;
 	lpNewTask->hIcon = 0;
 	lpNewTask->hModule = 0;
+	lpNewTask->hInst = hInst;
 	lpNewTask->hTask = hTask;
+	lpNewTask->unix_pid = getpid();
 	lpNewTask->lpWndList = (HWND *) malloc(MAXWIN_PER_TASK * sizeof(HWND));
 	if (lpNewTask->lpWndList != NULL) 
 		memset((LPSTR)lpNewTask->lpWndList, 0, MAXWIN_PER_TASK * sizeof(HWND));
-	lpNewTask->hInst = hInst;
-	lpNewTask->unix_pid = getpid();
+#ifdef DEBUG_TASK
     printf("CreateNewTask // unix_pid=%08X return hTask=%04X\n", 
 									lpNewTask->unix_pid, hTask);
+#endif
 	GlobalUnlock(hTask);	
+	nTaskCount++;
     return hTask;
 }
 
@@ -117,18 +172,27 @@
 	HWND 	*wptr;
 	int		count = 0;
 	LPTASKENTRY lpTask = lpTaskList;
+#ifdef DEBUG_TASK
 	printf("AddWindowToTask(%04X, %04X); !\n", hTask, hWnd);
+#endif
 	while (TRUE) {
 		if (lpTask->hTask == hTask) break;
-		if (lpTask == NULL) return FALSE;
+		if (lpTask == NULL) {
+			printf("AddWindowToTask // hTask=%04X not found !\n", hTask);
+			return FALSE;
+			}
 		lpTask = lpTask->lpNextTask;
 		}
 	wptr = lpTask->lpWndList;
 	if (wptr == NULL) return FALSE;
-	while (*(wptr++) != 0) {
+	while (*(wptr) != 0) {
 		if (++count >= MAXWIN_PER_TASK) return FALSE;
+		wptr++;
 		}
 	*wptr = hWnd;
+#ifdef DEBUG_TASK
+	printf("AddWindowToTask // window added, count=%d !\n", count);
+#endif
 	return TRUE;
 }
 
@@ -141,18 +205,31 @@
 	HWND 	*wptr;
 	int		count = 0;
 	LPTASKENTRY lpTask = lpTaskList;
-	printf("AddWindowToTask(%04X, %04X); !\n", hTask, hWnd);
+#ifdef DEBUG_TASK
+	printf("RemoveWindowToTask(%04X, %04X); !\n", hTask, hWnd);
+#endif
 	while (TRUE) {
 		if (lpTask->hTask == hTask) break;
-		if (lpTask == NULL) return FALSE;
+		if (lpTask == NULL) {
+			printf("RemoveWindowFromTask // hTask=%04X not found !\n", hTask);
+			return FALSE;
+			}
 		lpTask = lpTask->lpNextTask;
 		}
 	wptr = lpTask->lpWndList;
 	if (wptr == NULL) return FALSE;
-	while (*(wptr++) != hWnd) {
+	while (*(wptr) != hWnd) {
 		if (++count >= MAXWIN_PER_TASK) return FALSE;
+		wptr++;
 		}
-	*wptr = 0;
+	while (*(wptr) != 0) {
+		*(wptr) = *(wptr + 1);
+		if (++count >= MAXWIN_PER_TASK) return FALSE;
+		wptr++;
+		}
+#ifdef DEBUG_TASK
+	printf("RemoveWindowFromTask // window removed, count=%d !\n", --count);
+#endif
 	return TRUE;
 }
 
diff --git a/loader/wine.c b/loader/wine.c
index fc26d71..896ed06 100644
--- a/loader/wine.c
+++ b/loader/wine.c
@@ -23,6 +23,7 @@
 #include "windows.h"
 #include "wineopts.h"
 #include "arch.h"
+#include "options.h"
 
 /* #define DEBUG_FIXUP */
 
@@ -350,6 +351,8 @@
     ss_reg = wine_files->selector_table[wine_files->ne_header->ss-1].selector;
     sp_reg = wine_files->ne_header->sp;
 
+    if (Options.debug) wine_debug(0, NULL);
+
     rv = CallToInit16(cs_reg << 16 | ip_reg, ss_reg << 16 | sp_reg, ds_reg);
     printf ("rv = %x\n", rv);
 }
diff --git a/memory/global.c b/memory/global.c
index 11ab363..29717e0 100644
--- a/memory/global.c
+++ b/memory/global.c
@@ -163,6 +163,10 @@
     GDESC *g_prev;
     void *m;
 
+#ifdef DEBUG_HEAP
+	printf("GlobalAlloc flags %4X, size %d\n", flags, size);
+#endif
+
     /*
      * If this block is fixed or very big we need to allocate entire
      * segments.
diff --git a/memory/heap.c b/memory/heap.c
index 71cb561..471d5fe 100644
--- a/memory/heap.c
+++ b/memory/heap.c
@@ -116,14 +116,23 @@
 {
     MDESC *m_free;
     MDESC *m;
-
     /*
      * Check validity of block
      */
     m = (MDESC *) old_block - 1;
-    if (m->prev != m || m->next != m || 
+#ifdef DEBUG_HEAP
+	printf("HEAP_ReAlloc new_size=%d !\n", new_size);
+	printf("HEAP_ReAlloc old_block=%08X !\n", old_block);
+	printf("HEAP_ReAlloc m=%08X free_list=%08X !\n", m, free_list);
+	printf("HEAP_ReAlloc m->prev=%08X !\n", m->prev);
+	printf("HEAP_ReAlloc m->next=%08X !\n", m->next);
+	printf("HEAP_ReAlloc *free_list=%08X !\n", *free_list);
+#endif
+	if (m->prev != m || m->next != m || 
 	((int) m & 0xffff0000) != ((int) *free_list & 0xffff0000))
     {
+	printf("Attempt to resize bad pointer, m = %08x, *free_list = %08x\n",
+	       m, free_list);
 #ifdef DEBUG_HEAP
 	printf("Attempt to resize bad pointer, m = %08x, *free_list = %08x\n",
 	       m, free_list);
@@ -134,6 +143,9 @@
     /*
      * Check for grow block
      */
+#ifdef DEBUG_HEAP
+	printf("HEAP_ReAlloc Check for grow block !\n");
+#endif
     if (new_size > m->length)
     {
 	m_free = m + 1 + m->length / sizeof(MDESC);
@@ -142,7 +154,6 @@
 	    m_free->length + sizeof(MDESC) < new_size)
 	{
 	    void *new_p = HEAP_Alloc(free_list, flags, new_size);
-	    
 	    if (new_p ==NULL)
 		return NULL;
 	    memcpy(new_p, old_block, m->length);
@@ -159,6 +170,9 @@
 	    m_free->next->prev = m_free->prev;
 	
 	m->length += sizeof(MDESC) + m_free->length;
+#ifdef DEBUG_HEAP
+	printf("HEAP_ReAlloc before GLOBAL_FLAGS_ZEROINIT !\n");
+#endif
 	if (flags & GLOBAL_FLAGS_ZEROINIT)
 	    memset(m_free, '\0', sizeof(MDESC) + m_free->length);
     }
@@ -166,6 +180,9 @@
     /*
      * Check for shrink block.
      */
+#ifdef DEBUG_HEAP
+	printf("HEAP_ReAlloc Check for shrink block !\n");
+#endif
     if (new_size < m->length - 4 * sizeof(MDESC))
     {
 	m_free = m + new_size / sizeof(MDESC) + 2;
@@ -422,7 +439,7 @@
 	HEAP_Init(&lh->free_list,
 		  (void *) ((segment << 16) | start), end - start + 1);
     }
-
+	printf("WIN16_LocalInit // return segment=%04X !\n", segment);
     return segment;
 }
 
@@ -447,10 +464,14 @@
  *					WIN16_LocalReAlloc
  */
 void *
-WIN16_LocalReAlloc(unsigned int handle, int flags, int bytes)
+WIN16_LocalReAlloc(unsigned int handle, int bytes, int flags)
 {
     void *m;
-    
+#ifdef DEBUG_HEAP
+	printf("WIN16_LocalReAlloc(%04X, %d, %04X); !\n",	handle, bytes, flags);
+	printf("WIN16_LocalReAlloc // LOCALHEAP()=%08X !\n", LOCALHEAP());
+	printf("WIN16_LocalReAlloc // *LOCALHEAP()=%08X !\n", *LOCALHEAP());
+#endif
     m = HEAP_ReAlloc(LOCALHEAP(), (void *)
 		     (((int) *LOCALHEAP() & 0xffff0000) | (handle & 0xffff)),
 		     bytes, flags);
diff --git a/misc/Imakefile b/misc/Imakefile
index e081262..dffb628 100644
--- a/misc/Imakefile
+++ b/misc/Imakefile
@@ -14,6 +14,7 @@
 	lstr.c \
 	main.c \
 	message.c \
+	mmsystem.c \
 	profile.c \
 	property.c \
 	rect.c \
diff --git a/misc/dos_fs.c b/misc/dos_fs.c
index 78ee54c..6d34222 100644
--- a/misc/dos_fs.c
+++ b/misc/dos_fs.c
@@ -53,23 +53,30 @@
 
 static void ExpandTildeString(char *s)
 {
-	struct passwd *entry;
-	char temp[1024], *ptr = temp;
+    struct passwd *entry;
+    char temp[1024], *ptr = temp;
 	
-	strcpy(temp, s);
-	while (*ptr)
-	{
-		if (*ptr != '~') { 
-			*s++ = *ptr++;
-			continue;
-		}
-		ptr++;
-		if ( (entry = getpwuid(getuid())) == NULL) {
-			continue;
-		}
-		strcpy(s, entry->pw_dir);
-		s += strlen(entry->pw_dir);
+    strcpy(temp, s);
+
+    while (*ptr)
+    {
+	if (*ptr != '~') 
+	{ 
+	    *s++ = *ptr++;
+	    continue;
 	}
+
+	ptr++;
+
+	if ( (entry = getpwuid(getuid())) == NULL) 
+	{
+	    continue;
+	}
+
+	strcpy(s, entry->pw_dir);
+	s += strlen(entry->pw_dir);
+    }
+    *s = 0;
 }
 
 void ChopOffSlash(char *path)
diff --git a/misc/exec.c b/misc/exec.c
index bb37237..daccb03 100644
--- a/misc/exec.c
+++ b/misc/exec.c
@@ -7,6 +7,11 @@
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
+#include "neexe.h"
+#include "segmem.h"
+#include "prototypes.h"
+#include "dlls.h"
+#include "wine.h"
 #include "windows.h"
 
 #define HELP_CONTEXT      0x0001
@@ -24,6 +29,8 @@
 #define HELP_MULTIKEY     0x0201
 #define HELP_SETWINPOS    0x0203
 
+extern struct  w_files * wine_files;
+
 typedef struct {
 	WORD	wEnvSeg;
 	LPSTR	lpCmdLine;
@@ -31,8 +38,97 @@
 	DWORD	dwReserved;
 	} PARAMBLOCK;
 
+typedef BOOL (CALLBACK * LPFNWINMAIN)(HANDLE, HANDLE, LPSTR, int);
+
+
+extern int CallToInit16(unsigned long csip, unsigned long sssp, 
+			unsigned short ds);
 HANDLE CreateNewTask(HINSTANCE hInst);
 
+
+void InitializeLoadedNewDLLs(HINSTANCE hInst)
+{
+    struct w_files * w;
+    struct w_files * wpnt;
+    int cs_reg, ds_reg, ip_reg;
+    int rv;
+
+    fprintf(stderr, "Initializing New DLLs\n");
+
+    /*
+     * Initialize libraries
+     */
+	printf("InitializeLoadedNewDLLs() before searching hInst=%04X !\n", hInst);
+	w = wine_files;
+	while (w && w->hinstance != hInst) w = w->next;
+	if (w == NULL) return;
+	printf("InitializeLoadedNewDLLs() // before InitLoop !\n");
+    for(wpnt = w; wpnt; wpnt = wpnt->next)
+    {
+	/* 
+	 * Is this a library? 
+	 */
+	if (wpnt->ne_header->format_flags & 0x8000)
+	{
+	    if (!(wpnt->ne_header->format_flags & 0x0001))
+	    {
+		/* Not SINGLEDATA */
+		fprintf(stderr, "Library is not marked SINGLEDATA\n");
+		exit(1);
+	    }
+
+	    ds_reg = wpnt->selector_table[wpnt->
+					  ne_header->auto_data_seg-1].selector;
+	    cs_reg = wpnt->selector_table[wpnt->ne_header->cs-1].selector;
+	    ip_reg = wpnt->ne_header->ip;
+
+	    fprintf(stderr, "Initializing %s, cs:ip %04x:%04x, ds %04x\n", 
+		    wpnt->name, cs_reg, ip_reg, ds_reg);
+
+	    rv = CallTo16(cs_reg << 16 | ip_reg, ds_reg);
+	    printf ("rv = %x\n", rv);
+	}
+    }
+}
+
+
+void StartNewTask(HINSTANCE hInst)
+{
+	struct w_files * wpnt;
+	struct w_files * w;
+	int cs_reg, ds_reg, ss_reg, ip_reg, sp_reg;
+	int rv;
+	int segment;
+
+	printf("StartNewTask() before searching hInst=%04X !\n", hInst);
+	wpnt = wine_files;
+	while (wpnt && wpnt->hinstance != hInst) wpnt = wpnt->next;
+	if (wpnt == NULL) return;
+	printf("StartNewTask() // before FixupSegment !\n");
+	for(w = wpnt; w; w = w->next)	{
+		for (segment = 0; segment < w->ne_header->n_segment_tab; segment++) {
+			if (FixupSegment(w, segment) < 0) {
+				myerror("fixup failed.");
+				}
+			}
+		}
+	printf("StartNewTask() before InitializeLoadedNewDLLs !\n");
+	InitializeLoadedNewDLLs(hInst);
+	printf("StartNewTask() before setup register !\n");
+    ds_reg = (wpnt->selector_table[wpnt->ne_header->auto_data_seg-1].selector);
+    cs_reg = wpnt->selector_table[wpnt->ne_header->cs-1].selector;
+    ip_reg = wpnt->ne_header->ip;
+    ss_reg = wpnt->selector_table[wpnt->ne_header->ss-1].selector;
+    sp_reg = wpnt->ne_header->sp;
+
+	printf("StartNewTask() before CallToInit16() !\n");
+    rv = CallToInit16(cs_reg << 16 | ip_reg, ss_reg << 16 | sp_reg, ds_reg);
+    printf ("rv = %x\n", rv);
+
+}
+
+
+
 /**********************************************************************
  *				LoadModule	[KERNEL.45]
  */
@@ -52,43 +148,57 @@
  */
 WORD WinExec(LPSTR lpCmdLine, WORD nCmdShow)
 {
-	int X, X2, C;
-	char *ArgV[20];
-	HANDLE	hTask = 0;
+	int 		c = 0;
+	int 		x, x2;
+	char 		*ArgV[20];
+	LPFNWINMAIN lpfnMain;
+	HINSTANCE	hInst = 0;
+	HANDLE		hTask = 0;
 	printf("WinExec('%s', %04X)\n", lpCmdLine, nCmdShow);
-	ArgV[0] = "wine";
-	C = 1;
-	for (X = X2 = 0; X < strlen(lpCmdLine) + 1; X++) {
-		if ((lpCmdLine[X] == ' ') || (lpCmdLine[X] == '\0')) {
-			ArgV[C] = (char *)malloc(X - X2 + 1);
-			strncpy(ArgV[C], &lpCmdLine[X2], X - X2);
-			ArgV[C][X - X2] = '\0';
-			C++;   X2 = X + 1;
+/*	ArgV[0] = "wine";
+	c = 1; */
+	for (x = x2 = 0; x < strlen(lpCmdLine) + 1; x++) {
+		if ((lpCmdLine[x] == ' ') || (lpCmdLine[x] == '\0')) {
+			ArgV[c] = (char *)malloc(x - x2 + 1);
+			strncpy(ArgV[c], &lpCmdLine[x2], x - x2);
+			ArgV[c][x - x2] = '\0';
+			c++;   x2 = x + 1;
 			}							  
 		}  
-	ArgV[C] = NULL;
-	for (C = 0; ; C++) {
-		if (ArgV[C] == NULL)  break;
-		printf("--> '%s' \n", ArgV[C]);
-		}  
+	ArgV[c] = NULL;
+	for (c = 0; ArgV[c] != NULL; c++) printf("--> '%s' \n", ArgV[c]);
 	switch(fork()) {
 		case -1:
 			printf("Can't 'fork' process !\n");
 			break;
 		case 0:
-			hTask = CreateNewTask(0);
+			if ((hInst = LoadImage(ArgV[0], EXE)) == (HINSTANCE) NULL ) {
+				fprintf(stderr, "wine: can't find %s!.\n", ArgV[0]);
+				printf("Child process died !\n");
+				exit(1);
+				}
+			hTask = CreateNewTask(hInst);
+			printf("WinExec // hTask=%04X hInst=%04X !\n", hTask, hInst);
+			StartNewTask(hInst); 
+/*
+			lpfnMain = (LPFNWINMAIN)GetProcAddress(hInst, (LPSTR)0L);
+			printf("WineExec() // lpfnMain=%08X\n", (LONG)lpfnMain);
+			if (lpfnMain != NULL) {
+				(lpfnMain)(hInst, 0, lpCmdLine, nCmdShow);
+				printf("WineExec() // after lpfnMain\n");
+				}
+*/
+/*			hTask = CreateNewTask(0);
 			printf("WinExec // New Task hTask=%04X !\n", hTask);
-			execvp(ArgV[0], ArgV);
+			execvp(ArgV[0], ArgV); */
+
 			printf("Child process died !\n");
 			exit(1);
 		default:
 			printf("WinExec (Main process stay alive) hTask=%04X !\n", hTask);
 			break;         
 		}
-	for (C = 0; ; C++) {
-		if (ArgV[C] == NULL)  break;
-		free(ArgV[C]);
-		}  
+	for (c = 0; ArgV[c] != NULL; c++) 	free(ArgV[c]);
 	return hTask;
 }
 
diff --git a/misc/file.c b/misc/file.c
index 47beada..ff4bcba 100644
--- a/misc/file.c
+++ b/misc/file.c
@@ -27,6 +27,8 @@
 #include <windows.h>
 #include "prototypes.h"
 
+#define DEBUG_FILE
+
 char WindowsDirectory[256], SystemDirectory[256], TempDirectory[256];
 
 /***************************************************************************
@@ -119,33 +121,38 @@
  **************************************************************************/
 INT OpenFile (LPSTR lpFileName, LPOFSTRUCT ofs, WORD wStyle)
 {
-  int base,flags;
+	int 	base,flags;
+	int		handle;
+#ifdef DEBUG_FILE
+	fprintf(stderr,"Openfile(%s,<struct>,%d) ",lpFileName,wStyle);
+#endif
+	base=wStyle&0xF;
+	flags=wStyle&0xFFF0;
+  
+	flags&=0xFF0F;  /* strip SHARE bits for now */
+	flags&=0xD7FF;  /* strip PROMPT & CANCEL bits for now */
+	flags&=0x7FFF;  /* strip REOPEN bit for now */
+	flags&=0xFBFF;  /* strib VERIFY bit for now */
+  
+	if(flags&OF_CREATE) { base |=O_CREAT; flags &=0xEFFF; }
 
 #ifdef DEBUG_FILE
-  fprintf(stderr,"Openfile(%s,<struct>,%d) ",lpFileName,wStyle);
+	fprintf(stderr,"now %d,%d\n",base,flags);
 #endif
 
-  base=wStyle&0xF;
-  flags=wStyle&0xFFF0;
-  
-  flags&=0xFF0F;  /* strip SHARE bits for now */
-  flags&=0xD7FF;  /* strip PROMPT & CANCEL bits for now */
-  flags&=0x7FFF;  /* strip REOPEN bit for now */
-  flags&=0xFBFF;  /* strib VERIFY bit for now */
-  
-  if(flags&OF_CREATE) { base |=O_CREAT; flags &=0xEFFF; }
-
-  fprintf(stderr,"now %d,%d\n",base,flags);
-
-  if(flags&(OF_DELETE|OF_EXIST))
-    {
-      fprintf(stderr,"Unsupported OpenFile option\n");
-      return -1;
-    }
-  else
-    {
-      return _lopen (lpFileName, wStyle);
-   }
+	if (flags & OF_EXIST) {
+		printf("OpenFile // OF_EXIST '%s' !\n", lpFileName);
+		handle = _lopen (lpFileName, wStyle);
+		close(handle);
+		return handle;
+		}
+	if (flags & OF_DELETE) {
+		printf("OpenFile // OF_DELETE '%s' !\n", lpFileName);
+		return unlink(lpFileName);
+		}
+	else {
+		return _lopen (lpFileName, wStyle);
+		}
 }
 
 /**************************************************************************
@@ -200,11 +207,9 @@
 	fprintf(stderr, "_lcreate: filename %s, attributes %d\n",lpszFilename, 
   			fnAttribute);
 #endif
-
 	if ((UnixFileName = GetUnixFileName(lpszFilename)) == NULL)
   		return HFILE_ERROR;
-
-	handle =  open (UnixFileName, O_CREAT | O_TRUNC | O_WRONLY );
+	handle =  open (UnixFileName, O_CREAT | O_TRUNC | O_WRONLY, 426);
 
 	if (handle == -1)
 		return HFILE_ERROR;
@@ -282,6 +287,7 @@
 INT GetTempFileName(BYTE bDriveLetter, LPCSTR lpszPrefixString, UINT uUnique, LPSTR lpszTempFileName)
 {
 	int unique;
+	int handle;
 	char tempname[256];
 	
 	if (uUnique == 0)
@@ -301,6 +307,11 @@
 	fprintf(stderr,"GetTempFilename: %c %s %d => %s\n",bDriveLetter,
 		lpszPrefixString,uUnique,lpszTempFileName);
 #endif
+	if ((handle = _lcreate (lpszTempFileName, 0x0000)) == -1) {
+		fprintf(stderr,"GetTempFilename: can't create temp file '%s' !\n", lpszTempFileName);
+		}
+	else
+		close(handle);
 
 	return unique;
 }
diff --git a/misc/lstr.c b/misc/lstr.c
index e6dc701..eeaf7c2 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -18,7 +18,9 @@
 /* KERNEL.89 */
 LPSTR lstrcat(LPSTR target,LPCSTR source)
 {
+#ifdef DEBUG_STRING
   fprintf(stderr,"lstrcat(%s,%s)\n",target,source);
+#endif
   return strcat(target,source);
 }
 
diff --git a/misc/main.c b/misc/main.c
index 6efa211..d5784f3 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -54,6 +54,7 @@
     { "-privatemap",  ".privatemap",  XrmoptionNoArg,  (caddr_t)"on" },
     { "-synchronous", ".synchronous", XrmoptionNoArg,  (caddr_t)"on" },
     { "-spy",         ".spy",         XrmoptionSepArg, (caddr_t)NULL },
+    { "-debug",       ".debug",       XrmoptionNoArg,  (caddr_t)"on" },
     { "-relaydbg",    ".relaydbg",    XrmoptionNoArg,  (caddr_t)"on" }
 };
 
@@ -67,6 +68,7 @@
   "    -desktop geom   Use a desktop window of the given geometry\n" \
   "    -display name   Use the specified display\n" \
   "    -iconic         Start as an icon\n" \
+  "    -debug          Enter debugger before starting application\n" \
   "    -name name      Set the application name\n" \
   "    -privatemap     Use a private color map\n" \
   "    -synchronous    Turn on synchronous display mode\n" \
@@ -176,6 +178,8 @@
 	Options.synchronous = TRUE;
     if (MAIN_GetResource( db, ".relaydbg", &value ))
 	Options.relay_debug = TRUE;
+    if (MAIN_GetResource( db, ".debug", &value ))
+	Options.debug = TRUE;
     if (MAIN_GetResource( db, ".spy", &value))
 	Options.spyFilename = value.addr;
     if (MAIN_GetResource( db, ".depth", &value))
@@ -274,6 +278,7 @@
     Comm_DeInit();
     sync_profiles();
     MAIN_RestoreSetup();
+    WSACleanup();
 }
 
 /***********************************************************************
@@ -506,14 +511,6 @@
 }
 
 /***********************************************************************
-*	YIELD (KERNEL.29)
-*/
-void Yield(void)
-{
-	;
-}
-
-/***********************************************************************
 *	SWAPMOUSEBUTTON (USER.186)
 */
 BOOL SwapMouseButton(BOOL fSwap)
diff --git a/misc/message.c b/misc/message.c
index c545963..23e1be6 100644
--- a/misc/message.c
+++ b/misc/message.c
@@ -50,9 +50,10 @@
 	WND	    	*wndPtr;
 	WNDCLASS  	wndClass;
 	MSG	    	msg;
-	MSGBOX		mb;
+    LPMSGBOX 	lpmb;
 	DWORD		dwStyle;
 	HINSTANCE	hInst;
+	int			nRet;
 	wndPtr = WIN_FindWndPtr(hWnd);
 	if (wndPtr == NULL) {
 		hInst = hSysRes;
@@ -66,6 +67,16 @@
 		printf("MessageBox(%04X, '%s', '%s', %04X)\n", hWnd, str, title, type);
 #endif
 		}
+    lpmb = (LPMSGBOX) malloc(sizeof(MSGBOX));
+	memset(lpmb, 0, sizeof(MSGBOX));
+/*	lpmb->Title = title;*/
+	lpmb->Title = (LPSTR) malloc(strlen(title) + 1);
+	strcpy(lpmb->Title, title);
+/*	lpmb->Str = str;*/
+	lpmb->Str = (LPSTR) malloc(strlen(str) + 1);
+	strcpy(lpmb->Str, str);
+	lpmb->wType = type;
+	lpmb->ActiveFlg = TRUE;
 	wndClass.style           = CS_HREDRAW | CS_VREDRAW ;
 	wndClass.lpfnWndProc     = (WNDPROC)SystemMessageBoxProc;
 	wndClass.cbClsExtra      = 0;
@@ -76,29 +87,29 @@
 	wndClass.hbrBackground   = GetStockObject(WHITE_BRUSH);
 	wndClass.lpszMenuName    = NULL;
 	wndClass.lpszClassName   = "MESSAGEBOX";
+#ifdef DEBUG_MSGBOX
+	printf( "MessageBox // before RegisterClass, '%s' '%s' !\n", str, title);
+#endif
 	if (!RegisterClass(&wndClass)) {
 		printf("Unable to Register class 'MESSAGEBOX' !\n");
+		if (lpmb != NULL) free(lpmb);
 		return 0;
 		}
-	memset(&mb, 0, sizeof(MSGBOX));
-	mb.Title = title;
-	mb.Str = str;
-	mb.wType = type;
-	mb.ActiveFlg = TRUE;
 	dwStyle = WS_POPUP | WS_DLGFRAME | WS_VISIBLE;
 	if ((type & (MB_SYSTEMMODAL | MB_TASKMODAL)) == 0) dwStyle |= WS_CAPTION;
 	hWndOld = GetFocus();
-	hDlg = CreateWindow("MESSAGEBOX", title, dwStyle, 100, 150, 400, 120,
-				(HWND)NULL, (HMENU)NULL, hInst, (LPSTR)&mb);
+	hDlg = CreateWindow("MESSAGEBOX", lpmb->Title, dwStyle, 100, 150, 400, 160,
+				(HWND)NULL, (HMENU)NULL, hInst, (LPSTR)lpmb);
 	if (hDlg == 0) {
 		printf("Unable to create 'MESSAGEBOX' window !\n");
+		if (lpmb != NULL) free(lpmb);
 		return 0;
 		}
 #ifdef DEBUG_MSGBOX
 	printf( "MessageBox // before Msg Loop !\n");
 #endif
 	while(TRUE) {
-		if (!mb.ActiveFlg) break;
+		if (!lpmb->ActiveFlg) break;
 		if (!GetMessage(&msg, (HWND)NULL, 0, 0)) break;
 		TranslateMessage(&msg);
 		if ((type & (MB_SYSTEMMODAL | MB_TASKMODAL)) != 0 &&
@@ -115,11 +126,13 @@
 		DispatchMessage(&msg);
 		}
 	SetFocus(hWndOld);
+	nRet = lpmb->wRetVal;
+	if (lpmb != NULL) free(lpmb);
 	if (!UnregisterClass("MESSAGEBOX", hInst)) return 0;
 #ifdef DEBUG_MSGBOX
-	printf( "MessageBox return %04X !\n", mb.wRetVal);
+	printf( "MessageBox return %04X !\n", nRet);
 #endif
-	return(mb.wRetVal);
+	return(nRet);
 }
 
 
@@ -148,7 +161,6 @@
 	DWORD		OldTextColor;
 	RECT		rect;
 	LPMSGBOX	lpmb;
-	LPMSGBOX	lpmbInit;
 	BITMAP		bm;
 	HBITMAP		hBitMap;
 	HDC			hMemDC;
@@ -162,10 +174,13 @@
 #endif
 		wndPtr = WIN_FindWndPtr(hWnd);
 		createStruct = (CREATESTRUCT *)lParam;
-		lpmbInit = (LPMSGBOX)createStruct->lpCreateParams;
-		if (lpmbInit == 0) break;
-		*((LPMSGBOX *)&wndPtr->wExtra[1]) = lpmbInit;
-		lpmb = MsgBoxGetStorageHeader(hWnd);
+		lpmb = (LPMSGBOX)createStruct->lpCreateParams;
+		if (lpmb == NULL) break;
+		*((LPMSGBOX *)&wndPtr->wExtra[1]) = lpmb;
+#ifdef DEBUG_MSGBOX
+		printf("MessageBox WM_CREATE title='%s' str='%s' !\n", 
+									lpmb->Title, lpmb->Str);
+#endif
 		GetClientRect(hWnd, &rect);
 		CopyRect(&lpmb->rectStr, &rect);
 		lpmb->rectStr.bottom -= 32;
@@ -255,6 +270,7 @@
 		printf("MessageBox WM_PAINT !\n");
 #endif
 		lpmb = MsgBoxGetStorageHeader(hWnd);
+		if (lpmb == NULL) break;
 		CopyRect(&rect, &lpmb->rectStr);
 		hDC = BeginPaint(hWnd, &ps);
 		OldTextColor = SetTextColor(hDC, 0x00000000);
@@ -278,6 +294,7 @@
 #endif
 	    ReleaseCapture();
 	    lpmb = MsgBoxGetStorageHeader(hWnd);
+		if (lpmb == NULL) break;
 	    lpmb->ActiveFlg = FALSE;
 	    if (lpmb->hIcon) DestroyIcon(lpmb->hIcon);
 	    if (lpmb->hWndYes) DestroyWindow(lpmb->hWndYes);
@@ -289,6 +306,7 @@
 	    break;
 	case WM_COMMAND:
 	    lpmb = MsgBoxGetStorageHeader(hWnd);
+		if (lpmb == NULL) break;
 	    if (wParam < IDOK || wParam > IDNO) return(0);
 	    lpmb->wRetVal = wParam;
 #ifdef DEBUG_MSGBOX
@@ -298,6 +316,7 @@
 	    break;
 	case WM_CHAR:
 	    lpmb = MsgBoxGetStorageHeader(hWnd);
+		if (lpmb == NULL) break;
 		if (wParam >= 'a' || wParam <= 'z') wParam -= 'a' - 'A';
 		switch(wParam) {
 			case 'Y':
diff --git a/misc/shell.c b/misc/shell.c
index f60d9ff..bb86353 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -8,64 +8,202 @@
 #include <unistd.h>
 #include "windows.h"
 
+typedef DWORD HKEY;
+typedef FAR LONG *LPWORD;
+DECLARE_HANDLE(HDROP);
+
+extern HINSTANCE hSysRes;
 
 /*************************************************************************
- *				RegOpenKey			[SHELL.1]
+ *				RegOpenKey		[SHELL.1]
  */
-int RegOpenKey(void) 
+LONG RegOpenKey(HKEY k, LPCSTR s, HKEY FAR *p)
 {
-	printf("RegOpenKey : Empty Stub !!!\n");
+	fprintf(stderr, "RegOpenKey : Empty Stub !!!\n");
 }
 
+
 /*************************************************************************
  *				RegCreateKey		[SHELL.2]
  */
-int RegCreateKey(void) 
+LONG RegCreateKey(HKEY k, LPCSTR s, HKEY FAR *p)
 {
-	printf("RegCreateKey : Empty Stub !!!\n");
+	fprintf(stderr, "RegCreateKey : Empty Stub !!!\n");
 }
 
+
 /*************************************************************************
- *				RegCloseKey			[SHELL.3]
+ *				RegCloseKey		[SHELL.3]
  */
-int RegCloseKey(void) 
+LONG RegCloseKey(HKEY k)
 {
-	printf("RegCloseKey : Empty Stub !!!\n");
+	fprintf(stderr, "RegCloseKey : Empty Stub !!!\n");
 }
 
+
 /*************************************************************************
  *				RegDeleteKey		[SHELL.4]
  */
-int RegDeleteKey(void) 
+LONG RegDeleteKey(HKEY k, LPCSTR s)
 {
-	printf("RegDeleteKey : Empty Stub !!!\n");
+	fprintf(stderr, "RegDeleteKey : Empty Stub !!!\n");
+}
+
+
+/*************************************************************************
+ *				RegSetValue		[SHELL.5]
+ */
+LONG RegSetValue(HKEY k, LPCSTR s1, DWORD dw, LPCSTR s2, DWORD dw2)
+{
+	fprintf(stderr, "RegSetValue : Empty Stub !!!\n");
+}
+
+
+/*************************************************************************
+ *				RegQueryValue		[SHELL.6]
+ */
+LONG RegQueryValue(HKEY k, LPCSTR s, LPSTR s2, LONG FAR *p)
+{
+	fprintf(stderr, "RegQueryValue : Empty Stub !!!\n");
+}
+
+
+/*************************************************************************
+ *				RegEnumKey		[SHELL.7]
+ */
+LONG RegEnumKey(HKEY k, DWORD dw, LPSTR s, DWORD dw2)
+{
+	fprintf(stderr, "RegEnumKey : Empty Stub !!!\n");
+}
+
+/*************************************************************************
+ *				DragAcceptFiles		[SHELL.9]
+ */
+void DragAcceptFiles(HWND hWnd, BOOL b)
+{
+	fprintf(stderr, "DragAcceptFiles : Empty Stub !!!\n");
+}
+
+
+/*************************************************************************
+ *				DragQueryFile		[SHELL.11]
+ */
+void DragQueryFile(HDROP h, UINT u, LPSTR u2, UINT u3)
+{
+	fprintf(stderr, "DragQueryFile : Empty Stub !!!\n");
+
+}
+
+
+/*************************************************************************
+ *				DragFinish		[SHELL.12]
+ */
+void DragFinish(HDROP h)
+{
+	fprintf(stderr, "DragFinish : Empty Stub !!!\n");
+
+}
+
+
+/*************************************************************************
+ *				DragQueryPoint		[SHELL.13]
+ */
+BOOL DragQueryPoint(HDROP h, POINT FAR *p)
+{
+	fprintf(stderr, "DragQueryPoinyt : Empty Stub !!!\n");
+
 }
 
 
 /*************************************************************************
  *				ShellExecute		[SHELL.20]
  */
-int ShellExecute(LPSTR ptr)
+HINSTANCE ShellExecute(HWND hwnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, int iShowCmd)
 {
-	printf("ShellExecute : Empty Stub !!!\n");
+	fprintf(stderr, "ShellExecute : Empty Stub !!!\n");
 }
 
 
 /*************************************************************************
+ *				FindExecutable		[SHELL.21]
+ */
+HINSTANCE FindExecutable(LPCSTR lpFile, LPCSTR lpDirectory, LPSTR lpResult)
+{
+	fprintf(stderr, "FindExecutable : Empty Stub !!!\n");
+
+}
+
+char AppName[256], AppMisc[256];
+
+/*************************************************************************
+ *				AboutDlgProc		[SHELL.33]
+ */
+INT AboutDlgProc(HWND hWnd, WORD msg, WORD wParam, LONG lParam)
+{
+	char temp[256];
+
+	switch(msg) {
+        case WM_INITDIALOG:
+		sprintf(temp, "About %s", AppName);
+/*		SetDlgItemText(hWnd, 0, temp);*/
+		SetDlgItemText(hWnd, 100, AppMisc);
+		break;
+
+        case WM_COMMAND:
+		switch (wParam) {
+		case IDOK:
+			EndDialog(hWnd, TRUE);
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
+
+/*************************************************************************
+ *				ShellAbout		[SHELL.22]
+ */
+INT ShellAbout(HWND hWnd, LPCSTR szApp, LPCSTR szOtherStuff, HICON hIcon)
+{
+	fprintf(stderr, "ShellAbout ! (%s, %s)\n", szApp, szOtherStuff);
+
+	strcpy(AppName, szApp);
+	strcpy(AppMisc, szOtherStuff);
+
+	return DialogBox(hSysRes, "SHELL_ABOUT_MSGBOX", hWnd, (FARPROC)AboutDlgProc);
+}
+
+
+/*************************************************************************
+ *				ExtractIcon		[SHELL.34]
+ */
+HICON ExtractIcon(HINSTANCE hInst, LPCSTR lpszExeFileName, UINT nIconIndex)
+{
+	fprintf(stderr, "ExtractIcon : Empty Stub !!!\n");
+
+}
+
+
+/*************************************************************************
+ *				ExtractAssociatedIcon	[SHELL.36]
+ */
+HICON ExtractAssociatedIcon(HINSTANCE hInst,LPSTR lpIconPath, LPWORD lpiIcon)
+{
+	fprintf(stderr, "ExtractAssociatedIcon : Empty Stub !!!\n");
+}
+
+/*************************************************************************
  *				RegisterShellHook	[SHELL.102]
  */
 int RegisterShellHook(void *ptr) 
 {
-	printf("RegisterShellHook : Empty Stub !!!\n");
+	fprintf(stderr, "RegisterShellHook : Empty Stub !!!\n");
 }
 
+
 /*************************************************************************
  *				ShellHookProc		[SHELL.103]
  */
 int ShellHookProc(void) 
 {
-	printf("ShellHookProc : Empty Stub !!!\n");
+	fprintf(stderr, "ShellHookProc : Empty Stub !!!\n");
 }
-
-
-
diff --git a/misc/sound.c b/misc/sound.c
index c976a97..0728953 100644
--- a/misc/sound.c
+++ b/misc/sound.c
@@ -63,6 +63,40 @@
   return 0;
 }
 
+int WaitSoundState(int x)
+{
+	fprintf(stderr, "WaitSoundState(%d)\n", x);
+}
+
+SyncAllVoices(void)
+{
+	fprintf(stderr, "SyncAllVoices()\n");
+}
+
+int CountVoiceNotes(int x)
+{
+	fprintf(stderr, "CountVoiceNotes(%d)\n", x);
+}
+
+LPINT GetThresholdEvent(void)
+{
+	fprintf(stderr, "GetThresholdEvent()\n");
+}
+
+GetThresholdStatus(void)
+{
+	fprintf(stderr, "GetThresholdStatus()\n");
+}
+
+int SetVoiceThreshold(int a, int b)
+{
+	fprintf(stderr, "SetVoiceThreshold(%d,%d)\n", a, b);
+}
+
+void DoBeep(void)
+{
+	fprintf(stderr, "BEEP!\n");
+}
 
 /*
 11   pascal  WAITSOUNDSTATE(word) WaitSoundState(1)
@@ -71,7 +105,4 @@
 14   pascal  GETTHRESHOLDEVENT() GetThresholdEvent()
 15   pascal  GETTHRESHOLDSTATUS() GetThresholdStatus()
 16   pascal  SETVOICETHRESHOLD(word word) SetVoiceThreshold(1 2)
-
-
-
 */
diff --git a/miscemu/emulate.c b/miscemu/emulate.c
index b43f9f3..fd9cc05 100644
--- a/miscemu/emulate.c
+++ b/miscemu/emulate.c
@@ -18,8 +18,8 @@
 int
 WIN87_fpmath()
 {
-  printf( "_fpmath: (%d)\n",_BX);
-
+  printf( "_fpmath: (%x:%x %x %x)\n",_CONTEXT->sc_cs, _CONTEXT->sc_eip, 
+	 _CONTEXT->sc_es, _BX);
 
   switch(_BX )
     {
diff --git a/objects/bitblt.c b/objects/bitblt.c
index 24f05e0..4302362 100644
--- a/objects/bitblt.c
+++ b/objects/bitblt.c
@@ -63,7 +63,7 @@
     printf( "BitBlt: %d %d,%d %dx%d %d %d,%d %08x\n",
 	   hdcDest, xDest, yDest, width, height, hdcSrc, xSrc, ySrc, rop );
 #endif
-
+	if (width == 0 || height == 0) return FALSE;
     if ((rop & 0xcc0000) == ((rop & 0x330000) << 2))
 	return PatBlt( hdcDest, xDest, yDest, width, height, rop );
 
@@ -311,6 +311,7 @@
     DC *dcDest, *dcSrc;
     XImage *sxi, *dxi;
     WORD stretchmode;
+	BOOL	flg;
 
 #ifdef DEBUG_GDI     
     fprintf(stderr, "StretchBlt: %d %d,%d %dx%d %d %d,%d %dx%d %08x\n",
@@ -320,6 +321,8 @@
            ((DC *)GDI_GetObjPtr(hdcDest, DC_MAGIC))->w.stretchBltMode);	
 #endif 
 
+	if (widthDest == 0 || heightDest == 0) return FALSE;
+	if (widthSrc == 0 || heightSrc == 0) return FALSE;
     if ((rop & 0xcc0000) == ((rop & 0x330000) << 2))
         return PatBlt( hdcDest, xDest, yDest, widthDest, heightDest, rop );
 
diff --git a/windows/event.c b/windows/event.c
index b69223e..f2402b3 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -17,9 +17,11 @@
 #include "class.h"
 #include "message.h"
 
+#ifdef ndef
 #ifndef FamilyAmoeba
 typedef char *XPointer;
 #endif
+#endif
 
 #define NB_BUTTONS      3     /* Windows can handle 3 buttons */
 
diff --git a/windows/mdi.c b/windows/mdi.c
index ae04cd4..b2aadff 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -531,7 +531,7 @@
 
 	if (hbitmapClose == 0)
 	{
-	    hbitmapClose     = LoadBitmap(0, MAKEINTRESOURCE(OBM_CLOSE));
+	    hbitmapClose     = LoadBitmap(0, MAKEINTRESOURCE(OBM_OLD_CLOSE));
 	    hbitmapMaximized = LoadBitmap(0, MAKEINTRESOURCE(OBM_RESTORE));
 	}
 
diff --git a/windows/nonclient.c b/windows/nonclient.c
index 078bd00..a717031 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -524,9 +524,9 @@
     WND *wndPtr = WIN_FindWndPtr( hwnd );
 
 #ifdef DEBUG_NONCLIENT
-    printf( "NC_HandleNCPaint: %d %d\n", hwnd, hrgn );
+    printf( "NC_DoNCPaint: %d %d\n", hwnd, hrgn );
 #endif
-
+    if (!IsWindowVisible(hwnd)) return;
     if (!wndPtr || !hrgn) return;
     if (!(wndPtr->dwStyle & (WS_BORDER | WS_DLGFRAME | WS_THICKFRAME)))
 	return;  /* Nothing to do! */
@@ -1058,26 +1058,7 @@
     ScreenToClient(hwnd, &pt);
     pt.y += lppop->rect.bottom;
     SetCapture(hwnd);
-    if (!MenuButtonDown(hwnd, lppop, pt.x, pt.y)) {
-	    do {
-		if (!GetMessage(&msg, (HWND)NULL, 0, 0)) break;
-		ScreenToClient(hwnd, &msg.pt);
-		msg.pt.y += lppop->rect.bottom;
-		switch(msg.message) {
-		case WM_LBUTTONUP:
-		    MenuButtonUp(hwnd, lppop, msg.pt.x, msg.pt.y);
-		    break;
-		case WM_MOUSEMOVE:
-		    MenuMouseMove(hwnd, lppop, msg.wParam, msg.pt.x, msg.pt.y);
-		    break;
-		default:
-		    TranslateMessage(&msg);
-		    DispatchMessage(&msg);
-		    break;
-		}
-	    } while (msg.message != WM_LBUTTONUP);
-	    ReleaseCapture();
-	}
+    MenuButtonDown(hwnd, lppop, pt.x, pt.y);
     GlobalUnlock(wndPtr->wIDmenu);
 }
 
diff --git a/windows/win.c b/windows/win.c
index 799cf7e..aac7dcd 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -245,8 +245,9 @@
     XSetWindowAttributes win_attr;
 
 #ifdef DEBUG_WIN
-    printf( "CreateWindowEx: %d '%s' '%s' %d,%d %dx%d %08x %x\n",
-	   exStyle, className, windowName, x, y, width, height, style, parent);
+    printf( "CreateWindowEx: %04X '%s' '%s' %04X %d,%d %dx%d %04X %04X %04X %08X\n",
+				exStyle, className, windowName, style, x, y, width, height, 
+				parent, menu, instance, data);
 #endif
 
     if (x == CW_USEDEFAULT) x = y = 0;
@@ -431,6 +432,9 @@
       /* Create a copy of SysMenu */
     if (style & WS_SYSMENU) wndPtr->hSysMenu = CopySysMenu();
 
+	/* Register window in current task windows list */
+	AddWindowToTask(GetCurrentTask(), hwnd);
+
       /* Set window cursor */
     if (classPtr->wc.hCursor) CURSOR_SetWinCursor( hwnd, classPtr->wc.hCursor);
     else CURSOR_SetWinCursor( hwnd, LoadCursor( 0, IDC_ARROW ));
@@ -474,8 +478,10 @@
 	DestroyWindow( wndPtr->hwndChild );
     SendMessage( hwnd, WM_NCDESTROY, 0, 0 );
 
-      /* Remove the window from the linked list */
+      /* Remove the window from current task windows list */
+	RemoveWindowFromTask(GetCurrentTask(), hwnd);
 
+      /* Remove the window from the linked list */
     WIN_UnlinkWindow( hwnd );
 
       /* Destroy the window */
@@ -957,6 +963,16 @@
 }
 
 /*******************************************************************
+ *			AnyPopup		[USER.52]
+ */
+BOOL AnyPopup()
+{
+	printf("EMPTY STUB !! AnyPopup !\n");
+	return FALSE;
+}
+
+
+/*******************************************************************
  *			SetSysModalWindow		[USER.188]
  */
 HWND SetSysModalWindow(HWND hWnd)
@@ -967,6 +983,7 @@
 	return hWndOldModal;
 }
 
+
 /*******************************************************************
  *			GetSysModalWindow		[USER.189]
  */