diff --git a/ChangeLog b/ChangeLog index 1aa6162638a..a957c33c41b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,130 @@ +Tue Feb 1 21:14:47 1994 Bob Amstadt (bob@pooh) + + * [loader/selector.c] + Added function CreateNewSegments(). Modified IPCCopySelector + to allow aliasing to any arbitrary memory space. + + * [memory/global.c] + Fixed potential bug in GlobalGetFreeSegments(). + + * [memory/linear.c] + Created functions GlobalLinearLock() and GlobalLinearUnlock(). + +Tue Feb 1 05:51:43 1994 julliard@di.epfl.ch (Alexandre Julliard) + + * [controls/widgets.c] + Removed CAPTION window class. + + * [loader/cursor.c] + Bug fix in LoadCursor(): don't allocate memory every time for + built-in cursors. + + * [windows/clipping.c] + Invalidate child windows in InvalidateRgn(). + + * [windows/defwnd.c] + Added repaint of the caption when changing window text. + + * [windows/event.c] + Modified SetCapture() to allow keyboard events while capturing. + + * [windows/message.c] + New function MSG_GetHardwareMessage(), to do mouse tracking + without returning control to the Windows program. + + * [windows/nonclient.c] + A couple of changes in frame drawing for DLGMODALFRAME windows. + Rewritten window moving code, to use MSG_GetHardwareMessage() + instead of non-client mouse events (this is the way Windows + does it), and to send WM_ENTERSIZEMOVE messages. + Removed WM_NCBUTTONUP and WM_NCMOUSEMOVE handlers. + + * [windows/win.c] + Allocate temporary structures on the USER heap instead of + using GlobalAlloc(). + + * [windows/winpos.c] + Added function WINPOS_GetMinMaxInfo() to get sizing informations. + +Jan 31, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) + + * [windows/nonclient.c] + Call to StdDrawScrollBar() during NC's drawing. + Call to NC_ScrollBarButtonDown() on NC mouse events WM_LBUTTONDOWN. + Call to NC_ScrollBarButtonUp() on NC mouse events WM_LBUTTONUP. + Call to NC_ScrollBarMouseMove() on NC mouse events WM_MOUSEMOVE. + + * [controls/menu.c] + New GetSubMenu() function. + Move GetMenu() & SetMenu() functions from 'windows/win.c'. + + * [controls/combo.c] + Start changes to satisfy recent changes in scrollbars/windows. + + * [loader/resource.c] + Put some code in LoadAccelerators() stub. + New TranslateAccelerator() function. + + * [windows/win.c] + Remove GetMenu() & SetMenu() functions. + Call to NC_CreateScrollBars() if required by CreateWindow(). + +---------------------------------------------------------------------- +Mon Jan 24 10:40:10 EST 1994 John Richardson (jrichard@cs.uml.edu) + + * [window/win.c] + Added functions EnumWindows, EnumChildWindows, and helper + WIN_EnumChildWin. EnumWindows won't list all wine windows + because GetDesktopWindow isn't complete. However, the code + is in place for it to work correctly and only needs + GetDesktopWindow to do so. + +Tue Jan 25 05:51:47 1994 julliard@di.epfl.ch (Alexandre Julliard) + + * [windows/defwnd.c] + Added handling of activation messages (WM_ACTIVATE, + WM_NCACTIVATE, WM_MOUSEACTIVATE) + + * [windows/event.c] + De-activate the window when losing input focus. + + * [windows/focus.c] + Bug fix in SetFocus(). + + * [windows/message.c] + Added activation of the window on mouse-clicks. + + * [windows/nonclient.c] + Changed non-client area painting to use the correct colors + depending upon the activation state. + Added WM_NCACTIVATE message handling. + Fixed a couple of bugs in window moving and resizing. + + * [windows/winpos.c] + Implemented Get/SetActiveWindow(). + Implemented SWP_NOACTIVATE flag in SetWindowPos(). + +Jan 17, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) + + * [misc/message.c] + MessageBox has a CaptionBar for his title except for + MB_SYSTEMMODAL with MB_ICONHAND. + + * [windows/nonclient.c] + Call to NC_TrackSysMenu on SysMenu button mouse click. + + * [windows/defwnd.c] + Call to NC_TrackSysMenu on Alt key (VK_MENU). + + * [controls/menu.c] + New GetSystemMenu() function. + New CopySystemMenu() internal function. + New NC_TrackSysMenu() internal function. + + * [include/windows.h] + New WM_INITMENU, WM_INITMENUPOPUP, WM_MENUSELECT & WM_MENUCHAR defines. + +---------------------------------------------------------------------- Thu Jan 13 11:45:13 1994 John Richardson * [window/win.c] diff --git a/DEVELOPERS-HINTS b/DEVELOPERS-HINTS new file mode 100644 index 00000000000..3321aa9d06f --- /dev/null +++ b/DEVELOPERS-HINTS @@ -0,0 +1,81 @@ +This is intend to be a document to help new developers get started. +Existing developers should feel free to add there comments. + +RESERVING WINE PROJECT ARES: + +If you wish to work on a specific set of API functions. Send +mail to wine-project@amscons.com. The automatic mail handler +will provide you with instructions. + +SUBMITTING YOUR WORK: + +Submissions of code for inclussion into Wine should be sent to +bob@amscons.com (Bob Amstadt). You MUST provide a suitable +ChangeLog entry for any work that you submit. I prefer new code +to be submitted as diffs off of the latest release. Releases are +every Tuesday evening (approximately 19:00 PST or Wednesday 03:00 GMT). + +MEMORY AND SEGMENTS: + +NE (Win16) executables consist of multiple segments. The Wine loader +loads each segment into a unique location the Wine processes memory +and assigns a selector to that segment. To make address conversion +simpler, Wine loads the segments in such a way that the segmented +address (16:16) is stored in memory the same way as the 32-bit linear +address. For example, the segmented address 1237:89AB can be at the +address 0x123789AB in the Wine process space. + +This also implies that a Win16 program cannot access any arbitrary +memory location. If a pointer needs to be returned to a Win16 program, +then the memory block must be allocated using either GlobalAlloc() +or HEAP_Alloc(). The HEAP_* functions are faster than the Global* +functions but are only capable of managing a 64k memory block. The +HEAP_* functions are used to implement local heaps. Wine should +never call Local* functions. These functions are reserved for use +by Win16 programs only! + +The following code fragment should be used to establish a new Wine +local heap: + + #include "heap.h" + + #define MY_HEAP_SIZE 0x10000 /* Must be <= 64k */ + + int MyHeapHandle; + void *MyHeapBase; + MDESC *MyHeap; + + ... + + int InitMyHeap() + { + MyHeapHandle = GlobalAlloc(GMEM_FIXED, MY_HEAP_SIZE); + if (MyHeapHandle == 0) + return -1; + MyHeapBase = GlobalLock(MyHeapHandle); + HEAP_Init(&MyHeap, MyHeapBase, MY_HEAP_SIZE); + return 0; + } + +Memory blocks greater than 64 kilobytes in length must be allocated +using GlobalAlloc(). Because of our special memory mapping, GlobalLock() +cannot be used to obtain the address of a linearly accessible memory +block that is greater than 64kB in length. Instead GlobalLinearLock() +should be used. The inverse function GlobalLinearUnlock() must be +called before the block can be freed with GlobalFree(). + +API ENTRY POINTS: + +Because Win16 programs use a 16-bit stack and because they can only +call 16:16 addressed functions, all API entry points must be at low +address offsets and must have the arguments translated and moved to +Wines 32-bit stack. This task is handled by the code in the "if1632" +directory. To define a new API entry point handler you must place a +new entry in the appropriate API specification file. These files are +named *.spec. For example, the API specification file for the USER DLL +is contained in the file user.spec. These entries are processed by +the "build" program to create dll_*.s and dll_tab_*.c. The dll_*.s +files contain the entry point code for each API call, and the dll_tab_*.s +files contain tables used by relay.c to translate arguments and transfer +control to the proper handler. The format of the *.spec files is +documented in the file "tools/build-spec.txt". \ No newline at end of file diff --git a/Imakefile b/Imakefile index 26b35f407aa..05b5b4f0f9a 100644 --- a/Imakefile +++ b/Imakefile @@ -1,21 +1,22 @@ #include "Wine.tmpl" /* - * This is the first try at using Imakefiles. There are probably many - * problems and things I haven't even considered. I do not have a Linux - * system to test them on, just NetBSD, so you may need to change things - * like the the SYSLIBS definition below... + * This is the second try at using Imakefiles. There are probably many + * problems and things I haven't even considered. I do not have a fixed + * Linux system to test them on, but thanks to Thomas Michlmayr + * for use of one of his boxes. * - * Peter Galbavy, 5th Dec 1993 peter@wonderland.org + * SEE BELOW ABOUT DEBUGGING AND LINUX + * + * Peter Galbavy, 31st Jan 1994: peter@wonderland.org */ -#define IHaveSubDirs +#define IHaveSubdirs #define PassCDebugFlags 'CDEBUGFLAGS=$(CDEBUGFLAGS)' 'CC=$(CC)' SUBDIRS = \ tools \ controls \ - debugger \ etc \ if1632 \ include \ @@ -26,6 +27,21 @@ SUBDIRS = \ test \ windows +/* + * due to me not having the time and resources to test this, debugging + * has been left out by for now of the Imakefiles. To put it back you have + * to add: + * debugger + * to the SUBDIRS list and: + * debugger + * readline.o + * to the OBJS list. + * + * Not doing this will make the build fail in loader/signal.c, with an + * unresolved reference to wine_debug. Comment out the line for now... + * sigh. Fixed soon. + */ + WINEDIR = $(LIBDIR)/wine OBJS = \ @@ -35,32 +51,29 @@ OBJS = \ memory.o \ misc.o \ objects.o \ - windows.o \ - debugger.o \ - readline.o + windows.o #ifdef i386BsdArchitecture SYSLIBS = -ll -lm -li386 -lgnumalloc #else -#ifdef LinuxArchitechture +#ifdef LinuxArchitecture SYSLIBS = -lm #endif #endif -AllTarget(wine) - -NamedTargetSubdirs($(OBJS),$(SUBDIRS),"making",PassCDebugFlags,all) -MakefileSubdirs($(SUBDIRS)) +MakeSubdirs($(SUBDIRS)) DependSubdirs($(SUBDIRS)) -IncludesSubdirs($(SUBDIRS)) -CleanSubdirs($(SUBDIRS)) + +#ifdef i386BsdArchitecture +AllTarget(wine) +#endif NormalProgramTarget(wine,$(OBJS),XawClientDepLibs,XawClientLibs,$(SYSLIBS)) +#ifdef LinuxArchitecture +AllTarget(wine) +#endif + depend:: install:: - -includes:: - -clean:: diff --git a/Makefile b/Makefile index 033a5bf9c88..bbae18ac65c 100644 --- a/Makefile +++ b/Makefile @@ -27,6 +27,9 @@ clean: rm -f *~ *.o *# @for i in tools $(SUBDIRS); do (cd $$i && $(MAKE) clean) || exit; done +patchclean: + rm -f `find . -name '*.orig' -o -name '*.rej'` + $(TARGET): dummy @for i in tools $(SUBDIRS); \ do (cd $$i && echo $$i && $(MAKE) INCLUDE_DIR=../$(INCLUDE_DIR) \ @@ -36,5 +39,5 @@ $(TARGET): dummy depend: @for i in tools $(SUBDIRS); \ do (cd $$i && echo $$i && \ - $(MAKE) INCLUDE_DIR=../$(INCLUDE_DIR) depend) \ + $(MAKE) INCLUDE_DIR=../$(INCLUDE_DIR) COPTS="$(COPTS)" depend) \ || exit; done diff --git a/README b/README index 1b23e0588b4..6b0e42a3545 100644 --- a/README +++ b/README @@ -41,6 +41,17 @@ For example: to run Windows' solitaire: Have a nice game of solitaire, but be careful. Emulation isn't perfect. So, occassionally it will crash. +WHAT'S NEW with Wine-940201: (see ChangeLog for details) + - Support for huge data structures. + - FreeBSD support. + - Many many bug fixes + +WHAT'S NEW with version 0.8: (see ChangeLog for details) + - Eliminated Xt-dependent code. Thanks to Alexandre and Martin. + - EnumWindows() and EnumChildWindows() + - Activating and deactivating of windows. + - More work on system menus. + WHAT'S NEW with version 0.7: (see ChangeLog for details) - Eliminated Xt-dependent code. Thanks to Alexandre and Martin. - Other bug fixes. diff --git a/bsdmake.patch b/bsdmake.patch index 68fa15782a3..92dc3a5c879 100644 --- a/bsdmake.patch +++ b/bsdmake.patch @@ -1,15 +1,22 @@ -diff -ruN ../Backup//Makefile ./Makefile ---- ../Backup//Makefile Tue Sep 14 09:47:00 1993 -+++ ./Makefile Thu Sep 16 09:59:52 1993 -@@ -7,7 +7,7 @@ - ###################################################################### - # These definitions are for the top level - TARGET=wine --LIBS=-L. -L/usr/X386/lib -lXext -lXaw -lXt -lXmu -lX11 -lm -+LIBS=-L. -L/usr/X386/lib -lXext -lXaw -lXt -lXmu -lX11 -lm -li386 -lgnumalloc -ll - OBJS=if1632/if1632.o controls/controls.o loader/loader.o \ - memory/memory.o misc/misc.o objects/objects.o windows/windows.o - SUBDIRS=if1632 controls loader memory misc objects windows +*** Makefile.orig Tue Jan 18 12:36:47 1994 +--- Makefile Mon Jan 24 22:34:06 1994 +*************** +*** 8,14 **** + ###################################################################### + # These definitions are for the top level + TARGET=wine +! LIBS=-L/usr/X386/lib -lX11 -lm + OBJS=if1632/if1632.o controls/controls.o loader/loader.o \ + memory/memory.o misc/misc.o objects/objects.o windows/windows.o debugger/debugger.o + SUBDIRS=if1632 controls loader memory misc objects windows debugger +--- 8,14 ---- + ###################################################################### + # These definitions are for the top level + TARGET=wine +! LIBS=-L/usr/X386/lib -lX11 -lm -li386 -lgnumalloc -ll + OBJS=if1632/if1632.o controls/controls.o loader/loader.o \ + memory/memory.o misc/misc.o objects/objects.o windows/windows.o debugger/debugger.o + SUBDIRS=if1632 controls loader memory misc objects windows debugger diff -ruN ../Backup//controls/Makefile ./controls/Makefile --- ../Backup//controls/Makefile Sat Sep 11 22:13:44 1993 +++ ./controls/Makefile Thu Sep 16 10:00:24 1993 diff --git a/controls/Imakefile b/controls/Imakefile index aee3e147848..22fb4afae89 100644 --- a/controls/Imakefile +++ b/controls/Imakefile @@ -3,30 +3,24 @@ MODULE = controls SRCS = \ - menu.c \ - widgets.c \ button.c \ - scroll.c \ - listbox.c \ + caption.c \ combo.c \ + listbox.c \ + menu.c \ + scroll.c \ static.c \ - SmeMenuButto.c \ - WinLabel.c \ - WinCommand.c \ - WinMenuButto.c + widgets.c OBJS = \ - menu.o \ - widgets.o \ button.o \ - scroll.o \ - listbox.o \ + caption.o \ combo.o \ + listbox.o \ + menu.o \ + scroll.o \ static.o \ - SmeMenuButto.o \ - WinLabel.o \ - WinCommand.o \ - WinMenuButto.o + widgets.o WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) DependTarget() diff --git a/controls/button.c b/controls/button.c index aad2aa10ca8..7ecd9db1808 100644 --- a/controls/button.c +++ b/controls/button.c @@ -512,8 +512,8 @@ static LONG CB_Paint(HWND hWnd) FillRect(hDC, &rc, hBrush); textlen = GetWindowTextLength(hWnd); - hText = LocalAlloc(LMEM_MOVEABLE, textlen+1); - text = LocalLock(hText); + hText = USER_HEAP_ALLOC(0, textlen+1); + text = USER_HEAP_ADDR(hText); GetWindowText(hWnd, text, textlen+1); GetTextMetrics(hDC, &tm); @@ -555,8 +555,7 @@ static LONG CB_Paint(HWND hWnd) DrawFocusRect(hDC, &rc); } - LocalUnlock(hText); - LocalFree(hText); + USER_HEAP_FREE(hText); GlobalUnlock(hWnd); EndPaint(hWnd, &ps); } @@ -725,8 +724,8 @@ static LONG RB_Paint(HWND hWnd) FillRect(hDC, &rc, hBrush); textlen = GetWindowTextLength(hWnd); - hText = LocalAlloc(LMEM_MOVEABLE, textlen+1); - text = LocalLock(hText); + hText = USER_HEAP_ALLOC(0, textlen+1); + text = USER_HEAP_ADDR(hText); GetWindowText(hWnd, text, textlen+1); GetTextMetrics(hDC, &tm); @@ -760,8 +759,7 @@ static LONG RB_Paint(HWND hWnd) DrawFocusRect(hDC, &rc); } - LocalUnlock(hText); - LocalFree(hText); + USER_HEAP_FREE(hText); GlobalUnlock(hWnd); EndPaint(hWnd, &ps); } @@ -900,8 +898,8 @@ static LONG GB_Paint(HWND hWnd) FillRect(hDC, &rc, hBrush); textlen = GetWindowTextLength(hWnd); - hText = LocalAlloc(LMEM_MOVEABLE, textlen+1); - text = LocalLock(hText); + hText = USER_HEAP_ALLOC(0, textlen+1); + text = USER_HEAP_ADDR(hText); GetWindowText(hWnd, text, textlen+1); GetTextExtentPoint(hDC, text, textlen, &size); @@ -913,8 +911,7 @@ static LONG GB_Paint(HWND hWnd) rc.bottom = size.cy; DrawText(hDC, text, textlen, &rc, DT_SINGLELINE); - LocalUnlock(hText); - LocalFree(hText); + USER_HEAP_FREE(hText); EndPaint(hWnd, &ps); } diff --git a/controls/combo.c b/controls/combo.c index f4af8dca75b..2bcde7f37c1 100644 --- a/controls/combo.c +++ b/controls/combo.c @@ -66,9 +66,15 @@ LONG ComboBoxWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) lphc->hWndDrop = CreateWindow("BUTTON", "", WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | BS_OWNERDRAW, width - 16, 0, 16, 16, hwnd, 1, wndPtr->hInstance, 0L); - lphc->hWndEdit = CreateWindow("STATIC", "", - WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | SS_LEFT, - 0, 0, width - 16, 16, hwnd, 1, wndPtr->hInstance, 0L); + if (wndPtr->dwStyle & CBS_SIMPLE) +/* lphc->hWndEdit = CreateWindow("EDIT", "", */ + lphc->hWndEdit = CreateWindow("STATIC", "", + WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | SS_LEFT, + 0, 0, width - 16, 16, hwnd, 1, wndPtr->hInstance, 0L); + else + lphc->hWndEdit = CreateWindow("STATIC", "", + WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | SS_LEFT, + 0, 0, width - 16, 16, hwnd, 1, wndPtr->hInstance, 0L); lphc->hWndLBox = CreateWindow("LISTBOX", "", WS_CHILD | WS_CLIPCHILDREN | WS_BORDER | WS_VSCROLL | LBS_NOTIFY, wndPtr->rectClient.left, wndPtr->rectClient.top + 16, width, height, @@ -128,7 +134,7 @@ LONG ComboBoxWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) switch(HIWORD(lParam)) { case LBN_SELCHANGE: - lphc->dwState = lphc->dwState & (CB_SHOWDROPDOWN ^ 0xFFFF); + lphc->dwState = lphc->dwState & (CB_SHOWDROPDOWN ^ 0xFFFFFFFFL); ShowWindow(lphc->hWndLBox, SW_HIDE); y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L); if (y != LB_ERR) { diff --git a/controls/listbox.c b/controls/listbox.c index b1dfb731b25..642d47ef35e 100644 --- a/controls/listbox.c +++ b/controls/listbox.c @@ -79,11 +79,11 @@ LONG ListBoxWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) else lphl->hWndLogicParent = GetParent(hwnd); lphl->ColumnsWidth = wndPtr->rectClient.right - wndPtr->rectClient.left; - if (wndPtr->hWndVScroll != (HWND)NULL) { + if (wndPtr->dwStyle & WS_VSCROLL) { SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, TRUE); ShowScrollBar(hwnd, SB_VERT, FALSE); } - if (wndPtr->hWndHScroll != (HWND)NULL) { + if (wndPtr->dwStyle & WS_HSCROLL) { SetScrollRange(hwnd, SB_HORZ, 1, 1, TRUE); ShowScrollBar(hwnd, SB_HORZ, FALSE); } @@ -225,7 +225,7 @@ LONG ListBoxWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) lphl = ListBoxGetStorageHeader(hwnd); if (lphl->FirstVisible > 1) { lphl->FirstVisible--; - if (wndPtr->hWndVScroll != (HWND)NULL) + if (wndPtr->dwStyle & WS_VSCROLL) SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); @@ -237,7 +237,7 @@ LONG ListBoxWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) lphl = ListBoxGetStorageHeader(hwnd); if (lphl->FirstVisible < lphl->ItemsCount) { lphl->FirstVisible++; - if (wndPtr->hWndVScroll != (HWND)NULL) + if (wndPtr->dwStyle & WS_VSCROLL) SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); @@ -310,7 +310,7 @@ LONG ListBoxWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) if ((wndPtr->dwStyle & LBS_MULTIPLESEL) != LBS_MULTIPLESEL) { ListBoxSetCurSel(hwnd, lphl->ItemFocused); } - if (wndPtr->hWndVScroll != (HWND)NULL) + if (wndPtr->dwStyle & WS_VSCROLL) SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); @@ -419,7 +419,7 @@ LONG ListBoxWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) printf("ListBox LB_SETTOPINDEX wParam=%x !\n", wParam); lphl = ListBoxGetStorageHeader(hwnd); lphl->FirstVisible = wParam; - if (wndPtr->hWndVScroll != (HWND)NULL) + if (wndPtr->dwStyle & WS_VSCROLL) SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); @@ -482,10 +482,10 @@ void StdDrawListBox(HWND hwnd) MAKELONG(hwnd, CTLCOLOR_LISTBOX)); if (hBrush == (HBRUSH)NULL) hBrush = GetStockObject(WHITE_BRUSH); GetClientRect(hwnd, &rect); - if ((wndPtr->hWndVScroll != (HWND)NULL) && - IsWindowVisible(wndPtr->hWndVScroll)) rect.right -= 16; - if ((wndPtr->hWndHScroll != (HWND)NULL) && - IsWindowVisible(wndPtr->hWndHScroll)) rect.bottom -= 16; +/* + if (wndPtr->dwStyle & WS_VSCROLL) rect.right -= 16; + if (wndPtr->dwStyle & WS_HSCROLL) rect.bottom -= 16; +*/ FillRect(hdc, &rect, hBrush); maxwidth = rect.right; rect.right = lphl->ColumnsWidth; @@ -531,9 +531,11 @@ void StdDrawListBox(HWND hwnd) EndOfPaint: EndPaint( hwnd, &ps ); if ((lphl->ItemsCount > lphl->ItemsVisible) & - (wndPtr->hWndVScroll != (HWND)NULL)) { + (wndPtr->dwStyle & WS_VSCROLL)) { +/* InvalidateRect(wndPtr->hWndVScroll, NULL, TRUE); UpdateWindow(wndPtr->hWndVScroll); +*/ } } @@ -563,10 +565,8 @@ void OwnerDrawListBox(HWND hwnd) MAKELONG(hwnd, CTLCOLOR_LISTBOX)); if (hBrush == (HBRUSH)NULL) hBrush = GetStockObject(WHITE_BRUSH); GetClientRect(hwnd, &rect); - if ((wndPtr->hWndVScroll != (HWND)NULL) && - IsWindowVisible(wndPtr->hWndVScroll)) rect.right -= 16; - if ((wndPtr->hWndHScroll != (HWND)NULL) && - IsWindowVisible(wndPtr->hWndHScroll)) rect.bottom -= 16; + if (wndPtr->dwStyle & WS_VSCROLL) rect.right -= 16; + if (wndPtr->dwStyle & WS_HSCROLL) rect.bottom -= 16; FillRect(hdc, &rect, hBrush); maxwidth = rect.right; rect.right = lphl->ColumnsWidth; @@ -612,9 +612,11 @@ void OwnerDrawListBox(HWND hwnd) EndOfPaint: EndPaint( hwnd, &ps ); if ((lphl->ItemsCount > lphl->ItemsVisible) & - (wndPtr->hWndVScroll != (HWND)NULL)) { + (wndPtr->dwStyle & WS_VSCROLL)) { +/* InvalidateRect(wndPtr->hWndVScroll, NULL, TRUE); UpdateWindow(wndPtr->hWndVScroll); +*/ } } @@ -634,10 +636,8 @@ int ListBoxFindMouse(HWND hwnd, int X, int Y) lpls = lphl->lpFirst; if (lpls == NULL) return LB_ERR; GetClientRect(hwnd, &rect); - if ((wndPtr->hWndVScroll != (HWND)NULL) && - IsWindowVisible(wndPtr->hWndVScroll)) rect.right -= 16; - if ((wndPtr->hWndHScroll != (HWND)NULL) && - IsWindowVisible(wndPtr->hWndHScroll)) rect.bottom -= 16; + if (wndPtr->dwStyle & WS_VSCROLL) rect.right -= 16; + if (wndPtr->dwStyle & WS_HSCROLL) rect.bottom -= 16; h = w2 = 0; w = lphl->ColumnsWidth; for(i = 1; i <= lphl->ItemsCount; i++) { @@ -720,10 +720,10 @@ int ListBoxAddString(HWND hwnd, LPSTR newstr) lplsnew->dis.itemID = lphl->ItemsCount; lplsnew->dis.itemData = (DWORD)newstr; lplsnew->hData = hTemp; - if (wndPtr->hWndVScroll != (HWND)NULL) + if (wndPtr->dwStyle & WS_VSCROLL) SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, (lphl->FirstVisible != 1)); - if (wndPtr->hWndHScroll != (HWND)NULL && lphl->ItemsPerColumn != 0) + if ((wndPtr->dwStyle & WS_HSCROLL) && lphl->ItemsPerColumn != 0) SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / lphl->ItemsPerColumn + 1, (lphl->FirstVisible != 1)); if (lphl->FirstVisible >= (lphl->ItemsCount - lphl->ItemsVisible)) { @@ -731,9 +731,9 @@ int ListBoxAddString(HWND hwnd, LPSTR newstr) UpdateWindow(hwnd); } if ((lphl->ItemsCount - lphl->FirstVisible) == lphl->ItemsVisible) { - if (wndPtr->hWndVScroll != (HWND)NULL) + if (wndPtr->dwStyle & WS_VSCROLL) ShowScrollBar(hwnd, SB_VERT, TRUE); - if (wndPtr->hWndHScroll != (HWND)NULL) + if (wndPtr->dwStyle & WS_HSCROLL) ShowScrollBar(hwnd, SB_HORZ, TRUE); } return lphl->ItemsCount; @@ -779,17 +779,17 @@ int ListBoxInsertString(HWND hwnd, UINT uIndex, LPSTR newstr) lplsnew->dis.itemID = lphl->ItemsCount; lplsnew->dis.itemData = (DWORD)newstr; lplsnew->hData = hTemp; - if (wndPtr->hWndVScroll != (HWND)NULL) + if (wndPtr->dwStyle & WS_VSCROLL) SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, (lphl->FirstVisible != 1)); - if (wndPtr->hWndHScroll != (HWND)NULL && lphl->ItemsPerColumn != 0) + if ((wndPtr->dwStyle & WS_HSCROLL) && lphl->ItemsPerColumn != 0) SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / lphl->ItemsPerColumn + 1, (lphl->FirstVisible != 1)); if (((lphl->ItemsCount - lphl->FirstVisible) == lphl->ItemsVisible) && (lphl->ItemsVisible != 0)) { - if (wndPtr->hWndVScroll != (HWND)NULL) + if (wndPtr->dwStyle & WS_VSCROLL) ShowScrollBar(hwnd, SB_VERT, TRUE); - if (wndPtr->hWndHScroll != (HWND)NULL) + if (wndPtr->dwStyle & WS_HSCROLL) ShowScrollBar(hwnd, SB_HORZ, TRUE); } if ((lphl->FirstVisible <= uIndex) && @@ -851,15 +851,15 @@ int ListBoxDeleteString(HWND hwnd, UINT uIndex) lphl->ItemsCount--; if (lpls->hData != 0) USER_HEAP_FREE(lpls->hData); if (lpls->hMem != 0) USER_HEAP_FREE(lpls->hMem); - if (wndPtr->hWndVScroll != (HWND)NULL) + if (wndPtr->dwStyle & WS_VSCROLL) SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, TRUE); - if (wndPtr->hWndHScroll != (HWND)NULL && lphl->ItemsPerColumn != 0) + if ((wndPtr->dwStyle & WS_HSCROLL) && lphl->ItemsPerColumn != 0) SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / lphl->ItemsPerColumn + 1, TRUE); if (lphl->ItemsCount < lphl->ItemsVisible) { - if (wndPtr->hWndVScroll != (HWND)NULL) + if (wndPtr->dwStyle & WS_VSCROLL) ShowScrollBar(hwnd, SB_VERT, FALSE); - if (wndPtr->hWndHScroll != (HWND)NULL) + if (wndPtr->dwStyle & WS_HSCROLL) ShowScrollBar(hwnd, SB_HORZ, FALSE); } if ((lphl->FirstVisible <= uIndex) && @@ -922,14 +922,14 @@ int ListBoxResetContent(HWND hwnd) SendMessage(wndPtr->hwndParent, WM_COMMAND, wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE)); - if (wndPtr->hWndVScroll != (HWND)NULL) + if (wndPtr->dwStyle & WS_VSCROLL) SetScrollRange(hwnd, SB_VERT, 1, lphl->ItemsCount, TRUE); - if (wndPtr->hWndHScroll != (HWND)NULL && lphl->ItemsPerColumn != 0) + if ((wndPtr->dwStyle & WS_HSCROLL) && lphl->ItemsPerColumn != 0) SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / lphl->ItemsPerColumn + 1, TRUE); - if (wndPtr->hWndVScroll != (HWND)NULL) + if (wndPtr->dwStyle & WS_VSCROLL) ShowScrollBar(hwnd, SB_VERT, FALSE); - if (wndPtr->hWndHScroll != (HWND)NULL) + if (wndPtr->dwStyle & WS_HSCROLL) ShowScrollBar(hwnd, SB_HORZ, FALSE); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); diff --git a/controls/menu.c b/controls/menu.c index 8c43e6fd423..add8f1820e2 100644 --- a/controls/menu.c +++ b/controls/menu.c @@ -4,18 +4,26 @@ static char Copyright2[] = "Copyright Martin Ayotte, 1993"; /* #define DEBUG_MENU +#define DEBUG_SYSMENU */ #define USE_POPUPMENU #include #include #include "windows.h" +#include "sysmetrics.h" #include "menu.h" #include "heap.h" #include "win.h" #include "bitmaps/check_bitmap" #include "bitmaps/nocheck_bitmap" +#define SC_ABOUTWINE SC_SCREENSAVE+1 +#define SC_SYSMENU SC_SCREENSAVE+2 +#define SC_ABOUTWINEDLG SC_SCREENSAVE+3 + +extern HINSTANCE hSysRes; +HMENU hSysMenu = 0; HBITMAP hStdCheck = 0; HBITMAP hStdMnArrow = 0; @@ -40,9 +48,12 @@ WORD GetSelectionKey(LPSTR str); LPSTR GetShortCutString(LPSTR str); WORD GetShortCutPos(LPSTR str); BOOL HideAllSubPopupMenu(LPPOPUPMENU menu); +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); + /*********************************************************************** * PopupMenuWndProc */ @@ -98,13 +109,26 @@ LONG PopupMenuWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) return 0; case WM_COMMAND: lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); -#ifdef DEBUG_MENU - printf("PopupMenu // push to lower parent WM_COMMAND !\n"); -#endif - if (lppop->hWndParent != (HWND)NULL) + if (lppop->hWndParent != (HWND)NULL) { SendMessage(lppop->hWndParent, WM_COMMAND, wParam, lParam); - else - SendMessage(lppop->ownerWnd, WM_COMMAND, wParam, lParam); +#ifdef DEBUG_MENU + printf("PopupMenu // push to lower parent WM_COMMAND !\n"); +#endif + } + else { + if (lppop->SysFlag == 0) { + SendMessage(lppop->ownerWnd, WM_COMMAND, wParam, lParam); +#ifdef DEBUG_MENU + printf("PopupMenu // push to Owner WM_COMMAND !\n"); +#endif + } + else { +#ifdef DEBUG_SYSMENU + printf("PopupMenu // push to Owner WM_SYSCOMMAND !\n"); +#endif + SendMessage(lppop->ownerWnd, WM_SYSCOMMAND, wParam, lParam); + } + } if (lppop->BarFlags == 0) ShowWindow(hwnd, SW_HIDE); break; case WM_SHOWWINDOW: @@ -169,16 +193,18 @@ LONG PopupMenuWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) GetClientRect(hwnd, &rect); if (lppop->BarFlags != 0) { y = rect.bottom - rect.top; + GetWindowRect(hwnd, &rect); + y += rect.top; TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, - lpitem->rect.left, 0, - 0, lppop->ownerWnd, (LPRECT)NULL); + rect.left + lpitem->rect.left, + y, 0, lppop->ownerWnd, (LPRECT)NULL); } else { x = rect.right; GetWindowRect(hwnd, &rect); x += rect.left; TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, - x, lpitem->rect.top, + x, rect.top + lpitem->rect.top, 0, lppop->ownerWnd, (LPRECT)NULL); } break; @@ -199,12 +225,40 @@ LONG PopupMenuWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) if (((lpitem->item_flags & MF_SEPARATOR) != MF_SEPARATOR) && ((lpitem->item_flags & MF_POPUP) != MF_POPUP)) { ShowWindow(lppop->hWnd, SW_HIDE); - if (lppop->hWndParent != (HWND)NULL) + if (lppop->hWndParent != (HWND)NULL) { SendMessage(lppop->hWndParent, WM_COMMAND, lpitem->item_id, 0L); - else - SendMessage(lppop->ownerWnd, WM_COMMAND, +#ifdef DEBUG_MENU + printf("PopupMenu // WM_COMMAND to ParentMenu wParam=%d !\n", + lpitem->item_id); +#endif + } + else { + if (lppop->SysFlag == 0) { +#ifdef DEBUG_MENU + printf("PopupMenu // WM_COMMAND wParam=%d !\n", + lpitem->item_id); +#endif + SendMessage(lppop->ownerWnd, WM_COMMAND, lpitem->item_id, 0L); + } + else { + if (lpitem->item_id == SC_ABOUTWINE) { + printf("SysMenu // Show 'About Wine ...' !\n"); +/* DialogBox(hSysRes, MAKEINTRESOURCE(SC_ABOUTWINEDLG), */ + DialogBox(hSysRes, MAKEINTRESOURCE(2), + GetParent(hwnd), (FARPROC)AboutWine_Proc); + } + else { + SendMessage(lppop->ownerWnd, WM_SYSCOMMAND, + lpitem->item_id, 0L); +#ifdef DEBUG_SYSMENU + printf("PopupMenu // WM_SYSCOMMAND wParam=%04X !\n", + lpitem->item_id); +#endif + } + } + } #ifdef DEBUG_MENU printf("PopupMenu // SendMessage WM_COMMAND wParam=%d !\n", lpitem->item_id); @@ -248,10 +302,9 @@ LONG PopupMenuWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) if (lppop2 == NULL) break; if (lppop->BarFlags != 0) { lppop2->hWndParent = hwnd; - GetClientRect(hwnd, &rect); - y = rect.bottom - rect.top; + GetWindowRect(hwnd, &rect); TrackPopupMenu(hSubMenu, TPM_LEFTBUTTON, - lpitem->rect.left, 0, + lpitem->rect.left, rect.top, 0, lppop->ownerWnd, (LPRECT)NULL); } } @@ -747,6 +800,9 @@ void PopupMenuCalcSize(HWND hwnd) HFONT hOldFont; UINT i, OldWidth, TempWidth; DWORD dwRet; +#ifdef DEBUG_MENUCALC + printf("PopupMenuCalcSize hWnd=%04X !\n", hWnd); +#endif lppop = PopupMenuGetWindowAndStorage(hwnd, &wndPtr); if (lppop == NULL) return; if (lppop->nItems == 0) return; @@ -759,6 +815,9 @@ CalcAGAIN: lpitem = lppop->firstItem; for(i = 0; i < lppop->nItems; i++) { if (lpitem == NULL) break; +#ifdef DEBUG_MENUCALC + printf("PopupMenuCalcSize item #%d !\n", i); +#endif rect.right = rect.left + lppop->Width; if ((lpitem->item_flags & MF_SEPARATOR) == MF_SEPARATOR) { rect.bottom = rect.top + 3; @@ -788,11 +847,10 @@ CalcAGAIN: if (OldWidth < lppop->Width) goto CalcAGAIN; lppop->Height = rect.bottom; #ifdef DEBUG_MENUCALC - printf("PopupMenuCalcSize w=%d h=%d !\n", - lppop->Width, lppop->Height); + printf("PopupMenuCalcSize w=%d h=%d !\n", lppop->Width, lppop->Height); #endif SelectObject(hDC, hOldFont); - ReleaseDC(0, hDC); + ReleaseDC(hwnd, hDC); } @@ -1775,6 +1833,7 @@ HMENU CreatePopupMenu() menu->hWndParent = 0; menu->MouseFlags = 0; menu->BarFlags = 0; + menu->SysFlag = FALSE; menu->Width = 100; menu->Height = 0; return hMenu; @@ -1798,8 +1857,8 @@ BOOL TrackPopupMenu(HMENU hMenu, WORD wFlags, short x, short y, wndPtr = WIN_FindWndPtr(hWnd); lppop->ownerWnd = hWnd; if (lppop->hWnd == (HWND)NULL) { - lppop->hWnd = CreateWindow("POPUPMENU", "", WS_CHILD | WS_VISIBLE, - x, y, lppop->Width, lppop->Height, hWnd, 0, + lppop->hWnd = CreateWindow("POPUPMENU", "", WS_POPUP | WS_VISIBLE, + x, y, lppop->Width, lppop->Height, (HWND)NULL, 0, wndPtr->hInstance, (LPSTR)lppop); } else { @@ -1827,6 +1886,43 @@ BOOL TrackPopupMenu(HMENU hMenu, WORD wFlags, short x, short y, } +/********************************************************************** + * NC_TrackSysMenu [Internal] + */ +void NC_TrackSysMenu(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->BarFlags = FALSE; + lpsys->SysFlag = TRUE; + if (!IsWindowVisible(lpsys->hWnd)) { + GetWindowRect(hWnd, &rect); +#ifdef DEBUG_MENU + printf("NC_TrackSysMenu lpsys->hWnd=%04X !\n", lpsys->hWnd); +#endif + TrackPopupMenu(wndPtr->hSysMenu, TPM_LEFTBUTTON, + rect.left, rect.top + SYSMETRICS_CYSIZE, + 0, hWnd, (LPRECT)NULL); + } + else { + ShowWindow(lpsys->hWnd, SW_HIDE); + } +} + + /********************************************************************** * SetMenuItemBitmaps [USER.418] */ @@ -1881,6 +1977,7 @@ HMENU CreateMenu() menu->hWndParent = 0; menu->MouseFlags = 0; menu->BarFlags = TRUE; + menu->SysFlag = FALSE; menu->Width = 100; menu->Height = 0; return hMenu; @@ -1923,7 +2020,105 @@ BOOL DestroyMenu(HMENU hMenu) /********************************************************************** - * DrawMenuBar [USER.152] + * LoadMenu [USER.150] + */ +HMENU LoadMenu(HINSTANCE instance, char *menu_name) +{ + HMENU hMenu; + HANDLE hMenu_desc; + MENU_HEADER *menu_desc; + +#ifdef DEBUG_MENU + if ((LONG)menu_name & 0xFFFF0000L) + printf("LoadMenu: instance %02x, menu '%s'\n", instance, menu_name); + else + printf("LoadMenu: instance %02x, menu '%04X'\n", instance, menu_name); +#endif + if (instance == (HANDLE)NULL) instance = hSysRes; + if (menu_name == NULL || + (hMenu_desc = RSC_LoadMenu(instance, menu_name)) == 0 || + (menu_desc = (MENU_HEADER *) GlobalLock(hMenu_desc)) == NULL) + { + return 0; + } + hMenu = CreateMenu(); + ParseMenuResource((WORD *) (menu_desc + 1), 0, hMenu); + return hMenu; +} + + +/********************************************************************** + * GetSystemMenu [USER.156] + */ +HMENU GetSystemMenu(HWND hWnd, BOOL bRevert) +{ + WND *wndPtr; + wndPtr = WIN_FindWndPtr(hWnd); + if (!bRevert) { + return wndPtr->hSysMenu; + } + else { + DestroyMenu(wndPtr->hSysMenu); + wndPtr->hSysMenu = CopySysMenu(); + } + return wndPtr->hSysMenu; +} + + +/********************************************************************** + * GetMenu [USER.157] + */ +HMENU GetMenu(HWND hWnd) +{ + WND * wndPtr = WIN_FindWndPtr(hWnd); + if (wndPtr == NULL) return 0; + return wndPtr->wIDmenu; +} + +/********************************************************************** + * SetMenu [USER.158] + */ +BOOL SetMenu(HWND hWnd, HMENU hMenu) +{ + WND * wndPtr = WIN_FindWndPtr(hWnd); + if (wndPtr == NULL) return FALSE; + wndPtr->wIDmenu = hMenu; + return TRUE; +} + + +/********************************************************************** + * GetSubMenu [USER.159] + */ +HMENU GetSubMenu(HMENU hMenu, short nPos) +{ + HMENU hSubMenu; + LPPOPUPMENU lppop; + LPMENUITEM lpitem; + int i; +#ifdef DEBUG_MENU + 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) { + if (lpitem->item_flags & MF_POPUP) + return hSubMenu; + else + return 0; + } + lpitem = (LPMENUITEM)lpitem->next; + } + return 0; +} + + +/********************************************************************** + * DrawMenuBar [USER.160] */ void DrawMenuBar(HWND hWnd) { @@ -1940,31 +2135,53 @@ void DrawMenuBar(HWND hWnd) /********************************************************************** - * LoadMenu [USER.152] + * CopySysMenu (Internal) */ -HMENU LoadMenu(HINSTANCE instance, char *menu_name) +HMENU CopySysMenu() { HMENU hMenu; - HANDLE hMenu_desc; - MENU_HEADER *menu_desc; - + LPPOPUPMENU menu; + LPPOPUPMENU sysmenu; #ifdef DEBUG_MENU - printf("LoadMenu: instance %02x, menu '%s'\n", - instance, menu_name); + printf("CopySysMenu entry !\n"); #endif - if (menu_name == NULL || - (hMenu_desc = RSC_LoadMenu(instance, menu_name)) == 0 || - (menu_desc = (MENU_HEADER *) GlobalLock(hMenu_desc)) == NULL) - { - return 0; - } - hMenu = CreateMenu(); - ParseMenuResource((WORD *) (menu_desc + 1), 0, hMenu); - + 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->BarFlags = FALSE; + 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); return hMenu; } +/********************************************************************** + * ParseMenuResource (for Xlib version) + */ WORD * ParseMenuResource(WORD *first_item, int level, HMENU hMenu) { WORD *item; @@ -1975,12 +2192,10 @@ WORD * ParseMenuResource(WORD *first_item, int level, HMENU hMenu) level++; next_item = first_item; i = 0; - do - { + do { i++; item = next_item; - if (*item & MF_POPUP) - { + if (*item & MF_POPUP) { MENU_POPUPITEM *popup_item = (MENU_POPUPITEM *) item; next_item = (WORD *) (popup_item->item_text + strlen(popup_item->item_text) + 1); @@ -1988,20 +2203,19 @@ WORD * ParseMenuResource(WORD *first_item, int level, HMENU hMenu) next_item = ParseMenuResource(next_item, level, hSubMenu); AppendMenu(hMenu, popup_item->item_flags, hSubMenu, popup_item->item_text); - } - else - { + } + else { MENU_NORMALITEM *normal_item = (MENU_NORMALITEM *) item; next_item = (WORD *) (normal_item->item_text + strlen(normal_item->item_text) + 1); AppendMenu(hMenu, normal_item->item_flags, normal_item->item_id, normal_item->item_text); + } } - } while (!(*item & MF_END)); - return next_item; } + #endif diff --git a/controls/scroll.c b/controls/scroll.c index 47da5bfee9f..0f2aa848243 100644 --- a/controls/scroll.c +++ b/controls/scroll.c @@ -8,12 +8,12 @@ /* #define DEBUG_SCROLL */ - static char Copyright[] = "Copyright Martin Ayotte, 1993"; #include #include #include "windows.h" +#include "sysmetrics.h" #include "scroll.h" #include "heap.h" #include "win.h" @@ -30,33 +30,39 @@ HBITMAP hDnArrowD = 0; HBITMAP hLfArrowD = 0; HBITMAP hRgArrowD = 0; -LPHEADSCROLL ScrollBarGetWindowAndStorage(HWND hwnd, WND **wndPtr); -LPHEADSCROLL ScrollBarGetStorageHeader(HWND hwnd); -void StdDrawScrollBar(HWND hwnd); -int CreateScrollBarStruct(HWND hwnd); +LPHEADSCROLL ScrollBarGetWindowAndStorage(HWND hWnd, WND **wndPtr); +LPHEADSCROLL ScrollBarGetStorageHeader(HWND hWnd); +LPHEADSCROLL GetScrollObjectHandle(HWND hWnd, int nBar); +void ScrollBarButtonDown(HWND hWnd, int nBar, int x, int y); +void ScrollBarButtonUp(HWND hWnd, int nBar, int x, int y); +void ScrollBarMouseMove(HWND hWnd, int nBar, WORD wParam, int x, int y); +void StdDrawScrollBar(HWND hWnd, HDC hDC, int nBar, LPRECT lprect, LPHEADSCROLL lphs); +int CreateScrollBarStruct(HWND hWnd); +void NC_CreateScrollBars(HWND hWnd); +LPHEADSCROLL AllocScrollBar(DWORD dwStyle, int width, int height); /*********************************************************************** * WIDGETS_ScrollBarWndProc */ -LONG ScrollBarWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) +LONG ScrollBarWndProc( HWND hWnd, WORD message, WORD wParam, LONG lParam ) { WORD wRet; short x, y; short width, height; WND *wndPtr; LPHEADSCROLL lphs; - LPDRAWITEMSTRUCT lpdis; - HDC hMemDC; + PAINTSTRUCT ps; + HDC hDC; BITMAP bm; - RECT rect; + RECT rect, rect2; static RECT rectsel; switch(message) { case WM_CREATE: - CreateScrollBarStruct(hwnd); + CreateScrollBarStruct(hWnd); #ifdef DEBUG_SCROLL - printf("ScrollBar Creation up=%X down=%X!\n", lphs->hWndUp, lphs->hWndDown); + printf("ScrollBar Creation !\n"); #endif if (hUpArrow == (HBITMAP)NULL) hUpArrow = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_UPARROWI)); @@ -76,197 +82,271 @@ LONG ScrollBarWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) hRgArrowD = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_RGARROWD)); return 0; case WM_DESTROY: - lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr); + lphs = ScrollBarGetWindowAndStorage(hWnd, &wndPtr); if (lphs == 0) return 0; #ifdef DEBUG_SCROLL printf("ScrollBar WM_DESTROY %lX !\n", lphs); #endif - DestroyWindow(lphs->hWndUp); - DestroyWindow(lphs->hWndDown); free(lphs); *((LPHEADSCROLL *)&wndPtr->wExtra[1]) = 0; return 0; - case WM_COMMAND: -#ifdef DEBUG_SCROLL - printf("ScrollBar WM_COMMAND wParam=%X lParam=%lX !\n", wParam, lParam); -#endif - lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr); - if (HIWORD(lParam) != BN_CLICKED) return 0; - if (LOWORD(lParam) == lphs->hWndUp) - SendMessage(wndPtr->hwndParent, lphs->Direction, - SB_LINEUP, MAKELONG(0, hwnd)); - if (LOWORD(lParam) == lphs->hWndDown) - SendMessage(wndPtr->hwndParent, lphs->Direction, - SB_LINEDOWN, MAKELONG(0, hwnd)); -/* - SetFocus(hwnd); -*/ - return 0; - case WM_LBUTTONDOWN: - lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr); -/* - SetFocus(hwnd); -*/ - SetCapture(hwnd); - GetClientRect(hwnd, &rect); - if (lphs->Direction == WM_VSCROLL) { - y = HIWORD(lParam); -#ifdef DEBUG_SCROLL - printf("WM_LBUTTONDOWN y=%d cur+right=%d %d\n", - y, lphs->CurPix + rect.right, lphs->CurPix + (rect.right << 1)); -#endif - if (y < (lphs->CurPix + rect.right)) - SendMessage(wndPtr->hwndParent, lphs->Direction, - SB_PAGEUP, MAKELONG(0, hwnd)); - if (y > (lphs->CurPix + (rect.right << 1))) - SendMessage(wndPtr->hwndParent, lphs->Direction, - SB_PAGEDOWN, MAKELONG(0, hwnd)); - if ((y > (lphs->CurPix + rect.right)) && - (y < (lphs->CurPix + (rect.right << 1)))) { - lphs->ThumbActive = TRUE; -#ifdef DEBUG_SCROLL - printf("THUMB DOWN !\n"); -#endif - } - } - else { - x = LOWORD(lParam); -#ifdef DEBUG_SCROLL - printf("WM_LBUTTONDOWN x=%d Cur+bottom=%d %d\n", - x, lphs->CurPix + rect.bottom, lphs->CurPix + (rect.bottom << 1)); -#endif - if (x < (lphs->CurPix + rect.bottom)) - SendMessage(wndPtr->hwndParent, lphs->Direction, - SB_PAGEUP, MAKELONG(0, hwnd)); - if (x > (lphs->CurPix + (rect.bottom << 1))) - SendMessage(wndPtr->hwndParent, lphs->Direction, - SB_PAGEDOWN, MAKELONG(0, hwnd)); - if ((x > (lphs->CurPix + rect.bottom)) && - (x < (lphs->CurPix + (rect.bottom << 1)))) { - lphs->ThumbActive = TRUE; -#ifdef DEBUG_SCROLL - printf("THUMB DOWN !\n"); -#endif - } - } + SetCapture(hWnd); + ScrollBarButtonDown(hWnd, SB_CTL, LOWORD(lParam), HIWORD(lParam)); break; case WM_LBUTTONUP: - lphs = ScrollBarGetStorageHeader(hwnd); - lphs->ThumbActive = FALSE; ReleaseCapture(); + ScrollBarButtonUp(hWnd, SB_CTL, LOWORD(lParam), HIWORD(lParam)); break; case WM_MOUSEMOVE: - if ((wParam & MK_LBUTTON) != 0) { - lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr); - if (lphs->ThumbActive == 0) break; - GetClientRect(hwnd, &rect); - if (lphs->Direction == WM_VSCROLL) - y = HIWORD(lParam) - rect.right - (rect.right >> 1); - else - y = LOWORD(lParam) - rect.bottom - (rect.bottom >> 1); - x = (y * (lphs->MaxVal - lphs->MinVal) / - lphs->MaxPix) + lphs->MinVal; -#ifdef DEBUG_SCROLL - printf("Scroll WM_MOUSEMOVE val=%d pix=%d\n", x, y); -#endif - SendMessage(wndPtr->hwndParent, lphs->Direction, - SB_THUMBTRACK, MAKELONG(x, hwnd)); - } + ScrollBarMouseMove(hWnd, SB_CTL, wParam, LOWORD(lParam), HIWORD(lParam)); break; case WM_KEYDOWN: case WM_KEYUP: case WM_CHAR: - lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr); + lphs = ScrollBarGetWindowAndStorage(hWnd, &wndPtr); return(SendMessage(wndPtr->hwndParent, message, wParam, lParam)); - case WM_SIZE: - lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr); - width = LOWORD(lParam); - height = HIWORD(lParam); - if (lphs->Direction == WM_VSCROLL) { - MoveWindow(lphs->hWndUp, 0, 0, width, width, TRUE); - MoveWindow(lphs->hWndDown, 0, height - width, width, width, TRUE); - } - else { - MoveWindow(lphs->hWndUp, 0, 0, height, height, TRUE); - MoveWindow(lphs->hWndDown, width - height, 0, height, height, TRUE); - } - break; - case WM_DRAWITEM: + case WM_TIMER: #ifdef DEBUG_SCROLL - printf("Scroll WM_DRAWITEM w=%04X l=%08X\n", wParam, lParam); + printf("ScrollBar WM_TIMER wParam=%X lParam=%lX !\n", wParam, lParam); #endif - lpdis = (LPDRAWITEMSTRUCT)lParam; - if (lpdis->CtlType == ODT_BUTTON && lpdis->itemAction == ODA_DRAWENTIRE) { - hMemDC = CreateCompatibleDC(lpdis->hDC); - if (lpdis->CtlID == 1) { - GetObject(hUpArrow, sizeof(BITMAP), (LPSTR)&bm); - SelectObject(hMemDC, hUpArrow); -/* BitBlt(lpdis->hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); */ - StretchBlt(lpdis->hDC, 0, 0, lpdis->rcItem.right, lpdis->rcItem.right, - hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY); - } - if (lpdis->CtlID == 2) { - GetObject(hDnArrow, sizeof(BITMAP), (LPSTR)&bm); - SelectObject(hMemDC, hDnArrow); - BitBlt(lpdis->hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); - } - if (lpdis->CtlID == 3) { - GetObject(hLfArrow, sizeof(BITMAP), (LPSTR)&bm); - SelectObject(hMemDC, hLfArrow); - BitBlt(lpdis->hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); - } - if (lpdis->CtlID == 4) { - GetObject(hRgArrow, sizeof(BITMAP), (LPSTR)&bm); - SelectObject(hMemDC, hRgArrow); - BitBlt(lpdis->hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); - } - DeleteDC(hMemDC); + lphs = ScrollBarGetWindowAndStorage(hWnd, &wndPtr); + KillTimer(hWnd, wParam); + switch(lphs->ButtonDown) { + case 0: + lphs->TimerPending = FALSE; + return 0; + case 1: + case 3: + SendMessage(wndPtr->hwndParent, lphs->Direction, + SB_LINEUP, MAKELONG(0, hWnd)); + break; + case 2: + case 4: + SendMessage(wndPtr->hwndParent, lphs->Direction, + SB_LINEDOWN, MAKELONG(0, hWnd)); + break; + case 5: + SendMessage(wndPtr->hwndParent, lphs->Direction, + SB_PAGEUP, MAKELONG(0, hWnd)); + break; + case 6: + SendMessage(wndPtr->hwndParent, lphs->Direction, + SB_PAGEDOWN, MAKELONG(0, hWnd)); + break; } - if (lpdis->CtlType == ODT_BUTTON && lpdis->itemAction == ODA_SELECT) { - hMemDC = CreateCompatibleDC(lpdis->hDC); - if (lpdis->CtlID == 1) { - GetObject(hUpArrowD, sizeof(BITMAP), (LPSTR)&bm); - SelectObject(hMemDC, hUpArrowD); - BitBlt(lpdis->hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); - } - if (lpdis->CtlID == 2) { - GetObject(hDnArrowD, sizeof(BITMAP), (LPSTR)&bm); - SelectObject(hMemDC, hDnArrowD); - BitBlt(lpdis->hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); - } - if (lpdis->CtlID == 3) { - GetObject(hLfArrowD, sizeof(BITMAP), (LPSTR)&bm); - SelectObject(hMemDC, hLfArrowD); - BitBlt(lpdis->hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); - } - if (lpdis->CtlID == 4) { - GetObject(hRgArrowD, sizeof(BITMAP), (LPSTR)&bm); - SelectObject(hMemDC, hRgArrowD); - BitBlt(lpdis->hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); - } - DeleteDC(hMemDC); - } - break; + SetTimer(hWnd, 1, 100, NULL); + return 0; + case WM_PAINT: - StdDrawScrollBar(hwnd); + hDC = BeginPaint(hWnd, &ps); + lphs = ScrollBarGetStorageHeader(hWnd); + if (lphs != NULL) { + GetClientRect(hWnd, &rect); + StdDrawScrollBar(hWnd, hDC, SB_CTL, &rect, lphs); + } + EndPaint(hWnd, &ps); break; default: - return DefWindowProc( hwnd, message, wParam, lParam ); + return DefWindowProc( hWnd, message, wParam, lParam ); } return(0); } -LPHEADSCROLL ScrollBarGetWindowAndStorage(HWND hwnd, WND **wndPtr) +void ScrollBarButtonDown(HWND hWnd, int nBar, int x, int y) +{ + LPHEADSCROLL lphs; + HWND hWndParent; + RECT rect, rect2; + int width, height; + LONG dwOwner; + lphs = GetScrollObjectHandle(hWnd, nBar); + printf("ScrollBarButtonDown // x=%d y=%d\n", x, y); +#ifdef DEBUG_SCROLL + printf("ScrollBarButtonDown // x=%d y=%d\n", x, y); +#endif + if (nBar == SB_CTL) { + hWndParent = GetParent(hWnd); + dwOwner = MAKELONG(0, lphs->hWndOwner); + } + else { + hWndParent = hWnd; + dwOwner = 0L; + } +/* + SetFocus(lphs->hWndOwner); +*/ + if (nBar != SB_CTL) { + GetWindowRect(lphs->hWndOwner, &rect); + x -= rect.left; + y -= rect.top; + } + CopyRect(&rect, &lphs->rect); + printf("ScrollDown / x=%d y=%d left=%d top=%d right=%d bottom=%d \n", + x, y, rect.left, rect.top, rect.right, rect.bottom); + if (lphs->Direction == WM_VSCROLL) { + y -= rect.top; + width = rect.right - rect.left; + if (y < (lphs->CurPix + width)) { + if (y < width) { + lphs->ButtonDown = 1; + CopyRect(&rect2, &rect); + rect2.bottom = rect2.top + width; + InvalidateRect(lphs->hWndOwner, &rect2, TRUE); + printf("ScrollBarButtonDown // SB_LINEUP \n"); + SendMessage(hWndParent, lphs->Direction, + SB_LINEUP, dwOwner); + } + else { + lphs->ButtonDown = 5; + printf("ScrollBarButtonDown // SB_PAGEUP \n"); + SendMessage(hWndParent, lphs->Direction, + SB_PAGEUP, dwOwner); + } + } + if (y > (lphs->CurPix + (width << 1))) { + if (y > (rect.bottom - width)) { + lphs->ButtonDown = 2; + CopyRect(&rect2, &rect); + rect2.top = rect2.bottom - width; + InvalidateRect(lphs->hWndOwner, &rect2, TRUE); + printf("ScrollBarButtonDown // SB_LINEDOWN \n"); + SendMessage(hWndParent, lphs->Direction, + SB_LINEDOWN, dwOwner); + } + else { + lphs->ButtonDown = 6; + printf("ScrollBarButtonDown // SB_PAGEDOWN \n"); + SendMessage(hWndParent, lphs->Direction, + SB_PAGEDOWN, dwOwner); + } + } + if ((y > (lphs->CurPix + width)) && + (y < (lphs->CurPix + (width << 1)))) { + lphs->ThumbActive = TRUE; +#ifdef DEBUG_SCROLL + printf("THUMB DOWN !\n"); +#endif + } + } + else { + x -= rect.left; + height = rect.bottom - rect.top; + if (x < (lphs->CurPix + height)) { + if (x < height) { + lphs->ButtonDown = 3; + CopyRect(&rect2, &rect); + rect2.right = rect2.left + height; + InvalidateRect(lphs->hWndOwner, &rect2, TRUE); + SendMessage(hWndParent, lphs->Direction, + SB_LINEUP, dwOwner); + } + else { + lphs->ButtonDown = 5; + SendMessage(hWndParent, lphs->Direction, + SB_PAGEUP, dwOwner); + } + } + if (x > (lphs->CurPix + (height << 1))) { + if (x > (rect.right - rect.left - height)) { + lphs->ButtonDown = 4; + CopyRect(&rect2, &rect); + rect2.left = rect2.right - height; + InvalidateRect(lphs->hWndOwner, &rect2, TRUE); + SendMessage(hWndParent, lphs->Direction, + SB_LINEDOWN, dwOwner); + } + else { + lphs->ButtonDown = 6; + SendMessage(hWndParent, lphs->Direction, + SB_PAGEDOWN, dwOwner); + } + } + if ((x > (lphs->CurPix + height)) && + (x < (lphs->CurPix + (height << 1)))) { + lphs->ThumbActive = TRUE; +#ifdef DEBUG_SCROLL + printf("THUMB DOWN !\n"); +#endif + } + } + if (lphs->ButtonDown != 0) { + UpdateWindow(lphs->hWndOwner); + if (!lphs->TimerPending && nBar == SB_CTL) { + lphs->TimerPending = TRUE; + SetTimer(lphs->hWndOwner, 1, 500, NULL); + } + } +} + + +void ScrollBarButtonUp(HWND hWnd, int nBar, int x, int y) +{ + LPHEADSCROLL lphs; + RECT rect, rect2; + printf("ScrollBarButtonUp // x=%d y=%d\n", x, y); +#ifdef DEBUG_SCROLL + printf("ScrollBarButtonUp // x=%d y=%d\n", x, y); +#endif + lphs = GetScrollObjectHandle(hWnd, nBar); + lphs->ThumbActive = FALSE; + if (lphs->ButtonDown != 0) { + lphs->ButtonDown = 0; + GetClientRect(lphs->hWndOwner, &rect); + InvalidateRect(lphs->hWndOwner, &rect, TRUE); + UpdateWindow(lphs->hWndOwner); + } +} + + +void ScrollBarMouseMove(HWND hWnd, int nBar, WORD wParam, int x, int y) +{ + LPHEADSCROLL lphs; + HWND hWndParent; + HWND hWndOwner; + LONG dwOwner; + if ((wParam & MK_LBUTTON) == 0) return; +#ifdef DEBUG_SCROLL + printf("ScrollBarButtonMove // w=%04X x=%d y=%d \n", wParam, x, y); +#endif + lphs = GetScrollObjectHandle(hWnd, nBar); + if (lphs->ThumbActive == 0) return; + if (nBar == SB_CTL) { + hWndParent = GetParent(hWnd); + hWndOwner = lphs->hWndOwner; + } + else { + hWndParent = hWnd; + hWndOwner = 0; + } + if (lphs->Direction == WM_VSCROLL) { + int butsiz = lphs->rect.right - lphs->rect.left; + y = y - butsiz - (butsiz >> 1); + } + else { + int butsiz = lphs->rect.bottom - lphs->rect.top; + y = x - butsiz - (butsiz >> 1); + } + x = (y * (lphs->MaxVal - lphs->MinVal) / + lphs->MaxPix) + lphs->MinVal; +#ifdef DEBUG_SCROLL + printf("Scroll WM_MOUSEMOVE val=%d pix=%d\n", x, y); +#endif + SendMessage(hWndParent, lphs->Direction, + SB_THUMBTRACK, MAKELONG(x, hWndOwner)); +} + + +LPHEADSCROLL ScrollBarGetWindowAndStorage(HWND hWnd, WND **wndPtr) { WND *Ptr; LPHEADSCROLL lphs; - *(wndPtr) = Ptr = WIN_FindWndPtr(hwnd); + *(wndPtr) = Ptr = WIN_FindWndPtr(hWnd); if (Ptr == 0) { printf("Bad Window handle on ScrollBar !\n"); return 0; @@ -276,11 +356,11 @@ LPHEADSCROLL ScrollBarGetWindowAndStorage(HWND hwnd, WND **wndPtr) } -LPHEADSCROLL ScrollBarGetStorageHeader(HWND hwnd) +LPHEADSCROLL ScrollBarGetStorageHeader(HWND hWnd) { WND *wndPtr; LPHEADSCROLL lphs; - wndPtr = WIN_FindWndPtr(hwnd); + wndPtr = WIN_FindWndPtr(hWnd); if (wndPtr == 0) { printf("Bad Window handle on ScrollBar !\n"); return 0; @@ -290,106 +370,138 @@ LPHEADSCROLL ScrollBarGetStorageHeader(HWND hwnd) } -void StdDrawScrollBar(HWND hwnd) +void StdDrawScrollBar(HWND hWnd, HDC hDC, int nBar, LPRECT lprect, LPHEADSCROLL lphs) { - LPHEADSCROLL lphs; - PAINTSTRUCT ps; - HBRUSH hBrush; - HDC hdc; - RECT rect; - UINT i, w, h, siz; + HWND hWndParent; + HBRUSH hBrush; + HDC hMemDC; + BITMAP bm; + RECT rect; + UINT i, w, h, siz; char C[128]; - hdc = BeginPaint( hwnd, &ps ); - if (!IsWindowVisible(hwnd)) { - EndPaint( hwnd, &ps ); - return; - } - hBrush = SendMessage(GetParent(hwnd), WM_CTLCOLOR, (WORD)hdc, - MAKELONG(hwnd, CTLCOLOR_SCROLLBAR)); + if (lphs == NULL) return; +#ifdef DEBUG_SCROLL + if (lphs->Direction == WM_VSCROLL) + printf("StdDrawScrollBar Vertical left=%d top=%d right=%d bottom=%d !\n", + lprect->left, lprect->top, lprect->right, lprect->bottom); + else + printf("StdDrawScrollBar Horizontal left=%d top=%d right=%d bottom=%d !\n", + lprect->left, lprect->top, lprect->right, lprect->bottom); +#endif + if (nBar == SB_CTL) + hWndParent = GetParent(hWnd); + else + hWndParent = lphs->hWndOwner; + hBrush = SendMessage(hWndParent, WM_CTLCOLOR, (WORD)hDC, + MAKELONG(hWnd, CTLCOLOR_SCROLLBAR)); if (hBrush == (HBRUSH)NULL) hBrush = GetStockObject(LTGRAY_BRUSH); - lphs = ScrollBarGetStorageHeader(hwnd); - if (lphs == NULL) goto EndOfPaint; - GetClientRect(hwnd, &rect); + CopyRect(&lphs->rect, lprect); + CopyRect(&rect, lprect); w = rect.right - rect.left; h = rect.bottom - rect.top; + hMemDC = CreateCompatibleDC(hDC); if (lphs->Direction == WM_VSCROLL) { + GetObject(hUpArrow, sizeof(BITMAP), (LPSTR)&bm); + if (lphs->ButtonDown == 1) + SelectObject(hMemDC, hUpArrowD); + else + SelectObject(hMemDC, hUpArrow); + BitBlt(hDC, rect.left, rect.top, + bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); +/* + StretchBlt(hDC, 0, 0, lpdis->rcItem.right, lpdis->rcItem.right, + hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY); +*/ + GetObject(hDnArrow, sizeof(BITMAP), (LPSTR)&bm); + if (lphs->ButtonDown == 2) + SelectObject(hMemDC, hDnArrowD); + else + SelectObject(hMemDC, hDnArrow); + BitBlt(hDC, rect.left, rect.bottom - bm.bmHeight, + bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); rect.top += w; rect.bottom -= w; } else { + GetObject(hLfArrow, sizeof(BITMAP), (LPSTR)&bm); + if (lphs->ButtonDown == 3) + SelectObject(hMemDC, hLfArrowD); + else + SelectObject(hMemDC, hLfArrow); + BitBlt(hDC, rect.left, rect.top, + bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); + GetObject(hRgArrow, sizeof(BITMAP), (LPSTR)&bm); + if (lphs->ButtonDown == 4) + SelectObject(hMemDC, hRgArrowD); + else + SelectObject(hMemDC, hRgArrow); + BitBlt(hDC, rect.right - bm.bmWidth, rect.top, + bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); rect.left += h; rect.right -= h; } - FillRect(hdc, &rect, hBrush); + DeleteDC(hMemDC); + FillRect(hDC, &rect, hBrush); if (lphs->Direction == WM_VSCROLL) - SetRect(&rect, 0, lphs->CurPix + w, w, lphs->CurPix + (w << 1)); + SetRect(&rect, rect.left, rect.top + lphs->CurPix, + rect.left + w, rect.top + lphs->CurPix + w); else - SetRect(&rect, lphs->CurPix + h, 0, lphs->CurPix + (h << 1), h); - FrameRect(hdc, &rect, GetStockObject(BLACK_BRUSH)); + SetRect(&rect, rect.left + lphs->CurPix, rect.top, + rect.left + lphs->CurPix + h, rect.top + h); +/* + if (lphs->Direction == WM_VSCROLL) + SetRect(&rect, rect.left, rect.top + lphs->CurPix + w, + rect.left + w, rect.top + lphs->CurPix + (w << 1)); + else + SetRect(&rect, rect.left + lphs->CurPix + h, rect.top, + rect.left + lphs->CurPix + (h << 1), rect.top + h); +*/ + FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH)); InflateRect(&rect, -1, -1); - FillRect(hdc, &rect, GetStockObject(LTGRAY_BRUSH)); - DrawReliefRect(hdc, rect, 2, 0); + FillRect(hDC, &rect, GetStockObject(LTGRAY_BRUSH)); + DrawReliefRect(hDC, rect, 2, 0); InflateRect(&rect, -3, -3); - DrawReliefRect(hdc, rect, 1, 1); - if (!lphs->ThumbActive) { - InvalidateRect(lphs->hWndUp, NULL, TRUE); - UpdateWindow(lphs->hWndUp); - InvalidateRect(lphs->hWndDown, NULL, TRUE); - UpdateWindow(lphs->hWndDown); - } -EndOfPaint: - EndPaint( hwnd, &ps ); + DrawReliefRect(hDC, rect, 1, 1); } -int CreateScrollBarStruct(HWND hwnd) +int CreateScrollBarStruct(HWND hWnd) { RECT rect; int width, height; WND *wndPtr; LPHEADSCROLL lphs; - wndPtr = WIN_FindWndPtr(hwnd); + wndPtr = WIN_FindWndPtr(hWnd); lphs = (LPHEADSCROLL)malloc(sizeof(HEADSCROLL)); if (lphs == 0) { printf("Bad Memory Alloc on ScrollBar !\n"); return 0; } - #ifdef DEBUG_SCROLL printf("CreateScrollBarStruct %lX !\n", lphs); #endif *((LPHEADSCROLL *)&wndPtr->wExtra[1]) = lphs; + lphs->hWndOwner = hWnd; lphs->ThumbActive = FALSE; + lphs->TimerPending = FALSE; + lphs->ButtonDown = 0; lphs->MinVal = 0; lphs->MaxVal = 100; lphs->CurVal = 0; lphs->CurPix = 0; width = wndPtr->rectClient.right - wndPtr->rectClient.left; height = wndPtr->rectClient.bottom - wndPtr->rectClient.top; + CopyRect(&lphs->rect, &wndPtr->rectClient); if (width <= height) { lphs->MaxPix = height - 3 * width; lphs->Direction = WM_VSCROLL; - lphs->hWndUp = CreateWindow("BUTTON", "", - WS_CHILD | WS_VISIBLE | BS_OWNERDRAW, - 0, 0, width, width, hwnd, 1, wndPtr->hInstance, 0L); - lphs->hWndDown = CreateWindow("BUTTON", "", - WS_CHILD | WS_VISIBLE | BS_OWNERDRAW, - 0, height - width, width, width, hwnd, 2, - wndPtr->hInstance, 0L); } else { lphs->MaxPix = width - 3 * height; lphs->Direction = WM_HSCROLL; - lphs->hWndUp = CreateWindow("BUTTON", "", - WS_CHILD | WS_VISIBLE | BS_OWNERDRAW, - 0, 0, height, height, hwnd, 3, wndPtr->hInstance, 0L); - lphs->hWndDown = CreateWindow("BUTTON", "", - WS_CHILD | WS_VISIBLE | BS_OWNERDRAW, - width - height, 0, height, height, hwnd, 4, - wndPtr->hInstance, 0L); } if (lphs->MaxPix < 1) lphs->MaxPix = 1; if (wndPtr->hCursor == (HCURSOR)NULL) @@ -398,31 +510,90 @@ int CreateScrollBarStruct(HWND hwnd) } + +LPHEADSCROLL AllocScrollBar(DWORD dwStyle, int width, int height) +{ + LPHEADSCROLL lphs; + lphs = (LPHEADSCROLL)malloc(sizeof(HEADSCROLL)); + if (lphs == 0) { + printf("Bad Memory Alloc on ScrollBar !\n"); + return NULL; + } + lphs->ThumbActive = FALSE; + lphs->TimerPending = FALSE; + lphs->ButtonDown = 0; + lphs->MinVal = 0; + lphs->MaxVal = 100; + lphs->CurVal = 0; + lphs->CurPix = 0; + if (dwStyle & WS_VSCROLL) { + lphs->MaxPix = height - 3 * width; + lphs->Direction = WM_VSCROLL; + } + else { + lphs->MaxPix = width - 3 * height; + lphs->Direction = WM_HSCROLL; + } + if (lphs->MaxPix < 1) lphs->MaxPix = 1; + return lphs; +} + + +void NC_CreateScrollBars(HWND hWnd) +{ + RECT rect; + int width, height; + WND *wndPtr; + LPHEADSCROLL lphs; + wndPtr = WIN_FindWndPtr(hWnd); + width = wndPtr->rectClient.right - wndPtr->rectClient.left; + height = wndPtr->rectClient.bottom - wndPtr->rectClient.top; + if (wndPtr->dwStyle & WS_VSCROLL) { + if (wndPtr->dwStyle & WS_HSCROLL) height -= SYSMETRICS_CYHSCROLL; + lphs = AllocScrollBar(WS_VSCROLL, SYSMETRICS_CXVSCROLL, height); +#ifdef DEBUG_SCROLL + printf("NC_CreateScrollBars Vertical %lX !\n", lphs); +#endif + lphs->hWndOwner = hWnd; + wndPtr->VScroll = lphs; + } + if (wndPtr->dwStyle & WS_HSCROLL) { + if (wndPtr->dwStyle & WS_VSCROLL) width -= SYSMETRICS_CYVSCROLL; + lphs = AllocScrollBar(WS_HSCROLL, width, SYSMETRICS_CYHSCROLL); +#ifdef DEBUG_SCROLL + printf("NC_CreateScrollBars Horizontal %lX !\n", lphs); +#endif + lphs->hWndOwner = hWnd; + wndPtr->HScroll = lphs; + } +} + + /************************************************************************* - * GetScrollWindowHandle + * GetScrollObjectHandle */ -HWND GetScrollWindowHandle(HWND hWnd, int nBar) +LPHEADSCROLL GetScrollObjectHandle(HWND hWnd, int nBar) { WND *wndPtr; + LPHEADSCROLL lphs; if (nBar != SB_CTL) { - wndPtr = WIN_FindWndPtr(hWnd); - if (nBar == SB_VERT) return wndPtr->hWndVScroll; - if (nBar == SB_HORZ) return wndPtr->hWndHScroll; - return (HWND)NULL; + wndPtr = WIN_FindWndPtr(hWnd); + if (nBar == SB_VERT) return (LPHEADSCROLL)wndPtr->VScroll; + if (nBar == SB_HORZ) return (LPHEADSCROLL)wndPtr->HScroll; + return NULL; } - return hWnd; + return ScrollBarGetStorageHeader(hWnd); } /************************************************************************* * SetScrollPos [USER.62] */ -int SetScrollPos(HWND hwnd, int nBar, int nPos, BOOL bRedraw) +int SetScrollPos(HWND hWnd, int nBar, int nPos, BOOL bRedraw) { int nRet; LPHEADSCROLL lphs; - hwnd = GetScrollWindowHandle(hwnd, nBar); - lphs = ScrollBarGetStorageHeader(hwnd); + lphs = GetScrollObjectHandle(hWnd, nBar); if (lphs == NULL) return 0; nRet = lphs->CurVal; lphs->CurVal = (short)nPos; @@ -436,9 +607,9 @@ int SetScrollPos(HWND hwnd, int nBar, int nPos, BOOL bRedraw) printf("SetScrollPos min=%d max=%d\n", lphs->MinVal, lphs->MaxVal); #endif - if ((bRedraw) && (IsWindowVisible(hwnd))) { - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); + if ((bRedraw) && (IsWindowVisible(lphs->hWndOwner))) { + InvalidateRect(lphs->hWndOwner, &lphs->rect, TRUE); + UpdateWindow(lphs->hWndOwner); } return nRet; } @@ -448,11 +619,10 @@ int SetScrollPos(HWND hwnd, int nBar, int nPos, BOOL bRedraw) /************************************************************************* * GetScrollPos [USER.63] */ -int GetScrollPos(HWND hwnd, int nBar) +int GetScrollPos(HWND hWnd, int nBar) { LPHEADSCROLL lphs; - hwnd = GetScrollWindowHandle(hwnd, nBar); - lphs = ScrollBarGetStorageHeader(hwnd); + lphs = GetScrollObjectHandle(hWnd, nBar); if (lphs == NULL) return 0; return lphs->CurVal; } @@ -462,11 +632,10 @@ int GetScrollPos(HWND hwnd, int nBar) /************************************************************************* * SetScrollRange [USER.64] */ -void SetScrollRange(HWND hwnd, int nBar, int MinPos, int MaxPos, BOOL bRedraw) +void SetScrollRange(HWND hWnd, int nBar, int MinPos, int MaxPos, BOOL bRedraw) { LPHEADSCROLL lphs; - hwnd = GetScrollWindowHandle(hwnd, nBar); - lphs = ScrollBarGetStorageHeader(hwnd); + lphs = GetScrollObjectHandle(hWnd, nBar); if (lphs == NULL) return; lphs->MinVal = (short)MinPos; lphs->MaxVal = (short)MaxPos; @@ -478,9 +647,9 @@ void SetScrollRange(HWND hwnd, int nBar, int MinPos, int MaxPos, BOOL bRedraw) #ifdef DEBUG_SCROLL printf("SetScrollRange min=%d max=%d\n", lphs->MinVal, lphs->MaxVal); #endif - if ((bRedraw) && (IsWindowVisible(hwnd))) { - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); + if ((bRedraw) && (IsWindowVisible(lphs->hWndOwner))) { + InvalidateRect(lphs->hWndOwner, &lphs->rect, TRUE); + UpdateWindow(lphs->hWndOwner); } } @@ -489,11 +658,10 @@ void SetScrollRange(HWND hwnd, int nBar, int MinPos, int MaxPos, BOOL bRedraw) /************************************************************************* * GetScrollRange [USER.65] */ -void GetScrollRange(HWND hwnd, int nBar, LPINT lpMin, LPINT lpMax) +void GetScrollRange(HWND hWnd, int nBar, LPINT lpMin, LPINT lpMax) { LPHEADSCROLL lphs; - hwnd = GetScrollWindowHandle(hwnd, nBar); - lphs = ScrollBarGetStorageHeader(hwnd); + lphs = GetScrollObjectHandle(hWnd, nBar); if (lphs == NULL) return; *lpMin = lphs->MinVal; *lpMax = lphs->MaxVal; @@ -519,16 +687,20 @@ void ShowScrollBar(HWND hWnd, WORD wBar, BOOL bFlag) } wndPtr = WIN_FindWndPtr(hWnd); if ((wBar == SB_VERT) || (wBar == SB_BOTH)) { +/* if (bFlag) ShowWindow(wndPtr->hWndVScroll, SW_SHOW); else ShowWindow(wndPtr->hWndVScroll, SW_HIDE); +*/ } if ((wBar == SB_HORZ) || (wBar == SB_BOTH)) { +/* if (bFlag) ShowWindow(wndPtr->hWndHScroll, SW_SHOW); else ShowWindow(wndPtr->hWndHScroll, SW_HIDE); +*/ } } diff --git a/controls/static.c b/controls/static.c index 558110b6659..655d2fed52e 100644 --- a/controls/static.c +++ b/controls/static.c @@ -149,8 +149,8 @@ static LONG PaintTextfn(HWND hwnd) GetClientRect(hwnd, &rc); textlen = GetWindowTextLength(hwnd); - hText = LocalAlloc(LMEM_MOVEABLE, textlen+1); - text = LocalLock(hText); + hText = USER_HEAP_ALLOC(0, textlen+1); + text = USER_HEAP_ADDR(hText); GetWindowText(hwnd, text, textlen+1); switch (style & 0x0000000F) @@ -185,8 +185,7 @@ static LONG PaintTextfn(HWND hwnd) FillRect(hdc, &rc, hBrush); DrawText(hdc, text, textlen, &rc, wFormat); - LocalUnlock(hText); - LocalFree(hText); + USER_HEAP_FREE(hText); GlobalUnlock(hwnd); EndPaint(hwnd, &ps); } diff --git a/controls/widgets.c b/controls/widgets.c index 02d10b4dac7..37b74f1dbd4 100644 --- a/controls/widgets.c +++ b/controls/widgets.c @@ -7,7 +7,6 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "windows.h" -#include "win.h" #include "dialog.h" @@ -17,7 +16,6 @@ LONG ScrollBarWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ); LONG ListBoxWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam ); LONG ComboBoxWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam ); LONG PopupMenuWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam ); -LONG CaptionBarWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam ); static WNDCLASS WIDGETS_BuiltinClasses[] = @@ -34,8 +32,6 @@ static WNDCLASS WIDGETS_BuiltinClasses[] = 0, 0, 0, 0, NULL, "COMBOBOX" }, { CS_GLOBALCLASS, (LONG(*)())PopupMenuWndProc, 0, 8, 0, 0, 0, 0, NULL, "POPUPMENU" }, - { CS_GLOBALCLASS, (LONG(*)())CaptionBarWndProc, 0, 8, - 0, 0, 0, 0, NULL, "CAPTION" }, { CS_GLOBALCLASS, (LONG(*)())DefDlgProc, 0, DLGWINDOWEXTRA, 0, 0, 0, 0, NULL, DIALOG_CLASS_NAME } }; diff --git a/debugger/Makefile b/debugger/Makefile index 78954c054e2..6a2714091b0 100644 --- a/debugger/Makefile +++ b/debugger/Makefile @@ -1,4 +1,4 @@ -CFLAGS=-g -I../include -DUSE_READLINE +CFLAGS=-g -I../include -DUSE_READLINE ${COPTS} LIBS= readline/libedit.a OBJS=dbg.tab.o hash.o lex.yy.o info.o i386-pinsn.o #YACC=bison -v -d diff --git a/debugger/dtest.c b/debugger/dtest.c index bbad04e0cac..3872cbf8eb7 100644 --- a/debugger/dtest.c +++ b/debugger/dtest.c @@ -58,7 +58,7 @@ main(){ segv_act.sa_handler = (__sighandler_t) win_fault; sigaction(SIGSEGV, &segv_act, NULL); #endif -#ifdef __NetBSD__ +#if defined(__NetBSD__) || defined(__FreeBSD__) sigset_t sig_mask; sigemptyset(&sig_mask); diff --git a/debugger/regpos.h b/debugger/regpos.h index d3c3a4f7d35..01d2e00b6af 100644 --- a/debugger/regpos.h +++ b/debugger/regpos.h @@ -25,7 +25,8 @@ #define RN_CR2 21 #endif -#ifdef __NetBSD__ +#if defined(__NetBSD__) || defined(__FreeBSD__) +#define RN_OLDMASK 1 /* Register numbers */ #define RN_ESP 2 #define RN_EBP 3 @@ -50,6 +51,8 @@ #ifdef linux #define SC_GS regval[RN_GS] #define SC_FS regval[RN_FS] +#define I387 regval[RN_I387] +#define CR2 regval[RN_CR2] #endif #define SC_ES regval[RN_ES] #define SC_DS regval[RN_DS] @@ -68,7 +71,4 @@ #define SC_EFLAGS regval[RN_EFLAGS] #define ESP_AT_SIGNAL regval[RN_ESP_AT_SIGNAL] #define SC_SS regval[RN_SS] -#define I387 regval[RN_I387] #define OLDMASK regval[RN_OLDMASK] -#define CR2 regval[RN_CR2] - diff --git a/if1632/Imakefile b/if1632/Imakefile index 8c11afdfe95..4c36d99d270 100644 --- a/if1632/Imakefile +++ b/if1632/Imakefile @@ -7,6 +7,11 @@ SRCS = \ callback.c \ relay.c +/* + * Hack alert. There appear to be no object files, 'cause a very + * nasty rule below links *.o together, which is a generally bad idea, + * but I can't see how else to do it. + */ OBJS = \ call.o \ callback.o \ @@ -25,9 +30,11 @@ MakeDllFromSpec(user,$(TOP)/$(MODULE)) MakeDllFromSpec(win87em,$(TOP)/$(MODULE)) /* - * Yes I know *.o is not veru clever, but can you do it cleaner ? + * Yes I know *.o is not very clever, but can you do it cleaner ? */ -WineRelocatableTarget($(TOP)/$(MODULE),*.o,$(OBJS)) +WineRelocatableTarget($(TOP)/$(MODULE),*.o,) + +$(TOP)/$(MODULE).o: $(OBJS) clean:: $(RM) dll* diff --git a/if1632/Makefile b/if1632/Makefile index 0746063710d..36073244c2b 100644 --- a/if1632/Makefile +++ b/if1632/Makefile @@ -10,6 +10,10 @@ MUST_BE_LINKED_FIRST=call.o $(BUILDOBJS) OBJS=$(MUST_BE_LINKED_FIRST) callback.o relay.o +# Uncomment the following 2 lines for use with FreeBSD +# %.o: %.S +# $(CC) $(ASFLAGS) $(CPPFLAGS) $(TARGET_MACH) $(COPTS) -c -o $@ $< + default: if1632.o if1632.o: $(OBJS) diff --git a/if1632/call.S b/if1632/call.S index c8ac0300874..88534962d09 100644 --- a/if1632/call.S +++ b/if1632/call.S @@ -4,7 +4,7 @@ #ifdef linux #define UDATASEL 0x2b #endif -#ifdef __NetBSD__ +#if defined(__NetBSD__) || defined(__FreeBSD__) #define UDATASEL 0x27 #endif .data diff --git a/if1632/kernel.spec b/if1632/kernel.spec index 86a15087b2d..15021aa3f27 100644 --- a/if1632/kernel.spec +++ b/if1632/kernel.spec @@ -78,6 +78,7 @@ length 415 134 pascal GetWindowsDirectory(ptr word) GetWindowsDirectory(1 2) 135 pascal GetSystemDirectory(ptr word) GetSystemDirectory(1 2) 136 pascal GetDriveType(byte) GetWindowsDirectory(1) +152 return GetNumTasks 0 1 154 return GlobalNotify 4 0 163 pascal GlobalLRUOldest(word) ReturnArg(1) 164 pascal GlobalLRUNewest(word) ReturnArg(1) diff --git a/if1632/relay.c b/if1632/relay.c index fba4f52f03f..52f7d426b60 100644 --- a/if1632/relay.c +++ b/if1632/relay.c @@ -19,7 +19,7 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include "prototypes.h" #include "dlls.h" -/* #define DEBUG_RELAY */ +/* #define DEBUG_RELAY /* */ #define N_BUILTINS 8 diff --git a/if1632/user.spec b/if1632/user.spec index ebd04eaa250..5303a7511b0 100644 --- a/if1632/user.spec +++ b/if1632/user.spec @@ -46,10 +46,14 @@ length 540 49 pascal IsWindowVisible(word) IsWindowVisible(1) 50 pascal FindWindow(ptr ptr) FindWindow(1 2) 53 pascal DestroyWindow(word) DestroyWindow(1) +54 pascal EnumWindows(ptr long) EnumWindows(1 2) +55 pascal EnumChildWindows(word ptr long) EnumChildWindows(1 2 3) 56 pascal MoveWindow(word word word word word word) MoveWindow(1 2 3 4 5 6) 57 pascal RegisterClass(ptr) RegisterClass(1) 58 pascal GetClassName(word ptr word) GetClassName(1 2 3) +59 pascal SetActiveWindow(word) SetActiveWindow(1) +60 pascal GetActiveWindow() GetActiveWindow() 61 pascal ScrollWindow(word s_word s_word ptr ptr) ScrollWindow(1 2 3 4 5) 62 pascal SetScrollPos(word word word word) SetScrollPos(1 2 3 4) 63 pascal GetScrollPos(word word) GetScrollPos(1 2) @@ -122,8 +126,10 @@ length 540 152 pascal DestroyMenu(word) DestroyMenu(1) 154 pascal CheckMenuItem(word word word) CheckMenuItem(1 2 3) 155 pascal EnableMenuItem(word word word) EnableMenuItem(1 2 3) +156 pascal GetSystemMenu(word word) GetSystemMenu(1 2) 157 pascal GetMenu(word) GetMenu(1) 158 pascal SetMenu(word word) SetMenu(1 2) +159 pascal GetSubMenu(word word) GetSubMenu(1 2) 160 pascal DrawMenuBar(word) DrawMenuBar(1) 163 pascal CreateCaret(word word word word) CreateCaret(1 2 3 4) 164 pascal DestroyCaret() DestroyCaret() @@ -138,6 +144,7 @@ length 540 175 pascal LoadBitmap(word ptr) LoadBitmap(1 2) 176 pascal LoadString(word word ptr s_word) LoadString(1 2 3 4) 177 pascal LoadAccelerators(word ptr) LoadAccelerators(1 2) +178 pascal TranslateAccelerator(word word ptr) TranslateAccelerator(1 2 3) 179 pascal GetSystemMetrics(word) GetSystemMetrics(1) 180 pascal GetSysColor(word) GetSysColor(1) 181 pascal SetSysColors(word ptr ptr) SetSysColors(1 2 3) diff --git a/include/accel.h b/include/accel.h new file mode 100644 index 00000000000..6ea4084d75c --- /dev/null +++ b/include/accel.h @@ -0,0 +1,22 @@ +/* + * structure definitions for ACCELERATORS + * + * Copyright Martin Ayotte, 1994 + * + */ + +typedef struct { + WORD wEvent; + WORD wIDval; + BYTE type; + } ACCELENTRY, *LPACCELENTRY; + +typedef struct { + WORD wCount; + ACCELENTRY tbl[1]; + } ACCELHEADER, *LPACCELHEADER; + +#define VIRTKEY_ACCEL 0x01 +#define SHIFT_ACCEL 0x04 +#define CONTROL_ACCEL 0x08 +#define SYSTEM_ACCEL 0x80 diff --git a/include/heap.h b/include/heap.h index efbcd0ddebf..2b3b157b9a4 100644 --- a/include/heap.h +++ b/include/heap.h @@ -6,6 +6,9 @@ #ifndef HEAP_H #define HEAP_H +/********************************************************************** + * LOCAL HEAP STRUCTURES AND FUNCTIONS + */ typedef struct heap_mem_desc_s { struct heap_mem_desc_s *prev, *next; @@ -20,7 +23,44 @@ extern int HEAP_Free(MDESC **free_list, void *block); extern void *HEAP_ReAlloc(MDESC **free_list, void *old_block, int new_size, unsigned int flags); +/********************************************************************** + * GLOBAL HEAP STRUCTURES AND FUNCTIONS: + * + * Global memory pool descriptor. Segments MUST be maintained in segment + * ascending order. If not the reallocation routine will die a horrible + * death. + * + * handle = 0, this descriptor contains the address of a free pool. + * != 0, this describes an allocated block. + * + * sequence = 0, this is not a huge block + * > 0, this is a portion of a huge block + * =-1, this is a free segment + * + * addr - address of this memory block. + * + * length - used to maintain huge blocks. + */ +typedef struct global_mem_desc_s +{ + struct global_mem_desc_s *next; + struct global_mem_desc_s *prev; + unsigned short handle; + short sequence; + void *addr; + int length; + int lock_count; + void *linear_addr; + int linear_key; + int linear_count; +} GDESC; + +extern GDESC *GlobalList; + extern void *GlobalQuickAlloc(int size); extern unsigned int GlobalHandleFromPointer(void *block); +extern GDESC *GlobalGetGDesc(unsigned int block); +extern void *GlobalLinearLock(unsigned int block); +extern unsigned int GlobalLinearUnlock(unsigned int block); #endif /* HEAP_H */ diff --git a/include/menu.h b/include/menu.h index fa742406f76..34cdb2c1cec 100644 --- a/include/menu.h +++ b/include/menu.h @@ -54,6 +54,7 @@ typedef struct tagPOPUPMENU WORD FocusedItem; WORD MouseFlags; WORD BarFlags; + BOOL SysFlag; WORD Width; WORD Height; } POPUPMENU, *LPPOPUPMENU; diff --git a/include/message.h b/include/message.h index d64b4fcbb2f..fc3054dfc8d 100644 --- a/include/message.h +++ b/include/message.h @@ -51,5 +51,6 @@ extern void MSG_DecTimerCount( HANDLE hQueue ); extern BOOL MSG_CreateSysMsgQueue( int size ); extern void hardware_event(HWND hwnd, WORD message, WORD wParam, LONG lParam, WORD xPos, WORD yPos, DWORD time, DWORD extraInfo); +extern BOOL MSG_GetHardwareMessage( LPMSG msg ); #endif /* MESSAGE_H */ diff --git a/include/prototypes.h b/include/prototypes.h index 69fc97bd4a9..8bd189d3ba3 100644 --- a/include/prototypes.h +++ b/include/prototypes.h @@ -28,6 +28,10 @@ extern unsigned int GetEntryPointFromOrdinal(struct w_files * wpnt, extern struct segment_descriptor_s *GetNextSegment(unsigned int flags, unsigned int limit); +extern struct segment_descriptor_s *CreateNewSegments(int code_flag, + int read_only, + int length, + int n_segments); extern struct mz_header_s *CurrentMZHeader; extern struct ne_header_s *CurrentNEHeader; extern int CurrentNEFile; diff --git a/include/scroll.h b/include/scroll.h index 4dd4e7dc6c6..2804a46a2a8 100644 --- a/include/scroll.h +++ b/include/scroll.h @@ -9,12 +9,23 @@ typedef struct tagHEADSSCROLL { short MaxVal; short MaxPix; short CurPix; + RECT rect; BOOL ThumbActive; + BOOL TimerPending; + WORD ButtonDown; WORD Direction; DWORD dwStyle; - HWND hWndUp; - HWND hWndDown; + HWND hWndOwner; } HEADSCROLL; typedef HEADSCROLL FAR* LPHEADSCROLL; + +void ScrollBarButtonDown(HWND hWnd, int nBar, int x, int y); +void ScrollBarButtonUp(HWND hWnd, int nBar, int x, int y); +void ScrollBarMouseMove(HWND hWnd, int nBar, WORD wParam, int x, int y); +void StdDrawScrollBar(HWND hWnd, HDC hDC, int nBar, LPRECT lprect, LPHEADSCROLL lphs); +int CreateScrollBarStruct(HWND hWnd); +void NC_CreateScrollBars(HWND hWnd); + + diff --git a/include/segmem.h b/include/segmem.h index d4f6fd87b1d..f2bf2d6ba63 100644 --- a/include/segmem.h +++ b/include/segmem.h @@ -48,6 +48,8 @@ typedef struct segment_descriptor_s #endif } SEGDESC; +extern int IPCCopySelector(int i_old, unsigned long new, int swap_type); + /* * Additional flags */ diff --git a/include/win.h b/include/win.h index 12800c76304..371b0368249 100644 --- a/include/win.h +++ b/include/win.h @@ -38,15 +38,15 @@ typedef struct tagWND HANDLE hdce; /* Window DCE (if CS_OWNDC or CS_CLASSDC) */ HMENU hmenuSystem; /* System menu */ HCURSOR hCursor; /* Window Current Cursor */ - HWND hWndVScroll; /* Verti. ScrollBar handle of the window */ - HWND hWndHScroll; /* Horiz. ScrollBar handle of the window */ + void *VScroll; /* Vertical ScrollBar Struct Pointer */ + void *HScroll; /* Horizontal ScrollBar Struct Pointer */ WORD wIDmenu; /* ID or hmenu (from CreateWindow) */ HANDLE hText; /* Handle of window text */ WORD flags; /* Misc. flags */ Window window; /* X window */ LPMENUBAR menuBarPtr; /* Menu bar */ + HMENU hSysMenu; /* window's copy of System Menu */ HWND hWndMenuBar; /* Menu bar */ - HWND hWndCaption; /* Caption bar */ WORD wExtra[1]; /* Window extra bytes */ } WND; diff --git a/include/windows.h b/include/windows.h index a4064c3be81..a6f8c981acc 100644 --- a/include/windows.h +++ b/include/windows.h @@ -222,6 +222,17 @@ typedef struct { #define GW_OWNER 4 #define GW_CHILD 5 + /* WM_GETMINMAXINFO struct */ +typedef struct +{ + POINT ptReserved; + POINT ptMaxSize; + POINT ptMaxPosition; + POINT ptMinTrackSize; + POINT ptMaxTrackSize; +} MINMAXINFO; + + /* WM_WINDOWPOSCHANGING/CHANGED struct */ typedef struct { @@ -249,6 +260,17 @@ typedef struct #define WPF_SETMINPOSITION 0x0001 #define WPF_RESTORETOMAXIMIZED 0x0002 + /* WM_MOUSEACTIVATE return values */ +#define MA_ACTIVATE 1 +#define MA_ACTIVATEANDEAT 2 +#define MA_NOACTIVATE 3 +#define MA_NOACTIVATEANDEAT 4 + + /* WM_ACTIVATE wParam values */ +#define WA_INACTIVE 0 +#define WA_ACTIVE 1 +#define WA_CLICKACTIVE 2 + /* WM_NCCALCSIZE parameter structure */ typedef struct { @@ -1271,6 +1293,9 @@ enum { WM_NULL, WM_CREATE, WM_DESTROY, WM_MOVE, WM_UNUSED0, WM_SIZE, WM_ACTIVATE #define WM_PARENTNOTIFY 0x0210 +#define WM_ENTERSIZEMOVE 0x0231 +#define WM_EXITSIZEMOVE 0x0232 + /* misc messages */ #define WM_NULL 0x0000 #define WM_USER 0x0400 @@ -1349,6 +1374,13 @@ enum { SW_HIDE, SW_SHOWNORMAL, SW_NORMAL, SW_SHOWMINIMIZED, SW_SHOWMAXIMIZED, #define TPM_CENTERALIGN 0x0004 #define TPM_RIGHTALIGN 0x0008 +/* Menu messages */ +#define WM_INITMENU 0x0116 +#define WM_INITMENUPOPUP 0x0117 + +#define WM_MENUSELECT 0x011F +#define WM_MENUCHAR 0x0120 + #define MF_INSERT 0 #define MF_CHANGE 0x0080 #define MF_APPEND 0x0100 @@ -2254,7 +2286,7 @@ Fb(HBRUSH,CreateDIBPatternBrush,HANDLE,a,WORD,b) Fb(HBRUSH,CreateHatchBrush,short,a,COLORREF,b) Fb(HCURSOR,LoadCursor,HANDLE,a,LPSTR,b) Fb(HICON,LoadIcon,HANDLE,a,LPSTR,b) -Fb(HMENU,GetSubMenu,HMENU,a,int,b) +Fb(HMENU,GetSubMenu,HMENU,a,short,b) Fb(HMENU,GetSystemMenu,HWND,a,BOOL,b) Fb(HMENU,LoadMenu,HANDLE,a,LPSTR,b) Fb(HWND,ChildWindowFromPoint,HWND,a,POINT,b) diff --git a/include/wine.h b/include/wine.h index dbc034cd806..7931c486c2c 100644 --- a/include/wine.h +++ b/include/wine.h @@ -57,7 +57,7 @@ struct sigcontext_struct { }; #endif -#ifdef __NetBSD__ +#if defined(__NetBSD__) || defined(__FreeBSD__) #include #define sigcontext_struct sigcontext #define HZ 100 diff --git a/loader/Imakefile b/loader/Imakefile index 9c5130a48a6..f83143548f9 100644 --- a/loader/Imakefile +++ b/loader/Imakefile @@ -3,6 +3,8 @@ MODULE = loader SRCS = \ + int1a.c \ + int21.c \ dump.c \ files.c \ ldt.c \ @@ -15,6 +17,8 @@ SRCS = \ cursor.c OBJS = \ + int1a.o \ + int21.o \ dump.o \ files.o \ ldt.o \ diff --git a/loader/cursor.c b/loader/cursor.c index 3bf757730f3..ff8c7bdea48 100644 --- a/loader/cursor.c +++ b/loader/cursor.c @@ -30,6 +30,24 @@ RECT ClipCursorRect; extern HINSTANCE hSysRes; extern Window winHasCursor; +static struct { LPSTR name; HCURSOR cursor; } system_cursor[] = +{ + { IDC_ARROW, 0 }, + { IDC_IBEAM, 0 }, + { IDC_WAIT, 0 }, + { IDC_CROSS, 0 }, + { IDC_UPARROW, 0 }, + { IDC_SIZE, 0 }, + { IDC_ICON, 0 }, + { IDC_SIZENWSE, 0 }, + { IDC_SIZENESW, 0 }, + { IDC_SIZEWE, 0 }, + { IDC_SIZENS, 0 } +}; + +#define NB_SYS_CURSORS (sizeof(system_cursor)/sizeof(system_cursor[0])) + + /********************************************************************** * LoadCursor [USER.173] */ @@ -51,8 +69,22 @@ HCURSOR LoadCursor(HANDLE instance, LPSTR cursor_name) printf("LoadCursor: instance = %04x, name = %08x\n", instance, cursor_name); #endif + + if (!instance) + { + for (i = 0; i < NB_SYS_CURSORS; i++) + if (system_cursor[i].name == cursor_name) + { + hCursor = system_cursor[i].cursor; + break; + } + if (i == NB_SYS_CURSORS) return 0; + if (hCursor) return hCursor; + } hCursor = GlobalAlloc(GMEM_MOVEABLE, sizeof(CURSORALLOC) + 1024L); if (hCursor == (HCURSOR)NULL) return 0; + if (!instance) system_cursor[i].cursor = hCursor; + #ifdef DEBUG_CURSOR printf("LoadCursor Alloc hCursor=%X\n", hCursor); #endif @@ -203,9 +235,9 @@ HCURSOR CreateCursor(HANDLE instance, short nXhotspot, short nYhotspot, int i, j; #ifdef DEBUG_RESOURCE printf("CreateCursor: inst=%04x nXhotspot=%d nYhotspot=%d nWidth=%d nHeight=%d\n", - nXhotspot, nYhotspot, nWidth, nHeight); + instance, nXhotspot, nYhotspot, nWidth, nHeight); printf("CreateCursor: inst=%04x lpANDbitPlane=%08X lpXORbitPlane=%08X\n", - LPSTR lpANDbitPlane, LPSTR lpXORbitPlane); + instance, lpANDbitPlane, lpXORbitPlane); #endif if (!(hdc = GetDC(GetDesktopWindow()))) return 0; hCursor = GlobalAlloc(GMEM_MOVEABLE, sizeof(CURSORALLOC) + 1024L); diff --git a/loader/ldt.c b/loader/ldt.c index 235f1eb50df..8ac6b1e9ec4 100644 --- a/loader/ldt.c +++ b/loader/ldt.c @@ -6,7 +6,7 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include #include "prototypes.h" -#ifdef __NetBSD__ +#if defined(__NetBSD__) || defined(__FreeBSD__) #include #endif @@ -21,7 +21,7 @@ print_ldt() unsigned long *lp; unsigned long base_addr, limit; int type, dpl, i; -#ifdef __NetBSD__ +#if defined(__NetBSD__) || defined(__FreeBSD__) struct segment_descriptor *sd; #endif @@ -29,7 +29,7 @@ print_ldt() exit(1); lp = (unsigned long *) buffer; -#ifdef __NetBSD__ +#if defined(__NetBSD__) || defined(__FreeBSD__) sd = (struct segment_descriptor *) buffer; #endif @@ -47,7 +47,7 @@ print_ldt() type = (*lp >> 10) & 5; dpl = (*lp >> 13) & 3; #endif -#ifdef __NetBSD__ +#if defined(__NetBSD__) || defined(__FreeBSD__) type = sd->sd_type; dpl = sd->sd_dpl; sd++; diff --git a/loader/ldtlib.c b/loader/ldtlib.c index 39455372732..76924fe6b37 100644 --- a/loader/ldtlib.c +++ b/loader/ldtlib.c @@ -11,7 +11,7 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; _syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount) #endif -#ifdef __NetBSD__ +#if defined(__NetBSD__) || defined(__FreeBSD__) #include extern int i386_get_ldt(int, union descriptor *, int); @@ -43,7 +43,7 @@ get_ldt(void *buffer) #ifdef linux return modify_ldt(0, buffer, 32 * sizeof(struct modify_ldt_ldt_s)); #endif -#ifdef __NetBSD__ +#if defined(__NetBSD__) || defined(__FreeBSD__) return i386_get_ldt(0, (union descriptor *)buffer, 32); #endif } @@ -66,7 +66,7 @@ set_ldt_entry(int entry, unsigned long base, unsigned int limit, return modify_ldt(1, &ldt_info, sizeof(ldt_info)); #endif -#ifdef __NetBSD__ +#if defined(__NetBSD__) || defined(__FreeBSD__) struct segment_descriptor *sd; int ret; diff --git a/loader/resource.c b/loader/resource.c index da059d10b6f..bf2d18529a0 100644 --- a/loader/resource.c +++ b/loader/resource.c @@ -14,6 +14,7 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include "gdi.h" #include "wine.h" #include "icon.h" +#include "accel.h" #define MIN(a,b) ((a) < (b) ? (a) : (b)) @@ -388,6 +389,7 @@ HICON LoadIcon(HANDLE instance, LPSTR icon_name) DeleteDC(hMemDC); DeleteDC(hMemDC2); ReleaseDC(GetDesktopWindow(), hdc); + GlobalUnlock(hIcon); return hIcon; } @@ -407,12 +409,97 @@ BOOL DestroyIcon(HICON hIcon) /********************************************************************** - * LoadAccelerators + * LoadAccelerators [USER.177] */ -HANDLE -LoadAccelerators(HANDLE instance, LPSTR lpTableName) +HANDLE LoadAccelerators(HANDLE instance, LPSTR lpTableName) { - fprintf(stderr,"LoadAccelerators: (%d),%d\n",instance,lpTableName); + HANDLE hAccel; + HANDLE rsc_mem; + BYTE *lp; + ACCELHEADER *lpAccelTbl; + int i, image_size; +#ifdef DEBUG_ACCEL + if (((LONG)lpTableName & 0xFFFF0000L) == 0L) + printf("LoadAccelerators: instance = %04X, name = %08X\n", + instance, lpTableName); + else + printf("LoadAccelerators: instance = %04X, name = '%s'\n", + instance, lpTableName); +#endif + if (instance == (HANDLE)NULL) instance = hSysRes; + rsc_mem = RSC_LoadResource(instance, lpTableName, NE_RSCTYPE_ACCELERATOR, + &image_size); + if (rsc_mem == (HANDLE)NULL) { + printf("LoadAccelerators / AccelTable %04X not Found !\n", lpTableName); + return 0; + } + lp = (BYTE *)GlobalLock(rsc_mem); + if (lp == NULL) { + GlobalFree(rsc_mem); + return 0; + } +#ifdef DEBUG_ACCEL + printf("LoadAccelerators / image_size=%d\n", image_size); +#endif + hAccel = GlobalAlloc(GMEM_MOVEABLE, + sizeof(ACCELHEADER) + sizeof(ACCELENTRY) + image_size); + lpAccelTbl = (LPACCELHEADER)GlobalLock(hAccel); + lpAccelTbl->wCount = 0; + for (i = 0; ; i++) { + lpAccelTbl->tbl[i].type = *(lp++); + lpAccelTbl->tbl[i].wEvent = *((WORD *)lp); + lp += 2; + lpAccelTbl->tbl[i].wIDval = *((WORD *)lp); + lp += 2; + if (lpAccelTbl->tbl[i].wEvent == 0) break; +#ifdef DEBUG_ACCEL + printf("Accelerator #%u / event=%04X id=%04X type=%02X \n", + i, lpAccelTbl->tbl[i].wEvent, lpAccelTbl->tbl[i].wIDval, + lpAccelTbl->tbl[i].type); +#endif + lpAccelTbl->wCount++; + } + GlobalUnlock(hAccel); + GlobalUnlock(rsc_mem); + GlobalFree(rsc_mem); + return hAccel; +} + +/********************************************************************** + * TranslateAccelerator [USER.178] + */ +int TranslateAccelerator(HWND hWnd, HANDLE hAccel, LPMSG msg) +{ + ACCELHEADER *lpAccelTbl; + int i, image_size; + if (hAccel == 0 || msg == NULL) return 0; + if (msg->message != WM_KEYDOWN && + msg->message != WM_KEYUP && + msg->message != WM_CHAR) return 0; +#ifdef DEBUG_ACCEL + printf("TranslateAccelerators hAccel=%04X !\n", hAccel); +#endif + lpAccelTbl = (LPACCELHEADER)GlobalLock(hAccel); + for (i = 0; i < lpAccelTbl->wCount; i++) { +/* if (lpAccelTbl->tbl[i].type & SHIFT_ACCEL) { */ +/* if (lpAccelTbl->tbl[i].type & CONTROL_ACCEL) { */ + if (lpAccelTbl->tbl[i].type & VIRTKEY_ACCEL) { + if (msg->wParam == lpAccelTbl->tbl[i].wEvent && + msg->message == WM_KEYDOWN) { + SendMessage(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval, 0x00010000L); + return 1; + } + if (msg->message == WM_KEYUP) return 1; + } + else { + if (msg->wParam == lpAccelTbl->tbl[i].wEvent && + msg->message == WM_CHAR) { + SendMessage(hWnd, WM_COMMAND, lpAccelTbl->tbl[i].wIDval, 0x00010000L); + return 1; + } + } + } + GlobalUnlock(hAccel); return 0; } @@ -446,12 +533,12 @@ HANDLE FindResource(HANDLE instance, LPSTR resource_name, LPSTR type_name) if (((int) resource_name & 0xffff0000) == 0) { - r->size_shift = FindResourceByNumber(&r->nameinfo, type_name, + r->size_shift = FindResourceByNumber(&r->nameinfo, (int)type_name, (int) resource_name | 0x8000); } else { - r->size_shift = FindResourceByName(&r->nameinfo, type_name, + r->size_shift = FindResourceByName(&r->nameinfo, (int)type_name, resource_name); } @@ -683,14 +770,12 @@ LoadBitmap(HANDLE instance, LPSTR bmp_name) if (instance == (HANDLE)NULL) instance = hSysRes; if (!(hdc = GetDC(GetDesktopWindow()))) return 0; -printf("before RSC_Load\n"); rsc_mem = RSC_LoadResource(instance, bmp_name, NE_RSCTYPE_BITMAP, &image_size); if (rsc_mem == (HANDLE)NULL) { printf("LoadBitmap / BitMap %04X not Found !\n", bmp_name); return 0; } -printf("before GlobalLock\n"); lp = (long *) GlobalLock(rsc_mem); if (lp == NULL) { diff --git a/loader/selector.c b/loader/selector.c index 38ad26fee30..76c66ba37d7 100644 --- a/loader/selector.c +++ b/loader/selector.c @@ -14,7 +14,7 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include #include #endif -#ifdef __NetBSD__ +#if defined(__NetBSD__) || defined(__FreeBSD__) #include #endif #include @@ -23,13 +23,14 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include "prototypes.h" #include "wine.h" +/* #define DEBUG_SELECTORS /* */ #ifdef linux #define DEV_ZERO #define UTEXTSEL 0x23 #endif -#ifdef __NetBSD__ +#if defined(__NetBSD__) || defined(__FreeBSD__) #include #define PAGE_SIZE getpagesize() #define MODIFY_LDT_CONTENTS_DATA 0 @@ -59,7 +60,7 @@ extern char **Argv; extern int Argc; /********************************************************************** - * FindUnusedSelector + * FindUnusedSelectors */ int FindUnusedSelectors(int n_selectors) @@ -87,95 +88,123 @@ FindUnusedSelectors(int n_selectors) return i - n_selectors + 1; } -/********************************************************************** - * FindUnusedSelector - */ -int -FindUnusedSelector(void) -{ - int i; - - for (i = LastUsedSelector + 1; i != LastUsedSelector; i++) - { - if (i >= MAX_SELECTORS) - i = FIRST_SELECTOR; - - if (!SelectorMap[i]) - break; - } - - if (i == LastUsedSelector) - return 0; - - LastUsedSelector = i; - return i; -} - #ifdef HAVE_IPC /********************************************************************** * IPCCopySelector + * + * Created a shared memory copy of a segment: + * + * - at a new selector location (if "new" is a 16-bit value) + * - at an arbitrary memory location (if "new" is a 32-bit value) */ int -IPCCopySelector(int i_old, int i_new, int swap_type) +IPCCopySelector(int i_old, unsigned long new, int swap_type) { SEGDESC *s_new, *s_old; + int i_new; + void *base_addr; - s_old = &Segments[i_old]; - s_new = &Segments[i_new]; + s_old = &Segments[i_old]; - SelectorMap[i_new] = i_new; - - s_new->selector = (i_new << 3) | 0x0007; - s_new->base_addr = (void *) ((long) s_new->selector << 16); - s_new->length = s_old->length; - s_new->flags = s_old->flags; - s_new->owner = s_old->owner; - if (swap_type) + if (new & 0xffff0000) { - if (s_old->type == MODIFY_LDT_CONTENTS_DATA) - s_new->type = MODIFY_LDT_CONTENTS_CODE; - else - s_new->type = MODIFY_LDT_CONTENTS_DATA; + /************************************************************** + * Let's set the address parameter for no segment. + */ + i_new = -1; + s_new = NULL; + base_addr = (void *) new; } else - s_new->type = s_old->type; - + { + /*************************************************************** + * We need to fill in the segment descriptor for segment "new". + */ + i_new = new; + s_new = &Segments[i_new]; + + SelectorMap[i_new] = i_new; + + s_new->selector = (i_new << 3) | 0x0007; + s_new->base_addr = (void *) ((long) s_new->selector << 16); + s_new->length = s_old->length; + s_new->flags = s_old->flags; + s_new->owner = s_old->owner; + if (swap_type) + { + if (s_old->type == MODIFY_LDT_CONTENTS_DATA) + s_new->type = MODIFY_LDT_CONTENTS_CODE; + else + s_new->type = MODIFY_LDT_CONTENTS_DATA; + } + else + s_new->type = s_old->type; + + base_addr = s_new->base_addr; + } + + /****************************************************************** + * If we don't have a shared memory key for s_old, then we need + * to get one. In this case, we'll also have to copy the data + * to protect it. + */ if (s_old->shm_key == 0) { s_old->shm_key = shmget(IPC_PRIVATE, s_old->length, 0600); if (s_old->shm_key == 0) { - memset(s_new, 0, sizeof(*s_new)); - return 0; + if (s_new) + memset(s_new, 0, sizeof(*s_new)); + return -1; } - if (shmat(s_old->shm_key, s_new->base_addr, 0) == NULL) + if (shmat(s_old->shm_key, base_addr, 0) == NULL) { - memset(s_new, 0, sizeof(*s_new)); + if (s_new) + memset(s_new, 0, sizeof(*s_new)); shmctl(s_old->shm_key, IPC_RMID, NULL); - return 0; + return -1; } - memcpy(s_new->base_addr, s_old->base_addr, s_new->length); + memcpy(base_addr, s_old->base_addr, s_old->length); munmap(s_old->base_addr, ((s_old->length + PAGE_SIZE) & ~(PAGE_SIZE - 1))); shmat(s_old->shm_key, s_old->base_addr, 0); } + /****************************************************************** + * If have shared memory key s_old, then just attach the new + * address. + */ else { - if (shmat(s_old->shm_key, s_new->base_addr, 0) == NULL) + if (shmat(s_old->shm_key, base_addr, 0) == NULL) { - memset(s_new, 0, sizeof(*s_new)); - return 0; + if (s_new) + memset(s_new, 0, sizeof(*s_new)); + return -1; } } - s_new->shm_key = s_old->shm_key; - if (set_ldt_entry(i_new, (unsigned long) s_new->base_addr, - s_new->length - 1, 0, s_new->type, 0, 0) < 0) + /****************************************************************** + * If we are creating a new segment, then we also need to update + * the LDT to include the new selector. In this return the + * new selector. + */ + if (s_new) { - return 0; - } + s_new->shm_key = s_old->shm_key; - return s_new->selector; + if (set_ldt_entry(i_new, (unsigned long) base_addr, + s_old->length - 1, 0, s_new->type, 0, 0) < 0) + { + return -1; + } + + return s_new->selector; + } + /****************************************************************** + * No new segment. So, just return the shared memory key. + */ + else + return s_old->shm_key; } #endif @@ -190,15 +219,20 @@ AllocSelector(unsigned int old_selector) { SEGDESC *s_new, *s_old; int i_new, i_old; + int selector; - i_new = FindUnusedSelector(); + i_new = FindUnusedSelectors(1); s_new = &Segments[i_new]; if (old_selector) { i_old = (old_selector >> 3); #ifdef HAVE_IPC - return IPCCopySelector(i_old, i_new, 0); + selector = IPCCopySelector(i_old, i_new, 0); + if (selector < 0) + return 0; + else + return selector; #else s_old = &Segments[i_old]; s_new->selector = (i_new << 3) | 0x0007; @@ -428,64 +462,72 @@ unsigned int FreeSelector(unsigned int sel) } /********************************************************************** - * CreateNewSegment + * CreateNewSegments */ SEGDESC * -CreateNewSegment(int code_flag, int read_only, int length) +CreateNewSegments(int code_flag, int read_only, int length, int n_segments) { - SEGDESC *s; + SEGDESC *s, *first_segment; int contents; - int i; + int i, last_i; - i = FindUnusedSelector(); + i = FindUnusedSelectors(n_segments); + +#ifdef DEBUG_SELECTORS + fprintf(stderr, + "Using %d segments starting at index %d.\n", n_segments, i); +#endif /* * Fill in selector info. */ - s = &Segments[i]; - if (code_flag) + first_segment = s = &Segments[i]; + for (last_i = i + n_segments; i < last_i; i++, s++) { - contents = MODIFY_LDT_CONTENTS_CODE; - s->flags = 0; - } - else - { - contents = MODIFY_LDT_CONTENTS_DATA; - s->flags = NE_SEGFLAGS_DATA; - } - - s->selector = (i << 3) | 0x0007; - s->length = length; + if (code_flag) + { + contents = MODIFY_LDT_CONTENTS_CODE; + s->flags = 0; + } + else + { + contents = MODIFY_LDT_CONTENTS_DATA; + s->flags = NE_SEGFLAGS_DATA; + } + + s->selector = (i << 3) | 0x0007; + s->length = length; #ifdef DEV_ZERO - if (zfile == NULL) - zfile = fopen("/dev/zero","r"); - s->base_addr = (void *) mmap((char *) (s->selector << 16), - ((s->length + PAGE_SIZE - 1) & - ~(PAGE_SIZE - 1)), - PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_FIXED | MAP_PRIVATE, fileno(zfile), 0); - + if (zfile == NULL) + zfile = fopen("/dev/zero","r"); + s->base_addr = (void *) mmap((char *) (s->selector << 16), + ((s->length + PAGE_SIZE - 1) & + ~(PAGE_SIZE - 1)), + PROT_EXEC | PROT_READ | PROT_WRITE, + MAP_FIXED | MAP_PRIVATE, + fileno(zfile), 0); #else - s->base_addr = (void *) mmap((char *) (s->selector << 16), - ((s->length + PAGE_SIZE - 1) & - ~(PAGE_SIZE - 1)), - PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0); - + s->base_addr = (void *) mmap((char *) (s->selector << 16), + ((s->length + PAGE_SIZE - 1) & + ~(PAGE_SIZE - 1)), + PROT_EXEC | PROT_READ | PROT_WRITE, + MAP_FIXED | MAP_PRIVATE | MAP_ANON, + -1, 0); #endif - if (set_ldt_entry(i, (unsigned long) s->base_addr, - (s->length - 1) & 0xffff, 0, - contents, read_only, 0) < 0) - { - memset(s, 0, sizeof(*s)); - return NULL; + if (set_ldt_entry(i, (unsigned long) s->base_addr, + (s->length - 1) & 0xffff, 0, + contents, read_only, 0) < 0) + { + memset(s, 0, sizeof(*s)); + return NULL; + } + + SelectorMap[i] = (unsigned short) i; + s->type = contents; } - SelectorMap[i] = (unsigned short) i; - s->type = contents; - - return s; + return first_segment; } /********************************************************************** @@ -494,7 +536,7 @@ CreateNewSegment(int code_flag, int read_only, int length) SEGDESC * GetNextSegment(unsigned int flags, unsigned int limit) { - return CreateNewSegment(0, 0, limit); + return CreateNewSegments(0, 0, limit, 1); } /********************************************************************** @@ -672,7 +714,7 @@ CreateEnvironment(void) char *p; SEGDESC * s; - s = CreateNewSegment(0, 0, PAGE_SIZE); + s = CreateNewSegments(0, 0, PAGE_SIZE, 1); if (s == NULL) return NULL; @@ -702,7 +744,7 @@ CreatePSP(void) char *p1, *p2; int i; - s = CreateNewSegment(0, 0, PAGE_SIZE); + s = CreateNewSegments(0, 0, PAGE_SIZE, 1); /* * Fill PSP @@ -835,8 +877,8 @@ CreateSelectors(struct w_files * wpnt) read_only = 1; } - stmp = CreateNewSegment(!(s->flags & NE_SEGFLAGS_DATA), read_only, - s->length); + stmp = CreateNewSegments(!(s->flags & NE_SEGFLAGS_DATA), read_only, + s->length, 1); s->base_addr = stmp->base_addr; s->selector = stmp->selector; @@ -874,7 +916,7 @@ CreateSelectors(struct w_files * wpnt) if(!EnvironmentSelector) { EnvironmentSelector = CreateEnvironment(); PSP_Selector = CreatePSP(); - MakeProcThunks = CreateNewSegment(1, 0, 0x10000); + MakeProcThunks = CreateNewSegments(1, 0, 0x10000, 1); }; return selectors; diff --git a/loader/signal.c b/loader/signal.c index b2a492e221f..be88b963335 100644 --- a/loader/signal.c +++ b/loader/signal.c @@ -3,7 +3,7 @@ #include #include -#ifdef __NetBSD__ +#if defined(__NetBSD__) || defined(__FreeBSD__) #include #else #include @@ -55,7 +55,7 @@ static void win_fault(int signal, int code, struct sigcontext *scp){ if(signal != SIGSEGV) exit(1); if((scp->sc_cs & 7) != 7){ #endif -#ifdef __NetBSD__ +#if defined(__NetBSD__) || defined(__FreeBSD__) /* set_es(0x27); set_ds(0x27); */ if(signal != SIGBUS) exit(1); if(scp->sc_cs == 0x1f){ @@ -134,7 +134,7 @@ init_wine_signals(){ (void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3); wine_sigaction(SIGSEGV, &segv_act, NULL); #endif -#ifdef __NetBSD__ +#if defined(__NetBSD__) || defined(__FreeBSD__) struct sigstack ss; sigset_t sig_mask; diff --git a/loader/wine.c b/loader/wine.c index 48c5e2b2f00..11aed625aa8 100644 --- a/loader/wine.c +++ b/loader/wine.c @@ -363,11 +363,11 @@ _WinMain(int argc, char **argv) if (ss_reg == 0) { - fprintf(stderr, "SS is 0. Send email to bob@amscons.com.\n"); - fprintf(stderr, " No. Really. I want to know what programs\n"); - fprintf(stderr, " do this.\n"); + fprintf(stderr, "SS is 0\n"); } + LinearTest(); + rv = CallToInit16(cs_reg << 16 | ip_reg, ss_reg << 16 | sp_reg, ds_reg); printf ("rv = %x\n", rv); } diff --git a/memory/Makefile b/memory/Makefile index f3ff2c766b6..d9abf4c3a5c 100644 --- a/memory/Makefile +++ b/memory/Makefile @@ -1,6 +1,6 @@ CFLAGS=$(COPTS) $(DEBUGOPTS) -I$(INCLUDE_DIR) -OBJS=global.o heap.o atom.o +OBJS=global.o heap.o atom.o linear.o default: memory.o diff --git a/memory/global.c b/memory/global.c index bf11b370f13..76b558fc25f 100644 --- a/memory/global.c +++ b/memory/global.c @@ -7,37 +7,37 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include "heap.h" #include "segmem.h" -/* - * Global memory pool descriptor. Segments MUST be maintained in segment - * ascending order. If not the reallocation routine will die a horrible - * death. - * - * handle = 0, this descriptor contains the address of a free pool. - * != 0, this describes an allocated block. - * - * sequence = 0, this is not a huge block - * > 0, this is a portion of a huge block - * =-1, this is a free segment - * - * addr - address of this memory block. - * - * length - used to maintain huge blocks. - * - */ -typedef struct global_mem_desc_s -{ - struct global_mem_desc_s *next; - struct global_mem_desc_s *prev; - unsigned short handle; - short sequence; - void *addr; - int length; - int lock_count; -} GDESC; - GDESC *GlobalList = NULL; static unsigned short next_unused_handle = 1; +/********************************************************************** + * GlobalGetGDesc + */ +GDESC *GlobalGetGDesc(unsigned int block) +{ + GDESC *g; + + if (block == 0) + return NULL; + + /* + * Find GDESC for this block. + */ + if (block & 0xffff0000) + { + for (g = GlobalList; g != NULL; g = g->next) + if (g->handle > 0 && (unsigned int) g->addr == block) + break; + } + else + { + for (g = GlobalList; g != NULL; g = g->next) + if (g->handle == block) + break; + } + + return g; +} /********************************************************************** * GlobalGetFreeSegments @@ -91,13 +91,14 @@ GlobalGetFreeSegments(unsigned int flags, int n_segments) /* * Allocate segments. */ - for (count = 0; count < n_segments; count++) + s = CreateNewSegments(0, 0, 0x10000, n_segments); + if (s == NULL) + { + printf("GlobalGetFreeSegments // bad CreateNewSegments !\n"); + return NULL; + } + for (count = 0; count < n_segments; count++, s++) { - s = GetNextSegment(flags, 0x10000); - if (s == NULL) { - printf("GlobalGetFreeSegments // bad GetNextSegment !\n"); - return NULL; - } g = (GDESC *) malloc(sizeof(*g)); if (g == NULL) { printf("GlobalGetFreeSegments // bad GDESC malloc !\n"); @@ -109,6 +110,9 @@ GlobalGetFreeSegments(unsigned int flags, int n_segments) g->sequence = -1; g->addr = s->base_addr; g->length = s->length; + g->linear_addr = NULL; + g->linear_key = 0; + g->linear_count = 0; if (!(flags & GLOBAL_FLAGS_MOVEABLE)) g->lock_count = 1; else @@ -138,6 +142,9 @@ GlobalGetFreeSegments(unsigned int flags, int n_segments) } g->sequence = i + 1; g->length = n_segments; + g->linear_addr = NULL; + g->linear_key = 0; + g->linear_count = 0; } return g_start; @@ -223,6 +230,9 @@ GlobalAlloc(unsigned int flags, unsigned long size) g->handle = next_unused_handle; g->sequence = 0; g->addr = m; + g->linear_addr = NULL; + g->linear_key = 0; + g->linear_count = 0; g->length = size; g->next = g_prev->next; if (g->next) g->next->prev = g; diff --git a/memory/linear.c b/memory/linear.c new file mode 100644 index 00000000000..af403e28c57 --- /dev/null +++ b/memory/linear.c @@ -0,0 +1,193 @@ +static char RCSId[] = "$Id$"; +static char Copyright[] = "Copyright Robert J. Amstadt, 1994"; + +#include +#include +#include "prototypes.h" +#include "heap.h" +#include "segmem.h" + +#ifdef HAVE_IPC +static key_t MemoryKeys[SHMSEG]; /* Keep track of keys were using */ +static int LinearInitialized = 0; +#endif + + +#ifdef HAVE_IPC +/********************************************************************** + * LinearFindSpace + */ +int +LinearFindSpace(int n_segments) +{ + int i, n; + + if (!LinearInitialized) + { + memset(MemoryKeys, -1, sizeof(MemoryKeys)); + return 0; + } + + for (i = 0, n = 0; i < SHMSEG, n != n_segments; i++) + { + if (MemoryKeys[i] < 0) + n++; + else + n = 0; + } + + if (n != n_segments) + return -1; + else + return i - n; +} +#endif /* HAVE_IPC */ + +/********************************************************************** + * GlobalLinearLock + * + * OK, this is an evil beast. We will do one of two things: + * + * 1. If the data item <= 64k, then just call GlobalLock(). + * 2. If the data item > 64k, then map memory. + */ +void * +GlobalLinearLock(unsigned int block) +{ + GDESC *g, *g_first; + int loc_idx; + unsigned long addr; + int i; + + /****************************************************************** + * Get GDESC for this block. + */ + g_first = GlobalGetGDesc(block); + if (g_first == NULL) + return 0; + + /****************************************************************** + * Is block less then 64k in length? + */ + if (g_first->sequence != 1 || g_first->length == 1) + { + return (void *) GlobalLock(block); + } + + /****************************************************************** + * If there is already a linear lock on this memory, then + * just return a pointer to it. + */ + if (g_first->linear_count) + { + g_first->linear_count++; + return g_first->linear_addr; + } + + /****************************************************************** + * No luck. We need to do the linear mapping right now. + */ +#ifdef HAVE_IPC + loc_idx = LinearFindSpace(g_first->length); + if (loc_idx < 0) + return NULL; + + addr = (unsigned long) SHM_RANGE_START + (0x10000 * loc_idx); + g = g_first; + for (i = loc_idx; + i < loc_idx + g_first->length; + i++, addr += 0x10000, g = g->next) + { + if ((MemoryKeys[i] = IPCCopySelector(g->handle >> 3, addr, 0)) < 0) + return NULL; + g->linear_addr = (void *) addr; + g->linear_count = 1; + } +#endif /* HAVE_IPC */ + + return g_first->linear_addr; +} + +/********************************************************************** + * GlobalLinearUnlock + * + */ +unsigned int +GlobalLinearUnlock(unsigned int block) +{ + GDESC *g, *g_first; + int loc_idx; + int i; + + /****************************************************************** + * Get GDESC for this block. + */ + g_first = GlobalGetGDesc(block); + if (g_first == NULL) + return block; + + /****************************************************************** + * Is block less then 64k in length? + */ + if (g_first->sequence != 1 || g_first->length == 1) + { + return GlobalUnlock(block); + } + + /****************************************************************** + * Make sure we have a lock on this block. + */ +#ifdef HAVE_IPC + if (g_first->linear_count > 1) + { + g_first->linear_count--; + } + else if (g_first->linear_count == 1) + { + g = g_first; + loc_idx = (((unsigned int) g_first - (unsigned int) SHM_RANGE_START) + / 0x10000); + for (i = 0; i < g_first->length; i++, g = g->next) + { + shmdt(g->linear_addr); + g->linear_addr = NULL; + MemoryKeys[i] = -1; + } + + g_first->linear_count = 0; + return 0; + } +#endif /* HAVE_IPC */ + + return 0; +} +/**********************************************************************/ + +LinearTest() +{ +#if 0 + unsigned int handle; + int *seg_ptr; + int *lin_ptr; + int seg, i; + int *p; + + handle = GlobalAlloc(0, 0x40000); + seg_ptr = GlobalLock(handle); + lin_ptr = GlobalLinearLock(handle); + + for (seg = 0; seg < 4; seg++) + { + p = (int *) ((char *) seg_ptr + (0x80000 * seg)); + for (i = 0; i < (0x10000 / sizeof(int)); i++, p++) + *p = (seg * (0x10000 / sizeof(int))) + i; + } + + p = lin_ptr; + for (i = 0; i < (0x40000 / sizeof(int)); i++, p++) + { + if (*p != i) + printf("lin_ptr[%x] = %x\n", i, *p); + } +#endif +} diff --git a/misc/Imakefile b/misc/Imakefile index 53eda7629f5..b628e2e5a6f 100644 --- a/misc/Imakefile +++ b/misc/Imakefile @@ -3,37 +3,45 @@ MODULE = misc SRCS = \ - kernel.c \ - user.c \ - rect.c \ - file.c \ - sound.c \ + comm.c \ + dos.c \ + dos_fs.c \ emulate.c \ - keyboard.c \ - profile.c \ - lstr.c \ exec.c \ - message.c \ + file.c \ int1a.c \ int21.c \ - dos_fs.c \ + kernel.c \ + keyboard.c \ + lstr.c \ + main.c \ + message.c \ + profile.c \ + rect.c \ + sound.c \ + spy.c \ + user.c \ xt.c OBJS = \ - kernel.o \ - user.o \ - rect.o \ - file.o \ - sound.o \ + comm.o \ + dos.o \ + dos_fs.o \ emulate.o \ - keyboard.o \ - profile.o \ - lstr.o \ exec.o \ - message.o \ + file.o \ int1a.o \ int21.o \ - dos_fs.o \ + kernel.o \ + keyboard.o \ + lstr.o \ + main.o \ + message.o \ + profile.o \ + rect.o \ + sound.o \ + spy.o \ + user.o \ xt.o WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) diff --git a/misc/comm.c b/misc/comm.c index ca65c0d5ede..d9f53444973 100644 --- a/misc/comm.c +++ b/misc/comm.c @@ -8,7 +8,7 @@ #include #include #include -#ifdef __NetBSD__ +#if defined(__NetBSD__) || defined(__FreeBSD__) #include #include #endif diff --git a/misc/dos_fs.c b/misc/dos_fs.c index b8f052e77a4..3840972e0f4 100644 --- a/misc/dos_fs.c +++ b/misc/dos_fs.c @@ -13,7 +13,7 @@ #ifdef __linux__ #include #endif -#ifdef __NetBSD__ +#if defined(__NetBSD__) || defined(__FreeBSD__) #include #include #endif diff --git a/misc/int21.c b/misc/int21.c index 4d1ae704d76..6caaa7cf46b 100644 --- a/misc/int21.c +++ b/misc/int21.c @@ -1,7 +1,9 @@ #include #include #include +#ifndef __STDC__ #include +#endif #include #include #include diff --git a/misc/message.c b/misc/message.c index f6fb52f3e4e..364b4602b89 100644 --- a/misc/message.c +++ b/misc/message.c @@ -6,7 +6,14 @@ static char Copyright[] = "Copyright Martin Ayotte, 1993"; -#include "windows.h" +#define DEBUG_MSGBOX + +#include +#include +#include +#include +#include +#include "prototypes.h" #include "heap.h" #include "win.h" @@ -26,7 +33,6 @@ typedef struct tagMSGBOX { } MSGBOX; typedef MSGBOX FAR* LPMSGBOX; - LONG SystemMessageBoxProc(HWND hwnd, WORD message, WORD wParam, LONG lParam); /************************************************************************** @@ -40,8 +46,11 @@ int MessageBox( HWND hWnd, LPSTR str, LPSTR title, WORD type ) WNDCLASS wndClass; MSG msg; MSGBOX mb; + DWORD dwStyle; wndPtr = WIN_FindWndPtr(hWnd); +#ifdef DEBUG_MSGBOX printf( "MessageBox: '%s'\n", str ); +#endif wndClass.style = CS_HREDRAW | CS_VREDRAW ; wndClass.lpfnWndProc = (WNDPROC)SystemMessageBoxProc; wndClass.cbClsExtra = 0; @@ -58,8 +67,9 @@ int MessageBox( HWND hWnd, LPSTR str, LPSTR title, WORD type ) mb.Str = str; mb.wType = type; mb.ActiveFlg = TRUE; - hDlg = CreateWindow("MESSAGEBOX", title, - WS_POPUP | WS_DLGFRAME | WS_VISIBLE, 100, 150, 400, 120, + dwStyle = WS_POPUP | WS_DLGFRAME | WS_VISIBLE; + if ((type & (MB_SYSTEMMODAL | MB_TASKMODAL)) == 0) dwStyle |= WS_CAPTION; + hDlg = CreateWindow("MESSAGEBOX", title, dwStyle, 100, 150, 400, 120, (HWND)NULL, (HMENU)NULL, wndPtr->hInstance, (LPSTR)&mb); if (hDlg == 0) return 0; while(TRUE) { @@ -68,8 +78,10 @@ int MessageBox( HWND hWnd, LPSTR str, LPSTR title, WORD type ) TranslateMessage(&msg); DispatchMessage(&msg); } - printf( "after MessageBox !\n"); if (!UnregisterClass("MESSAGEBOX", wndPtr->hInstance)) return 0; +#ifdef DEBUG_MSGBOX + printf( "MessageBox return %04X !\n", mb.wRetVal); +#endif return(mb.wRetVal); } @@ -219,7 +231,9 @@ LONG SystemMessageBoxProc(HWND hWnd, WORD message, WORD wParam, LONG lParam) EndPaint(hWnd, &ps); break; case WM_DESTROY: +#ifdef DEBUG_MSGBOX printf("MessageBox WM_DESTROY !\n"); +#endif ReleaseCapture(); lpmb = MsgBoxGetStorageHeader(hWnd); lpmb->ActiveFlg = FALSE; @@ -227,6 +241,9 @@ LONG SystemMessageBoxProc(HWND hWnd, WORD message, WORD wParam, LONG lParam) if (lpmb->hWndYes) DestroyWindow(lpmb->hWndYes); if (lpmb->hWndNo) DestroyWindow(lpmb->hWndNo); if (lpmb->hWndCancel) DestroyWindow(lpmb->hWndCancel); +#ifdef DEBUG_MSGBOX + printf("MessageBox WM_DESTROY end !\n"); +#endif break; case WM_COMMAND: lpmb = MsgBoxGetStorageHeader(hWnd); @@ -257,17 +274,41 @@ BOOL FAR PASCAL AboutWine_Proc(HWND hDlg, WORD msg, WORD wParam, LONG lParam) HFONT hOldFont; RECT rect; BITMAP bm; - char C[80]; int X; - static HBITMAP hBitMap; + OFSTRUCT ofstruct; + static LPSTR ptr; + static char str[256]; + static HBITMAP hBitMap = 0; + static BOOL CreditMode; + static HANDLE hFile = 0; switch (msg) { case WM_INITDIALOG: - strcpy(C, "WINELOGO"); - hBitMap = LoadBitmap((HINSTANCE)NULL, (LPSTR)C); + CreditMode = FALSE; + strcpy(str, "WINELOGO"); + hBitMap = LoadBitmap((HINSTANCE)NULL, (LPSTR)str); +/* getcwd(str, 256); + strcat(str, ";"); + strcat(str, getenv("HOME")); + strcat(str, ";"); + strcat(str, getenv("WINEPATH")); */ + strcpy(str, "PROPOSED_LICENSE"); + printf("str = '%s'\n", str); + hFile = KERNEL_OpenFile((LPSTR)str, &ofstruct, OF_READ); + ptr = (LPSTR)malloc(2048); + lseek(hFile, 0L, SEEK_SET); + KERNEL__lread(hFile, ptr, 2000L); + close(hFile); return TRUE; case WM_PAINT: hDC = BeginPaint(hDlg, &ps); GetClientRect(hDlg, &rect); + if (CreditMode) { + FillRect(hDC, &rect, GetStockObject(WHITE_BRUSH)); + InflateRect(&rect, -8, -8); + DrawText(hDC, ptr, -1, &rect, DT_LEFT | DT_WORDBREAK); + EndPaint(hDlg, &ps); + return TRUE; + } FillRect(hDC, &rect, GetStockObject(GRAY_BRUSH)); InflateRect(&rect, -3, -3); FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH)); @@ -283,8 +324,26 @@ BOOL FAR PASCAL AboutWine_Proc(HWND hDlg, WORD msg, WORD wParam, LONG lParam) case WM_COMMAND: switch (wParam) { + case IDYES: + if (!CreditMode) { + SetWindowPos(hDlg, (HWND)NULL, 0, 0, 640, 480, + SWP_NOMOVE | SWP_NOZORDER); + } + else { + SetWindowPos(hDlg, (HWND)NULL, 0, 0, 320, 250, + SWP_NOMOVE | SWP_NOZORDER); + } + CreditMode = !CreditMode; + ShowWindow(GetDlgItem(hDlg, IDYES), CreditMode ? SW_HIDE : SW_SHOW); + ShowWindow(GetDlgItem(hDlg, IDOK), CreditMode ? SW_HIDE : SW_SHOW); + InvalidateRect(hDlg, (LPRECT)NULL, TRUE); + UpdateWindow(hDlg); + return TRUE; + case IDCANCEL: case IDOK: -CloseDLG: EndDialog(hDlg, TRUE); +CloseDLG: if (hBitMap != 0 ) DeleteObject(hBitMap); + if (ptr != NULL) free(ptr); + EndDialog(hDlg, TRUE); return TRUE; default: return TRUE; diff --git a/objects/palette.c b/objects/palette.c index f107a618d0c..0ff149ebb6e 100644 --- a/objects/palette.c +++ b/objects/palette.c @@ -10,7 +10,7 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #ifdef linux #include #endif -#ifdef __NetBSD__ +#if defined(__NetBSD__) || defined(__FreeBSD__) #include #define MAXINT INT_MAX #endif diff --git a/sysres.dll b/sysres.dll index 0a61ba9a491..8b55d673859 100755 Binary files a/sysres.dll and b/sysres.dll differ diff --git a/test/widget.exe b/test/widget.exe index 95413e0ec83..42d1465cc5f 100755 Binary files a/test/widget.exe and b/test/widget.exe differ diff --git a/tools/build.c b/tools/build.c index d596493847d..7343b765e16 100644 --- a/tools/build.c +++ b/tools/build.c @@ -9,7 +9,7 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #ifdef linux #define UTEXTSEL 0x23 #endif -#ifdef __NetBSD__ +#if defined(__NetBSD__) || defined(__FreeBSD__) #define UTEXTSEL 0x1f #endif diff --git a/windows/Imakefile b/windows/Imakefile index b16652fcaab..5aa561e1adc 100644 --- a/windows/Imakefile +++ b/windows/Imakefile @@ -3,46 +3,54 @@ MODULE = windows SRCS = \ + caret.c \ class.c \ + clipping.c \ dc.c \ dce.c \ - event.c \ - message.c \ - win.c \ - timer.c \ - graphics.c \ - clipping.c \ - mapping.c \ - painting.c \ - keyboard.c \ - utility.c \ - syscolor.c \ - defwnd.c \ defdlg.c \ + defwnd.c \ dialog.c \ + event.c \ focus.c \ - scroll.c + graphics.c \ + keyboard.c \ + mapping.c \ + message.c \ + nonclient.c \ + painting.c \ + scroll.c \ + syscolor.c \ + sysmetrics.c \ + timer.c \ + utility.c \ + win.c \ + winpos.c OBJS = \ + caret.o \ class.o \ + clipping.o \ dc.o \ dce.o \ - event.o \ - message.o \ - win.o \ - timer.o \ - graphics.o \ - clipping.o \ - mapping.o \ - painting.o \ - keyboard.o \ - utility.o \ - syscolor.o \ - defwnd.o \ defdlg.o \ + defwnd.o \ dialog.o \ + event.o \ focus.o \ - scroll.o + graphics.o \ + keyboard.o \ + mapping.o \ + message.o \ + nonclient.o \ + painting.o \ + scroll.o \ + syscolor.o \ + sysmetrics.o \ + timer.o \ + utility.o \ + win.o \ + winpos.o WineRelocatableTarget($(TOP)/$(MODULE),,$(OBJS)) DependTarget() diff --git a/windows/clipping.c b/windows/clipping.c index 3c759a68790..28d0da9578e 100644 --- a/windows/clipping.c +++ b/windows/clipping.c @@ -38,6 +38,16 @@ void InvalidateRgn( HWND hwnd, HRGN hrgn, BOOL erase ) else MSG_IncPaintCount( wndPtr->hmemTaskQ ); wndPtr->hrgnUpdate = newRgn; if (erase) wndPtr->flags |= WIN_ERASE_UPDATERGN; + + /* Invalidate the children overlapping the region */ + + if (wndPtr->dwStyle & WS_CLIPCHILDREN) return; + for (hwnd = wndPtr->hwndChild; (hwnd); hwnd = wndPtr->hwndNext) + { + if (!(wndPtr = WIN_FindWndPtr( hwnd ))) break; + if (hrgn && !RectInRegion( hrgn, &wndPtr->rectWindow )) continue; + InvalidateRgn( hwnd, hrgn, erase ); + } } diff --git a/windows/defwnd.c b/windows/defwnd.c index 95bb0f0fc85..62f9f502d71 100644 --- a/windows/defwnd.c +++ b/windows/defwnd.c @@ -13,14 +13,34 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "user.h" extern LONG NC_HandleNCPaint( HWND hwnd, HRGN hrgn ); +extern LONG NC_HandleNCActivate( HWND hwnd, WORD wParam ); extern LONG NC_HandleNCCalcSize( HWND hwnd, NCCALCSIZE_PARAMS *params ); extern LONG NC_HandleNCHitTest( HWND hwnd, POINT pt ); extern LONG NC_HandleNCLButtonDown( HWND hwnd, WORD wParam, LONG lParam ); -extern LONG NC_HandleNCLButtonUp( HWND hwnd, WORD wParam, LONG lParam ); extern LONG NC_HandleNCLButtonDblClk( HWND hwnd, WORD wParam, LONG lParam ); -extern LONG NC_HandleNCMouseMove( HWND hwnd, WORD wParam, POINT pt ); extern LONG NC_HandleSysCommand( HWND hwnd, WORD wParam, POINT pt ); extern LONG NC_HandleSetCursor( HWND hwnd, WORD wParam, LONG lParam ); +extern void NC_TrackSysMenu( HWND hwnd ); /* menu.c */ + + + +/*********************************************************************** + * DEFWND_SetText + * + * Set the window text. + */ +void DEFWND_SetText( HWND hwnd, LPSTR text ) +{ + LPSTR textPtr; + WND *wndPtr = WIN_FindWndPtr( hwnd ); + + if (wndPtr->hText) USER_HEAP_FREE( wndPtr->hText ); + wndPtr->hText = USER_HEAP_ALLOC( LMEM_MOVEABLE, strlen(text) + 2 ); + textPtr = (LPSTR) USER_HEAP_ADDR( wndPtr->hText ); + strcpy( textPtr, text ); + /* for use by edit control */ + *(textPtr + strlen(text) + 1) = '\0'; +} /*********************************************************************** @@ -43,15 +63,7 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) { CREATESTRUCT * createStruct = (CREATESTRUCT *)lParam; if (createStruct->lpszName) - { - /* Allocate space for window text */ - wndPtr->hText = USER_HEAP_ALLOC(GMEM_MOVEABLE, - strlen(createStruct->lpszName) + 2); - textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText); - strcpy(textPtr, createStruct->lpszName); - *(textPtr + strlen(createStruct->lpszName) + 1) = '\0'; - /* for use by edit control */ - } + DEFWND_SetText( hwnd, createStruct->lpszName ); return 1; } @@ -67,14 +79,11 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) case WM_NCLBUTTONDOWN: return NC_HandleNCLButtonDown( hwnd, wParam, lParam ); - case WM_NCLBUTTONUP: - return NC_HandleNCLButtonUp( hwnd, wParam, lParam ); - case WM_NCLBUTTONDBLCLK: return NC_HandleNCLButtonDblClk( hwnd, wParam, lParam ); - case WM_NCMOUSEMOVE: - return NC_HandleNCMouseMove( hwnd, wParam, MAKEPOINT(lParam) ); + case WM_NCACTIVATE: + return NC_HandleNCActivate( hwnd, wParam ); case WM_NCDESTROY: { @@ -95,6 +104,19 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) DestroyWindow( hwnd ); return 0; + case WM_MOUSEACTIVATE: + if (wndPtr->dwStyle & WS_CHILD) + { + LONG ret = SendMessage( wndPtr->hwndParent, WM_MOUSEACTIVATE, + wParam, lParam ); + if (ret) return ret; + } + return MA_ACTIVATE; + + case WM_ACTIVATE: + if (wParam) SetFocus( hwnd ); + break; + case WM_WINDOWPOSCHANGED: { WINDOWPOS * winPos = (WINDOWPOS *)lParam; @@ -170,16 +192,9 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) } case WM_SETTEXT: - { - if (wndPtr->hText) - USER_HEAP_FREE(wndPtr->hText); - - wndPtr->hText = USER_HEAP_ALLOC(GMEM_MOVEABLE, - strlen((LPSTR)lParam) + 1); - textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText); - strcpy(textPtr, (LPSTR)lParam); - return (0L); - } + DEFWND_SetText( hwnd, (LPSTR)lParam ); + NC_HandleNCPaint( hwnd, (HRGN)1 ); /* Repaint caption */ + return 0; case WM_SETCURSOR: if (wndPtr->dwStyle & WS_CHILD) @@ -193,6 +208,7 @@ LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) case WM_SYSKEYDOWN: if (wParam == VK_MENU) { printf("VK_MENU Pressed // hMenu=%04X !\n", GetMenu(hwnd)); + NC_TrackSysMenu(hwnd); } break; case WM_SYSKEYUP: diff --git a/windows/dialog.c b/windows/dialog.c index 6316e34c05b..9f0b64af166 100644 --- a/windows/dialog.c +++ b/windows/dialog.c @@ -9,6 +9,7 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "windows.h" #include "dialog.h" #include "win.h" +#include "user.h" /* Dialog base units */ @@ -510,14 +511,13 @@ int GetDlgItemText( HWND hwnd, WORD id, LPSTR str, WORD max ) */ void SetDlgItemInt( HWND hwnd, WORD id, WORD value, BOOL fSigned ) { - HANDLE hText = LocalAlloc( LMEM_MOVEABLE, 10 ); - char * str = (char *) LocalLock( hText ); + HANDLE hText = USER_HEAP_ALLOC(0, 10 ); + char * str = (char *) USER_HEAP_ADDR( hText ); if (fSigned) sprintf( str, "%d", value ); else sprintf( str, "%u", value ); SendDlgItemMessage( hwnd, id, WM_SETTEXT, 0, (DWORD)str ); - LocalUnlock( hText ); - LocalFree( hText ); + USER_HEAP_FREE( hText ); } @@ -534,9 +534,9 @@ WORD GetDlgItemInt( HWND hwnd, WORD id, BOOL * translated, BOOL fSigned ) if (translated) *translated = FALSE; if (!(len = SendDlgItemMessage( hwnd, id, WM_GETTEXTLENGTH, 0, 0 ))) return 0; - if (!(hText = LocalAlloc(LMEM_MOVEABLE, len+1 ))) + if (!(hText = USER_HEAP_ALLOC(0, len+1 ))) return 0; - str = (char *) LocalLock( hText ); + str = (char *) USER_HEAP_ADDR( hText ); if (SendDlgItemMessage( hwnd, id, WM_GETTEXT, len+1, (DWORD)str )) { char * endptr; @@ -555,8 +555,7 @@ WORD GetDlgItemInt( HWND hwnd, WORD id, BOOL * translated, BOOL fSigned ) } } } - LocalUnlock( hText ); - LocalFree( hText ); + USER_HEAP_FREE( hText ); return (WORD)result; } diff --git a/windows/event.c b/windows/event.c index ba1c0a363d2..155c66f5e58 100644 --- a/windows/event.c +++ b/windows/event.c @@ -18,6 +18,8 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; extern Display * display; +extern void WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg ); /*winpos.c*/ + /* X context to associate a hwnd to an X window */ static XContext winContext = 0; @@ -453,10 +455,11 @@ static void EVENT_FocusIn( HWND hwnd, XFocusChangeEvent *event ) */ static void EVENT_FocusOut( HWND hwnd, XFocusChangeEvent *event ) { - WND * wndPtr = WIN_FindWndPtr( hwnd ); - if (!wndPtr) return; + + if (hwnd == GetActiveWindow()) WINPOS_ChangeActiveWindow( 0, FALSE ); + if (wndPtr->dwStyle & WS_DISABLED) { return; } @@ -503,8 +506,8 @@ HWND SetCapture(HWND wnd) return 0; rv = XGrabPointer(display, wnd_p->window, False, - ButtonPressMask | ButtonReleaseMask | ButtonMotionMask, - GrabModeAsync, GrabModeSync, None, None, CurrentTime); + ButtonPressMask | ButtonReleaseMask | PointerMotionMask, + GrabModeAsync, GrabModeAsync, None, None, CurrentTime); if (rv == GrabSuccess) { diff --git a/windows/focus.c b/windows/focus.c index a2d2b8d75f8..0e8813857f1 100644 --- a/windows/focus.c +++ b/windows/focus.c @@ -24,6 +24,7 @@ HWND SetFocus(HWND hwnd) WND *wndPtr; hWndPrevFocus = hWndFocus; + hWndFocus = hwnd; if (hwnd == 0) { diff --git a/windows/message.c b/windows/message.c index b41dbf88b5c..de06f2841ce 100644 --- a/windows/message.c +++ b/windows/message.c @@ -24,6 +24,7 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; extern BOOL TIMER_CheckTimer( DWORD *next ); /* timer.c */ extern void EVENT_ProcessEvent( XEvent *event ); /* event.c */ +extern void WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg ); /*winpos.c*/ extern Display * display; @@ -195,32 +196,65 @@ static void MSG_RemoveMsg( MESSAGEQUEUE * msgQueue, int pos ) * MSG_TranslateMouseMsg * * Translate an mouse hardware event into a real mouse message. + * Return value indicates whether the translated message must be passed + * to the user. * Actions performed: * - Translate button-down messages in double-clicks. * - Send the WM_NCHITTEST message to find where the cursor is. + * - Activate the window if needed. * - Translate the message into a non-client message, or translate * the coordinates to client coordinates. * - Send the WM_SETCURSOR message. */ -static void MSG_TranslateMouseMsg( MSG *msg ) +static BOOL MSG_TranslateMouseMsg( MSG *msg ) { + BOOL eatMsg = FALSE; static DWORD lastClickTime = 0; static WORD lastClickMsg = 0; static POINT lastClickPos = { 0, 0 }; + BOOL mouseClick = ((msg->message == WM_LBUTTONDOWN) || + (msg->message == WM_RBUTTONDOWN) || + (msg->message == WM_MBUTTONDOWN)); + + /* Send the WM_NCHITTEST message */ + LONG hittest_result = SendMessage( msg->hwnd, WM_NCHITTEST, 0, MAKELONG( msg->pt.x, msg->pt.y ) ); + + /* Activate the window if needed */ + + if (mouseClick) + { + HWND parent, hwndTop = msg->hwnd; + while ((parent = GetParent(hwndTop)) != 0) hwndTop = parent; + if (hwndTop != GetActiveWindow()) + { + LONG ret = SendMessage( msg->hwnd, WM_MOUSEACTIVATE, hwndTop, + MAKELONG( hittest_result, msg->message ) ); + if ((ret == MA_ACTIVATEANDEAT) || (ret == MA_NOACTIVATEANDEAT)) + eatMsg = TRUE; + if ((ret == MA_ACTIVATE) || (ret == MA_ACTIVATEANDEAT)) + { + SetWindowPos( hwndTop, HWND_TOP, 0, 0, 0, 0, + SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE ); + WINPOS_ChangeActiveWindow( hwndTop, TRUE ); + } + } + } + + /* Send the WM_SETCURSOR message */ + SendMessage( msg->hwnd, WM_SETCURSOR, msg->hwnd, MAKELONG( hittest_result, msg->message )); + if (eatMsg) return FALSE; - if ((msg->message == WM_LBUTTONDOWN) || - (msg->message == WM_RBUTTONDOWN) || - (msg->message == WM_MBUTTONDOWN)) + /* Check for double-click */ + + if (mouseClick) { BOOL dbl_click = FALSE; - /* Check for double-click */ - if ((msg->message == lastClickMsg) && (msg->time - lastClickTime < doubleClickSpeed) && (abs(msg->pt.x - lastClickPos.x) < SYSMETRICS_CXDOUBLECLK/2) && @@ -247,6 +281,8 @@ static void MSG_TranslateMouseMsg( MSG *msg ) lastClickPos = msg->pt; } + /* Build the translated message */ + msg->lParam = MAKELONG( msg->pt.x, msg->pt.y ); if (hittest_result == HTCLIENT) { @@ -257,6 +293,7 @@ static void MSG_TranslateMouseMsg( MSG *msg ) msg->wParam = hittest_result; msg->message += WM_NCLBUTTONDOWN - WM_LBUTTONDOWN; } + return TRUE; } @@ -350,6 +387,33 @@ void hardware_event( HWND hwnd, WORD message, WORD wParam, LONG lParam, } +/*********************************************************************** + * MSG_GetHardwareMessage + * + * Like GetMessage(), but only return mouse and keyboard events. + * Used internally for window moving and resizing. Mouse messages + * are not translated. + */ +BOOL MSG_GetHardwareMessage( LPMSG msg ) +{ + int pos; + XEvent event; + + while(1) + { + if ((pos = MSG_FindMsg( sysMsgQueue, 0, 0, 0 )) != -1) + { + *msg = sysMsgQueue->messages[pos].msg; + MSG_RemoveMsg( sysMsgQueue, pos ); + break; + } + XNextEvent( display, &event ); + EVENT_ProcessEvent( &event ); + } + return TRUE; +} + + /*********************************************************************** * SetTaskQueue (KERNEL.34) */ @@ -505,9 +569,14 @@ static BOOL MSG_PeekMessage( MESSAGEQUEUE * msgQueue, LPMSG msg, HWND hwnd, msgQueue->GetMessagePosVal = *(DWORD *)&msg->pt; msgQueue->GetMessageExtraInfoVal = qmsg->extraInfo; - if (flags & PM_REMOVE) MSG_RemoveMsg( sysMsgQueue, pos ); if ((msg->message >= WM_MOUSEFIRST) && - (msg->message <= WM_MOUSELAST)) MSG_TranslateMouseMsg( msg ); + (msg->message <= WM_MOUSELAST)) + if (!MSG_TranslateMouseMsg( msg )) + { + MSG_RemoveMsg( sysMsgQueue, pos ); + continue; + } + if (flags & PM_REMOVE) MSG_RemoveMsg( sysMsgQueue, pos ); break; } diff --git a/windows/nonclient.c b/windows/nonclient.c index d326ab91528..8f848020c8b 100644 --- a/windows/nonclient.c +++ b/windows/nonclient.c @@ -7,7 +7,10 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1994"; #include "win.h" +#include "message.h" #include "sysmetrics.h" +#include "user.h" +#include "scroll.h" static HBITMAP hbitmapClose = 0; @@ -18,15 +21,12 @@ static HBITMAP hbitmapMaximizeD = 0; static HBITMAP hbitmapRestore = 0; static HBITMAP hbitmapRestoreD = 0; - /* Hit test code returned when the mouse is captured. */ - /* Used to direct NC mouse messages to the correct part of the window. */ -static WORD captureHitTest = HTCLIENT; +extern void NC_TrackSysMenu( HWND hwnd ); /* menu.c */ +extern void WINPOS_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos, + POINT *minTrack, POINT *maxTrack ); /* winpos.c */ - /* Point where the current capture started. Used for SC_SIZE and SC_MOVE. */ -static POINT capturePoint; +extern Display * display; - /* Current window rectangle when a move or resize is in progress. */ -static RECT sizingRect; /* Some useful macros */ #define HAS_DLGFRAME(style,exStyle) \ @@ -136,7 +136,10 @@ static void NC_GetInsideRect( HWND hwnd, RECT *rect ) /* Remove frame from rectangle */ if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle )) + { InflateRect( rect, -SYSMETRICS_CXDLGFRAME, -SYSMETRICS_CYDLGFRAME); + if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME) InflateRect( rect, -1, 0); + } else { if (HAS_THICKFRAME( wndPtr->dwStyle )) @@ -264,7 +267,7 @@ LONG NC_HandleNCHitTest( HWND hwnd, POINT pt ) #ifdef DEBUG_NONCLIENT printf( "NC_HandleNCHitTest: hwnd=%x pt=%d,%d\n", hwnd, pt.x, pt.y ); #endif - if (hwnd == GetCapture()) return captureHitTest; + if (hwnd == GetCapture()) return HTCLIENT; return NC_InternalNCHitTest( hwnd, pt ); } @@ -272,18 +275,16 @@ LONG NC_HandleNCHitTest( HWND hwnd, POINT pt ) /*********************************************************************** * NC_DrawSysButton */ -static void NC_DrawSysButton( HWND hwnd, HDC hdc ) +static void NC_DrawSysButton( HWND hwnd, HDC hdc, BOOL down ) { RECT rect; - BOOL down; HDC hdcMem = CreateCompatibleDC( hdc ); if (hdcMem) { NC_GetInsideRect( hwnd, &rect ); - down = ((GetCapture() == hwnd) && (captureHitTest == HTSYSMENU)); SelectObject( hdcMem, hbitmapClose ); - BitBlt( hdc, rect.left-1, rect.top-1, SYSMETRICS_CXSIZE+1, - SYSMETRICS_CYSIZE+1, hdcMem, 0, 0, down ? NOTSRCCOPY : SRCCOPY); + BitBlt( hdc, rect.left, rect.top, SYSMETRICS_CXSIZE, + SYSMETRICS_CYSIZE, hdcMem, 1, 1, down ? NOTSRCCOPY : SRCCOPY ); DeleteDC( hdcMem ); } } @@ -292,15 +293,13 @@ static void NC_DrawSysButton( HWND hwnd, HDC hdc ) /*********************************************************************** * NC_DrawMaxButton */ -static void NC_DrawMaxButton( HWND hwnd, HDC hdc ) +static void NC_DrawMaxButton( HWND hwnd, HDC hdc, BOOL down ) { RECT rect; - BOOL down; HDC hdcMem = CreateCompatibleDC( hdc ); if (hdcMem) { NC_GetInsideRect( hwnd, &rect ); - down = ((GetCapture() == hwnd) && (captureHitTest == HTMAXBUTTON)); if (IsZoomed(hwnd)) SelectObject( hdcMem, down ? hbitmapRestoreD : hbitmapRestore ); else SelectObject( hdcMem, down ? hbitmapMaximizeD : hbitmapMaximize ); @@ -314,7 +313,7 @@ static void NC_DrawMaxButton( HWND hwnd, HDC hdc ) /*********************************************************************** * NC_DrawMinButton */ -static void NC_DrawMinButton( HWND hwnd, HDC hdc ) +static void NC_DrawMinButton( HWND hwnd, HDC hdc, BOOL down ) { RECT rect; WND *wndPtr = WIN_FindWndPtr( hwnd ); @@ -324,8 +323,7 @@ static void NC_DrawMinButton( HWND hwnd, HDC hdc ) NC_GetInsideRect( hwnd, &rect ); if (wndPtr->dwStyle & WS_MAXIMIZEBOX) rect.right -= SYSMETRICS_CXSIZE + 1; - if ((GetCapture() == hwnd) && (captureHitTest == HTMINBUTTON)) - SelectObject( hdcMem, hbitmapMinimizeD ); + if (down) SelectObject( hdcMem, hbitmapMinimizeD ); else SelectObject( hdcMem, hbitmapMinimize ); BitBlt( hdc, rect.right - SYSMETRICS_CXSIZE - 1, rect.top - 1, SYSMETRICS_CXSIZE+2, SYSMETRICS_CYSIZE+2, hdcMem, 0, 0, SRCCOPY); @@ -346,8 +344,8 @@ static void NC_DrawFrame( HDC hdc, RECT *rect, BOOL dlgFrame ) if (dlgFrame) { - width = SYSMETRICS_CXDLGFRAME; - height = SYSMETRICS_CYDLGFRAME; + width = SYSMETRICS_CXDLGFRAME - 1; + height = SYSMETRICS_CYDLGFRAME - 1; } else { @@ -412,12 +410,9 @@ static void NC_DrawFrame( HDC hdc, RECT *rect, BOOL dlgFrame ) * * Draw the frame used when moving or resizing window. */ -static void NC_DrawMovingFrame( HWND hwnd, RECT *rect ) +static void NC_DrawMovingFrame( HDC hdc, RECT *rect, BOOL thickframe ) { - WND *wndPtr = WIN_FindWndPtr( hwnd ); - HDC hdc = GetDC( 0 ); - - if (HAS_THICKFRAME( wndPtr->dwStyle )) + if (thickframe) { SelectObject( hdc, GetStockObject( GRAY_BRUSH ) ); PatBlt( hdc, rect->left, rect->top, @@ -433,7 +428,6 @@ static void NC_DrawMovingFrame( HWND hwnd, RECT *rect ) rect->bottom - rect->top - SYSMETRICS_CYFRAME, PATINVERT ); } else DrawFocusRect( hdc, rect ); - ReleaseDC( 0, hdc ); } @@ -443,10 +437,12 @@ static void NC_DrawMovingFrame( HWND hwnd, RECT *rect ) * Draw the window caption. * The correct pen for the window frame must be selected in the DC. */ -static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd, DWORD style ) +static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd, + DWORD style, BOOL active ) { RECT r = *rect; HBRUSH hbrushCaption; + WND * wndPtr = WIN_FindWndPtr( hwnd ); char buffer[256]; if (!hbitmapClose) @@ -461,52 +457,66 @@ static void NC_DrawCaption( HDC hdc, RECT *rect, HWND hwnd, DWORD style ) hbitmapRestoreD = LoadBitmap( 0, MAKEINTRESOURCE(OBM_RESTORED) ); } - hbrushCaption = CreateSolidBrush( GetSysColor( COLOR_ACTIVECAPTION ) ); + if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME) + { + HBRUSH hbrushWindow = CreateSolidBrush(GetSysColor(COLOR_WINDOW)); + HBRUSH hbrushOld = SelectObject( hdc, hbrushWindow ); + PatBlt( hdc, r.left, r.top, 1, r.bottom-r.top+1,PATCOPY ); + PatBlt( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY ); + PatBlt( hdc, r.left, r.top-1, r.right-r.left, 1, PATCOPY ); + r.left++; + r.right--; + SelectObject( hdc, hbrushOld ); + DeleteObject( hbrushWindow ); + } + + if (active) + hbrushCaption = CreateSolidBrush( GetSysColor(COLOR_ACTIVECAPTION) ); + else hbrushCaption = CreateSolidBrush( GetSysColor(COLOR_INACTIVECAPTION)); MoveTo( hdc, r.left, r.bottom ); LineTo( hdc, r.right-1, r.bottom ); if (style & WS_SYSMENU) { - NC_DrawSysButton( hwnd, hdc ); + NC_DrawSysButton( hwnd, hdc, FALSE ); r.left += SYSMETRICS_CXSIZE + 1; MoveTo( hdc, r.left - 1, r.top ); LineTo( hdc, r.left - 1, r.bottom ); } if (style & WS_MAXIMIZEBOX) { - NC_DrawMaxButton( hwnd, hdc ); + NC_DrawMaxButton( hwnd, hdc, FALSE ); r.right -= SYSMETRICS_CXSIZE + 1; } if (style & WS_MINIMIZEBOX) { - NC_DrawMinButton( hwnd, hdc ); + NC_DrawMinButton( hwnd, hdc, FALSE ); r.right -= SYSMETRICS_CXSIZE + 1; } FillRect( hdc, &r, hbrushCaption ); + DeleteObject( hbrushCaption ); if (GetWindowText( hwnd, buffer, 256 )) { - SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) ); + if (active) SetTextColor( hdc, GetSysColor( COLOR_CAPTIONTEXT ) ); + else SetTextColor( hdc, GetSysColor( COLOR_INACTIVECAPTIONTEXT ) ); SetBkMode( hdc, TRANSPARENT ); - DrawText( hdc, buffer, -1, &r, - DT_SINGLELINE | DT_CENTER | DT_VCENTER ); + DrawText( hdc, buffer, -1, &r, DT_SINGLELINE | DT_CENTER | DT_VCENTER); } - - DeleteObject( hbrushCaption ); } /*********************************************************************** - * NC_HandleNCPaint + * NC_DoNCPaint * - * Handle a WM_NCPAINT message. Called from DefWindowProc(). + * Paint the non-client area. */ -LONG NC_HandleNCPaint( HWND hwnd, HRGN hrgn ) +static void NC_DoNCPaint( HWND hwnd, HRGN hrgn, BOOL active ) { HDC hdc; - RECT rect; + RECT rect, rect2; HBRUSH hbrushBorder = 0; HPEN hpenFrame = 0; @@ -516,13 +526,13 @@ LONG NC_HandleNCPaint( HWND hwnd, HRGN hrgn ) printf( "NC_HandleNCPaint: %d %d\n", hwnd, hrgn ); #endif - if (!wndPtr || !hrgn) return 0; + if (!wndPtr || !hrgn) return; if (!(wndPtr->dwStyle & (WS_BORDER | WS_DLGFRAME | WS_THICKFRAME))) - return 0; /* Nothing to do! */ + return; /* Nothing to do! */ if (hrgn == 1) hdc = GetDCEx( hwnd, 0, DCX_CACHE | DCX_WINDOW ); else hdc = GetDCEx( hwnd, hrgn, DCX_CACHE | DCX_WINDOW | DCX_INTERSECTRGN); - if (!hdc) return 0; + if (!hdc) return; if (ExcludeVisRect( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left, wndPtr->rectClient.top-wndPtr->rectWindow.top, wndPtr->rectClient.right-wndPtr->rectWindow.left, @@ -530,7 +540,7 @@ LONG NC_HandleNCPaint( HWND hwnd, HRGN hrgn ) == NULLREGION) { ReleaseDC( hwnd, hdc ); - return 0; + return; } rect.top = rect.left = 0; @@ -539,7 +549,9 @@ LONG NC_HandleNCPaint( HWND hwnd, HRGN hrgn ) hpenFrame = CreatePen( PS_SOLID, 1, GetSysColor(COLOR_WINDOWFRAME) ); SelectObject( hdc, hpenFrame ); - hbrushBorder = CreateSolidBrush( GetSysColor(COLOR_ACTIVEBORDER) ); + if (active) + hbrushBorder = CreateSolidBrush( GetSysColor(COLOR_ACTIVEBORDER) ); + else hbrushBorder = CreateSolidBrush( GetSysColor(COLOR_INACTIVEBORDER) ); SelectObject( hdc, hbrushBorder ); if ((wndPtr->dwStyle & WS_BORDER) || (wndPtr->dwStyle & WS_DLGFRAME)) @@ -552,34 +564,36 @@ LONG NC_HandleNCPaint( HWND hwnd, HRGN hrgn ) InflateRect( &rect, -1, -1 ); } - if ((wndPtr->dwStyle & WS_DLGFRAME) && - ((wndPtr->dwExStyle & WS_EX_DLGMODALFRAME) || - !(wndPtr->dwStyle & WS_BORDER))) NC_DrawFrame( hdc, &rect, TRUE ); - else if (wndPtr->dwStyle & WS_THICKFRAME) NC_DrawFrame(hdc, &rect, FALSE); + if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle )) + NC_DrawFrame( hdc, &rect, TRUE ); + else if (wndPtr->dwStyle & WS_THICKFRAME) + NC_DrawFrame(hdc, &rect, FALSE); if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION) { RECT r = rect; rect.top += SYSMETRICS_CYSIZE + 1; r.bottom = rect.top - 1; - if (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME) - { - HBRUSH hbrushWindow = CreateSolidBrush(GetSysColor(COLOR_WINDOW)); - HBRUSH hbrushOld = SelectObject( hdc, hbrushWindow ); - PatBlt( hdc, r.left, r.top, 1, r.bottom-r.top+1, PATCOPY ); - PatBlt( hdc, r.right-1, r.top, 1, r.bottom-r.top+1, PATCOPY ); - PatBlt( hdc, r.left, r.top, r.right-r.left, 1, PATCOPY ); - r.left++; - r.right--; - r.top++; - SelectObject( hdc, hbrushOld ); - DeleteObject( hbrushWindow ); - } - NC_DrawCaption( hdc, &r, hwnd, wndPtr->dwStyle ); + NC_DrawCaption( hdc, &r, hwnd, wndPtr->dwStyle, active ); } if (wndPtr->dwStyle & (WS_VSCROLL | WS_HSCROLL)) { + if (wndPtr->dwStyle & WS_VSCROLL) { + int bottom = rect.bottom; + if (wndPtr->dwStyle & WS_HSCROLL) bottom -= SYSMETRICS_CYHSCROLL; + SetRect(&rect2, rect.right - SYSMETRICS_CXVSCROLL, rect.top, + rect.right, bottom); + StdDrawScrollBar(hwnd, hdc, SB_VERT, &rect2, (LPHEADSCROLL)wndPtr->VScroll); + } + if (wndPtr->dwStyle & WS_HSCROLL) { + int right = rect.right; + if (wndPtr->dwStyle & WS_VSCROLL) right -= SYSMETRICS_CYVSCROLL; + SetRect(&rect2, rect.left, rect.bottom - SYSMETRICS_CYHSCROLL, + right, rect.bottom); + StdDrawScrollBar(hwnd, hdc, SB_HORZ, &rect2, (LPHEADSCROLL)wndPtr->HScroll); + } +/* HBRUSH hbrushScroll = CreateSolidBrush( GetSysColor(COLOR_SCROLLBAR) ); HBRUSH hbrushOld = SelectObject( hdc, hbrushScroll ); if (wndPtr->dwStyle & WS_VSCROLL) @@ -590,15 +604,244 @@ LONG NC_HandleNCPaint( HWND hwnd, HRGN hrgn ) rect.right-rect.left, SYSMETRICS_CYHSCROLL, PATCOPY ); SelectObject( hdc, hbrushOld ); DeleteObject( hbrushScroll ); +*/ } ReleaseDC( hwnd, hdc ); if (hbrushBorder) DeleteObject( hbrushBorder ); if (hpenFrame) DeleteObject( hpenFrame ); +} + + +/*********************************************************************** + * NC_HandleNCPaint + * + * Handle a WM_NCPAINT message. Called from DefWindowProc(). + */ +LONG NC_HandleNCPaint( HWND hwnd, HRGN hrgn ) +{ + NC_DoNCPaint( hwnd, hrgn, (hwnd == GetActiveWindow()) ); return 0; } +/*********************************************************************** + * NC_HandleNCActivate + * + * Handle a WM_NCACTIVATE message. Called from DefWindowProc(). + */ +LONG NC_HandleNCActivate( HWND hwnd, WORD wParam ) +{ + NC_DoNCPaint( hwnd, (HRGN)1, wParam ); + return TRUE; +} + + +/*********************************************************************** + * NC_DoSizeMove + * + * Perform SC_MOVE and SC_SIZE commands. + */ +static void NC_DoSizeMove( HWND hwnd, WORD wParam, POINT pt ) +{ + MSG msg; + WORD hittest; + RECT sizingRect; + HDC hdc; + BOOL thickframe; + POINT minTrack, maxTrack, capturePoint = pt; + WND * wndPtr = WIN_FindWndPtr( hwnd ); + + if (IsZoomed(hwnd) || IsIconic(hwnd) || !IsWindowVisible(hwnd)) return; + hittest = wParam & 0x0f; + thickframe = HAS_THICKFRAME( wndPtr->dwStyle ); + + if ((wParam & 0xfff0) == SC_MOVE) + { + if (!(wndPtr->dwStyle & WS_CAPTION)) return; + if (!hittest) + { + /* Move pointer at the center of the caption */ + RECT rect; + POINT point; + NC_GetInsideRect( hwnd, &rect ); + if (wndPtr->dwStyle & WS_SYSMENU) + rect.left += SYSMETRICS_CXSIZE + 1; + if (wndPtr->dwStyle & WS_MINIMIZEBOX) + rect.right -= SYSMETRICS_CXSIZE + 1; + if (wndPtr->dwStyle & WS_MAXIMIZEBOX) + rect.right -= SYSMETRICS_CXSIZE + 1; + point.x = wndPtr->rectWindow.left + (rect.right - rect.left) / 2; + point.y = wndPtr->rectWindow.top + rect.top + SYSMETRICS_CYSIZE/2; + if (wndPtr->dwStyle & WS_CHILD) + ClientToScreen( wndPtr->hwndParent, &point ); + SetCursorPos( point.x, point.y ); + hittest = HTCAPTION; + capturePoint = point; + } + } + else /* SC_SIZE */ + { + if (!thickframe) return; + if (hittest) hittest += HTLEFT-1; + } + + WINPOS_GetMinMaxInfo( hwnd, NULL, NULL, &minTrack, &maxTrack ); + SendMessage( hwnd, WM_ENTERSIZEMOVE, 0, 0 ); + + if (wndPtr->dwStyle & WS_CHILD) hdc = GetDC( wndPtr->hwndParent ); + else + { /* Grab the server only when moving top-level windows */ + hdc = GetDC( 0 ); + XGrabServer( display ); + } + SetCapture( hwnd ); + sizingRect = wndPtr->rectWindow; + NC_DrawMovingFrame( hdc, &sizingRect, thickframe ); + + while(1) + { + int dx = 0, dy = 0; + + MSG_GetHardwareMessage( &msg ); + + /* Exit on button-up, Return, or Esc */ + if ((msg.message == WM_LBUTTONUP) || + ((msg.message == WM_KEYDOWN) && + ((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break; + + if (wndPtr->dwStyle & WS_CHILD) + ScreenToClient( wndPtr->hwndParent, &msg.pt ); + + switch(msg.message) + { + case WM_MOUSEMOVE: + dx = msg.pt.x - capturePoint.x; + dy = msg.pt.y - capturePoint.y; + break; + + case WM_KEYDOWN: + switch(msg.wParam) + { + case VK_UP: msg.pt.y -= 8; break; + case VK_DOWN: msg.pt.y += 8; break; + case VK_LEFT: msg.pt.x -= 8; break; + case VK_RIGHT: msg.pt.x += 8; break; + } + SetCursorPos( msg.pt.x, msg.pt.y ); + break; + } + + if (dx || dy) + { + RECT newRect = sizingRect; + switch(hittest) + { + case HTCAPTION: + OffsetRect( &newRect, dx, dy ); + break; + case HTLEFT: + newRect.left += dx; + break; + case HTRIGHT: + newRect.right += dx; + break; + case HTTOP: + newRect.top += dy; + break; + case HTTOPLEFT: + newRect.left += dx; + newRect.top += dy; + break; + case HTTOPRIGHT: + newRect.right += dx; + newRect.top += dy; + break; + case HTBOTTOM: + newRect.bottom += dy; + break; + case HTBOTTOMLEFT: + newRect.left += dx; + newRect.bottom += dy; + break; + case HTBOTTOMRIGHT: + newRect.right += dx; + newRect.bottom += dy; + break; + } + NC_DrawMovingFrame( hdc, &sizingRect, thickframe ); + NC_DrawMovingFrame( hdc, &newRect, thickframe ); + capturePoint = msg.pt; + sizingRect = newRect; + } + } + + NC_DrawMovingFrame( hdc, &sizingRect, thickframe ); + ReleaseCapture(); + if (wndPtr->dwStyle & WS_CHILD) ReleaseDC( wndPtr->hwndParent, hdc ); + else + { + ReleaseDC( 0, hdc ); + XUngrabServer( display ); + } + SendMessage( hwnd, WM_EXITSIZEMOVE, 0, 0 ); + + /* If Esc key, don't move the window */ + if ((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) return; + + if (hittest != HTCAPTION) + SetWindowPos( hwnd, 0, sizingRect.left, sizingRect.top, + sizingRect.right - sizingRect.left, + sizingRect.bottom - sizingRect.top, + SWP_NOACTIVATE | SWP_NOZORDER ); + else SetWindowPos( hwnd, 0, sizingRect.left, sizingRect.top, 0, 0, + SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER ); +} + + +/*********************************************************************** + * NC_TrackMinMaxBox + * + * Track a mouse button press on the minimize or maximize box. + */ +static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam ) +{ + MSG msg; + HDC hdc = GetWindowDC( hwnd ); + BOOL pressed = TRUE; + + SetCapture( hwnd ); + if (wParam == HTMINBUTTON) NC_DrawMinButton( hwnd, hdc, TRUE ); + else NC_DrawMaxButton( hwnd, hdc, TRUE ); + + do + { + BOOL oldstate = pressed; + MSG_GetHardwareMessage( &msg ); + + pressed = (NC_InternalNCHitTest( hwnd, msg.pt ) == wParam); + if (pressed != oldstate) + { + if (wParam == HTMINBUTTON) NC_DrawMinButton( hwnd, hdc, pressed ); + else NC_DrawMaxButton( hwnd, hdc, pressed ); + } + } while (msg.message != WM_LBUTTONUP); + + if (wParam == HTMINBUTTON) NC_DrawMinButton( hwnd, hdc, FALSE ); + else NC_DrawMaxButton( hwnd, hdc, FALSE ); + + ReleaseCapture(); + ReleaseDC( hwnd, hdc ); + if (!pressed) return; + + if (wParam == HTMINBUTTON) + SendMessage( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, *(LONG*)&msg.pt ); + else + SendMessage( hwnd, WM_SYSCOMMAND, + IsZoomed(hwnd) ? SC_RESTORE : SC_MAXIMIZE, *(LONG*)&msg.pt ); +} + + /*********************************************************************** * NC_HandleNCLButtonDown * @@ -611,39 +854,28 @@ LONG NC_HandleNCLButtonDown( HWND hwnd, WORD wParam, LONG lParam ) switch(wParam) /* Hit test */ { case HTCAPTION: - if (GetCapture() != hwnd) - SendMessage( hwnd, WM_SYSCOMMAND, SC_MOVE, lParam ); + SendMessage( hwnd, WM_SYSCOMMAND, SC_MOVE + HTCAPTION, lParam ); break; case HTSYSMENU: - captureHitTest = wParam; - SetCapture( hwnd ); - NC_DrawSysButton( hwnd, hdc ); + NC_DrawSysButton( hwnd, hdc, TRUE ); + NC_TrackSysMenu(hwnd); break; case HTMENU: break; case HTHSCROLL: - if (GetCapture() != hwnd) - SendMessage( hwnd, WM_SYSCOMMAND, SC_HSCROLL, lParam ); + SendMessage( hwnd, WM_SYSCOMMAND, SC_HSCROLL, lParam ); break; case HTVSCROLL: - if (GetCapture() != hwnd) - SendMessage( hwnd, WM_SYSCOMMAND, SC_VSCROLL, lParam ); + SendMessage( hwnd, WM_SYSCOMMAND, SC_VSCROLL, lParam ); break; case HTMINBUTTON: - captureHitTest = wParam; - SetCapture( hwnd ); - NC_DrawMinButton( hwnd, hdc ); - break; - case HTMAXBUTTON: - captureHitTest = wParam; - SetCapture( hwnd ); - NC_DrawMaxButton( hwnd, hdc ); + NC_TrackMinMaxBox( hwnd, wParam ); break; case HTLEFT: @@ -654,9 +886,7 @@ LONG NC_HandleNCLButtonDown( HWND hwnd, WORD wParam, LONG lParam ) case HTBOTTOM: case HTBOTTOMLEFT: case HTBOTTOMRIGHT: - if (GetCapture() != hwnd) - SendMessage( hwnd, WM_SYSCOMMAND, - SC_SIZE + wParam - HTLEFT + 1, lParam ); + SendMessage( hwnd, WM_SYSCOMMAND, SC_SIZE + wParam - HTLEFT+1, lParam); break; case HTBORDER: @@ -668,79 +898,6 @@ LONG NC_HandleNCLButtonDown( HWND hwnd, WORD wParam, LONG lParam ) } -/*********************************************************************** - * NC_HandleNCLButtonUp - * - * Handle a WM_NCLBUTTONUP message. Called from DefWindowProc(). - */ -LONG NC_HandleNCLButtonUp( HWND hwnd, WORD wParam, LONG lParam ) -{ - HDC hdc; - WORD hittest; - - if (hwnd != GetCapture()) return 0; - - ReleaseCapture(); - captureHitTest = HTCLIENT; - hdc = GetWindowDC( hwnd ); - hittest = NC_InternalNCHitTest( hwnd, MAKEPOINT(lParam) ); - - switch(wParam) /* Hit test */ - { - case HTCAPTION: /* End of window moving */ - NC_DrawMovingFrame( hwnd, &sizingRect ); - SetWindowPos( hwnd, 0, sizingRect.left, sizingRect.top, 0, 0, - SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER ); - break; - - case HTSYSMENU: - NC_DrawSysButton( hwnd, hdc ); - break; - - case HTMENU: - case HTHSCROLL: - case HTVSCROLL: - break; - - case HTMINBUTTON: - NC_DrawMinButton( hwnd, hdc ); - if (hittest == HTMINBUTTON) - SendMessage( hwnd, WM_SYSCOMMAND, SC_MINIMIZE, lParam ); - break; - - case HTMAXBUTTON: - NC_DrawMaxButton( hwnd, hdc ); - if (hittest == HTMAXBUTTON) - { - if (IsZoomed(hwnd)) - SendMessage( hwnd, WM_SYSCOMMAND, SC_RESTORE, lParam ); - else SendMessage( hwnd, WM_SYSCOMMAND, SC_MAXIMIZE, lParam ); - } - break; - - case HTLEFT: - case HTRIGHT: - case HTTOP: - case HTTOPLEFT: - case HTTOPRIGHT: - case HTBOTTOM: - case HTBOTTOMLEFT: - case HTBOTTOMRIGHT: /* End of window resizing */ - NC_DrawMovingFrame( hwnd, &sizingRect ); - SetWindowPos( hwnd, 0, sizingRect.left, sizingRect.top, - sizingRect.right - sizingRect.left, - sizingRect.bottom - sizingRect.top, - SWP_NOACTIVATE | SWP_NOZORDER ); - break; - - case HTBORDER: - break; - } - ReleaseDC( hwnd, hdc ); - return 0; -} - - /*********************************************************************** * NC_HandleNCLButtonDblClk * @@ -762,73 +919,6 @@ LONG NC_HandleNCLButtonDblClk( HWND hwnd, WORD wParam, LONG lParam ) } -/*********************************************************************** - * NC_HandleNCMouseMove - * - * Handle a WM_NCMOUSEMOVE message. Called from DefWindowProc(). - */ -LONG NC_HandleNCMouseMove( HWND hwnd, WORD wParam, POINT pt ) -{ - RECT newRect; - - if (hwnd != GetCapture()) return 0; - newRect = sizingRect; - - switch(wParam) /* Hit test */ - { - case HTCAPTION: - OffsetRect( &newRect, pt.x - capturePoint.x, pt.y - capturePoint.y); - break; - - case HTLEFT: - newRect.left += pt.x - capturePoint.x; - break; - - case HTRIGHT: - newRect.right += pt.x - capturePoint.x; - break; - - case HTTOP: - newRect.top += pt.y - capturePoint.y; - break; - - case HTTOPLEFT: - newRect.left += pt.x - capturePoint.x; - newRect.top += pt.y - capturePoint.y; - break; - - case HTTOPRIGHT: - newRect.right += pt.x - capturePoint.x; - newRect.top += pt.y - capturePoint.y; - break; - - case HTBOTTOM: - newRect.bottom += pt.y - capturePoint.y; - break; - - case HTBOTTOMLEFT: - newRect.left += pt.x - capturePoint.x; - newRect.bottom += pt.y - capturePoint.y; - break; - - case HTBOTTOMRIGHT: - newRect.right += pt.x - capturePoint.x; - newRect.bottom += pt.y - capturePoint.y; - break; - - default: - return 0; /* Nothing to do */ - } - - NC_DrawMovingFrame( hwnd, &sizingRect ); - NC_DrawMovingFrame( hwnd, &newRect ); - capturePoint = pt; - sizingRect = newRect; - - return 0; -} - - /*********************************************************************** * NC_HandleSysCommand * @@ -842,27 +932,13 @@ LONG NC_HandleSysCommand( HWND hwnd, WORD wParam, POINT pt ) printf( "Handling WM_SYSCOMMAND %x %d,%d\n", wParam, pt.x, pt.y ); #endif + if (wndPtr->dwStyle & WS_CHILD) ScreenToClient( wndPtr->hwndParent, &pt ); + switch (wParam & 0xfff0) { case SC_SIZE: - if (!HAS_THICKFRAME(wndPtr->dwStyle)) break; - if (IsZoomed(hwnd) || IsIconic(hwnd)) break; - if (wParam & 0x0f) captureHitTest = (wParam & 0x0f) + HTLEFT - 1; - else captureHitTest = HTBORDER; - capturePoint = pt; - SetCapture( hwnd ); - GetWindowRect( hwnd, &sizingRect ); - NC_DrawMovingFrame( hwnd, &sizingRect ); - break; - case SC_MOVE: - if (!(wndPtr->dwStyle & WS_CAPTION)) break; - if (IsZoomed(hwnd) || IsIconic(hwnd)) break; - captureHitTest = HTCAPTION; - capturePoint = pt; - SetCapture( hwnd ); - GetWindowRect( hwnd, &sizingRect ); - NC_DrawMovingFrame( hwnd, &sizingRect ); + NC_DoSizeMove( hwnd, wParam, pt ); break; case SC_MINIMIZE: @@ -886,6 +962,7 @@ LONG NC_HandleSysCommand( HWND hwnd, WORD wParam, POINT pt ) case SC_VSCROLL: case SC_HSCROLL: + break; case SC_MOUSEMENU: case SC_KEYMENU: case SC_ARRANGE: @@ -956,3 +1033,5 @@ LONG NC_HandleSetCursor( HWND hwnd, WORD wParam, LONG lParam ) SetCursor( LoadCursor( 0, IDC_ARROW ) ); return TRUE; } + + diff --git a/windows/timer.c b/windows/timer.c index da649610fd2..2a40bec2c28 100644 --- a/windows/timer.c +++ b/windows/timer.c @@ -142,7 +142,10 @@ static WORD TIMER_SetTimer( HWND hwnd, WORD id, WORD timeout, pTimer->proc = proc; TIMER_InsertTimer( pTimer ); MSG_IncTimerCount( GetTaskQueue(0) ); - return id; + if (!id) + return TRUE; + else + return id; } diff --git a/windows/win.c b/windows/win.c index 95730dd6601..5cef378027c 100644 --- a/windows/win.c +++ b/windows/win.c @@ -16,11 +16,13 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "user.h" #include "dce.h" #include "sysmetrics.h" +#include "scroll.h" extern Display * display; extern Colormap COLOR_WinColormap; extern void EVENT_RegisterWindow( Window w, HWND hwnd ); /* event.c */ +extern HMENU CopySysMenu(); /* menu.c */ HWND firstWindow = 0; @@ -256,10 +258,10 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, wndPtr->hText = 0; wndPtr->flags = 0; wndPtr->hCursor = 0; - wndPtr->hWndVScroll = 0; - wndPtr->hWndHScroll = 0; + wndPtr->VScroll = NULL; + wndPtr->HScroll = NULL; + wndPtr->hSysMenu = 0; wndPtr->hWndMenuBar = 0; - wndPtr->hWndCaption = 0; if (classPtr->wc.cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->wc.cbWndExtra ); @@ -311,8 +313,8 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, /* Send the WM_CREATE message */ - hcreateStruct = GlobalAlloc( GMEM_MOVEABLE, sizeof(CREATESTRUCT) ); - createStruct = (CREATESTRUCT *) GlobalLock( hcreateStruct ); + hcreateStruct = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(CREATESTRUCT) ); + createStruct = (CREATESTRUCT *) USER_HEAP_ADDR( hcreateStruct ); createStruct->lpCreateParams = data; createStruct->hInstance = instance; createStruct->hMenu = menu; @@ -333,22 +335,20 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, /* Send WM_NCCALCSIZE message */ NCCALCSIZE_PARAMS *params; HANDLE hparams; - hparams = GlobalAlloc( GMEM_MOVEABLE, sizeof(*params) ); + hparams = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(*params) ); if (hparams) { - params = (NCCALCSIZE_PARAMS *) GlobalLock( hparams ); + params = (NCCALCSIZE_PARAMS *) USER_HEAP_ADDR( hparams ); params->rgrc[0] = wndPtr->rectWindow; params->lppos = NULL; SendMessage( hwnd, WM_NCCALCSIZE, FALSE, (LONG)params ); wndPtr->rectClient = params->rgrc[0]; - GlobalUnlock( hparams ); - GlobalFree( hparams ); + USER_HEAP_FREE( hparams ); } wmcreate = SendMessage( hwnd, WM_CREATE, 0, (LONG)createStruct ); } - GlobalUnlock( hcreateStruct ); - GlobalFree( hcreateStruct ); + USER_HEAP_FREE( hcreateStruct ); if (wmcreate == -1) { @@ -364,14 +364,9 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, /* Create scrollbars */ -#if 0 - if (windowName != NULL) SetWindowText(hwnd, windowName); - if ((style & WS_CAPTION) == WS_CAPTION) { - wndPtr->hWndCaption = CreateWindow("CAPTION", "", - WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, - 0, -20, width, 20, hwnd, 1, instance, 0L); + if ((style & WS_SYSMENU) == WS_SYSMENU) { + wndPtr->hSysMenu = CopySysMenu(); } -#endif if (((style & WS_CHILD) != WS_CHILD) && (wndPtr->wIDmenu != 0)) { lpbar = (LPPOPUPMENU) GlobalLock(wndPtr->wIDmenu); if (lpbar != NULL) { @@ -381,25 +376,11 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, 0, 0, width, 20, hwnd, 2, instance, (LPSTR)lpbar); } } - if ((style & WS_VSCROLL) == WS_VSCROLL) - { - wndPtr->hWndVScroll = CreateWindow("SCROLLBAR", "", - WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SBS_VERT, - wndPtr->rectClient.right-wndPtr->rectClient.left, 0, - SYSMETRICS_CXVSCROLL, - wndPtr->rectClient.bottom-wndPtr->rectClient.top, - hwnd, 3, instance, 0L); - } - if ((style & WS_HSCROLL) == WS_HSCROLL) - { - wndPtr->hWndHScroll = CreateWindow("SCROLLBAR", "", - WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SBS_HORZ, - 0, wndPtr->rectClient.bottom-wndPtr->rectClient.top, - wndPtr->rectClient.right-wndPtr->rectClient.left, - SYSMETRICS_CYHSCROLL, - hwnd, 4, instance, 0L); - } - + /* Create scrollbars */ + if ((style & WS_VSCROLL) == WS_VSCROLL || + (style & WS_HSCROLL) == WS_HSCROLL) { + NC_CreateScrollBars(hwnd); + } EVENT_RegisterWindow( wndPtr->window, hwnd ); WIN_SendParentNotify( hwnd, wndPtr, WM_CREATE ); @@ -429,8 +410,8 @@ BOOL DestroyWindow( HWND hwnd ) /* Destroy all children */ - if (wndPtr->hWndVScroll) DestroyWindow(wndPtr->hWndVScroll); - if (wndPtr->hWndHScroll) DestroyWindow(wndPtr->hWndHScroll); + if (wndPtr->VScroll) free(wndPtr->VScroll); + if (wndPtr->HScroll) free(wndPtr->HScroll); while (wndPtr->hwndChild) /* The child removes itself from the list */ DestroyWindow( wndPtr->hwndChild ); @@ -445,6 +426,9 @@ BOOL DestroyWindow( HWND hwnd ) if (wndPtr->flags & WIN_OWN_DC) DCE_FreeDCE( wndPtr->hdce ); classPtr->cWindows--; USER_HEAP_FREE( hwnd ); +/* + printf("End of DestroyWindow // hwnd=%04X !\n", hwnd); +*/ return TRUE; } @@ -493,25 +477,6 @@ void UpdateWindow( HWND hwnd ) } } -/********************************************************************** - * GetMenu (USER.157) - */ -HMENU GetMenu( HWND hwnd ) -{ - WND * wndPtr = WIN_FindWndPtr(hwnd); - if (wndPtr == NULL) - return 0; - return wndPtr->wIDmenu; -} - -/********************************************************************** - * SetMenu (USER.158) - */ -BOOL SetMenu(HWND hwnd, HMENU hmenu) -{ - return FALSE; -} - /********************************************************************** * GetDesktopWindow (USER.286) @@ -842,3 +807,127 @@ HWND GetNextWindow( HWND hwnd, WORD flag ) if ((flag != GW_HWNDNEXT) && (flag != GW_HWNDPREV)) return 0; return GetWindow( hwnd, flag ); } + + + + +/******************************************************************* + * EnumWindows (USER.54) + * + * o gets the desktop window and iterates over all the windows + * which are direct decendents of the desktop * by iterating over + * the desktop's child window and all the child windows next + * pointers + * + * o call wndenumprc for every child window the desktop has + * (parameters to Callback16 passed backwards so they are + * put in in pascal calling order) + * + * o if wndenumprc returns 0 exit + * + * * remove the HAS_DESKTOP_WINDOW ifdef when the GetDesktopWindow() call + * is fixed to actually return the desktop window + * + */ +BOOL EnumWindows(FARPROC wndenumprc, LPARAM lParam) +{ + HWND hwnd = GetDesktopWindow(); + WND *wndPtr; + int result; + +#ifdef DEBUG_ENUM + printf("EnumWindows\n"); +#endif +#ifdef HAS_DESKTOP_WINDOW + if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0; + hwnd = wndPtr->hwndChild; +#else + hwnd = firstWindow; +#endif + + while (hwnd) { + char *ptr; + + if ( !(wndPtr=WIN_FindWndPtr(hwnd)) ) { + return 0; + } +#ifdef DEBUG_ENUM + if (XFetchName(display, wndPtr->window, &ptr) && ptr) + printf("found a window (%s)\n", ptr); + else + printf("found nameless parent window\n"); +#endif + result = CallBack16(wndenumprc, 2, lParam, (int) hwnd); + if ( ! result ) { + return 0; + } + hwnd=wndPtr->hwndNext; + } + return 1; /* for now */ +} + +/******************************************************************* + * WIN_EnumChildWin + * + * o hwnd is the first child to use, loop until all next windows + * are processed + * + * o call wdnenumprc with parameters in inverse order (pascal) + * + * o call ourselves with the next child window + * + */ +static BOOL WIN_EnumChildWin(HWND hwnd, FARPROC wndenumprc, LPARAM lParam) +{ + WND *wndPtr; + int result; + + + while (hwnd) { + char *ptr; + if ( !(wndPtr=WIN_FindWndPtr(hwnd)) ) { + return 0; + } +#ifdef DEBUG_ENUM + if (XFetchName(display, wndPtr->window, &ptr) && ptr) + printf("EnumChild: found a child window (%s)\n", ptr); + else + printf("EnumChild: nameless child\n"); + + if (!(wndPtr->dwStyle & WS_CHILD)) { + printf("this is not a child window! What is it doing here?\n"); + return 0; + } +#endif + if (!CallBack16(wndenumprc, 2, lParam, (int) hwnd)) { + return 0; + } + if (!WIN_EnumChildWin(wndPtr->hwndChild, wndenumprc, lParam)) { + return 0; + } + hwnd=wndPtr->hwndNext; + } + return 1; +} + +/******************************************************************* + * EnumChildWindows (USER.55) + * + * o gets the first child of hwnd + * + * o calls WIN_EnumChildWin to do a recursive decent of child windows + */ +BOOL EnumChildWindows(HWND hwnd, FARPROC wndenumprc, LPARAM lParam) +{ + WND *wndPtr; + +#ifdef DEBUG_ENUM + printf("EnumChildWindows\n"); +#endif + + if (hwnd == 0) return 0; + if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0; + hwnd = wndPtr->hwndChild; + return WIN_EnumChildWin(hwnd, wndenumprc, lParam); +} + diff --git a/windows/winpos.c b/windows/winpos.c index ad231611564..49d091fa6f4 100644 --- a/windows/winpos.c +++ b/windows/winpos.c @@ -6,10 +6,14 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; +#include "sysmetrics.h" +#include "user.h" #include "win.h" extern Display * display; +static HWND hwndActive = 0; /* Currently active window */ + /*********************************************************************** * GetWindowRect (USER.32) @@ -156,6 +160,28 @@ BOOL IsZoomed(HWND hWnd) } +/******************************************************************* + * GetActiveWindow (USER.60) + */ +HWND GetActiveWindow() +{ + return hwndActive; +} + + +/******************************************************************* + * SetActiveWindow (USER.59) + */ +HWND SetActiveWindow( HWND hwnd ) +{ + HWND prev = hwndActive; + WND *wndPtr = WIN_FindWndPtr( hwnd ); + if (!wndPtr || (wndPtr->dwStyle & WS_CHILD)) return 0; + SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE ); + return prev; +} + + /*********************************************************************** * BringWindowToTop (USER.45) */ @@ -204,6 +230,7 @@ BOOL ShowWindow( HWND hwnd, int cmd ) case SW_SHOWMINNOACTIVE: case SW_SHOWMINIMIZED: + case SW_SHOWMAXIMIZED: case SW_MINIMIZE: wndPtr->dwStyle |= WS_MINIMIZE; swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | @@ -211,15 +238,23 @@ BOOL ShowWindow( HWND hwnd, int cmd ) break; case SW_SHOWNA: - case SW_SHOWNOACTIVATE: case SW_MAXIMIZE: - case SW_SHOWMAXIMIZED: case SW_SHOW: + swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE; + break; + case SW_NORMAL: case SW_SHOWNORMAL: + case SW_SHOWNOACTIVATE: + case SW_RESTORE: wndPtr->dwStyle &= ~WS_MINIMIZE; - swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | - SWP_NOACTIVATE | SWP_NOZORDER; + wndPtr->dwStyle &= ~WS_MAXIMIZE; + swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE; + if (cmd == SW_SHOWNOACTIVATE) + { + swpflags |= SWP_NOZORDER; + if (GetActiveWindow()) swpflags |= SWP_NOACTIVATE; + } break; } SendMessage( hwnd, WM_SHOWWINDOW, (cmd != SW_HIDE), 0 ); @@ -311,10 +346,76 @@ BOOL SetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl ) } +/******************************************************************* + * WINPOS_GetMinMaxInfo + * + * Send a WM_GETMINMAXINFO to the window. + */ +void WINPOS_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos, + POINT *minTrack, POINT *maxTrack ) +{ + HANDLE minmaxHandle; + MINMAXINFO MinMax, *pMinMax; + WND *wndPtr = WIN_FindWndPtr( hwnd ); + + MinMax.ptMaxSize.x = SYSMETRICS_CXSCREEN; + MinMax.ptMaxSize.y = SYSMETRICS_CYSCREEN; + MinMax.ptMaxPosition = wndPtr->ptMaxPos; + MinMax.ptMinTrackSize.x = SYSMETRICS_CXMINTRACK; + MinMax.ptMinTrackSize.y = SYSMETRICS_CYMINTRACK; + MinMax.ptMaxTrackSize.x = SYSMETRICS_CXSCREEN; + MinMax.ptMaxTrackSize.y = SYSMETRICS_CYSCREEN; + + minmaxHandle = USER_HEAP_ALLOC( LMEM_MOVEABLE, sizeof(MINMAXINFO) ); + if (minmaxHandle) + { + pMinMax = (MINMAXINFO *) USER_HEAP_ADDR( minmaxHandle ); + memcpy( pMinMax, &MinMax, sizeof(MinMax) ); + SendMessage( hwnd, WM_GETMINMAXINFO, 0, (LONG)pMinMax ); + } + else pMinMax = &MinMax; + + if (maxSize) *maxSize = pMinMax->ptMaxSize; + if (maxPos) *maxPos = pMinMax->ptMaxPosition; + if (minTrack) *minTrack = pMinMax->ptMinTrackSize; + if (maxTrack) *maxTrack = pMinMax->ptMaxTrackSize; + if (minmaxHandle) USER_HEAP_FREE( minmaxHandle ); +} + + +/******************************************************************* + * WINPOS_ChangeActiveWindow + * + * Change the active window and send the corresponding messages. + */ +HWND WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg ) +{ + HWND prevActive = hwndActive; + if (hwnd == hwndActive) return 0; + if (hwndActive) + { + if (!SendMessage( hwndActive, WM_NCACTIVATE, FALSE, 0 )) return 0; + SendMessage( hwndActive, WM_ACTIVATE, WA_INACTIVE, + MAKELONG( IsIconic(hwndActive), hwnd ) ); + /* Send WM_ACTIVATEAPP here */ + } + + hwndActive = hwnd; + if (hwndActive) + { + /* Send WM_ACTIVATEAPP here */ + SendMessage( hwnd, WM_NCACTIVATE, TRUE, 0 ); + SendMessage( hwnd, WM_ACTIVATE, mouseMsg ? WA_CLICKACTIVE : WA_ACTIVE, + MAKELONG( IsIconic(hwnd), prevActive ) ); + } + return prevActive; +} + + /*********************************************************************** * SetWindowPos (USER.232) */ -/* Unimplemented flags: SWP_NOREDRAW, SWP_NOACTIVATE +/* Unimplemented flags: SWP_NOREDRAW */ /* Note: all this code should be in the DeferWindowPos() routines, * and SetWindowPos() should simply call them. This will be implemented @@ -342,8 +443,9 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, short x, short y, /* Send WM_WINDOWPOSCHANGING message */ - if (!(hmem = GlobalAlloc( GMEM_MOVEABLE,sizeof(WINDOWPOS) ))) return FALSE; - winPos = (WINDOWPOS *)GlobalLock( hmem ); + if (!(hmem = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(WINDOWPOS) ))) + return FALSE; + winPos = (WINDOWPOS *)USER_HEAP_ADDR( hmem ); winPos->hwnd = hwnd; winPos->hwndInsertAfter = hwndInsertAfter; winPos->x = x; @@ -398,16 +500,15 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, short x, short y, NCCALCSIZE_PARAMS *params; HANDLE hparams; - if (!(hparams = GlobalAlloc( GMEM_MOVEABLE, sizeof(*params) ))) + if (!(hparams = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(*params) ))) goto Abort; - params = (NCCALCSIZE_PARAMS *) GlobalLock( hparams ); + params = (NCCALCSIZE_PARAMS *) USER_HEAP_ADDR( hparams ); params->rgrc[0] = newWindowRect; params->rgrc[1] = wndPtr->rectWindow; params->rgrc[2] = wndPtr->rectClient; params->lppos = winPos; calcsize_result = SendMessage(hwnd, WM_NCCALCSIZE, TRUE, (LONG)params); - GlobalUnlock( hparams ); - GlobalFree( hparams ); + USER_HEAP_FREE( hparams ); newClientRect = params->rgrc[0]; /* Handle result here */ } @@ -470,6 +571,12 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, short x, short y, XUnmapWindow( display, wndPtr->window ); } + if (!(winPos->flags & SWP_NOACTIVATE)) + { + if (!(wndPtr->dwStyle & WS_CHILD)) + WINPOS_ChangeActiveWindow( hwnd, FALSE ); + } + /* Send WM_NCPAINT message if needed */ if ((winPos->flags & (SWP_FRAMECHANGED | SWP_SHOWWINDOW)) || (!(winPos->flags & SWP_NOSIZE)) || @@ -482,18 +589,11 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, short x, short y, wndPtr->rectWindow = newWindowRect; wndPtr->rectClient = newClientRect; SendMessage( hwnd, WM_WINDOWPOSCHANGED, 0, (LONG)winPos ); - GlobalUnlock( hmem ); - GlobalFree( hmem ); + USER_HEAP_FREE( hmem ); return TRUE; Abort: /* Fatal error encountered */ - if (hmem) - { - GlobalUnlock( hmem ); - GlobalFree( hmem ); - } + if (hmem) USER_HEAP_FREE( hmem ); return FALSE; } - - diff --git a/wine.ini b/wine.ini index a06ea5c372d..d8755c42bf5 100644 --- a/wine.ini +++ b/wine.ini @@ -22,7 +22,7 @@ Lpt1=/dev/lp0 [spy] ;;;;; Uncomment the following line to activate spying to the console ;;;;; -;File=CON +File=CON ;;;;; Uncomment the following line to activate spying to the spy.log ;;;;; ;File=spy.log