Release 940815
Tue Aug 9 23:58:29 MET DST 1994 <erik@hacktic.nl>
* [misc/file.c]
OpenFile(): Completly rewritten.
* [miscemu/int21.c]
CreateFile(): Fixed wrong mode in call to open.
OpenExistingFile(): Implemented file sharing.
FindNext(): Fixed.
CreateNewFile(): Fixed wrong mode in call to open.
fLock(): Added to handle record locking.
GetFileAttribute(): Added.
As a result, AH = 0x5c, 0x09, and 0x0b were changed.
* [miscemu/int2f.c]
AH = 0x10: SHARE installation check
* [loader/resource.c]
AccessResource(): Fixed. A new file descriptor will be returned by
every call to AccessResource().
* [windows/utility.c]
wvsprintf(): Fixed.
* [controls/menu.c]
FindMenuItem(): Fixed (handling for nPos == -1 added).
* [windows/win.c]
CreateWindowEx(): Added call to WINPOS_GetMinMaxInfo.
* [Configure]
Added two options for a processor emulator that might be
plugged in later..
* [loader/task.c] [include/toolhelp.h] [if1632/toolhelp.spec]
CreateNewTask() stores real modulename instead of 'TASKxxxx'.
Added TaskFirst(), TaskNext(), TaskFindHandle().
* [memory/global.c]
Added stub for MemManInfo().
* [objects/text.c]
Added stub for GetTabbedTextExt().
* [miscemu/*]
Changed all references to registers. Please don't access
the context structure.
fix for GetSystemTime() by <jspeter@birch.ee.vt.edu> added.
* [misc/lstr.c]
Fixed bug in AnsiUpper() & AnsiLower().
* [misc/winsocket.c]
bugfix in getsockopt()/setsockopt(): winsock uses different values
than unix.
* [objects/dib.c]
Added DIB_SetImageBits_RLE[48] to support compressed bitmaps.
Mon Aug 8 21:12:33 1994 David Metcalfe <david@prism.demon.co.uk>
* [controls/edit.c]
Added support for WM_COPY, WM_CUT and WM_PASTE messages.
* [windows/dialog.c] [windows/defdlg.c] [include/dialog.h]
Modified dialog code to create new heap for edit controls
unless DS_LOCALEDIT style is set.
Thu Aug 4 18:50:56 1994 Alexandre Julliard (julliard@lamisun.epfl.ch)
* [controls/button.c] [controls/edit.c] [controls/static.c]
Removed unneeded GlobalUnlock() calls.
* [controls/menu.c] [include/menu.h]
Lots of changes, fixed a lot of old bugs and introduced a lot of
new ones :-)
- Changed message loop to use MSG_GetInternalMessage().
- Fixed a bug that caused the main window to lose activation when
displaying a menu.
- Correctly send initialisation messages (WM_INITMENUPOPUP).
- Implemented EndMenu() and LookupMenuHandle().
- Changed internal structures to be as compatible as possible with
MS-Windows.
- Allocated everything on the USER heap instead of the global heap.
- Prefixed all internal function names with MENU_ and declared
them static.
- Moved "About Wine..." handling to NC_HandleSysCommand().
- Multi-line menus should now work correctly.
* [loader/resource.c] [objects/bitmap.c]
Added the possibility to create OEM bitmaps directly as X bitmaps.
* [objects/dcvalues.c] [windows/dc.c]
Fixed GetDCOrg() to return screen coordinates.
* [windows/message.c]
Fixed double-click checks when the message is not removed from the
queue.
Fixed MSG_GetInternalMessage() to send WM_ENTERIDLE messages.
* [windows/nonclient.c]
Bug fix in system menu hit-test calculation.
A few changes for new menu functions.
Thu Aug 11 17:51:02 1994 Thomas Sandford <t.d.g.sandford@bradford.ac.uk>
* [controls/edit.c]
Bug fix in Edit_NCCreateMessage
es->textlen was being used before being set
* [controls/menu.c]
Bug fix in MENU_DrawMenuItem
don't try to write text if NULL pointer passed
diff --git a/ChangeLog b/ChangeLog
index 59d5518..e7dfebd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,119 @@
----------------------------------------------------------------------
+Tue Aug 9 23:58:29 MET DST 1994 <erik@hacktic.nl>
+
+ * [misc/file.c]
+ OpenFile(): Completly rewritten.
+
+ * [miscemu/int21.c]
+ CreateFile(): Fixed wrong mode in call to open.
+ OpenExistingFile(): Implemented file sharing.
+ FindNext(): Fixed.
+ CreateNewFile(): Fixed wrong mode in call to open.
+ fLock(): Added to handle record locking.
+ GetFileAttribute(): Added.
+ As a result, AH = 0x5c, 0x09, and 0x0b were changed.
+
+ * [miscemu/int2f.c]
+ AH = 0x10: SHARE installation check
+
+ * [loader/resource.c]
+ AccessResource(): Fixed. A new file descriptor will be returned by
+ every call to AccessResource().
+
+ * [windows/utility.c]
+ wvsprintf(): Fixed.
+
+ * [controls/menu.c]
+ FindMenuItem(): Fixed (handling for nPos == -1 added).
+
+ * [windows/win.c]
+ CreateWindowEx(): Added call to WINPOS_GetMinMaxInfo.
+
+ * [Configure]
+ Added two options for a processor emulator that might be
+ plugged in later..
+
+ * [loader/task.c] [include/toolhelp.h] [if1632/toolhelp.spec]
+ CreateNewTask() stores real modulename instead of 'TASKxxxx'.
+ Added TaskFirst(), TaskNext(), TaskFindHandle().
+
+ * [memory/global.c]
+ Added stub for MemManInfo().
+
+ * [objects/text.c]
+ Added stub for GetTabbedTextExt().
+
+ * [miscemu/*]
+ Changed all references to registers. Please don't access
+ the context structure.
+ fix for GetSystemTime() by <jspeter@birch.ee.vt.edu> added.
+
+ * [misc/lstr.c]
+ Fixed bug in AnsiUpper() & AnsiLower().
+
+ * [misc/winsocket.c]
+ bugfix in getsockopt()/setsockopt(): winsock uses different values
+ than unix.
+
+ * [objects/dib.c]
+ Added DIB_SetImageBits_RLE[48] to support compressed bitmaps.
+
+Mon Aug 8 21:12:33 1994 David Metcalfe <david@prism.demon.co.uk>
+
+ * [controls/edit.c]
+ Added support for WM_COPY, WM_CUT and WM_PASTE messages.
+
+ * [windows/dialog.c] [windows/defdlg.c] [include/dialog.h]
+ Modified dialog code to create new heap for edit controls
+ unless DS_LOCALEDIT style is set.
+
+Thu Aug 4 18:50:56 1994 Alexandre Julliard (julliard@lamisun.epfl.ch)
+
+ * [controls/button.c] [controls/edit.c] [controls/static.c]
+ Removed unneeded GlobalUnlock() calls.
+
+ * [controls/menu.c] [include/menu.h]
+ Lots of changes, fixed a lot of old bugs and introduced a lot of
+ new ones :-)
+ - Changed message loop to use MSG_GetInternalMessage().
+ - Fixed a bug that caused the main window to lose activation when
+ displaying a menu.
+ - Correctly send initialisation messages (WM_INITMENUPOPUP).
+ - Implemented EndMenu() and LookupMenuHandle().
+ - Changed internal structures to be as compatible as possible with
+ MS-Windows.
+ - Allocated everything on the USER heap instead of the global heap.
+ - Prefixed all internal function names with MENU_ and declared
+ them static.
+ - Moved "About Wine..." handling to NC_HandleSysCommand().
+ - Multi-line menus should now work correctly.
+
+ * [loader/resource.c] [objects/bitmap.c]
+ Added the possibility to create OEM bitmaps directly as X bitmaps.
+
+ * [objects/dcvalues.c] [windows/dc.c]
+ Fixed GetDCOrg() to return screen coordinates.
+
+ * [windows/message.c]
+ Fixed double-click checks when the message is not removed from the
+ queue.
+ Fixed MSG_GetInternalMessage() to send WM_ENTERIDLE messages.
+
+ * [windows/nonclient.c]
+ Bug fix in system menu hit-test calculation.
+ A few changes for new menu functions.
+
+Thu Aug 11 17:51:02 1994 Thomas Sandford <t.d.g.sandford@bradford.ac.uk>
+
+ * [controls/edit.c]
+ Bug fix in Edit_NCCreateMessage
+ es->textlen was being used before being set
+
+ * [controls/menu.c]
+ Bug fix in MENU_DrawMenuItem
+ don't try to write text if NULL pointer passed
+
+----------------------------------------------------------------------
Thu Aug 4 07:18:02 1994 Michael Patra <micky@marie.physik.tu-berlin.de>
* [windows/message.c]
diff --git a/Configure b/Configure
index 1cb4d5c..c2fee7d 100644
--- a/Configure
+++ b/Configure
@@ -11,8 +11,23 @@
ALLDEFINES="$ALLDEFINES -DWINELIB"
else
WINELIB=''
+ echo -n 'Use processor emulator (*DOES*NOT*WORK*YET*) (Y/N) [N]? '
+ read input
+ if [ "$input" = 'y' -o "$input" = 'Y' ]
+ then
+ PROCEMU='#define PROCEMU'
+ echo -n 'bochs directory [/usr/src/bochs]? '
+ read input
+ if [ "$input" = '' ]
+ then
+ ALLDEFINES="$ALLDEFINES -DPROC_EMU_DIR=/usr/src/bochs"
+ else
+ ALLDEFINES="$ALLDEFINES -DPROC_EMU_DIR="$input
+ fi
+ fi
fi
+echo
echo -n 'Short filenames (Y/N) [N]? '
read input
if [ "$input" = 'y' -o "$input" = 'Y' ]
@@ -47,17 +62,13 @@
NEWBUILD=''
fi
+NEWLINUXLDT=''
if [ -f /usr/include/linux/ldt.h ]
then
- if grep -q seg_not_present /usr/include/linux/ldt.h
+ if grep seg_not_present /usr/include/linux/ldt.h
then
- NEWLINUXLDT='#define NewLinuxLdt -DNEW_LDT_STRUCT'
- ALLDEFINES="$ALLDEFINES -DNEW_LDT_STRUCT"
- else
- NEWLINUXLDT=''
+ NEWLINUXLDT='#define NEW_LDT_STRUCT'
fi
-else
- NEWLINUXLDT=''
fi
echo '/* autoconf.h generated automatically. Run Configure. */' > autoconf.h
@@ -66,6 +77,9 @@
echo $NEWBUILD >> autoconf.h
echo $WINE_INI_GLOBAL >> autoconf.h
echo $NEWLINUXLDT >> autoconf.h
+echo $ENDIAN >> autoconf.h
+echo $PROCEMU >> autoconf.h
+echo $PROCEMUDIR >> autoconf.h
echo "#define AutoDefines $ALLDEFINES" >> autoconf.h
xmkmf -a
diff --git a/controls/button.c b/controls/button.c
index 67de0ab..a5d3946 100644
--- a/controls/button.c
+++ b/controls/button.c
@@ -254,7 +254,6 @@
break;
}
- GlobalUnlock(hWnd);
return lResult;
}
@@ -522,7 +521,6 @@
SelectObject(hDC, hOldPen);
USER_HEAP_FREE(hText);
- GlobalUnlock(hWnd);
EndPaint(hWnd, &ps);
}
@@ -604,7 +602,6 @@
}
NOTIFY_PARENT(hWnd, BN_CLICKED);
}
- GlobalUnlock(hWnd);
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
@@ -644,7 +641,6 @@
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
- GlobalUnlock(hWnd);
}
static LONG CB_GetCheck(HWND hWnd)
@@ -653,7 +649,6 @@
WND *wndPtr = WIN_FindWndPtr(hWnd);
wResult = (WORD)(*(wndPtr->wExtra));
- GlobalUnlock(hWnd);
return (LONG)wResult;
}
@@ -723,7 +718,6 @@
SelectObject(hDC, hOldPen );
USER_HEAP_FREE(hText);
- GlobalUnlock(hWnd);
EndPaint(hWnd, &ps);
}
@@ -777,7 +771,6 @@
(WORD)(*(wndPtr->wExtra)) = 1;
NOTIFY_PARENT(hWnd, BN_CLICKED);
}
- GlobalUnlock(hWnd);
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
@@ -817,7 +810,6 @@
InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd);
}
- GlobalUnlock(hWnd);
}
static LONG RB_GetCheck(HWND hWnd)
@@ -826,7 +818,6 @@
WND *wndPtr = WIN_FindWndPtr(hWnd);
wResult = (WORD)(*(wndPtr->wExtra));
- GlobalUnlock(hWnd);
return (LONG)wResult;
}
diff --git a/controls/edit.c b/controls/edit.c
index 7f00cb8..bcbe8f2 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -17,12 +17,6 @@
#include "user.h"
#include "scroll.h"
-#define EDIT_HEAP_ALLOC(size) USER_HEAP_ALLOC(GMEM_MOVEABLE,size)
-#define EDIT_HEAP_REALLOC(handle,size) USER_HEAP_REALLOC(handle,size,\
- GMEM_MOVEABLE)
-#define EDIT_HEAP_ADDR(handle) USER_HEAP_ADDR(handle)
-#define EDIT_HEAP_FREE(handle) USER_HEAP_FREE(handle)
-
/* #define DEBUG_EDIT /* */
#define NOTIFY_PARENT(hWndCntrl, wNotifyCode) \
@@ -37,7 +31,6 @@
#define HSCROLLDIM (ClientWidth(wndPtr) / 3)
/* "line" dimension for horizontal scroll */
-
typedef struct
{
int wlines; /* number of lines of text */
@@ -172,6 +165,8 @@
unsigned int EDIT_HeapSize(HWND hwnd, unsigned int handle);
void EDIT_SetHandleMsg(HWND hwnd, WORD wParam);
LONG EDIT_SetTabStopsMsg(HWND hwnd, WORD wParam, LONG lParam);
+void EDIT_CopyToClipboard(HWND hwnd);
+void EDIT_PasteMsg(HWND hwnd);
void swap(int *a, int *b);
@@ -326,10 +321,20 @@
EDIT_CharMsg(hwnd, wParam);
break;
+ case WM_COPY:
+ EDIT_CopyToClipboard(hwnd);
+ EDIT_ClearSel(hwnd);
+ break;
+
case WM_CREATE:
lResult = EDIT_CreateMsg(hwnd, lParam);
break;
+ case WM_CUT:
+ EDIT_CopyToClipboard(hwnd);
+ EDIT_DeleteSel(hwnd);
+ break;
+
case WM_DESTROY:
EDIT_HeapFree(hwnd, es->hTextPtrs);
EDIT_HeapFree(hwnd, es->hCharWidths);
@@ -403,6 +408,10 @@
EDIT_PaintMsg(hwnd);
break;
+ case WM_PASTE:
+ EDIT_PasteMsg(hwnd);
+ break;
+
case WM_SETFOCUS:
CreateCaret(hwnd, 0, 2, es->txtht);
SetCaretPos(es->WndCol, es->WndRow * es->txtht);
@@ -435,7 +444,6 @@
break;
}
- GlobalUnlock(hwnd);
return lResult;
}
@@ -479,11 +487,11 @@
{
if (strlen(createStruct->lpszName) < EditBufLen(wndPtr))
{
+ es->textlen = EditBufLen(wndPtr) + 1;
es->hText = EDIT_HeapAlloc(hwnd, EditBufLen(wndPtr) + 2);
text = EDIT_HeapAddr(hwnd, es->hText);
strcpy(text, createStruct->lpszName);
*(text + es->textlen) = '\0';
- es->textlen = EditBufLen(wndPtr) + 1;
}
else
{
@@ -3146,6 +3154,65 @@
/*********************************************************************
+ * EDIT_CopyToClipboard
+ *
+ * Copy the specified text to the clipboard.
+ */
+
+void EDIT_CopyToClipboard(HWND hwnd)
+{
+ HANDLE hMem;
+ char *lpMem;
+ int i, len;
+ char *bbl, *bel;
+ WND *wndPtr = WIN_FindWndPtr(hwnd);
+ EDITSTATE *es =
+ (EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
+
+ bbl = EDIT_TextLine(hwnd, es->SelBegLine) + es->SelBegCol;
+ bel = EDIT_TextLine(hwnd, es->SelEndLine) + es->SelEndCol;
+ len = (int)(bel - bbl);
+
+ hMem = GlobalAlloc(GHND, (DWORD)(len + 1));
+ lpMem = GlobalLock(hMem);
+
+ for (i = 0; i < len; i++)
+ *lpMem++ = *bbl++;
+
+ GlobalUnlock(hMem);
+ OpenClipboard(hwnd);
+ EmptyClipboard();
+ SetClipboardData(CF_TEXT, hMem);
+ CloseClipboard();
+}
+
+
+/*********************************************************************
+ * WM_PASTE message function
+ */
+
+void EDIT_PasteMsg(HWND hwnd)
+{
+ HANDLE hClipMem;
+ char *lpClipMem;
+
+ OpenClipboard(hwnd);
+ if (!(hClipMem = GetClipboardData(CF_TEXT)))
+ {
+ /* no text in clipboard */
+ CloseClipboard();
+ return;
+ }
+ lpClipMem = GlobalLock(hClipMem);
+ EDIT_InsertText(hwnd, lpClipMem, strlen(lpClipMem));
+ GlobalUnlock(hClipMem);
+ CloseClipboard();
+ InvalidateRect(hwnd, NULL, TRUE);
+ UpdateWindow(hwnd);
+}
+
+
+/*********************************************************************
* Utility functions
*/
diff --git a/controls/menu.c b/controls/menu.c
index 18ca832..0f791c7 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -3,71 +3,238 @@
*/
static char RCSId[] = "$Id$";
static char Copyright[] = "Copyright Martin Ayotte, 1993";
+static char Copyright2[] = "Copyright Alexandre Julliard, 1994";
+
+/*
+ * Note: the style MF_MOUSESELECT is used to mark popup items that
+ * have been selected, i.e. their popup menu is currently displayed.
+ * This is probably not the meaning this style has in MS-Windows.
+ */
/*
#define DEBUG_MENU
*/
+#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
#include "windows.h"
#include "syscolor.h"
#include "sysmetrics.h"
#include "prototypes.h"
#include "menu.h"
#include "user.h"
-#include "heap.h"
#include "win.h"
-
-#define SC_ABOUTWINE SC_SCREENSAVE+1
-#define SC_SYSMENU SC_SCREENSAVE+2
-#define SC_ABOUTWINEDLG SC_SCREENSAVE+3
+#include "message.h"
/* 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;
+ /* Flag set by EndMenu() to force an exit from menu tracking */
+static BOOL fEndMenuCalled = FALSE;
+
/* 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;
-HBITMAP hStdMnArrow = 0;
-static BOOL MenuHasFocus = FALSE;
+ /* Values for menu->FocusedItem */
+ /* (other values give the position of the focused item) */
+#define NO_SELECTED_ITEM 0xffff
+#define SYSMENU_SELECTED 0xfffe /* Only valid on menu-bars */
-LPPOPUPMENU PopupMenuGetStorageHeader(HWND hwnd);
-LPPOPUPMENU PopupMenuGetWindowAndStorage(HWND hwnd, WND **wndPtr);
-void StdDrawMenuBar(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop,
- BOOL suppress_draw);
-BOOL MenuButtonDown(HWND hWnd, LPPOPUPMENU lppop, int x, int y);
-void MenuButtonUp(HWND hWnd, LPPOPUPMENU lppop, int x, int y);
-void MenuMouseMove(HWND hWnd, LPPOPUPMENU lppop, WORD wParam, int x, int y);
-void StdDrawPopupMenu(HWND hwnd);
-void ResetHiliteFlags(LPPOPUPMENU lppop);
-void SelectPrevItem(LPPOPUPMENU lppop);
-void SelectNextItem(LPPOPUPMENU lppop);
-BOOL ExecFocusedMenuItem(HWND hWnd, LPPOPUPMENU lppop);
-void MenuItemSelect(HWND hWnd, LPPOPUPMENU lppop, WORD wIndex);
-LPMENUITEM MenuFindItem(LPPOPUPMENU lppop, int x, int y, WORD *lpRet);
-LPMENUITEM MenuFindItemBySelKey(LPPOPUPMENU lppop, WORD key, WORD *lpRet);
-BOOL ActivateMenuBarFocus(HWND hWnd);
-BOOL MenuFocusLoop(HWND hWnd, LPPOPUPMENU lpmenu);
-LPMENUITEM FindMenuItem(HMENU hMenu, WORD nPos, WORD wFlags);
-LPMENUITEM GetMenuItemPtr(LPPOPUPMENU menu, WORD nPos);
+#define IS_STRING_ITEM(flags) (!((flags) & (MF_BITMAP | MF_OWNERDRAW | \
+ MF_MENUBARBREAK | MF_MENUBREAK | MF_SEPARATOR)))
+
+
+extern void NC_DrawSysButton(HWND hwnd, HDC hdc, BOOL down); /* nonclient.c */
+extern void CURSOR_SetWinCursor( HWND hwnd, HCURSOR hcursor ); /* cursor.c */
+
+extern HINSTANCE hSysRes;
+
+static HMENU hSysMenu = 0;
+static HBITMAP hStdCheck = 0;
+static HBITMAP hStdMnArrow = 0;
+
WORD GetSelectionKey(LPSTR str);
LPSTR GetShortCutString(LPSTR str);
int GetShortCutPos(LPSTR str);
-BOOL HideAllSubPopupMenu(LPPOPUPMENU menu);
-void InitStdBitmaps();
HMENU CopySysMenu();
WORD * ParseMenuResource(WORD *first_item, int level, HMENU hMenu);
-void SetMenuLogicalParent(HMENU hMenu, HWND hWnd);
-BOOL FAR PASCAL AboutWine_Proc(HWND hDlg, WORD msg, WORD wParam, LONG lParam);
+
+/***********************************************************************
+ * MENU_Init
+ *
+ * Menus initialisation.
+ */
+BOOL MENU_Init()
+{
+ BITMAP bm;
+
+ /* Load bitmaps */
+
+ if (!(hStdCheck = LoadBitmap( 0, MAKEINTRESOURCE(OBM_CHECK) )))
+ return FALSE;
+ GetObject( hStdCheck, sizeof(BITMAP), (LPSTR)&bm );
+ check_bitmap_width = bm.bmWidth;
+ check_bitmap_height = bm.bmHeight;
+ if (!(hStdMnArrow = LoadBitmap( 0, MAKEINTRESOURCE(OBM_MNARROW) )))
+ return FALSE;
+ GetObject( hStdMnArrow, sizeof(BITMAP), (LPSTR)&bm );
+ arrow_bitmap_width = bm.bmWidth;
+ arrow_bitmap_height = bm.bmHeight;
+
+ /* Load system menu */
+
+ if (!(hSysMenu = LoadMenu( hSysRes, "SYSMENU" )))
+ {
+ printf("SysMenu not found in system resources !\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * MENU_HasSysMenu
+ *
+ * Check whether the window owning the menu bar has a system menu.
+ */
+static BOOL MENU_HasSysMenu( POPUPMENU *menu )
+{
+ WND *wndPtr;
+
+ if (menu->wFlags & MF_POPUP) return FALSE;
+ if (!(wndPtr = WIN_FindWndPtr( menu->hWnd ))) return FALSE;
+ return (wndPtr->dwStyle & WS_SYSMENU) != 0;
+}
+
+
+/***********************************************************************
+ * MENU_IsInSysMenu
+ *
+ * Check whether the point (in screen coords) is in the system menu
+ * of the window owning the given menu.
+ */
+static BOOL MENU_IsInSysMenu( POPUPMENU *menu, POINT pt )
+{
+ WND *wndPtr;
+
+ if (menu->wFlags & MF_POPUP) return FALSE;
+ if (!(wndPtr = WIN_FindWndPtr( menu->hWnd ))) return FALSE;
+ if (!(wndPtr->dwStyle & WS_SYSMENU)) return FALSE;
+ if ((pt.x < wndPtr->rectClient.left) ||
+ (pt.x >= wndPtr->rectClient.left+SYSMETRICS_CXSIZE+SYSMETRICS_CXBORDER))
+ return FALSE;
+ if ((pt.y >= wndPtr->rectClient.top - menu->Height) ||
+ (pt.y < wndPtr->rectClient.top - menu->Height -
+ SYSMETRICS_CYSIZE - SYSMETRICS_CYBORDER)) return FALSE;
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * MENU_FindItem
+ *
+ * Find a menu item. Return a pointer on the item, and modifies *hmenu
+ * in case the item was in a sub-menu.
+ */
+static MENUITEM *MENU_FindItem( HMENU *hmenu, WORD *nPos, WORD wFlags )
+{
+ POPUPMENU *menu;
+ MENUITEM *item;
+ int i;
+
+ if (!(menu = (POPUPMENU *) USER_HEAP_ADDR(*hmenu))) return NULL;
+ item = (MENUITEM *) USER_HEAP_ADDR( menu->hItems );
+ if (wFlags & MF_BYPOSITION)
+ {
+ if (*nPos >= menu->nItems) return NULL;
+ return &item[*nPos];
+ }
+ else
+ {
+ for (i = 0; i < menu->nItems; i++, item++)
+ {
+ if (item->item_id == *nPos)
+ {
+ *nPos = i;
+ return item;
+ }
+ else if (item->item_flags & MF_POPUP)
+ {
+ HMENU hsubmenu = (HMENU)item->item_id;
+ MENUITEM *subitem = MENU_FindItem( &hsubmenu, nPos, wFlags );
+ if (subitem)
+ {
+ *hmenu = hsubmenu;
+ return subitem;
+ }
+ }
+ }
+ }
+ return NULL;
+}
+
+
+/***********************************************************************
+ * MENU_FindItemByCoords
+ *
+ * Find the item at the specified coordinates (screen coords).
+ */
+static MENUITEM *MENU_FindItemByCoords( POPUPMENU *menu, int x, int y, WORD *pos )
+{
+ MENUITEM *item;
+ WND *wndPtr;
+ int i;
+
+ if (!(wndPtr = WIN_FindWndPtr( menu->hWnd ))) return NULL;
+ x -= wndPtr->rectWindow.left;
+ y -= wndPtr->rectWindow.top;
+ item = (MENUITEM *) USER_HEAP_ADDR( menu->hItems );
+ for (i = 0; i < menu->nItems; i++, item++)
+ {
+ if ((x >= item->rect.left) && (x < item->rect.right) &&
+ (y >= item->rect.top) && (y < item->rect.bottom))
+ {
+ if (pos) *pos = i;
+ return item;
+ }
+ }
+ return NULL;
+}
+
+
+/***********************************************************************
+ * MENU_FindItemByKey
+ *
+ * Find the menu item selected by a key press.
+ * Return item id, -1 if none, -2 if we should close the menu.
+ */
+static WORD MENU_FindItemByKey( HWND hwndOwner, HMENU hmenu, WORD key )
+{
+ POPUPMENU *menu;
+ LPMENUITEM lpitem;
+ int i;
+ LONG menuchar;
+
+ menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+ lpitem = (MENUITEM *) USER_HEAP_ADDR( menu->hItems );
+ for (i = 0; i < menu->nItems; i++, lpitem++)
+ {
+ if (toupper(key) == lpitem->sel_key) return i;
+ }
+ menuchar = SendMessage( hwndOwner, WM_MENUCHAR, key,
+ MAKELONG( menu->wFlags, hmenu ) );
+ if (HIWORD(menuchar) == 2) return LOWORD(menuchar);
+ if (HIWORD(menuchar) == 1) return -2;
+ return -1;
+}
/***********************************************************************
@@ -87,7 +254,12 @@
return;
}
- if (!menuBar) lpitem->rect.right += check_bitmap_width+arrow_bitmap_width;
+ if (!menuBar)
+ {
+ lpitem->rect.right += 2 * check_bitmap_width;
+ if (lpitem->item_flags & MF_POPUP)
+ lpitem->rect.right += arrow_bitmap_width;
+ }
if (lpitem->item_flags & MF_BITMAP)
{
@@ -113,30 +285,27 @@
*
* Calculate the size of a popup menu.
*/
-static void MENU_PopupMenuCalcSize( HWND hwnd )
+static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop )
{
- LPPOPUPMENU lppop;
- LPMENUITEM lpitem, lpitemStart, lptmp;
- WND *wndPtr;
+ LPMENUITEM items, lpitem;
HDC hdc;
- int orgX, orgY, maxX;
+ int start, i, 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)
+ items = (MENUITEM *)USER_HEAP_ADDR( lppop->hItems );
+ hdc = GetDC( 0 );
+ maxX = start = 0;
+ while (start < lppop->nItems)
{
+ lpitem = &items[start];
orgX = maxX;
orgY = 0;
/* Parse items until column break or end of menu */
- for (lpitem = lpitemStart; lpitem != NULL; lpitem = lpitem->next)
+ for (i = start; i < lppop->nItems; i++, lpitem++)
{
- if ((lpitem != lpitemStart) &&
+ if ((i != start) &&
(lpitem->item_flags & (MF_MENUBREAK | MF_MENUBARBREAK))) break;
MENU_CalcItemSize( hdc, lpitem, orgX, orgY, FALSE );
maxX = max( maxX, lpitem->rect.right );
@@ -144,19 +313,12 @@
}
/* 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 */
+ while (start < i) items[start++].rect.right = maxX;
lppop->Height = max( lppop->Height, orgY );
- lpitemStart = lpitem;
}
lppop->Width = maxX;
- SetRect( &lppop->rect, 0, 0, lppop->Width, lppop->Height );
- ReleaseDC( hwnd, hdc );
+ ReleaseDC( 0, hdc );
}
@@ -167,8 +329,8 @@
*/
static void MENU_MenuBarCalcSize( HDC hdc, LPRECT lprect, LPPOPUPMENU lppop )
{
- LPMENUITEM lpitem, lpitemStart, lptmp;
- int orgX, orgY, maxY;
+ LPMENUITEM lpitem, items;
+ int start, i, orgX, orgY, maxY;
if ((lprect == NULL) || (lppop == NULL)) return;
if (lppop->nItems == 0) return;
@@ -176,25 +338,26 @@
printf("MenuBarCalcSize left=%d top=%d right=%d bottom=%d !\n",
lprect->left, lprect->top, lprect->right, lprect->bottom);
#endif
+ items = (MENUITEM *)USER_HEAP_ADDR( lppop->hItems );
lppop->Width = lprect->right - lprect->left;
lppop->Height = 0;
maxY = lprect->top;
-
- lpitemStart = lppop->firstItem;
- while (lpitemStart != NULL)
+ start = 0;
+ while (start < lppop->nItems)
{
+ lpitem = &items[start];
orgX = lprect->left;
orgY = maxY;
/* Parse items until line break or end of menu */
- for (lpitem = lpitemStart; lpitem != NULL; lpitem = lpitem->next)
+ for (i = start; i < lppop->nItems; i++, lpitem++)
{
- if ((lpitem != lpitemStart) &&
+ if ((i != start) &&
(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;
+ if (i != start) break;
else lpitem->rect.right = lprect->right;
}
maxY = max( maxY, lpitem->rect.bottom );
@@ -202,18 +365,11 @@
}
/* 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;
+ while (start < i) items[start++].rect.bottom = maxY;
}
lprect->bottom = maxY;
lppop->Height = lprect->bottom - lprect->top;
- CopyRect( &lppop->rect, lprect );
}
@@ -223,7 +379,7 @@
* Draw a single menu item.
*/
static void MENU_DrawMenuItem( HDC hdc, LPMENUITEM lpitem,
- LPRECT menuRect, BOOL menuBar )
+ WORD height, BOOL menuBar )
{
RECT rect;
@@ -242,8 +398,8 @@
if (!menuBar && (lpitem->item_flags & MF_MENUBARBREAK))
{
SelectObject( hdc, sysColorObjects.hpenWindowFrame );
- MoveTo( hdc, rect.left, menuRect->top );
- LineTo( hdc, rect.left, menuRect->bottom );
+ MoveTo( hdc, rect.left, 0 );
+ LineTo( hdc, rect.left, height );
}
if (lpitem->item_flags & MF_SEPARATOR)
{
@@ -252,6 +408,25 @@
LineTo( hdc, rect.right, rect.top + SEPARATOR_HEIGHT/2 );
}
+ /* Setup colors */
+
+ if (lpitem->item_flags & MF_HILITE)
+ {
+ if (lpitem->item_flags & MF_GRAYED)
+ SetTextColor( hdc, GetSysColor( COLOR_GRAYTEXT ) );
+ else
+ 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 ) );
+ }
+
if (!menuBar)
{
/* Draw the check mark */
@@ -287,7 +462,7 @@
{
HDC hMemDC = CreateCompatibleDC( hdc );
SelectObject(hMemDC, hStdMnArrow);
- BitBlt( hdc, rect.right-arrow_bitmap_width,
+ BitBlt( hdc, rect.right-arrow_bitmap_width-1,
(rect.top + rect.bottom - arrow_bitmap_height) / 2,
arrow_bitmap_width, arrow_bitmap_height,
hMemDC, 0, 0, SRCCOPY );
@@ -298,22 +473,6 @@
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)
@@ -327,7 +486,8 @@
DeleteDC( hMemDC );
return;
}
- else /* No bitmap */
+ /* No bitmap - process text if present */
+ else if ((lpitem->item_text) != ((char *) NULL))
{
int x = GetShortCutPos(lpitem->item_text);
if (menuBar)
@@ -349,735 +509,869 @@
/***********************************************************************
- * PopupMenuWndProc
+ * MENU_DrawPopupMenu
+ *
+ * Paint a popup menu.
*/
-LONG PopupMenuWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam )
-{
- CREATESTRUCT *createStruct;
- WORD wRet;
- short x, y;
- WND *wndPtr;
- LPPOPUPMENU lppop, lppop2;
- LPMENUITEM lpitem, lpitem2;
- HMENU hSubMenu;
- RECT rect;
- HDC hDC;
- PAINTSTRUCT ps;
- switch(message) {
- case WM_CREATE:
-#ifdef DEBUG_MENU
- printf("PopupMenu WM_CREATE lParam=%08X !\n", lParam);
-#endif
- createStruct = (CREATESTRUCT *)lParam;
- lppop = (LPPOPUPMENU)createStruct->lpCreateParams;
- if (lppop == NULL) break;
- wndPtr = WIN_FindWndPtr(hwnd);
- *((LPPOPUPMENU *)&wndPtr->wExtra[1]) = lppop;
-#ifdef DEBUG_MENU
- printf("PopupMenu WM_CREATE lppop=%08X !\n", lppop);
-#endif
- InitStdBitmaps();
-#ifdef DEBUG_MENU
- printf("PopupMenu End of WM_CREATE !\n");
-#endif
- ResetHiliteFlags(lppop);
- return 0;
- case WM_DESTROY:
- lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
-#ifdef DEBUG_MENU
- printf("PopupMenu WM_DESTROY %lX !\n", lppop);
-#endif
- return 0;
- case WM_COMMAND:
-#ifdef DEBUG_MENU
- printf("PopupMenuWndProc // WM_COMMAND received !\n");
-#endif
- lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
- if (lppop == NULL) break;
- if (lppop->SysFlag) {
- MenuHasFocus = FALSE;
- if (wParam == SC_ABOUTWINE) {
- printf("SysMenu // Show 'About Wine ...' !\n");
-/* DialogBox(hSysRes, MAKEINTRESOURCE(SC_ABOUTWINEDLG), */
- DialogBox(hSysRes, MAKEINTRESOURCE(2),
- GetParent(hwnd), (FARPROC)AboutWine_Proc);
- }
- else {
-#ifdef DEBUG_MENU
- printf("PopupMenuWndProc // push to Owner WM_SYSCOMMAND !\n");
-#endif
- PostMessage(lppop->ownerWnd, WM_SYSCOMMAND, wParam, lParam);
- }
- break;
- }
-#ifdef DEBUG_MENU
- printf("PopupMenuWndProc // push to Owner WM_COMMAND !\n");
-#endif
- MenuHasFocus = FALSE;
- PostMessage(lppop->hWndParent, WM_COMMAND, wParam, lParam);
- break;
- case WM_SHOWWINDOW:
-#ifdef DEBUG_MENU
- printf("PopupMenuWndProc // WM_SHOWWINDOW received !\n");
-#endif
- lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
- if (lppop == NULL) break;
- if (wParam == 0 && lParam == 0L) {
- ResetHiliteFlags(lppop);
- HideAllSubPopupMenu(lppop);
-#ifdef DEBUG_MENU
- printf("PopupMenuWndProc hWnd=%04X WM_SHOWWINDOW -> HIDE!\n", hwnd);
-#endif
- if (lppop->SysFlag) MenuHasFocus = FALSE;
- SetFocus(lppop->hWndPrev);
- if (GetCapture() != 0) ReleaseCapture();
- break;
- }
- lppop->FocusedItem = (WORD)-1;
- break;
- case WM_LBUTTONDOWN:
- lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
- if (lppop == NULL) break;
- SetCapture(hwnd);
- MenuButtonDown(hwnd, lppop, LOWORD(lParam), HIWORD(lParam));
- break;
- case WM_LBUTTONUP:
- lppop = PopupMenuGetStorageHeader(hwnd);
- if (lppop == NULL) break;
- ReleaseCapture();
- MenuButtonUp(hwnd, lppop, LOWORD(lParam), HIWORD(lParam));
- break;
- case WM_MOUSEMOVE:
- lppop = PopupMenuGetStorageHeader(hwnd);
- if (lppop == NULL) break;
- MenuMouseMove(hwnd, lppop, wParam, LOWORD(lParam), HIWORD(lParam));
- break;
+static void MENU_DrawPopupMenu( HWND hwnd, HDC hdc, HMENU hmenu )
+{
+ POPUPMENU *menu;
+ MENUITEM *item;
+ RECT rect;
+ int i;
- case WM_KEYUP:
-#ifdef DEBUG_MENU
- printf("PopupMenuWndProc hWnd=%04X WM_KEYUP w=%04X l=%08X !\n",
- hwnd, wParam, lParam);
-#endif
- break;
- case WM_KEYDOWN:
-#ifdef DEBUG_MENU
- printf("PopupMenuWndProc hWnd=%04X WM_KEYDOWN w=%04X l=%08X !\n",
- hwnd, wParam, lParam);
-#endif
- if (lParam < 0L) break;
- lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
- if (lppop == NULL) break;
- switch(wParam) {
- case VK_HOME:
- if (lppop->FocusedItem == 0) break;
- MenuItemSelect(hwnd, lppop, 0);
- break;
- case VK_UP:
- if (lppop->BarFlag) break;
- SelectPrevItem(lppop);
- break;
- case VK_DOWN:
- if (lppop->BarFlag) goto ProceedSPACE;
- SelectNextItem(lppop);
- break;
- case VK_LEFT:
- if (lppop->SysFlag != 0) {
- ShowWindow(hwnd, SW_HIDE);
- hwnd = lppop->hWndParent;
- lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
- printf("VK_LEFT // try to put focus on MenuBar %08X !\n", lppop);
- if (lppop == NULL) break;
- MenuItemSelect(hwnd, lppop, lppop->nItems - 1);
- break;
- }
- if (lppop->BarFlag) {
- if (lppop->FocusedItem < 1) {
- MenuItemSelect(hwnd, lppop, -1);
- NC_TrackSysMenu(hwnd);
- break;
- }
- if (HideAllSubPopupMenu(lppop)) {
- MenuItemSelect(hwnd, lppop, lppop->FocusedItem - 1);
- goto ProceedSPACE;
- }
- }
- if (lppop->hWndParent != 0) {
- PostMessage(lppop->hWndParent, WM_KEYDOWN, wParam, lParam);
- break;
- }
- MenuItemSelect(hwnd, lppop, lppop->FocusedItem - 1);
- break;
- case VK_RIGHT:
- if (lppop->SysFlag != 0) {
- ShowWindow(hwnd, SW_HIDE);
- hwnd = lppop->hWndParent;
- lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
- printf("VK_RIGHT // try to put focus on MenuBar %08X !\n", lppop);
- if (lppop == NULL) break;
- MenuItemSelect(hwnd, lppop, 0);
- break;
- }
- if (lppop->BarFlag) {
- if (lppop->FocusedItem >= lppop->nItems - 1) {
- MenuItemSelect(hwnd, lppop, -1);
- NC_TrackSysMenu(hwnd);
- break;
- }
- if (HideAllSubPopupMenu(lppop)) {
- MenuItemSelect(hwnd, lppop, lppop->FocusedItem + 1);
- goto ProceedSPACE;
- }
- }
- if (lppop->hWndParent != 0) {
- PostMessage(lppop->hWndParent, WM_KEYDOWN, wParam, lParam);
- break;
- }
- MenuItemSelect(hwnd, lppop, lppop->FocusedItem + 1);
- break;
- default:
- break;
- }
- break;
- case WM_CHAR:
-#ifdef DEBUG_MENU
- printf("PopupMenuWndProc hWnd=%04X WM_CHAR wParam=%04X !\n", hwnd, wParam);
-#endif
- if (lParam < 0L) break;
- hwnd = GetFocus();
- lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
- if (lppop == NULL) break;
- switch(wParam) {
- case VK_RETURN:
- case VK_SPACE:
-ProceedSPACE: lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
- ExecFocusedMenuItem(hwnd, lppop);
- break;
- case VK_ESCAPE:
- if (lppop->BarFlag) {
-#ifdef DEBUG_MENU
- printf("VK_ESCAPE // Unselect all MenuBar's Items !\n");
-#endif
- if (lppop->FocusedItem != (WORD)-1)
- MenuItemSelect(hwnd, lppop, -1);
- }
- if (lppop->SysFlag) {
-#ifdef DEBUG_MENU
- printf("VK_ESCAPE // SysMenu !\n");
-#endif
- ShowWindow(hwnd, SW_HIDE);
- break;
- }
- if (lppop->hWndParent != 0) {
-#ifdef DEBUG_MENU
- printf("VK_ESCAPE // Hide only SubPopup !\n");
-#endif
- lppop2 = PopupMenuGetWindowAndStorage(lppop->hWndParent, &wndPtr);
- if (lppop2 == NULL) break;
- HideAllSubPopupMenu(lppop2);
- break;
- }
- else {
-#ifdef DEBUG_MENU
- printf("VK_ESCAPE // Hide Root Popup !\n");
-#endif
- ShowWindow(hwnd, SW_HIDE);
- MenuHasFocus = FALSE;
- }
- break;
- default:
- if (wParam >= 'a' && wParam <= 'z') wParam -= 'a' - 'A';
- lpitem = MenuFindItemBySelKey(lppop, wParam, &wRet);
- if (lpitem != NULL) {
- printf("ShortKey Found wRet=%d !\n", wRet);
- MenuItemSelect(hwnd, lppop, wRet);
- lppop->FocusedItem = wRet;
- goto ProceedSPACE;
- }
- printf("ShortKey Not Found wParam=%04X wRet=%d lpitem=%08X !\n",
- wParam, wRet, lpitem);
- if (lppop->hWndParent != (HWND)NULL)
- SendMessage(lppop->hWndParent, WM_MENUCHAR, wParam,
- MAKELONG(0, 0));
- else
- SendMessage(lppop->ownerWnd, WM_MENUCHAR, wParam,
- MAKELONG(0, 0));
- break;
- }
- break;
- case WM_PAINT:
-#ifdef DEBUG_MENU
- printf("PopupMenuWndProc // WM_PAINT received !\n");
-#endif
- StdDrawPopupMenu(hwnd);
- break;
- default:
- return DefWindowProc(hwnd, message, wParam, lParam);
- }
-return 0;
+ GetClientRect( hwnd, &rect );
+ FillRect( hdc, &rect, sysColorObjects.hbrushMenu );
+ menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+ if (!menu || !menu->nItems) return;
+ item = (MENUITEM *) USER_HEAP_ADDR( menu->hItems );
+ for (i = menu->nItems; i > 0; i--, item++)
+ MENU_DrawMenuItem( hdc, item, menu->Height, FALSE );
}
-BOOL ExecFocusedMenuItem(HWND hWnd, LPPOPUPMENU lppop)
+/***********************************************************************
+ * MENU_DrawMenuBar
+ *
+ * Paint a menu bar. Returns the height of the menu bar.
+ */
+WORD MENU_DrawMenuBar(HDC hDC, LPRECT lprect, HMENU hmenu, BOOL suppress_draw)
{
- short x, y;
- LPPOPUPMENU lppop2;
- LPMENUITEM lpitem;
- HMENU hSubMenu;
- RECT rect;
- lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem);
- if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
- hSubMenu = (HMENU)lpitem->item_id;
- lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu);
- if (lppop2 == NULL) return FALSE;
- lppop2->hWndParent = hWnd;
- GetClientRect(hWnd, &rect);
- if (lppop->BarFlag) {
- GetWindowRect(hWnd, &rect);
- y = rect.top + lpitem->rect.bottom;
- TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON,
- rect.left + lpitem->rect.left,
- y, 0, lppop->ownerWnd, (LPRECT)NULL);
- }
- else {
- x = lppop->rect.right;
- GetWindowRect(hWnd, &rect);
- x += rect.left;
- TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON,
- x, rect.top + lpitem->rect.top,
- 0, lppop->ownerWnd, (LPRECT)NULL);
- }
- GlobalUnlock(hSubMenu);
- return TRUE;
- }
- if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
- ((lpitem->item_flags & MF_POPUP) != MF_POPUP)) {
- MenuHasFocus = FALSE;
- if (lppop->BarFlag) {
- PostMessage(lppop->ownerWnd, WM_COMMAND, lpitem->item_id, 0L);
- }
- else {
- ShowWindow(lppop->hWnd, SW_HIDE);
- SendMessage(lppop->hWnd, WM_COMMAND, lpitem->item_id, 0L);
- }
- }
- return TRUE;
-}
-
-
-
-BOOL MenuButtonDown(HWND hWnd, LPPOPUPMENU lppop, int x, int y)
-{
- HDC hDC;
- LPMENUITEM lpitem, lpitem2;
- RECT rect;
- HMENU hSubMenu;
- WORD wRet;
- LPPOPUPMENU lppop2;
- if (lppop == NULL) return;
- lpitem = MenuFindItem(lppop, x, y, &wRet);
-#ifdef DEBUG_MENU
- printf("MenuButtonDown hWnd=%04X x=%d y=%d // wRet=%d lpitem=%08X !\n",
- hWnd, x, y, wRet, lpitem);
-#endif
- if (lpitem != NULL) {
- if (lppop->FocusedItem != (WORD)-1 && wRet == lppop->FocusedItem) {
- lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem);
- if ((lpitem2->item_flags & MF_POPUP) == MF_POPUP) {
- hSubMenu = (HMENU)lpitem2->item_id;
- lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu);
- if (lppop2 == NULL) return FALSE;
- if (IsWindowVisible(lppop2->hWnd)) {
- ShowWindow(lppop2->hWnd, SW_HIDE);
- return TRUE;
- }
- }
- }
- MenuItemSelect(hWnd, lppop, wRet);
- if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
- hSubMenu = (HMENU)lpitem->item_id;
- lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu);
- if (lppop2 == NULL) return FALSE;
- lppop2->hWndParent = hWnd;
- if (lppop->BarFlag) {
- GetWindowRect(hWnd, &rect);
- y = rect.top + lpitem->rect.bottom;
- ReleaseCapture();
- if (MenuHasFocus) {
- TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON,
- rect.left + lpitem->rect.left,
- y, 0, lppop->ownerWnd, (LPRECT)NULL);
- }
- else {
- MenuHasFocus = TRUE;
- TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON,
- rect.left + lpitem->rect.left,
- y, 0, lppop->ownerWnd, (LPRECT)NULL);
- MenuHasFocus = FALSE;
- MenuFocusLoop(hWnd, lppop);
- return TRUE;
- }
- }
- else {
- x = lppop->rect.right;
- GetWindowRect(hWnd, &rect);
- x += rect.left;
- TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON,
- x, rect.top + lpitem->rect.top,
- 0, lppop->ownerWnd, (LPRECT)NULL);
- }
- GlobalUnlock(hSubMenu);
- return TRUE;
- }
- if (lppop->BarFlag && !MenuHasFocus) {
- MenuFocusLoop(hWnd, lppop);
- }
- return TRUE;
- }
- printf("MenuButtonDown // x=%d y=%d // Not Found !\n", x, y);
- if (GetCapture() != 0) ReleaseCapture();
- MenuHasFocus = FALSE;
- ShowWindow(lppop->hWnd, SW_HIDE);
- return FALSE;
-}
-
-
-
-void MenuButtonUp(HWND hWnd, LPPOPUPMENU lppop, int x, int y)
-{
- HDC hDC;
- LPMENUITEM lpitem, lpitem2;
- RECT rect;
- HMENU hSubMenu;
- WORD wRet;
- LPPOPUPMENU lppop2;
- if (lppop == NULL) return;
- lpitem = MenuFindItem(lppop, x, y, &wRet);
-#ifdef DEBUG_MENU
- printf("MenuButtonUp // x=%d y=%d // wRet=%d lpitem=%08X !\n",
- x, y, wRet, lpitem);
-#endif
- if (lpitem != NULL) {
- if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
- return;
- }
- if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) &&
- ((lpitem->item_flags & MF_POPUP) != MF_POPUP)) {
- MenuHasFocus = FALSE;
- if (lppop->BarFlag) {
- PostMessage(lppop->ownerWnd, WM_COMMAND, lpitem->item_id, 0L);
- }
- else {
- ShowWindow(lppop->hWnd, SW_HIDE);
- SendMessage(lppop->hWnd, WM_COMMAND, lpitem->item_id, 0L);
- }
- return;
- }
- }
- if (lppop->FocusedItem != (WORD)-1) {
- MenuItemSelect(hWnd, lppop, lppop->FocusedItem);
- }
-}
-
-
-
-void MenuMouseMove(HWND hWnd, LPPOPUPMENU lppop, WORD wParam, int x, int y)
-{
- HDC hDC;
- RECT rect;
- HMENU hSubMenu;
- LPMENUITEM lpitem, lpitem2;
- LPPOPUPMENU lppop2;
- WORD wRet;
-
- if (GetKeyState(VK_LBUTTON) != 0)
- {
- lpitem = MenuFindItem(lppop, x, y, &wRet);
-#ifdef DEBUG_MENU
- printf("MenuMouseMove // x=%d y=%d // wRet=%d lpitem=%08X !\n",
- x, y, wRet, lpitem);
-#endif
- if ((lpitem != NULL) && (lppop->FocusedItem != wRet))
- {
- lpitem2 = GetMenuItemPtr(lppop, lppop->FocusedItem);
- hDC = GetWindowDC(hWnd);
- if ((lpitem2 != NULL ) &&
- (lpitem2->item_flags & MF_POPUP) == MF_POPUP)
- {
- HideAllSubPopupMenu(lppop);
- }
- MenuItemSelect(hWnd, lppop, wRet);
- if ((lpitem->item_flags & MF_POPUP) == MF_POPUP)
- {
- hSubMenu = (HMENU)lpitem->item_id;
- lppop2 = (LPPOPUPMENU) GlobalLock(hSubMenu);
- if (lppop2 == NULL)
- {
- ReleaseDC(hWnd, hDC);
- return;
- }
- if (lppop->BarFlag)
- {
- lppop2->hWndParent = hWnd;
- GetWindowRect(hWnd, &rect);
- rect.top += lpitem->rect.bottom;
- TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON,
- rect.left + lpitem->rect.left, rect.top,
- 0, lppop->ownerWnd, (LPRECT)NULL);
- }
- GlobalUnlock(hSubMenu);
- }
- ReleaseDC(hWnd, hDC);
- }
- }
-}
-
-
-void SelectPrevItem(LPPOPUPMENU lppop)
-{
- int nIndex;
- LPMENUITEM lpitem;
- if (lppop == NULL) return;
- nIndex = lppop->FocusedItem;
- if (nIndex < 1) {
- if (nIndex == -1)
- nIndex = 0;
- else
- nIndex = lppop->nItems - 1;
- lpitem = GetMenuItemPtr(lppop, nIndex);
- }
- else {
- nIndex--;
- lpitem = GetMenuItemPtr(lppop, nIndex);
- }
- while (lpitem != NULL && lpitem->item_flags & MF_SEPARATOR) {
- nIndex--;
- lpitem = GetMenuItemPtr(lppop, nIndex);
- }
- MenuItemSelect(lppop->hWnd, lppop, nIndex);
-}
-
-
-void SelectNextItem(LPPOPUPMENU lppop)
-{
- int nIndex;
- LPMENUITEM lpitem;
- if (lppop == NULL) return;
- nIndex = lppop->FocusedItem;
- if ((nIndex == -1) || (nIndex >= lppop->nItems - 1)) {
- nIndex = 0;
- lpitem = GetMenuItemPtr(lppop, nIndex);
- }
- else {
- nIndex++;
- lpitem = GetMenuItemPtr(lppop, nIndex);
- }
- while (lpitem != NULL && (lpitem->item_flags & MF_SEPARATOR)) {
- nIndex++;
- lpitem = GetMenuItemPtr(lppop, nIndex);
- }
- MenuItemSelect(lppop->hWnd, lppop, nIndex);
-}
-
-
-void ResetHiliteFlags(LPPOPUPMENU lppop)
-{
- LPMENUITEM lpitem;
- int i;
-#ifdef DEBUG_MENU
- printf("ResetHiliteFlags lppop=%08X\n", lppop);
-#endif
- if (lppop == NULL) return;
- lpitem = lppop->firstItem;
- for(i = 0; i < lppop->nItems; i++) {
- if (lpitem == NULL) return;
- lpitem->item_flags &= ~MF_HILITE;
- lpitem = (LPMENUITEM)lpitem->next;
- }
-}
-
-
-void MenuItemSelect(HWND hWnd, LPPOPUPMENU lppop, WORD wIndex)
-{
+ LPPOPUPMENU lppop;
LPMENUITEM lpitem;
+ int i;
+
+ lppop = (LPPOPUPMENU) USER_HEAP_ADDR( hmenu );
+ if (lppop == NULL || lprect == NULL) return SYSMETRICS_CYMENU;
+#ifdef DEBUG_MENU
+ printf("MENU_DrawMenuBar(%04X, %08X, %08X); !\n", hDC, lprect, lppop);
+#endif
+ if (lppop->Height == 0) MENU_MenuBarCalcSize(hDC, lprect, lppop);
+ if (suppress_draw) return lppop->Height;
+
+ 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 SYSMETRICS_CYMENU;
+ lpitem = (MENUITEM *) USER_HEAP_ADDR( lppop->hItems );
+ for (i = 0; i < lppop->nItems; i++, lpitem++)
+ {
+ MENU_DrawMenuItem( hDC, lpitem, lppop->Height, TRUE );
+ }
+ return lppop->Height;
+}
+
+
+/***********************************************************************
+ * MENU_ShowPopup
+ *
+ * Display a popup menu.
+ */
+static BOOL MENU_ShowPopup(HWND hwndOwner, HMENU hmenu, WORD id, int x, int y)
+{
+ POPUPMENU *menu;
+
+ if (!(menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu ))) return FALSE;
+ if (menu->FocusedItem != NO_SELECTED_ITEM)
+ {
+ MENUITEM *item = (MENUITEM *) USER_HEAP_ADDR( menu->hItems );
+ item[menu->FocusedItem].item_flags &= ~(MF_HILITE | MF_MOUSESELECT);
+ menu->FocusedItem = NO_SELECTED_ITEM;
+ }
+ SendMessage( hwndOwner, WM_INITMENUPOPUP, hmenu,
+ MAKELONG( id, (menu->wFlags & MF_POPUP) ? 1 : 0 ));
+ MENU_PopupMenuCalcSize( menu );
+ if (!menu->hWnd)
+ {
+ WND *wndPtr = WIN_FindWndPtr( hwndOwner );
+ if (!wndPtr) return FALSE;
+ menu->hWnd = CreateWindow( POPUPMENU_CLASS_NAME, "",
+ WS_POPUP | WS_BORDER, x, y,
+ menu->Width + 2*SYSMETRICS_CXBORDER,
+ menu->Height + 2*SYSMETRICS_CYBORDER,
+ 0, 0, wndPtr->hInstance,
+ (LPSTR)(DWORD)hmenu );
+ if (!menu->hWnd) return FALSE;
+ }
+ else SetWindowPos( menu->hWnd, 0, x, y,
+ menu->Width + 2*SYSMETRICS_CXBORDER,
+ menu->Height + 2*SYSMETRICS_CYBORDER,
+ SWP_NOACTIVATE | SWP_NOZORDER );
+
+ /* Display the window */
+
+ SetWindowPos( menu->hWnd, HWND_TOP, 0, 0, 0, 0,
+ SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE );
+ UpdateWindow( menu->hWnd );
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * MENU_SelectItem
+ */
+static void MENU_SelectItem( HMENU hmenu, WORD wIndex )
+{
+ MENUITEM *items;
+ LPPOPUPMENU lppop;
HDC hdc;
- if (lppop == NULL) return;
- if (lppop->BarFlag) hdc = GetDCEx( hWnd, 0, DCX_CACHE | DCX_WINDOW );
- else hdc = GetDC( hWnd );
+ lppop = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+ if (!lppop->nItems) return;
+ items = (MENUITEM *) USER_HEAP_ADDR( lppop->hItems );
+ if ((wIndex != NO_SELECTED_ITEM) &&
+ (wIndex != SYSMENU_SELECTED) &&
+ (items[wIndex].item_flags & MF_SEPARATOR))
+ wIndex = NO_SELECTED_ITEM;
+ if (lppop->FocusedItem == wIndex) return;
+ if (lppop->wFlags & MF_POPUP) hdc = GetDC( lppop->hWnd );
+ else hdc = GetDCEx( lppop->hWnd, 0, DCX_CACHE | DCX_WINDOW);
/* Clear previous highlighted item */
- if (lppop->FocusedItem != (WORD)-1)
+ if (lppop->FocusedItem != NO_SELECTED_ITEM)
{
- if ((lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem)) != NULL)
+ if (lppop->FocusedItem == SYSMENU_SELECTED)
+ NC_DrawSysButton( lppop->hWnd, hdc, FALSE );
+ else
{
- lpitem->item_flags &= ~MF_HILITE;
- if ((lpitem->item_flags & MF_POPUP) == MF_POPUP)
- HideAllSubPopupMenu(lppop);
- MENU_DrawMenuItem( hdc, lpitem, &lppop->rect, lppop->BarFlag );
+ items[lppop->FocusedItem].item_flags &=~(MF_HILITE|MF_MOUSESELECT);
+ MENU_DrawMenuItem( hdc, &items[lppop->FocusedItem], lppop->Height,
+ !(lppop->wFlags & MF_POPUP) );
}
}
/* Highlight new item (if any) */
lppop->FocusedItem = wIndex;
- if (lppop->FocusedItem != (WORD)-1)
+ if (lppop->FocusedItem != NO_SELECTED_ITEM)
{
- if ((lpitem = GetMenuItemPtr(lppop, lppop->FocusedItem)) != NULL)
+ if (lppop->FocusedItem == SYSMENU_SELECTED)
+ NC_DrawSysButton( lppop->hWnd, hdc, TRUE );
+ else
{
- 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));
+ items[lppop->FocusedItem].item_flags |= MF_HILITE;
+ MENU_DrawMenuItem( hdc, &items[lppop->FocusedItem], lppop->Height,
+ !(lppop->wFlags & MF_POPUP) );
+ SendMessage(lppop->hWnd, WM_MENUSELECT,
+ items[lppop->FocusedItem].item_id,
+ MAKELONG( hmenu, items[lppop->FocusedItem].item_flags));
}
}
- ReleaseDC( hWnd, hdc );
+ ReleaseDC( lppop->hWnd, hdc );
}
-LPPOPUPMENU PopupMenuGetWindowAndStorage(HWND hwnd, WND **wndPtr)
+/***********************************************************************
+ * MENU_SelectNextItem
+ */
+static void MENU_SelectNextItem( HMENU hmenu )
{
- WND *Ptr;
- LPPOPUPMENU lppop;
- *(wndPtr) = Ptr = WIN_FindWndPtr(hwnd);
- if (Ptr == 0) {
- printf("PopupMenuGetWindowAndStorage // Bad Window handle !\n");
- return NULL;
- }
- lppop = *((LPPOPUPMENU *)&Ptr->wExtra[1]);
- if (lppop == NULL) {
- lppop = (LPPOPUPMENU) GlobalLock(Ptr->wIDmenu);
- if (lppop == NULL) {
- printf("PopupMenuGetWindowAndStorage // Bad Menu Handle !\n");
- return NULL;
- }
- }
- return lppop;
-}
+ int i;
+ MENUITEM *items;
+ POPUPMENU *menu;
-
-LPPOPUPMENU PopupMenuGetStorageHeader(HWND hwnd)
-{
- WND *Ptr;
- LPPOPUPMENU lppop;
- Ptr = WIN_FindWndPtr(hwnd);
- if (Ptr == 0) {
- printf("Bad Window handle on PopupMenu !\n");
- return 0;
- }
- lppop = *((LPPOPUPMENU *)&Ptr->wExtra[1]);
- return lppop;
-}
-
-
-void SetMenuLogicalParent(HMENU hMenu, HWND hWnd)
-{
- LPPOPUPMENU lppop;
- lppop = (LPPOPUPMENU)GlobalLock(hMenu);
- lppop->hWndParent = hWnd;
- GlobalUnlock(hMenu);
-}
-
-
-void StdDrawPopupMenu(HWND hwnd)
-{
- WND *wndPtr;
- LPPOPUPMENU lppop;
- LPMENUITEM lpitem;
- PAINTSTRUCT ps;
- RECT rect;
- HDC hDC;
-
- hDC = BeginPaint(hwnd, &ps);
- GetClientRect(hwnd, &rect);
- FillRect(hDC, &rect, sysColorObjects.hbrushMenu );
-
- lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr);
- for (lpitem = lppop->firstItem; lpitem != NULL; lpitem = lpitem->next )
+ menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+ if (!menu->nItems) return;
+ items = (MENUITEM *) USER_HEAP_ADDR( menu->hItems );
+ if ((menu->FocusedItem != NO_SELECTED_ITEM) &&
+ (menu->FocusedItem != SYSMENU_SELECTED))
+ {
+ for (i = menu->FocusedItem+1; i < menu->nItems; i++)
{
- MENU_DrawMenuItem( hDC, lpitem, &rect, FALSE );
+ if (!(items[i].item_flags & MF_SEPARATOR))
+ {
+ MENU_SelectItem( hmenu, i );
+ return;
+ }
}
- EndPaint( hwnd, &ps );
+ if (MENU_HasSysMenu( menu ))
+ {
+ MENU_SelectItem( hmenu, SYSMENU_SELECTED );
+ return;
+ }
+ }
+ for (i = 0; i < menu->nItems; i++)
+ {
+ if (!(items[i].item_flags & MF_SEPARATOR))
+ {
+ MENU_SelectItem( hmenu, i );
+ return;
+ }
+ }
+ if (MENU_HasSysMenu( menu )) MENU_SelectItem( hmenu, SYSMENU_SELECTED );
}
-void StdDrawMenuBar(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop,
- BOOL suppress_draw)
+/***********************************************************************
+ * MENU_SelectPrevItem
+ */
+static void MENU_SelectPrevItem( HMENU hmenu )
{
- LPMENUITEM lpitem;
- if (lppop == NULL || lprect == NULL) return;
+ int i;
+ MENUITEM *items;
+ POPUPMENU *menu;
+
+ menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+ if (!menu->nItems) return;
+ items = (MENUITEM *) USER_HEAP_ADDR( menu->hItems );
+ if ((menu->FocusedItem != NO_SELECTED_ITEM) &&
+ (menu->FocusedItem != SYSMENU_SELECTED))
+ {
+ for (i = menu->FocusedItem - 1; i >= 0; i--)
+ {
+ if (!(items[i].item_flags & MF_SEPARATOR))
+ {
+ MENU_SelectItem( hmenu, i );
+ return;
+ }
+ }
+ if (MENU_HasSysMenu( menu ))
+ {
+ MENU_SelectItem( hmenu, SYSMENU_SELECTED );
+ return;
+ }
+ }
+ for (i = menu->nItems - 1; i > 0; i--)
+ {
+ if (!(items[i].item_flags & MF_SEPARATOR))
+ {
+ MENU_SelectItem( hmenu, i );
+ return;
+ }
+ }
+ if (MENU_HasSysMenu( menu )) MENU_SelectItem( hmenu, SYSMENU_SELECTED );
+}
+
+
+/***********************************************************************
+ * MENU_GetSubPopup
+ *
+ * Return the handle of the selected sub-popup menu (if any).
+ */
+static HMENU MENU_GetSubPopup( HMENU hmenu )
+{
+ POPUPMENU *menu;
+ MENUITEM *item;
+
+ menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+ if (menu->FocusedItem == NO_SELECTED_ITEM) return 0;
+ else if (menu->FocusedItem == SYSMENU_SELECTED)
+ return GetSystemMenu( menu->hWnd, FALSE );
+
+ item = ((MENUITEM *)USER_HEAP_ADDR( menu->hItems )) + menu->FocusedItem;
+ if (!(item->item_flags & MF_POPUP) || !(item->item_flags & MF_MOUSESELECT))
+ return 0;
+ return item->item_id;
+}
+
+
+/***********************************************************************
+ * MENU_HideSubPopups
+ *
+ * Hide the sub-popup menus of this menu.
+ */
+static void MENU_HideSubPopups( HMENU hmenu )
+{
+ MENUITEM *item;
+ POPUPMENU *menu, *submenu;
+ HMENU hsubmenu;
+
+ if (!(menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu ))) return;
+ if (menu->FocusedItem == NO_SELECTED_ITEM) return;
+ if (menu->FocusedItem == SYSMENU_SELECTED)
+ {
+ hsubmenu = GetSystemMenu( menu->hWnd, FALSE );
+ }
+ else
+ {
+ item = ((MENUITEM *)USER_HEAP_ADDR(menu->hItems)) + menu->FocusedItem;
+ if (!(item->item_flags & MF_POPUP) ||
+ !(item->item_flags & MF_MOUSESELECT)) return;
+ item->item_flags &= ~MF_MOUSESELECT;
+ hsubmenu = item->item_id;
+ }
+ submenu = (POPUPMENU *) USER_HEAP_ADDR( hsubmenu );
+ MENU_HideSubPopups( hsubmenu );
+ if (submenu->hWnd) ShowWindow( submenu->hWnd, SW_HIDE );
+ MENU_SelectItem( hsubmenu, NO_SELECTED_ITEM );
+}
+
+
+/***********************************************************************
+ * MENU_ShowSubPopup
+ *
+ * Display the sub-menu of the selected item of this menu.
+ * Return the handle of the submenu, or hmenu if no submenu to display.
+ */
+static HMENU MENU_ShowSubPopup( HWND hwndOwner, HMENU hmenu, BOOL selectFirst )
+{
+ POPUPMENU *menu;
+ MENUITEM *item;
+ WND *wndPtr;
+
+ if (!(menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu ))) return hmenu;
+ if (!(wndPtr = WIN_FindWndPtr( menu->hWnd ))) return hmenu;
+ if (menu->FocusedItem == NO_SELECTED_ITEM) return hmenu;
+ if (menu->FocusedItem == SYSMENU_SELECTED)
+ {
+ MENU_ShowPopup(hwndOwner, wndPtr->hSysMenu, 0, wndPtr->rectClient.left,
+ wndPtr->rectClient.top - menu->Height - 2*SYSMETRICS_CYBORDER);
+ if (selectFirst) MENU_SelectNextItem( wndPtr->hSysMenu );
+ return wndPtr->hSysMenu;
+ }
+ item = ((MENUITEM *)USER_HEAP_ADDR( menu->hItems )) + menu->FocusedItem;
+ if (!(item->item_flags & MF_POPUP) ||
+ (item->item_flags & (MF_GRAYED | MF_DISABLED))) return hmenu;
+ item->item_flags |= MF_MOUSESELECT;
+ if (menu->wFlags & MF_POPUP)
+ {
+ MENU_ShowPopup( hwndOwner, (HMENU)item->item_id, menu->FocusedItem,
+ wndPtr->rectWindow.left + item->rect.right-arrow_bitmap_width,
+ wndPtr->rectWindow.top + item->rect.top );
+ }
+ else
+ {
+ MENU_ShowPopup( hwndOwner, (HMENU)item->item_id, menu->FocusedItem,
+ wndPtr->rectWindow.left + item->rect.left,
+ wndPtr->rectWindow.top + item->rect.bottom );
+ }
+ if (selectFirst) MENU_SelectNextItem( (HMENU)item->item_id );
+ return (HMENU)item->item_id;
+}
+
+
+/***********************************************************************
+ * MENU_FindMenuByCoords
+ *
+ * Find the menu containing a given point (in screen coords).
+ */
+static HMENU MENU_FindMenuByCoords( HMENU hmenu, POINT pt )
+{
+ POPUPMENU *menu;
+ HWND hwnd;
+
+ if (!(hwnd = WindowFromPoint( pt ))) return 0;
+ while (hmenu)
+ {
+ menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+ if (menu->hWnd == hwnd)
+ {
+ if (!(menu->wFlags & MF_POPUP))
+ {
+ /* Make sure it's in the menu bar (or in system menu) */
+ WND *wndPtr = WIN_FindWndPtr( menu->hWnd );
+ if ((pt.x < wndPtr->rectClient.left) ||
+ (pt.x >= wndPtr->rectClient.right) ||
+ (pt.y >= wndPtr->rectClient.top)) return 0;
+ if (pt.y < wndPtr->rectClient.top - menu->Height)
+ {
+ if (!MENU_IsInSysMenu( menu, pt )) return 0;
+ }
+ /* else it's in the menu bar */
+ }
+ return hmenu;
+ }
+ hmenu = MENU_GetSubPopup( hmenu );
+ }
+ return 0;
+}
+
+
+/***********************************************************************
+ * MENU_ExecFocusedItem
+ *
+ * Execute a menu item (for instance when user pressed Enter).
+ * Return TRUE if we can go on with menu tracking.
+ */
+static BOOL MENU_ExecFocusedItem( HWND hwndOwner, HMENU hmenu,
+ HMENU *hmenuCurrent )
+{
+ MENUITEM *item;
+ POPUPMENU *menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+ if (!menu || !menu->nItems || (menu->FocusedItem == NO_SELECTED_ITEM) ||
+ (menu->FocusedItem == SYSMENU_SELECTED)) return TRUE;
+ item = ((MENUITEM *)USER_HEAP_ADDR( menu->hItems )) + menu->FocusedItem;
+ if (!(item->item_flags & MF_POPUP))
+ {
+ if (!(item->item_flags & (MF_GRAYED | MF_DISABLED)))
+ {
+ PostMessage( hwndOwner, (menu->wFlags & MF_SYSMENU) ?
+ WM_SYSCOMMAND : WM_COMMAND, item->item_id, 0 );
+ return FALSE;
+ }
+ else return TRUE;
+ }
+ else
+ {
+ *hmenuCurrent = MENU_ShowSubPopup( hwndOwner, hmenu, TRUE );
+ return TRUE;
+ }
+}
+
+
+/***********************************************************************
+ * MENU_ButtonDown
+ *
+ * Handle a button-down event in a menu. Point is in screen coords.
+ * hmenuCurrent is the top-most visible popup.
+ * Return TRUE if we can go on with menu tracking.
+ */
+static BOOL MENU_ButtonDown( HWND hwndOwner, HMENU hmenu, HMENU *hmenuCurrent,
+ POINT pt )
+{
+ POPUPMENU *menu;
+ MENUITEM *item;
+ WORD id;
+
+ if (!hmenu) return FALSE; /* Outside all menus */
+ menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+ item = MENU_FindItemByCoords( menu, pt.x, pt.y, &id );
+ if (!item) /* Maybe in system menu */
+ {
+ if (!MENU_IsInSysMenu( menu, pt )) return FALSE;
+ id = SYSMENU_SELECTED;
+ }
+
+ if (menu->FocusedItem == id)
+ {
+ if (id == SYSMENU_SELECTED) return FALSE;
+ if (item->item_flags & MF_POPUP)
+ {
+ if (item->item_flags & MF_MOUSESELECT)
+ {
+ if (menu->wFlags & MF_POPUP)
+ {
+ MENU_HideSubPopups( hmenu );
+ *hmenuCurrent = hmenu;
+ }
+ else return FALSE;
+ }
+ else *hmenuCurrent = MENU_ShowSubPopup( hwndOwner, hmenu, FALSE );
+ }
+ }
+ else
+ {
+ MENU_HideSubPopups( hmenu );
+ MENU_SelectItem( hmenu, id );
+ *hmenuCurrent = MENU_ShowSubPopup( hwndOwner, hmenu, FALSE );
+ }
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * MENU_ButtonUp
+ *
+ * Handle a button-up event in a menu. Point is in screen coords.
+ * hmenuCurrent is the top-most visible popup.
+ * Return TRUE if we can go on with menu tracking.
+ */
+static BOOL MENU_ButtonUp( HWND hwndOwner, HMENU hmenu, HMENU *hmenuCurrent,
+ POINT pt )
+{
+ POPUPMENU *menu;
+ MENUITEM *item;
+ HMENU hsubmenu;
+ WORD id;
+
+ if (!hmenu) return FALSE; /* Outside all menus */
+ menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+ item = MENU_FindItemByCoords( menu, pt.x, pt.y, &id );
+ if (!item) /* Maybe in system menu */
+ {
+ if (!MENU_IsInSysMenu( menu, pt )) return FALSE;
+ id = SYSMENU_SELECTED;
+ hsubmenu = GetSystemMenu( menu->hWnd, FALSE );
+ }
+
+ if (menu->FocusedItem != id) return FALSE;
+
+ if (id != SYSMENU_SELECTED)
+ {
+ if (!(item->item_flags & MF_POPUP))
+ {
+ return MENU_ExecFocusedItem( hwndOwner, hmenu, hmenuCurrent );
+ }
+ hsubmenu = item->item_id;
+ }
+ /* Select first item of sub-popup */
+ MENU_SelectItem( hsubmenu, NO_SELECTED_ITEM );
+ MENU_SelectNextItem( hsubmenu );
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * MENU_MouseMove
+ *
+ * Handle a motion event in a menu. Point is in screen coords.
+ * hmenuCurrent is the top-most visible popup.
+ * Return TRUE if we can go on with menu tracking.
+ */
+static BOOL MENU_MouseMove( HWND hwndOwner, HMENU hmenu, HMENU *hmenuCurrent,
+ POINT pt )
+{
+ POPUPMENU *menu;
+ MENUITEM *item;
+ WORD id = NO_SELECTED_ITEM;
+
+ if (hmenu)
+ {
+ menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+ item = MENU_FindItemByCoords( menu, pt.x, pt.y, &id );
+ if (!item) /* Maybe in system menu */
+ {
+ if (!MENU_IsInSysMenu( menu, pt ))
+ id = NO_SELECTED_ITEM; /* Outside all items */
+ else id = SYSMENU_SELECTED;
+ }
+ }
+ if (id == NO_SELECTED_ITEM)
+ {
+ MENU_SelectItem( *hmenuCurrent, NO_SELECTED_ITEM );
+ }
+ else if (menu->FocusedItem != id)
+ {
+ MENU_HideSubPopups( hmenu );
+ MENU_SelectItem( hmenu, id );
+ *hmenuCurrent = MENU_ShowSubPopup( hwndOwner, hmenu, FALSE );
+ }
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * MENU_KeyLeft
+ *
+ * Handle a VK_LEFT key event in a menu.
+ * hmenuCurrent is the top-most visible popup.
+ */
+static void MENU_KeyLeft( HWND hwndOwner, HMENU hmenu, HMENU *hmenuCurrent )
+{
+ POPUPMENU *menu;
+ HMENU hmenutmp, hmenuprev;
+
+ menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+ hmenuprev = hmenutmp = hmenu;
+ while (hmenutmp != *hmenuCurrent)
+ {
+ hmenutmp = MENU_GetSubPopup( hmenuprev );
+ if (hmenutmp != *hmenuCurrent) hmenuprev = hmenutmp;
+ }
+ MENU_HideSubPopups( hmenuprev );
+
+ if ((hmenuprev == hmenu) && !(menu->wFlags & MF_POPUP))
+ {
+ /* Select previous item on the menu bar */
+ MENU_SelectPrevItem( hmenu );
+ if (*hmenuCurrent != hmenu)
+ {
+ /* A popup menu was displayed -> display the next one */
+ *hmenuCurrent = MENU_ShowSubPopup( hwndOwner, hmenu, TRUE );
+ }
+ }
+ else *hmenuCurrent = hmenuprev;
+}
+
+
+/***********************************************************************
+ * MENU_KeyRight
+ *
+ * Handle a VK_RIGHT key event in a menu.
+ * hmenuCurrent is the top-most visible popup.
+ */
+static void MENU_KeyRight( HWND hwndOwner, HMENU hmenu, HMENU *hmenuCurrent )
+{
+ POPUPMENU *menu;
+ HMENU hmenutmp;
+
+ menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+
+ if ((menu->wFlags & MF_POPUP) || (*hmenuCurrent != hmenu))
+ {
+ /* If already displaying a popup, try to display sub-popup */
+ hmenutmp = MENU_ShowSubPopup( hwndOwner, *hmenuCurrent, TRUE );
+ if (hmenutmp != *hmenuCurrent) /* Sub-popup displayed */
+ {
+ *hmenuCurrent = hmenutmp;
+ return;
+ }
+ }
+
+ /* If on menu-bar, go to next item */
+ if (!(menu->wFlags & MF_POPUP))
+ {
+ MENU_HideSubPopups( hmenu );
+ MENU_SelectNextItem( hmenu );
+ if (*hmenuCurrent != hmenu)
+ {
+ /* A popup menu was displayed -> display the next one */
+ *hmenuCurrent = MENU_ShowSubPopup( hwndOwner, hmenu, TRUE );
+ }
+ }
+ else if (*hmenuCurrent != hmenu) /* Hide last level popup */
+ {
+ HMENU hmenuprev;
+ hmenuprev = hmenutmp = hmenu;
+ while (hmenutmp != *hmenuCurrent)
+ {
+ hmenutmp = MENU_GetSubPopup( hmenuprev );
+ if (hmenutmp != *hmenuCurrent) hmenuprev = hmenutmp;
+ }
+ MENU_HideSubPopups( hmenuprev );
+ *hmenuCurrent = hmenuprev;
+ }
+}
+
+
+/***********************************************************************
+ * MENU_TrackMenu
+ *
+ * Menu tracking code.
+ * If 'x' and 'y' are not 0, we simulate a button-down event at (x,y)
+ * before beginning tracking. This is to help menu-bar tracking.
+ */
+static BOOL MENU_TrackMenu( HMENU hmenu, WORD wFlags, int x, int y,
+ HWND hwnd, LPRECT lprect )
+{
+ MSG msg;
+ POPUPMENU *menu;
+ HMENU hmenuCurrent = hmenu;
+ BOOL fClosed = FALSE;
+ WORD pos;
+
+ fEndMenuCalled = FALSE;
+ if (!(menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu ))) return FALSE;
+ if (x && y)
+ {
+ POINT pt = { x, y };
+ MENU_ButtonDown( hwnd, hmenu, &hmenuCurrent, pt );
+ }
+ SetCapture( hwnd );
+
+ while (!fClosed)
+ {
+ if (!MSG_InternalGetMessage( &msg, 0, hwnd, MSGF_MENU, 0, TRUE ))
+ break;
+
+ if ((msg.message >= WM_MOUSEFIRST) && (msg.message <= WM_MOUSELAST))
+ {
+ /* Find the sub-popup for this mouse event (if any) */
+ HMENU hsubmenu = MENU_FindMenuByCoords( hmenu, msg.pt );
+
+ switch(msg.message)
+ {
+ case WM_RBUTTONDOWN:
+ case WM_NCRBUTTONDOWN:
+ if (!(wFlags & TPM_RIGHTBUTTON)) break;
+ /* fall through */
+ case WM_LBUTTONDOWN:
+ case WM_NCLBUTTONDOWN:
+ fClosed = !MENU_ButtonDown( hwnd, hsubmenu,
+ &hmenuCurrent, msg.pt );
+ break;
+
+ case WM_RBUTTONUP:
+ case WM_NCRBUTTONUP:
+ if (!(wFlags & TPM_RIGHTBUTTON)) break;
+ /* fall through */
+ case WM_LBUTTONUP:
+ case WM_NCLBUTTONUP:
+ /* If outside all menus but inside lprect, ignore it */
+ if (!hsubmenu && lprect && PtInRect( lprect, msg.pt )) break;
+ fClosed = !MENU_ButtonUp( hwnd, hsubmenu,
+ &hmenuCurrent, msg.pt );
+ break;
+
+ case WM_MOUSEMOVE:
+ case WM_NCMOUSEMOVE:
+ if ((msg.wParam & MK_LBUTTON) ||
+ ((wFlags & TPM_RIGHTBUTTON) && (msg.wParam & MK_RBUTTON)))
+ {
+ fClosed = !MENU_MouseMove( hwnd, hsubmenu,
+ &hmenuCurrent, msg.pt );
+ }
+ break;
+ }
+ }
+ else if ((msg.message >= WM_KEYFIRST) && (msg.message <= WM_KEYLAST))
+ {
+ switch(msg.message)
+ {
+ case WM_KEYDOWN:
+ switch(msg.wParam)
+ {
+ case VK_HOME:
+ MENU_SelectItem( hmenuCurrent, NO_SELECTED_ITEM );
+ MENU_SelectNextItem( hmenuCurrent );
+ break;
+
+ case VK_END:
+ MENU_SelectItem( hmenuCurrent, NO_SELECTED_ITEM );
+ MENU_SelectPrevItem( hmenuCurrent );
+ break;
+
+ case VK_UP:
+ MENU_SelectPrevItem( hmenuCurrent );
+ break;
+
+ case VK_DOWN:
+ /* If on menu bar, pull-down the menu */
+ if (!(menu->wFlags & MF_POPUP) && (hmenuCurrent == hmenu))
+ hmenuCurrent = MENU_ShowSubPopup( hwnd, hmenu, TRUE );
+ else
+ MENU_SelectNextItem( hmenuCurrent );
+ break;
+
+ case VK_LEFT:
+ MENU_KeyLeft( hwnd, hmenu, &hmenuCurrent );
+ break;
+
+ case VK_RIGHT:
+ MENU_KeyRight( hwnd, hmenu, &hmenuCurrent );
+ break;
+
+ case VK_SPACE:
+ case VK_RETURN:
+ fClosed = !MENU_ExecFocusedItem( hwnd, hmenuCurrent,
+ &hmenuCurrent );
+ break;
+
+ case VK_ESCAPE:
+ fClosed = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ break; /* WM_KEYDOWN */
+
+ case WM_SYSKEYDOWN:
+ switch(msg.wParam)
+ {
+ case VK_MENU:
+ fClosed = TRUE;
+ break;
+
+ }
+ break; /* WM_SYSKEYDOWN */
+
+ case WM_CHAR:
+ {
+ /* Hack to avoid control chars. */
+ /* We will find a better way real soon... */
+ if ((msg.wParam <= 32) || (msg.wParam >= 127)) break;
+ pos = MENU_FindItemByKey( hwnd, hmenuCurrent, msg.wParam );
+ if (pos == (WORD)-2) fClosed = TRUE;
+ else if (pos == (WORD)-1) MessageBeep(0);
+ else
+ {
+ MENU_SelectItem( hmenuCurrent, pos );
+ fClosed = !MENU_ExecFocusedItem( hwnd, hmenuCurrent,
+ &hmenuCurrent );
+
+ }
+ }
+ break; /* WM_CHAR */
+ } /* switch(msg.message) */
+ }
+ else
+ {
+ DispatchMessage( &msg );
+ }
+ if (fEndMenuCalled) fClosed = TRUE;
+
+ if (!fClosed) /* Remove the message from the queue */
+ PeekMessage( &msg, 0, 0, 0, PM_REMOVE );
+ }
+ ReleaseCapture();
+ MENU_HideSubPopups( hmenu );
+ if (menu->wFlags & MF_POPUP) ShowWindow( menu->hWnd, SW_HIDE );
+ MENU_SelectItem( hmenu, NO_SELECTED_ITEM );
+ fEndMenuCalled = FALSE;
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * MENU_TrackMouseMenuBar
+ *
+ * Menu-bar tracking upon a mouse event. Called from NC_HandleSysCommand().
+ */
+void MENU_TrackMouseMenuBar( HWND hwnd, POINT pt )
+{
+ WND *wndPtr = WIN_FindWndPtr( hwnd );
+ MENU_TrackMenu( (HMENU)wndPtr->wIDmenu, TPM_LEFTALIGN | TPM_LEFTBUTTON,
+ pt.x, pt.y, hwnd, NULL );
+}
+
+
+/***********************************************************************
+ * MENU_TrackKbdMenuBar
+ *
+ * Menu-bar tracking upon a keyboard event. Called from NC_HandleSysCommand().
+ */
+void MENU_TrackKbdMenuBar( HWND hwnd, WORD wParam )
+{
+ WND *wndPtr = WIN_FindWndPtr( hwnd );
+ /* Select first selectable item */
+ MENU_SelectItem( wndPtr->wIDmenu, NO_SELECTED_ITEM );
+ MENU_SelectNextItem( (HMENU)wndPtr->wIDmenu );
+ MENU_TrackMenu( (HMENU)wndPtr->wIDmenu, TPM_LEFTALIGN | TPM_LEFTBUTTON,
+ 0, 0, hwnd, NULL );
+}
+
+
+/**********************************************************************
+ * TrackPopupMenu [USER.416]
+ */
+BOOL TrackPopupMenu( HMENU hMenu, WORD wFlags, short x, short y,
+ short nReserved, HWND hWnd, LPRECT lpRect )
+{
+ if (!MENU_ShowPopup( hWnd, hMenu, 0, x, y )) return FALSE;
+ return MENU_TrackMenu( hMenu, wFlags, 0, 0, hWnd, lpRect );
+}
+
+
+/***********************************************************************
+ * PopupMenuWndProc
+ */
+LONG PopupMenuWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam )
+{
+ switch(message)
+ {
+ case WM_CREATE:
+ {
#ifdef DEBUG_MENU
- printf("StdDrawMenuBar(%04X, %08X, %08X); !\n", hDC, lprect, lppop);
+ printf("PopupMenu WM_CREATE lParam=%08X !\n", lParam);
#endif
- if (lppop->Height == 0) MENU_MenuBarCalcSize(hDC, lprect, lppop);
- if (suppress_draw) return;
-
- 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 );
+ CREATESTRUCT *createStruct = (CREATESTRUCT *)lParam;
+ HMENU hmenu = (HMENU) ((int)createStruct->lpCreateParams & 0xffff);
+ SetWindowWord( hwnd, 0, hmenu );
+ return 0;
}
-}
+ case WM_MOUSEACTIVATE: /* We don't want to be activated */
+ return MA_NOACTIVATE;
+ case WM_PAINT:
+ {
+ PAINTSTRUCT ps;
+ BeginPaint( hwnd, &ps );
+ MENU_DrawPopupMenu( hwnd, ps.hdc,
+ (HMENU)GetWindowWord( hwnd, 0 ) );
+ EndPaint( hwnd, &ps );
+ return 0;
+ }
-LPMENUITEM MenuFindItem(LPPOPUPMENU lppop, int x, int y, WORD *lpRet)
-{
- LPMENUITEM lpitem;
- UINT i;
- if (lpRet != NULL) *lpRet = 0;
- if (lppop == NULL) return NULL;
- if (lppop->nItems == 0) return NULL;
- lpitem = lppop->firstItem;
- for(i = 0; i < lppop->nItems; i++) {
- if (lpitem == NULL) return NULL;
-#ifdef DEBUG_MENUFINDITEM
- printf("FindItem // left=%d top=%d right=%d bottom=%d\n",
- lpitem->rect.left, lpitem->rect.top,
- lpitem->rect.right, lpitem->rect.bottom);
-#endif
- if (x > lpitem->rect.left && x < lpitem->rect.right &&
- y > lpitem->rect.top && y < lpitem->rect.bottom) {
- if (lpRet != NULL) *lpRet = i;
- return lpitem;
- }
- lpitem = (LPMENUITEM)lpitem->next;
- }
- return NULL;
+ default:
+ return DefWindowProc(hwnd, message, wParam, lParam);
+ }
+ return 0;
}
-LPMENUITEM MenuFindItemBySelKey(LPPOPUPMENU lppop, WORD key, WORD *lpRet)
-{
- LPMENUITEM lpitem;
- UINT i;
- if (lppop == NULL) return NULL;
-
- if (lppop->nItems == 0) return NULL;
- lpitem = lppop->firstItem;
- for(i = 0; i < lppop->nItems; i++) {
- if (lpitem == NULL) return NULL;
-#ifdef DEBUG_MENUFINDITEM
- printf("FindItemBySelKey // key=%04X lpitem->sel_key=%04X\n",
- key, lpitem->sel_key);
-#endif
- if (key == lpitem->sel_key) {
- if (lpRet != NULL) *lpRet = i;
- return lpitem;
- }
- lpitem = (LPMENUITEM)lpitem->next;
- }
- return NULL;
-}
-
-
-
-
-
-
/***********************************************************************
* MENU_GetMenuBarHeight
*
@@ -1090,60 +1384,18 @@
WND *wndPtr;
LPPOPUPMENU lppop;
- if (!(lppop = PopupMenuGetWindowAndStorage( hwnd, &wndPtr ))) return 0;
- if (!wndPtr) return 0;
+ if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
+ if (!(lppop = (LPPOPUPMENU)USER_HEAP_ADDR( wndPtr->wIDmenu ))) return 0;
hdc = GetDC( hwnd );
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;
}
-/***********************************************************************
- * FindMenuItem
- */
-LPMENUITEM FindMenuItem(HMENU hMenu, WORD nPos, WORD wFlags)
-{
- LPPOPUPMENU menu;
- LPMENUITEM lpitem;
- int i;
- menu = (LPPOPUPMENU) GlobalLock(hMenu);
- if (menu == NULL) {
- GlobalUnlock(hMenu);
- return FALSE;
- }
- lpitem = menu->firstItem;
- if (wFlags & MF_BYPOSITION) {
- for (i = 0; i < nPos; i++, lpitem = lpitem->next)
- if (lpitem == NULL) return NULL;
- }
- else {
- for (i = 0; i < menu->nItems && lpitem != NULL; i++) {
- if (lpitem->item_id == nPos) return lpitem;
- lpitem = lpitem->next;
- }
- return NULL;
- }
- return lpitem;
-}
-LPMENUITEM GetMenuItemPtr(LPPOPUPMENU menu, WORD nPos)
-{
- LPMENUITEM lpitem;
- int i;
- if (menu == NULL) return NULL;
- lpitem = menu->firstItem;
- for (i = 0; i < menu->nItems; i++) {
- if (lpitem == NULL) return NULL;
- if (i == nPos) return(lpitem);
- lpitem = (LPMENUITEM)lpitem->next;
- }
- return NULL;
-}
-
WORD GetSelectionKey(LPSTR str)
{
@@ -1206,35 +1458,6 @@
}
-
-BOOL HideAllSubPopupMenu(LPPOPUPMENU menu)
-{
- LPPOPUPMENU submenu;
- LPMENUITEM lpitem;
- BOOL someClosed = FALSE;
- int i;
- if (menu == NULL) return;
- lpitem = menu->firstItem;
- for (i = 0; i < menu->nItems; i++) {
- if (lpitem == NULL) return;
- if (lpitem->item_flags & MF_POPUP) {
- submenu = (LPPOPUPMENU) GlobalLock((HMENU)lpitem->item_id);
- if (submenu != NULL) {
- if (IsWindowVisible(submenu->hWnd)) {
- ShowWindow(submenu->hWnd, SW_HIDE);
- someClosed = TRUE;
- }
- GlobalUnlock((HMENU)lpitem->item_id);
- }
- }
- lpitem = (LPMENUITEM)lpitem->next;
- }
- return someClosed;
-}
-
-
-
-
/**********************************************************************
* ChangeMenu [USER.153]
*/
@@ -1264,18 +1487,10 @@
#ifdef DEBUG_MENU
printf("CheckMenuItem (%04X, %04X, %04X) !\n", hMenu, wItemID, wFlags);
#endif
- lpitem = FindMenuItem(hMenu, wItemID, wFlags);
- if (lpitem != NULL) {
- if ((wFlags & MF_CHECKED) == MF_CHECKED)
- lpitem->item_flags |= MF_CHECKED;
- else
- lpitem->item_flags &= ((WORD)-1 ^ MF_CHECKED);
-#ifdef DEBUG_MENU
- printf("CheckMenuItem // Found !\n");
-#endif
- return(TRUE);
- }
- return FALSE;
+ if (!(lpitem = MENU_FindItem(&hMenu, &wItemID, wFlags))) return FALSE;
+ if (wFlags & MF_CHECKED) lpitem->item_flags |= MF_CHECKED;
+ else lpitem->item_flags &= ~MF_CHECKED;
+ return TRUE;
}
@@ -1288,7 +1503,7 @@
#ifdef DEBUG_MENU
printf("EnableMenuItem (%04X, %04X, %04X) !\n", hMenu, wItemID, wFlags);
#endif
- if (!(lpitem = FindMenuItem(hMenu, wItemID, wFlags))) return FALSE;
+ if (!(lpitem = MENU_FindItem( &hMenu, &wItemID, wFlags ))) return FALSE;
/* We can't have MF_GRAYED and MF_DISABLED together */
if (wFlags & MF_GRAYED)
@@ -1311,7 +1526,7 @@
* GetMenuString [USER.161]
*/
int GetMenuString(HMENU hMenu, WORD wItemID,
- LPSTR str, short nMaxSiz, WORD wFlags)
+ LPSTR str, short nMaxSiz, WORD wFlags)
{
LPMENUITEM lpitem;
int maxsiz;
@@ -1320,7 +1535,7 @@
hMenu, wItemID, str, nMaxSiz, wFlags);
#endif
if (str == NULL) return FALSE;
- lpitem = FindMenuItem(hMenu, wItemID, wFlags);
+ lpitem = MENU_FindItem( &hMenu, &wItemID, wFlags );
if (lpitem != NULL) {
if (lpitem->item_text != NULL) {
maxsiz = min(nMaxSiz - 1, strlen(lpitem->item_text));
@@ -1342,17 +1557,18 @@
*/
BOOL HiliteMenuItem(HWND hWnd, HMENU hMenu, WORD wItemID, WORD wHilite)
{
- LPPOPUPMENU menu;
- LPMENUITEM lpitem;
+ LPPOPUPMENU menu;
+ LPMENUITEM lpitem;
#ifdef DEBUG_MENU
printf("HiliteMenuItem(%04X, %04X, %04X, %04X);\n",
hWnd, hMenu, wItemID, wHilite);
#endif
- menu = (LPPOPUPMENU) GlobalLock(hMenu);
- if (menu == NULL) return FALSE;
- lpitem = FindMenuItem(hMenu, wItemID, wHilite);
- if (lpitem == NULL) return FALSE;
- return FALSE;
+ if (!(lpitem = MENU_FindItem( &hMenu, &wItemID, wHilite ))) return FALSE;
+ if (!(menu = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu))) return FALSE;
+ if (menu->FocusedItem == wItemID) return TRUE;
+ MENU_HideSubPopups( hMenu );
+ MENU_SelectItem( hMenu, wItemID );
+ return TRUE;
}
@@ -1361,16 +1577,18 @@
*/
WORD GetMenuState(HMENU hMenu, WORD wItemID, WORD wFlags)
{
- LPPOPUPMENU menu;
- LPMENUITEM lpitem;
+ LPMENUITEM lpitem;
#ifdef DEBUG_MENU
- printf("GetMenuState(%04X, %04X, %04X);\n", hMenu, wItemID, wFlags);
+ printf("GetMenuState(%04X, %04X, %04X);\n", hMenu, wItemID, wFlags);
#endif
- menu = (LPPOPUPMENU) GlobalLock(hMenu);
- if (menu == NULL) return -1;
- lpitem = FindMenuItem(hMenu, wItemID, wFlags);
- if (lpitem == NULL) return -1;
- return lpitem->item_flags;
+ if (!(lpitem = MENU_FindItem( &hMenu, &wItemID, wFlags ))) return -1;
+ if (lpitem->item_flags & MF_POPUP)
+ {
+ POPUPMENU *menu = (POPUPMENU *) USER_HEAP_ADDR( lpitem->item_id );
+ if (!menu) return -1;
+ else return (menu->nItems << 8) | (menu->wFlags & 0xff);
+ }
+ else return lpitem->item_flags;
}
@@ -1383,7 +1601,7 @@
#ifdef DEBUG_MENU
printf("GetMenuItemCount(%04X);\n", hMenu);
#endif
- menu = (LPPOPUPMENU) GlobalLock(hMenu);
+ menu = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu);
if (menu == NULL) return (WORD)-1;
#ifdef DEBUG_MENU
printf("GetMenuItemCount(%04X) return %d \n", hMenu, menu->nItems);
@@ -1397,24 +1615,17 @@
*/
WORD GetMenuItemID(HMENU hMenu, int nPos)
{
- WORD i;
- LPPOPUPMENU menu;
- LPMENUITEM lpitem;
- printf("GetMenuItemID(%04X, %d);\n", hMenu, nPos);
- menu = (LPPOPUPMENU) GlobalLock(hMenu);
- if (menu == NULL) return -1;
- lpitem = menu->firstItem;
- for (i = 0; i < menu->nItems; i++) {
- if (lpitem == NULL) break;
- if (i == nPos) {
+ LPPOPUPMENU menu;
+ MENUITEM *item;
+
#ifdef DEBUG_MENU
- printf("GetMenuItemID // Found !\n");
+ printf("GetMenuItemID(%04X, %d);\n", hMenu, nPos);
#endif
- return lpitem->item_id;
- }
- lpitem = (LPMENUITEM)lpitem->next;
- }
- return -1;
+ if (!(menu = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu))) return -1;
+ if ((nPos < 0) || (nPos >= menu->nItems)) return -1;
+ item = (MENUITEM *) USER_HEAP_ADDR( menu->hItems );
+ if (item[nPos].item_flags & MF_POPUP) return -1;
+ return item[nPos].item_id;
}
@@ -1423,64 +1634,70 @@
*/
BOOL InsertMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewItem)
{
- LPPOPUPMENU menu;
- HANDLE hNewItem;
- LPMENUITEM lpitem, lpitem2;
+ HANDLE hNewItems;
+ MENUITEM *lpitem, *newItems;
+ LPPOPUPMENU menu;
+
#ifdef DEBUG_MENU
- if ((wFlags & (MF_BITMAP | MF_SEPARATOR | MF_MENUBREAK | MF_OWNERDRAW)) == 0)
+ if (IS_STRING_ITEM(wFlags))
printf("InsertMenu (%04X, %04X, %04X, '%s') !\n",
hMenu, wFlags, wItemID, lpNewItem);
- else
+ else
printf("InsertMenu (%04X, %04X, %04X, %04X, %08X) !\n",
- hMenu, nPos, wFlags, wItemID, lpNewItem);
+ hMenu, nPos, wFlags, wItemID, lpNewItem);
#endif
- menu = (LPPOPUPMENU) GlobalLock(hMenu);
- if (menu == NULL) return FALSE;
- lpitem = FindMenuItem(hMenu, nPos, wFlags);
- if (lpitem == NULL) lpitem = menu->firstItem;
- hNewItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM));
- if (hNewItem == 0) {
- GlobalUnlock(hMenu);
- return FALSE;
- }
- lpitem2 = (LPMENUITEM)GlobalLock(hNewItem);
- if (lpitem2 == NULL) {
- GlobalFree(hNewItem);
- GlobalUnlock(hMenu);
- return FALSE;
- }
- lpitem2->hItem = hNewItem;
- lpitem2->item_flags = wFlags;
- lpitem2->item_id = wItemID;
- if (!(wFlags & (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK |
- MF_MENUBREAK | MF_SEPARATOR))) {
- lpitem2->hText = GlobalAlloc(GMEM_MOVEABLE, strlen(lpNewItem) + 1);
- lpitem2->item_text = GlobalLock(lpitem2->hText);
- if (lpitem2->item_text != NULL)
- strcpy(lpitem2->item_text, lpNewItem);
- else {
- printf("InsertMenu // Bad Alloc !\n");
- return FALSE;
- }
- lpitem2->sel_key = GetSelectionKey(lpitem2->item_text);
- }
- else {
- lpitem2->item_text = lpNewItem;
- }
- if (lpitem == NULL) {
- menu->firstItem = lpitem2;
- lpitem2->prev = NULL;
- lpitem2->next = NULL;
- }
- else {
- lpitem2->prev = lpitem;
- lpitem2->next = lpitem->next;
- if (lpitem2->next != NULL) lpitem2->next->prev = lpitem2;
- lpitem->next = lpitem2;
- }
- menu->nItems++;
- GlobalUnlock(hMenu);
- return TRUE;
+
+ /* Find where to insert new item */
+
+ if ((wFlags & MF_BYPOSITION) && (nPos == (WORD)-1))
+ {
+ /* Special case: append to menu */
+ if (!(menu = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu))) return FALSE;
+ nPos = menu->nItems;
+ }
+ else
+ {
+ if (!MENU_FindItem( &hMenu, &nPos, wFlags )) return FALSE;
+ if (!(menu = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu))) return FALSE;
+ }
+
+ /* Create new items array */
+
+ hNewItems = USER_HEAP_ALLOC( GMEM_MOVEABLE,
+ sizeof(MENUITEM) * (menu->nItems+1) );
+ if (!hNewItems) return FALSE;
+ newItems = (MENUITEM *) USER_HEAP_ADDR( hNewItems );
+ if (menu->nItems > 0)
+ {
+ /* Copy the old array into the new */
+ MENUITEM *oldItems = (MENUITEM *) USER_HEAP_ADDR( menu->hItems );
+ if (nPos > 0) memcpy( newItems, oldItems, nPos * sizeof(MENUITEM) );
+ if (nPos < menu->nItems) memcpy( &newItems[nPos+1], &oldItems[nPos],
+ (menu->nItems-nPos)*sizeof(MENUITEM) );
+
+ USER_HEAP_FREE( menu->hItems );
+ }
+ menu->hItems = hNewItems;
+ menu->nItems++;
+
+ /* Store the new item data */
+
+ lpitem = &newItems[nPos];
+ lpitem->item_flags = wFlags & ~(MF_HILITE | MF_MOUSESELECT);
+ lpitem->item_id = wItemID;
+
+ if (IS_STRING_ITEM(wFlags))
+ {
+ lpitem->hText = USER_HEAP_ALLOC( GMEM_MOVEABLE, strlen(lpNewItem)+1 );
+ lpitem->item_text = (char *)USER_HEAP_ADDR( lpitem->hText );
+ strcpy( lpitem->item_text, lpNewItem );
+ lpitem->sel_key = GetSelectionKey( lpitem->item_text );
+ }
+ else lpitem->item_text = lpNewItem;
+ SetRectEmpty( &lpitem->rect );
+ lpitem->hCheckBit = hStdCheck;
+ lpitem->hUnCheckBit = 0;
+ return TRUE;
}
@@ -1489,65 +1706,7 @@
*/
BOOL AppendMenu(HMENU hMenu, WORD wFlags, WORD wItemID, LPSTR lpNewItem)
{
- LPPOPUPMENU menu;
- HANDLE hNewItem;
- LPMENUITEM lpitem, lpitem2;
-#ifdef DEBUG_MENU
- if ((wFlags & (MF_BITMAP | MF_SEPARATOR | MF_MENUBREAK | MF_OWNERDRAW)) == 0)
- printf("AppendMenu (%04X, %04X, %04X, '%s') !\n",
- hMenu, wFlags, wItemID, lpNewItem);
- else
- printf("AppendMenu (%04X, %04X, %04X, %08X) !\n",
- hMenu, wFlags, wItemID, lpNewItem);
-#endif
- menu = (LPPOPUPMENU) GlobalLock(hMenu);
- if (menu == NULL) return FALSE;
- lpitem = menu->firstItem;
- if (lpitem != NULL) {
- while (lpitem->next != NULL) {
- lpitem = (LPMENUITEM)lpitem->next;
- }
- }
- hNewItem = GlobalAlloc(GMEM_MOVEABLE, sizeof(MENUITEM));
- if (hNewItem == 0) {
- GlobalUnlock(hMenu);
- return FALSE;
- }
- lpitem2 = (LPMENUITEM)GlobalLock(hNewItem);
- lpitem2->hItem = hNewItem;
- if (lpitem2 == NULL) {
- GlobalFree(hNewItem);
- GlobalUnlock(hMenu);
- return FALSE;
- }
- lpitem2->item_flags = wFlags;
- lpitem2->item_id = wItemID;
- if (!(wFlags & (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK |
- MF_MENUBREAK | MF_SEPARATOR))) {
- lpitem2->hText = GlobalAlloc(GMEM_MOVEABLE, strlen(lpNewItem) + 1);
- lpitem2->item_text = GlobalLock(lpitem2->hText);
- if (lpitem2->item_text != NULL)
- strcpy(lpitem2->item_text, lpNewItem);
- else {
- printf("AppendMenu // Bad Alloc !\n");
- return FALSE;
- }
- lpitem2->sel_key = GetSelectionKey(lpitem2->item_text);
- }
- else {
- lpitem2->item_text = lpNewItem;
- }
- if (lpitem == NULL)
- menu->firstItem = lpitem2;
- else
- lpitem->next = lpitem2;
- lpitem2->prev = lpitem;
- lpitem2->next = NULL;
- lpitem2->hCheckBit = (HBITMAP)NULL;
- lpitem2->hUnCheckBit = (HBITMAP)NULL;
- menu->nItems++;
- GlobalUnlock(hMenu);
- return TRUE;
+ return InsertMenu( hMenu, -1, wFlags | MF_BYPOSITION, wItemID, lpNewItem );
}
@@ -1556,36 +1715,35 @@
*/
BOOL RemoveMenu(HMENU hMenu, WORD nPos, WORD wFlags)
{
- LPPOPUPMENU menu;
- LPMENUITEM lpitem;
- int i;
+ LPPOPUPMENU menu;
+ LPMENUITEM lpitem;
#ifdef DEBUG_MENU
printf("RemoveMenu (%04X, %04X, %04X) !\n", hMenu, nPos, wFlags);
#endif
- menu = (LPPOPUPMENU) GlobalLock(hMenu);
- if (menu == NULL) return FALSE;
- lpitem = menu->firstItem;
- for (i = 0; i < menu->nItems; i++) {
- if (lpitem == NULL) break;
- if (i == nPos) {
- lpitem->prev->next = lpitem->next;
- lpitem->next->prev = lpitem->prev;
- if (!(lpitem->item_flags &
- (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK |
- MF_MENUBREAK | MF_SEPARATOR))) {
- GlobalUnlock(lpitem->hText);
- GlobalFree(lpitem->hText);
- }
- GlobalFree(lpitem->hItem);
- GlobalUnlock(hMenu);
- return TRUE;
- }
- lpitem = (LPMENUITEM)lpitem->next;
- printf("RemoveMenu // during loop items !\n");
- }
- printf("RemoveMenu // after loop items !\n");
- GlobalUnlock(hMenu);
- return FALSE;
+ if (!(lpitem = MENU_FindItem( &hMenu, &nPos, wFlags ))) return FALSE;
+ if (!(menu = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu))) return FALSE;
+
+ /* Remove item */
+
+ if (IS_STRING_ITEM(lpitem->item_flags)) USER_HEAP_FREE( lpitem->hText );
+ if (--menu->nItems == 0)
+ {
+ USER_HEAP_FREE( menu->hItems );
+ menu->hItems = 0;
+ }
+ else
+ {
+ while(nPos < menu->nItems)
+ {
+ *lpitem = *(lpitem+1);
+ lpitem++;
+ nPos++;
+ }
+ menu->hItems = USER_HEAP_REALLOC( menu->hItems,
+ menu->nItems * sizeof(MENUITEM),
+ GMEM_MOVEABLE );
+ }
+ return TRUE;
}
@@ -1594,35 +1752,12 @@
*/
BOOL DeleteMenu(HMENU hMenu, WORD nPos, WORD wFlags)
{
- LPPOPUPMENU menu;
- LPMENUITEM lpitem;
- int i;
-#ifdef DEBUG_MENU
- printf("DeleteMenu (%04X, %04X, %04X) !\n", hMenu, nPos, wFlags);
-#endif
- menu = (LPPOPUPMENU) GlobalLock(hMenu);
- if (menu == NULL) {
- GlobalUnlock(hMenu);
- return FALSE;
- }
- lpitem = FindMenuItem(hMenu, nPos, wFlags);
- if (lpitem != NULL) {
- if ((lpitem->item_flags & MF_POPUP) == MF_POPUP)
- DestroyMenu((HMENU)lpitem->item_id);
- if (!(lpitem->item_flags &
- (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK |
- MF_MENUBREAK | MF_SEPARATOR))) {
- GlobalUnlock(lpitem->hText);
- GlobalFree(lpitem->hText);
- }
- if (lpitem->prev) lpitem->prev->next = lpitem->next;
- if (lpitem->next) lpitem->next->prev = lpitem->prev;
- GlobalFree(lpitem->hItem);
- GlobalUnlock(hMenu);
- return TRUE;
- }
- GlobalUnlock(hMenu);
- return FALSE;
+ MENUITEM *item = MENU_FindItem( &hMenu, &nPos, wFlags );
+ if (!item) return FALSE;
+ if (item->item_flags & MF_POPUP) DestroyMenu( item->item_id );
+ /* nPos is now the position of the item */
+ RemoveMenu( hMenu, nPos, wFlags | MF_BYPOSITION );
+ return TRUE;
}
@@ -1631,48 +1766,31 @@
*/
BOOL ModifyMenu(HMENU hMenu, WORD nPos, WORD wFlags, WORD wItemID, LPSTR lpNewItem)
{
- LPPOPUPMENU menu;
- LPMENUITEM lpitem;
- int i;
+ LPMENUITEM lpitem;
#ifdef DEBUG_MENU
- if ((wFlags & (MF_BITMAP | MF_SEPARATOR | MF_MENUBREAK | MF_OWNERDRAW)) == 0)
- printf("ModifyMenu (%04X, %04X, %04X, %04X, '%s') !\n",
- hMenu, nPos, wFlags, wItemID, lpNewItem);
- else
- printf("ModifyMenu (%04X, %04X, %04X, %04X, %08X) !\n",
- hMenu, nPos, wFlags, wItemID, lpNewItem);
+ if (IS_STRING_ITEM(wFlags))
+ printf("ModifyMenu (%04X, %04X, %04X, %04X, '%s') !\n",
+ hMenu, nPos, wFlags, wItemID, lpNewItem);
+ else
+ printf("ModifyMenu (%04X, %04X, %04X, %04X, %08X) !\n",
+ hMenu, nPos, wFlags, wItemID, lpNewItem);
#endif
- menu = (LPPOPUPMENU) GlobalLock(hMenu);
- if (menu == NULL) return FALSE;
- lpitem = menu->firstItem;
- for (i = 0; i < menu->nItems; i++) {
- if (lpitem == NULL) break;
- if (i == nPos) {
- lpitem->item_flags = wFlags;
- lpitem->item_id = wItemID;
- if (!(lpitem->item_flags &
- (MF_BITMAP | MF_OWNERDRAW | MF_MENUBARBREAK |
- MF_MENUBREAK | MF_SEPARATOR))) {
- GlobalUnlock(lpitem->hText);
- GlobalFree(lpitem->hText);
- lpitem->hText = GlobalAlloc(GMEM_MOVEABLE, strlen(lpNewItem) + 1);
- lpitem->item_text = GlobalLock(lpitem->hText);
- printf("ModifyMenu %08X %08X '%s') !\n",
- lpitem->item_text, lpNewItem, lpNewItem);
- if (lpitem->item_text != NULL)
- strcpy(lpitem->item_text, lpNewItem);
- else
- printf("ModifyMenu // Bad Alloc !\n");
- }
- else
- lpitem->item_text = lpNewItem;
- GlobalUnlock(hMenu);
- return(TRUE);
- }
- lpitem = (LPMENUITEM)lpitem->next;
- }
- GlobalUnlock(hMenu);
- return FALSE;
+ if (!(lpitem = MENU_FindItem( &hMenu, &nPos, wFlags ))) return FALSE;
+
+ if (IS_STRING_ITEM(lpitem->item_flags)) USER_HEAP_FREE( lpitem->hText );
+ lpitem->item_flags = wFlags & ~(MF_HILITE | MF_MOUSESELECT);
+ lpitem->item_id = wItemID;
+
+ if (IS_STRING_ITEM(wFlags))
+ {
+ lpitem->hText = USER_HEAP_ALLOC( GMEM_MOVEABLE, strlen(lpNewItem)+1 );
+ lpitem->item_text = (char *)USER_HEAP_ADDR( lpitem->hText );
+ strcpy( lpitem->item_text, lpNewItem );
+ lpitem->sel_key = GetSelectionKey( lpitem->item_text );
+ }
+ else lpitem->item_text = lpNewItem;
+ SetRectEmpty( &lpitem->rect );
+ return TRUE;
}
@@ -1681,238 +1799,13 @@
*/
HMENU CreatePopupMenu()
{
- HANDLE hItem;
- HMENU hMenu;
- LPPOPUPMENU menu;
-#ifdef DEBUG_MENU
- printf("CreatePopupMenu !\n");
-#endif
- hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(POPUPMENU));
- menu = (LPPOPUPMENU) GlobalLock(hMenu);
- if (menu == NULL) {
- GlobalFree(hMenu);
- return 0;
- }
- menu->nItems = 0;
- menu->firstItem = NULL;
- menu->ownerWnd = 0;
- menu->hWndPrev = 0;
- menu->hWnd = 0;
- menu->hWndParent = 0;
- menu->MouseFlags = 0;
- menu->BarFlag = FALSE;
- menu->SysFlag = FALSE;
- menu->ChildFlag = TRUE;
- menu->Width = 100;
- menu->Height = 0;
- GlobalUnlock(hMenu);
-#ifdef DEBUG_MENU
- printf("CreatePopupMenu // return %04X\n", hMenu);
-#endif
- return hMenu;
-}
+ HMENU hmenu;
+ POPUPMENU *menu;
-
-/**********************************************************************
- * TrackPopupMenu [USER.416]
- */
-BOOL TrackPopupMenu(HMENU hMenu, WORD wFlags, short x, short y,
- short nReserved, HWND hWnd, LPRECT lpRect)
-{
- WND *wndPtr;
- LPPOPUPMENU lppop;
- RECT rect;
-#ifdef DEBUG_MENU
- printf("TrackPopupMenu (%04X, %04X, %d, %d, %04X, %04X, %08X) !\n",
- hMenu, wFlags, x, y, nReserved, hWnd, lpRect);
-#endif
- lppop = (LPPOPUPMENU) GlobalLock(hMenu);
- if (lppop == NULL) {
- printf("TrackPopupMenu // Bad menu handle %04X !\n", hMenu);
- return FALSE;
- }
- wndPtr = WIN_FindWndPtr(hWnd);
- if (wndPtr == NULL) {
- printf("TrackPopupMenu // Bad window handle %04X !\n", hWnd);
- return FALSE;
- }
- lppop->ownerWnd = hWnd;
- lppop->hWndPrev = GetFocus();
- if (lppop->hWnd == (HWND)NULL) {
- 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) {
- printf("TrackPopupMenu // Can't create PopupMenu window !\n");
- return FALSE;
- }
- }
- if (!lppop->BarFlag) {
- 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 + 2,
- SWP_NOACTIVATE | SWP_NOZORDER);
- }
- ShowWindow(lppop->hWnd, SW_SHOWNOACTIVATE);
- SetFocus(lppop->hWnd);
- if (!MenuHasFocus) {
-#ifdef DEBUG_MENU
- printf("TrackPopupMenu // before MenuFocusLoop !\n");
-#endif
- MenuFocusLoop(hWnd, NULL);
-#ifdef DEBUG_MENU
- printf("TrackPopupMenu // after MenuFocusLoop !\n");
-#endif
- }
- GlobalUnlock(hMenu);
- return TRUE;
-}
-
-
-BOOL ActivateMenuBarFocus(HWND hWnd)
-{
- WND *wndPtr;
- LPPOPUPMENU lpmenu;
- BOOL bRet;
- MSG msg;
- if (MenuHasFocus) return FALSE;
- wndPtr = WIN_FindWndPtr(hWnd);
- if (wndPtr == NULL) return FALSE;
-#ifdef DEBUG_MENU
- printf("ActivateMenuBarFocus (%04X) !\n", hWnd);
-#endif
- while((wndPtr->dwStyle & WS_CHILD) == WS_CHILD) {
- hWnd = GetParent(hWnd);
- printf("ActivateMenuBarFocus // next Parent=%04X !\n", hWnd);
- wndPtr = WIN_FindWndPtr(hWnd);
- if (wndPtr == NULL) return FALSE;
- }
- if ((wndPtr->dwStyle & WS_CHILD) == 0 && wndPtr->wIDmenu != 0) {
- lpmenu = (LPPOPUPMENU) GlobalLock(wndPtr->wIDmenu);
- if (lpmenu == NULL) return FALSE;
- lpmenu->hWndPrev = GetFocus();
- SetFocus(hWnd);
- MenuItemSelect(hWnd, lpmenu, 0);
- bRet = MenuFocusLoop(hWnd, lpmenu);
- GlobalUnlock(wndPtr->wIDmenu);
- return bRet;
- }
- return FALSE;
-}
-
-
-BOOL MenuFocusLoop(HWND hWnd, LPPOPUPMENU lpmenu)
-{
- MSG msg;
-#ifdef DEBUG_MENU
- printf("Enter in Menu Focus Loop !\n");
-#endif
- MenuHasFocus = TRUE;
- while(TRUE) {
- if (!MenuHasFocus) break;
- if (!GetMessage(&msg, (HWND)NULL, 0, 0)) break;
- TranslateMessage(&msg);
- if (hWnd == msg.hwnd && lpmenu != NULL) {
- if ((msg.message == WM_SYSKEYDOWN && msg.wParam == VK_MENU) ||
- (msg.message == WM_CHAR && msg.wParam == VK_ESCAPE)) {
- HideAllSubPopupMenu(lpmenu);
- break;
- }
- ScreenToClient(hWnd, &msg.pt);
- msg.pt.y += lpmenu->rect.bottom;
- switch(msg.message) {
- case WM_LBUTTONDOWN:
- case WM_NCLBUTTONDOWN:
- SetCapture(hWnd);
- MenuButtonDown(hWnd, lpmenu, msg.pt.x, msg.pt.y);
- break;
- case WM_LBUTTONUP:
- case WM_NCLBUTTONUP:
- MenuButtonUp(hWnd, lpmenu, msg.pt.x, msg.pt.y);
- ReleaseCapture();
- break;
- case WM_MOUSEMOVE:
- case WM_NCMOUSEMOVE:
- MenuMouseMove(hWnd, lpmenu, msg.wParam, msg.pt.x, msg.pt.y);
- break;
- case WM_KEYDOWN:
- case WM_KEYUP:
- case WM_CHAR:
- PopupMenuWndProc(hWnd, msg.message, msg.wParam, msg.lParam);
- default:
- DispatchMessage(&msg);
- }
- }
- else
- DispatchMessage(&msg);
- }
-EndOfFocus:
- MenuHasFocus = FALSE;
- if (lpmenu != NULL) MenuItemSelect(hWnd, lpmenu, -1);
-#ifdef DEBUG_MENU
- printf("End of Menu Focus Loop !\n");
-#endif
- return TRUE;
-}
-
-
-/**********************************************************************
- * NC_TrackSysMenu [Internal]
- */
-void NC_TrackSysMenu(HWND hWnd)
-{
- RECT rect;
- LPPOPUPMENU lpsys;
- WND *wndPtr = WIN_FindWndPtr(hWnd);
-#ifdef DEBUG_MENU
- printf("NC_TrackSysMenu hWnd=%04X !\n", hWnd);
-#endif
- if (!wndPtr) return;
- lpsys = (LPPOPUPMENU)GlobalLock(wndPtr->hSysMenu);
-#ifdef DEBUG_MENU
- printf("NC_TrackSysMenu wndPtr->hSysMenu=%04X !\n", wndPtr->hSysMenu);
-#endif
- if (lpsys == NULL) return;
-#ifdef DEBUG_MENU
- printf("NC_TrackSysMenu wndPtr->hSysMenu=%04X !\n", wndPtr->hSysMenu);
-#endif
- lpsys->BarFlag = FALSE;
- lpsys->SysFlag = TRUE;
- lpsys->ChildFlag = FALSE;
- lpsys->hWndParent = hWnd;
- if (!IsWindowVisible(lpsys->hWnd)) {
- GetWindowRect(hWnd, &rect);
-#ifdef DEBUG_MENU
- printf("NC_TrackSysMenu lpsys->hWnd=%04X !\n", lpsys->hWnd);
-#endif
- if (MenuHasFocus) {
- TrackPopupMenu(wndPtr->hSysMenu, TPM_LEFTBUTTON,
- rect.left, rect.top + SYSMETRICS_CYSIZE,
- 0, hWnd, (LPRECT)NULL);
- }
- else {
- MenuHasFocus = TRUE;
- TrackPopupMenu(wndPtr->hSysMenu, TPM_LEFTBUTTON,
- rect.left, rect.top + SYSMETRICS_CYSIZE,
- 0, hWnd, (LPRECT)NULL);
- MenuHasFocus = FALSE;
-#ifdef DEBUG_MENU
- printf("NC_TrackSysMenu // before MenuFocusLoop !\n");
-#endif
- MenuFocusLoop(hWnd, NULL);
-#ifdef DEBUG_MENU
- printf("NC_TrackSysMenu // after MenuFocusLoop !\n");
-#endif
- }
- }
- else {
- ShowWindow(lpsys->hWnd, SW_HIDE);
- }
- GlobalUnlock(wndPtr->hSysMenu);
+ if (!(hmenu = CreateMenu())) return 0;
+ menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+ menu->wFlags |= MF_POPUP;
+ return hmenu;
}
@@ -1921,7 +1814,6 @@
*/
DWORD GetMenuCheckMarkDimensions()
{
- InitStdBitmaps();
return MAKELONG( check_bitmap_width, check_bitmap_height );
}
@@ -1932,28 +1824,27 @@
BOOL SetMenuItemBitmaps(HMENU hMenu, WORD nPos, WORD wFlags,
HBITMAP hNewCheck, HBITMAP hNewUnCheck)
{
- LPPOPUPMENU menu;
- LPMENUITEM lpitem;
- int i;
+ LPMENUITEM lpitem;
#ifdef DEBUG_MENU
- printf("SetMenuItemBitmaps (%04X, %04X, %04X, %04X, %08X) !\n",
- hMenu, nPos, wFlags, hNewCheck, hNewUnCheck);
+ printf("SetMenuItemBitmaps (%04X, %04X, %04X, %04X, %08X) !\n",
+ hMenu, nPos, wFlags, hNewCheck, hNewUnCheck);
#endif
- menu = (LPPOPUPMENU) GlobalLock(hMenu);
- if (menu == NULL) return FALSE;
- lpitem = menu->firstItem;
- for (i = 0; i < menu->nItems; i++) {
- if (lpitem == NULL) break;
- if (i == nPos) {
- lpitem->hCheckBit = hNewCheck;
- lpitem->hUnCheckBit = hNewUnCheck;
- GlobalUnlock(hMenu);
- return TRUE;
- }
- lpitem = (LPMENUITEM)lpitem->next;
- }
- GlobalUnlock(hMenu);
- return FALSE;
+ if (!(lpitem = MENU_FindItem( &hMenu, &nPos, wFlags ))) return FALSE;
+
+ if (!hNewCheck && !hNewUnCheck)
+ {
+ /* If both are NULL, restore default bitmaps */
+ lpitem->hCheckBit = hStdCheck;
+ lpitem->hUnCheckBit = 0;
+ lpitem->item_flags &= ~MF_USECHECKBITMAPS;
+ }
+ else /* Install new bitmaps */
+ {
+ lpitem->hCheckBit = hNewCheck;
+ lpitem->hUnCheckBit = hNewUnCheck;
+ lpitem->item_flags |= MF_USECHECKBITMAPS;
+ }
+ return TRUE;
}
@@ -1962,35 +1853,28 @@
*/
HMENU CreateMenu()
{
- HANDLE hItem;
- HMENU hMenu;
- LPPOPUPMENU menu;
+ HMENU hMenu;
+ LPPOPUPMENU menu;
#ifdef DEBUG_MENU
printf("CreateMenu !\n");
#endif
- hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(POPUPMENU));
- menu = (LPPOPUPMENU) GlobalLock(hMenu);
- if (menu == NULL) {
- GlobalFree(hMenu);
- return 0;
- }
- menu->nItems = 0;
- menu->firstItem = NULL;
- menu->hWndPrev = 0;
- menu->ownerWnd = 0;
- menu->hWnd = 0;
- menu->hWndParent = 0;
- menu->MouseFlags = 0;
- menu->BarFlag = TRUE;
- menu->SysFlag = FALSE;
- menu->ChildFlag = TRUE;
- menu->Width = 100;
- menu->Height = 0;
- GlobalUnlock(hMenu);
+ if (!(hMenu = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(POPUPMENU) )))
+ return 0;
+ menu = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu);
+ menu->hNext = 0;
+ menu->wFlags = 0;
+ menu->wMagic = MENU_MAGIC;
+ menu->hTaskQ = 0;
+ menu->Width = 0;
+ menu->Height = 0;
+ menu->nItems = 0;
+ menu->hWnd = 0;
+ menu->hItems = 0;
+ menu->FocusedItem = NO_SELECTED_ITEM;
#ifdef DEBUG_MENU
- printf("CreateMenu // return %04X\n", hMenu);
+ printf("CreateMenu // return %04X\n", hMenu);
#endif
- return hMenu;
+ return hMenu;
}
@@ -2000,26 +1884,26 @@
BOOL DestroyMenu(HMENU hMenu)
{
LPPOPUPMENU lppop;
- LPMENUITEM lpitem, lpitem2;
#ifdef DEBUG_MENU
printf("DestroyMenu (%04X) !\n", hMenu);
#endif
if (hMenu == 0) return FALSE;
- lppop = (LPPOPUPMENU) GlobalLock(hMenu);
+ lppop = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu);
if (lppop == NULL) return FALSE;
if (lppop->hWnd) DestroyWindow (lppop->hWnd);
- lpitem = lppop->firstItem;
- while (lpitem != NULL) {
-#ifdef DEBUG_MENU
- printf("DestroyMenu (%04X) // during loop items !\n", hMenu);
-#endif
- if ((lpitem->item_flags & MF_POPUP) == MF_POPUP) {
- DestroyMenu((HMENU)lpitem->item_id);
- }
- lpitem = (LPMENUITEM)lpitem->next;
- }
- GlobalUnlock(hMenu);
- GlobalFree(hMenu);
+
+ if (lppop->hItems)
+ {
+ int i;
+ MENUITEM *item = (MENUITEM *) USER_HEAP_ADDR( lppop->hItems );
+ for (i = lppop->nItems; i > 0; i--, item++)
+ {
+ if (item->item_flags & MF_POPUP)
+ DestroyMenu( item->item_flags & MF_POPUP );
+ }
+ USER_HEAP_FREE( lppop->hItems );
+ }
+ USER_HEAP_FREE( hMenu );
#ifdef DEBUG_MENU
printf("DestroyMenu (%04X) // End !\n", hMenu);
#endif
@@ -2048,6 +1932,7 @@
return 0;
}
hMenu = LoadMenuIndirect((LPSTR)menu_desc);
+ GlobalUnlock( hMenu_desc );
return hMenu;
}
@@ -2091,14 +1976,13 @@
return wndPtr->wIDmenu;
}
+
/**********************************************************************
* SetMenu [USER.158]
*/
BOOL SetMenu(HWND hWnd, HMENU hMenu)
{
- RECT rect;
LPPOPUPMENU lpmenu;
- WORD flags;
WND * wndPtr = WIN_FindWndPtr(hWnd);
if (wndPtr == NULL) {
printf("SetMenu(%04X, %04X) // Bad window handle !\n", hWnd, hMenu);
@@ -2111,15 +1995,14 @@
wndPtr->wIDmenu = hMenu;
if (hMenu != 0)
{
- lpmenu = (LPPOPUPMENU) GlobalLock(hMenu);
+ lpmenu = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu);
if (lpmenu == NULL) {
printf("SetMenu(%04X, %04X) // Bad menu handle !\n", hWnd, hMenu);
return FALSE;
}
- lpmenu->ownerWnd = hWnd;
+ lpmenu->hWnd = hWnd;
+ lpmenu->wFlags &= ~MF_POPUP; /* Can't be a popup */
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 );
@@ -2133,31 +2016,16 @@
*/
HMENU GetSubMenu(HMENU hMenu, short nPos)
{
- HMENU hSubMenu;
- LPPOPUPMENU lppop;
- LPMENUITEM lpitem;
- int i;
+ LPPOPUPMENU lppop;
+ LPMENUITEM lpitem;
#ifdef DEBUG_MENU
- printf("GetSubMenu (%04X, %04X) !\n", hMenu, nPos);
+ printf("GetSubMenu (%04X, %04X) !\n", hMenu, nPos);
#endif
- if (hMenu == 0) return 0;
- lppop = (LPPOPUPMENU) GlobalLock(hMenu);
- if (lppop == NULL) return 0;
- lpitem = lppop->firstItem;
- for (i = 0; i < lppop->nItems; i++) {
- if (lpitem == NULL) break;
- if (i == nPos) {
-#ifdef DEBUG_MENU
- printf(" found %04x\n", lpitem->item_id);
-#endif
- if (lpitem->item_flags & MF_POPUP)
- return lpitem->item_id;
- else
- return 0;
- }
- lpitem = (LPMENUITEM)lpitem->next;
- }
- return 0;
+ if (!(lppop = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu))) return 0;
+ if ((WORD)nPos >= lppop->nItems) return 0;
+ lpitem = (MENUITEM *) USER_HEAP_ADDR( lppop->hItems );
+ if (!(lpitem[nPos].item_flags & MF_POPUP)) return 0;
+ return lpitem[nPos].item_id;
}
@@ -2177,17 +2045,36 @@
#ifdef DEBUG_MENU
printf("DrawMenuBar wIDmenu=%04X \n", wndPtr->wIDmenu);
#endif
- lppop = (LPPOPUPMENU) GlobalLock(wndPtr->wIDmenu);
+ lppop = (LPPOPUPMENU) USER_HEAP_ADDR(wndPtr->wIDmenu);
if (lppop == NULL) return;
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);
}
}
+/***********************************************************************
+ * EndMenu (USER.187)
+ */
+void EndMenu(void)
+{
+ /* Note: this won't work when we have multiple tasks... */
+ fEndMenuCalled = TRUE;
+}
+
+
+/***********************************************************************
+ * LookupMenuHandle (USER.217)
+ */
+HMENU LookupMenuHandle( HMENU hmenu, INT id )
+{
+ if (!MENU_FindItem( &hmenu, &id, MF_BYCOMMAND )) return 0;
+ else return hmenu;
+}
+
+
/**********************************************************************
* LoadMenuIndirect [USER.220]
*/
@@ -2195,89 +2082,40 @@
{
HMENU hMenu;
MENU_HEADER *menu_desc;
- LPPOPUPMENU lppop;
#ifdef DEBUG_MENU
printf("LoadMenuIndirect: menu_template '%08X'\n", menu_template);
#endif
hMenu = CreateMenu();
menu_desc = (MENU_HEADER *)menu_template;
ParseMenuResource((WORD *)(menu_desc + 1), 0, hMenu);
- lppop = (LPPOPUPMENU) GlobalLock(hMenu);
- ResetHiliteFlags(lppop);
- GlobalUnlock(hMenu);
return hMenu;
}
/**********************************************************************
- * InitStdBitmaps (Internal)
- */
-void InitStdBitmaps()
-{
- 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;
- }
-}
-
-
-/**********************************************************************
* CopySysMenu (Internal)
*/
HMENU CopySysMenu()
{
- HMENU hMenu;
- LPPOPUPMENU menu;
- LPPOPUPMENU sysmenu;
+ HMENU hMenu;
+ LPPOPUPMENU sysmenu, menu;
+ MENUITEM *item;
+ int i;
+
+ sysmenu = (LPPOPUPMENU) USER_HEAP_ADDR(hSysMenu);
+ if (!(hMenu = CreatePopupMenu())) return 0;
+ menu = (POPUPMENU *) USER_HEAP_ADDR( hMenu );
+ menu->wFlags |= MF_SYSMENU;
+ item = (MENUITEM *) USER_HEAP_ADDR( sysmenu->hItems );
+ for (i = 0; i < sysmenu->nItems; i++, item++)
+ {
+ AppendMenu( hMenu, item->item_flags, item->item_id, item->item_text );
+ }
+
#ifdef DEBUG_MENU
- printf("CopySysMenu entry !\n");
+ printf("CopySysMenu hMenu=%04X !\n", hMenu);
#endif
- if (hSysMenu == 0) {
-/* hSysMenu = LoadMenu((HINSTANCE)NULL, MAKEINTRESOURCE(1)); */
-/* hSysMenu = LoadMenu((HINSTANCE)NULL, MAKEINTRESOURCE(SC_SYSMENU));*/
- hSysMenu = LoadMenu((HINSTANCE)NULL, "SYSMENU");
- if (hSysMenu == 0) {
- printf("SysMenu not found in system resources !\n");
- return (HMENU)NULL;
- }
-#ifdef DEBUG_MENU
- else
- printf("SysMenu loaded from system resources %04X !\n", hSysMenu);
-#endif
- }
- hMenu = GlobalAlloc(GMEM_MOVEABLE, sizeof(POPUPMENU));
- menu = (LPPOPUPMENU) GlobalLock(hMenu);
- sysmenu = (LPPOPUPMENU) GlobalLock(hSysMenu);
- if (menu != NULL && sysmenu != NULL) {
- sysmenu->BarFlag = FALSE;
- sysmenu->SysFlag = TRUE;
- memcpy(menu, sysmenu, sizeof(POPUPMENU));
- }
- else {
- printf("CopySysMenu // Bad SysMenu pointers !\n");
- if (menu != NULL) {
- GlobalUnlock(hMenu);
- GlobalFree(hMenu);
- }
- return (HMENU)NULL;
- }
- GlobalUnlock(hMenu);
- GlobalUnlock(hSysMenu);
-#ifdef DEBUG_MENU
- printf("CopySysMenu hMenu=%04X !\n", hMenu);
-#endif
- return hMenu;
+ return hMenu;
}
@@ -2320,17 +2158,13 @@
return next_item;
}
+
/**********************************************************************
- * IsMenu(USER.358)
+ * IsMenu (USER.358)
*/
-BOOL IsMenu(HMENU hMenu)
+BOOL IsMenu( HMENU hmenu )
{
- LPPOPUPMENU menu;
-
- menu = (LPPOPUPMENU) GlobalLock(hMenu);
- if (menu == NULL)
- return FALSE;
-
- GlobalUnlock(hMenu);
- return TRUE;
+ LPPOPUPMENU menu;
+ if (!(menu = (LPPOPUPMENU) USER_HEAP_ADDR( hmenu ))) return FALSE;
+ return (menu->wMagic == MENU_MAGIC);
}
diff --git a/controls/static.c b/controls/static.c
index 0f84195..409fd03 100644
--- a/controls/static.c
+++ b/controls/static.c
@@ -127,7 +127,6 @@
break;
}
- GlobalUnlock(hWnd);
return lResult;
}
@@ -187,7 +186,6 @@
DrawText(hdc, text, textlen, &rc, wFormat);
USER_HEAP_FREE(hText);
- GlobalUnlock(hwnd);
EndPaint(hwnd, &ps);
}
@@ -231,7 +229,6 @@
DeleteObject((HANDLE)hPen);
DeleteObject((HANDLE)hBrush);
- GlobalUnlock(hwnd);
EndPaint(hwnd, &ps);
}
@@ -273,7 +270,6 @@
DeleteObject((HANDLE)hPen);
DeleteObject((HANDLE)hBrush);
- GlobalUnlock(hwnd);
EndPaint(hwnd, &ps);
}
@@ -304,7 +300,6 @@
hIcon = LoadIcon(wndPtr->hInstance, textPtr);
DrawIcon(hdc, rc.left, rc.top, hIcon);
EndPaint(hwnd, &ps);
- GlobalUnlock(hwnd);
}
diff --git a/if1632/relay.c b/if1632/relay.c
index 070a58a..3122d8b 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -290,7 +290,7 @@
used++;
if (table[j].handler) implemented++;
else
- printf("%s.%d\n",
+ printf("%s.%d not implemented\n",
dll_builtin_table[i].dll_name,
j);
};
@@ -301,10 +301,11 @@
perc = implemented * 100.00 / used;
else
perc = 0.0;
- printf("%s: %d of %d (%3.1f %%)\n", dll_builtin_table[i].dll_name, implemented, used, perc);
+ if (used)
+ printf("%s: %d of %d (%3.1f %%)\n", dll_builtin_table[i].dll_name, implemented, used, perc);
};
perc = timplemented * 100.00 / tused;
- printf("TOTAL: %d of %d implemented (%3.1f %%)\n",timplemented, tused, perc);
+ printf("TOTAL: %d of %d winapi functions implemented (%3.1f %%)\n",timplemented, tused, perc);
}
#endif /* WINESTAT */
#endif /* !WINELIB */
diff --git a/if1632/toolhelp.spec b/if1632/toolhelp.spec
index 682dec5..4380277 100644
--- a/if1632/toolhelp.spec
+++ b/if1632/toolhelp.spec
@@ -15,16 +15,16 @@
60 pascal ModuleNext(ptr) ModuleNext(1)
61 pascal ModuleFindName(ptr ptr) ModuleFindName(1 2)
62 pascal ModuleFindHandle(ptr word) ModuleFindHandle(1 2)
-# 63 1 0caa TASKFIRST exported, shared data
-# 64 1 0ced TASKNEXT exported, shared data
-# 65 1 0d2e TASKFINDHANDLE exported, shared data
+63 pascal16 TaskFirst(ptr) TaskFirst(1)
+64 pascal16 TaskNext(ptr) TaskNext(1)
+65 pascal16 TaskFindHandle(ptr word) TaskFindHandle(1 2)
# 66 1 0f1c STACKTRACEFIRST exported, shared data
# 67 1 0f67 STACKTRACECSIPFIRST exported, shared data
# 68 1 0fca STACKTRACENEXT exported, shared data
# 69 1 28b0 CLASSFIRST exported, shared data
# 70 1 2925 CLASSNEXT exported, shared data
# 71 1 11ce SYSTEMHEAPINFO exported, shared data
-# 72 1 13f4 MEMMANINFO exported, shared data
+72 pascal16 MemManInfo(ptr) MemManInfo(1)
# 73 1 1b72 NOTIFYREGISTER exported, shared data
# 74 1 1c29 NOTIFYUNREGISTER exported, shared data
# 75 1 2060 INTERRUPTREGISTER exported, shared data
diff --git a/if1632/user.spec b/if1632/user.spec
index 88c5d9d..371b3d7 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -190,7 +190,7 @@
185 pascal GrayString(word word ptr ptr word word word word word)
GrayString(1 2 3 4 5 6 7 8 9)
186 pascal SwapMouseButton(word) SwapMouseButton(1)
-#187 ENDMENU
+187 pascal EndMenu() EndMenu()
188 pascal SetSysModalWindow(word) SetSysModalWindow(1)
189 pascal GetSysModalWindow() GetSysModalWindow()
190 pascal GetUpdateRect(word ptr word) GetUpdateRect(1 2 3)
@@ -201,7 +201,8 @@
195 pascal DlgDirListComboBox(word ptr word word word) DlgDirListComboBox(1 2 3 4 5)
196 pascal TabbedTextOut(word s_word s_word ptr s_word s_word ptr s_word)
TabbedTextOut(1 2 3 4 5 6 7 8)
-#197 GETTABBEDTEXTEXTENT
+197 pascal GETTABBEDTEXTEXTENT(word ptr word word ptr)
+ GetTabbedTextExtent(1 2 3 4 5)
#198 CASCADECHILDWINDOWS
#199 TILECHILDWINDOWS
200 pascal OpenComm(ptr word word) OpenComm(1 2 3)
@@ -221,7 +222,7 @@
214 pascal EscapeCommFunction(word word) EscapeCommFunction(1 2)
215 pascal FlushComm(word word) FlushComm(1 2)
#216 USERSEEUSERDO
-#217 LOOKUPMENUHANDLE
+217 pascal LookupMenuHandle(word s_word) LookupMenuHandle(1 2)
218 pascal DialogBoxIndirect(word word word ptr) DialogBoxIndirect(1 2 3 4)
219 pascal CreateDialogIndirect(word ptr word ptr)
CreateDialogIndirect(1 2 3 4)
diff --git a/include/bitmaps/check_bitmap b/include/bitmaps/check_bitmap
deleted file mode 100644
index bc76d9f..0000000
--- a/include/bitmaps/check_bitmap
+++ /dev/null
@@ -1,7 +0,0 @@
-#define check_bitmap_width 10
-#define check_bitmap_height 10
-#define check_bitmap_x_hot 0
-#define check_bitmap_y_hot 0
-static char check_bitmap_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x80, 0x01, 0xc0, 0x00,
- 0x63, 0x00, 0x36, 0x00, 0x1c, 0x00, 0x08, 0x00};
diff --git a/include/bitmaps/check_mark b/include/bitmaps/check_mark
new file mode 100644
index 0000000..4c7adce
--- /dev/null
+++ b/include/bitmaps/check_mark
@@ -0,0 +1,6 @@
+#define check_mark_width 14
+#define check_mark_height 14
+static char check_mark_bits[] = {
+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x04, 0x00, 0x06,
+ 0x30, 0x02, 0x60, 0x03, 0x40, 0x01, 0xc0, 0x01, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00};
diff --git a/include/bitmaps/menu_arrow b/include/bitmaps/menu_arrow
new file mode 100644
index 0000000..a38ff70
--- /dev/null
+++ b/include/bitmaps/menu_arrow
@@ -0,0 +1,4 @@
+#define menu_arrow_width 7
+#define menu_arrow_height 11
+static char menu_arrow_bits[] = {
+ 0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00};
diff --git a/include/bitmaps/nocheck_bitmap b/include/bitmaps/nocheck_bitmap
deleted file mode 100644
index a56ae35..0000000
--- a/include/bitmaps/nocheck_bitmap
+++ /dev/null
@@ -1,7 +0,0 @@
-#define nocheck_bitmap_width 10
-#define nocheck_bitmap_height 10
-#define nocheck_bitmap_x_hot 0
-#define nocheck_bitmap_y_hot 0
-static char nocheck_bitmap_bits[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
diff --git a/include/dialog.h b/include/dialog.h
index b6fe1b3..3b33347 100644
--- a/include/dialog.h
+++ b/include/dialog.h
@@ -25,6 +25,7 @@
WORD xBaseUnit;
WORD yBaseUnit;
WORD fEnd;
+ HANDLE hDialogHeap;
} DIALOGINFO;
diff --git a/include/menu.h b/include/menu.h
index c877618..2e0f7ca 100644
--- a/include/menu.h
+++ b/include/menu.h
@@ -6,42 +6,34 @@
#ifndef MENU_H
#define MENU_H
+#define MENU_MAGIC 0x554d /* 'MU' */
typedef struct tagMENUITEM
{
- struct tagMENUITEM *next;
- struct tagMENUITEM *prev;
- HANDLE hItem;
WORD item_flags;
WORD item_id;
- WORD sel_key;
- char *item_text;
- HANDLE hText;
RECT rect;
+ WORD sel_key;
HBITMAP hCheckBit;
HBITMAP hUnCheckBit;
+ char *item_text;
+ HANDLE hText;
} MENUITEM, *LPMENUITEM;
typedef struct tagPOPUPMENU
{
- HWND hWnd; /* PopupMenu window handle */
- HWND hWndParent; /* Parent PopupMenu window handle */
- HWND ownerWnd; /* Owner window */
- HWND hWndPrev; /* Previous Window Focus Owner */
- WORD nItems; /* Number of items on menu */
- MENUITEM *firstItem;
- WORD FocusedItem;
- WORD MouseFlags;
- BOOL BarFlag; /* TRUE if menu is a MENUBAR */
- BOOL SysFlag; /* TRUE if menu is a SYSMENU */
- BOOL ChildFlag; /* TRUE if child of other menu */
- WORD Width;
- WORD Height;
- WORD CheckWidth;
- WORD PopWidth;
- RECT rect;
+ HMENU hNext; /* Next menu (compatibility only, always 0) */
+ WORD wFlags; /* Menu flags (MF_POPUP, MF_SYSMENU) */
+ WORD wMagic; /* Magic number */
+ HANDLE hTaskQ; /* Task queue for this menu */
+ WORD Width; /* Width of the whole menu */
+ WORD Height; /* Height of the whole menu */
+ WORD nItems; /* Number of items in the menu */
+ HWND hWnd; /* Window containing the menu */
+ HANDLE hItems; /* Handle to the items array */
+ WORD FocusedItem; /* Currently focused item */
} POPUPMENU, *LPPOPUPMENU;
typedef struct
@@ -63,11 +55,4 @@
char item_text[1]; /* Text for menu item */
} MENUITEMTEMPLATE;
-void StdDrawMenuBar(HDC hDC, LPRECT lprect, LPPOPUPMENU lppop,
- BOOL suppress_draw);
-BOOL MenuButtonDown(HWND hWnd, LPPOPUPMENU lppop, int x, int y);
-void MenuButtonUp(HWND hWnd, LPPOPUPMENU lppop, int x, int y);
-void MenuMouseMove(HWND hWnd, LPPOPUPMENU lppop, WORD wParam, int x, int y);
-extern void NC_TrackSysMenu(HWND hwnd);
-
#endif /* MENU_H */
diff --git a/include/message.h b/include/message.h
index 5e6e9e8..66d7926 100644
--- a/include/message.h
+++ b/include/message.h
@@ -53,7 +53,7 @@
extern void hardware_event( WORD message, WORD wParam, LONG lParam,
int xPos, int yPos, DWORD time, DWORD extraInfo );
extern BOOL MSG_GetHardwareMessage( LPMSG msg );
-extern BOOL MSG_InternalGetMessage( LPMSG msg, HWND hwnd,
- short code, BOOL sendIdle );
+extern BOOL MSG_InternalGetMessage( LPMSG msg, HWND hwnd, HWND hwndOwner,
+ short code, WORD flags, BOOL sendIdle );
#endif /* MESSAGE_H */
diff --git a/include/msdos.h b/include/msdos.h
index 99eccef..e5443f1 100644
--- a/include/msdos.h
+++ b/include/msdos.h
@@ -17,29 +17,6 @@
#define DOSVERSION 0x0330;
#define MAX_DOS_DRIVES 26
-#define EAX context->sc_eax
-#define EBX context->sc_ebx
-#define ECX context->sc_ecx
-#define EDX context->sc_edx
-
-#define AX (context->sc_eax & 0x0000ffffL)
-#define BX (context->sc_ebx & 0x0000ffffL)
-#define CX (context->sc_ecx & 0x0000ffffL)
-#define DX (context->sc_edx & 0x0000ffffL)
-
-#define CS context->sc_cs
-#define DS context->sc_ds
-#define ES context->sc_es
-#define SS context->sc_ss
-
-#define DI context->sc_edi
-#define SI context->sc_esi
-#define SP context->sc_esp
-#define EFL context->sc_efl
-
-#define SetCflag (EFL |= 0x00000001L)
-#define ResetCflag (EFL &= 0xfffffffeL)
-
#define pointer(a,b) (BYTE*)(((WORD) a << 16) | b)
#define segment(a) ((DWORD)a >> 16)
#define offset(a) ((DWORD)a & 0xffff)
diff --git a/include/registers.h b/include/registers.h
new file mode 100644
index 0000000..0284abf
--- /dev/null
+++ b/include/registers.h
@@ -0,0 +1,50 @@
+#ifndef __WINE_REGISTERS_H
+#define __WINE_REGISTERS_H
+
+#include <windows.h>
+#include "autoconf.h"
+
+#ifndef PROCEMU
+
+#define EAX context->sc_eax
+#define EBX context->sc_ebx
+#define ECX context->sc_ecx
+#define EDX context->sc_edx
+
+#define AX *(WORD*)&context->sc_eax
+#define BX *(WORD*)&context->sc_ebx
+#define CX *(WORD*)&context->sc_ecx
+#define DX *(WORD*)&context->sc_edx
+
+#define AL *(BYTE*)&context->sc_eax
+#define AH *(((BYTE*)&context->sc_eax)+1)
+#define BL *(BYTE*)&context->sc_ebx
+#define BH *(((BYTE*)&context->sc_ebx)+1)
+#define CL *(BYTE*)&context->sc_ecx
+#define CH *(((BYTE*)&context->sc_ecx)+1)
+#define DL *(BYTE*)&context->sc_edx
+#define DH *(((BYTE*)&context->sc_edx)+1)
+
+#define CS context->sc_cs
+#define DS context->sc_ds
+#define ES context->sc_es
+#define SS context->sc_ss
+
+#define DI context->sc_edi
+#define SI context->sc_esi
+#define SP context->sc_esp
+#define EFL context->sc_efl
+#define EIP context->sc_eip
+
+#define SetCflag (EFL |= 0x00000001)
+#define ResetCflag (EFL &= 0xfffffffe)
+
+#else
+
+#include "bx_bochs.h"
+
+#define SetCflag bx_STC()
+#define ResetCflag bx_CLC()
+
+#endif /* PROCEMU */
+#endif /* __WINE_REGISTERS_H */
diff --git a/include/task.h b/include/task.h
index 1c05265..8be9787 100644
--- a/include/task.h
+++ b/include/task.h
@@ -7,30 +7,9 @@
#include "toolhelp.h"
-typedef HANDLE HGLOBAL;
-
-typedef struct {
- DWORD dwSize;
- HTASK hTask;
- HTASK hTaskParent;
- HINSTANCE hInst;
- HMODULE hModule;
- WORD wSS;
- WORD wSP;
- WORD wStackTop;
- WORD wStackMinimum;
- WORD wStackBottom;
- WORD wcEvents;
- HGLOBAL hQueue;
- char szModule[MAX_MODULE_NAME + 1];
- WORD wPSPOffset;
- HANDLE hNext;
-} TASKENTRY;
-typedef TASKENTRY *LPTASKENTRY;
-
typedef struct {
TASKENTRY te;
- int unix_pid;
+ int unix_pid;
HICON hIcon;
HWND *lpWndList;
void *lpPrevTask;
diff --git a/include/toolhelp.h b/include/toolhelp.h
index 6941d1b..40d7d9b 100644
--- a/include/toolhelp.h
+++ b/include/toolhelp.h
@@ -4,9 +4,14 @@
#include "windows.h"
DECLARE_HANDLE(HMODULE);
+DECLARE_HANDLE(HGLOBAL);
-#define MAX_MODULE_NAME 9
-#define MAX_PATH 255
+#define MAX_DATA 11
+#define MAX_MODULE_NAME 9
+#define MAX_PATH 255
+#define MAX_CLASSNAME 255
+
+/* modules */
typedef struct {
DWORD dwSize;
@@ -23,4 +28,61 @@
HMODULE ModuleFindName(MODULEENTRY *lpModule, LPCSTR lpstrName);
HMODULE ModuleFindHandle(MODULEENTRY *lpModule, HMODULE hModule);
+/* tasks */
+
+typedef struct tagTASKENTRY {
+ DWORD dwSize;
+ HTASK hTask;
+ HTASK hTaskParent;
+ HINSTANCE hInst;
+ HMODULE hModule;
+ WORD wSS;
+ WORD wSP;
+ WORD wStackTop;
+ WORD wStackMinimum;
+ WORD wStackBottom;
+ WORD wcEvents;
+ HGLOBAL hQueue;
+ char szModule[MAX_MODULE_NAME + 1];
+ WORD wPSPOffset;
+ HANDLE hNext;
+} TASKENTRY;
+typedef TASKENTRY *LPTASKENTRY;
+
+BOOL TaskFirst(LPTASKENTRY lpTask);
+BOOL TaskNext(LPTASKENTRY lpTask);
+BOOL TaskFindHandle(LPTASKENTRY lpTask, HTASK hTask);
+DWORD TaskSetCSIP(HTASK hTask, WORD wCS, WORD wIP);
+DWORD TaskGetCSIP(HTASK hTask);
+BOOL TaskSwitch(HTASK hTask, DWORD dwNewCSIP);
+
+/* mem info */
+
+typedef struct tagMEMMANINFO {
+ DWORD dwSize;
+ DWORD dwLargestFreeBlock;
+ DWORD dwMaxPagesAvailable;
+ DWORD dwMaxPagesLockable;
+ DWORD dwTotalLinearSpace;
+ DWORD dwTotalUnlockedPages;
+ DWORD dwFreePages;
+ DWORD dwTotalPages;
+ DWORD dwFreeLinearSpace;
+ DWORD dwSwapFilePages;
+ WORD wPageSize;
+} MEMMANINFO;
+typedef MEMMANINFO *LPMEMMANINFO;
+
+typedef struct tagSYSHEAPINFO {
+ DWORD dwSize;
+ WORD wUserFreePercent;
+ WORD wGDIFreePercent;
+ HGLOBAL hUserSegment;
+ HGLOBAL hGDISegment;
+} SYSHEAPINFO;
+typedef SYSHEAPINFO *LPSYSHEAPINFO;
+
+BOOL MemManInfo(LPMEMMANINFO lpEnhMode);
+BOOL SystemHeapInfo(LPSYSHEAPINFO lpSysHeap);
+
#endif /* __TOOLHELP_H */
diff --git a/include/windows.h b/include/windows.h
index 3f14d8b..711210a 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -1496,6 +1496,8 @@
#define WM_HSCROLL 0x0114
#define WM_VSCROLL 0x0115
+#define WM_ENTERIDLE 0x0121
+
/* Mouse messages */
#define WM_MOUSEMOVE 0x0200
#define WM_LBUTTONDOWN 0x0201
@@ -2714,6 +2716,7 @@
Fb(HMENU,GetSubMenu,HMENU,a,short,b)
Fb(HMENU,GetSystemMenu,HWND,a,BOOL,b)
Fb(HMENU,LoadMenu,HANDLE,a,LPSTR,b)
+Fb(HMENU,LookupMenuHandle,HMENU,a,INT,b)
Fb(HWND,ChildWindowFromPoint,HWND,a,POINT,b)
Fb(HWND,FindWindow,LPSTR,a,LPSTR,b)
Fb(HWND,GetDlgItem,HWND,a,WORD,b)
diff --git a/loader/ldtlib.c b/loader/ldtlib.c
index 40929d6..181c4b1 100644
--- a/loader/ldtlib.c
+++ b/loader/ldtlib.c
@@ -5,6 +5,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
+#include "autoconf.h"
+
#ifdef linux
#include <linux/unistd.h>
#include <linux/head.h>
diff --git a/loader/resource.c b/loader/resource.c
index 662fa34..b69c5f2 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -37,6 +37,8 @@
static RESOURCE *Top = NULL;
extern HINSTANCE hSysRes;
+extern HBITMAP BITMAP_LoadOEMBitmap( WORD id ); /* objects/bitmap.c */
+
HANDLE RSC_LoadResource(int instance, char *rsc_name, int type,
int *image_size_ret);
void RSC_LoadNameTable(void);
@@ -1153,8 +1155,14 @@
printf("LoadBitmap: instance = %04x, name = %08x\n",
instance, bmp_name);
#endif
- if (instance == (HANDLE)NULL) instance = hSysRes;
- if (!(hdc = GetDC(GetDesktopWindow()))) return 0;
+ if (!instance)
+ {
+ /* Try to create an OEM bitmap */
+ hbitmap = BITMAP_LoadOEMBitmap( ((int)bmp_name) & 0xffff );
+ if (hbitmap) return hbitmap;
+ /* Failed -> load it from sysres.dll */
+ instance = hSysRes;
+ }
rsc_mem = RSC_LoadResource(instance, bmp_name, NE_RSCTYPE_BITMAP,
&image_size);
@@ -1163,6 +1171,7 @@
return 0;
}
lp = (long *) GlobalLinearLock(rsc_mem);
+ if (!(hdc = GetDC(0))) lp = NULL;
if (lp == NULL)
{
GlobalFree(rsc_mem);
diff --git a/loader/task.c b/loader/task.c
index 569c64b..d227640 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -10,6 +10,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
#include "windows.h"
#include "wine.h"
#include "task.h"
@@ -17,7 +19,6 @@
static LPWINETASKENTRY lpTaskList = NULL;
static int nTaskCount = 0;
-
/**********************************************************************
* GetCurrentTask [KERNEL.36]
*/
@@ -122,9 +123,14 @@
*/
HANDLE CreateNewTask(HINSTANCE hInst, HTASK hTaskParent)
{
- HANDLE hTask;
+ HANDLE hTask;
LPWINETASKENTRY lpTask = lpTaskList;
LPWINETASKENTRY lpNewTask;
+ MODULEENTRY module;
+
+ module.dwSize = sizeof(module);
+ ModuleFindHandle(&module, hInst);
+
if (lpTask != NULL) {
while (TRUE) {
if (lpTask->lpNextTask == NULL) break;
@@ -160,7 +166,7 @@
lpNewTask->te.wStackBottom = 0;
lpNewTask->te.wcEvents = 0;
lpNewTask->te.hQueue = 0;
- sprintf(lpNewTask->te.szModule, "TASK%04X", hInst);
+ strcpy(lpNewTask->te.szModule, module.szModule);
lpNewTask->te.wPSPOffset = 0;
lpNewTask->unix_pid = getpid();
lpNewTask->lpWndList = (HWND *) malloc(MAXWIN_PER_TASK * sizeof(HWND));
@@ -245,4 +251,55 @@
return TRUE;
}
+BOOL TaskFirst(LPTASKENTRY lpTask)
+{
+ printf("TaskFirst(%8x)\n", (int) lpTask);
+ if (lpTaskList) {
+ memcpy(lpTask, &lpTaskList->te, lpTask->dwSize);
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+BOOL TaskNext(LPTASKENTRY lpTask)
+{
+ LPWINETASKENTRY list;
+
+ printf("TaskNext(%8x)\n", (int) lpTask);
+
+ list = lpTaskList;
+ while (list) {
+ if (list->te.hTask == lpTask->hTask) {
+ list = list->lpNextTask;
+ if (list) {
+ memcpy(lpTask, &list->te, lpTask->dwSize);
+ return TRUE;
+ } else
+ return FALSE;
+ }
+ list = list->lpNextTask;
+ }
+ return FALSE;
+}
+
+BOOL TaskFindHandle(LPTASKENTRY lpTask, HTASK hTask)
+{
+ static LPWINETASKENTRY list;
+
+ printf("TaskFindHandle(%8x,%4x)\n", (int) lpTask, hTask);
+
+ list = lpTaskList;
+ while (list) {
+ if (list->te.hTask == hTask) {
+ list = list->lpNextTask;
+ if (list) {
+ memcpy(lpTask, &list->te, lpTask->dwSize);
+ return TRUE;
+ } else
+ return FALSE;
+ }
+ list = list->lpNextTask;
+ }
+ return FALSE;
+}
diff --git a/memory/global.c b/memory/global.c
index 7509868..117c532 100644
--- a/memory/global.c
+++ b/memory/global.c
@@ -8,6 +8,7 @@
#include <stdlib.h>
#include <string.h>
#include "prototypes.h"
+#include "toolhelp.h"
#include "heap.h"
#include "segmem.h"
@@ -807,3 +808,11 @@
printf("GetFreeSpace // return %ld !\n", total_free << 16);
return total_free << 16;
}
+
+/**********************************************************************
+ * MemManInfo (toolhelp.72)
+ */
+BOOL MemManInfo(LPMEMMANINFO lpmmi)
+{
+ return 1;
+}
diff --git a/misc/file.c b/misc/file.c
index 92359fd..db2293d 100644
--- a/misc/file.c
+++ b/misc/file.c
@@ -23,13 +23,28 @@
#include <unistd.h>
#include <time.h>
#include <windows.h>
+#include <sys/stat.h>
#include "prototypes.h"
+#include "regfunc.h"
+#include "windows.h"
+#include "wine.h"
+#include "msdos.h"
+#include "registers.h"
+#include "options.h"
+
+#define MAX_PATH 255
/* #define DEBUG_FILE /* */
char WindowsDirectory[256], SystemDirectory[256], TempDirectory[256];
extern char WindowsPath[256];
+extern char WindowsPath[];
+extern WORD ExtendedError;
+
+
+char *GetDosFileName(char *unixfilename);
+
/***************************************************************************
_lopen
@@ -116,83 +131,153 @@
/**************************************************************************
OpenFile
-
- Warning: This is nearly totally untested. It compiles, that's it...
- -SL 9/13/93
**************************************************************************/
INT OpenFile (LPSTR lpFileName, LPOFSTRUCT ofs, WORD wStyle)
{
- int base, flags;
- int handle;
- char buf[256];
-
-#ifdef DEBUG_FILE
- fprintf(stderr,"OpenFile(%s,<struct>,%04X)\n",lpFileName,wStyle);
-#endif
-
- base = wStyle & 0xF;
- flags = wStyle & 0xFFF0;
+ int handle;
+ struct sigcontext_struct ccontext;
+ /* To make macros like EAX happy */
+ struct sigcontext_struct *context=&ccontext;
+ char filename[MAX_PATH+1];
+ int action;
+ struct stat s;
+ struct tm *now;
+ int res;
+ int verify_time;
- flags &= 0xFF0F; /* strip SHARE bits for now */
- flags &= 0xD7FF; /* strip PROMPT & CANCEL bits for now */
- flags &= 0x7FFF; /* strip REOPEN bit for now */
- flags &= 0xFBFF; /* strib VERIFY bit for now */
+ #ifdef DEBUG_FILE
+ fprintf(stderr,"Openfile(%s,<struct>,%d) ",lpFileName,wStyle);
+ #endif
- if (flags & OF_CREATE)
- {
- base |= O_CREAT;
- flags &= 0xEFFF;
- }
+ action = wStyle & 0xff00;
+
+
+ /* OF_CREATE is completly different from all other options, so
+ handle it first */
-#ifdef DEBUG_FILE
- fprintf(stderr,"now %d,%d\n",base,flags);
-#endif
+ if (action & OF_CREATE)
+ {
+ int handle;
+ char *unixfilename;
- if (flags & OF_EXIST)
- {
- printf("OpenFile // OF_EXIST '%s' !\n", lpFileName);
- handle = _lopen (lpFileName, wStyle);
- if (handle == -1) {
- /* Try again with WindowsPath */
- if (FindFile(buf, sizeof(buf), lpFileName, NULL, WindowsPath) != NULL) {
- handle = _lopen (buf, wStyle);
- }
- }
- close(handle);
- return handle;
- }
- if (flags & OF_DELETE)
- {
- printf("OpenFile // OF_DELETE '%s' !\n", lpFileName);
- return unlink(lpFileName);
- }
- else
- {
- int handle;
- char *UnixFileName;
- if ((UnixFileName = GetUnixFileName(lpFileName)) == NULL)
- return HFILE_ERROR;
- handle = open(UnixFileName, base, 0666);
- if (handle == -1) {
- /* Try again with WindowsPath */
- if (FindFile(buf, sizeof(buf), lpFileName, NULL, WindowsPath) != NULL) {
-#ifdef DEBUG_FILE
- printf("OpenFile // file '%s' found !\n", buf);
-#endif
- UnixFileName = buf;
- handle = open(UnixFileName, base, 0666);
- }
- }
+ if (!(action & OF_REOPEN))
+ strcpy(ofs->szPathName, lpFileName);
+ ofs->cBytes = sizeof(OFSTRUCT);
+ ofs->fFixedDisk = FALSE;
+ ofs->nErrCode = 0;
+ *((int*)ofs->reserved) = 0;
-#ifdef DEBUG_FILE
- fprintf(stderr, "OpenFile: returning %04.4x\n", handle);
-#endif
+ if ((unixfilename = GetUnixFileName (ofs->szPathName)) == NULL)
+ {
+ errno_to_doserr();
+ ofs->nErrCode = ExtendedError;
+ return -1;
+ }
+ handle = open (ofs->szPathName, (wStyle & 0x0003) | O_CREAT, 0x666);
+ if (handle == -1)
+ {
+ errno_to_doserr();
+ ofs->nErrCode = ExtendedError;
+ }
+ return handle;
+ }
- if (handle == -1)
- return HFILE_ERROR;
+
+ /* If path isn't given, try to find the file. */
+
+ if (!(action & OF_REOPEN))
+ {
+ if( !( index(lpFileName,'\\') || index(lpFileName,'/') ||
+ index(lpFileName,':')))
+ while(1)
+ {
+ char temp[MAX_PATH+1];
+ strcpy (filename, lpFileName);
+ if ( (!stat(GetUnixFileName(filename), &s)) && (S_ISREG(s.st_mode)) )
+ break;
+ GetWindowsDirectory (filename,MAX_PATH);
+ if (filename[1] != ':')
+ strcat(filename,'\\');
+ strcat (filename, lpFileName);
+ if ( (!stat(GetUnixFileName(filename), &s)) && (S_ISREG(s.st_mode)) )
+ break;
+ GetSystemDirectory (filename,MAX_PATH);
+ if (filename[1] != ':')
+ strcat(filename,'\\');
+ strcat (filename, lpFileName);
+ if ( (!stat(GetUnixFileName(filename), &s)) && (S_ISREG(s.st_mode)) )
+ break;
+ if (!FindFile(temp,MAX_PATH,lpFileName,NULL,WindowsPath))
+ {
+ strcpy(filename, GetDosFileName(temp));
+ break;
+ }
+ strcpy (filename, lpFileName);
+ break;
+ }
else
- return handle;
+ strcpy (filename,lpFileName);
+
+ ofs->cBytes = sizeof(OFSTRUCT);
+ ofs->fFixedDisk = FALSE;
+ strcpy(ofs->szPathName, filename);
+ ofs->nErrCode = 0;
+ if (!(action & OF_VERIFY))
+ *((int*)ofs->reserved) = 0;
}
+
+
+ if (action & OF_PARSE)
+ return 0;
+
+ if (action & OF_DELETE)
+ return unlink(ofs->szPathName);
+
+
+ /* Now on to getting some information about that file */
+
+ if (res = stat(GetUnixFileName(ofs->szPathName), &s))
+ {
+ errno_to_doserr();
+ ofs->nErrCode = ExtendedError;
+ return -1;
+ }
+
+ now = localtime (&s.st_mtime);
+
+ if (action & OF_VERIFY)
+ verify_time = *((int*)ofs->reserved);
+
+ *((WORD*)(&ofs->reserved[2]))=
+ ((now->tm_hour * 0x2000) + (now->tm_min * 0x20) + (now->tm_sec / 2));
+ *((WORD*)(&ofs->reserved[0]))=
+ ((now->tm_year * 0x200) + (now->tm_mon * 0x20) + now->tm_mday);
+
+ if (action & OF_EXIST)
+ return 0;
+
+ if (action & OF_VERIFY)
+ return (verify_time != *((int*)ofs->reserved));
+
+
+ /* Now we are actually going to open the file. According to Microsoft's
+ Knowledge Basis, this is done by calling int 21h, ax=3dh. */
+
+ EAX = 0x00003d00;
+ EAX = (EAX & 0xffffff0f) | (wStyle & 0x0070); /* Handle OF_SHARE_xxx etc. */
+ EAX = (EAX & 0xfffffff0) | (wStyle & 0x0003); /* Handle OF_READ etc. */
+ DS = segment (ofs->szPathName);
+ EDX = (EDX & 0xffff0000) | offset (ofs->szPathName);
+
+ OpenExistingFile (context);
+
+ if (EFL & 0x00000001) /* Cflag */
+ {
+ ofs->nErrCode = (AX & 0x00ff);
+ return -1;
+ }
+
+ return AX;
}
/**************************************************************************
diff --git a/misc/lstr.c b/misc/lstr.c
index 361ea10..28ec8c4 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -12,8 +12,10 @@
#include "regfunc.h"
#include "windows.h"
+#define ToUpper(c) toupper(c)
+#define ToLower(c) tolower(c)
- /* Funny to divide them between user and kernel. */
+/* Funny to divide them between user and kernel. */
/* KERNEL.89 */
LPSTR lstrcat(LPSTR target,LPCSTR source)
@@ -58,44 +60,50 @@
return strlen(str);
}
-
-/* AnsiUpper USER.431 */
-char FAR* AnsiUpper(char FAR* strOrChar)
+/* IsCharAlpha USER 433 */
+BOOL IsCharAlpha(char ch)
{
- /* I am not sure if the locale stuff works with toupper, but then again
- I am not sure if the Linux libc locale stuffs works at all */
-/* if((int)strOrChar<256)
- return (char FAR*) toupper((int)strOrChar);
- else {
- int i;
- for(i=0;(i<65536) && strOrChar[i];i++)
- strOrChar[i]=toupper(strOrChar[i]);
- return strOrChar;
- } */
- int i;
- for (i = 0; (i < 65536 && strOrChar[i]);i++)
- strOrChar[i] = (strOrChar[i] >= 'a' && strOrChar[i] <= 'z') ?
- strOrChar[i] - ('a' - 'A') : strOrChar[i];
- return strOrChar;
+ return isalpha(ch); /* This is probably not right for NLS */
}
-/* AnsiLower USER.432 */
-char FAR* AnsiLower(char FAR* strOrChar)
+/* IsCharAlphanumeric USER 434 */
+BOOL IsCharAlphanumeric(char ch)
{
- /* I am not sure if the locale stuff works with tolower, but then again
+ return (ch<'0')?0:(ch<'9');
+}
+
+/* IsCharUpper USER 435 */
+BOOL IsCharUpper(char ch)
+{
+ return isupper(ch);
+}
+
+/* IsCharLower USER 436 */
+BOOL IsCharLower(char ch)
+{
+ return islower(ch);
+}
+
+/* AnsiUpper USER.431 */
+LPSTR AnsiUpper(LPSTR strOrChar)
+{
+ char *s = strOrChar;
+ /* I am not sure if the locale stuff works with toupper, but then again
I am not sure if the Linux libc locale stuffs works at all */
-/* if((int)strOrChar<256)
- return (char FAR*)tolower((int)strOrChar);
- else {
- int i;
- for(i=0;(i<65536)&&strOrChar[i];i++)
- strOrChar[i]=tolower(strOrChar[i]);
- return strOrChar;
- }*/
- int i;
- for (i = 0; (i < 65536 && strOrChar[i]);i++)
- strOrChar[i] = (strOrChar[i] >= 'A' && strOrChar[i] <= 'Z') ?
- strOrChar[i] + ('a' - 'A') : strOrChar[i];
+
+ /* uppercase only one char if strOrChar < 0x10000 */
+ if(HIWORD((DWORD)strOrChar)) {
+ while (*s) {
+ if (IsCharLower(*s))
+ *s = ToUpper(*s);
+ s++;
+ }
+ return strOrChar;
+ } else
+ if (IsCharLower((char) strOrChar))
+ return (LPSTR) ToUpper(strOrChar);
+ else
+ return (LPSTR) strOrChar;
}
/* AnsiUpperBuff USER.437 */
@@ -109,6 +117,28 @@
return i;
}
+/* AnsiLower USER.432 */
+LPSTR AnsiLower(LPSTR strOrChar)
+{
+ char *s = strOrChar;
+ /* I am not sure if the locale stuff works with toupper, but then again
+ I am not sure if the Linux libc locale stuffs works at all */
+
+ /* lowercase only one char if strOrChar < 0x10000 */
+ if(HIWORD((DWORD)strOrChar)) {
+ while (*s) {
+ if (IsCharUpper(*s))
+ *s = ToLower(*s);
+ s++;
+ }
+ return strOrChar;
+ } else
+ if (IsCharUpper((char) strOrChar))
+ return (LPSTR) ToLower(strOrChar);
+ else
+ return (LPSTR) strOrChar;
+}
+
/* AnsiLowerBuff USER.438 */
UINT AnsiLowerBuff(LPSTR str,UINT len)
{
@@ -134,29 +164,6 @@
return (current==start)?start:current-1;
}
-/* IsCharAlpha USER 433 */
-BOOL IsCharAlpha(char ch)
-{
- return isalpha(ch); /* This is probably not right for NLS */
-}
-/* IsCharAlphanumeric USER 434 */
-BOOL IsCharAlphanumeric(char ch)
-{
- return (ch<'0')?0:(ch<'9');
-}
-
-/* IsCharUpper USER 435 */
-BOOL IsCharUpper(char ch)
-{
- return isupper(ch);
-}
-
-/* IsCharUpper USER 436 */
-BOOL IsCharLower(char ch)
-{
- return islower(ch);
-}
-
static char Oem2Ansi[256];
static char Ansi2Oem[256];
diff --git a/misc/spy.c b/misc/spy.c
index c52db35..efb2210 100644
--- a/misc/spy.c
+++ b/misc/spy.c
@@ -153,7 +153,8 @@
"WM_TIMER", /* 0x0113 */
"WM_HSCROLL", /* 0x0114 */
"WM_VSCROLL", /* 0x0115 */
- NULL, NULL,
+ "WM_INITMENU", /* 0x0116 */
+ "WM_INITMENUPOPUP", /* 0x0117 */
"WM_SYSTIMER", /* 0x0118 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
diff --git a/misc/user.c b/misc/user.c
index cce820e..609e5ec 100644
--- a/misc/user.c
+++ b/misc/user.c
@@ -17,6 +17,7 @@
extern BOOL ATOM_Init();
extern BOOL GDI_Init();
extern void SYSMETRICS_Init();
+extern BOOL MENU_Init();
extern BOOL WIN_CreateDesktopWindow();
#ifndef WINELIB
@@ -69,6 +70,9 @@
/* Initialize dialog manager */
if (!DIALOG_Init()) return 0;
+ /* Initialize menus */
+ if (!MENU_Init()) return 0;
+
/* Create system message queue */
queueSize = GetProfileInt( "windows", "TypeAhead", 120 );
if (!MSG_CreateSysMsgQueue( queueSize )) return 0;
diff --git a/misc/winsocket.c b/misc/winsocket.c
index cd7fb53..5195e2a 100644
--- a/misc/winsocket.c
+++ b/misc/winsocket.c
@@ -136,8 +136,47 @@
{
wsa_errno = wsaerrno();
}
-
-SOCKET Winsock_accept(SOCKET s, struct sockaddr FAR *addr, INT FAR *addrlen)
+
+static void convert_sockopt(INT *level, INT *optname)
+{
+/* $%#%!@! why couldn't they use the same values for both winsock and unix ? */
+
+ switch (*level) {
+ case -1:
+ *level = SOL_SOCKET;
+ switch (*optname) {
+ case 0x01: *optname = SO_DEBUG;
+ break;
+ case 0x04: *optname = SO_REUSEADDR;
+ break;
+ case 0x08: *optname = SO_KEEPALIVE;
+ break;
+ case 0x10: *optname = SO_DONTROUTE;
+ break;
+ case 0x20: *optname = SO_BROADCAST;
+ break;
+ case 0x80: *optname = SO_LINGER;
+ break;
+ case 0x100: *optname = SO_OOBINLINE;
+ break;
+ case 0x1001: *optname = SO_SNDBUF;
+ break;
+ case 0x1002: *optname = SO_RCVBUF;
+ break;
+ case 0x1007: *optname = SO_ERROR;
+ break;
+ case 0x1008: *optname = SO_TYPE;
+ break;
+ default:
+ fprintf(stderr, "convert_sockopt() unknown optname %d\n", optname);
+ break;
+ }
+ break;
+ case 6: *optname = IPPROTO_TCP;
+ }
+}
+
+SOCKET Winsock_accept(SOCKET s, struct sockaddr *addr, INT *addrlen)
{
int sock;
@@ -152,7 +191,7 @@
return sock;
}
-INT Winsock_bind(SOCKET s, struct sockaddr FAR *name, INT namelen)
+INT Winsock_bind(SOCKET s, struct sockaddr *name, INT namelen)
{
#ifdef DEBUG_WINSOCK
fprintf(stderr, "WSA_bind: socket %d, ptr %8x, length %d\n", s, (int) name, namelen);
@@ -181,7 +220,7 @@
return 0;
}
-INT Winsock_connect(SOCKET s, struct sockaddr FAR *name, INT namelen)
+INT Winsock_connect(SOCKET s, struct sockaddr *name, INT namelen)
{
#ifdef DEBUG_WINSOCK
fprintf(stderr, "WSA_connect: socket %d, ptr %8x, length %d\n", s, (int) name, namelen);
@@ -195,7 +234,7 @@
return 0;
}
-INT Winsock_getpeername(SOCKET s, struct sockaddr FAR *name, INT FAR *namelen)
+INT Winsock_getpeername(SOCKET s, struct sockaddr *name, INT *namelen)
{
#ifdef DEBUG_WINSOCK
fprintf(stderr, "WSA_getpeername: socket: %d, ptr %8x, ptr %8x\n", s, (int) name, *namelen);
@@ -209,7 +248,7 @@
return 0;
}
-INT Winsock_getsockname(SOCKET s, struct sockaddr FAR *name, INT FAR *namelen)
+INT Winsock_getsockname(SOCKET s, struct sockaddr *name, INT *namelen)
{
#ifdef DEBUG_WINSOCK
fprintf(stderr, "WSA_getsockname: socket: %d, ptr %8x, ptr %8x\n", s, (int) name, (int) *namelen);
@@ -221,12 +260,15 @@
return 0;
}
-INT Winsock_getsockopt(SOCKET s, INT loptname, char FAR *optval, INT FAR *optlen)
+INT
+Winsock_getsockopt(SOCKET s, INT level, INT optname, char *optval, INT *optlen)
{
#ifdef DEBUG_WINSOCK
- fprintf(stderr, "WSA_getsockopt: socket: %d, opt %d, ptr %8x, ptr %8x\n", s, loptname, (int) optval, (int) *optlen);
+ fprintf(stderr, "WSA_getsockopt: socket: %d, opt %d, ptr %8x, ptr %8x\n", s, level, (int) optval, (int) *optlen);
#endif
- if (getsockopt(s, 0, (int) loptname, optval, (int *) optlen) < 0) {
+ convert_sockopt(&level, &optname);
+
+ if (getsockopt(s, (int) level, optname, optval, (int *) optlen) < 0) {
errno_to_wsaerrno();
return SOCKET_ERROR;
}
@@ -243,7 +285,7 @@
return( htons(hostshort) );
}
-u_long Winsock_inet_addr(char FAR *cp)
+u_long Winsock_inet_addr(char *cp)
{
return( inet_addr(cp) );
}
@@ -266,7 +308,7 @@
return (char *) &heap->ntoa_buffer;
}
-INT Winsock_ioctlsocket(SOCKET s, long cmd, u_long FAR *argp)
+INT Winsock_ioctlsocket(SOCKET s, long cmd, u_long *argp)
{
#ifdef DEBUG_WINSOCK
fprintf(stderr, "WSA_ioctl: socket %d, cmd %d, ptr %8x\n", s, cmd, (int) argp);
@@ -302,7 +344,7 @@
return( ntohs(netshort) );
}
-INT Winsock_recv(SOCKET s, char FAR *buf, INT len, INT flags)
+INT Winsock_recv(SOCKET s, char *buf, INT len, INT flags)
{
int length;
@@ -317,8 +359,8 @@
return length;
}
-INT Winsock_recvfrom(SOCKET s, char FAR *buf, INT len, INT flags,
- struct sockaddr FAR *from, int FAR *fromlen)
+INT Winsock_recvfrom(SOCKET s, char *buf, INT len, INT flags,
+ struct sockaddr *from, int *fromlen)
{
int length;
@@ -333,8 +375,8 @@
return length;
}
-INT Winsock_select(INT nfds, fd_set FAR *readfds, fd_set FAR *writefds,
- fd_set FAR *exceptfds, struct timeval FAR *timeout)
+INT Winsock_select(INT nfds, fd_set *readfds, fd_set *writefds,
+ fd_set *exceptfds, struct timeval *timeout)
{
#ifdef DEBUG_WINSOCK
fprintf(stderr, "WSA_select: fd # %d, ptr %8x, ptr %8x, ptr %*X\n", nfds, readfds, writefds, exceptfds);
@@ -343,7 +385,7 @@
return(select(nfds, readfds, writefds, exceptfds, timeout));
}
-INT Winsock_send(SOCKET s, char FAR *buf, INT len, INT flags)
+INT Winsock_send(SOCKET s, char *buf, INT len, INT flags)
{
int length;
@@ -358,8 +400,8 @@
return length;
}
-INT Winsock_sendto(SOCKET s, char FAR *buf, INT len, INT flags,
- struct sockaddr FAR *to, INT tolen)
+INT Winsock_sendto(SOCKET s, char *buf, INT len, INT flags,
+ struct sockaddr *to, INT tolen)
{
int length;
@@ -374,13 +416,14 @@
return length;
}
-INT Winsock_setsockopt(SOCKET s, INT level, INT optname, const char FAR *optval,
+INT Winsock_setsockopt(SOCKET s, INT level, INT optname, const char *optval,
INT optlen)
{
#ifdef DEBUG_WINSOCK
fprintf(stderr, "WSA_setsockopt: socket %d, level %d, opt %d, ptr %8x, len %d\n", s, level, optname, (int) optval, optlen);
#endif
-
+ convert_sockopt(&level, &optname);
+
if (setsockopt(s, level, optname, optval, optlen) < 0) {
errno_to_wsaerrno();
return SOCKET_ERROR;
@@ -430,7 +473,7 @@
return sock;
}
-struct hostent *Winsock_gethostbyaddr(const char FAR *addr, INT len, INT type)
+struct hostent *Winsock_gethostbyaddr(const char *addr, INT len, INT type)
{
struct hostent *host;
@@ -447,7 +490,7 @@
return (struct hostent *) &heap->hostent_addr;
}
-struct hostent *Winsock_gethostbyname(const char FAR *name)
+struct hostent *Winsock_gethostbyname(const char *name)
{
struct hostent *host;
@@ -464,7 +507,7 @@
return (struct hostent *) &heap->hostent_name;
}
-int Winsock_gethostname(char FAR *name, INT namelen)
+int Winsock_gethostname(char *name, INT namelen)
{
#ifdef DEBUG_WINSOCK
@@ -478,7 +521,7 @@
return 0;
}
-struct protoent *Winsock_getprotobyname(char FAR *name)
+struct protoent *Winsock_getprotobyname(char *name)
{
struct protoent *proto;
@@ -512,7 +555,7 @@
return (struct protoent *) &heap->protoent_number;
}
-struct servent *Winsock_getservbyname(const char FAR *name, const char FAR *proto)
+struct servent *Winsock_getservbyname(const char *name, const char *proto)
{
struct servent *service;
@@ -529,7 +572,7 @@
return (struct servent *) &heap->servent_name;
}
-struct servent *Winsock_getservbyport(INT port, const char FAR *proto)
+struct servent *Winsock_getservbyport(INT port, const char *proto)
{
struct servent *service;
@@ -597,8 +640,8 @@
}
-HANDLE WSAAsyncGetHostByAddr(HWND hWnd, u_int wMsg, const char FAR *addr,
- INT len, INT type, char FAR *buf, INT buflen)
+HANDLE WSAAsyncGetHostByAddr(HWND hWnd, u_int wMsg, const char *addr,
+ INT len, INT type, char *buf, INT buflen)
{
HANDLE handle;
struct hostent *host;
@@ -619,8 +662,8 @@
}
-HANDLE WSAAsyncGetHostByName(HWND hWnd, u_int wMsg, const char FAR *name,
- char FAR *buf, INT buflen)
+HANDLE WSAAsyncGetHostByName(HWND hWnd, u_int wMsg, const char *name,
+ char *buf, INT buflen)
{
HANDLE handle;
struct hostent *host;
@@ -641,8 +684,8 @@
}
-HANDLE WSAAsyncGetProtoByName(HWND hWnd, u_int wMsg, const char FAR *name,
- char FAR *buf, INT buflen)
+HANDLE WSAAsyncGetProtoByName(HWND hWnd, u_int wMsg, const char *name,
+ char *buf, INT buflen)
{
HANDLE handle;
struct protoent *proto;
@@ -664,7 +707,7 @@
HANDLE WSAAsyncGetProtoByNumber(HWND hWnd, u_int wMsg, INT number,
- char FAR *buf, INT buflen)
+ char *buf, INT buflen)
{
HANDLE handle;
struct protoent *proto;
@@ -685,8 +728,8 @@
}
-HANDLE WSAAsyncGetServByName(HWND hWnd, u_int wMsg, const char FAR *name,
- const char FAR *proto, char FAR *buf, INT buflen)
+HANDLE WSAAsyncGetServByName(HWND hWnd, u_int wMsg, const char *name,
+ const char *proto, char *buf, INT buflen)
{
HANDLE handle;
struct servent *service;
@@ -707,8 +750,8 @@
}
-HANDLE WSAAsyncGetServByPort(HWND hWnd, u_int wMsg, INT port, const char FAR
- *proto, char FAR *buf, INT buflen)
+HANDLE WSAAsyncGetServByPort(HWND hWnd, u_int wMsg, INT port, const char
+ *proto, char *buf, INT buflen)
{
HANDLE handle;
struct servent *service;
diff --git a/miscemu/emulate.c b/miscemu/emulate.c
index 1b69503..78b49a9 100644
--- a/miscemu/emulate.c
+++ b/miscemu/emulate.c
@@ -28,19 +28,19 @@
}
-int
+void
WIN87_WinEm87Info(struct Win87EmInfoStruct *pWIS, int cbWin87EmInfoStruct)
{
printf( "__WinEm87Info(%p,%d)\n",pWIS,cbWin87EmInfoStruct);
}
-int
+void
WIN87_WinEm87Restore(void *pWin87EmSaveArea, int cbWin87EmSaveArea)
{
printf( "__WinEm87Restore(%p,%d)\n",pWin87EmSaveArea,cbWin87EmSaveArea);
}
-int
+void
WIN87_WinEm87Save(void *pWin87EmSaveArea, int cbWin87EmSaveArea)
{
printf( "__WinEm87Save(%p,%d)\n",pWin87EmSaveArea,cbWin87EmSaveArea);
diff --git a/miscemu/int10.c b/miscemu/int10.c
index 1d49f5e..632f279 100644
--- a/miscemu/int10.c
+++ b/miscemu/int10.c
@@ -1,6 +1,6 @@
#include <stdio.h>
#include <stdlib.h>
-#include "msdos.h"
+#include "registers.h"
#include "wine.h"
void IntBarf(int i, struct sigcontext_struct *context)
@@ -13,23 +13,22 @@
int do_int10(struct sigcontext_struct *context)
{
- switch((context->sc_eax >> 8) & 0xff)
- {
+ switch(AH) {
case 0x0f:
- EAX = (EAX & 0xffffff00) | 0x5b;
+ AL = 0x5b;
break;
case 0x12:
- if ((EBX & 0xff) == 0x10) {
- EBX = (EBX & 0xffff0000) | 0x0003;
- ECX = (ECX & 0xffff0000) | 0x0009;
+ if (BL == 0x10) {
+ BX = 0x0003;
+ CX = 0x0009;
}
break;
case 0x1a:
- EBX = (EBX & 0xffff0000) | 0x0008;
+ BX = 0x0008;
break;
-
+
default:
IntBarf(0x10, context);
};
diff --git a/miscemu/int13.c b/miscemu/int13.c
index 55fb5b2..8fb128e 100644
--- a/miscemu/int13.c
+++ b/miscemu/int13.c
@@ -1,29 +1,28 @@
#include <stdio.h>
#include <stdlib.h>
-#include "msdos.h"
+#include "registers.h"
#include "wine.h"
int do_int13(struct sigcontext_struct *context)
{
- switch((context->sc_eax >> 8) & 0xff)
- {
+ switch(AH) {
case 0x00: /* RESET DISK SYSTEM */
case 0x04: /* VERIFY DISK SECTOR(S) */
- EAX = (EAX & 0xffff00ff);
+ AH = 0;
break;
case 0x05: /* FORMAT TRACK */
- EAX = (EAX & 0xffff00ff) | 0x0c;
+ AH = 0x0c;
SetCflag;
break;
case 0x06: /* FORMAT TRACK AND SET BAD SECTOR FLAGS */
case 0x07: /* FORMAT DRIVE STARTING AT GIVEN TRACK */
- EAX = (EAX & 0xffff00ff) | 0x0c;
+ AH = 0x0c;
break;
case 0x08: /* GET DRIVE PARAMETERS */
- EAX = (EAX & 0xffff00ff) | ((EDX & 0x00000080)? 0x07: 0x01);
+ AH = (DL & 0x80) ? 0x07 : 0x01;
SetCflag;
break;
@@ -33,20 +32,17 @@
case 0x10: /* CHECK IF DRIVE READY */
case 0x11: /* RECALIBRATE DRIVE */
case 0x14: /* CONTROLLER INTERNAL DIAGNOSTIC */
- EAX = (EAX & 0xffff00ff);
+ AH = 0;
break;
case 0x0e: /* READ SECTOR BUFFER (XT only) */
case 0x0f: /* WRITE SECTOR BUFFER (XT only) */
case 0x12: /* CONTROLLER RAM DIAGNOSTIC (XT,PS) */
case 0x13: /* DRIVE DIAGNOSTIC (XT,PS) */
- EAX = (EAX & 0xffff00ff) | 0x01;
+ AH = 0x01;
SetCflag;
break;
-
-
-
default:
IntBarf(0x13, context);
};
diff --git a/miscemu/int15.c b/miscemu/int15.c
index 054a7e3..67a0b7a 100644
--- a/miscemu/int15.c
+++ b/miscemu/int15.c
@@ -1,12 +1,11 @@
#include <stdio.h>
#include <stdlib.h>
-#include "msdos.h"
+#include "registers.h"
#include "wine.h"
int do_int15(struct sigcontext_struct *context)
{
- switch((context->sc_eax >> 8) & 0xff)
- {
+ switch(AH) {
case 0xc0:
default:
diff --git a/miscemu/int16.c b/miscemu/int16.c
index 88ff49d..33ecef5 100644
--- a/miscemu/int16.c
+++ b/miscemu/int16.c
@@ -1,12 +1,11 @@
#include <stdio.h>
#include <stdlib.h>
-#include "msdos.h"
+#include "registers.h"
#include "wine.h"
int do_int16(struct sigcontext_struct *context)
{
- switch((context->sc_eax >> 8) & 0xff)
- {
+ switch(AH) {
case 0xc0:
default:
diff --git a/miscemu/int1a.c b/miscemu/int1a.c
index 95b19bd..f43fef3 100644
--- a/miscemu/int1a.c
+++ b/miscemu/int1a.c
@@ -1,7 +1,7 @@
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
-#include "msdos.h"
+#include "registers.h"
#include "wine.h"
#include "options.h"
@@ -23,13 +23,13 @@
AX, BX, CX, DX, SI, DI, DS, ES);
}
- switch((context->sc_eax >> 8) & 0xff){
+ switch(AH) {
case 0:
ltime = time(NULL);
ticks = (int) (ltime * HZ);
- context->sc_ecx = ticks >> 16;
- context->sc_edx = ticks & 0x0000FFFF;
- context->sc_eax = 0; /* No midnight rollover */
+ CX = ticks >> 16;
+ DX = ticks & 0x0000FFFF;
+ AX = 0; /* No midnight rollover */
printf("int1a_00 // ltime=%ld ticks=%ld\n", ltime, ticks);
break;
@@ -37,14 +37,14 @@
ltime = time(NULL);
bdtime = localtime(<ime);
- context->sc_ecx = (BIN_TO_BCD(bdtime->tm_hour)<<8) | BIN_TO_BCD(bdtime->tm_min);
- context->sc_edx = (BIN_TO_BCD(bdtime->tm_sec)<<8);
+ CX = (BIN_TO_BCD(bdtime->tm_hour)<<8) | BIN_TO_BCD(bdtime->tm_min);
+ DX = (BIN_TO_BCD(bdtime->tm_sec)<<8);
case 4:
ltime = time(NULL);
bdtime = localtime(<ime);
- context->sc_ecx = (BIN_TO_BCD(bdtime->tm_year/100)<<8) | BIN_TO_BCD((bdtime->tm_year-1900)%100);
- context->sc_edx = (BIN_TO_BCD(bdtime->tm_mon)<<8) | BIN_TO_BCD(bdtime->tm_mday);
+ CX = (BIN_TO_BCD(bdtime->tm_year/100)<<8) | BIN_TO_BCD((bdtime->tm_year-1900)%100);
+ DX = (BIN_TO_BCD(bdtime->tm_mon)<<8) | BIN_TO_BCD(bdtime->tm_mday);
break;
/* setting the time,date or RTC is not allow -EB */
diff --git a/miscemu/int21.c b/miscemu/int21.c
index 2485f59..5ed34e0 100644
--- a/miscemu/int21.c
+++ b/miscemu/int21.c
@@ -7,15 +7,20 @@
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
+#include <sys/file.h>
#include <string.h>
#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
#include <unistd.h>
#include <utime.h>
+#include <ctype.h>
#include "prototypes.h"
#include "regfunc.h"
#include "windows.h"
#include "wine.h"
#include "msdos.h"
+#include "registers.h"
#include "options.h"
WORD ExtendedError, CodePage = 437;
@@ -29,6 +34,9 @@
};
static struct DosHeap *heap;
+WORD sharing_retries = 3; /* number of retries at sharing violation */
+WORD sharing_pause = 1; /* pause between retries */
+
extern char TempDirectory[];
static int Error(int e, int class, int el)
@@ -41,7 +49,7 @@
return e;
}
-static void errno_to_doserr(void)
+void errno_to_doserr(void)
{
switch (errno) {
case EAGAIN:
@@ -138,28 +146,28 @@
int drive;
long size,available;
- if (!(EDX & 0xff))
+ if (DL == 0)
drive = DOS_GetDefaultDrive();
else
- drive = (EDX & 0xff) - 1;
+ drive = DL - 1;
if (!DOS_ValidDrive(drive)) {
Error(InvalidDrive, EC_MediaError , EL_Disk);
- EAX |= 0xffffL;
+ AX = 0xffff;
return;
}
if (!DOS_GetFreeSpace(drive, &size, &available)) {
Error(GeneralFailure, EC_MediaError , EL_Disk);
- EAX |= 0xffffL;
+ AX = 0xffff;
return;
}
- EAX = (EAX & 0xffff0000) | 4;
- ECX = (ECX & 0xffff0000) | 512;
+ AX = 4;
+ CX = 512;
- EBX = (EBX & 0xffff0000) | (available / (CX * AX));
- EDX = (EDX & 0xffff0000) | (size / (CX * AX));
+ BX = (available / (CX * AX));
+ DX = (size / (CX * AX));
Error (0,0,0);
}
@@ -169,43 +177,41 @@
long size, available;
BYTE mediaID;
- drive = EDX & 0xffL;
-
- if (!DOS_ValidDrive(drive)) {
- EAX = (EAX & 0xffff0000) | 4;
- ECX = (ECX & 0xffff0000) | 512;
- EDX = (EDX & 0xffff0000);
+ if (!DOS_ValidDrive(DL)) {
+ AX = 4;
+ CX = 512;
+ DX = 0;
Error (InvalidDrive, EC_MediaError, EL_Disk);
return;
}
- if (!DOS_GetFreeSpace(drive, &size, &available)) {
+ if (!DOS_GetFreeSpace(DL, &size, &available)) {
Error(GeneralFailure, EC_MediaError , EL_Disk);
- EAX |= 0xffffL;
+ AX = 0xffff;
return;
}
- EAX = (EAX & 0xffff0000) | 4;
- ECX = (ECX & 0xffff0000) | 512;
- EDX = (EDX & 0xffff0000) | (size / (CX * AX));
+ EAX = 4;
+ ECX = 512;
+ EDX = (size / (CX * AX));
mediaID = 0xf0;
DS = segment(mediaID);
- EBX = offset(mediaID);
+ BX = offset(mediaID);
Error (0,0,0);
}
static void GetDefDriveAllocInfo(struct sigcontext_struct *context)
{
- EDX = DOS_GetDefaultDrive();
+ DX = DOS_GetDefaultDrive();
GetDriveAllocInfo(context);
}
static void GetDrivePB(struct sigcontext_struct *context)
{
Error (InvalidDrive, EC_MediaError, EL_Disk);
- EAX = (EAX & 0xffff0000) | 0xffL;
+ AX = 0x00ff;
/* I'm sorry but I only got networked drives :-) */
}
@@ -217,7 +223,7 @@
/* can't read from stdout / stderr */
if ((BX == 1) || (BX == 2)) {
Error (InvalidHandle, EL_Unknown, EC_Unknown);
- EAX = (EAX & 0xffff0000) | InvalidHandle;
+ AX = InvalidHandle;
SetCflag;
return;
}
@@ -226,19 +232,19 @@
if (BX == 0) {
*ptr = EOF;
Error (0,0,0);
- EAX = (EAX & 0xffff0000) | 1;
+ AX = 1;
ResetCflag;
return;
} else {
size = read(BX, ptr, CX);
if (size == -1) {
errno_to_doserr();
- EAX = (EAX & 0xffffff00) | ExtendedError;
+ AL = ExtendedError;
SetCflag;
return;
}
Error (0,0,0);
- EAX = (EAX & 0xffff0000) | size;
+ AX = size;
ResetCflag;
}
}
@@ -264,24 +270,24 @@
fflush(stderr);
Error (0,0,0);
- EAX = (EAX & 0xffffff00) | CX;
+ AL = CX;
ResetCflag;
} else {
size = write(BX, ptr , CX);
if (size == 0) {
Error (WriteFault, EC_Unknown, EL_Unknown);
- EAX = (EAX & 0xffffff00) | ExtendedError;
+ AL = ExtendedError;
return;
}
if (size == -1) {
errno_to_doserr();
- EAX = (EAX & 0xffffff00) | ExtendedError;
+ AL = ExtendedError;
SetCflag;
return;
}
Error (0,0,0);
- EAX = (EAX & 0xffff0000) | size;
+ AX = size;
ResetCflag;
}
}
@@ -290,7 +296,7 @@
{
off_t status, fileoffset;
- switch (EAX & 0xff) {
+ switch (AL) {
case 1: fileoffset = SEEK_CUR;
break;
case 2: fileoffset = SEEK_END;
@@ -302,41 +308,39 @@
status = lseek(BX, (CX * 0x100) + DX, fileoffset);
if (status == -1) {
errno_to_doserr();
- EAX = (EAX & 0xffffff00) | ExtendedError; SetCflag;
+ AL = ExtendedError; SetCflag;
return;
}
Error (0,0,0);
- EAX = (EAX & 0xffff0000L) | (status & 0xffff);
- EDX = (EDX & 0xffff0000L) | ((status >> 16) & 0xffff);
-
+ AX = (status & 0xffff);
+ DX = ((status >> 16) & 0xffff);
+
ResetCflag;
}
static void ioctlGetDeviceInfo(struct sigcontext_struct *context)
{
- WORD handle = EBX & 0xffff;
-
- switch (handle) {
+ switch (BX) {
case 0:
case 1:
case 2:
- EDX = (EDX & 0xffff0000) | 0x80d3;
+ DX = 0x80d3;
break;
default:
{
struct stat sbuf;
- if (fstat(handle, &sbuf) < 0)
+ if (fstat(BX, &sbuf) < 0)
{
IntBarf(0x21, context);
- EDX = (EDX & 0xffff0000) | 0x50;
+ DX = 0x50;
SetCflag;
return;
}
/* This isn't the right answer, but should be close enough. */
- EDX = (EDX & 0xffff0000) | 0x0943;
+ DX = 0x0943;
}
}
ResetCflag;
@@ -347,16 +351,16 @@
BYTE *dataptr = pointer(DS, DX);
int drive;
- if (!(EBX & 0xff))
+ if (BL == 0)
drive = DOS_GetDefaultDrive();
else
- drive = (EBX & 0xff) - 1;
+ drive = BL - 1;
- if ((ECX & 0xff00) != 0x0800) {
+ if (CH != 0x08) {
IntBarf(0x21, context);
return;
}
- switch (ECX & 0xff) {
+ switch (CL) {
case 0x60: /* get device parameters */
/* used by w4wgrp's winfile */
dataptr[0] = 0x04;
@@ -374,7 +378,7 @@
setword(&dataptr[4], 80); /* # of cylinders */
}
CreateBPB(drive, &dataptr[7]);
- EAX = (EAX & 0xfffff00);
+ AL = 0;
ResetCflag;
return;
default:
@@ -390,50 +394,52 @@
ltime = time(NULL);
now = localtime(<ime);
- ECX = (ECX & 0xffff0000) | (now->tm_year + 1900);
- EDX = (EDX & 0xffff0000) | ((now->tm_mon + 1) << 8) | now->tm_mday;
- EAX = (EAX & 0xffff0000) | now->tm_wday;
+ CX = now->tm_year + 1900;
+ DX = ((now->tm_mon + 1) << 8) | now->tm_mday;
+ AX = now->tm_wday;
}
static void GetSystemTime(struct sigcontext_struct *context)
{
struct tm *now;
- time_t ltime;
+ struct timeval tv;
- ltime = time(NULL);
- now = localtime(<ime);
+ gettimeofday(&tv,NULL); /* Note use of gettimeofday(), instead of time() */
+ now = localtime(&tv.tv_sec);
- ECX = (ECX & 0xffffff00) | (now->tm_hour << 8) | now->tm_min;
- EDX = (EDX & 0xffffff00) | now->tm_sec << 8;
+ CX = (now->tm_hour<<8) | now->tm_min;
+ DX = (now->tm_sec<<8) | tv.tv_usec/10000;
+ /* Note hundredths of seconds */
}
static void GetExtendedErrorInfo(struct sigcontext_struct *context)
{
- EAX = (EAX & 0xffffff00) | ExtendedError;
- EBX = (EBX & 0xffff0000) | (ErrorClass << 8) | Action;
- ECX = (ECX & 0xffff00ff) | (ErrorLocus << 8);
+ AL = ExtendedError;
+ BX = (ErrorClass << 8) | Action;
+ CH = ErrorLocus << 8;
}
static void CreateFile(struct sigcontext_struct *context)
{
int handle;
- if ((handle = open(GetUnixFileName( pointer(DS,DX)), O_CREAT | O_TRUNC)) == -1) {
+ if ((handle = open(GetUnixFileName( pointer(DS,DX)),
+ O_CREAT | O_TRUNC | O_RDWR )) == -1) {
errno_to_doserr();
- EAX = (EAX & 0xffffff00) | ExtendedError;
+ AL = ExtendedError;
SetCflag;
return;
}
Error (0,0,0);
- EBX = (EBX & 0xffff0000) | handle;
- EAX = (EAX & 0xffffff00) | NoError;
+ EAX = (EAX & 0xffff0000) | handle;
ResetCflag;
}
-static void OpenExistingFile(struct sigcontext_struct *context)
+void OpenExistingFile(struct sigcontext_struct *context)
{
int handle;
int mode;
+ int lock;
switch (AX & 0x0007)
{
@@ -450,16 +456,66 @@
break;
}
- fprintf(stderr,"OpenExistingFile (%s)\n", pointer(DS,DX));
-
if ((handle = open(GetUnixFileName(pointer(DS,DX)), mode)) == -1) {
errno_to_doserr();
- EAX = (EAX & 0xffffff00) | ExtendedError;
+ AL = ExtendedError;
SetCflag;
return;
}
+
+ switch (AX & 0x0070)
+ {
+ case 0x00: /* compatability mode */
+ case 0x40: /* DENYNONE */
+ lock = -1;
+ break;
+
+ case 0x30: /* DENYREAD */
+ fprintf(stderr,
+ "OpenExistingFile (%s): DENYREAD changed to DENYALL\n",
+ pointer(DS,DX));
+ case 0x10: /* DENYALL */
+ lock = LOCK_EX;
+ break;
+
+ case 0x20: /* DENYWRITE */
+ lock = LOCK_SH;
+ break;
+
+ default:
+ lock = -1;
+ }
+
+ if (lock != -1)
+ {
+
+ int result,retries=sharing_retries;
+ {
+ result = flock(handle, lock | LOCK_NB);
+ if ( retries && (!result) )
+ {
+ int i;
+ for(i=0;i<32768*((int)sharing_pause);i++)
+ result++; /* stop the optimizer */
+ for(i=0;i<32768*((int)sharing_pause);i++)
+ result--;
+ }
+ }
+ while( (!result) && (!(retries--)) );
+
+ if(result)
+ {
+ errno_to_doserr();
+ EAX = (EAX & 0xffffff00) | ExtendedError;
+ close(handle);
+ SetCflag;
+ return;
+ }
+
+ }
+
Error (0,0,0);
- EAX = (EBX & 0xffff0000) | handle;
+ EAX = (EAX & 0xffff0000) | handle;
ResetCflag;
}
@@ -467,12 +523,12 @@
{
if (close(BX) == -1) {
errno_to_doserr();
- EAX = (EAX & 0xffffff00) | ExtendedError;
+ AL = ExtendedError;
SetCflag;
return;
}
Error (0,0,0);
- EAX = (EAX & 0xffffff00) | NoError;
+ AL = NoError;
ResetCflag;
}
@@ -498,13 +554,13 @@
fprintf(stderr,"int21: makedir %s\n", pointer(DS,DX) );
if ((dirname = GetUnixFileName( pointer(DS,DX) ))== NULL) {
- EAX = (EAX & 0xffffff00) | CanNotMakeDir;
+ AL = CanNotMakeDir;
SetCflag;
return;
}
if (mkdir(dirname,0) == -1) {
- EAX = (EAX & 0xffffff00) | CanNotMakeDir;
+ AL = CanNotMakeDir;
SetCflag;
return;
}
@@ -531,19 +587,19 @@
fprintf(stderr,"int21: removedir %s\n", pointer(DS,DX) );
if ((dirname = GetUnixFileName( pointer(DS,DX) ))== NULL) {
- EAX = (EAX & 0xffffff00) | CanNotMakeDir;
+ AL = CanNotMakeDir;
SetCflag;
return;
}
/*
if (strcmp(unixname,DosDrives[drive].CurrentDirectory)) {
- EAX = (EAX & 0xffffff00) | CanNotRemoveCwd;
+ AL = CanNotRemoveCwd;
SetCflag;
}
*/
if (rmdir(dirname) == -1) {
- EAX = (EAX & 0xffffff00) | CanNotMakeDir;
+ AL = CanNotMakeDir;
SetCflag;
}
ResetCflag;
@@ -558,23 +614,23 @@
{
struct dosdirent *dp;
- dp = (struct dosdirent *)(dta + 0x0d);
+ memcpy(&dp, dta+0x0d, sizeof(dp));
do {
if ((dp = DOS_readdir(dp)) == NULL) {
Error(NoMoreFiles, EC_MediaError , EL_Disk);
- EAX = (EAX & 0xffffff00) | NoMoreFiles;
+ AL = NoMoreFiles;
SetCflag;
return;
}
} while (*(dta + 0x0c) != dp->attribute);
-
+
setword(&dta[0x16], 0x1234); /* time */
setword(&dta[0x18], 0x1234); /* date */
setdword(&dta[0x1a], dp->filesize);
strncpy(dta + 0x1e, dp->filename, 13);
- EAX = (EAX & 0xffffff00);
+ AL;
ResetCflag;
return;
}
@@ -589,7 +645,7 @@
if (!DOS_ValidDrive(drive)) {
Error(InvalidDrive, EC_MediaError , EL_Disk);
- EAX = (EAX & 0xffffff00L) | InvalidDrive;
+ AL = InvalidDrive;
SetCflag;
return;
}
@@ -606,14 +662,14 @@
if (DOS_GetVolumeLabel(drive) != NULL)
strncpy(dta + 0x1e, DOS_GetVolumeLabel(drive), 8);
- EAX = (EAX & 0xffffff00L);
+ AL = 0;
ResetCflag;
return;
}
if ((dp = DOS_opendir(path)) == NULL) {
Error(PathNotFound, EC_MediaError, EL_Disk);
- EAX = (EAX & 0xffffff00L) | FileNotFound;
+ AL = FileNotFound;
SetCflag;
return;
}
@@ -629,7 +685,7 @@
struct tm *now;
if ((filename = GetUnixFileName( pointer(DS,DX) ))== NULL) {
- EAX = (EAX & 0xffffff00) | FileNotFound;
+ AL = FileNotFound;
SetCflag;
return;
}
@@ -637,8 +693,8 @@
now = localtime (&filestat.st_mtime);
- ECX = (ECX & 0xffff0000) | ((now->tm_hour * 0x2000) + (now->tm_min * 0x20) + now->tm_sec/2);
- EDX = (EDX & 0xffff0000) | ((now->tm_year * 0x200) + (now->tm_mon * 0x20) + now->tm_mday);
+ CX = ((now->tm_hour * 0x2000) + (now->tm_min * 0x20) + now->tm_sec/2);
+ DX = ((now->tm_year * 0x200) + (now->tm_mon * 0x20) + now->tm_mday);
ResetCflag;
}
@@ -669,14 +725,14 @@
handle = open(GetUnixFileName(temp), O_CREAT | O_TRUNC | O_RDWR);
if (handle == -1) {
- EAX = (EAX & 0xffffff00) | WriteProtected;
+ AL = WriteProtected;
SetCflag;
return;
}
strcpy(pointer(DS,DX), temp);
- EAX = (EAX & 0xffff0000) | handle;
+ AX = handle;
ResetCflag;
}
@@ -684,13 +740,13 @@
{
int handle;
- if ((handle = open(GetUnixFileName( pointer(DS,DX) ), O_CREAT | O_TRUNC | O_RDWR)) == -1) {
- EAX = (EAX & 0xffffff00) | WriteProtected;
+ if ((handle = open(GetUnixFileName( pointer(DS,DX) ), O_CREAT | O_EXCL | O_RDWR)) == -1) {
+ AL = WriteProtected;
SetCflag;
return;
}
- EAX = (EAX & 0xffff0000) | handle;
+ AX = handle;
ResetCflag;
}
@@ -698,13 +754,13 @@
{
int drive;
- if ((EDX & 0xff) == 0)
+ if (DL == 0)
drive = DOS_GetDefaultDrive();
else
- drive = (EDX & 0xff)-1;
+ drive = DL - 1;
if (!DOS_ValidDrive(drive)) {
- EAX = (EAX & 0xffffff00) | InvalidDrive;
+ AL = InvalidDrive;
SetCflag;
return;
}
@@ -719,13 +775,13 @@
BYTE *dataptr = pointer(DS, DX);
DWORD serialnumber;
- if ((EBX & 0xff) == 0)
+ if (BL == 0)
drive = DOS_GetDefaultDrive();
else
- drive = (EBX & 0xff) - 1;
+ drive = BL - 1;
if (!DOS_ValidDrive(drive)) {
- EAX = (EAX & 0xffffff00) |InvalidDrive;
+ AL =InvalidDrive;
SetCflag;
return;
}
@@ -737,7 +793,7 @@
strncpy(dataptr + 6, DOS_GetVolumeLabel(drive), 8);
strncpy(dataptr + 0x11, "FAT16 ", 8);
- EAX = (EAX & 0xffffff00);
+ AL;
ResetCflag;
}
@@ -747,13 +803,13 @@
BYTE *dataptr = pointer(DS, DX);
DWORD serialnumber;
- if ((EBX & 0xff) == 0)
+ if (BL == 0)
drive = DOS_GetDefaultDrive();
else
- drive = (EBX & 0xff) - 1;
+ drive = BL - 1;
if (!DOS_ValidDrive(drive)) {
- EAX = (EAX & 0xffffff00) | InvalidDrive;
+ AL = InvalidDrive;
SetCflag;
return;
}
@@ -762,7 +818,7 @@
(dataptr[4] << 24);
DOS_SetSerialNumber(drive, serialnumber);
- EAX = (EAX & 0xffffff00) | 1L;
+ AL = 1L;
ResetCflag;
}
@@ -803,7 +859,7 @@
strncpy(dta, DOS_GetVolumeLabel(drive), 8);
*(dta + 0x0b) = FA_DIREC;
- EAX = (EAX & 0xffffff00);
+ AL;
return;
}
}
@@ -833,7 +889,7 @@
if ((dp = DOS_opendir(temp)) == NULL) {
Error(InvalidDrive, EC_MediaError , EL_Disk);
- EAX = (EAX & 0xffffff00) | 0xffL;
+ AL = 0xffL;
return;
}
@@ -849,7 +905,7 @@
/* unlink(GetUnixFileName(temp)); */
}
DOS_closedir(dp);
- EAX = (EAX & 0xffffff00);
+ AL;
}
static void RenameFileFCB(struct sigcontext_struct *context)
@@ -875,7 +931,7 @@
if ((dp = DOS_opendir(temp)) == NULL) {
Error(InvalidDrive, EC_MediaError , EL_Disk);
- EAX = (EAX & 0xffffff00) | 0xffL;
+ AL = 0xffL;
return;
}
@@ -894,15 +950,95 @@
fprintf(stderr, "int21: renamefile %s -> %s\n", oldname, newname);
}
DOS_closedir(dp);
- EAX = (EAX & 0xffffff00);
+ AL;
}
+
+
+static void fLock (struct sigcontext_struct * context)
+{
+ struct flock f;
+ int result,retries=sharing_retries;
+
+ f.l_start = MAKELONG(DX,CX);
+ f.l_len = MAKELONG(DI,SI);
+ f.l_whence = 0;
+ f.l_pid = 0;
+
+ switch ( AX & 0xff )
+ {
+ case 0x00: /* LOCK */
+ f.l_type = F_WRLCK;
+ break;
+
+ case 0x01: /* UNLOCK */
+ f.l_type = F_UNLCK;
+ break;
+
+ default:
+ EAX = (EAX & 0xffff0000) | 0x0001;
+ SetCflag;
+ return;
+ }
+
+ {
+ result = fcntl(BX,F_SETLK,&f);
+ if ( retries && (!result) )
+ {
+ int i;
+ for(i=0;i<32768*((int)sharing_pause);i++)
+ result++; /* stop the optimizer */
+ for(i=0;i<32768*((int)sharing_pause);i++)
+ result--;
+ }
+ }
+ while( (!result) && (!(retries--)) );
+
+ if(result)
+ {
+ errno_to_doserr();
+ EAX = (EAX & 0xffffff00) | ExtendedError;
+ SetCflag;
+ return;
+ }
+
+ Error (0,0,0);
+ ResetCflag;
+}
+
+
+static void GetFileAttribute (struct sigcontext_struct * context)
+{
+ char *filename = pointer (DS,DX);
+ struct stat s;
+ int res,cx;
+
+ res = stat(GetUnixFileName(filename), &s);
+ if (res==-1)
+ {
+ errno_to_doserr();
+ EAX = (EAX & 0xffffff00) | ExtendedError;
+ SetCflag;
+ return;
+ }
+
+ cx = 0;
+ if (S_ISDIR(s.st_mode))
+ cx|=0x10;
+ if ((S_IWRITE & s.st_mode) != S_IWRITE)
+ cx|=0x01;
+
+ ECX = (ECX & 0xffff0000) | cx;
+ ResetCflag;
+ Error (0,0,0);
+}
+
+
+
/************************************************************************/
int do_int21(struct sigcontext_struct * context)
{
- int ah;
-
if (Options.relay_debug)
{
printf("int21: AX %04x, BX %04x, CX %04x, DX %04x, "
@@ -910,9 +1046,7 @@
AX, BX, CX, DX, SI, DI, DS, ES);
}
- ah = (EAX >> 8) & 0xffL;
-
- if (ah == 0x59)
+ if (AH == 0x59)
{
GetExtendedErrorInfo(context);
return 1;
@@ -920,7 +1054,7 @@
else
{
Error (0,0,0);
- switch(ah)
+ switch(AH)
{
case 0x00: /* TERMINATE PROGRAM */
exit(0);
@@ -970,17 +1104,21 @@
EAX &= 0xff00;
break;
+ case 0x5c: /* "FLOCK" - RECORD LOCKING */
+ fLock(context);
+ break;
+
case 0x0d: /* DISK BUFFER FLUSH */
ResetCflag; /* dos 6+ only */
break;
case 0x0e: /* SELECT DEFAULT DRIVE */
- if (!DOS_ValidDrive(EDX & 0xff)) {
+ if (!DOS_ValidDrive(DL)) {
Error (InvalidDrive, EC_MediaError, EL_Disk);
return;
} else {
- DOS_SetDefaultDrive(EDX & 0xff);
- EAX = (EAX &0xffffff00) | MAX_DOS_DRIVES;
+ DOS_SetDefaultDrive(DL);
+ AX = MAX_DOS_DRIVES;
Error(0,0,0);
}
break;
@@ -998,7 +1136,7 @@
break;
case 0x19: /* GET CURRENT DEFAULT DRIVE */
- EAX = (EAX & 0xffffff00) | DOS_GetDefaultDrive();
+ AL = DOS_GetDefaultDrive();
Error (0,0,0);
break;
@@ -1020,7 +1158,7 @@
case 0x25: /* SET INTERRUPT VECTOR */
/* Ignore any attempt to set a segment vector */
- fprintf(stderr, "int21: set interrupt vector %2x (%04x:%04x)\n", AX & 0xff, DS, DX);
+ fprintf(stderr, "int21: set interrupt vector %2x (%04x:%04x)\n", AL, DS, DX);
break;
case 0x2a: /* GET SYSTEM DATE */
@@ -1033,13 +1171,13 @@
case 0x2f: /* GET DISK TRANSFER AREA ADDRESS */
ES = segment(dta);
- EBX = (EBX & 0xffff0000) | offset(dta);
+ BX = offset(dta);
break;
case 0x30: /* GET DOS VERSION */
- EAX = (EAX & 0xffff0000) | DOSVERSION;
- EBX = (EBX & 0xffff0000) | 0x0012; /* 0x123456 is Wine's serial # */
- ECX = (ECX & 0xffff0000) | 0x3456;
+ AX = DOSVERSION;
+ BX = 0x0012; /* 0x123456 is Wine's serial # */
+ CX = 0x3456;
break;
case 0x31: /* TERMINATE AND STAY RESIDENT */
@@ -1051,9 +1189,9 @@
break;
case 0x33: /* MULTIPLEXED */
- switch (EAX & 0xff) {
+ switch (AL) {
case 0x00: /* GET CURRENT EXTENDED BREAK STATE */
- if (!(EAX & 0xff))
+ if (!(AL))
EDX &= 0xff00L;
break;
@@ -1061,11 +1199,11 @@
break;
case 0x02: /* GET AND SET EXTENDED CONTROL-BREAK CHECKING STATE*/
- EDX &= 0xff00L;
+ DL = 0;
break;
case 0x05: /* GET BOOT DRIVE */
- EDX = (EDX & 0xff00) | 2;
+ DL = 2;
/* c: is Wine's bootdrive */
break;
@@ -1081,8 +1219,8 @@
break;
case 0x34: /* GET ADDRESS OF INDOS FLAG */
- ES = (ES & 0xffff0000) | segment(heap->InDosFlag);
- EBX = (EBX & 0xffff0000) | offset(heap->InDosFlag);
+ ES = segment(heap->InDosFlag);
+ BX = offset(heap->InDosFlag);
break;
case 0x35: /* GET INTERRUPT VECTOR */
@@ -1090,7 +1228,7 @@
if anyone ever tries to use it */
fprintf(stderr, "int21: get interrupt vector %2x\n", AX & 0xff);
ES = 0;
- EBX = 0;
+ BX = 0;
break;
case 0x36: /* GET FREE DISK SPACE */
@@ -1098,8 +1236,7 @@
break;
case 0x38: /* GET COUNTRY-SPECIFIC INFORMATION */
- EAX &= 0xff00;
- EAX |= 0x02; /* no country support available */
+ AX = 0x02; /* no country support available */
SetCflag;
break;
@@ -1138,7 +1275,7 @@
case 0x41: /* "UNLINK" - DELETE FILE */
if (unlink( GetUnixFileName( pointer(DS,DX)) ) == -1) {
errno_to_doserr();
- EAX = (EAX & 0xffffff00) | ExtendedError;
+ AL = ExtendedError;
SetCflag;
return;
}
@@ -1151,11 +1288,10 @@
break;
case 0x43: /* FILE ATTRIBUTES */
- switch (EAX & 0xff)
+ switch (AL)
{
case 0x00:
- EAX &= 0xfffff00L;
- ResetCflag;
+ GetFileAttribute(context);
break;
case 0x01:
ResetCflag;
@@ -1164,18 +1300,27 @@
break;
case 0x44: /* IOCTL */
- switch (EAX & 0xff)
+ switch (AL)
{
case 0x00:
ioctlGetDeviceInfo(context);
break;
case 0x09: /* CHECK IF BLOCK DEVICE REMOTE */
- EDX = (EDX & 0xffff0000) | (1<<9) | (1<<12);
+ EDX = (EDX & 0xffff0000) | (1<<9) | (1<<12) | (1<<15);
ResetCflag;
break;
case 0x0b: /* SET SHARING RETRY COUNT */
+ if (!CX)
+ {
+ EAX = (EAX & 0xffff0000) | 0x0001;
+ SetCflag;
+ break;
+ }
+ sharing_pause = CX;
+ if (!DX)
+ sharing_retries = DX;
ResetCflag;
break;
@@ -1191,13 +1336,13 @@
case 0x45: /* "DUP" - DUPLICATE FILE HANDLE */
case 0x46: /* "DUP2", "FORCEDUP" - FORCE DUPLICATE FILE HANDLE */
- EAX = (EAX & 0xffff0000) | dup(BX);
+ AX = dup(BX);
ResetCflag;
break;
case 0x47: /* "CWD" - GET CURRENT DIRECTORY */
GetCurrentDirectory(context);
- EAX = (EAX & 0xffff0000) | 0x0100;
+ AX = 0x0100;
/* intlist: many Microsoft products for Windows rely on this */
break;
@@ -1212,11 +1357,11 @@
break;
case 0x4c: /* "EXIT" - TERMINATE WITH RETURN CODE */
- exit(EAX & 0xff);
+ exit(AL);
break;
case 0x4d: /* GET RETURN CODE */
- EAX = (EAX & 0xffffff00) | NoError; /* normal exit */
+ AL = NoError; /* normal exit */
break;
case 0x4e: /* "FINDFIRST" - FIND FIRST MATCHING FILE */
@@ -1229,7 +1374,7 @@
case 0x52: /* "SYSVARS" - GET LIST OF LISTS */
ES = 0x0;
- EBX = (EBX & 0xffff0000);
+ BX = 0x0;
IntBarf(0x21, context);
break;
@@ -1238,7 +1383,7 @@
break;
case 0x57: /* FILE DATE AND TIME */
- switch (EAX & 0xff)
+ switch (AL)
{
case 0x00:
GetFileDateTime(context);
@@ -1250,10 +1395,10 @@
break;
case 0x58: /* GET OR SET MEMORY/UMB ALLOCATION STRATEGY */
- switch (EAX & 0xff)
+ switch (AL)
{
case 0x00:
- EAX = (EAX & 0xffffff00) | 0x01L;
+ AL = 0x01L;
break;
case 0x02:
EAX &= 0xff00L;
@@ -1273,25 +1418,21 @@
CreateNewFile(context);
break;
- case 0x5c: /* "FLOCK" - RECORD LOCKING */
- IntBarf(0x21, context);
- break;
-
case 0x5d: /* NETWORK */
case 0x5e:
/* network software not installed */
- EAX = (EAX & 0xfffff00) | NoNetwork;
+ AL = NoNetwork;
SetCflag;
break;
case 0x5f: /* NETWORK */
- switch (EAX & 0xff)
+ switch (AL)
{
case 0x07: /* ENABLE DRIVE */
- if (!DOS_EnableDrive(EDX & 0xff))
+ if (!DOS_EnableDrive(DL))
{
Error(InvalidDrive, EC_MediaError , EL_Disk);
- EAX = (EAX & 0xfffff00) | InvalidDrive;
+ AL = InvalidDrive;
SetCflag;
break;
}
@@ -1301,10 +1442,10 @@
break;
}
case 0x08: /* DISABLE DRIVE */
- if (!DOS_DisableDrive(EDX & 0xff))
+ if (!DOS_DisableDrive(DL))
{
Error(InvalidDrive, EC_MediaError , EL_Disk);
- EAX = (EAX & 0xfffff00) | InvalidDrive;
+ AL = InvalidDrive;
SetCflag;
break;
}
@@ -1315,7 +1456,7 @@
}
default:
/* network software not installed */
- EAX = (EAX & 0xfffff00) | NoNetwork;
+ AL = NoNetwork;
SetCflag;
break;
}
@@ -1335,11 +1476,10 @@
break;
case 0x66: /* GLOBAL CODE PAGE TABLE */
- switch (EAX & 0xff)
- {
+ switch (AL) {
case 0x01:
- EBX = CodePage;
- EDX = BX;
+ BX = CodePage;
+ DX = BX;
ResetCflag;
break;
case 0x02:
@@ -1358,7 +1498,7 @@
break;
case 0x69: /* DISK SERIAL NUMBER */
- switch (EAX & 0xff)
+ switch (AL)
{
case 0x00:
GetDiskSerialNumber(context);
diff --git a/miscemu/int25.c b/miscemu/int25.c
index 9a9a366..af79ec4 100644
--- a/miscemu/int25.c
+++ b/miscemu/int25.c
@@ -1,5 +1,6 @@
#include <stdio.h>
#include <stdlib.h>
+#include "registers.h"
#include "msdos.h"
#include "wine.h"
@@ -8,15 +9,14 @@
BYTE *dataptr = pointer(DS, BX);
DWORD begin, length;
- if( (ECX & 0xffff) == 0xffff)
- {
+ if (CX == 0xffff) {
begin = getdword(dataptr);
length = getword(&dataptr[4]);
dataptr = (BYTE *) getdword(&dataptr[6]);
} else {
- begin = EDX & 0xffff;
- length = ECX & 0xffff;
+ begin = DX;
+ length = CX;
}
fprintf(stderr, "int25: abs diskread, drive %d, sector %d, "
"count %d, buffer %d\n", EAX & 0xff, begin, length, (int) dataptr);
diff --git a/miscemu/int26.c b/miscemu/int26.c
index 0308d37..ff145b1 100644
--- a/miscemu/int26.c
+++ b/miscemu/int26.c
@@ -1,5 +1,6 @@
#include <stdio.h>
#include <stdlib.h>
+#include "registers.h"
#include "msdos.h"
#include "wine.h"
@@ -8,15 +9,14 @@
BYTE *dataptr = pointer(DS, BX);
DWORD begin, length;
- if( (ECX & 0xffff) == 0xffff)
- {
+ if (CX == 0xffff) {
begin = getdword(dataptr);
length = getword(&dataptr[4]);
dataptr = (BYTE *) getdword(&dataptr[6]);
} else {
- begin = EDX & 0xffff;
- length = ECX & 0xffff;
+ begin = DX;
+ length = CX;
}
fprintf(stderr,"int26: abs diskwrite, drive %d, sector %d, count %d,"
diff --git a/miscemu/int2f.c b/miscemu/int2f.c
index c652bba..e1a6195 100644
--- a/miscemu/int2f.c
+++ b/miscemu/int2f.c
@@ -1,6 +1,6 @@
#include <stdio.h>
#include <stdlib.h>
-#include "msdos.h"
+#include "registers.h"
#include "wine.h"
int do_int2f_16(struct sigcontext_struct *context);
@@ -10,8 +10,8 @@
{
switch((context->sc_eax >> 8) & 0xff)
{
- case 0x10: /* share isn't installed */
- EAX = (EAX & 0xffffff00) | 0x01;
+ case 0x10: /* share is installed */
+ EAX = (EAX & 0xffffff00) | 0xff;
break;
case 0x15: /* mscdex */
diff --git a/miscemu/int31.c b/miscemu/int31.c
index 3d4500c..d738772 100644
--- a/miscemu/int31.c
+++ b/miscemu/int31.c
@@ -1,6 +1,6 @@
#include <stdio.h>
#include <stdlib.h>
-#include "msdos.h"
+#include "registers.h"
#include "wine.h"
typedef struct {
diff --git a/miscemu/ioports.c b/miscemu/ioports.c
index 35560a2..07d6af3 100644
--- a/miscemu/ioports.c
+++ b/miscemu/ioports.c
@@ -1,7 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
-#include "msdos.h"
+#include "registers.h"
#include "wine.h"
static BYTE cmosaddress;
@@ -18,15 +18,14 @@
void inportb(struct sigcontext_struct *context)
{
- fprintf(stderr, "IO: inb (%x)\n", EDX & 0xffff);
+ fprintf(stderr, "IO: inb (%x)\n", DX);
- switch(EDX & 0xffff)
- {
+ switch(DX) {
case 0x70:
- EAX = (EAX & 0xffffff00L) | cmosaddress;
+ AL = cmosaddress;
break;
case 0x71:
- EAX = (EAX & 0xffffff00L) | cmosimage[cmosaddress & 0x3f];
+ AL = cmosimage[cmosaddress & 0x3f];
break;
default:
}
@@ -34,22 +33,22 @@
void inport(struct sigcontext_struct *context)
{
- fprintf(stderr, "IO: in (%x)\n", EDX & 0xffff);
+ fprintf(stderr, "IO: in (%x)\n", DX);
- EAX = (EAX & 0xffff0000L) | 0xffff;
+ AX = 0xffff;
}
void outportb(struct sigcontext_struct *context)
{
- fprintf(stderr, "IO: outb (%x), %x\n", EDX & 0xffff, EAX & 0xff);
+ fprintf(stderr, "IO: outb (%x), %x\n", DX, AX);
switch (EDX & 0xffff)
{
case 0x70:
- cmosaddress = EAX & 0x7f;
+ cmosaddress = AL & 0x7f;
break;
case 0x71:
- cmosimage[cmosaddress & 0x3f] = EAX & 0xff;
+ cmosimage[cmosaddress & 0x3f] = AL;
break;
default:
}
@@ -57,5 +56,5 @@
void outport(struct sigcontext_struct *context)
{
- fprintf(stderr, "IO: out (%x), %x\n", EDX & 0xffff, EAX & 0xffff);
+ fprintf(stderr, "IO: out (%x), %x\n", DX, AX);
}
diff --git a/objects/bitmap.c b/objects/bitmap.c
index b068a2a..cd4f623 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -12,6 +12,9 @@
#include "gdi.h"
#include "bitmap.h"
+ /* Include OEM bitmaps */
+#include "bitmaps/check_mark"
+#include "bitmaps/menu_arrow"
/* Handle of the bitmap selected by default in a memory DC */
HBITMAP BITMAP_hbitmapMemDC = 0;
@@ -74,6 +77,59 @@
/***********************************************************************
+ * BITMAP_LoadOEMBitmap
+ */
+HBITMAP BITMAP_LoadOEMBitmap( WORD id )
+{
+ BITMAPOBJ * bmpObjPtr;
+ HBITMAP hbitmap;
+ WORD width, height;
+ char *data;
+
+ switch(id)
+ {
+ case OBM_MNARROW:
+ width = menu_arrow_width;
+ height = menu_arrow_height;
+ data = menu_arrow_bits;
+ break;
+
+ case OBM_CHECK:
+ width = check_mark_width;
+ height = check_mark_height;
+ data = check_mark_bits;
+ break;
+
+ default:
+ return 0;
+ }
+
+ /* Create the BITMAPOBJ */
+ if (!(hbitmap = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC )))
+ return 0;
+ bmpObjPtr = (BITMAPOBJ *) GDI_HEAP_ADDR( hbitmap );
+ bmpObjPtr->size.cx = 0;
+ bmpObjPtr->size.cy = 0;
+ bmpObjPtr->bitmap.bmType = 0;
+ bmpObjPtr->bitmap.bmWidth = width;
+ bmpObjPtr->bitmap.bmHeight = height;
+ bmpObjPtr->bitmap.bmWidthBytes = (width + 15) / 16 * 2;
+ bmpObjPtr->bitmap.bmPlanes = 1;
+ bmpObjPtr->bitmap.bmBitsPixel = 1;
+ bmpObjPtr->bitmap.bmBits = NULL;
+
+ /* Create the pixmap */
+ if (!(bmpObjPtr->pixmap = XCreateBitmapFromData( display, rootWindow,
+ data, width, height )))
+ {
+ GDI_HEAP_FREE( hbitmap );
+ return 0;
+ }
+ return hbitmap;
+}
+
+
+/***********************************************************************
* CreateBitmap (GDI.48)
*/
HBITMAP CreateBitmap( short width, short height,
diff --git a/objects/dcvalues.c b/objects/dcvalues.c
index 33b51ac..c1fafaf 100644
--- a/objects/dcvalues.c
+++ b/objects/dcvalues.c
@@ -73,7 +73,7 @@
{ \
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); \
if (!dc) return 0; \
- return dc->w.ret_x | (dc->w.ret_y << 16); \
+ return MAKELONG( dc->w.ret_x, dc->w.ret_y << 16 ); \
}
#define DC_GET_VAL_EX( func_name, ret_x, ret_y ) \
@@ -127,7 +127,6 @@
DC_GET_VAL( COLORREF, GetBkColor, backgroundColor ) /* GDI.75 */
DC_GET_VAL( WORD, GetBkMode, backgroundMode ) /* GDI.76 */
DC_GET_X_Y( DWORD, GetCurrentPosition, CursPosX, CursPosY ) /* GDI.78 */
-DC_GET_X_Y( DWORD, GetDCOrg, DCOrgX, DCOrgY ) /* GDI.79 */
DC_GET_VAL( WORD, GetMapMode, MapMode ) /* GDI.81 */
DC_GET_VAL( WORD, GetPolyFillMode, polyFillMode ) /* GDI.84 */
DC_GET_VAL( WORD, GetROP2, ROPmode ) /* GDI.85 */
diff --git a/objects/dib.c b/objects/dib.c
index c6d9d44..6042cb2 100644
--- a/objects/dib.c
+++ b/objects/dib.c
@@ -128,6 +128,71 @@
}
}
+#define check_xy(x,y) \
+ if (x > width) { \
+ x = 0; \
+ if (lines) \
+ lines--; \
+ }
+
+/***********************************************************************
+ * DIB_SetImageBits_RLE4
+ *
+ * SetDIBits for a 4-bit deep compressed DIB.
+ */
+static void DIB_SetImageBits_RLE4( WORD lines, BYTE *bits, WORD width,
+ WORD *colors, XImage *bmpImage )
+{
+ int x = 0, c, length;
+ BYTE *begin = bits;
+
+ lines--;
+ while (1) {
+ length = *bits++;
+ if (length) { /* encoded */
+ c = *bits++;
+ while (length--) {
+ XPutPixel(bmpImage, x++, lines, colors[c >> 4]);
+ check_xy(x, y);
+ if (length) {
+ length--;
+ XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
+ check_xy(x, y);
+ }
+ }
+ } else {
+ length = *bits++;
+ switch (length) {
+ case 0: /* eol */
+ x = 0;
+ lines--;
+ continue;
+
+ case 1: /* eopicture */
+ return;
+
+ case 2: /* delta */
+ x += *bits++;
+ lines -= *bits++;
+ continue;
+
+ default: /* absolute */
+ while (length--) {
+ c = *bits++;
+ XPutPixel(bmpImage, x++, lines, colors[c >> 4]);
+ check_xy(x, y);
+ if (length) {
+ length--;
+ XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
+ check_xy(x, y);
+ }
+ }
+ if ((bits - begin) & 1)
+ bits++;
+ }
+ }
+ }
+}
/***********************************************************************
* DIB_SetImageBits_8
@@ -148,6 +213,62 @@
}
}
+/***********************************************************************
+ * DIB_SetImageBits_RLE8
+ *
+ * SetDIBits for an 8-bit deep compressed DIB.
+ */
+static void DIB_SetImageBits_RLE8( WORD lines, BYTE *bits, WORD width,
+ WORD *colors, XImage *bmpImage )
+{
+ int x = 0, i, length;
+ BYTE *begin = bits;
+
+ lines--;
+ while (1) {
+ length = *bits++;
+ if (length) { /* encoded */
+ while (length--) {
+ XPutPixel(bmpImage, x++, lines, colors[*bits]);
+ if (x > width) {
+ x = 0;
+ if (lines)
+ lines--;
+ }
+ }
+ bits++;
+ } else {
+ length = *bits++;
+ switch (length) {
+ case 0: /* eol */
+ x = 0;
+ lines--;
+ continue;
+
+ case 1: /* eopicture */
+ return;
+
+ case 2: /* delta */
+ x += *bits++;
+ lines -= *bits++;
+ continue;
+
+ default: /* absolute */
+ for (i = length; i ; i--) {
+ XPutPixel(bmpImage, x++, lines,
+ colors[*bits++]);
+ if (x > width) {
+ x = 0;
+ if (lines)
+ lines--;
+ }
+ }
+ if ((bits - begin) & 1)
+ bits++;
+ }
+ }
+ }
+}
/***********************************************************************
* DIB_SetImageBits_24
@@ -228,11 +349,19 @@
colorMapping, bmpImage );
break;
case 4:
- DIB_SetImageBits_4( lines, bits, info->bmiHeader.biWidth,
+ if (info->bmiHeader.biCompression)
+ DIB_SetImageBits_RLE4( lines, bits, info->bmiHeader.biWidth,
+ colorMapping, bmpImage );
+ else
+ DIB_SetImageBits_4( lines, bits, info->bmiHeader.biWidth,
colorMapping, bmpImage );
break;
case 8:
- DIB_SetImageBits_8( lines, bits, info->bmiHeader.biWidth,
+ if (info->bmiHeader.biCompression)
+ DIB_SetImageBits_RLE8( lines, bits, info->bmiHeader.biWidth,
+ colorMapping, bmpImage );
+ else
+ DIB_SetImageBits_8( lines, bits, info->bmiHeader.biWidth,
colorMapping, bmpImage );
break;
case 24:
diff --git a/objects/metafile.c b/objects/metafile.c
index 544e6e4..fd9c3ae 100644
--- a/objects/metafile.c
+++ b/objects/metafile.c
@@ -103,8 +103,8 @@
mf = (METAFILE *)GlobalLock(dc->w.hMetaFile);
mh = (METAHEADER *)GlobalLock(mf->hMetaHdr);
- /* Construct the end of metafile record - this is undocumented
- * but is created by MS Windows 3.1.
+ /* Construct the end of metafile record - this is documented
+ * in SDK Knowledgebase Q99334.
*/
if (!MF_MetaParam0(dc, META_EOF))
{
diff --git a/objects/text.c b/objects/text.c
index f8be278..10a6a75 100644
--- a/objects/text.c
+++ b/objects/text.c
@@ -451,4 +451,15 @@
return FALSE;
}
+/***********************************************************************
+ * GetTabbedTextExtent [USER.197]
+ */
+DWORD GetTabbedTextExtent(HDC hDC, LPSTR lpString, int nCount,
+ int nTabPositions, LPINT lpnTabStopPositions)
+{
+ printf("EMPTY STUB !!! GetTabbedTextExtent(); !\n");
+
+ return (18 << 16) | (nCount * 18);
+}
+
diff --git a/windows/dc.c b/windows/dc.c
index 056329a..9c8a274 100644
--- a/windows/dc.c
+++ b/windows/dc.c
@@ -532,6 +532,23 @@
/***********************************************************************
+ * GetDCOrg (GDI.79)
+ */
+DWORD GetDCOrg( HDC hdc )
+{
+ Window root;
+ int x, y, w, h, border, depth;
+
+ DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+ if (!dc) return 0;
+ if (dc->w.flags & DC_MEMORY) return 0;
+ XGetGeometry( display, dc->u.x.drawable, &root,
+ &x, &y, &w, &h, &border, &depth );
+ return MAKELONG( dc->w.DCOrgX + (WORD)x, dc->w.DCOrgY + (WORD)y );
+}
+
+
+/***********************************************************************
* SetDCOrg (GDI.117)
*/
DWORD SetDCOrg( HDC hdc, short x, short y )
diff --git a/windows/defdlg.c b/windows/defdlg.c
index 8405dc3..2e5607d 100644
--- a/windows/defdlg.c
+++ b/windows/defdlg.c
@@ -50,6 +50,14 @@
case WM_NCDESTROY:
+ /* Free dialog heap (if created) */
+ if (dlgInfo->hDialogHeap)
+ {
+ GlobalUnlock(dlgInfo->hDialogHeap);
+ GlobalFree(dlgInfo->hDialogHeap);
+ dlgInfo->hDialogHeap = 0;
+ }
+
/* Delete font */
if (dlgInfo->hUserFont)
{
diff --git a/windows/defwnd.c b/windows/defwnd.c
index 1adc1e3..12443b1 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -26,9 +26,6 @@
extern LONG NC_HandleSysCommand( HWND hwnd, WORD wParam, POINT pt );
extern LONG NC_HandleSetCursor( HWND hwnd, WORD wParam, LONG lParam );
extern LONG WINPOS_HandleWindowPosChanging( WINDOWPOS *winpos ); /* winpos.c */
-extern void NC_TrackSysMenu( HWND hwnd ); /* menu.c */
-extern BOOL ActivateMenuBarFocus(HWND hWnd); /* menu.c */
-
/***********************************************************************
@@ -229,13 +226,12 @@
return NC_HandleSysCommand( hwnd, wParam, MAKEPOINT(lParam) );
case WM_SYSKEYDOWN:
- if (wParam == VK_MENU) ActivateMenuBarFocus(hwnd);
- break;
+ if (wParam == VK_MENU)
+ SendMessage( hwnd, WM_SYSCOMMAND, SC_KEYMENU, 0L );
+ break;
+
case WM_SYSKEYUP:
break;
- case WM_MENUCHAR:
- MessageBeep(0);
- break;
case WM_MEASUREITEM:
measure = (MEASUREITEMSTRUCT *)lParam;
switch(measure->CtlType) {
diff --git a/windows/dialog.c b/windows/dialog.c
index e91d95a..7b28b2d 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -15,6 +15,8 @@
#include "dialog.h"
#include "win.h"
#include "user.h"
+#include "message.h"
+#include "heap.h"
/* Dialog base units */
@@ -208,6 +210,8 @@
DWORD exStyle = 0;
WORD xUnit = xBaseUnit;
WORD yUnit = yBaseUnit;
+ void *dlgHeapBase;
+ MDESC *dlgHeap;
/* Parse dialog template */
@@ -278,15 +282,16 @@
return 0;
}
- ShowWindow(hwnd, SW_SHOWNORMAL);
- UpdateWindow(hwnd);
-
/* Create control windows */
#ifdef DEBUG_DIALOG
printf( " BEGIN\n" );
#endif
+ wndPtr = WIN_FindWndPtr( hwnd );
+ dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
+ dlgInfo->hDialogHeap = 0;
+
for (i = 0; i < template.header->nbItems; i++)
{
DLGCONTROLHEADER * next_header;
@@ -303,16 +308,39 @@
printf(" %d, %d, %d, %d, %d, %08x\n", header->id, header->x, header->y,
header->cx, header->cy, header->style );
#endif
- if ((strcmp(class, "STATIC") == 0) & ((header->style & SS_ICON) == SS_ICON)) {
- header->cx = 32;
- header->cy = 32;
+
+ if ((strcmp(class, "EDIT") == 0) &&
+ ((header->style & DS_LOCALEDIT) != DS_LOCALEDIT)) {
+ if (!dlgInfo->hDialogHeap) {
+ dlgInfo->hDialogHeap = GlobalAlloc(GMEM_FIXED, 0x10000);
+ if (!dlgInfo->hDialogHeap) {
+ printf("CreateDialogIndirectParam: Insufficient memory ",
+ "to create heap for edit control\n");
+ continue;
+ }
+ dlgHeapBase = GlobalLock(dlgInfo->hDialogHeap);
+ HEAP_Init(&dlgHeap, dlgHeapBase, 0x10000);
}
- header->style |= WS_CHILD;
- CreateWindowEx( WS_EX_NOPARENTNOTIFY,
- class, text, header->style,
- header->x * xUnit / 4, header->y * yUnit / 8,
- header->cx * xUnit / 4, header->cy * yUnit / 8,
- hwnd, header->id, hInst, NULL );
+ header->style |= WS_CHILD;
+ CreateWindowEx( WS_EX_NOPARENTNOTIFY,
+ class, text, header->style,
+ header->x * xUnit / 4, header->y * yUnit / 8,
+ header->cx * xUnit / 4, header->cy * yUnit / 8,
+ hwnd, header->id, HIWORD((LONG)dlgHeapBase), NULL );
+ }
+ else {
+ if ((strcmp(class, "STATIC") == 0) &
+ ((header->style & SS_ICON) == SS_ICON)) {
+ header->cx = 32;
+ header->cy = 32;
+ }
+ header->style |= WS_CHILD;
+ CreateWindowEx( WS_EX_NOPARENTNOTIFY,
+ class, text, header->style,
+ header->x * xUnit / 4, header->y * yUnit / 8,
+ header->cx * xUnit / 4, header->cy * yUnit / 8,
+ hwnd, header->id, hInst, NULL );
+ }
header = next_header;
}
@@ -322,8 +350,6 @@
/* Initialise dialog extra data */
- wndPtr = WIN_FindWndPtr( hwnd );
- dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
dlgInfo->dlgProc = dlgProc;
dlgInfo->hUserFont = hFont;
dlgInfo->hMenu = hMenu;
@@ -346,7 +372,7 @@
/***********************************************************************
* DIALOG_DoDialogBox
*/
-static int DIALOG_DoDialogBox( HWND hwnd )
+static int DIALOG_DoDialogBox( HWND hwnd, HWND owner )
{
WND * wndPtr;
DIALOGINFO * dlgInfo;
@@ -360,7 +386,8 @@
dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
ShowWindow( hwnd, SW_SHOW );
- while (MSG_InternalGetMessage( lpmsg, hwnd, MSGF_DIALOGBOX, TRUE ))
+ while (MSG_InternalGetMessage( lpmsg, hwnd, owner, MSGF_DIALOGBOX,
+ PM_REMOVE, TRUE ))
{
if (!IsDialogMessage( hwnd, lpmsg))
{
@@ -399,7 +426,7 @@
hInst, dlgTemplate, owner, dlgProc, param );
#endif
hwnd = CreateDialogParam( hInst, dlgTemplate, owner, dlgProc, param );
- if (hwnd) return DIALOG_DoDialogBox( hwnd );
+ if (hwnd) return DIALOG_DoDialogBox( hwnd, owner );
return -1;
}
@@ -426,7 +453,7 @@
if (!(ptr = GlobalLock( dlgTemplate ))) return -1;
hwnd = CreateDialogIndirectParam( hInst, ptr, owner, dlgProc, param );
GlobalUnlock( dlgTemplate );
- if (hwnd) return DIALOG_DoDialogBox( hwnd );
+ if (hwnd) return DIALOG_DoDialogBox( hwnd, owner );
return -1;
}
diff --git a/windows/mdi.c b/windows/mdi.c
index 0835c8a..80dd6d7 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -12,10 +12,12 @@
#include "mdi.h"
#include "user.h"
#include "sysmetrics.h"
-#include "menu.h"
#define DEBUG_MDI /* */
+extern WORD MENU_DrawMenuBar( HDC hDC, LPRECT lprect,
+ HMENU hmenu, BOOL suppress_draw ); /* menu.c */
+
/**********************************************************************
* MDIRecreateMenuList
*/
@@ -80,7 +82,7 @@
WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SYSMENU |
WS_THICKFRAME | WS_VISIBLE | cs->style,
cs->x, cs->y, cs->cx, cs->cy, parent, (HMENU) 0,
- w->hInstance, (LPSTR) cs->lParam);
+ w->hInstance, (LPSTR) cs);
if (hwnd)
{
@@ -569,9 +571,7 @@
rect.right -= SYSMETRICS_CXSIZE;
rect.bottom = rect.top + SYSMETRICS_CYMENU;
- StdDrawMenuBar(hdc, &rect, (LPPOPUPMENU) GlobalLock(wndPtr->wIDmenu),
- FALSE);
- GlobalUnlock(wndPtr->wIDmenu);
+ MENU_DrawMenuBar(hdc, &rect, wndPtr->wIDmenu, FALSE);
DeleteDC(hdcMem);
ReleaseDC(hwndFrame, hdc);
diff --git a/windows/message.c b/windows/message.c
index dcb8e5c..fdac135 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -205,7 +205,7 @@
* the coordinates to client coordinates.
* - Send the WM_SETCURSOR message.
*/
-static BOOL MSG_TranslateMouseMsg( MSG *msg )
+static BOOL MSG_TranslateMouseMsg( MSG *msg, BOOL remove )
{
BOOL eatMsg = FALSE;
static DWORD lastClickTime = 0;
@@ -280,9 +280,12 @@
case WM_MBUTTONDOWN: msg->message = WM_MBUTTONDBLCLK; break;
}
- lastClickTime = msg->time;
- lastClickMsg = msg->message;
- lastClickPos = msg->pt;
+ if (remove)
+ {
+ lastClickTime = msg->time;
+ lastClickMsg = msg->message;
+ lastClickPos = msg->pt;
+ }
}
/* Build the translated message */
@@ -631,7 +634,7 @@
if ((msg->message >= WM_MOUSEFIRST) &&
(msg->message <= WM_MOUSELAST))
- if (!MSG_TranslateMouseMsg( msg ))
+ if (!MSG_TranslateMouseMsg( msg, flags & PM_REMOVE ))
{
MSG_RemoveMsg( sysMsgQueue, pos );
continue;
@@ -690,20 +693,30 @@
* 'hwnd' must be the handle of the dialog or menu window.
* 'code' is the message filter value (MSGF_??? codes).
*/
-BOOL MSG_InternalGetMessage( LPMSG msg, HWND hwnd, short code, BOOL sendIdle )
+BOOL MSG_InternalGetMessage( LPMSG msg, HWND hwnd, HWND hwndOwner, short code,
+ WORD flags, BOOL sendIdle )
{
- do
+ for (;;)
{
if (sendIdle)
{
- if (MSG_PeekMessage(appMsgQueue, msg, 0, 0, 0, PM_REMOVE, TRUE))
- continue;
- /* FIXME: to which window should we send this? */
- /* SendMessage( hwnd, WM_ENTERIDLE, code, (LPARAM)hwnd ); */
+ if (!MSG_PeekMessage( appMsgQueue, msg, 0, 0, 0, flags, TRUE ))
+ {
+ /* No message present -> send ENTERIDLE and wait */
+ SendMessage( hwndOwner, WM_ENTERIDLE, code, (LPARAM)hwnd );
+ MSG_PeekMessage( appMsgQueue, msg, 0, 0, 0, flags, FALSE );
+ }
}
- MSG_PeekMessage( appMsgQueue, msg, 0, 0, 0, PM_REMOVE, FALSE );
- } while (CallMsgFilter( msg, code ) != 0);
- return (msg->message != WM_QUIT);
+ else /* Always wait for a message */
+ MSG_PeekMessage( appMsgQueue, msg, 0, 0, 0, flags, FALSE );
+
+ if (!CallMsgFilter( msg, code )) return (msg->message != WM_QUIT);
+
+ /* Message filtered -> remove it from the queue */
+ /* if it's still there. */
+ if (!(flags & PM_REMOVE))
+ MSG_PeekMessage( appMsgQueue, msg, 0, 0, 0, PM_REMOVE, TRUE );
+ }
}
diff --git a/windows/nonclient.c b/windows/nonclient.c
index c364b02..2bb188e 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -12,7 +12,6 @@
#include "sysmetrics.h"
#include "user.h"
#include "scroll.h"
-#include "menu.h"
#include "syscolor.h"
static HBITMAP hbitmapClose = 0;
@@ -24,11 +23,19 @@
static HBITMAP hbitmapRestore = 0;
static HBITMAP hbitmapRestoreD = 0;
+#define SC_ABOUTWINE (SC_SCREENSAVE+1)
+extern HINSTANCE hSysRes;
+extern BOOL AboutWine_Proc( HWND hDlg, WORD msg, WORD wParam, LONG lParam );
+
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,
int orgX, int orgY ); /* menu.c */
+extern void MENU_TrackMouseMenuBar( HWND hwnd, POINT pt ); /* menu.c */
+extern void MENU_TrackKbdMenuBar( HWND hwnd, WORD wParam ); /* menu.c */
+extern WORD MENU_DrawMenuBar( HDC hDC, LPRECT lprect,
+ HMENU hmenu, BOOL suppress_draw ); /* menu.c */
/* Some useful macros */
@@ -70,8 +77,8 @@
}
if ((style & WS_CAPTION) == WS_CAPTION)
- rect->top -= SYSMETRICS_CYCAPTION - 1;
- if (menu) rect->top -= SYSMETRICS_CYMENU + 1;
+ rect->top -= SYSMETRICS_CYCAPTION - SYSMETRICS_CYBORDER;
+ if (menu) rect->top -= SYSMETRICS_CYMENU + SYSMETRICS_CYBORDER;
if (style & WS_VSCROLL) rect->right += SYSMETRICS_CXVSCROLL;
if (style & WS_HSCROLL) rect->bottom += SYSMETRICS_CYHSCROLL;
@@ -237,8 +244,9 @@
if (!PtInRect( &rect, pt ))
{
/* Check system menu */
- if ((wndPtr->dwStyle & WS_SYSMENU) && (pt.x <= SYSMETRICS_CXSIZE))
- return HTSYSMENU;
+ if (wndPtr->dwStyle & WS_SYSMENU)
+ rect.left += SYSMETRICS_CXSIZE;
+ if (pt.x <= rect.left) return HTSYSMENU;
/* Check maximize box */
if (wndPtr->dwStyle & WS_MAXIMIZEBOX)
rect.right -= SYSMETRICS_CXSIZE + 1;
@@ -311,7 +319,7 @@
/***********************************************************************
* NC_DrawSysButton
*/
-static void NC_DrawSysButton( HWND hwnd, HDC hdc, BOOL down )
+void NC_DrawSysButton( HWND hwnd, HDC hdc, BOOL down )
{
RECT rect;
WND *wndPtr = WIN_FindWndPtr( hwnd );
@@ -611,19 +619,17 @@
if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)
{
RECT r = rect;
- rect.top += SYSMETRICS_CYSIZE + 1;
- r.bottom = rect.top - 1;
+ r.bottom = rect.top + SYSMETRICS_CYSIZE;
+ rect.top += SYSMETRICS_CYSIZE + SYSMETRICS_CYBORDER;
NC_DrawCaption( hdc, &r, hwnd, wndPtr->dwStyle, active );
}
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 );
+ r.bottom = rect.top + SYSMETRICS_CYMENU; /* default height */
+ rect.top += MENU_DrawMenuBar( hdc, &r, (HMENU)wndPtr->wIDmenu,
+ suppress_menupaint );
}
if (wndPtr->dwStyle & (WS_VSCROLL | WS_HSCROLL)) {
@@ -1111,27 +1117,33 @@
ReleaseCapture();
}
-
/***********************************************************************
- * NC_TrackMouseMenuBar
+ * NC_TrackSysMenu
*
- * Track a mouse events for the MenuBar.
+ * Track a mouse button press on the system menu.
*/
-static void NC_TrackMouseMenuBar( HWND hwnd, WORD wParam, POINT pt )
+static void NC_TrackSysMenu( HWND hwnd, HDC hdc, POINT pt )
{
- WND *wndPtr;
- LPPOPUPMENU lppop;
- MSG msg;
- wndPtr = WIN_FindWndPtr(hwnd);
- lppop = (LPPOPUPMENU)GlobalLock(wndPtr->wIDmenu);
-#ifdef DEBUG_MENU
- printf("NC_TrackMouseMenuBar // wndPtr=%08X lppop=%08X !\n", wndPtr, lppop);
-#endif
- ScreenToClient(hwnd, &pt);
- pt.y += lppop->rect.bottom;
- SetCapture(hwnd);
- MenuButtonDown(hwnd, lppop, pt.x, pt.y);
- GlobalUnlock(wndPtr->wIDmenu);
+ RECT rect;
+ WND *wndPtr = WIN_FindWndPtr( hwnd );
+
+ if (!(wndPtr->dwStyle & WS_SYSMENU)) return;
+ /* If window has a menu, track the menu bar normally */
+ if (HAS_MENU(wndPtr)) MENU_TrackMouseMenuBar( hwnd, pt );
+ else
+ {
+ /* Otherwise track the system menu like a normal popup menu */
+ NC_GetInsideRect( hwnd, &rect );
+ OffsetRect( &rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top );
+ if (wndPtr->dwStyle & WS_CHILD)
+ ClientToScreen( wndPtr->hwndParent, (POINT *)&rect );
+ rect.right = rect.left + SYSMETRICS_CXSIZE;
+ rect.bottom = rect.top + SYSMETRICS_CYSIZE;
+ NC_DrawSysButton( hwnd, hdc, TRUE );
+ TrackPopupMenu( wndPtr->hSysMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON,
+ rect.left, rect.bottom, 0, hwnd, &rect );
+ NC_DrawSysButton( hwnd, hdc, FALSE );
+ }
}
@@ -1151,8 +1163,7 @@
break;
case HTSYSMENU:
- NC_DrawSysButton( hwnd, hdc, TRUE );
- NC_TrackSysMenu(hwnd);
+ NC_TrackSysMenu( hwnd, hdc, MAKEPOINT(lParam) );
break;
case HTMENU:
@@ -1263,22 +1274,28 @@
break;
case SC_MOUSEMENU:
- NC_TrackMouseMenuBar( hwnd, wParam, pt );
+ MENU_TrackMouseMenuBar( hwnd, pt );
break;
case SC_KEYMENU:
-/* NC_KeyMenuBar( hwnd, wParam, pt ); */
+ MENU_TrackKbdMenuBar( hwnd, wParam );
break;
case SC_ARRANGE:
break;
case SC_TASKLIST:
- case SC_SCREENSAVE:
+ /* WinExec( "taskman.exe", SW_SHOWNORMAL ); */
+ break;
+
case SC_HOTKEY:
break;
+
+ case SC_SCREENSAVE:
+ if (wParam == SC_ABOUTWINE)
+ DialogBox( hSysRes, MAKEINTRESOURCE(2),
+ hwnd, (FARPROC)AboutWine_Proc );
+ break;
}
return 0;
}
-
-
diff --git a/windows/utility.c b/windows/utility.c
index 32f1e59..afec604 100644
--- a/windows/utility.c
+++ b/windows/utility.c
@@ -382,21 +382,14 @@
int wvsprintf(LPSTR buf, LPSTR format, LPSTR args)
{
- char qualified_fmt[1536];
char *newargs;
int result;
- /* 1.5K is a safe value as wvsprintf can only handle buffers up to
- 1K and in a worst case such a buffer would look like "%i%i%i..." */
-
if(!buf || !format) return 0;
- /* Change the format string so that ints are handled as short by
- default */
-
/* Convert agruments to 32-bit values */
newargs = UTILITY_convertArgs(format, args);
- result = vsprintf(buf, qualified_fmt, newargs);
+ result = vsprintf(buf, format, newargs);
free(newargs);
return result;
diff --git a/windows/win.c b/windows/win.c
index 8aeba56..3924908 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -247,6 +247,7 @@
HANDLE class, hwnd;
CLASS *classPtr;
WND *wndPtr, *parentPtr = NULL;
+ POINT maxSize, maxPos, minTrack, maxTrack;
CREATESTRUCT *createStruct;
HANDLE hcreateStruct;
int wmcreate;
@@ -379,6 +380,19 @@
win_attr.save_under = ((classPtr->wc.style & CS_SAVEBITS) != 0);
+ WINPOS_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack );
+
+ if ( maxSize.x < width)
+ {
+ width = maxSize.x;
+ wndPtr->rectWindow.right = x + width;
+ }
+ if ( maxSize.y < height)
+ {
+ height = maxSize.y;
+ wndPtr->rectWindow.bottom = y + height;
+ }
+
wndPtr->window = XCreateWindow( display, parentPtr->window,
x + parentPtr->rectClient.left - parentPtr->rectWindow.left,
y + parentPtr->rectClient.top - parentPtr->rectWindow.top,