Release 940722

Mon Jul 18 23:55:13 MET DST 1994

	* [if1632/call.S]
	CallTo16(): added `mov %eax,%edx' just before lcall,
	to make sure that DX contain the DLL's hinstance when
	initialised.

	CallTo32_16() added, equal to CallTo32() except for
	one thing: it saves DX and 

	* [tools/build.c]
	Added some code to support 16 and 32 bit return values.

	* [1632/{kernel,user}.spec]
	Changed most of the `pascal' style to pascal_16 when
	function returned a 16bit value.

Tue Jul 19 18:40:25 1994  Alexandre Julliard  (julliard@lamisun.epfl.ch)

	* [controls/menu.c]
	Reorganized sizing and drawing code to implement multi-line menus.
	Implemented MENUBREAK style.
	Use system colors to draw menus.

	* [objects/color.c]
	Bug fix in COLOR_IsSolid().

	* [objects/font.c]
	Bug fix in FONT_GetMetrics(): calculate average character width
	only on existing chars (dialogs look much better).

	* [objects/text.c]
	Bug fix in DrawText(): use text color to underline mnemonic.

	* [windows/nonclient.c]
	Changed WM_NCHITTEST handling to cope with multi-line menu bars.

	* [windows/syscolor.c]
	Added system objects for menu colors.

Mon Jul 18 19:32:08 PDT 1994  Andrew Lagodzinski  (andrew@netcom.com)

        * [controls/menu.c]
        Fixed bug in SelectPrevItem that caused seperators to not be
	skipped when using the up arrow key.
diff --git a/ChangeLog b/ChangeLog
index 96b0bbb..e1c6f0a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,51 @@
 ----------------------------------------------------------------------
+Mon Jul 18 23:55:13 MET DST 1994
+
+	* [if1632/call.S]
+	CallTo16(): added `mov %eax,%edx' just before lcall,
+	to make sure that DX contain the DLL's hinstance when
+	initialised.
+
+	CallTo32_16() added, equal to CallTo32() except for
+	one thing: it saves DX and 
+
+	* [tools/build.c]
+	Added some code to support 16 and 32 bit return values.
+
+	* [1632/{kernel,user}.spec]
+	Changed most of the `pascal' style to pascal_16 when
+	function returned a 16bit value.
+
+Tue Jul 19 18:40:25 1994  Alexandre Julliard  (julliard@lamisun.epfl.ch)
+
+	* [controls/menu.c]
+	Reorganized sizing and drawing code to implement multi-line menus.
+	Implemented MENUBREAK style.
+	Use system colors to draw menus.
+
+	* [objects/color.c]
+	Bug fix in COLOR_IsSolid().
+
+	* [objects/font.c]
+	Bug fix in FONT_GetMetrics(): calculate average character width
+	only on existing chars (dialogs look much better).
+
+	* [objects/text.c]
+	Bug fix in DrawText(): use text color to underline mnemonic.
+
+	* [windows/nonclient.c]
+	Changed WM_NCHITTEST handling to cope with multi-line menu bars.
+
+	* [windows/syscolor.c]
+	Added system objects for menu colors.
+
+Mon Jul 18 19:32:08 PDT 1994  Andrew Lagodzinski  (andrew@netcom.com)
+
+        * [controls/menu.c]
+        Fixed bug in SelectPrevItem that caused seperators to not be
+	skipped when using the up arrow key.
+
+----------------------------------------------------------------------
 Thu Jul 14 17:50:45 1994  Bob Amstadt  (bob@pooh)
 
 	* [Configure]
diff --git a/controls/menu.c b/controls/menu.c
index 5e3dee5..18ca832 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -11,6 +11,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include "windows.h"
+#include "syscolor.h"
 #include "sysmetrics.h"
 #include "prototypes.h"
 #include "menu.h"
@@ -22,6 +23,16 @@
 #define SC_SYSMENU			SC_SCREENSAVE+2
 #define SC_ABOUTWINEDLG		SC_SCREENSAVE+3
 
+  /* Dimension of the menu bitmaps */
+static WORD check_bitmap_width = 0, check_bitmap_height = 0;
+static WORD arrow_bitmap_width = 0, arrow_bitmap_height = 0;
+
+  /* Space between 2 menu bar items */
+#define MENU_BAR_ITEMS_SPACE  16
+
+  /* Height of a separator item */
+#define SEPARATOR_HEIGHT      5
+
 extern HINSTANCE hSysRes;
 HMENU	hSysMenu = 0;
 HBITMAP hStdCheck = 0;
@@ -45,13 +56,11 @@
 LPMENUITEM MenuFindItemBySelKey(LPPOPUPMENU lppop, WORD key, WORD *lpRet);
 BOOL ActivateMenuBarFocus(HWND hWnd);
 BOOL MenuFocusLoop(HWND hWnd, LPPOPUPMENU lpmenu);
-void PopupMenuCalcSize(HWND hwnd);
-void MenuBarCalcSize(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop);
 LPMENUITEM FindMenuItem(HMENU hMenu, WORD nPos, WORD wFlags);
 LPMENUITEM GetMenuItemPtr(LPPOPUPMENU menu, WORD nPos);
 WORD GetSelectionKey(LPSTR str);
 LPSTR GetShortCutString(LPSTR str);
-WORD GetShortCutPos(LPSTR str);
+int GetShortCutPos(LPSTR str);
 BOOL HideAllSubPopupMenu(LPPOPUPMENU menu);
 void InitStdBitmaps();
 HMENU CopySysMenu();
@@ -60,10 +69,287 @@
 
 BOOL FAR PASCAL AboutWine_Proc(HWND hDlg, WORD msg, WORD wParam, LONG lParam);
 
+
+/***********************************************************************
+ *           MENU_CalcItemSize
+ *
+ * Calculate the size of the menu item and store it in lpitem->rect.
+ */
+static void MENU_CalcItemSize( HDC hdc, LPMENUITEM lpitem,
+			       int orgX, int orgY, BOOL menuBar )
+{
+    DWORD dwSize;
+    SetRect( &lpitem->rect, orgX, orgY, orgX, orgY );
+
+    if (lpitem->item_flags & MF_SEPARATOR)
+    {
+	lpitem->rect.bottom += SEPARATOR_HEIGHT;
+	return;
+    }
+
+    if (!menuBar) lpitem->rect.right += check_bitmap_width+arrow_bitmap_width;
+
+    if (lpitem->item_flags & MF_BITMAP)
+    {
+	BITMAP bm;
+	HBITMAP hbitmap = (HBITMAP)LOWORD((LONG)lpitem->item_text);
+	GetObject(hbitmap, sizeof(BITMAP), (LPSTR)&bm);
+	lpitem->rect.right  += bm.bmWidth;
+	lpitem->rect.bottom += bm.bmHeight;
+	return;
+    }
+    
+      /* If we get here, then it is a text item */
+
+    if (menuBar) lpitem->rect.right += MENU_BAR_ITEMS_SPACE;
+    dwSize = GetTextExtent( hdc, lpitem->item_text, strlen(lpitem->item_text));
+    lpitem->rect.right  += LOWORD(dwSize);
+    lpitem->rect.bottom += max( HIWORD(dwSize), SYSMETRICS_CYMENU );
+}
+
+
+/***********************************************************************
+ *           MENU_PopupMenuCalcSize
+ *
+ * Calculate the size of a popup menu.
+ */
+static void MENU_PopupMenuCalcSize( HWND hwnd )
+{
+    LPPOPUPMENU lppop;
+    LPMENUITEM  lpitem, lpitemStart, lptmp;
+    WND *wndPtr;
+    HDC hdc;
+    int orgX, orgY, maxX;
+
+    if (!(lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr))) return;
+    SetRect( &lppop->rect, 0, 0, 0, 0 );
+    lppop->Width = lppop->Height = 0;
+    if (lppop->nItems == 0) return;
+    hdc = GetDC( hwnd );
+    maxX = 0;
+    lpitemStart = lppop->firstItem;
+    while (lpitemStart != NULL)
+    {
+	orgX = maxX;
+	orgY = 0;
+
+	  /* Parse items until column break or end of menu */
+	for (lpitem = lpitemStart; lpitem != NULL; lpitem = lpitem->next)
+	{
+	    if ((lpitem != lpitemStart) &&
+		(lpitem->item_flags & (MF_MENUBREAK | MF_MENUBARBREAK))) break;
+	    MENU_CalcItemSize( hdc, lpitem, orgX, orgY, FALSE );
+	    maxX = max( maxX, lpitem->rect.right );
+	    orgY = lpitem->rect.bottom;
+	}
+
+	  /* Finish the column (set all items to the largest width found) */
+	for (lptmp = lpitemStart; lptmp != lpitem; lptmp = lptmp->next)
+	{
+	    lptmp->rect.right = maxX;
+	}
+
+	  /* And go to the next column */
+	lppop->Height = max( lppop->Height, orgY );
+	lpitemStart = lpitem;
+    }
+
+    lppop->Width  = maxX;
+    SetRect( &lppop->rect, 0, 0, lppop->Width, lppop->Height );
+    ReleaseDC( hwnd, hdc );
+}
+
+
+/***********************************************************************
+ *           MENU_MenuBarCalcSize
+ *
+ * Calculate the size of the menu bar.
+ */
+static void MENU_MenuBarCalcSize( HDC hdc, LPRECT lprect, LPPOPUPMENU lppop )
+{
+    LPMENUITEM lpitem, lpitemStart, lptmp;
+    int orgX, orgY, maxY;
+
+    if ((lprect == NULL) || (lppop == NULL)) return;
+    if (lppop->nItems == 0) return;
+#ifdef DEBUG_MENUCALC
+	printf("MenuBarCalcSize left=%d top=%d right=%d bottom=%d !\n", 
+		lprect->left, lprect->top, lprect->right, lprect->bottom);
+#endif
+    lppop->Width  = lprect->right - lprect->left;
+    lppop->Height = 0;
+    maxY = lprect->top;
+
+    lpitemStart = lppop->firstItem;
+    while (lpitemStart != NULL)
+    {
+	orgX = lprect->left;
+	orgY = maxY;
+
+	  /* Parse items until line break or end of menu */
+	for (lpitem = lpitemStart; lpitem != NULL; lpitem = lpitem->next)
+	{
+	    if ((lpitem != lpitemStart) &&
+		(lpitem->item_flags & (MF_MENUBREAK | MF_MENUBARBREAK))) break;
+	    MENU_CalcItemSize( hdc, lpitem, orgX, orgY, TRUE );
+	    if (lpitem->rect.right > lprect->right)
+	    {
+		if (lpitem != lpitemStart) break;
+		else lpitem->rect.right = lprect->right;
+	    }
+	    maxY = max( maxY, lpitem->rect.bottom );
+	    orgX = lpitem->rect.right;
+	}
+
+	  /* Finish the line (set all items to the largest height found) */
+	for (lptmp = lpitemStart; lptmp != lpitem; lptmp = lptmp->next)
+	{
+	    lptmp->rect.bottom = maxY;
+	}
+
+	  /* And go to the next line */
+	lpitemStart = lpitem;
+    }
+
+    lprect->bottom = maxY;
+    lppop->Height = lprect->bottom - lprect->top;
+    CopyRect( &lppop->rect, lprect );
+}
+
+
+/***********************************************************************
+ *           MENU_DrawMenuItem
+ *
+ * Draw a single menu item.
+ */
+static void MENU_DrawMenuItem( HDC hdc, LPMENUITEM lpitem,
+			       LPRECT menuRect, BOOL menuBar )
+{
+    RECT rect;
+
+    if (menuBar && (lpitem->item_flags & MF_SEPARATOR)) return;
+    rect = lpitem->rect;
+
+      /* Draw the background */
+
+    if (lpitem->item_flags & MF_HILITE)
+	FillRect( hdc, &rect, sysColorObjects.hbrushHighlight );
+    else FillRect( hdc, &rect, sysColorObjects.hbrushMenu );
+    SetBkMode( hdc, TRANSPARENT );
+
+      /* Draw the separator bar (if any) */
+
+    if (!menuBar && (lpitem->item_flags & MF_MENUBARBREAK))
+    {
+	SelectObject( hdc, sysColorObjects.hpenWindowFrame );
+	MoveTo( hdc, rect.left, menuRect->top );
+	LineTo( hdc, rect.left, menuRect->bottom );
+    }
+    if (lpitem->item_flags & MF_SEPARATOR)
+    {
+	SelectObject( hdc, sysColorObjects.hpenWindowFrame );
+	MoveTo( hdc, rect.left, rect.top + SEPARATOR_HEIGHT/2 );
+	LineTo( hdc, rect.right, rect.top + SEPARATOR_HEIGHT/2 );
+    }
+
+    if (!menuBar)
+    {
+	  /* Draw the check mark */
+
+	if (lpitem->item_flags & MF_CHECKED)
+	{
+	    HDC hMemDC = CreateCompatibleDC( hdc );
+	    if (lpitem->hCheckBit == 0)	SelectObject(hMemDC, hStdCheck);
+	    else SelectObject(hMemDC, lpitem->hCheckBit);
+	    BitBlt( hdc, rect.left,
+		    (rect.top + rect.bottom - check_bitmap_height) / 2,
+		    check_bitmap_width, check_bitmap_height,
+		    hMemDC, 0, 0, SRCCOPY );
+	    DeleteDC( hMemDC );
+	}
+	else  /* Not checked */
+	{
+	    if (lpitem->hUnCheckBit != 0)
+	    {
+		HDC hMemDC = CreateCompatibleDC( hdc );
+		SelectObject(hMemDC, lpitem->hUnCheckBit);
+		BitBlt( hdc, rect.left,
+		       (rect.top + rect.bottom - check_bitmap_height) / 2,
+		       check_bitmap_width, check_bitmap_height,
+		       hMemDC, 0, 0, SRCCOPY );
+		DeleteDC( hMemDC );
+	    }
+	}
+
+	  /* Draw the popup-menu arrow */
+
+	if (lpitem->item_flags & MF_POPUP)
+	{
+	    HDC hMemDC = CreateCompatibleDC( hdc );
+	    SelectObject(hMemDC, hStdMnArrow);
+	    BitBlt( hdc, rect.right-arrow_bitmap_width,
+		    (rect.top + rect.bottom - arrow_bitmap_height) / 2,
+		    arrow_bitmap_width, arrow_bitmap_height,
+		    hMemDC, 0, 0, SRCCOPY );
+	    DeleteDC(hMemDC);
+	}
+
+	rect.left += check_bitmap_width;
+	rect.right -= arrow_bitmap_width;
+    }
+
+      /* Setup colors */
+
+    if (lpitem->item_flags & MF_HILITE)
+    {
+	SetTextColor( hdc, GetSysColor( COLOR_HIGHLIGHTTEXT ) );
+	SetBkColor( hdc, GetSysColor( COLOR_HIGHLIGHT ) );
+    }
+    else
+    {
+	if (lpitem->item_flags & MF_GRAYED)
+	    SetTextColor( hdc, GetSysColor( COLOR_GRAYTEXT ) );
+	else
+	    SetTextColor( hdc, GetSysColor( COLOR_MENUTEXT ) );
+	SetBkColor( hdc, GetSysColor( COLOR_MENU ) );
+    }
+
+      /* Draw the item text or bitmap */
+
+    if (lpitem->item_flags & MF_BITMAP)
+    {
+	HBITMAP hbitmap = (HBITMAP)LOWORD((LONG)lpitem->item_text);
+	HDC hMemDC = CreateCompatibleDC( hdc );
+	SelectObject( hMemDC, hbitmap );
+	BitBlt( hdc, rect.left, rect.top,
+	        rect.right-rect.left, rect.bottom-rect.top,
+	        hMemDC, 0, 0, SRCCOPY );
+	DeleteDC( hMemDC );
+	return;
+    }
+    else  /* No bitmap */
+    {
+	int x = GetShortCutPos(lpitem->item_text);
+	if (menuBar)
+	{
+	    rect.left += MENU_BAR_ITEMS_SPACE / 2;
+	    rect.right -= MENU_BAR_ITEMS_SPACE / 2;
+	}
+	if (x != -1)
+	{
+	    DrawText( hdc, lpitem->item_text, x, &rect,
+		      DT_LEFT | DT_VCENTER | DT_SINGLELINE );
+	    DrawText( hdc, lpitem->item_text + x, -1, &rect,
+		      DT_RIGHT | DT_VCENTER | DT_SINGLELINE );
+	}
+	else DrawText( hdc, lpitem->item_text, -1, &rect,
+		       DT_LEFT | DT_VCENTER | DT_SINGLELINE );
+    }
+}
+
+
 /***********************************************************************
  *           PopupMenuWndProc
-				SetWindow
-				SetWindow
  */
 LONG PopupMenuWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam )
 {    
@@ -148,19 +434,6 @@
 			break;
 			}
 		lppop->FocusedItem = (WORD)-1;
-		if (!lppop->BarFlag) {
-			PopupMenuCalcSize(hwnd);
-/*			ResetHiliteFlags(lppop); */
-#ifdef DEBUG_MENU
-			printf("PopupMenuWndProc hWnd=%04X WM_SHOWWINDOW Width=%d Height=%d !\n", 
-									hwnd, lppop->Width, lppop->Height);
-#endif
-			SetWindowPos(hwnd, 0, 0, 0, lppop->Width + 2, lppop->Height, 
-									SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE );
-#ifdef DEBUG_MENU
-			printf("PopupMenuWndProc // End of WM_SHOWWINDOW !\n");
-#endif
-			}
     	break;
 	case WM_LBUTTONDOWN:
 		lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
@@ -335,12 +608,7 @@
 #ifdef DEBUG_MENU
 		printf("PopupMenuWndProc // WM_PAINT received !\n");
 #endif
-		lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
-		if (lppop == NULL) break;
-		if (!lppop->BarFlag) {
-			PopupMenuCalcSize(hwnd);
-			StdDrawPopupMenu(hwnd);
-			}
+		StdDrawPopupMenu(hwnd);
 		break;
 	default:
 		return DefWindowProc(hwnd, message, wParam, lParam);
@@ -365,7 +633,7 @@
 		GetClientRect(hWnd, &rect);
 		if (lppop->BarFlag) {
 			GetWindowRect(hWnd, &rect);
-			y = rect.top + lppop->rect.bottom;
+			y = rect.top + lpitem->rect.bottom;
 			TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, 
 				rect.left + lpitem->rect.left, 
 				y, 0, lppop->ownerWnd, (LPRECT)NULL);
@@ -432,7 +700,7 @@
 			lppop2->hWndParent = hWnd;
 			if (lppop->BarFlag) {
 				GetWindowRect(hWnd, &rect);
-				y = rect.top + lppop->rect.bottom;
+				y = rect.top + lpitem->rect.bottom;
 				ReleaseCapture(); 
 				if (MenuHasFocus) {
 					TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, 
@@ -551,7 +819,7 @@
 		{
 		    lppop2->hWndParent = hWnd;
 		    GetWindowRect(hWnd, &rect);
-		    rect.top += lppop->rect.bottom;
+		    rect.top += lpitem->rect.bottom;
 		    TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, 
 				   rect.left + lpitem->rect.left, rect.top, 
 				   0, lppop->ownerWnd, (LPRECT)NULL);
@@ -581,7 +849,7 @@
 		nIndex--;
 		lpitem = GetMenuItemPtr(lppop, nIndex);
 		}
-	while (lpitem != NULL && lpitem->item_flags & MF_HILITE) {
+	while (lpitem != NULL && lpitem->item_flags & MF_SEPARATOR) {
 		nIndex--;
 		lpitem = GetMenuItemPtr(lppop, nIndex);
 		}
@@ -622,63 +890,46 @@
 	lpitem = lppop->firstItem;
 	for(i = 0; i < lppop->nItems; i++) {
 		if (lpitem == NULL) return;
-		lpitem->item_flags &= 0xFFFF ^ MF_HILITE;
+		lpitem->item_flags &= ~MF_HILITE;
 		lpitem = (LPMENUITEM)lpitem->next;
 		}
 }
 
 
-void MenuItemSelect0(HWND hWnd, LPPOPUPMENU lppop, 
-				LPMENUITEM lpitem, WORD wIndex)
-{
-    LPMENUITEM lpprev;
-    
-    if (lppop == NULL) 
-	return;
-    if (lppop->FocusedItem != (WORD)-1) 
-    {
-	lpprev = GetMenuItemPtr(lppop, lppop->FocusedItem);
-	if (lpprev != NULL) 
-	{
-	    lpprev->item_flags &= MF_HILITE ^ 0xFFFF;
-	    if ((lpprev->item_flags & MF_POPUP) == MF_POPUP)
-		HideAllSubPopupMenu(lppop);
-	    if (lppop->BarFlag)
-		DrawMenuBar(hWnd);
-	    else 
-	    {
-		InvalidateRect(hWnd, &lpprev->rect, TRUE);
-		UpdateWindow(hWnd);
-	    }
-	}
-    }
-    lppop->FocusedItem = wIndex;
-    if (lpitem == NULL || wIndex == (WORD)-1) 
-    {
-	ResetHiliteFlags(lppop);
-	if (lppop->BarFlag) DrawMenuBar(hWnd);
-    }
-    else 
-    {
-	lpitem->item_flags |= MF_HILITE;
-	if (lppop->BarFlag)
-	    DrawMenuBar(hWnd);
-	else 
-	{
-	    InvalidateRect(hWnd, &lpitem->rect, TRUE);
-	    UpdateWindow(hWnd);
-	}
-	SendMessage(hWnd, WM_MENUSELECT, lpitem->item_id, 
-		    MAKELONG(0, lpitem->item_flags));
-    }
-}
-
-
 void MenuItemSelect(HWND hWnd, LPPOPUPMENU lppop, WORD wIndex)
 {
-	LPMENUITEM lpitem;
-    lpitem = GetMenuItemPtr(lppop, wIndex);
-	MenuItemSelect0(hWnd, lppop, lpitem, wIndex);
+    LPMENUITEM lpitem;
+    HDC hdc;
+
+    if (lppop == NULL) return;
+    if (lppop->BarFlag) hdc = GetDCEx( hWnd, 0, DCX_CACHE | DCX_WINDOW );
+    else hdc = GetDC( hWnd );
+
+      /* Clear previous highlighted item */
+    if (lppop->FocusedItem != (WORD)-1) 
+    {
+	if ((lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem)) != NULL)
+	{
+	    lpitem->item_flags &= ~MF_HILITE;
+	    if ((lpitem->item_flags & MF_POPUP) == MF_POPUP)
+		HideAllSubPopupMenu(lppop);
+	    MENU_DrawMenuItem( hdc, lpitem, &lppop->rect, lppop->BarFlag );
+	}
+    }
+
+      /* Highlight new item (if any) */
+    lppop->FocusedItem = wIndex;
+    if (lppop->FocusedItem != (WORD)-1) 
+    {
+	if ((lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem)) != NULL)
+	{
+	    lpitem->item_flags |= MF_HILITE;
+	    MENU_DrawMenuItem( hdc, lpitem, &lppop->rect, lppop->BarFlag );
+	    SendMessage(hWnd, WM_MENUSELECT, lpitem->item_id, 
+			MAKELONG(0, lpitem->item_flags));
+	}
+    }
+    ReleaseDC( hWnd, hdc );
 }
 
 
@@ -728,249 +979,47 @@
 
 void StdDrawPopupMenu(HWND hwnd)
 {
-	WND 	*wndPtr;
+	WND *wndPtr;
 	LPPOPUPMENU lppop;
-	LPMENUITEM 	lpitem;
+	LPMENUITEM  lpitem;
 	PAINTSTRUCT ps;
-	HBRUSH 	hBrush;
-	HPEN	hOldPen;
-	HWND	hWndParent;
-	HDC 	hDC, hMemDC;
-	RECT 	rect, rect2, rect3;
-	DWORD	OldTextColor;
-	int		OldBkMode;
-	HFONT	hOldFont;
-	HBITMAP	hBitMap;
-	BITMAP	bm;
-	UINT  	i, x;
+	RECT rect;
+	HDC hDC;
+
 	hDC = BeginPaint(hwnd, &ps);
-	if (!IsWindowVisible(hwnd)) {
-		EndPaint(hwnd, &ps);
-		return;
-		}
-	InitStdBitmaps();
-	lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
-	if (lppop == NULL) goto EndOfPaint;
-	hBrush = GetStockObject(WHITE_BRUSH);
 	GetClientRect(hwnd, &rect);
-	GetClientRect(hwnd, &rect2);
-	FillRect(hDC, &rect, hBrush);
-	FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH));
-	if (lppop->nItems == 0) goto EndOfPaint;
-	lpitem = lppop->firstItem;
-	if (lpitem == NULL) goto EndOfPaint;
-	for(i = 0; i < lppop->nItems; i++) {
-	CopyRect(&rect2, &lpitem->rect);
-	if ((lpitem->item_flags & MF_SEPARATOR) == MF_SEPARATOR) {
-		hOldPen = SelectObject(hDC, GetStockObject(BLACK_PEN));
-		MoveTo(hDC, rect2.left, rect2.top + 1);
-		LineTo(hDC, rect2.right, rect2.top + 1);
-		SelectObject(hDC, hOldPen);
-		}
-	if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) {
-		hMemDC = CreateCompatibleDC(hDC);
-		if (lpitem->hCheckBit == 0) {
-			SelectObject(hMemDC, hStdCheck);
-			GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm);
-			}
-		else {
-			SelectObject(hMemDC, lpitem->hCheckBit);
-			GetObject(lpitem->hCheckBit, sizeof(BITMAP), (LPSTR)&bm);
-			}
-		BitBlt(hDC, rect2.left, rect2.top + 1,
-		bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
-		DeleteDC(hMemDC);
-		}
-	else {
-		if (lpitem->hUnCheckBit != 0) {
-			hMemDC = CreateCompatibleDC(hDC);
-			SelectObject(hMemDC, lpitem->hUnCheckBit);
-			GetObject(lpitem->hUnCheckBit, sizeof(BITMAP), (LPSTR)&bm);
-			BitBlt(hDC, rect2.left, rect2.top + 1,
-			bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
-			DeleteDC(hMemDC);
-			}
-		}
-	if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) {
-		hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text);
-		rect2.left += lppop->CheckWidth;
-		hMemDC = CreateCompatibleDC(hDC);
-		SelectObject(hMemDC, hBitMap);
-		GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
-#ifdef DEBUG_MENU
-		printf("StdDrawPopupMenu // MF_BITMAP hBit=%04X w=%d h=%d\n",
-				hBitMap, bm.bmWidth, bm.bmHeight);
-#endif
-		BitBlt(hDC, rect2.left, rect2.top,
-				bm.bmWidth, bm.bmHeight, 
-				hMemDC, 0, 0, SRCCOPY);
-		DeleteDC(hMemDC);
-		if ((lpitem->item_flags & MF_HILITE) == MF_HILITE)
-			InvertRect(hDC, &lpitem->rect);
-		}
-	if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) &&
-		((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
-		((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
-		hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
-		OldBkMode = SetBkMode(hDC, TRANSPARENT);
-		if ((lpitem->item_flags & MF_DISABLED) == MF_DISABLED)
-			OldTextColor = SetTextColor(hDC, 0x00C0C0C0L);
-		else {
-			if ((lpitem->item_flags & MF_HILITE) == MF_HILITE)
-				OldTextColor = SetTextColor(hDC, 0x00FFFFFFL);
-			else
-				OldTextColor = SetTextColor(hDC, 0x00000000L);
-			}
-		CopyRect(&rect3, &lpitem->rect);
-		if ((lpitem->item_flags & MF_HILITE) == MF_HILITE)
-			FillRect(hDC, &rect3, GetStockObject(BLACK_BRUSH));
-		InflateRect(&rect3, 0, -2);
-		rect3.left += lppop->CheckWidth;
-		hOldPen = SelectObject(hDC, GetStockObject(BLACK_PEN));
-		if ((x = GetShortCutPos(lpitem->item_text)) != (WORD)-1) {
-			DrawText(hDC, lpitem->item_text, x, &rect3, 
-				DT_LEFT | DT_VCENTER | DT_SINGLELINE);
-			DrawText(hDC, &lpitem->item_text[x], -1, &rect3, 
-				DT_RIGHT | DT_VCENTER | DT_SINGLELINE);
-			} 
-	    else
-			DrawText(hDC, lpitem->item_text, -1, &rect3, 
-				DT_LEFT | DT_VCENTER | DT_SINGLELINE);
-		SelectObject(hDC, hOldPen);
-		SetTextColor(hDC, OldTextColor);
-		SetBkMode(hDC, OldBkMode);
-		SelectObject(hDC, hOldFont);
-		CopyRect(&rect2, &lpitem->rect);
-		}
-	if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
-		CopyRect(&rect3, &lpitem->rect);
-		rect3.left = rect3.right - lppop->PopWidth;
-		hMemDC = CreateCompatibleDC(hDC);
-		SelectObject(hMemDC, hStdMnArrow);
-		GetObject(hStdMnArrow, sizeof(BITMAP), (LPSTR)&bm);
-		BitBlt(hDC, rect3.left, rect3.top + 1,
-		bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
-		DeleteDC(hMemDC);
-		}
-	if (lpitem->next == NULL) goto EndOfPaint;
-	lpitem = (LPMENUITEM)lpitem->next;
+	FillRect(hDC, &rect, sysColorObjects.hbrushMenu );
+
+	lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
+	for (lpitem = lppop->firstItem; lpitem != NULL; lpitem = lpitem->next )
+	{
+	    MENU_DrawMenuItem( hDC, lpitem, &rect, FALSE );
 	}
-EndOfPaint:
 	EndPaint( hwnd, &ps );
 }
 
 
-
 void StdDrawMenuBar(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop, 
 		    BOOL suppress_draw)
 {
 	LPMENUITEM 	lpitem;
-	HBRUSH 	hBrush;
-	HPEN	hOldPen;
-	HDC 	hMemDC;
-	RECT 	rect, rect2, rect3;
-	HFONT	hOldFont;
-	DWORD	OldTextColor;
-	int		OldBkMode;
-	HBITMAP	hBitMap;
-	BITMAP	bm;
-	UINT  	i, textwidth;
 	if (lppop == NULL || lprect == NULL) return;
 #ifdef DEBUG_MENU
 	printf("StdDrawMenuBar(%04X, %08X, %08X); !\n", hDC, lprect, lppop);
 #endif
-	MenuBarCalcSize(hDC, lprect, lppop);
+	if (lppop->Height == 0) MENU_MenuBarCalcSize(hDC, lprect, lppop);
 	if (suppress_draw) return;
-	hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
-	hOldPen = SelectObject(hDC, GetStockObject(BLACK_PEN));
-	hBrush = GetStockObject(WHITE_BRUSH);
-	CopyRect(&rect, lprect);
-	FillRect(hDC, &rect, hBrush);
-	FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH));
-	if (lppop->nItems == 0) goto EndOfPaint;
-	lpitem = lppop->firstItem;
-	if (lpitem == NULL) goto EndOfPaint;
-	for(i = 0; i < lppop->nItems; i++) {
-		CopyRect(&rect2, &lpitem->rect);
-#ifdef DEBUG_MENU
-		printf("StdDrawMenuBar // start left=%d\n", rect2.left);
-#endif
-		if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) {
-			hMemDC = CreateCompatibleDC(hDC);
-			if (lpitem->hCheckBit == 0) {
-				SelectObject(hMemDC, hStdCheck);
-				GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm);
-				}
-			else {
-				SelectObject(hMemDC, lpitem->hCheckBit);
-				GetObject(lpitem->hCheckBit, sizeof(BITMAP), (LPSTR)&bm);
-				}
-			BitBlt(hDC, rect2.left, rect2.top + 1,
-				bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
-			rect2.left += bm.bmWidth;
-#ifdef DEBUG_MENU
-			printf("StdDrawMenuBar // MF_CHECKED bm.bmWidth=%d\n", bm.bmWidth);
-#endif
-			DeleteDC(hMemDC);
-			}
-		else {
-			if (lpitem->hUnCheckBit != 0) {
-				hMemDC = CreateCompatibleDC(hDC);
-				SelectObject(hMemDC, lpitem->hUnCheckBit);
-				GetObject(lpitem->hUnCheckBit, sizeof(BITMAP), (LPSTR)&bm);
-				BitBlt(hDC, rect2.left, rect2.top + 1,
-					bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
-				rect2.left += bm.bmWidth;
-#ifdef DEBUG_MENU
-				printf("StdDrawMenuBar // MF_UNCHECKED bm.bmWidth=%d\n", bm.bmWidth);
-#endif
-				DeleteDC(hMemDC);
-				}
-			}
-		if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) {
-			hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text);
-			hMemDC = CreateCompatibleDC(hDC);
-			SelectObject(hMemDC, hBitMap);
-			GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
-#ifdef DEBUG_MENU
-			printf("StdDrawMenuBar // MF_BITMAP hBit=%04X w=%d h=%d\n",
-					hBitMap, bm.bmWidth, bm.bmHeight);
-#endif
-			BitBlt(hDC, rect2.left, rect2.top,
-						bm.bmWidth, bm.bmHeight, 
-						hMemDC, 0, 0, SRCCOPY);
-			DeleteDC(hMemDC);
-			}
-		if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) &&
-			((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
-			((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
-			hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
-			OldBkMode = SetBkMode(hDC, TRANSPARENT);
-			if ((lpitem->item_flags & MF_DISABLED) == MF_DISABLED)
-				OldTextColor = SetTextColor(hDC, 0x00C0C0C0L);
-			else {
-				if ((lpitem->item_flags & MF_HILITE) == MF_HILITE)
-					OldTextColor = SetTextColor(hDC, 0x00FFFFFFL);
-				else
-					OldTextColor = SetTextColor(hDC, 0x00000000L);
-				}
-			if ((lpitem->item_flags & MF_HILITE) == MF_HILITE)
-				FillRect(hDC, &rect2, GetStockObject(BLACK_BRUSH));
-#ifdef DEBUG_MENU
-			printf("StdDrawMenuBar // rect2.left=%d\n", rect2.left);
-#endif
-			DrawText(hDC, lpitem->item_text, -1, &rect2, 
-				DT_LEFT | DT_VCENTER | DT_SINGLELINE);
-			SetTextColor(hDC, OldTextColor);
-			SetBkMode(hDC, OldBkMode);
-			SelectObject(hDC, hOldFont);
-			}
-		if (lpitem->next == NULL) goto EndOfPaint;
-		lpitem = (LPMENUITEM)lpitem->next;
-		}
-EndOfPaint:
-	SelectObject(hDC, hOldPen);
-	SelectObject(hDC, hOldFont);
+
+	FillRect(hDC, lprect, sysColorObjects.hbrushMenu );
+	SelectObject( hDC, sysColorObjects.hpenWindowFrame );
+	MoveTo( hDC, lprect->left, lprect->bottom );
+	LineTo( hDC, lprect->right, lprect->bottom );
+
+	if (lppop->nItems == 0) return;
+	for (lpitem = lppop->firstItem; lpitem != NULL; lpitem = lpitem->next )
+	{
+	    MENU_DrawMenuItem( hDC, lpitem, lprect, TRUE );
+	}
 } 
 
 
@@ -1025,188 +1074,16 @@
 }
 
 
-void PopupMenuCalcSize(HWND hwnd)
-{
-	WND 	*wndPtr;
-	LPPOPUPMENU lppop;
-	LPMENUITEM 	lpitem;
-	HDC		hDC;
-	RECT 	rect;
-	HBITMAP	hBitMap;
-	BITMAP	bm;
-	HFONT	hOldFont;
-	UINT  	i, OldWidth, TempWidth;
-	DWORD	dwRet;
-#ifdef DEBUG_MENUCALC
-	printf("PopupMenuCalcSize hWnd=%04X !\n", hWnd);
-#endif
-	InitStdBitmaps();
-	lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
-	if (lppop == NULL) return;
-	if (lppop->nItems == 0) return;
-	hDC = GetDC(hwnd);
-	lppop->Width = 20;
-	lppop->CheckWidth = lppop->PopWidth = 0;
-	hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
-CalcAGAIN:
-	OldWidth = lppop->Width;
-	SetRect(&rect, 1, 1, OldWidth, 0);
-	lpitem = lppop->firstItem;
-	for(i = 0; i < lppop->nItems; i++) {
-		if (lpitem == NULL) break;
-#ifdef DEBUG_MENUCALC
-		printf("PopupMenuCalcSize item #%d !\n", i);
-#endif
-		rect.right = rect.left + lppop->Width;
-		if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) {
-			if (lpitem->hCheckBit != 0)
-				GetObject(lpitem->hCheckBit, sizeof(BITMAP), (LPSTR)&bm);
-			else
-				GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm);
-			lppop->CheckWidth = max(lppop->CheckWidth, bm.bmWidth);
-			}
-		else {
-			if (lpitem->hUnCheckBit != 0) {
-				GetObject(lpitem->hUnCheckBit, sizeof(BITMAP), (LPSTR)&bm);
-				lppop->CheckWidth = max(lppop->CheckWidth, bm.bmWidth);
-				}
-			}
-		if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
-			GetObject(hStdMnArrow, sizeof(BITMAP), (LPSTR)&bm);
-			lppop->PopWidth = max(lppop->PopWidth, bm.bmWidth);
-			}
-		if ((lpitem->item_flags & MF_SEPARATOR) == MF_SEPARATOR) {
-			rect.bottom = rect.top + 3;
-			}
-		if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) {
-			hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text);
-			GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
-			rect.bottom = rect.top + bm.bmHeight;
-			lppop->Width = max(lppop->Width, bm.bmWidth);
-			}
-		if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) &&
-			((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
-			((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
-			dwRet = GetTextExtent(hDC, (char *)lpitem->item_text, 
-			strlen((char *)lpitem->item_text));
-			rect.bottom = rect.top + HIWORD(dwRet);
-			InflateRect(&rect, 0, 2);
-			TempWidth = LOWORD(dwRet);
-			if (GetShortCutPos(lpitem->item_text) != (WORD)-1) 
-				TempWidth += 15;
-			TempWidth += lppop->CheckWidth;
-			TempWidth += lppop->PopWidth;
-			lppop->Width = max(lppop->Width, TempWidth);
-			}
-		CopyRect(&lpitem->rect, &rect);
-		rect.top = rect.bottom;
-		lpitem = (LPMENUITEM)lpitem->next;
-		}
-	if (OldWidth < lppop->Width) goto CalcAGAIN;
-	lppop->Height = rect.bottom;
-	SetRect(&lppop->rect, 1, 1, lppop->Width, lppop->Height);
-#ifdef DEBUG_MENUCALC
-	printf("PopupMenuCalcSize w=%d h=%d !\n", lppop->Width, lppop->Height);
-#endif
-	SelectObject(hDC, hOldFont);
-	ReleaseDC(hwnd, hDC);
-}
 
 
 
-void MenuBarCalcSize(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop)
-{
-	LPMENUITEM 	lpitem;
-	LPMENUITEM 	lpitem2;
-	RECT 	rect;
-	HBITMAP	hBitMap;
-	BITMAP	bm;
-	HFONT	hOldFont;
-	UINT  	i, j;
-	UINT	OldHeight, LineHeight;
-	DWORD	dwRet;
-	if (lprect == NULL) return;
-	if (lppop == NULL) return;
-	if (lppop->nItems == 0) return;
-	InitStdBitmaps();
-#ifdef DEBUG_MENUCALC
-	printf("MenuBarCalcSize left=%d top=%d right=%d bottom=%d !\n", 
-		lprect->left, lprect->top, lprect->right, lprect->bottom);
-#endif
-	hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
-	lppop->CheckWidth = 0;
-	LineHeight = OldHeight = SYSMETRICS_CYMENU + 1;
-	SetRect(&rect, lprect->left, lprect->top, 0, lprect->top + LineHeight);
-	lpitem2 = lppop->firstItem;
-	while (lpitem != NULL) {
-		lpitem = lpitem2;
-		while(rect.right < lprect->right) {
-			if (lpitem == NULL) break;
-			rect.right = rect.left;
-			if ((lpitem->item_flags & MF_BITMAP) == MF_BITMAP) {
-				hBitMap = (HBITMAP)LOWORD((LONG)lpitem->item_text);
-				GetObject(hBitMap, sizeof(BITMAP), (LPSTR)&bm);
-				rect.right = rect.left + bm.bmWidth;
-				LineHeight = max(LineHeight, bm.bmHeight);
-				}
-			if (((lpitem->item_flags & MF_BITMAP) != MF_BITMAP) &&
-				((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
-				((lpitem->item_flags & MF_MENUBREAK) != MF_MENUBREAK)) {
-				dwRet = GetTextExtent(hDC, (char *)lpitem->item_text, 
-				strlen((char *)lpitem->item_text));
-				rect.right = rect.left + LOWORD(dwRet) + 10;
-				dwRet = max(SYSMETRICS_CYMENU, (HIWORD(dwRet) + 6));
-				LineHeight = max(LineHeight, (WORD)dwRet);
-				}
-			if ((lpitem->item_flags & MF_CHECKED) == MF_CHECKED) {
-				if (lpitem->hCheckBit != 0)
-					GetObject(lpitem->hCheckBit, sizeof(BITMAP), (LPSTR)&bm);
-				else
-					GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm);
-				rect.right += bm.bmWidth;
-				LineHeight = max(LineHeight, bm.bmHeight);
-				}
-			else {
-				if (lpitem->hUnCheckBit != 0) {
-					GetObject(lpitem->hUnCheckBit, sizeof(BITMAP), (LPSTR)&bm);
-					rect.right += bm.bmWidth;
-					LineHeight = max(LineHeight, bm.bmHeight);
- 					}
-				}
-			CopyRect(&lpitem->rect, &rect);
-			rect.left = rect.right;
-			lpitem = (LPMENUITEM)lpitem->next;
-			}
-		if (LineHeight == OldHeight) {
-			lpitem2 = lpitem;
-			LineHeight = OldHeight = SYSMETRICS_CYMENU + 1;
-			if (lpitem != NULL) 
-				SetRect(&rect, lprect->left, rect.bottom, 
-						0, rect.bottom + LineHeight);
-			}
-		else {
-			OldHeight = LineHeight;
-			SetRect(&rect, lprect->left, rect.top, 0, rect.top + LineHeight);
-			}
-		}
-	lppop->Width = lprect->right - lprect->left;
-	lppop->Height = rect.bottom - lprect->top;
-	lprect->bottom = lprect->top + lppop->Height;
-	CopyRect(&lppop->rect, lprect);
-#ifdef DEBUG_MENUCALC
-	printf("MenuBarCalcSize w=%d h=%d !\n", lppop->Width, lppop->Height);
-#endif
-	SelectObject(hDC, hOldFont);
-}
-
-
 
 /***********************************************************************
  *           MENU_GetMenuBarHeight
  *
  * Compute the size of the menu bar height. Used by NC_HandleNCCalcSize().
  */
-WORD MENU_GetMenuBarHeight( HWND hwnd, WORD menubarWidth )
+WORD MENU_GetMenuBarHeight( HWND hwnd, WORD menubarWidth, int orgX, int orgY )
 {
     HDC hdc;
     RECT rectBar;
@@ -1216,8 +1093,8 @@
     if (!(lppop = PopupMenuGetWindowAndStorage( hwnd, &wndPtr ))) return 0;
     if (!wndPtr) return 0;
     hdc = GetDC( hwnd );
-    SetRect( &rectBar, 0, 0, menubarWidth, SYSMETRICS_CYMENU );
-    MenuBarCalcSize( hdc, &rectBar, lppop );
+    SetRect( &rectBar, orgX, orgY, orgX+menubarWidth, orgY+SYSMETRICS_CYMENU );
+    MENU_MenuBarCalcSize( hdc, &rectBar, lppop );
     ReleaseDC( hwnd, hdc );
     printf( "MENU_GetMenuBarHeight: returning %d\n", lppop->Height );
     return lppop->Height;
@@ -1311,7 +1188,7 @@
 
 
 
-WORD GetShortCutPos(LPSTR str)
+int GetShortCutPos(LPSTR str)
 {
 	int		i;
 	for (i = 0; i < strlen(str); i++) {
@@ -1407,22 +1284,26 @@
  */
 BOOL EnableMenuItem(HMENU hMenu, WORD wItemID, WORD wFlags)
 {
-	LPMENUITEM 	lpitem;
+    LPMENUITEM 	lpitem;
 #ifdef DEBUG_MENU
-	printf("EnableMenuItem (%04X, %04X, %04X) !\n", hMenu, wItemID, wFlags);
+    printf("EnableMenuItem (%04X, %04X, %04X) !\n", hMenu, wItemID, wFlags);
 #endif
-	lpitem = FindMenuItem(hMenu, wItemID, wFlags);
-	if (lpitem != NULL) {
-		if (wFlags && MF_DISABLED)
-			lpitem->item_flags |= MF_DISABLED;
-		else
-			lpitem->item_flags &= ((WORD)-1 ^ MF_DISABLED);
-#ifdef DEBUG_MENU
-		printf("EnableMenuItem // Found !\n");
-#endif
-		return(TRUE);
-		}
-	return FALSE;
+    if (!(lpitem = FindMenuItem(hMenu, wItemID, wFlags))) return FALSE;
+
+      /* We can't have MF_GRAYED and MF_DISABLED together */
+    if (wFlags & MF_GRAYED)
+    {
+	lpitem->item_flags = (lpitem->item_flags & ~MF_DISABLED) | MF_GRAYED;
+    }
+    else if (wFlags & MF_DISABLED)
+    {
+	lpitem->item_flags = (lpitem->item_flags & ~MF_GRAYED) | MF_DISABLED;
+    }
+    else   /* MF_ENABLED */
+    {
+	lpitem->item_flags &= ~(MF_GRAYED | MF_DISABLED);
+    }
+    return TRUE;
 }
 
 
@@ -1858,7 +1739,8 @@
 	lppop->ownerWnd = hWnd;
 	lppop->hWndPrev = GetFocus();
 	if (lppop->hWnd == (HWND)NULL) {
-		lppop->hWnd = CreateWindow("POPUPMENU", "", WS_POPUP | WS_VISIBLE,
+		lppop->hWnd = CreateWindow(POPUPMENU_CLASS_NAME, "",
+					   WS_POPUP | WS_BORDER,
 			x, y, lppop->Width, lppop->Height, (HWND)NULL, 0, 
 			wndPtr->hInstance, (LPSTR)lppop);
 		if (lppop->hWnd == 0) {
@@ -1866,18 +1748,16 @@
 			return FALSE;
 			}
 		}
-	else {
-		ShowWindow(lppop->hWnd, SW_SHOWNOACTIVATE);
-		}
 	if (!lppop->BarFlag) {
-		PopupMenuCalcSize(lppop->hWnd);
+	    MENU_PopupMenuCalcSize(lppop->hWnd);
 #ifdef DEBUG_MENU
 		printf("TrackPopupMenu // x=%d y=%d Width=%d Height=%d\n", 
 			x, y, lppop->Width, lppop->Height); 
 #endif
-		SetWindowPos(lppop->hWnd, 0, x, y, lppop->Width + 2, lppop->Height, 
+		SetWindowPos(lppop->hWnd, 0, x, y, lppop->Width + 2, lppop->Height + 2, 
 			SWP_NOACTIVATE | SWP_NOZORDER);
 		}
+	ShowWindow(lppop->hWnd, SW_SHOWNOACTIVATE);
 	SetFocus(lppop->hWnd);
 	if (!MenuHasFocus) {
 #ifdef DEBUG_MENU
@@ -2041,10 +1921,8 @@
  */
 DWORD GetMenuCheckMarkDimensions()
 {
-    BITMAP	bm;
-	InitStdBitmaps();
-    GetObject(hStdCheck, sizeof(BITMAP), (LPSTR)&bm);
-    return MAKELONG(bm.bmWidth, bm.bmHeight);
+    InitStdBitmaps();
+    return MAKELONG( check_bitmap_width, check_bitmap_height );
 }
 
 
@@ -2230,27 +2108,21 @@
 	printf("SetMenu(%04X, %04X);\n", hWnd, hMenu);
 #endif
 	if (GetCapture() == hWnd) ReleaseCapture();
-	if (wndPtr->window != 0) {
-		flags = SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED;
-/*		if (!IsWindowVisible(hWnd)) flags |= SWP_NOREDRAW; */
-		flags |= SWP_NOREDRAW;
-		if (hMenu == 0) {
-			wndPtr->wIDmenu = hMenu;
-			printf("SetMenu(%04X, %04X) // Menu removed, need NC recalc!\n", hWnd, hMenu);
-			SetWindowPos(hWnd, 0, 0, 0, 0, 0, flags);
-			return TRUE;
-			}
-		wndPtr->wIDmenu = hMenu;
-		SetWindowPos(hWnd, 0, 0, 0, 0, 0, flags);
-		}
-	lpmenu = (LPPOPUPMENU) GlobalLock(hMenu);
-	if (lpmenu == NULL) {
+	wndPtr->wIDmenu = hMenu;
+	if (hMenu != 0)
+	{
+	    lpmenu = (LPPOPUPMENU) GlobalLock(hMenu);
+	    if (lpmenu == NULL) {
 		printf("SetMenu(%04X, %04X) // Bad menu handle !\n", hWnd, hMenu);
 		return FALSE;
 		}
-	lpmenu->ownerWnd = hWnd;
-	ResetHiliteFlags(lpmenu);
-	GlobalUnlock(hMenu);
+	    lpmenu->ownerWnd = hWnd;
+	    lpmenu->Height = 0;  /* Make sure we recalculate the size */
+	    ResetHiliteFlags(lpmenu);
+	    GlobalUnlock(hMenu);
+	}
+	SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
+		      SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
 	return TRUE;
 }
 
@@ -2296,7 +2168,6 @@
 {
 	WND		*wndPtr;
 	LPPOPUPMENU lppop;
-	HDC		hDC;
 #ifdef DEBUG_MENU
 	printf("DrawMenuBar (%04X)\n", hWnd);
 #endif
@@ -2308,27 +2179,12 @@
 #endif
 		lppop = (LPPOPUPMENU) GlobalLock(wndPtr->wIDmenu);
 		if (lppop == NULL) return;
-		if (lppop->Height != 0) {
-			int oldHeight;
-			oldHeight = lppop->Height;
-			hDC = GetWindowDC(hWnd);
-			StdDrawMenuBar(hDC, &lppop->rect, lppop, TRUE);
-			ReleaseDC(hWnd, hDC);
-			if (oldHeight != lppop->Height) {
-				printf("DrawMenuBar // menubar changed oldHeight=%d != lppop->Height=%d\n",
-											oldHeight, lppop->Height);
-				/* Reduce ClientRect according to MenuBar height */
-				wndPtr->rectClient.top -= oldHeight;
-				wndPtr->rectClient.top += lppop->Height;
-				SendMessage(hWnd, WM_NCPAINT, 1, 0L);
-				}
-			else
-				StdDrawMenuBar(hDC, &lppop->rect, lppop, FALSE);
-			}
-		else
-			SendMessage(hWnd, WM_NCPAINT, 1, 0L);
+
+		lppop->Height = 0; /* Make sure we call MENU_MenuBarCalcSize */
+		SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
+			    SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
 		GlobalUnlock(wndPtr->wIDmenu);
-		}
+	    }
 }
 
 
@@ -2358,10 +2214,21 @@
  */
 void InitStdBitmaps()
 {
-	if (hStdCheck == (HBITMAP)NULL) 
-		hStdCheck = LoadBitmap((HANDLE)NULL, (LPSTR)OBM_CHECK);
-	if (hStdMnArrow == (HBITMAP)NULL) 
-		hStdMnArrow = LoadBitmap((HANDLE)NULL, (LPSTR)OBM_MNARROW);
+    BITMAP bm;
+    if (hStdCheck == (HBITMAP)NULL)
+    {
+	hStdCheck = LoadBitmap((HANDLE)NULL, (LPSTR)OBM_CHECK);
+	GetObject( hStdCheck, sizeof(BITMAP), (LPSTR)&bm );
+	check_bitmap_width = bm.bmWidth;
+	check_bitmap_height = bm.bmHeight;
+    }
+    if (hStdMnArrow == (HBITMAP)NULL) 
+    {
+	hStdMnArrow = LoadBitmap((HANDLE)NULL, (LPSTR)OBM_MNARROW);
+	GetObject( hStdMnArrow, sizeof(BITMAP), (LPSTR)&bm );
+	arrow_bitmap_width = bm.bmWidth;
+	arrow_bitmap_height = bm.bmHeight;
+    }
 }
 
 
diff --git a/controls/widgets.c b/controls/widgets.c
index 204b65f..c6866c6 100644
--- a/controls/widgets.c
+++ b/controls/widgets.c
@@ -37,7 +37,7 @@
     { CS_GLOBALCLASS, (LONG(*)())EditWndProc, 0, 4, 
       0, 0, 0, 0, NULL, "EDIT" },
     { CS_GLOBALCLASS | CS_SAVEBITS, (LONG(*)())PopupMenuWndProc, 0, 8,
-      0, 0, 0, 0, NULL, "POPUPMENU" },
+      0, 0, 0, 0, NULL, POPUPMENU_CLASS_NAME },
     { CS_GLOBALCLASS, (LONG(*)())DesktopWndProc, 0, sizeof(DESKTOPINFO),
       0, 0, 0, 0, NULL, DESKTOP_CLASS_NAME },
     { CS_GLOBALCLASS, (LONG(*)())DefDlgProc, 0, DLGWINDOWEXTRA,
diff --git a/if1632/call.S b/if1632/call.S
index 7c42967..48f6d75 100644
--- a/if1632/call.S
+++ b/if1632/call.S
@@ -190,6 +190,7 @@
 	 * Call entry point
 	 */
 	movw	%ax,%ds
+	movw	%ax,%di
 	.byte	0x66
 	lcall	%fs:(%edx)
 
@@ -284,11 +285,16 @@
 	/*
 	 * Call entry point
 	 */
+	pushl	%edx
 	pushw	_IF1632_Saved16_ss
 	pushw	_IF1632_Saved16_esp
 	pushl	%eax
 	call	_DLLRelay
 
+	popl	%edx
+	popl	%edx
+	popl	%edx
+
 	/*
  	 * Restore registers, but do not destroy return value.
 	 */
@@ -327,6 +333,7 @@
 	/*
 	 * Last, but not least we need to move the high word from eax to dx
 	 */
+
 	pushl	%eax
 	popw	%dx
 	popw	%dx
@@ -335,6 +342,99 @@
 	lret
 
 /**********************************************************************
+ *	CallTo32_16()
+ *
+ *	This function is same one as CallTo32() except that the high
+ *	word of EAX won't be moved to DX.
+ */
+	.align	4
+	.globl _CallTo32_16
+_CallTo32_16:
+	pushl	%ebp
+	movl	%esp,%ebp
+
+	/*
+ 	 * Save registers.  286 mode does not have fs or gs.
+	 */
+	pushw	%ds
+	pushw	%es
+
+	/*
+	 * Restore segment registers.
+	 */
+	pushl	%eax
+	movw	$UDATASEL,%ax
+	movw	%ax,%ds
+	movw	%ax,%es
+	popl	%eax
+
+	/*
+	 * Save old stack save variables, save stack registers, reload
+	 * stack registers.
+	 */
+	pushl	_IF1632_Saved16_esp
+	pushl	_IF1632_Saved16_ebp
+	pushw	_IF1632_Saved16_ss
+
+	movw	%ss,_IF1632_Saved16_ss
+	movl	%esp,_IF1632_Saved16_esp
+	movl	%ebp,_IF1632_Saved16_ebp
+
+	movw	_IF1632_Saved32_ss,%ss
+	movl	_IF1632_Saved32_esp,%esp
+	movl	_IF1632_Saved32_ebp,%ebp
+
+	/*
+	 * Call entry point
+	 */
+	pushl	%edx
+	pushw	_IF1632_Saved16_ss
+	pushw	_IF1632_Saved16_esp
+	pushl	%eax
+	call	_DLLRelay
+
+	popl	%edx
+	popl	%edx
+	popl	%edx
+
+	/*
+ 	 * Restore registers, but do not destroy return value.
+	 */
+	movw	_IF1632_Saved16_ss,%ss
+	movl	_IF1632_Saved16_esp,%esp
+	movl	_IF1632_Saved16_ebp,%ebp
+
+	popw	_IF1632_Saved16_ss
+	popl	_IF1632_Saved16_ebp
+	popl	_IF1632_Saved16_esp
+
+	popw	%es
+	popw	%ds
+
+	.align	2,0x90
+	leave
+	/*
+	 * Now we need to ditch the parameter bytes that were left on the
+	 * stack. We do this by effectively popping the number of bytes,
+	 * and the return address, removing the parameters and then putting
+	 * the return address back on the stack.
+	 * Normally this field is filled in by the relevant function in
+	 * the emulation library, since it should know how many bytes to
+	 * expect.
+	 */
+	popw	%gs:nbytes
+	cmpw	$0,%gs:nbytes
+	je	noargs2
+	popw	%gs:offset
+	popw	%gs:selector
+	addw	%gs:nbytes,%esp
+	pushw	%gs:selector
+	pushw	%gs:offset
+noargs2:
+	.byte	0x66
+	lret
+
+/**********************************************************************
  *	ReturnFromRegisterFunc()
  */
 	.globl _ReturnFromRegisterFunc
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index 4cba3a6..663e14e 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -7,26 +7,26 @@
 #1 FATALEXIT
 #2 EXITKERNEL
 3   pascal GetVersion() GetVersion()
-4   pascal LocalInit(word word word) WIN16_LocalInit(1 2 3)
-5   pascal LocalAlloc(word word) WIN16_LocalAlloc(1 2)
-6   pascal LocalReAlloc(word word word) WIN16_LocalReAlloc(1 2 3)
-7   pascal LocalFree(word) WIN16_LocalFree(1)
+4   pascal16 LocalInit(word word word) WIN16_LocalInit(1 2 3)
+5   pascal16 LocalAlloc(word word) WIN16_LocalAlloc(1 2)
+6   pascal16 LocalReAlloc(word word word) WIN16_LocalReAlloc(1 2 3)
+7   pascal16 LocalFree(word) WIN16_LocalFree(1)
 8   pascal LocalLock(word) WIN16_LocalLock(1)
-9   pascal LocalUnlock(word) WIN16_LocalUnlock(1)
+9   pascal16 LocalUnlock(word) WIN16_LocalUnlock(1)
 10  pascal LocalSize(word) WIN16_LocalSize(1)
-11  pascal LocalHandle(word) ReturnArg(1)
-12  pascal LocalFlags(word) WIN16_LocalFlags(1)
-13  pascal LocalCompact(word) WIN16_LocalCompact(1)
+11  pascal16 LocalHandle(word) ReturnArg(1)
+12  pascal16 LocalFlags(word) WIN16_LocalFlags(1)
+13  pascal16 LocalCompact(word) WIN16_LocalCompact(1)
 14  return LocalNotify 4 0
-15  pascal GlobalAlloc(word long) WIN16_GlobalAlloc(1 2)
-16  pascal GlobalReAlloc(word long word) GlobalReAlloc(1 2 3)
-17  pascal GlobalFree(word) GlobalFree(1)
+15  pascal16 GlobalAlloc(word long) WIN16_GlobalAlloc(1 2)
+16  pascal16 GlobalReAlloc(word long word) GlobalReAlloc(1 2 3)
+17  pascal16 GlobalFree(word) GlobalFree(1)
 18  pascal GlobalLock(word) GlobalLock(1)
-19  pascal GlobalUnlock(word) GlobalUnlock(1)
+19  pascal16 GlobalUnlock(word) GlobalUnlock(1)
 20  pascal GlobalSize(word) GlobalSize(1)
 21  pascal GlobalHandle(word) GlobalHandle(1)
-22  pascal GlobalFlags(word) GlobalFlags(1)
-23  pascal LockSegment(s_word) KERNEL_LockSegment(1)
+22  pascal16 GlobalFlags(word) GlobalFlags(1)
+23  pascal16 LockSegment(s_word) KERNEL_LockSegment(1)
 24  pascal UnlockSegment(s_word) KERNEL_UnlockSegment(1)
 25  pascal GlobalCompact(long) GlobalCompact(1)
 #26 GLOBALFREEALL
@@ -38,66 +38,66 @@
 #33 LOCKCURRENTTASK
 34  pascal SetTaskQueue(word word) SetTaskQueue(1 2)
 35  pascal GetTaskQueue(word) GetTaskQueue(1)
-36  pascal GetCurrentTask() GetCurrentTask()
-37  pascal GetCurrentPDB() GetCurrentPDB()
+36  pascal16 GetCurrentTask() GetCurrentTask()
+37  pascal16 GetCurrentPDB() GetCurrentPDB()
 #38 SETTASKSIGNALPROC
 #41 ENABLEDOS
 #42 DISABLEDOS
-45  pascal LoadModule(ptr ptr) LoadModule(1 2)
-46  pascal FreeModule(word) FreeLibrary(1)
-47  pascal GetModuleHandle(ptr) GetModuleHandle(1)
-48  pascal GetModuleUsage(word) GetModuleUsage(1)
-49  pascal GetModuleFileName(word ptr s_word) GetModuleFileName(1 2 3)
+45  pascal16 LoadModule(ptr ptr) LoadModule(1 2)
+46  pascal16 FreeModule(word) FreeLibrary(1)
+47  pascal16 GetModuleHandle(ptr) GetModuleHandle(1)
+48  pascal16 GetModuleUsage(word) GetModuleUsage(1)
+49  pascal16 GetModuleFileName(word ptr s_word) GetModuleFileName(1 2 3)
 50  pascal GetProcAddress(word ptr) GetProcAddress(1 2)
 51  pascal MakeProcInstance(ptr word) CALLBACK_MakeProcInstance(1 2)
 52  pascal FreeProcInstance(ptr) FreeProcInstance(1)
 #53 CALLPROCINSTANCE
-#54 GETINSTANCEDATA
-55  pascal Catch(ptr) Catch (1)
+#54 pascal16 GETINSTANCEDATA
+55  pascal16 Catch(ptr) Catch (1)
 56  pascal Throw(ptr word) Throw(1 2)
-57  pascal GetProfileInt(ptr ptr word) GetProfileInt(1 2 3)
-58  pascal GetProfileString(ptr ptr ptr ptr word) GetProfileString(1 2 3 4 5)
-59  pascal WriteProfileString(ptr ptr ptr) WriteProfileString(1 2 3)
-60  pascal FindResource(word ptr ptr) FindResource(1 2 3)
-61  pascal LoadResource(word word) LoadResource(1 2)
+57  pascal16 GetProfileInt(ptr ptr word) GetProfileInt(1 2 3)
+58  pascal16 GetProfileString(ptr ptr ptr ptr word) GetProfileString(1 2 3 4 5)
+59  pascal16 WriteProfileString(ptr ptr ptr) WriteProfileString(1 2 3)
+60  pascal16 FindResource(word ptr ptr) FindResource(1 2 3)
+61  pascal16 LoadResource(word word) LoadResource(1 2)
 62  pascal LockResource(word) LockResource(1)
-63  pascal FreeResource(word) FreeResource(1)
-64  pascal AccessResource(word word) AccessResource(1 2)
+63  pascal16 FreeResource(word) FreeResource(1)
+64  pascal16 AccessResource(word word) AccessResource(1 2)
 65  pascal SizeofResource(word word) SizeofResource(1 2)
-66  pascal AllocResource(word word long) AllocResource(1 2 3)
+66  pascal16 AllocResource(word word long) AllocResource(1 2 3)
 #67 SETRESOURCEHANDLER
-68  pascal InitAtomTable(word) InitAtomTable(1)
-69  pascal FindAtom(ptr) FindAtom(1)
-70  pascal AddAtom(ptr) AddAtom(1)
-71  pascal DeleteAtom(word) DeleteAtom(1)
-72  pascal GetAtomName(word ptr word) GetAtomName(1 2 3)
-73  pascal GetAtomHandle(word) GetAtomHandle(1)
-74  pascal OpenFile(ptr ptr word) OpenFile(1 2 3)
+68  pascal16 InitAtomTable(word) InitAtomTable(1)
+69  pascal16 FindAtom(ptr) FindAtom(1)
+70  pascal16 AddAtom(ptr) AddAtom(1)
+71  pascal16 DeleteAtom(word) DeleteAtom(1)
+72  pascal16 GetAtomName(word ptr word) GetAtomName(1 2 3)
+73  pascal16 GetAtomHandle(word) GetAtomHandle(1)
+74  pascal16 OpenFile(ptr ptr word) OpenFile(1 2 3)
 #75 OPENPATHNAME
 #76 DELETEPATHNAME
 #77 RESERVED1
 #78 RESERVED2
 #79 RESERVED3
 #80 RESERVED4
-81  pascal _lclose(word) _lclose(1)
-82  pascal _lread(word ptr word) _lread(1 2 3)
-83  pascal _lcreat(ptr word) _lcreat(1 2)
+81  pascal16 _lclose(word) _lclose(1)
+82  pascal16 _lread(word ptr word) _lread(1 2 3)
+83  pascal16 _lcreat(ptr word) _lcreat(1 2)
 84  pascal _llseek(word long word) _llseek(1 2 3)
-85  pascal _lopen(ptr word) _lopen(1 2)
-86  pascal _lwrite(word ptr word) _lwrite(1 2 3)
+85  pascal16 _lopen(ptr word) _lopen(1 2)
+86  pascal16 _lwrite(word ptr word) _lwrite(1 2 3)
 #87 RESERVED5
 88  pascal lstrcpy(ptr ptr) lstrcpy(1 2)
 89  pascal lstrcat(ptr ptr) lstrcat(1 2)
-90  pascal lstrlen(ptr) lstrlen(1)
+90  pascal16 lstrlen(ptr) lstrlen(1)
 91  register InitTask(word word word word word
 		      word word word word word) 
 	     KERNEL_InitTask()
-92  pascal GetTempDrive(byte) GetTempDrive(1)
-#93 GETCODEHANDLE
+92  pascal16 GetTempDrive(byte) GetTempDrive(1)
+#93 pascal16 GETCODEHANDLE
 #94 DEFINEHANDLETABLE
-95  pascal LoadLibrary(ptr) LoadLibrary(1)
-96  pascal FreeLibrary(word) FreeLibrary(1)
-97  pascal GetTempFileName(byte ptr word ptr) GetTempFileName(1 2 3 4)
+95  pascal16 LoadLibrary(ptr) LoadLibrary(1)
+96  pascal16 FreeLibrary(word) FreeLibrary(1)
+97  pascal16 GetTempFileName(byte ptr word ptr) GetTempFileName(1 2 3 4)
 #98 GETLASTDISKCHANGE
 #99 GETLPERRMODE
 #100 VALIDATECODESEGMENTS
@@ -114,9 +114,9 @@
 #109 SWITCHSTACKBACK
 #110 PATCHCODEHANDLE
 111 pascal GlobalWire(word) GlobalLock(1)
-112 pascal GlobalUnWire(word) GlobalUnlock(1)
-#113 __AHSHIFT
-#114 __AHINCR
+112 pascal16 GlobalUnWire(word) GlobalUnlock(1)
+113 equate __AHSHIFT 3
+114 equate __AHINCR 8
 115 pascal OutputDebugString(ptr) OutputDebugString(1)
 #116 INITLIB
 117 return OldYield 0 0
@@ -129,19 +129,19 @@
 #124 ENABLEKERNEL
 #125 DISABLEKERNEL
 #126 MEMORYFREED
-127 pascal GetPrivateProfileInt(ptr ptr s_word ptr)
-	   GetPrivateProfileInt(1 2 3 4)
-128 pascal GetPrivateProfileString(ptr ptr ptr ptr s_word ptr)
-	   GetPrivateProfileString(1 2 3 4 5 6)
-129 pascal WritePrivateProfileString(ptr ptr ptr ptr)
-	   WritePrivateProfileString(1 2 3 4)
+127 pascal16 GetPrivateProfileInt(ptr ptr s_word ptr)
+	     GetPrivateProfileInt(1 2 3 4)
+128 pascal16 GetPrivateProfileString(ptr ptr ptr ptr s_word ptr)
+	     GetPrivateProfileString(1 2 3 4 5 6)
+129 pascal16 WritePrivateProfileString(ptr ptr ptr ptr)
+	     WritePrivateProfileString(1 2 3 4)
 #130 FILECBR
 131 pascal GetDOSEnvironment() GetDOSEnvironment()
 132 pascal GetWinFlags() GetWinFlags()
 #133 GETEXEPTR
-134 pascal GetWindowsDirectory(ptr word) GetWindowsDirectory(1 2)
-135 pascal GetSystemDirectory(ptr word) GetSystemDirectory(1 2)
-136 pascal GetDriveType(byte) GetDriveType(1)
+134 pascal16 GetWindowsDirectory(ptr word) GetWindowsDirectory(1 2)
+135 pascal16 GetSystemDirectory(ptr word) GetSystemDirectory(1 2)
+136 pascal16 GetDriveType(byte) GetDriveType(1)
 137 pascal FatalAppExit(word ptr) FatalAppExit(1 2)
 #138 GETHEAPSPACES - This is not correct but may fake out most apps
 138 return GetHeapSpaces 2 0x80004000
@@ -150,7 +150,7 @@
 #141 INITTASK1
 150 return DirectedYield 2 0
 #151 WINOLDAPCALL
-152 pascal GetNumTasks() GetNumTasks()
+152 pascal16 GetNumTasks() GetNumTasks()
 154 return GlobalNotify 4 0
 #155 GETTASKDS
 #156 LIMITEMSPAGES
@@ -160,10 +160,10 @@
 #160 EMSCOPY
 #161 LOCALCOUNTFREE
 #162 LOCALHEAPSIZE
-163 pascal GlobalLRUOldest(word) ReturnArg(1)
-164 pascal GlobalLRUNewest(word) ReturnArg(1)
+163 pascal16 GlobalLRUOldest(word) ReturnArg(1)
+164 pascal16 GlobalLRUNewest(word) ReturnArg(1)
 #165 A20PROC
-166 pascal WinExec(ptr word) WinExec(1 2)
+166 pascal16 WinExec(ptr word) WinExec(1 2)
 #167 GETEXPWINVER
 #168 DIRECTRESALLOC
 169 pascal GetFreeSpace(word) GetFreeSpace(1)
@@ -172,9 +172,9 @@
 #172 ALLOCALIAS
 #173 __ROMBIOS
 #174 __A000H
-175 pascal AllocSelector(word) AllocSelector(1)
-176 pascal FreeSelector(word) FreeSelector(1)
-177 pascal PrestoChangoSelector(word word) PrestoChangoSelector(1 2)
+175 pascal16 AllocSelector(word) AllocSelector(1)
+176 pascal16 FreeSelector(word) FreeSelector(1)
+177 pascal16 PrestoChangoSelector(word word) PrestoChangoSelector(1 2)
 178 equate __WINFLAGS 0x413
 #179 __D000H
 #180 LONGPTRADD
@@ -183,10 +183,10 @@
 #183 __0000H
 184 return GlobalDOSAlloc 4 0
 185 return GlobalDOSFree 2 0
-186 pascal GetSelectorBase(word) GetSelectorBase(1)
-187 pascal SetSelectorBase(word long) SetSelectorBase(1 2)
+186 pascal16 GetSelectorBase(word) GetSelectorBase(1)
+187 pascal16 SetSelectorBase(word long) SetSelectorBase(1 2)
 188 pascal GetSelectorLimit(word) GetSelectorLimit(1)
-189 pascal SetSelectorLimit(word long) SetSelectorLimit(1 2)
+189 pascal16 SetSelectorLimit(word long) SetSelectorLimit(1 2)
 #190 __E000H
 191 pascal GlobalPageLock(word) GlobalLock(1)
 192 pascal GlobalPageUnlock(word) GlobalUnlock(1)
@@ -196,7 +196,7 @@
 #196 SELECTORACCESSRIGHTS
 197 pascal GlobalFix(word) GlobalLock(1)
 198 pascal GlobalUnfix(word) GlobalUnlock(1)
-199 pascal SetHandleCount(word) SetHandleCount(1)
+199 pascal16 SetHandleCount(word) SetHandleCount(1)
 #200 VALIDATEFREESPACES
 #201 REPLACEINST
 #202 REGISTERPTRACE
@@ -236,8 +236,8 @@
 #346 ISBADHUGEREADPTR
 #347 ISBADHUGEWRITEPTR
 348 pascal hmemcpy(ptr ptr long) hmemcpy(1 2 3)
-349 pascal _hread(word ptr long) _hread(1 2 3)
-350 pascal _hwrite(word ptr long) _hwrite(1 2 3)
+349 pascal16 _hread(word ptr long) _hread(1 2 3)
+350 pascal16 _hwrite(word ptr long) _hwrite(1 2 3)
 #351 BUNNY_351
 353 pascal lstrcpyn(ptr ptr word) lstrcpyn(1 2 3)
 #354 GETAPPCOMPATFLAGS
diff --git a/if1632/user.spec b/if1632/user.spec
index edb86b9..a8e5597 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -178,7 +178,7 @@
 173 pascal LoadCursor(word ptr) LoadCursor(1 2)
 174 pascal LoadIcon(word ptr) LoadIcon(1 2)
 175 pascal LoadBitmap(word ptr) LoadBitmap(1 2)
-176 pascal LoadString(word word ptr s_word) LoadString(1 2 3 4)
+176 pascal16 LoadString(word word ptr s_word) LoadString(1 2 3 4)
 177 pascal LoadAccelerators(word ptr) LoadAccelerators(1 2)
 178 pascal TranslateAccelerator(word word ptr) TranslateAccelerator(1 2 3)
 179 pascal GetSystemMetrics(word) GetSystemMetrics(1)
@@ -228,9 +228,9 @@
 220 pascal LoadMenuIndirect(ptr) LoadMenuIndirect(1)
 221 pascal ScrollDC(word s_word s_word ptr ptr word ptr) 
 	   ScrollDC(1 2 3 4 5 6 7)
-222 pascal GetKeyboardState(ptr) GetKeyboardState(1)
+222 pascal16 GetKeyboardState(ptr) GetKeyboardState(1)
 #223 SETKEYBOARDSTATE
-224 pascal GetWindowTask(word) GetWindowTask(1)
+224 pascal16 GetWindowTask(word) GetWindowTask(1)
 225 pascal EnumTaskWindows(word ptr long) EnumTaskWindows(1 2 3)
 #226 LOCKINPUT
 227 pascal GetNextDlgGroupItem(word word word) GetNextDlgGroupItem(1 2 3)
@@ -294,7 +294,7 @@
 281 pascal GetSysColorBrush(word) GetSysColorBrush(1)
 282 pascal SelectPalette(word word word) SelectPalette(1 2 3)
 283 pascal RealizePalette(word) RealizePalette(1)
-284 pascal GetFreeSystemResources(word) GetFreeSystemResources(1)
+284 pascal16 GetFreeSystemResources(word) GetFreeSystemResources(1)
 #285 BEAR285
 286 pascal GetDesktopWindow() GetDesktopWindow()
 #287 GETLASTACTIVEPOPUP
@@ -366,15 +366,15 @@
 421 pascal wvsprintf(ptr ptr ptr) wvsprintf(1 2 3)
 #422 DLGDIRSELECTEX
 #423 DLGDIRSELECTCOMBOBOXEX
-430 pascal lstrcmp(ptr ptr) lstrcmp(1 2)
+430 pascal16 lstrcmp(ptr ptr) lstrcmp(1 2)
 431 pascal AnsiUpper(ptr) AnsiUpper(1)
 432 pascal AnsiLower(ptr) AnsiLower(1)
-433 pascal IsCharAlpha(byte) IsCharAlpha(1)
-434 pascal IsCharAlphanumeric(byte) IsCharAlphanumeric(1)
-435 pascal IsCharUpper(byte) IsCharUpper(1)
-436 pascal IsCharLower(byte) IsCharLower(1)
-437 pascal AnsiUpperBuff(ptr word) AnsiUpperBuff(1 2)
-438 pascal AnsiLowerBuff(ptr word) AnsiLowerBuff(1 2)
+433 pascal16 IsCharAlpha(byte) IsCharAlpha(1)
+434 pascal16 IsCharAlphanumeric(byte) IsCharAlphanumeric(1)
+435 pascal16 IsCharUpper(byte) IsCharUpper(1)
+436 pascal16 IsCharLower(byte) IsCharLower(1)
+437 pascal16 AnsiUpperBuff(ptr word) AnsiUpperBuff(1 2)
+438 pascal16 AnsiLowerBuff(ptr word) AnsiLowerBuff(1 2)
 445 pascal DefFrameProc(word word word word long) DefFrameProc(1 2 3 4 5)
 447 pascal DefMDIChildProc(word word word long) DefMDIChildProc(1 2 3 4)
 451 pascal TranslateMDISysAccel(word ptr) TranslateMDISysAccel(1 2)
@@ -395,7 +395,7 @@
 #465 DRAGDETECT
 466 pascal DrawFocusRect(word ptr) DrawFocusRect(1 2)
 #470 STRINGFUNC
-471 pascal lstrcmpi(ptr ptr) lstrcmpi(1 2)
+471 pascal16 lstrcmpi(ptr ptr) lstrcmpi(1 2)
 472 pascal AnsiNext(ptr) AnsiNext(1 )
 473 pascal AnsiPrev(ptr ptr) AnsiPrev(1 2)
 #480 GETUSERLOCALOBJTYPE
@@ -415,13 +415,13 @@
 #509 WNETUNWATCHQUEUE
 #510 WNETLOCKQUEUEDATA
 #511 WNETUNLOCKQUEUEDATA
-512 pascal WNetGetConnection(ptr ptr ptr) WNetGetConnection(1 2 3)
+512 pascal16 WNetGetConnection(ptr ptr ptr) WNetGetConnection(1 2 3)
 513 pascal WNetGetCaps(word) WNetGetCaps(1)
 #514 WNETDEVICEMODE
 #515 WNETBROWSEDIALOG
 516 pascal WNetGetUser(ptr ptr ptr) WNetGetUser(1 2 3)
-517 pascal WNetAddConnection(ptr ptr ptr) WNetAddConnection(1 2 3)
-518 pascal WNetCancelConnection(ptr word) WNetCancelConnection(1 2)
+517 pascal16 WNetAddConnection(ptr ptr ptr) WNetAddConnection(1 2 3)
+518 pascal16 WNetCancelConnection(ptr word) WNetCancelConnection(1 2)
 #519 WNETGETERROR
 #520 WNETGETERRORTEXT
 #521 WNETENABLE
diff --git a/include/syscolor.h b/include/syscolor.h
index 9bd12d5..7001448 100644
--- a/include/syscolor.h
+++ b/include/syscolor.h
@@ -15,7 +15,7 @@
                                    /* COLOR_BACKGROUND          */
     HBRUSH hbrushActiveCaption;    /* COLOR_ACTIVECAPTION       */
     HBRUSH hbrushInactiveCaption;  /* COLOR_INACTIVECAPTION     */
-                                   /* COLOR_MENU                */
+    HBRUSH hbrushMenu;             /* COLOR_MENU                */
     HBRUSH hbrushWindow;           /* COLOR_WINDOW              */
     HPEN hpenWindowFrame;          /* COLOR_WINDOWFRAME         */
                                    /* COLOR_MENUTEXT            */
@@ -24,7 +24,7 @@
     HBRUSH hbrushActiveBorder;     /* COLOR_ACTIVEBORDER        */
     HBRUSH hbrushInactiveBorder;   /* COLOR_INACTIVEBORDER      */
                                    /* COLOR_APPWORKSPACE        */
-                                   /* COLOR_HIGHLIGHT           */
+    HBRUSH hbrushHighlight;        /* COLOR_HIGHLIGHT           */
                                    /* COLOR_HIGHLIGHTTEXT       */
     HBRUSH hbrushBtnFace;          /* COLOR_BTNFACE             */
     HBRUSH hbrushBtnShadow;        /* COLOR_BTNSHADOW           */
diff --git a/loader/signal.c b/loader/signal.c
index c0c52fb..9b8e851 100644
--- a/loader/signal.c
+++ b/loader/signal.c
@@ -7,6 +7,7 @@
 
 #if defined(__NetBSD__) || defined(__FreeBSD__)
 #include <sys/syscall.h>
+#include <sys/param.h>
 #else
 #include <syscall.h>
 #endif
@@ -20,13 +21,14 @@
 #include "prototypes.h"
 #include "win.h"
  
+#if !defined(BSD4_4) || defined(linux)
 char * cstack[4096];
+#endif
 struct sigaction segv_act;
 
 #ifdef linux
 extern void ___sig_restore();
 extern void ___masksig_restore();
-#endif
 
 /* Similar to the sigaction function in libc, except it leaves alone the
    restorer field */
@@ -41,6 +43,7 @@
 	errno = -sig;
 	return -1;
 }
+#endif
 
 int do_int(int intnum, struct sigcontext_struct *scp)
 {
@@ -111,7 +114,7 @@
 #endif
 #if defined(__NetBSD__) || defined(__FreeBSD__)
 /*         set_es(0x27); set_ds(0x27); */
-    if(signal != SIGBUS) 
+    if(signal != SIGBUS && signal != SIGSEGV && signal != SIGTRAP) 
 	exit(1);
     if(scp->sc_cs == 0x1f)
     {
@@ -181,7 +184,7 @@
 	XUngrabServer(display);
 	XFlush(display);
     fprintf(stderr,"In win_fault %x:%x\n", scp->sc_cs, scp->sc_eip);
-#ifdef linux
+#if defined(linux) || defined(__NetBSD__)
     wine_debug(signal, scp);  /* Enter our debugger */
 #else
     fprintf(stderr,"Stack: %x:%x\n", scp->sc_ss, scp->sc_esp);
@@ -213,8 +216,23 @@
 	wine_sigaction(SIGTRAP, &segv_act, NULL); /* For breakpoints */
 #endif
 #if defined(__NetBSD__) || defined(__FreeBSD__)
-        struct sigstack ss;
         sigset_t sig_mask;
+#ifdef BSD4_4
+        struct sigaltstack ss;
+        
+        if ((ss.ss_base = malloc(MINSIGSTKSZ)) == NULL) {
+	        fprintf(stderr, "Unable to allocate signal stack (%d bytes)\n",
+		        MINSIGSTKSZ);
+		exit(1);
+	}
+	ss.ss_size = MINSIGSTKSZ;
+        ss.ss_flags = 0;
+        if (sigaltstack(&ss, NULL) < 0) {
+                perror("sigstack");
+                exit(1);
+        }
+#else
+        struct sigstack ss;
         
         ss.ss_sp = (char *) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3);
         ss.ss_onstack = 0;
@@ -222,12 +240,27 @@
                 perror("sigstack");
                 exit(1);
         }
+#endif
         sigemptyset(&sig_mask);
-        segv_act.sa_handler = (__sighandler_t) win_fault;
+        segv_act.sa_handler = (void (*)) win_fault;
 	segv_act.sa_flags = SA_ONSTACK;
         segv_act.sa_mask = sig_mask;
 	if (sigaction(SIGBUS, &segv_act, NULL) < 0) {
-                perror("sigaction");
+                perror("sigaction: SIGBUS");
+                exit(1);
+        }
+        segv_act.sa_handler = (void (*)) win_fault;
+	segv_act.sa_flags = SA_ONSTACK;
+        segv_act.sa_mask = sig_mask;
+	if (sigaction(SIGSEGV, &segv_act, NULL) < 0) {
+                perror("sigaction: SIGSEGV");
+                exit(1);
+        }
+        segv_act.sa_handler = (void (*)) win_fault; /* For breakpoints */
+	segv_act.sa_flags = SA_ONSTACK;
+        segv_act.sa_mask = sig_mask;
+	if (sigaction(SIGTRAP, &segv_act, NULL) < 0) {
+                perror("sigaction: SIGTRAP");
                 exit(1);
         }
 #endif
diff --git a/misc/audio.c b/misc/audio.c
index dcdee0d..98ab81c 100644
--- a/misc/audio.c
+++ b/misc/audio.c
@@ -16,8 +16,11 @@
 
 #include <fcntl.h>
 #include <sys/ioctl.h>
+#ifdef linux
 #include <linux/soundcard.h>
+#endif
 
+#ifdef linux
 #define SOUND_DEV "/dev/dsp"
 
 #ifdef SOUND_VERSION
@@ -66,6 +69,7 @@
 static LINUX_WAVEOUT	WOutDev[MAX_WAVOUTDRV];
 static LINUX_WAVEIN		WInDev[MAX_WAVOUTDRV];
 static LINUX_MCIWAVE	MCIWavDev[MAX_MCIWAVDRV];
+#endif
 
 DWORD WAVE_mciOpen(DWORD dwFlags, LPMCI_WAVE_OPEN_PARMS lpParms);
 DWORD WAVE_mciClose(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms);
@@ -93,6 +97,7 @@
 DWORD WAVE_NotifyClient(UINT wDevID, WORD wMsg, 
 				DWORD dwParam1, DWORD dwParam2)
 {
+#ifdef linux
 	if (WInDev[wDevID].wFlags != DCB_NULL && !DriverCallback(
 		WInDev[wDevID].waveDesc.dwCallBack, WInDev[wDevID].wFlags, 
 		WInDev[wDevID].waveDesc.hWave, wMsg, 
@@ -100,6 +105,9 @@
 		printf("WAVE_NotifyClient // can't notify client !\n");
 		return MMSYSERR_NOERROR;
 		}
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 
@@ -109,6 +117,7 @@
 LRESULT WAVE_DriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg, 
 						DWORD dwParam1, DWORD dwParam2)
 {
+#ifdef linux
 	switch(wMsg) {
 		case DRV_LOAD:
 			return (LRESULT)1L;
@@ -159,12 +168,16 @@
 		default:
 			return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
 		}
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 /**************************************************************************
 * 				WAVE_mciOpen	*/
 DWORD WAVE_mciOpen(DWORD dwFlags, LPMCI_WAVE_OPEN_PARMS lpParms)
 {
+#ifdef linux
 	int			hFile;
 	UINT 		wDevID;
 	OFSTRUCT	OFstruct;
@@ -223,6 +236,9 @@
 	dwRet = wodMessage(0, WODM_OPEN, 0, (DWORD)&WaveDesc, CALLBACK_NULL);
 	dwRet = widMessage(0, WIDM_OPEN, 0, (DWORD)&WaveDesc, CALLBACK_NULL);
 	return 0;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 /**************************************************************************
@@ -230,6 +246,7 @@
 */
 DWORD WAVE_mciClose(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
 {
+#ifdef linux
 	DWORD		dwRet;
 #ifdef DEBUG_MCIWAVE
 	printf("WAVE_mciClose(%u, %08X, %08X);\n", wDevID, dwParam, lpParms);
@@ -246,6 +263,9 @@
 		if (dwRet != MMSYSERR_NOERROR) return MCIERR_INTERNAL;
 		}
 	return 0;
+#else
+	return 0;
+#endif
 }
 
 
@@ -254,6 +274,7 @@
 */
 DWORD WAVE_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
 {
+#ifdef linux
 	int			count;
 	int			start, end;
 	LPWAVEHDR		lpWaveHdr;
@@ -323,6 +344,9 @@
 			MCIWavDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
 		}
 	return 0;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 
@@ -331,6 +355,7 @@
 */
 DWORD WAVE_mciRecord(UINT wDevID, DWORD dwFlags, LPMCI_RECORD_PARMS lpParms)
 {
+#ifdef linux
 	int			count;
 	int			start, end;
 	LPWAVEHDR		lpWaveHdr;
@@ -382,6 +407,9 @@
 			MCIWavDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
 		}
 	return 0;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 
@@ -390,11 +418,15 @@
 */
 DWORD WAVE_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 {
+#ifdef linux
 #ifdef DEBUG_MCIWAVE
 	printf("WAVE_mciStop(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
 #endif
 	if (lpParms == NULL) return MCIERR_INTERNAL;
 	return 0;
+#else
+	return MCIERR_INTERNAL;
+#endif
 }
 
 
@@ -403,11 +435,15 @@
 */
 DWORD WAVE_mciPause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 {
+#ifdef linux
 #ifdef DEBUG_MCIWAVE
 	printf("WAVE_mciPause(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
 #endif
 	if (lpParms == NULL) return MCIERR_INTERNAL;
 	return 0;
+#else
+	return MCIERR_INTERNAL;
+#endif
 }
 
 
@@ -416,11 +452,15 @@
 */
 DWORD WAVE_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 {
+#ifdef linux
 #ifdef DEBUG_MCIWAVE
 	printf("WAVE_mciResume(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
 #endif
 	if (lpParms == NULL) return MCIERR_INTERNAL;
 	return 0;
+#else
+	return MCIERR_INTERNAL;
+#endif
 }
 
 
@@ -429,6 +469,7 @@
 */
 DWORD WAVE_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
 {
+#ifdef linux
 #ifdef DEBUG_MCIWAVE
 	printf("WAVE_mciSet(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
 #endif
@@ -502,6 +543,9 @@
 		printf("WAVE_mciSet // MCI_WAVE_SET_SAMPLESPERSEC !\n");
 		}
  	return 0;
+#else
+	return MCIERR_INTERNAL;
+#endif
 }
 
 
@@ -510,6 +554,7 @@
 */
 DWORD WAVE_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
 {
+#ifdef linux
 #ifdef DEBUG_MCIWAVE
 	printf("WAVE_mciStatus(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
 #endif
@@ -601,6 +646,9 @@
 			MCIWavDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
 		}
  	return 0;
+#else
+	return MCIERR_INTERNAL;
+#endif
 }
 
 /**************************************************************************
@@ -609,6 +657,7 @@
 DWORD WAVE_mciGetDevCaps(UINT wDevID, DWORD dwFlags, 
 					LPMCI_GETDEVCAPS_PARMS lpParms)
 {
+#ifdef linux
 	printf("WAVE_mciGetDevCaps(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
 	if (dwFlags & MCI_GETDEVCAPS_ITEM) {
@@ -651,6 +700,9 @@
 			}
 		}
  	return 0;
+#else
+	return MCIERR_INTERNAL;
+#endif
 }
 
 /**************************************************************************
@@ -658,6 +710,7 @@
 */
 DWORD WAVE_mciInfo(UINT wDevID, DWORD dwFlags, LPMCI_INFO_PARMS lpParms)
 {
+#ifdef linux
 	printf("WAVE_mciInfo(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
 	if (lpParms == NULL) return MCIERR_INTERNAL;
 	lpParms->lpstrReturn = NULL;
@@ -682,6 +735,9 @@
 	else
 		lpParms->dwRetSize = 0;
  	return 0;
+#else
+	return MCIERR_INTERNAL;
+#endif
 }
 
 
@@ -693,6 +749,7 @@
 */
 DWORD wodGetDevCaps(WORD wDevID, LPWAVEOUTCAPS lpCaps, DWORD dwSize)
 {
+#ifdef linux
 	int 	audio;
 	int		smplrate;
 	int		samplesize = 16;
@@ -739,6 +796,9 @@
 	close(audio);
 	printf("wodGetDevCaps // dwFormats = %08X\n", lpCaps->dwFormats);
 	return MMSYSERR_NOERROR;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 
@@ -747,6 +807,7 @@
 */
 DWORD wodOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
 {
+#ifdef linux
 	int 		audio;
 	int			abuf_size;
 	int			smplrate;
@@ -826,6 +887,9 @@
 		return MMSYSERR_INVALPARAM;
 		}
 	return MMSYSERR_NOERROR;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 /**************************************************************************
@@ -833,6 +897,7 @@
 */
 DWORD wodClose(WORD wDevID)
 {
+#ifdef linux
 	printf("wodClose(%u);\n", wDevID);
 	if (WOutDev[wDevID].unixdev == 0) {
 		printf("Linux 'wodClose' // can't close !\n");
@@ -846,6 +911,9 @@
 		return MMSYSERR_INVALPARAM;
 		}
 	return MMSYSERR_NOERROR;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 /**************************************************************************
@@ -853,6 +921,7 @@
 */
 DWORD wodWrite(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
 {
+#ifdef linux
 	printf("wodWrite(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
 	if (WOutDev[wDevID].unixdev == 0) {
 		printf("Linux 'wodWrite' // can't play !\n");
@@ -875,6 +944,9 @@
 		return MMSYSERR_INVALPARAM;
 		}
 	return MMSYSERR_NOERROR;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 /**************************************************************************
@@ -882,6 +954,7 @@
 */
 DWORD wodPrepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
 {
+#ifdef linux
 	printf("wodPrepare(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
 	if (WOutDev[wDevID].unixdev == 0) {
 		printf("Linux 'wodPrepare' // can't prepare !\n");
@@ -897,6 +970,9 @@
 	lpWaveHdr->dwFlags |= WHDR_PREPARED;
 	lpWaveHdr->dwFlags &= ~WHDR_DONE;
 	return MMSYSERR_NOERROR;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 /**************************************************************************
@@ -904,12 +980,16 @@
 */
 DWORD wodUnprepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
 {
+#ifdef linux
 	printf("wodUnprepare(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
 	if (WOutDev[wDevID].unixdev == 0) {
 		printf("Linux 'wodUnprepare' // can't unprepare !\n");
 		return MMSYSERR_NOTENABLED;
 		}
 	return MMSYSERR_NOERROR;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 /**************************************************************************
@@ -917,12 +997,16 @@
 */
 DWORD wodRestart(WORD wDevID)
 {
+#ifdef linux
 	printf("wodRestart(%u);\n", wDevID);
 	if (WOutDev[wDevID].unixdev == 0) {
 		printf("Linux 'wodRestart' // can't restart !\n");
 		return MMSYSERR_NOTENABLED;
 		}
 	return MMSYSERR_NOERROR;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 /**************************************************************************
@@ -930,12 +1014,16 @@
 */
 DWORD wodReset(WORD wDevID)
 {
+#ifdef linux
 	printf("wodReset(%u);\n", wDevID);
 	if (WOutDev[wDevID].unixdev == 0) {
 		printf("Linux 'wodReset' // can't reset !\n");
 		return MMSYSERR_NOTENABLED;
 		}
 	return MMSYSERR_NOERROR;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 
@@ -944,6 +1032,7 @@
 */
 DWORD wodGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
 {
+#ifdef linux
 	int		time;
 	printf("wodGetPosition(%u, %08X, %u);\n", wDevID, lpTime, uSize);
 	if (WOutDev[wDevID].unixdev == 0) {
@@ -988,6 +1077,9 @@
 			goto TryAGAIN;
 		}
 	return MMSYSERR_NOERROR;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 /**************************************************************************
@@ -995,6 +1087,7 @@
 */
 DWORD wodSetVolume(WORD wDevID, DWORD dwParam)
 {
+#ifdef linux
 	int 	mixer;
 	int		volume = 50;
 	printf("wodSetVolume(%u, %08X);\n", wDevID, dwParam);
@@ -1012,6 +1105,9 @@
 		}
 	close(mixer);
 	return MMSYSERR_NOERROR;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 
@@ -1072,6 +1168,7 @@
 */
 DWORD widGetDevCaps(WORD wDevID, LPWAVEINCAPS lpCaps, DWORD dwSize)
 {
+#ifdef linux
 	int 	audio;
 	int		smplrate;
 	int		samplesize = 16;
@@ -1117,6 +1214,9 @@
 	close(audio);
 	printf("widGetDevCaps // dwFormats = %08X\n", lpCaps->dwFormats);
 	return MMSYSERR_NOERROR;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 
@@ -1125,6 +1225,7 @@
 */
 DWORD widOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags)
 {
+#ifdef linux
 	int 		audio;
 	int			abuf_size;
 	int			smplrate;
@@ -1209,6 +1310,9 @@
 		return MMSYSERR_INVALPARAM;
 		}
 	return MMSYSERR_NOERROR;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 /**************************************************************************
@@ -1216,6 +1320,7 @@
 */
 DWORD widClose(WORD wDevID)
 {
+#ifdef linux
 	printf("widClose(%u);\n", wDevID);
 	if (WInDev[wDevID].unixdev == 0) {
 		printf("Linux 'widClose' // can't close !\n");
@@ -1229,6 +1334,9 @@
 		return MMSYSERR_INVALPARAM;
 		}
 	return MMSYSERR_NOERROR;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 /**************************************************************************
@@ -1236,6 +1344,7 @@
 */
 DWORD widAddBuffer(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
 {
+#ifdef linux
 	int			count	= 1;
 	LPWAVEHDR 	lpWIHdr;
 	printf("widAddBuffer(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
@@ -1270,6 +1379,9 @@
 		}
 	printf("widAddBuffer // buffer added ! (now %u in queue)\n", count);
 	return MMSYSERR_NOERROR;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 /**************************************************************************
@@ -1277,6 +1389,7 @@
 */
 DWORD widPrepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
 {
+#ifdef linux
 	printf("widPrepare(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
 	if (WInDev[wDevID].unixdev == 0) {
 		printf("Linux 'widPrepare' // can't prepare !\n");
@@ -1295,6 +1408,9 @@
 	lpWaveHdr->dwBytesRecorded = 0;
 	printf("Linux 'widPrepare' // header prepared !\n");
 	return MMSYSERR_NOERROR;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 /**************************************************************************
@@ -1302,6 +1418,7 @@
 */
 DWORD widUnprepare(WORD wDevID, LPWAVEHDR lpWaveHdr, DWORD dwSize)
 {
+#ifdef linux
 	printf("widUnprepare(%u, %08X, %08X);\n", wDevID, lpWaveHdr, dwSize);
 	if (WInDev[wDevID].unixdev == 0) {
 		printf("Linux 'widUnprepare' // can't unprepare !\n");
@@ -1313,6 +1430,9 @@
 	WInDev[wDevID].lpQueueHdr = NULL;
 	printf("Linux 'widUnprepare' // all headers unprepared !\n");
 	return MMSYSERR_NOERROR;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 /**************************************************************************
@@ -1320,6 +1440,7 @@
 */
 DWORD widStart(WORD wDevID)
 {
+#ifdef linux
 	int			count	= 1;
 	LPWAVEHDR 	lpWIHdr;
 	printf("widStart(%u);\n", wDevID);
@@ -1355,6 +1476,9 @@
 	printf("widStart // end of recording !\n");
 	fflush(stdout);
 	return MMSYSERR_NOERROR;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 /**************************************************************************
@@ -1362,12 +1486,16 @@
 */
 DWORD widStop(WORD wDevID)
 {
+#ifdef linux
 	printf("widStop(%u);\n", wDevID);
 	if (WInDev[wDevID].unixdev == 0) {
 		printf("Linux 'widStop' // can't stop !\n");
 		return MMSYSERR_NOTENABLED;
 		}
 	return MMSYSERR_NOERROR;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 /**************************************************************************
@@ -1375,12 +1503,16 @@
 */
 DWORD widReset(WORD wDevID)
 {
+#ifdef linux
 	printf("widReset(%u);\n", wDevID);
 	if (WInDev[wDevID].unixdev == 0) {
 		printf("Linux 'widReset' // can't reset !\n");
 		return MMSYSERR_NOTENABLED;
 		}
 	return MMSYSERR_NOERROR;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 /**************************************************************************
@@ -1388,6 +1520,7 @@
 */
 DWORD widGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
 {
+#ifdef linux
 	int		time;
 #ifdef DEBUG_MCIWAVE
 	printf("widGetPosition(%u, %08X, %u);\n", wDevID, lpTime, uSize);
@@ -1446,6 +1579,9 @@
 			goto TryAGAIN;
 		}
 	return MMSYSERR_NOERROR;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 /**************************************************************************
@@ -1506,5 +1642,4 @@
 	return MMSYSERR_NOTENABLED;
 }
 
-
 #endif /* !WINELIB */
diff --git a/misc/mcicda.c b/misc/mcicda.c
index 3b49cde..c96fb27 100644
--- a/misc/mcicda.c
+++ b/misc/mcicda.c
@@ -18,8 +18,10 @@
 
 #include <fcntl.h>
 #include <sys/ioctl.h>
+#ifdef linux
 #include <linux/soundcard.h>
 #include <linux/cdrom.h>
+#endif
 
 #define SOUND_DEV "/dev/dsp"
 #define CDAUDIO_DEV "/dev/sbpcd"
@@ -37,6 +39,7 @@
 #define CDFRAMES_PERMIN 	4500
 #define SECONDS_PERMIN	 	60
 
+#ifdef linux
 typedef struct {
     int     nUseCount;          /* Incremented for each shared open */
     BOOL    fShareable;         /* TRUE if first open was shareable */
@@ -57,6 +60,7 @@
 	} LINUX_CDAUDIO;
 
 static LINUX_CDAUDIO	CDADev[MAX_CDAUDIODRV];
+#endif
 
 UINT CDAUDIO_GetNumberOfTracks(UINT wDevID);
 BOOL CDAUDIO_GetTracksInfo(UINT wDevID);
@@ -72,6 +76,7 @@
 */
 DWORD CDAUDIO_mciOpen(DWORD dwFlags, LPMCI_OPEN_PARMS lpParms)
 {
+#ifdef linux
 	UINT	wDevID;
 	int		cdrom;
 #ifdef DEBUG_CDAUDIO
@@ -121,6 +126,9 @@
 			CDADev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
 		}
  	return 0;
+#else
+	return MCIERR_HARDWARE;
+#endif
 }
 
 /**************************************************************************
@@ -128,12 +136,14 @@
 */
 DWORD CDAUDIO_mciClose(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
 {
+#ifdef linux
 #ifdef DEBUG_CDAUDIO
 	printf("CDAUDIO_mciClose(%u, %08X, %08X);\n", wDevID, dwParam, lpParms);
 #endif
 	if (CDADev[wDevID].lpdwTrackLen != NULL) free(CDADev[wDevID].lpdwTrackLen);
 	if (CDADev[wDevID].lpdwTrackPos != NULL) free(CDADev[wDevID].lpdwTrackPos);
 	close(CDADev[wDevID].unixdev);
+#endif
 }
 
 /**************************************************************************
@@ -142,6 +152,7 @@
 DWORD CDAUDIO_mciGetDevCaps(UINT wDevID, DWORD dwFlags, 
 						LPMCI_GETDEVCAPS_PARMS lpParms)
 {
+#ifdef linux
 #ifdef DEBUG_CDAUDIO
 	printf("CDAUDIO_mciGetDevCaps(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
 #endif
@@ -183,6 +194,9 @@
 		}
 	printf("CDAUDIO_mciGetDevCaps // lpParms->dwReturn=%08X);\n", lpParms->dwReturn);
  	return 0;
+#else
+	return MCIERR_INTERNAL;
+#endif
 }
 
 /**************************************************************************
@@ -190,6 +204,7 @@
 */
 DWORD CDAUDIO_mciInfo(UINT wDevID, DWORD dwFlags, LPMCI_INFO_PARMS lpParms)
 {
+#ifdef linux
 #ifdef DEBUG_CDAUDIO
 	printf("CDAUDIO_mciInfo(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
 #endif
@@ -207,6 +222,9 @@
 	else
 		lpParms->dwRetSize = 0;
  	return 0;
+#else
+	return MCIERR_INTERNAL;
+#endif
 }
 
 /**************************************************************************
@@ -214,6 +232,7 @@
 */
 DWORD CDAUDIO_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
 {
+#ifdef linux
 #ifdef DEBUG_CDAUDIO
 	printf("CDAUDIO_mciStatus(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
 #endif
@@ -315,6 +334,9 @@
 		}
 	printf("CDAUDIO_mciStatus // not MCI_STATUS_ITEM !\n");
  	return 0;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 
@@ -324,6 +346,7 @@
 DWORD CDAUDIO_CalcTime(UINT wDevID, DWORD dwFormatType, DWORD dwFrame)
 {
 	DWORD	dwTime = 0;
+#ifdef linux
 	UINT	wTrack;
 	UINT	wMinutes;
 	UINT	wSeconds;
@@ -372,6 +395,7 @@
 			dwFormatType = MCI_FORMAT_TMSF;
 			goto TryAGAIN;
 		}
+#endif
 	return dwTime;
 }
 
@@ -382,6 +406,7 @@
 DWORD CDAUDIO_CalcFrame(UINT wDevID, DWORD dwFormatType, DWORD dwTime)
 {
 	DWORD	dwFrame = 0;
+#ifdef linux
 	UINT	wTrack;
 #ifdef DEBUG_CDAUDIO
 	printf("CDAUDIO_CalcFrame(%u, %08X, %lu);\n", wDevID, dwFormatType, dwTime);
@@ -423,6 +448,7 @@
 			dwFormatType = MCI_FORMAT_TMSF;
 			goto TryAGAIN;
 		}
+#endif
 	return dwFrame;
 }
 
@@ -432,6 +458,7 @@
 */
 UINT CDAUDIO_GetNumberOfTracks(UINT wDevID)
 {
+#ifdef linux
 	struct cdrom_tochdr	hdr;
 	if (CDADev[wDevID].nTracks == 0) {
 		if (ioctl(CDADev[wDevID].unixdev, CDROMREADTOCHDR, &hdr)) {
@@ -441,6 +468,9 @@
 		CDADev[wDevID].nTracks = hdr.cdth_trk1;
 		}
 	return CDADev[wDevID].nTracks;
+#else
+	return (WORD)-1;
+#endif
 }
 
 /**************************************************************************
@@ -448,6 +478,7 @@
 */
 BOOL CDAUDIO_GetTracksInfo(UINT wDevID)
 {
+#ifdef linux
 	int		i, length;
 	int		start, last_start;
 	int		total_length = 0;
@@ -503,6 +534,9 @@
 	CDADev[wDevID].dwTotalLen = total_length;
 	printf("CDAUDIO_GetTracksInfo // total_len=%u\n", total_length);
 	return TRUE;
+#else
+	return FALSE;
+#endif
 }
 
 
@@ -511,6 +545,7 @@
 */
 BOOL CDAUDIO_GetCDStatus(UINT wDevID)
 {
+#ifdef linux
 	int		oldmode = CDADev[wDevID].mode;
 	CDADev[wDevID].sc.cdsc_format = CDROM_MSF;
 	if (ioctl(CDADev[wDevID].unixdev, CDROMSUBCHNL, &CDADev[wDevID].sc)) {
@@ -565,6 +600,9 @@
 			}
 		}
 	return TRUE;
+#else
+	return FALSE;
+#endif
 }
 
 /**************************************************************************
@@ -572,6 +610,7 @@
 */
 DWORD CDAUDIO_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
 {
+#ifdef linux
 	int 	start, end;
 	struct 	cdrom_msf	msf;
 #ifdef DEBUG_CDAUDIO
@@ -625,6 +664,9 @@
 			CDADev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
 		}
 	return 0;
+#else
+	return MCIERR_HARDWARE;
+#endif
 }
 
 /**************************************************************************
@@ -632,6 +674,7 @@
 */
 DWORD CDAUDIO_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 {
+#ifdef linux
 #ifdef DEBUG_CDAUDIO
 	printf("CDAUDIO_mciStop(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
 #endif
@@ -644,6 +687,9 @@
 			CDADev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
 		}
  	return 0;
+#else
+	return MCIERR_HARDWARE;
+#endif
 }
 
 /**************************************************************************
@@ -651,6 +697,7 @@
 */
 DWORD CDAUDIO_mciPause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 {
+#ifdef linux
 #ifdef DEBUG_CDAUDIO
 	printf("CDAUDIO_mciPause(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
 #endif
@@ -663,6 +710,9 @@
 			CDADev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
 		}
 	return 0;
+#else
+	return MCIERR_HARDWARE;
+#endif
 }
 
 /**************************************************************************
@@ -670,6 +720,7 @@
 */
 DWORD CDAUDIO_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 {
+#ifdef linux
 #ifdef DEBUG_CDAUDIO
 	printf("CDAUDIO_mciResume(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
 #endif
@@ -682,6 +733,9 @@
 			CDADev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
 		}
 	return 0;
+#else
+	return MCIERR_HARDWARE;
+#endif
 }
 
 /**************************************************************************
@@ -689,6 +743,7 @@
 */
 DWORD CDAUDIO_mciSeek(UINT wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms)
 {
+#ifdef linux
 	DWORD	dwRet;
 	MCI_PLAY_PARMS PlayParms;
 #ifdef DEBUG_CDAUDIO
@@ -717,6 +772,9 @@
 			CDADev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
 		}
 	return dwRet;
+#else
+	return MCIERR_HARDWARE;
+#endif
 }
 
 
@@ -725,6 +783,7 @@
 */
 DWORD CDAUDIO_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
 {
+#ifdef linux
 #ifdef DEBUG_CDAUDIO
 	printf("CDAUDIO_mciSet(%u, %08X, %08X);\n", wDevID, dwFlags, lpParms);
 #endif
@@ -775,6 +834,9 @@
 			CDADev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
 		}
 	return 0;
+#else
+	return MCIERR_HARDWARE;
+#endif
 }
 
 
@@ -784,6 +846,7 @@
 LRESULT CDAUDIO_DriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg, 
 							DWORD dwParam1, DWORD dwParam2)
 {
+#ifdef linux
 	switch(wMsg) {
 		case DRV_LOAD:
 			return (LRESULT)1L;
@@ -852,6 +915,9 @@
 		default:
 			return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
 		}
+#else
+	return MCIERR_HARDWARE;
+#endif
 }
 
 
diff --git a/misc/mmaux.c b/misc/mmaux.c
index 58bc85d..a83bf45 100644
--- a/misc/mmaux.c
+++ b/misc/mmaux.c
@@ -14,7 +14,9 @@
 
 #include <fcntl.h>
 #include <sys/ioctl.h>
+#ifdef linux
 #include <linux/soundcard.h>
+#endif
 
 #define SOUND_DEV "/dev/dsp"
 #define MIXER_DEV "/dev/mixer"
@@ -34,6 +36,7 @@
 */
 DWORD AUX_GetDevCaps(WORD wDevID, LPAUXCAPS lpCaps, DWORD dwSize)
 {
+#ifdef linux
 	int 	mixer;
 	int		volume;
 	printf("AUX_GetDevCaps(%u, %08X, %u);\n", wDevID, lpCaps, dwSize);
@@ -48,6 +51,9 @@
 		}
 	close(mixer);
 	return MMSYSERR_NOERROR;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 
@@ -56,6 +62,7 @@
 */
 DWORD AUX_GetVolume(WORD wDevID, DWORD dwParam)
 {
+#ifdef linux
 	int 	mixer;
 	int		volume;
 	printf("AUX_GetVolume(%u, %08X);\n", wDevID, dwParam);
@@ -69,6 +76,9 @@
 		}
 	close(mixer);
 	return MMSYSERR_NOERROR;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 /**************************************************************************
@@ -76,6 +86,7 @@
 */
 DWORD AUX_SetVolume(WORD wDevID, DWORD dwParam)
 {
+#ifdef linux
 	int 	mixer;
 	int		volume = 50;
 	printf("AUX_SetVolume(%u, %08X);\n", wDevID, dwParam);
@@ -89,6 +100,9 @@
 		}
 	close(mixer);
 	return MMSYSERR_NOERROR;
+#else
+	return MMSYSERR_NOTENABLED;
+#endif
 }
 
 
diff --git a/objects/color.c b/objects/color.c
index 41f3ae6..c6cbddc 100644
--- a/objects/color.c
+++ b/objects/color.c
@@ -233,7 +233,7 @@
     WORD *mapping;
 
     if (!dc->u.x.pal.hMapping) return 0;
-    switch(color & 0xff000000)
+    switch(color >> 24)
     {
     case 0:  /* RGB */
 	index = GetNearestPaletteIndex( STOCK_DEFAULT_PALETTE, color );
diff --git a/objects/font.c b/objects/font.c
index 63a5543..3f3b4cb 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -16,6 +16,34 @@
 #define MAX_FONTS	256
 static LPLOGFONT lpLogFontList[MAX_FONTS] = { NULL };
 
+
+#define CI_NONEXISTCHAR(cs) (((cs)->width == 0) && \
+			     (((cs)->rbearing|(cs)->lbearing| \
+			       (cs)->ascent|(cs)->descent) == 0))
+
+/* 
+ * CI_GET_CHAR_INFO - return the charinfo struct for the indicated 8bit
+ * character.  If the character is in the column and exists, then return the
+ * appropriate metrics (note that fonts with common per-character metrics will
+ * return min_bounds).  If none of these hold true, try again with the default
+ * char.
+ */
+#define CI_GET_CHAR_INFO(fs,col,def,cs) \
+{ \
+    cs = def; \
+    if (col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \
+	if (fs->per_char == NULL) { \
+	    cs = &fs->min_bounds; \
+	} else { \
+	    cs = &fs->per_char[(col - fs->min_char_or_byte2)]; \
+	    if (CI_NONEXISTCHAR(cs)) cs = def; \
+	} \
+    } \
+}
+
+#define CI_GET_DEFAULT_INFO(fs,cs) \
+  CI_GET_CHAR_INFO(fs, fs->default_char, NULL, cs)
+
 /***********************************************************************
  *           FONT_MatchFont
  *
@@ -86,7 +114,7 @@
 void FONT_GetMetrics( LOGFONT * logfont, XFontStruct * xfont,
 		      TEXTMETRIC * metrics )
 {    
-    int average, i;
+    int average, i, count;
     unsigned long prop;
 	
     metrics->tmAscent  = xfont->ascent;
@@ -116,13 +144,17 @@
     else
     {
 	XCharStruct * charPtr = xfont->per_char;
-	average = 0;
+	average = count = 0;
 	for (i = metrics->tmFirstChar; i <= metrics->tmLastChar; i++)
 	{
-	    average += charPtr->width;
+	    if (!CI_NONEXISTCHAR( charPtr ))
+	    {
+		average += charPtr->width;
+		count++;
+	    }
 	    charPtr++;
 	}
-	average /= metrics->tmLastChar - metrics->tmFirstChar + 1;
+	if (count) average = (average + count/2) / count;
     }
     metrics->tmAveCharWidth = average;
 }
@@ -373,33 +405,6 @@
  
 /***********************************************************************/
 
-#define CI_NONEXISTCHAR(cs) (((cs)->width == 0) && \
-			     (((cs)->rbearing|(cs)->lbearing| \
-			       (cs)->ascent|(cs)->descent) == 0))
-
-/* 
- * CI_GET_CHAR_INFO - return the charinfo struct for the indicated 8bit
- * character.  If the character is in the column and exists, then return the
- * appropriate metrics (note that fonts with common per-character metrics will
- * return min_bounds).  If none of these hold true, try again with the default
- * char.
- */
-#define CI_GET_CHAR_INFO(fs,col,def,cs) \
-{ \
-    cs = def; \
-    if (col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \
-	if (fs->per_char == NULL) { \
-	    cs = &fs->min_bounds; \
-	} else { \
-	    cs = &fs->per_char[(col - fs->min_char_or_byte2)]; \
-	    if (CI_NONEXISTCHAR(cs)) cs = def; \
-	} \
-    } \
-}
-
-#define CI_GET_DEFAULT_INFO(fs,cs) \
-  CI_GET_CHAR_INFO(fs, fs->default_char, NULL, cs)
-
 
 /***********************************************************************
  *           GetCharWidth    (GDI.350)
diff --git a/objects/text.c b/objects/text.c
index 0cb0686..f8be278 100644
--- a/objects/text.c
+++ b/objects/text.c
@@ -235,8 +235,12 @@
 	    if (!TextOut(hdc, x, y, line, len)) return 0;
 	if (prefix_offset != -1)
 	{
+	    HPEN hpen = CreatePen( PS_SOLID, 1, GetTextColor(hdc) );
+	    HPEN oldPen = SelectObject( hdc, hpen );
 	    MoveTo(hdc, x + prefix_x, y + tm.tmAscent + 1 );
 	    LineTo(hdc, x + prefix_end, y + tm.tmAscent + 1 );
+	    SelectObject( hdc, oldPen );
+	    DeleteObject( hpen );
 	}
 
 	if (strPtr)
diff --git a/tools/build.c b/tools/build.c
index 096c1d6..160d0fb 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -20,9 +20,10 @@
 #define VARTYPE_LONG	2
 #define VARTYPE_FARPTR	3
 
-#define FUNCTYPE_PASCAL	16
-#define FUNCTYPE_C	17
-#define FUNCTYPE_REG	19
+#define FUNCTYPE_PASCAL_16	15
+#define FUNCTYPE_PASCAL		16
+#define FUNCTYPE_C		17
+#define FUNCTYPE_REG		19
 
 #define EQUATETYPE_ABS	18
 #define TYPE_RETURN	20
@@ -372,7 +373,8 @@
     }
     fdp->n_args_16 = i;
 
-    if (type == FUNCTYPE_PASCAL || type == FUNCTYPE_REG)
+    if (type == FUNCTYPE_PASCAL_16 || type == FUNCTYPE_PASCAL ||
+	type == FUNCTYPE_REG )
     {
 	current_offset = 0;
 	for (i--; i >= 0; i--)
@@ -521,6 +523,8 @@
 	return ParseExportFunction(ordinal, FUNCTYPE_PASCAL);
     else if (stricmp(token, "pascal") == 0)
 	return ParseExportFunction(ordinal, FUNCTYPE_PASCAL);
+    else if (stricmp(token, "pascal16") == 0)
+	return ParseExportFunction(ordinal, FUNCTYPE_PASCAL_16);
     else if (stricmp(token, "register") == 0)
 	return ParseExportFunction(ordinal, FUNCTYPE_REG);
     else if (stricmp(token, "equate") == 0)
@@ -755,6 +759,13 @@
     fprintf(fp, "\torl\t$0x%08x,%%eax\n", DLLId << 16);
     fprintf(fp, "\tjmp\t_CallTo32\n\n");
 
+    fprintf(fp, "\t.globl _%s_Dispatch_16\n", UpperDLLName);
+    fprintf(fp, "_%s_Dispatch_16:\n", UpperDLLName);
+    fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
+    fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
+    fprintf(fp, "\torl\t$0x%08x,%%eax\n", DLLId << 16);
+    fprintf(fp, "\tjmp\t_CallTo32_16\n\n");
+
     odp = OrdinalDefinitions;
     for (i = 0; i <= Limit; i++, odp++)
     {
@@ -829,6 +840,13 @@
 		fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
 		break;
 		
+	      case FUNCTYPE_PASCAL_16:
+		fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
+		fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
+		fprintf(fp, "\tpushw\t$%d\n", fdp->arg_16_size);
+		fprintf(fp, "\tjmp\t_%s_Dispatch_16\n\n", UpperDLLName);
+		break;
+		
 	      case FUNCTYPE_C:
 	      default:
 		fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
@@ -862,8 +880,8 @@
     for (i = 0; i <= Limit; i++, odp++)
     {
 	if (odp->valid && 
-	    (odp->type == FUNCTYPE_PASCAL || odp->type == FUNCTYPE_C ||
-	     odp->type == FUNCTYPE_REG))
+	    (odp->type == FUNCTYPE_PASCAL || odp->type == FUNCTYPE_PASCAL_16 ||
+	     odp->type == FUNCTYPE_REG || odp->type == FUNCTYPE_C ))
 	{
 	    fdp = odp->additional_data;
 	    fprintf(fp, "extern int %s();\n", fdp->internal_name);
@@ -884,6 +902,7 @@
 	switch (odp->type)
 	{
 	  case FUNCTYPE_PASCAL:
+	  case FUNCTYPE_PASCAL_16:
 	  case FUNCTYPE_REG:
 	    fprintf(fp, "    { 0x%x, %s_Ordinal_%d, ", UTEXTSEL, UpperDLLName, i);
 	    fprintf(fp, "\042%s\042, ", odp->export_name);
diff --git a/windows/nonclient.c b/windows/nonclient.c
index edc5ac2..c364b02 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -27,7 +27,8 @@
 extern void WINPOS_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos,
 			    POINT *minTrack, POINT *maxTrack );  /* winpos.c */
 extern void CURSOR_SetWinCursor( HWND hwnd, HCURSOR hcursor );   /* cursor.c */
-extern WORD MENU_GetMenuBarHeight( HWND hwnd, WORD menubarWidth ); /* menu.c */
+extern WORD MENU_GetMenuBarHeight( HWND hwnd, WORD menubarWidth,
+				   int orgX, int orgY );         /* menu.c */
 
 
   /* Some useful macros */
@@ -127,7 +128,8 @@
     if (HAS_MENU(wndPtr))
     {
 	params->rgrc[0].top += MENU_GetMenuBarHeight( hwnd,
-				params->rgrc[0].right - params->rgrc[0].left );
+				  params->rgrc[0].right - params->rgrc[0].left,
+				  -tmpRect.left, -tmpRect.top ) + 1;
     }
     return 0;
 }
@@ -178,43 +180,61 @@
 
     GetWindowRect( hwnd, &rect );
     if (!PtInRect( &rect, pt )) return HTNOWHERE;
-    ScreenToClient( hwnd, &pt );
-    GetClientRect( hwnd, &rect );
-    
-    if (PtInRect( &rect, pt )) return HTCLIENT;
 
-      /* Check vertical scroll bar */
-    if (wndPtr->dwStyle & WS_VSCROLL)
-    {
-	rect.right += SYSMETRICS_CXVSCROLL;
-	if (PtInRect( &rect, pt )) return HTVSCROLL;
-    }
+      /* Check borders */
 
-      /* Check horizontal scroll bar */
-    if (wndPtr->dwStyle & WS_HSCROLL)
+    if (HAS_THICKFRAME( wndPtr->dwStyle ))
     {
-	rect.bottom += SYSMETRICS_CYHSCROLL;
-	if (PtInRect( &rect, pt ))
+	InflateRect( &rect, -SYSMETRICS_CXFRAME, -SYSMETRICS_CYFRAME );
+	if (wndPtr->dwStyle & WS_BORDER)
+	    InflateRect( &rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER );
+	if (!PtInRect( &rect, pt ))
 	{
-	      /* Check size box */
-	    if ((wndPtr->dwStyle & WS_VSCROLL) &&
-		(pt.x >= rect.right - SYSMETRICS_CXVSCROLL)) return HTSIZE;
-	    return HTHSCROLL;
+	      /* Check top sizing border */
+	    if (pt.y < rect.top)
+	    {
+		if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTTOPLEFT;
+		if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTTOPRIGHT;
+		return HTTOP;
+	    }
+	      /* Check bottom sizing border */
+	    if (pt.y >= rect.bottom)
+	    {
+		if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTBOTTOMLEFT;
+		if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTBOTTOMRIGHT;
+		return HTBOTTOM;
+	    }
+	      /* Check left sizing border */
+	    if (pt.x < rect.left)
+	    {
+		if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPLEFT;
+		if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMLEFT;
+		return HTLEFT;
+	    }
+	      /* Check right sizing border */
+	    if (pt.x >= rect.right)
+	    {
+		if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPRIGHT;
+		if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMRIGHT;
+		return HTRIGHT;
+	    }
 	}
     }
-
-      /* Check menu */
-    if (HAS_MENU(wndPtr))
+    else  /* No thick frame */
     {
-	rect.top -= SYSMETRICS_CYMENU + 1;
-	if (PtInRect( &rect, pt )) return HTMENU;
+	if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle ))
+	    InflateRect(&rect, -SYSMETRICS_CXDLGFRAME, -SYSMETRICS_CYDLGFRAME);
+	else if (wndPtr->dwStyle & WS_BORDER)
+	    InflateRect(&rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER);
+	if (!PtInRect( &rect, pt )) return HTBORDER;
     }
 
       /* Check caption */
+
     if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
     {
-	rect.top -= SYSMETRICS_CYCAPTION - 1;
-	if (PtInRect( &rect, pt ))
+	rect.top += SYSMETRICS_CYCAPTION - 1;
+	if (!PtInRect( &rect, pt ))
 	{
 	      /* Check system menu */
 	    if ((wndPtr->dwStyle & WS_SYSMENU) && (pt.x <= SYSMETRICS_CXSIZE))
@@ -230,40 +250,42 @@
 	    return HTCAPTION;
 	}
     }
-    
-      /* Check non-sizing border */
-    if (!HAS_THICKFRAME( wndPtr->dwStyle )) return HTBORDER;
 
-      /* Check top sizing border */
-    if (pt.y < rect.top)
+      /* Check client area */
+
+    ScreenToClient( hwnd, &pt );
+    GetClientRect( hwnd, &rect );
+    if (PtInRect( &rect, pt )) return HTCLIENT;
+
+      /* Check vertical scroll bar */
+
+    if (wndPtr->dwStyle & WS_VSCROLL)
     {
-	if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTTOPLEFT;
-	if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTTOPRIGHT;
-	return HTTOP;
+	rect.right += SYSMETRICS_CXVSCROLL;
+	if (PtInRect( &rect, pt )) return HTVSCROLL;
     }
 
-      /* Check bottom sizing border */
-    if (pt.y >= rect.bottom)
+      /* Check horizontal scroll bar */
+
+    if (wndPtr->dwStyle & WS_HSCROLL)
     {
-	if (pt.x < rect.left+SYSMETRICS_CXSIZE) return HTBOTTOMLEFT;
-	if (pt.x >= rect.right-SYSMETRICS_CXSIZE) return HTBOTTOMRIGHT;
-	return HTBOTTOM;
-    }
-    
-      /* Check left sizing border */
-    if (pt.x < rect.left)
-    {
-	if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPLEFT;
-	if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMLEFT;
-	return HTLEFT;
+	rect.bottom += SYSMETRICS_CYHSCROLL;
+	if (PtInRect( &rect, pt ))
+	{
+	      /* Check size box */
+	    if ((wndPtr->dwStyle & WS_VSCROLL) &&
+		(pt.x >= rect.right - SYSMETRICS_CXVSCROLL))
+		return HTSIZE;
+	    return HTHSCROLL;
+	}
     }
 
-      /* Check right sizing border */
-    if (pt.x >= rect.right)
+      /* Check menu bar */
+
+    if (HAS_MENU(wndPtr))
     {
-	if (pt.y < rect.top+SYSMETRICS_CYSIZE) return HTTOPRIGHT;
-	if (pt.y >= rect.bottom-SYSMETRICS_CYSIZE) return HTBOTTOMRIGHT;
-	return HTRIGHT;
+	if ((pt.y < 0) && (pt.x >= 0) && (pt.x < rect.right))
+	    return HTMENU;
     }
 
       /* Should never get here */
@@ -537,9 +559,9 @@
 #ifdef DEBUG_NONCLIENT
     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)))
+    if ((!(wndPtr->dwStyle & (WS_BORDER | WS_DLGFRAME | WS_THICKFRAME))) ||
+	(!(wndPtr->dwStyle & WS_VISIBLE)))
 	return;  /* Nothing to do! */
 
     if (hrgn == 1) hdc = GetDCEx( hwnd, 0, DCX_CACHE | DCX_WINDOW );
@@ -594,27 +616,15 @@
 	NC_DrawCaption( hdc, &r, hwnd, wndPtr->dwStyle, active );
     }
 
-    if (wndPtr->wIDmenu != 0 &&
-	(wndPtr->dwStyle & WS_CHILD) != WS_CHILD) {
-	LPPOPUPMENU	lpMenu = (LPPOPUPMENU) GlobalLock(wndPtr->wIDmenu);
-	if (lpMenu != NULL) {
-		int oldHeight;
-		CopyRect(&rect2, &rect);
-		/* Default MenuBar height */
-		if (lpMenu->Height == 0) lpMenu->Height = SYSMETRICS_CYMENU + 1;
-		oldHeight = lpMenu->Height;
-		rect2.bottom = rect2.top + oldHeight; 
-		StdDrawMenuBar(hdc, &rect2, lpMenu, suppress_menupaint);
-		if (oldHeight != lpMenu->Height) {
-			printf("NC_DoNCPaint // menubar changed oldHeight=%d != lpMenu->Height=%d\n",
-									oldHeight, lpMenu->Height);
-			/* Reduce ClientRect according to MenuBar height */
-			wndPtr->rectClient.top -= oldHeight;
-			wndPtr->rectClient.top += lpMenu->Height;
-			}
-		GlobalUnlock(wndPtr->wIDmenu);
-		}
-	}
+    if (HAS_MENU(wndPtr))
+    {
+	LPPOPUPMENU lpMenu = (LPPOPUPMENU) GlobalLock( wndPtr->wIDmenu );
+	RECT r = rect;
+	r.bottom = rect.top + lpMenu->Height;
+	rect.top += lpMenu->Height;
+	StdDrawMenuBar( hdc, &r, lpMenu, suppress_menupaint );
+	GlobalUnlock( wndPtr->wIDmenu );
+    }
 
     if (wndPtr->dwStyle & (WS_VSCROLL | WS_HSCROLL)) {
  	if ((wndPtr->dwStyle & WS_VSCROLL) && (wndPtr->VScroll != NULL) &&
@@ -624,9 +634,6 @@
 			bottom -= SYSMETRICS_CYHSCROLL;
 	    SetRect(&rect2, rect.right - SYSMETRICS_CXVSCROLL, 
 	    	rect.top, rect.right, bottom); 
-	    if (wndPtr->dwStyle & WS_CAPTION) rect.top += SYSMETRICS_CYSIZE;
-	    if (wndPtr->wIDmenu != 0 && (wndPtr->dwStyle & WS_CHILD) != WS_CHILD) 
-	    	rect2.top += SYSMETRICS_CYMENU + 1;
  	    StdDrawScrollBar(hwnd, hdc, SB_VERT, &rect2, (LPHEADSCROLL)wndPtr->VScroll);
  	    }
  	if ((wndPtr->dwStyle & WS_HSCROLL) && wndPtr->HScroll != NULL &&
diff --git a/windows/syscolor.c b/windows/syscolor.c
index c92d549..8d0cda3 100644
--- a/windows/syscolor.c
+++ b/windows/syscolor.c
@@ -45,6 +45,8 @@
 
 static COLORREF SysColors[NUM_SYS_COLORS];
 
+#define MAKE_SOLID(color) \
+         (PALETTEINDEX(GetNearestPaletteIndex(STOCK_DEFAULT_PALETTE,(color))))
 
 /*************************************************************************
  *             SYSCOLOR_SetColor
@@ -69,6 +71,8 @@
 	sysColorObjects.hbrushInactiveCaption = CreateSolidBrush( color );
 	break;
     case COLOR_MENU:
+	DeleteObject( sysColorObjects.hbrushMenu );
+	sysColorObjects.hbrushMenu = CreateSolidBrush( MAKE_SOLID(color) );
 	break;
     case COLOR_WINDOW:
 	DeleteObject( sysColorObjects.hbrushWindow );
@@ -95,7 +99,11 @@
 	sysColorObjects.hbrushInactiveBorder = CreateSolidBrush( color );
 	break;
     case COLOR_APPWORKSPACE:
+	break;
     case COLOR_HIGHLIGHT:
+	DeleteObject( sysColorObjects.hbrushHighlight );
+	sysColorObjects.hbrushHighlight = CreateSolidBrush( MAKE_SOLID(color));
+	break;
     case COLOR_HIGHLIGHTTEXT:
 	break;
     case COLOR_BTNFACE:
diff --git a/windows/win.c b/windows/win.c
index f03902d..8aeba56 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -260,8 +260,11 @@
 #endif
 	/* 'soundrec.exe' has negative position ! 
 	Why ? For now, here a patch : */
-	if (x < 0) x = 0;
-	if (y < 0) y = 0;
+        if (!strcmp(className, "SoundRec"))
+	{
+	    if (x < 0) x = 0;
+	    if (y < 0) y = 0;
+	}
     if (x == CW_USEDEFAULT) x = y = 0;
     if (width == CW_USEDEFAULT)
     {
diff --git a/windows/winpos.c b/windows/winpos.c
index f60ea4a..8e013e7 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -647,16 +647,21 @@
     
       /* Send WM_NCPAINT message if needed */
 
-    if ((flags & (SWP_FRAMECHANGED | SWP_SHOWWINDOW)) ||
-	(!(flags & SWP_NOSIZE)) || (!(flags & SWP_NOMOVE)) ||
-	(!(flags & SWP_NOACTIVATE)) || (!(flags & SWP_NOZORDER)))
-	    SendMessage( winpos->hwnd, WM_NCPAINT, 1, 0L );
-#if 0
-    if ((flags & (SWP_FRAMECHANGED | SWP_SHOWWINDOW)) &&
-	(!(flags & SWP_NOREDRAW)) && 
-	(wndPtr->dwStyle & WS_VISIBLE))
-	InvalidateRect(winpos->hwnd, NULL, TRUE);
-#endif
+    if (flags & SWP_SHOWWINDOW)
+    {
+	  /* Repaint the window frame and background */
+	RedrawWindow( winpos->hwnd, NULL, 0,
+		      RDW_INVALIDATE | RDW_FRAME | RDW_ERASENOW );
+    }
+    else
+    {
+	if ((flags & SWP_FRAMECHANGED) ||
+	    (!(flags & SWP_NOSIZE)) ||
+	    (!(flags & SWP_NOMOVE)) ||
+	    (!(flags & SWP_NOACTIVATE)) ||
+	    (!(flags & SWP_NOZORDER)))
+	        SendMessage( winpos->hwnd, WM_NCPAINT, 1, 0L );
+    }
 
       /* And last, send the WM_WINDOWPOSCHANGED message */