diff --git a/ANNOUNCE b/ANNOUNCE index a486e164a66..3b5dff6b08c 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,14 +1,13 @@ -This is release 951124 of Wine the MS Windows emulator. This is still a +This is release 951212 of Wine the MS Windows emulator. This is still a developer's only release. There are many bugs and many unimplemented API features. Most applications still do not work. Patches should be submitted to "wine-new@amscons.com". Please don't forget to include a ChangeLog entry. I'll make a new release every other week. -WHAT'S NEW with Wine-951124: (see ChangeLog for details) - - Drag and drop implemented. - - Unixware is now fully supported. - - Many Win32 improvements. +WHAT'S NEW with Wine-951212: (see ChangeLog for details) + - Many more Winelib and Win32 fixes. + - Window management and MDI improvements. - Lots of bug fixes. See the README file in the distribution for installation instructions. @@ -17,11 +16,10 @@ Because of lags created by using mirror, this message may reach you before the release is available at the ftp sites. The sources will be available from the following locations: - sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-951124.tar.gz - tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-951124.tar.gz - ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-951124.tar.gz - ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-951124.tar.gz - aris.com:/pub/linux/ALPHA/Wine/development/Wine-951124.tar.gz + sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-951212.tar.gz + tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-951212.tar.gz + ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-951212.tar.gz + aris.com:/pub/linux/ALPHA/Wine/development/Wine-951212.tar.gz It should also be available from any site that mirrors tsx-11 or sunsite. diff --git a/ChangeLog b/ChangeLog index 9fcdf038429..efd9fa46c77 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,182 @@ +---------------------------------------------------------------------- +Mon Dec 11 19:08:55 1995 Alexandre Julliard + + * [misc/lstr.c] + Replaced wine_strncpy() by a 32-bit version of lstrcpyn(), since + they do the same job. + + * [tools/build.c] + Fixed __attribute__((stdcall)) to make it compile with gcc + versions under 2.7. Doesn't mean it will run OK though... + +Sat Dec 09 13:22:58 1995 Cameron Heide + + * [include/kernel32.h] [include/winerror.h] + Added file attribute definitions and more error codes. + + * [win32/error.c] + Added some rudimentary errno-to-Win32 error conversion + code. + + * [win32/file.c] + Added to GetFileInformationByHandle, filled in some known + error codes, and switched to dprintf_win32. + + * [win32/time.c] + Added GetLocalTime. + +Fri Dec 8 14:37:39 1995 Jim Peterson + + * [controls/combo.c] + Converted functions of the type LONG _(HWND,WORD,LONG) to the type + LRESULT _(HWND,WPARAM,LPARAM) where needed. + + * [include/libres.h] + Restructured libres prototypes to closer match the windows API. + + * [include/windows.h] + Changed several API prototypes' parameter types from 'short' to INT, + which is #defined as short in the emulator, but is a normal int in + WINELIB32. Also changed SEGPTR from DWORD to void* when WINELIB32. + (This creates a lot of warnings at library-compile time, but less + warnings at app-compile time. I'll remove the warnings soon.) + + * [loader/resource.c] + Fixed parameter mismatch in call to LIBRES_FindResource(). Changed + various implementations of the LIBRES_* API functions. + + * [loader/signal.c] + Deleted local 'i' from win_fault(), since it was unused. + + * [objects/bitblt.c] + Mirrored changes to include/windows.h mentioned above. + + * [toolkit/hello3.c] + Changed LoadMenuIndirect() call to LoadMenu() to test the new + resource registration technique. + + * [toolkit/libres.c] + Removed definition of 'struct resource' and fixed bugs in the resource + implementation. Implemented LIBRES_FindResource. + + * [windows/graphics.c] + Mirrored changes to include/windows.h mentioned above. + +Thu Dec 7 23:15:56 1995 Martin von Loewis + + * [controls/edit.c] + LOCAL_HeapExists: Changed parameter to HANDLE. For WineLib, return true + + * [controls/listbox.c] + CreateListBoxStruct: Initialize HeapSel to 0 for WineLib + + * [include/listbox.h] + change HeapSel from WORD to HANDLE + + * [include/resource.h][rc/winerc.c] + struct ResourceTable: removed + struct resource: moved to header file + autoregister resources if supported by compiler + + * [memory/local.h] + LOCAL_GetHeap: expect HANDLE rather than WORD + + * [toolkit/Makefile.in] + Add ALLCFLAGS to make hello3 + + * [toolkit/heap.c] + LocalFree, HEAP_Free: handle 0 parameter gracefully + +Wed Dec 06 15:34:23 1995 Greg Cooper + + * [misc/winsocket.c] + Fixed the msgsnd and msgrcv errors that winsock programs get. + +Wed Dec 06 12:47:23 MET 1995 Sven Verdoolaege + + * [if1632/kernel.spec] + Fixed _hread and _hwrite return type + + * [if1632/relay32.c] [loader/pe_image.c] + Hacked loading of PE-dll's in + + * [win32/advapi.c] + Added stubs for RegCreateKeyEx, RegSetValueEx, RegQueryValueEx + + * [win32/file.c] + Added stubs for OpenFileMapping, CreateFileMapping, MapViewOfFileEx + + * [win32/process.c] + Added stubs for CreateMutexA, ReleaseMutex, CreateEventA, + WaitForSingleObject, DuplicateHandle, GetCurrentProcess + +Mon Dec 04 13:06:37 1995 Bernd Schmidt + + * [include/wine.h] [misc/lstr.c] + Define wine_strncpy(). This function does not pad the buffer with + zeroes like GNU strncpy(), which might break some Windows programs + that pass bogus size arguments. + + * [loader/module.c]: GetModuleFileName(), + [misc/commdlg.c]: GetFileTitle(), + [misc/keyboard.c], [misc/lstr.c]: lstrcpyn(), + [misc/ole2nls.c], [misc/profile.c], [multimedia/mcistring.c], + [multimedia/mmsystem.c], [objects/font.c]: + Use wine_strncpy() where strings are returned to Windows programs. + + * [objects/metafile.c] + PlayMetafile(): Clear the handle table before using it. + + * [misc/shell.c] [misc/main.c] + Rename SHELL_RegCheckForRoot() to SHELL_Init() and call it from main(). + + * [misc/profile.c] + load(): Need to handle comments. + + * [toolkit/libres.c] + Make it compile. + + * [windows/nonclient.c] + Use MAKE_SEGPTR macro in two places where a user heap block used + to be allocated instead. + +Sat Dec 02 16:43:43 1995 Ramon Garcia + + * [windows/winpos.c] + In function SetWindowPos: do not redraw the parent of + a window if the specified window is placed on the top. + This avoids that ShowWindow(hwnd,1) hides hwnd instead + of showing it. + +Sat Dec 02 11:00:00 1995 Alex Korobka + + * [windows/scroll.c] + Now it can scroll children along with the client region of parent + window. Tried to optimize update region calculation. + + * [windows/mdi.c] + ScrollChildren function, more other features added. Basically + a rewrite. + + * [windows/winpos.c] [windows/focus.c] + Reimplemented window activation and focus handling. + + * [windows/nonclient.c] + Added new flag WIN_NCACTIVATED. + + * [windows/message.c] [loader/task.c] + Small changes (to maintain linked list of message queues). + +Wed Nov 29 15:51:48 1995 Daniel Schepler + + * [include/options.h] [misc/main.c] [windows/defwnd.c] + [windows/event.c] [windows/nonclient.c] [windows/win.c] [Wine.man] + Implemented a -managed option to replace the standard Windows + frame of top-level windows with the window manager's decorations. + If a top-level window makes its own frame, this will still show + up, inside the window manager decorations (I believe ctl3dv2.dll + would do this, although I can't test this). + ---------------------------------------------------------------------- Tue Nov 21 18:49:10 1995 Alexandre Julliard diff --git a/Wine.man b/Wine.man index 789a5035e15..f585a534afb 100644 --- a/Wine.man +++ b/Wine.man @@ -67,6 +67,14 @@ Start as an icon .I -debug Enter the debugger before starting application .TP +.I -language xx +Set the language to +.I xx +(one of En, Es, De, No, Fr, Fi, Da) +.TP +.I -managed +Create each top-level window as a properly managed X window +.TP .I -name name Set the application name .TP diff --git a/controls/combo.c b/controls/combo.c index bed192e3c9c..e82deaa8e1d 100644 --- a/controls/combo.c +++ b/controls/combo.c @@ -82,7 +82,7 @@ void ComboUpdateWindow(HWND hwnd, LPHEADLIST lphl, LPHEADCOMBO lphc, BOOL repain /*********************************************************************** * CBNCCreate */ -static LONG CBNCCreate(HWND hwnd, WORD wParam, LONG lParam) +static LRESULT CBNCCreate(HWND hwnd, WPARAM wParam, LPARAM lParam) { CREATESTRUCT *createStruct; @@ -100,7 +100,7 @@ static LONG CBNCCreate(HWND hwnd, WORD wParam, LONG lParam) /*********************************************************************** * CBCreate */ -static LONG CBCreate(HWND hwnd, WORD wParam, LONG lParam) +static LRESULT CBCreate(HWND hwnd, WPARAM wParam, LPARAM lParam) { LPHEADLIST lphl; LPHEADCOMBO lphc; @@ -178,7 +178,7 @@ static LONG CBCreate(HWND hwnd, WORD wParam, LONG lParam) /*********************************************************************** * CBDestroy */ -static LONG CBDestroy(HWND hwnd, WORD wParam, LONG lParam) +static LRESULT CBDestroy(HWND hwnd, WPARAM wParam, LPARAM lParam) { LPHEADLIST lphl = ComboGetListHeader(hwnd); @@ -191,7 +191,7 @@ static LONG CBDestroy(HWND hwnd, WORD wParam, LONG lParam) /*********************************************************************** * CBPaint */ -static LONG CBPaint(HWND hwnd, WORD wParam, LONG lParam) +static LRESULT CBPaint(HWND hwnd, WPARAM wParam, LPARAM lParam) { LPHEADLIST lphl = ComboGetListHeader(hwnd); LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd); @@ -255,7 +255,7 @@ static LONG CBPaint(HWND hwnd, WORD wParam, LONG lParam) /*********************************************************************** * CBGetDlgCode */ -static LONG CBGetDlgCode(HWND hwnd, WORD wParam, LONG lParam) +static LRESULT CBGetDlgCode(HWND hwnd, WPARAM wParam, LPARAM lParam) { return DLGC_WANTARROWS | DLGC_WANTCHARS; } @@ -263,7 +263,7 @@ static LONG CBGetDlgCode(HWND hwnd, WORD wParam, LONG lParam) /*********************************************************************** * CBLButtonDown */ -static LONG CBLButtonDown(HWND hwnd, WORD wParam, LONG lParam) +static LRESULT CBLButtonDown(HWND hwnd, WPARAM wParam, LPARAM lParam) { LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd); SendMessage(hwnd,CB_SHOWDROPDOWN,!lphc->DropDownVisible,0); @@ -273,7 +273,7 @@ static LONG CBLButtonDown(HWND hwnd, WORD wParam, LONG lParam) /*********************************************************************** * CBKeyDown */ -static LONG CBKeyDown(HWND hwnd, WORD wParam, LONG lParam) +static LRESULT CBKeyDown(HWND hwnd, WPARAM wParam, LPARAM lParam) { LPHEADLIST lphl = ComboGetListHeader(hwnd); WORD newFocused = lphl->ItemFocused; @@ -312,7 +312,7 @@ static LONG CBKeyDown(HWND hwnd, WORD wParam, LONG lParam) /*********************************************************************** * CBChar */ -static LONG CBChar(HWND hwnd, WORD wParam, LONG lParam) +static LRESULT CBChar(HWND hwnd, WPARAM wParam, LPARAM lParam) { LPHEADLIST lphl = ComboGetListHeader(hwnd); WORD newFocused; @@ -337,7 +337,7 @@ static LONG CBChar(HWND hwnd, WORD wParam, LONG lParam) /*********************************************************************** * CBKillFocus */ -static LONG CBKillFocus(HWND hwnd, WORD wParam, LONG lParam) +static LRESULT CBKillFocus(HWND hwnd, WPARAM wParam, LPARAM lParam) { return 0; } @@ -345,7 +345,7 @@ static LONG CBKillFocus(HWND hwnd, WORD wParam, LONG lParam) /*********************************************************************** * CBSetFocus */ -static LONG CBSetFocus(HWND hwnd, WORD wParam, LONG lParam) +static LRESULT CBSetFocus(HWND hwnd, WPARAM wParam, LPARAM lParam) { return 0; } @@ -353,7 +353,7 @@ static LONG CBSetFocus(HWND hwnd, WORD wParam, LONG lParam) /*********************************************************************** * CBResetContent */ -static LONG CBResetContent(HWND hwnd, WORD wParam, LONG lParam) +static LRESULT CBResetContent(HWND hwnd, WPARAM wParam, LPARAM lParam) { LPHEADLIST lphl = ComboGetListHeader(hwnd); LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd); @@ -366,7 +366,7 @@ static LONG CBResetContent(HWND hwnd, WORD wParam, LONG lParam) /*********************************************************************** * CBDir */ -static LONG CBDir(HWND hwnd, WORD wParam, LONG lParam) +static LRESULT CBDir(HWND hwnd, WPARAM wParam, LPARAM lParam) { WORD wRet; LPHEADLIST lphl = ComboGetListHeader(hwnd); @@ -380,7 +380,7 @@ static LONG CBDir(HWND hwnd, WORD wParam, LONG lParam) /*********************************************************************** * CBInsertString */ -static LONG CBInsertString(HWND hwnd, WORD wParam, LONG lParam) +static LRESULT CBInsertString(HWND hwnd, WPARAM wParam, LPARAM lParam) { WORD wRet; LPHEADLIST lphl = ComboGetListHeader(hwnd); @@ -398,7 +398,7 @@ static LONG CBInsertString(HWND hwnd, WORD wParam, LONG lParam) /*********************************************************************** * CBAddString */ -static LONG CBAddString(HWND hwnd, WORD wParam, LONG lParam) +static LRESULT CBAddString(HWND hwnd, WPARAM wParam, LPARAM lParam) { WORD wRet; LPHEADLIST lphl = ComboGetListHeader(hwnd); @@ -416,7 +416,7 @@ static LONG CBAddString(HWND hwnd, WORD wParam, LONG lParam) /*********************************************************************** * CBDeleteString */ -static LONG CBDeleteString(HWND hwnd, WORD wParam, LONG lParam) +static LRESULT CBDeleteString(HWND hwnd, WPARAM wParam, LPARAM lParam) { LPHEADLIST lphl = ComboGetListHeader(hwnd); LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd); @@ -429,7 +429,7 @@ static LONG CBDeleteString(HWND hwnd, WORD wParam, LONG lParam) /*********************************************************************** * CBSelectString */ -static LONG CBSelectString(HWND hwnd, WORD wParam, LONG lParam) +static LRESULT CBSelectString(HWND hwnd, WPARAM wParam, LPARAM lParam) { LPHEADLIST lphl = ComboGetListHeader(hwnd); WORD wRet; @@ -444,7 +444,7 @@ static LONG CBSelectString(HWND hwnd, WORD wParam, LONG lParam) /*********************************************************************** * CBFindString */ -static LONG CBFindString(HWND hwnd, WORD wParam, LONG lParam) +static LRESULT CBFindString(HWND hwnd, WPARAM wParam, LPARAM lParam) { LPHEADLIST lphl = ComboGetListHeader(hwnd); return ListBoxFindString(lphl, wParam, lParam); @@ -453,7 +453,7 @@ static LONG CBFindString(HWND hwnd, WORD wParam, LONG lParam) /*********************************************************************** * CBGetCount */ -static LONG CBGetCount(HWND hwnd, WORD wParam, LONG lParam) +static LRESULT CBGetCount(HWND hwnd, WPARAM wParam, LPARAM lParam) { LPHEADLIST lphl = ComboGetListHeader(hwnd); return lphl->ItemsCount; @@ -462,7 +462,7 @@ static LONG CBGetCount(HWND hwnd, WORD wParam, LONG lParam) /*********************************************************************** * CBSetCurSel */ -static LONG CBSetCurSel(HWND hwnd, WORD wParam, LONG lParam) +static LRESULT CBSetCurSel(HWND hwnd, WPARAM wParam, LPARAM lParam) { LPHEADLIST lphl = ComboGetListHeader(hwnd); WORD wRet; @@ -478,7 +478,7 @@ static LONG CBSetCurSel(HWND hwnd, WORD wParam, LONG lParam) /*********************************************************************** * CBGetCurSel */ -static LONG CBGetCurSel(HWND hwnd, WORD wParam, LONG lParam) +static LRESULT CBGetCurSel(HWND hwnd, WPARAM wParam, LPARAM lParam) { LPHEADLIST lphl = ComboGetListHeader(hwnd); return lphl->ItemFocused; @@ -487,7 +487,7 @@ static LONG CBGetCurSel(HWND hwnd, WORD wParam, LONG lParam) /*********************************************************************** * CBGetItemHeight */ -static LONG CBGetItemHeight(HWND hwnd, WORD wParam, LONG lParam) +static LRESULT CBGetItemHeight(HWND hwnd, WPARAM wParam, LPARAM lParam) { LPHEADLIST lphl = ComboGetListHeader(hwnd); LPLISTSTRUCT lpls = ListBoxGetItem (lphl, wParam); @@ -499,7 +499,7 @@ static LONG CBGetItemHeight(HWND hwnd, WORD wParam, LONG lParam) /*********************************************************************** * CBSetItemHeight */ -static LONG CBSetItemHeight(HWND hwnd, WORD wParam, LONG lParam) +static LRESULT CBSetItemHeight(HWND hwnd, WPARAM wParam, LPARAM lParam) { LPHEADLIST lphl = ComboGetListHeader(hwnd); return ListBoxSetItemHeight(lphl, wParam, lParam); @@ -508,7 +508,7 @@ static LONG CBSetItemHeight(HWND hwnd, WORD wParam, LONG lParam) /*********************************************************************** * CBSetRedraw */ -static LONG CBSetRedraw(HWND hwnd, WORD wParam, LONG lParam) +static LRESULT CBSetRedraw(HWND hwnd, WPARAM wParam, LPARAM lParam) { LPHEADLIST lphl = ComboGetListHeader(hwnd); lphl->bRedrawFlag = wParam; @@ -518,7 +518,7 @@ static LONG CBSetRedraw(HWND hwnd, WORD wParam, LONG lParam) /*********************************************************************** * CBSetFont */ -static LONG CBSetFont(HWND hwnd, WPARAM wParam, LPARAM lParam) +static LRESULT CBSetFont(HWND hwnd, WPARAM wParam, LPARAM lParam) { LPHEADLIST lphl = ComboGetListHeader(hwnd); @@ -533,7 +533,7 @@ static LONG CBSetFont(HWND hwnd, WPARAM wParam, LPARAM lParam) /*********************************************************************** * CBGetLBTextLen */ -static LONG CBGetLBTextLen(HWND hwnd, WORD wParam, LONG lParam) +static LRESULT CBGetLBTextLen(HWND hwnd, WPARAM wParam, LPARAM lParam) { LPHEADLIST lphl = ComboGetListHeader(hwnd); LPLISTSTRUCT lpls = ListBoxGetItem(lphl,wParam); @@ -545,7 +545,7 @@ static LONG CBGetLBTextLen(HWND hwnd, WORD wParam, LONG lParam) /*********************************************************************** * CBGetLBText */ -static LONG CBGetLBText(HWND hwnd, WORD wParam, LONG lParam) +static LRESULT CBGetLBText(HWND hwnd, WPARAM wParam, LPARAM lParam) { LPHEADLIST lphl = ComboGetListHeader(hwnd); return ListBoxGetText(lphl, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam)); @@ -554,7 +554,7 @@ static LONG CBGetLBText(HWND hwnd, WORD wParam, LONG lParam) /*********************************************************************** * CBGetItemData */ -static LONG CBGetItemData(HWND hwnd, WORD wParam, LONG lParam) +static LRESULT CBGetItemData(HWND hwnd, WPARAM wParam, LPARAM lParam) { LPHEADLIST lphl = ComboGetListHeader(hwnd); return ListBoxGetItemData(lphl, wParam); @@ -563,7 +563,7 @@ static LONG CBGetItemData(HWND hwnd, WORD wParam, LONG lParam) /*********************************************************************** * CBSetItemData */ -static LONG CBSetItemData(HWND hwnd, WORD wParam, LONG lParam) +static LRESULT CBSetItemData(HWND hwnd, WPARAM wParam, LPARAM lParam) { LPHEADLIST lphl = ComboGetListHeader(hwnd); return ListBoxSetItemData(lphl, wParam, lParam); @@ -572,7 +572,7 @@ static LONG CBSetItemData(HWND hwnd, WORD wParam, LONG lParam) /*********************************************************************** * CBShowDropDown */ -static LONG CBShowDropDown(HWND hwnd, WORD wParam, LONG lParam) +static LRESULT CBShowDropDown(HWND hwnd, WPARAM wParam, LPARAM lParam) { LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd); RECT rect; @@ -650,7 +650,7 @@ LPHEADLIST CLBoxGetListHeader(HWND hwnd) /*********************************************************************** * CBLCreate */ -static LONG CBLCreate( HWND hwnd, WORD wParam, LONG lParam ) +static LRESULT CBLCreate( HWND hwnd, WPARAM wParam, LPARAM lParam ) { CREATESTRUCT *createStruct = (CREATESTRUCT *)PTR_SEG_TO_LIN(lParam); #ifdef WINELIB32 @@ -664,7 +664,7 @@ static LONG CBLCreate( HWND hwnd, WORD wParam, LONG lParam ) /*********************************************************************** * CBLGetDlgCode */ -static LONG CBLGetDlgCode( HWND hwnd, WORD wParam, LONG lParam ) +static LRESULT CBLGetDlgCode( HWND hwnd, WPARAM wParam, LPARAM lParam ) { return DLGC_WANTARROWS | DLGC_WANTCHARS; } @@ -672,7 +672,7 @@ static LONG CBLGetDlgCode( HWND hwnd, WORD wParam, LONG lParam ) /*********************************************************************** * CBLKeyDown */ -static LONG CBLKeyDown( HWND hwnd, WORD wParam, LONG lParam ) +static LRESULT CBLKeyDown( HWND hwnd, WPARAM wParam, LPARAM lParam ) { LPHEADLIST lphl = CLBoxGetListHeader(hwnd); WORD newFocused = lphl->ItemFocused; @@ -720,7 +720,7 @@ static LONG CBLKeyDown( HWND hwnd, WORD wParam, LONG lParam ) /*********************************************************************** * CBLChar */ -static LONG CBLChar( HWND hwnd, WORD wParam, LONG lParam ) +static LRESULT CBLChar( HWND hwnd, WPARAM wParam, LPARAM lParam ) { return 0; } @@ -728,7 +728,7 @@ static LONG CBLChar( HWND hwnd, WORD wParam, LONG lParam ) /*********************************************************************** * CBLPaint */ -static LONG CBLPaint( HWND hwnd, WORD wParam, LONG lParam ) +static LRESULT CBLPaint( HWND hwnd, WPARAM wParam, LPARAM lParam ) { LPHEADLIST lphl = CLBoxGetListHeader(hwnd); LPLISTSTRUCT lpls; @@ -805,7 +805,7 @@ static LONG CBLPaint( HWND hwnd, WORD wParam, LONG lParam ) /*********************************************************************** * CBLKillFocus */ -static LONG CBLKillFocus( HWND hwnd, WORD wParam, LONG lParam ) +static LRESULT CBLKillFocus( HWND hwnd, WPARAM wParam, LPARAM lParam ) { /* SendMessage(CLBoxGetCombo(hwnd),CB_SHOWDROPDOWN,0,0);*/ return 0; @@ -814,7 +814,7 @@ static LONG CBLKillFocus( HWND hwnd, WORD wParam, LONG lParam ) /*********************************************************************** * CBLActivate */ -static LONG CBLActivate( HWND hwnd, WORD wParam, LONG lParam ) +static LRESULT CBLActivate( HWND hwnd, WPARAM wParam, LPARAM lParam ) { if (wParam == WA_INACTIVE) SendMessage(CLBoxGetCombo(hwnd),CB_SHOWDROPDOWN,0,0); @@ -824,7 +824,7 @@ static LONG CBLActivate( HWND hwnd, WORD wParam, LONG lParam ) /*********************************************************************** * CBLLButtonDown */ -static LONG CBLLButtonDown( HWND hwnd, WORD wParam, LONG lParam ) +static LRESULT CBLLButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam ) { LPHEADLIST lphl = CLBoxGetListHeader(hwnd); int y; @@ -849,7 +849,7 @@ static LONG CBLLButtonDown( HWND hwnd, WORD wParam, LONG lParam ) /*********************************************************************** * CBLLButtonUp */ -static LONG CBLLButtonUp( HWND hwnd, WORD wParam, LONG lParam ) +static LRESULT CBLLButtonUp( HWND hwnd, WPARAM wParam, LPARAM lParam ) { LPHEADLIST lphl = CLBoxGetListHeader(hwnd); @@ -873,7 +873,7 @@ static LONG CBLLButtonUp( HWND hwnd, WORD wParam, LONG lParam ) /*********************************************************************** * CBLMouseMove */ -static LONG CBLMouseMove( HWND hwnd, WORD wParam, LONG lParam ) +static LRESULT CBLMouseMove( HWND hwnd, WPARAM wParam, LPARAM lParam ) { LPHEADLIST lphl = CLBoxGetListHeader(hwnd); int y; @@ -916,7 +916,7 @@ static LONG CBLMouseMove( HWND hwnd, WORD wParam, LONG lParam ) /*********************************************************************** * CBLVScroll */ -static LONG CBLVScroll( HWND hwnd, WORD wParam, LONG lParam ) +static LRESULT CBLVScroll( HWND hwnd, WPARAM wParam, LPARAM lParam ) { LPHEADLIST lphl = CLBoxGetListHeader(hwnd); int y; diff --git a/controls/edit.c b/controls/edit.c index 04383fb1bc7..8663d409bd2 100644 --- a/controls/edit.c +++ b/controls/edit.c @@ -2210,10 +2210,13 @@ static void EDIT_WM_Paint(HWND hwnd) EndPaint(hwnd, &ps); } -static BOOL LOCAL_HeapExists(WORD ds) +static BOOL LOCAL_HeapExists(HANDLE ds) { +/* There is always a local heap in WineLib */ +#ifndef WINELIB INSTANCEDATA *ptr = (INSTANCEDATA *)PTR_SEG_OFF_TO_LIN( ds, 0 ); if (!ptr->heap) return 0; +#endif return 1; } @@ -2249,7 +2252,7 @@ static long EDIT_WM_NCCreate(HWND hwnd, LONG lParam) { DWORD globalSize; globalSize = GlobalSize(ds); - printf("No local heap allocated global size is %d 0x%x\n",globalSize, globalSize); + dprintf_edit(stddeb, "No local heap allocated global size is %ld 0x%lx\n",globalSize, globalSize); /* * I assume the local heap should start at 0 */ diff --git a/controls/listbox.c b/controls/listbox.c index a215ec380e3..0beca3e4fd3 100644 --- a/controls/listbox.c +++ b/controls/listbox.c @@ -111,8 +111,13 @@ void CreateListBoxStruct(HWND hwnd, WORD CtlType, LONG styles, HWND parent) HeapBase = GlobalLock(HeapHandle); HEAP_Init(&lphl->Heap, HeapBase, LIST_HEAP_SIZE); #endif +/* WINELIBS list boxes do not operate on local heaps */ +#ifndef WINELIB lphl->HeapSel = GlobalAlloc(GMEM_FIXED,LIST_HEAP_SIZE); LocalInit( lphl->HeapSel, 0, LIST_HEAP_SIZE-1); +#else + lphl->HeapSel = 0; +#endif } void DestroyListBoxStruct(LPHEADLIST lphl) @@ -896,6 +901,8 @@ static LONG LBLButtonDown(HWND hwnd, WORD wParam, LONG lParam) int y; RECT rectsel; LONG dwStyle = GetWindowLong(lphl->hSelf,GWL_STYLE); + POINT tmpPOINT; + tmpPOINT.x = LOWORD(lParam); tmpPOINT.y = HIWORD(lParam); SetFocus(hwnd); SetCapture(hwnd); @@ -928,11 +935,11 @@ static LONG LBLButtonDown(HWND hwnd, WORD wParam, LONG lParam) if (dwStyle & LBS_NOTIFY) SendMessage(lphl->hParent, WM_LBTRACKPOINT, y, lParam); - +#ifndef WINELIB if (GetWindowLong(lphl->hSelf,GWL_EXSTYLE) & WS_EX_DRAGDETECT) - if( DragDetect(lphl->hSelf,MAKEPOINT(lParam)) ) + if( DragDetect(lphl->hSelf,tmpPOINT) ) SendMessage(lphl->hParent, WM_BEGINDRAG,0,0L); - +#endif return 0; } diff --git a/if1632/advapi32.spec b/if1632/advapi32.spec index 2676a5c9829..b5de7d9fa33 100644 --- a/if1632/advapi32.spec +++ b/if1632/advapi32.spec @@ -127,11 +127,11 @@ base 1 0123 stub QueryServiceStatus 0124 stub ReadEventLogA 0125 stub ReadEventLogW -0126 stub RegCloseKey +0126 stdcall RegCloseKey(long) RegCloseKey 0127 stub RegConnectRegistryA 0128 stub RegConnectRegistryW 0129 stub RegCreateKeyA -0130 stub RegCreateKeyExA +0130 stdcall RegCreateKeyExA(long ptr long ptr long long ptr ptr ptr) RegCreateKeyEx 0131 stub RegCreateKeyExW 0132 stub RegCreateKeyW 0133 stub RegDeleteKeyA @@ -158,7 +158,7 @@ base 1 0154 stub RegQueryMultipleValuesA 0155 stub RegQueryMultipleValuesW 0156 stub RegQueryValueA -0157 stub RegQueryValueExA +0157 stdcall RegQueryValueExA(long ptr long long ptr ptr) RegQueryValueEx 0158 stub RegQueryValueExW 0159 stub RegQueryValueW 0160 stub RegRemapPreDefKey @@ -170,7 +170,7 @@ base 1 0166 stub RegSaveKeyW 0167 stub RegSetKeySecurity 0168 stub RegSetValueA -0169 stub RegSetValueExA +0169 stdcall RegSetValueExA(long ptr long long ptr long) RegSetValueEx 0170 stub RegSetValueExW 0171 stub RegSetValueW 0172 stub RegUnLoadKeyA diff --git a/if1632/kernel.spec b/if1632/kernel.spec index 7f9b7c6eeeb..2899a60e9b2 100644 --- a/if1632/kernel.spec +++ b/if1632/kernel.spec @@ -256,11 +256,11 @@ id 1 346 pascal16 IsBadHugeReadPtr(segptr long) IsBadHugeReadPtr 347 pascal16 IsBadHugeWritePtr(segptr long) IsBadHugeWritePtr 348 pascal hmemcpy(ptr ptr long) hmemcpy -349 pascal16 _hread(word ptr long) _hread -350 pascal16 _hwrite(word ptr long) _hwrite +349 pascal _hread(word ptr long) _hread +350 pascal _hwrite(word ptr long) _hwrite #351 BUNNY_351 352 stub lstrcatn -353 pascal lstrcpyn(segptr segptr word) lstrcpyn +353 pascal lstrcpyn(segptr segptr word) WIN16_lstrcpyn 354 stub GetAppCompatFlags 355 pascal16 GetWinDebugInfo(ptr word) GetWinDebugInfo 356 pascal16 SetWinDebugInfo(ptr) SetWinDebugInfo diff --git a/if1632/kernel32.spec b/if1632/kernel32.spec index e9e9abf387b..bb122a01686 100644 --- a/if1632/kernel32.spec +++ b/if1632/kernel32.spec @@ -44,16 +44,16 @@ base 1 0040 stub CreateDirectoryExA 0041 stub CreateDirectoryExW 0042 stub CreateDirectoryW -0043 stub CreateEventA +0043 stdcall CreateEventA(ptr long long ptr) CreateEventA 0044 stub CreateEventW 0045 stdcall CreateFileA(ptr long long ptr long long long) CreateFileA -0046 stub CreateFileMappingA +0046 stdcall CreateFileMappingA(long ptr long long long ptr) CreateFileMapping 0047 stub CreateFileMappingW 0048 stub CreateFileW 0049 stub CreateIoCompletionPort 0050 stub CreateMailslotA 0051 stub CreateMailslotW -0052 stub CreateMutexA +0052 stdcall CreateMutexA(ptr long ptr) CreateMutexA 0053 stub CreateMutexW 0054 stub CreateNamedPipeA 0055 stub CreateNamedPipeW @@ -79,7 +79,7 @@ base 1 0075 stub DisconnectNamedPipe 0076 stub DosDateTimeToFileTime 0077 stub DuplicateConsoleHandle -0078 stub DuplicateHandle +0078 stdcall DuplicateHandle(long long long ptr long long long) DuplicateHandle 0079 stub EndUpdateResourceA 0080 stub EndUpdateResourceW 0081 stub EnterCriticalSection @@ -199,9 +199,9 @@ base 1 0195 stub GetCurrentConsoleFont 0196 stub GetCurrentDirectoryA 0197 stub GetCurrentDirectoryW -0198 stub GetCurrentProcess +0198 stdcall GetCurrentProcess() GetCurrentProcess 0199 stdcall GetCurrentProcessId() GetCurrentThreadId -0200 stub GetCurrentThread +0200 stdcall GetCurrentThread() GetCurrentThread 0201 stdcall GetCurrentThreadId() GetCurrentThreadId 0202 stub GetDateFormatA 0203 stub GetDateFormatW @@ -229,7 +229,7 @@ base 1 0225 stub GetHandleInformation 0226 stub GetLargestConsoleWindowSize 0227 stdcall GetLastError() GetLastError -0228 stub GetLocalTime +0228 stdcall GetLocalTime(ptr) GetLocalTime 0229 stub GetLocaleInfoA 0230 stub GetLocaleInfoW 0231 stub GetLogicalDriveStringsA @@ -388,7 +388,7 @@ base 1 0383 stub LockFileEx 0384 stub LockResource 0385 stub MapViewOfFile -0386 stub MapViewOfFileEx +0386 stdcall MapViewOfFileEx(long long long long long long) MapViewOfFileEx 0387 stub MoveFileA 0388 stub MoveFileExA 0389 stub MoveFileExW @@ -399,7 +399,7 @@ base 1 0394 stub OpenEventA 0395 stub OpenEventW 0396 stub OpenFile -0397 stub OpenFileMappingA +0397 stdcall OpenFileMappingA(long long ptr) OpenFileMapping 0398 stub OpenFileMappingW 0399 stub OpenMutexA 0400 stub OpenMutexW @@ -437,11 +437,11 @@ base 1 0432 stub RegisterWaitForInputIdle 0433 stub RegisterWowBaseHandlers 0434 stub RegisterWowExec -0435 stub ReleaseMutex +0435 stdcall ReleaseMutex(long) ReleaseMutex 0436 stub ReleaseSemaphore 0437 stub RemoveDirectoryA 0438 stub RemoveDirectoryW -0439 stub ResetEvent +0439 stdcall ResetEvent(long) ResetEvent 0440 stub ResumeThread 0441 stub RtlFillMemory 0442 stub RtlMoveMemory @@ -489,7 +489,7 @@ base 1 0484 stdcall SetEnvironmentVariableA(ptr ptr) SetEnvironmentVariableA 0485 stub SetEnvironmentVariableW 0486 stub SetErrorMode -0487 stub SetEvent +0487 stdcall SetEvent(long) SetEvent 0488 stub SetFileApisToANSI 0489 stub SetFileApisToOEM 0490 stub SetFileAttributesA @@ -563,7 +563,7 @@ base 1 0558 stub WaitForDebugEvent 0559 stub WaitForMultipleObjects 0560 stub WaitForMultipleObjectsEx -0561 stub WaitForSingleObject +0561 stdcall WaitForSingleObject(long long) WaitForSingleObject 0562 stub WaitForSingleObjectEx 0563 stub WaitNamedPipeA 0564 stub WaitNamedPipeW diff --git a/if1632/relay32.c b/if1632/relay32.c index 0d906d4daed..67c64617361 100644 --- a/if1632/relay32.c +++ b/if1632/relay32.c @@ -13,6 +13,7 @@ #include "windows.h" #include "dlls.h" #include "pe_image.h" +#include "peexe.h" #include "relay32.h" #include "stddebug.h" /* #define DEBUG_RELAY */ @@ -48,8 +49,12 @@ int RELAY32_Init(void) WIN32_builtin *RELAY32_GetBuiltinDLL(char *name) { WIN32_builtin *it; + size_t len; + char *cp; + + len = (cp=strchr(name,'.')) ? (cp-name) : strlen(name); for(it=WIN32_builtin_list;it;it=it->next) - if(strcasecmp(name,it->name)==0) + if(strncasecmp(name,it->name,len)==0) return it; return NULL; } @@ -71,10 +76,57 @@ void *RELAY32_GetEntryPoint(char *dll_name, char *item, int hint) { WIN32_builtin *dll; int i; + u_short * ordinal; + u_long * function; + u_char ** name, *ename; + struct PE_Export_Directory * pe_exports; + unsigned int load_addr; + dprintf_module(stddeb, "Looking for %s in %s, hint %x\n", item ? item: "(no name)", dll_name, hint); dll=RELAY32_GetBuiltinDLL(dll_name); - if(!dll)return 0; + if(!dll) { + if(!wine_files || !wine_files->name || + strcasecmp(dll_name, wine_files->name)) { + LoadModule(dll_name, (LPVOID) -1); + if(!wine_files || !wine_files->name || + strcasecmp(dll_name, wine_files->name)) + return 0; + } + load_addr = wine_files->load_addr; + pe_exports = wine_files->pe->pe_export; + ordinal = (u_short *) (((char *) load_addr) + (int) pe_exports->Address_Of_Name_Ordinals); + function = (u_long *) (((char *) load_addr) + (int) pe_exports->AddressOfFunctions); + name = (u_char **) (((char *) load_addr) + (int) pe_exports->AddressOfNames); + /* import by ordinal */ + if(!item){ + return 0; + } + /* hint is correct */ + #if 0 + if(hint && hintsize && + dll->functions[hint].name && + strcmp(item,dll->functions[hint].name)==0) + return dll->functions[hint].definition; + #endif + /* hint is incorrect, search for name */ + for(i=0;iNumber_Of_Functions;i++) + if (name[i] && !strcmp(item,name[i]+load_addr)) + return function[i]+(char *)load_addr; + + /* function at hint has no name (unimplemented) */ + #if 0 + if(hint && hintsize && !dll->functions[hint].name) + { + dll->functions[hint].name=strdup(item); + dprintf_module(stddeb, "Returning unimplemented function %s.%d\n", + dll_name,hint); + return dll->functions[hint].definition; + } + #endif + printf("Not found\n"); + return 0; + } /* import by ordinal */ if(!item){ if(hint && hintsize)return dll->functions[hint].definition; diff --git a/if1632/user.spec b/if1632/user.spec index fae1cc02b81..240daa54bf5 100644 --- a/if1632/user.spec +++ b/if1632/user.spec @@ -409,7 +409,7 @@ id 2 460 pascal16 GetInternalWindowPos(word ptr ptr) GetInternalWindowPos 461 pascal16 SetInternalWindowPos(word word ptr ptr) SetInternalWindowPos 462 pascal16 CalcChildScroll(word word) CalcChildScroll -463 stub ScrollChildren +463 pascal16 ScrollChildren(word word word long) ScrollChildren 464 pascal DragObject(word word word word word word) DragObject 465 pascal16 DragDetect(word long) DragDetect 466 pascal16 DrawFocusRect(word ptr) DrawFocusRect diff --git a/if1632/winprocs.spec b/if1632/winprocs.spec index b770e4dd26b..e564fa53bc1 100644 --- a/if1632/winprocs.spec +++ b/if1632/winprocs.spec @@ -29,6 +29,7 @@ id 24 26 register Win32CallToStart() PE_Win32CallToStart 27 pascal EntryAddrProc(word word) MODULE_GetEntryPoint 28 pascal MyAlloc(word word word) MODULE_AllocateSegment +29 pascal16 ActivateAppProc(word long) ACTIVATEAPP_callback # Interrupt vectors 0-255 are ordinals 100-355 # The 'word' parameter are the flags pushed on the stack by the interrupt diff --git a/include/advapi32.h b/include/advapi32.h new file mode 100644 index 00000000000..634c3f4373c --- /dev/null +++ b/include/advapi32.h @@ -0,0 +1,31 @@ +#ifndef __WINE_ADVAPI32_H +#define __WINE_ADVAPI32_H +#include "shell.h" +#include "kernel32.h" +#define REGSAM long +BOOL WINAPI GetUserNameA (char * lpBuffer, DWORD *nSize); +WINAPI LONG RegCreateKeyEx(HKEY key, + const char *subkey, + long dontuse, + const char *keyclass, + DWORD options, + REGSAM sam, + SECURITY_ATTRIBUTES *atts, + HKEY *res, + DWORD *disp); +WINAPI LONG RegSetValueExA (HKEY key, + const char *name, + DWORD dontuse, + DWORD type, + const void* data, + DWORD len + ); +WINAPI LONG RegQueryValueExA(HKEY key, + const char *subkey, + DWORD dontuse, + DWORD *type, + void *ptr, + DWORD *len); + + +#endif /* __WINE_ADVAPI32_H */ diff --git a/include/dlls.h b/include/dlls.h index 4b4b606feee..89c434ad9a7 100644 --- a/include/dlls.h +++ b/include/dlls.h @@ -12,10 +12,6 @@ #define MAX_NAME_LENGTH 64 -#define DLL 0 -#define EXE 1 - - struct dll_table_s { char * name; /* DLL name */ diff --git a/include/handle32.h b/include/handle32.h index f4e0d9e8590..e6d07a75b46 100644 --- a/include/handle32.h +++ b/include/handle32.h @@ -40,6 +40,13 @@ typedef struct { unsigned long create_flags; /* UNIX creation flags */ } FILE_OBJECT; +typedef struct { + KERNEL_OBJECT common; + FILE_OBJECT *file_obj; + int prot; + unsigned long size; +} FILEMAP_OBJECT; + typedef struct { KERNEL_OBJECT common; } SEMAPHORE_OBJECT; @@ -65,6 +72,7 @@ typedef struct { #define KERNEL_OBJECT_SEMAPHORE (KERNEL_OBJECT_UNUSED + 4) #define KERNEL_OBJECT_EVENT (KERNEL_OBJECT_UNUSED + 5) #define KERNEL_OBJECT_REGKEY (KERNEL_OBJECT_UNUSED + 6) +#define KERNEL_OBJECT_FILEMAP (KERNEL_OBJECT_UNUSED + 7) /* Define the invalid handle value */ diff --git a/include/kernel32.h b/include/kernel32.h index dd38cdc5bd1..501e8d8a55a 100644 --- a/include/kernel32.h +++ b/include/kernel32.h @@ -106,11 +106,14 @@ typedef struct { #define STD_OUTPUT_HANDLE ((DWORD) -11) #define STD_ERROR_HANDLE ((DWORD) -12) -/* The security attributes structure (not filled in yet) +/* The security attributes structure */ typedef struct { - void *junk; + DWORD nLength; + void *lpSecurityDescriptor; + BOOL bInheritHandle; } SECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES; + typedef struct { int dwLowDateTime; @@ -131,4 +134,17 @@ typedef struct int nFileIndexLow; } BY_HANDLE_FILE_INFORMATION ; +/* File attribute flags + */ +#define FILE_ATTRIBUTE_ARCHIVE 0x0020 +#define FILE_ATTRIBUTE_COMPRESSED 0x0800 +#define FILE_ATTRIBUTE_DIRECTORY 0x0010 +#define FILE_ATTRIBUTE_HIDDEN 0x0002 +#define FILE_ATTRIBUTE_NORMAL 0x0080 +#define FILE_ATTRIBUTE_READONLY 0x0001 +#define FILE_ATTRIBUTE_SYSTEM 0x0004 +#define FILE_ATTRIBUTE_TEMPORARY 0x0100 +#define FILE_ATTRIBUTE_ATOMIC_WRITE 0x0200 +#define FILE_ATTRIBUTE_XACTION_WRITE 0x0400 + #endif /* __WINE_KERNEL32_H */ diff --git a/include/libres.h b/include/libres.h index 68ada6f19e4..918f0426d9c 100644 --- a/include/libres.h +++ b/include/libres.h @@ -4,16 +4,21 @@ #ifndef __WINE_LIBRES_H #define __WINE_LIBRES_H -#include "windows.h" - #ifdef WINELIB -HRSRC LIBRES_FindResource( HMODULE hModule, SEGPTR name, SEGPTR type ); -HGLOBAL LIBRES_LoadResource( HMODULE hModule, HRSRC hRsrc ); -LPSTR LIBRES_LockResource( HMODULE hModule, HGLOBAL handle ); -BOOL LIBRES_FreeResource( HMODULE hModule, HGLOBAL handle ); -INT LIBRES_AccessResource( HINSTANCE hModule, HRSRC hRsrc ); -DWORD LIBRES_SizeofResource( HMODULE hModule, HRSRC hRsrc ); -HGLOBAL LIBRES_AllocResource( HMODULE hModule, HRSRC hRsrc, DWORD size ); -#endif + +#include "windows.h" +#include "resource.h" + +void LIBRES_RegisterResources(struct resource** Res); + +INT LIBRES_AccessResource( HINSTANCE hModule, HRSRC hRsrc ); +HGLOBAL LIBRES_AllocResource( HINSTANCE hModule, HRSRC hRsrc, DWORD size ); +HRSRC LIBRES_FindResource( HINSTANCE hModule, LPCSTR name, LPCSTR type ); +BOOL LIBRES_FreeResource( HGLOBAL handle ); +HGLOBAL LIBRES_LoadResource( HINSTANCE hModule, HRSRC hRsrc ); +LPVOID LIBRES_LockResource( HGLOBAL handle ); +DWORD LIBRES_SizeofResource( HINSTANCE hModule, HRSRC hRsrc ); + +#endif /* WINELIB */ #endif diff --git a/include/listbox.h b/include/listbox.h index 1ca08912d2f..e266b8a72d5 100644 --- a/include/listbox.h +++ b/include/listbox.h @@ -34,7 +34,7 @@ typedef struct { LPINT TabStops; HANDLE hDrawItemStruct; BOOL needMeasure; - WORD HeapSel; + HANDLE HeapSel; /* MDESC *Heap; */ } HEADLIST,*LPHEADLIST; diff --git a/include/mdi.h b/include/mdi.h index d2d1434ac03..e7c257325f9 100644 --- a/include/mdi.h +++ b/include/mdi.h @@ -1,6 +1,7 @@ /* MDI.H * * Copyright 1994, Bob Amstadt + * 1995 Alex Korobka * * MDI structure definitions. */ @@ -10,29 +11,32 @@ #include "windows.h" -#define MDI_MAXLISTLENGTH 64 +#define MDI_MAXLISTLENGTH 0x40 + +#define WM_MDICALCCHILDSCROLL 0x10AC /* this is exactly what Windows uses */ + extern LRESULT MDIClientWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); /* mdi.c */ - -typedef struct +typedef struct tagMDIWCL { - HLOCAL next, prev; - HWND hwnd; -} MDICHILDINFO; + HWND hChild; + struct tagMDIWCL *prev; +} MDIWCL; typedef struct { - HMENU hWindowMenu; - HLOCAL infoActiveChildren; WORD nActiveChildren; - WORD idFirstChild; + HWND flagChildMaximized; HWND hwndActiveChild; + HMENU hWindowMenu; + WORD idFirstChild; /* order is 3.1-like up to this point */ + WORD sbStop; + WORD sbRecalc; HWND hwndHitTest; - BOOL flagMenuAltered; - BOOL flagChildMaximized; RECT rectMaximize; RECT rectRestore; } MDICLIENTINFO; + #endif /* MDI_H */ diff --git a/include/message.h b/include/message.h index e604a41ad02..8956faf6a5d 100644 --- a/include/message.h +++ b/include/message.h @@ -70,6 +70,8 @@ extern void MSG_DecTimerCount( HANDLE hQueue ); extern void MSG_Synchronize(); extern BOOL MSG_WaitXEvent( LONG maxWait ); extern BOOL MSG_CreateSysMsgQueue( int size ); +extern BOOL MSG_DeleteMsgQueue( HANDLE hQueue ); +extern HTASK MSG_GetQueueTask( HANDLE hQueue ); extern void hardware_event( WORD message, WORD wParam, LONG lParam, int xPos, int yPos, DWORD time, DWORD extraInfo ); extern BOOL MSG_GetHardwareMessage( LPMSG msg ); diff --git a/include/msdos.h b/include/msdos.h index 5ee696acc7b..5964d82556c 100644 --- a/include/msdos.h +++ b/include/msdos.h @@ -16,7 +16,6 @@ struct dosdirent { char search_attribute; long filesize; long filetime; - int telldirnum; short entnum; /* Directory entry number */ struct dosdirent *next; }; diff --git a/include/options.h b/include/options.h index 834713cb70d..7d3bbf1a9f9 100644 --- a/include/options.h +++ b/include/options.h @@ -34,6 +34,7 @@ struct options int enhanced; /* Start Wine in enhanced mode */ int ipc; /* Use IPC mechanisms */ WINE_LANGUAGE language; /* Current language */ + int managed; /* Managed windows */ }; extern struct options Options; diff --git a/include/pe_image.h b/include/pe_image.h index a65c7566f92..b83e6519bd2 100644 --- a/include/pe_image.h +++ b/include/pe_image.h @@ -25,6 +25,7 @@ struct w_files struct mz_header_s *mz_header; struct pe_data *pe; OFSTRUCT ofs; + unsigned int load_addr; }; @@ -33,6 +34,7 @@ extern int PE_StartProgram(struct w_files *wpnt); extern void PE_InitDLL(struct w_files *wpnt); extern HINSTANCE PE_LoadImage(struct w_files *wpnt); extern void my_wcstombs(char * result, u_short * source, int len); +extern struct w_files *wine_files; typedef struct _WIN32_function{ char *name; diff --git a/include/peexe.h b/include/peexe.h index 6f548114ec6..43aa48a9e57 100644 --- a/include/peexe.h +++ b/include/peexe.h @@ -167,6 +167,7 @@ struct PE_Export_Directory u_long * AddressOfFunctions; u_long * AddressOfNames; u_short * Address_Of_Name_Ordinals; + u_char ModuleName[1]; }; /* diff --git a/include/resource.h b/include/resource.h index d389ce4d714..26d5897d23b 100644 --- a/include/resource.h +++ b/include/resource.h @@ -17,12 +17,19 @@ extern SEGPTR NE_LockResource( HMODULE hModule, HGLOBAL handle ); extern HGLOBAL NE_AllocResource( HMODULE hModule, HRSRC hRsrc, DWORD size ); extern HGLOBAL NE_LoadResource( HMODULE hModule, HRSRC hRsrc ); -struct ResourceTable +struct resource { int id,type; char *name; - unsigned char* value; + unsigned char* bytes; unsigned size; }; +#if defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ >= 7) +#define WINE_CONSTRUCTOR __attribute__((constructor)) +#define HAVE_WINE_CONSTRUCTOR +#else +#define WINE_CONSTRUCTOR +#endif + #endif /* __WINE_RESOURCE_H */ diff --git a/include/shell.h b/include/shell.h index 5a546ec8b14..652f481d737 100644 --- a/include/shell.h +++ b/include/shell.h @@ -3,6 +3,9 @@ */ extern INT ShellAbout(HWND hWnd, LPCSTR szApp, LPCSTR szOtherStuff, HICON hIcon); +extern void SHELL_LoadRegistry(); +extern void SHELL_SaveRegistry(); +extern BOOL SHELL_Init(); #define ERROR_SUCCESS 0L #define ERROR_BADDB 1L @@ -33,15 +36,14 @@ typedef struct tagKEYSTRUCT { struct tagKEYSTRUCT *lpPrevKey; struct tagKEYSTRUCT *lpNextKey; struct tagKEYSTRUCT *lpSubLvl; - } KEYSTRUCT; -typedef KEYSTRUCT *LPKEYSTRUCT; +} KEYSTRUCT, *LPKEYSTRUCT; -typedef struct tagDROPFILESTRUCT { /* structure for dropped files */ +typedef struct { /* structure for dropped files */ WORD wSize; POINT ptMousePos; BOOL fInNonClientArea; /* memory block with filenames follows */ - } DROPFILESTRUCT,FAR *LPDROPFILESTRUCT; +} DROPFILESTRUCT, *LPDROPFILESTRUCT; #define SE_ERR_SHARE 26 #define SE_ERR_ASSOCINCOMPLETE 27 diff --git a/include/win.h b/include/win.h index 49491a2fe3a..f5f7ba15c9b 100644 --- a/include/win.h +++ b/include/win.h @@ -43,7 +43,6 @@ typedef struct tagWND POINT ptMaxPos; /* Maximized window position */ HGLOBAL hmemTaskQ; /* Task queue global memory handle */ HRGN hrgnUpdate; /* Update region */ - HWND hwndPrevActive; /* Previous active top-level window */ HWND hwndLastActive; /* Last active popup hwnd */ WNDPROC lpfnWndProc; /* Window procedure */ DWORD dwStyle; /* Window style (from CreateWindow) */ @@ -68,6 +67,7 @@ typedef struct tagWND #define WIN_INTERNAL_PAINT 0x10 /* Internal WM_PAINT message pending */ #define WIN_NO_REDRAW 0x20 /* WM_SETREDRAW called for this window */ #define WIN_GOT_SIZEMSG 0x40 /* WM_SIZE has been sent to the window */ +#define WIN_NCACTIVATED 0x80 /* last WM_NCACTIVATE was positive */ #define WIN_CLASS_INFO(wndPtr) (CLASS_FindClassPtr((wndPtr)->hClass)->wc) #define WIN_CLASS_STYLE(wndPtr) (WIN_CLASS_INFO(wndPtr).style) diff --git a/include/windows.h b/include/windows.h index 02542d091df..e0430aa25cf 100644 --- a/include/windows.h +++ b/include/windows.h @@ -1428,22 +1428,69 @@ typedef struct tagDRAGINFO { /* Messages */ -enum { WM_NULL, WM_CREATE, WM_DESTROY, WM_MOVE, WM_UNUSED0, WM_SIZE, WM_ACTIVATE, - WM_SETFOCUS, WM_KILLFOCUS, WM_SETVISIBLE, WM_ENABLE, WM_SETREDRAW, - WM_SETTEXT, WM_GETTEXT, WM_GETTEXTLENGTH, WM_PAINT, WM_CLOSE, - WM_QUERYENDSESSION, WM_QUIT, WM_QUERYOPEN, WM_ERASEBKGND, - WM_SYSCOLORCHANGE, WM_ENDSESSION, WM_SYSTEMERROR, - WM_SHOWWINDOW, WM_CTLCOLOR, WM_WININICHANGE, WM_DEVMODECHANGE, - WM_ACTIVATEAPP, WM_FONTCHANGE, WM_TIMECHANGE, WM_CANCELMODE, WM_SETCURSOR, - WM_MOUSEACTIVATE, WM_CHILDACTIVATE, WM_QUEUESYNC, WM_GETMINMAXINFO, - WM_UNUSED3, WM_PAINTICON, WM_ICONERASEBKGND, WM_NEXTDLGCTL, - WM_UNUSED4, WM_SPOOLERSTATUS, WM_DRAWITEM, WM_MEASUREITEM, - WM_DELETEITEM, WM_VKEYTOITEM, - WM_CHARTOITEM, WM_SETFONT, WM_GETFONT }; +#define WM_NULL 0x0000 +#define WM_CREATE 0x0001 +#define WM_DESTROY 0x0002 +#define WM_MOVE 0x0003 +#define WM_SIZEWAIT 0x0004 +#define WM_SIZE 0x0005 +#define WM_ACTIVATE 0x0006 +#define WM_SETFOCUS 0x0007 +#define WM_KILLFOCUS 0x0008 +#define WM_SETVISIBLE 0x0009 +#define WM_ENABLE 0x000a +#define WM_SETREDRAW 0x000b +#define WM_SETTEXT 0x000c +#define WM_GETTEXT 0x000d +#define WM_GETTEXTLENGTH 0x000e +#define WM_PAINT 0x000f +#define WM_CLOSE 0x0010 +#define WM_QUERYENDSESSION 0x0011 +#define WM_QUIT 0x0012 +#define WM_QUERYOPEN 0x0013 +#define WM_ERASEBKGND 0x0014 +#define WM_SYSCOLORCHANGE 0x0015 +#define WM_ENDSESSION 0x0016 +#define WM_SYSTEMERROR 0x0017 +#define WM_SHOWWINDOW 0x0018 +#define WM_CTLCOLOR 0x0019 +#define WM_WININICHANGE 0x001a +#define WM_DEVMODECHANGE 0x001b +#define WM_ACTIVATEAPP 0x001c +#define WM_FONTCHANGE 0x001d +#define WM_TIMECHANGE 0x001e +#define WM_CANCELMODE 0x001f +#define WM_SETCURSOR 0x0020 +#define WM_MOUSEACTIVATE 0x0021 +#define WM_CHILDACTIVATE 0x0022 +#define WM_QUEUESYNC 0x0023 +#define WM_GETMINMAXINFO 0x0024 -#define WM_QUERYDRAGICON 0x0037 +#define WM_PAINTICON 0x0026 +#define WM_ICONERASEBKGND 0x0027 +#define WM_NEXTDLGCTL 0x0028 +#define WM_ALTTABACTIVE 0x0029 +#define WM_SPOOLERSTATUS 0x002a +#define WM_DRAWITEM 0x002b +#define WM_MEASUREITEM 0x002c +#define WM_DELETEITEM 0x002d +#define WM_VKEYTOITEM 0x002e +#define WM_CHARTOITEM 0x002f +#define WM_SETFONT 0x0030 +#define WM_GETFONT 0x0031 +#define WM_SETHOTKEY 0x0032 +#define WM_GETHOTKEY 0x0033 +#define WM_FILESYSCHANGE 0x0034 +#define WM_ISACTIVEICON 0x0035 +#define WM_QUERYPARKICON 0x0036 +#define WM_QUERYDRAGICON 0x0037 +#define WM_QUERYSAVESTATE 0x0038 +#define WM_COMPAREITEM 0x0039 +#define WM_TESTING 0x003a -#define WM_COMPAREITEM 0x0039 +#define WM_OTHERWINDOWCREATED 0x003c +#define WM_OTHERWINDOWDESTROYED 0x003d +#define WM_ACTIVATESHELLWINDOW 0x003e #define WM_COMPACTING 0x0041 @@ -1461,6 +1508,7 @@ enum { WM_NULL, WM_CREATE, WM_DESTROY, WM_MOVE, WM_UNUSED0, WM_SIZE, WM_ACTIVAT #define WM_GETDLGCODE 0x0087 #define WM_SYNCPAINT 0x0088 +#define WM_SYNCTASK 0x0089 /* Non-client mouse messages */ #define WM_NCMOUSEMOVE 0x00a0 @@ -1532,6 +1580,7 @@ enum { WM_NULL, WM_CREATE, WM_DESTROY, WM_MOVE, WM_UNUSED0, WM_SIZE, WM_ACTIVAT #define WM_PARENTNOTIFY 0x0210 #define WM_ENTERMENULOOP 0x0211 #define WM_EXITMENULOOP 0x0212 +#define WM_NEXTMENU 0x0213 #define WM_MDICREATE 0x0220 #define WM_MDIDESTROY 0x0221 @@ -1943,10 +1992,6 @@ enum { WM_NULL, WM_CREATE, WM_DESTROY, WM_MOVE, WM_UNUSED0, WM_SIZE, WM_ACTIVAT #define LBN_SETFOCUS 4 #define LBN_KILLFOCUS 5 -/* Listbox notification messages */ -#define WM_VKEYTOITEM 0x002E -#define WM_CHARTOITEM 0x002F - /* Listbox message return values */ #define LB_OKAY 0 #define LB_ERR (-1) @@ -2095,8 +2140,6 @@ typedef int (CALLBACK *EDITWORDBREAKPROC)(LPSTR lpch, int ichCurrent, #define EN_VSCROLL 0x0602 -#define WM_DRAWITEM 0x002B - typedef struct { UINT CtlType; @@ -2112,8 +2155,6 @@ typedef struct typedef DRAWITEMSTRUCT NEAR* PDRAWITEMSTRUCT; typedef DRAWITEMSTRUCT FAR* LPDRAWITEMSTRUCT; -#define WM_MEASUREITEM 0x002C - typedef struct { UINT CtlType; @@ -2126,8 +2167,6 @@ typedef struct typedef MEASUREITEMSTRUCT NEAR* PMEASUREITEMSTRUCT; typedef MEASUREITEMSTRUCT FAR* LPMEASUREITEMSTRUCT; -#define WM_DELETEITEM 0x002D - typedef struct { UINT CtlType; @@ -2139,8 +2178,6 @@ typedef struct typedef DELETEITEMSTRUCT NEAR* PDELETEITEMSTRUCT; typedef DELETEITEMSTRUCT FAR* LPDELETEITEMSTRUCT; -#define WM_COMPAREITEM 0x0039 - typedef struct { UINT CtlType; @@ -2499,13 +2536,14 @@ LPSTR AnsiUpper(LPSTR); UINT AnsiUpperBuff(LPSTR,UINT); BOOL AnyPopup(void); BOOL AppendMenu(HMENU,UINT,UINT,LPSTR); -BOOL Arc(HDC,int,int,int,int,int,int,int,int); +BOOL Arc(HDC,INT,INT,INT,INT,INT,INT,INT,INT); WORD ArrangeIconicWindows(HWND); HDWP BeginDeferWindowPos(INT); HDC BeginPaint(HWND,LPPAINTSTRUCT); -BOOL BitBlt(HDC,short,short,short,short,HDC,short,short,DWORD); +BOOL BitBlt(HDC,INT,INT,INT,INT,HDC,INT,INT,DWORD); BOOL BringWindowToTop(HWND); int BuildCommDCB(LPSTR,DCB*); +void CalcChildScroll(HWND,WORD); BOOL CallMsgFilter(SEGPTR,short); DWORD CallNextHookEx(HHOOK,short,WPARAM,LPARAM); LONG CallWindowProc(WNDPROC,HWND,UINT,WPARAM,LPARAM); @@ -2517,7 +2555,7 @@ void CheckDlgButton(HWND,WORD,WORD); BOOL CheckMenuItem(HMENU,UINT,UINT); void CheckRadioButton(HWND,WORD,WORD,WORD); HWND ChildWindowFromPoint(HWND,POINT); -BOOL Chord(HDC,int,int,int,int,int,int,int,int); +BOOL Chord(HDC,INT,INT,INT,INT,INT,INT,INT,INT); int ClearCommBreak(int); void ClientToScreen(HWND,LPPOINT); void ClipCursor(LPRECT); @@ -2600,13 +2638,13 @@ int DlgDirListComboBox(HWND,SEGPTR,int,int,WORD); BOOL DlgDirSelect(HWND,LPSTR,int); BOOL DlgDirSelectComboBox(HWND,LPSTR,int); BOOL DragDetect(HWND,POINT); -DWORD DragObject(HWND, HWND, WORD, WORD, WORD, HCURSOR); +DWORD DragObject(HWND, HWND, WORD, HANDLE, WORD, HCURSOR); void DrawFocusRect(HDC,LPRECT); BOOL DrawIcon(HDC,short,short,HICON); void DrawMenuBar(HWND); int DrawText(HDC,LPSTR,int,LPRECT,WORD); DWORD DumpIcon(SEGPTR,WORD*,SEGPTR*,SEGPTR*); -BOOL Ellipse(HDC,int,int,int,int); +BOOL Ellipse(HDC,INT,INT,INT,INT); BOOL EmptyClipboard(void); BOOL EnableHardwareInput(BOOL); BOOL EnableMenuItem(HMENU,UINT,UINT); @@ -2640,7 +2678,7 @@ int FillRect(HDC,LPRECT,HBRUSH); BOOL FillRgn(HDC,HRGN,HBRUSH); void FillWindow(HWND,HWND,HDC,HBRUSH); ATOM FindAtom(SEGPTR); -HANDLE FindResource(HANDLE,SEGPTR,SEGPTR); +HRSRC FindResource(HINSTANCE,SEGPTR,SEGPTR); HWND FindWindow(SEGPTR,LPSTR); BOOL FlashWindow(HWND,BOOL); BOOL FloodFill(HDC,INT,INT,COLORREF); @@ -2650,7 +2688,7 @@ BOOL FrameRgn(HDC,HRGN,HBRUSH,int,int); void FreeLibrary(HANDLE); BOOL FreeModule(HANDLE); void FreeProcInstance(FARPROC); -BOOL FreeResource(HANDLE); +BOOL FreeResource(HGLOBAL); WORD FreeSelector(WORD); UINT GDIRealizePalette(HDC); HPALETTE GDISelectPalette(HDC,HPALETTE); @@ -2897,7 +2935,7 @@ HANDLE LoadLibrary(LPCSTR); HMENU LoadMenu(HANDLE,SEGPTR); HMENU LoadMenuIndirect(LPSTR); HANDLE LoadModule(LPCSTR,LPVOID); -HANDLE LoadResource(HANDLE,HANDLE); +HGLOBAL LoadResource(HINSTANCE,HRSRC); int LoadString(HANDLE,WORD,LPSTR,int); HANDLE LocalAlloc(WORD,WORD); #ifndef WINELIB32 /* Obsolete in Win32 */ @@ -2915,7 +2953,7 @@ UINT LocalShrink(HANDLE,WORD); #endif UINT LocalSize(HLOCAL); BOOL LocalUnlock(HANDLE); -LPSTR LockResource(HANDLE); +LPVOID LockResource(HGLOBAL); HGLOBAL LockSegment(HGLOBAL); HMENU LookupMenuHandle(HMENU,INT); FARPROC MakeProcInstance(FARPROC,HANDLE); @@ -2949,7 +2987,7 @@ void PaintRect(HWND,HWND,HDC,HBRUSH,LPRECT); BOOL PaintRgn(HDC,HRGN); BOOL PatBlt(HDC,short,short,short,short,DWORD); BOOL PeekMessage(LPMSG,HWND,WORD,WORD,WORD); -BOOL Pie(HDC,int,int,int,int,int,int,int,int); +BOOL Pie(HDC,INT,INT,INT,INT,INT,INT,INT,INT); BOOL PlayMetaFile(HDC,HANDLE); void PlayMetaFileRecord(HDC,LPHANDLETABLE,LPMETARECORD,WORD); BOOL PolyPolygon(HDC,LPPOINT,LPINT,WORD); @@ -2975,7 +3013,7 @@ WORD RealizeDefaultPalette(HDC); UINT RealizePalette(HDC); BOOL RectInRegion(HRGN,LPRECT); BOOL RectVisible(HDC,LPRECT); -BOOL Rectangle(HDC,int,int,int,int); +BOOL Rectangle(HDC,INT,INT,INT,INT); BOOL RedrawWindow(HWND,LPRECT,HRGN,UINT); ATOM RegisterClass(LPWNDCLASS); WORD RegisterClipboardFormat(LPCSTR); @@ -2989,7 +3027,7 @@ void ReplyMessage(LONG); BOOL ResizePalette(HPALETTE,UINT); BOOL RestoreDC(HDC,short); int RestoreVisRgn(HDC); -BOOL RoundRect(HDC,short,short,short,short,short,short); +BOOL RoundRect(HDC,INT,INT,INT,INT,INT,INT); int SaveDC(HDC); HRGN SaveVisRgn(HDC); DWORD ScaleViewportExt(HDC,short,short,short,short); @@ -2997,6 +3035,7 @@ BOOL ScaleViewportExtEx(HDC,short,short,short,short,LPSIZE); DWORD ScaleWindowExt(HDC,short,short,short,short); BOOL ScaleWindowExtEx(HDC,short,short,short,short,LPSIZE); void ScreenToClient(HWND,LPPOINT); +void ScrollChildren(HWND,UINT,WPARAM,LPARAM); BOOL ScrollDC(HDC,short,short,LPRECT,LPRECT,HRGN,LPRECT); void ScrollWindow(HWND,short,short,LPRECT,LPRECT); int ScrollWindowEx(HWND,short,short,LPRECT,LPRECT,HRGN,LPRECT,WORD); @@ -3103,7 +3142,7 @@ int ShowCursor(BOOL); void ShowOwnedPopups(HWND,BOOL); void ShowScrollBar(HWND,WORD,BOOL); BOOL ShowWindow(HWND,int); -DWORD SizeofResource(HANDLE,HRSRC); +DWORD SizeofResource(HINSTANCE,HRSRC); int StartSound(void); int StopSound(void); BOOL StretchBlt(HDC,short,short,short,short,HDC,short,short,short,short,DWORD); @@ -3139,6 +3178,7 @@ void ValidateRgn(HWND,HRGN); WORD VkKeyScan(WORD); SEGPTR WIN16_GlobalLock(HGLOBAL); SEGPTR WIN16_LockResource(HANDLE); +SEGPTR WIN16_lstrcpyn(SEGPTR,SEGPTR,WORD); void WaitMessage(void); int WaitSoundState(int); HANDLE WinExec(LPSTR,WORD); @@ -3160,7 +3200,7 @@ SEGPTR lstrcat(SEGPTR,SEGPTR); INT lstrcmp(LPCSTR,LPCSTR); INT lstrcmpi(LPCSTR,LPCSTR); SEGPTR lstrcpy(SEGPTR,SEGPTR); -SEGPTR lstrcpyn(SEGPTR,SEGPTR,WORD); +char * lstrcpyn(char *,char *,int); INT lstrlen(LPCSTR); int wvsprintf(LPSTR,LPSTR,LPSTR); diff --git a/include/winerror.h b/include/winerror.h index ec4ba25c08e..67e8d71ccfc 100644 --- a/include/winerror.h +++ b/include/winerror.h @@ -7,6 +7,21 @@ extern int WIN32_LastError; */ #define ERROR_UNKNOWN 99999 +#define ERROR_FILE_NOT_FOUND 2 +#define ERROR_TOO_MANY_OPEN_FILES 4 +#define ERROR_ACCESS_DENIED 5 #define ERROR_INVALID_HANDLE 6 +#define ERROR_BAD_FORMAT 11 +#define ERROR_OUTOFMEMORY 14 +#define ERROR_FILE_EXISTS 80 #define ERROR_INVALID_PARAMETER 87 +#define ERROR_BROKEN_PIPE 109 +#define ERROR_DISK_FULL 112 #define ERROR_CALL_NOT_IMPLEMENTED 120 +#define ERROR_SEEK_ON_DEVICE 132 +#define ERROR_DIR_NOT_EMPTY 145 +#define ERROR_BUSY 170 +#define ERROR_FILENAME_EXCED_RANGE 206 +#define ERROR_IO_DEVICE 1117 +#define ERROR_POSSIBLE_DEADLOCK 1131 +#define ERROR_BAD_DEVICE 1200 diff --git a/include/winpos.h b/include/winpos.h index 68edbd89362..56cabb7f780 100644 --- a/include/winpos.h +++ b/include/winpos.h @@ -19,8 +19,15 @@ typedef struct WINDOWPOS winPos[1]; } DWP; +typedef struct +{ + HTASK hWindowTask; + HTASK hTaskSendTo; + BOOL wFlag; +} ACTIVATESTRUCT, *LPACTIVATESTRUCT; extern void WINPOS_FindIconPos( HWND hwnd ); +extern BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus); extern HWND WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg ); extern LONG WINPOS_SendNCCalcSize( HWND hwnd, BOOL calcValidRect, RECT *newWindowRect, RECT *oldWindowRect, diff --git a/include/wintypes.h b/include/wintypes.h index eb917b55d8b..0d7689aced4 100644 --- a/include/wintypes.h +++ b/include/wintypes.h @@ -31,6 +31,7 @@ typedef short SHORT; typedef LONG WPARAM; typedef void* HANDLE; typedef void* NPVOID; +typedef void* SEGPTR; #define UIFMT "%u" #define NPFMT "%p" #else @@ -39,13 +40,13 @@ typedef unsigned short UINT; typedef UINT WPARAM; typedef WORD HANDLE; typedef WORD NPVOID; +typedef DWORD SEGPTR; #define UIFMT "%hu" #define NPFMT "%04X" #endif typedef LONG LPARAM; typedef LONG LRESULT; typedef DWORD HHOOK; -typedef DWORD SEGPTR; typedef char *LPSTR; typedef const char *LPCSTR; typedef char *NPSTR; diff --git a/loader/module.c b/loader/module.c index 2a95c4a52bc..1137f3dcd36 100644 --- a/loader/module.c +++ b/loader/module.c @@ -1184,8 +1184,7 @@ int GetModuleFileName( HANDLE hModule, LPSTR lpFileName, short nSize ) hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */ if (!(pModule = (NE_MODULE *)GlobalLock( hModule ))) return 0; name = ((LOADEDFILEINFO*)((char*)pModule + pModule->fileinfo))->filename; - strncpy( lpFileName, name, nSize ); - lpFileName[nSize-1] = '\0'; + lstrcpyn( lpFileName, name, nSize ); dprintf_module( stddeb, "GetModuleFilename: %s\n", lpFileName ); return strlen(lpFileName); } diff --git a/loader/pe_image.c b/loader/pe_image.c index cfd9e08bdda..8a05457afa8 100644 --- a/loader/pe_image.c +++ b/loader/pe_image.c @@ -5,6 +5,8 @@ * based on Eric Youndale's pe-test and: * * ftp.microsoft.com:/pub/developer/MSDN/CD8/PEFILE.ZIP + * make that: + * ftp.microsoft.com:/developr/MSDN/OctCD/PEFILE.ZIP */ #include @@ -35,8 +37,6 @@ struct w_files *wine_files = NULL; -unsigned int load_addr; - void my_wcstombs(char * result, u_short * source, int len) { while(len--) { @@ -76,7 +76,7 @@ char * xmmap(char * vaddr, unsigned int v_size, unsigned int r_size, return vaddr; }; -void dump_exports(struct PE_Export_Directory * pe_exports) +void dump_exports(struct PE_Export_Directory * pe_exports, unsigned int load_addr) { char * Module; int i; @@ -85,7 +85,7 @@ void dump_exports(struct PE_Export_Directory * pe_exports) u_char ** name, *ename; Module = ((char *) load_addr) + pe_exports->Name; - printf("\n*******EXPORT DATA*******\nModule name is %s, %ld functions, %ld names\n", + dprintf_win32(stddeb,"\n*******EXPORT DATA*******\nModule name is %s, %ld functions, %ld names\n", Module, pe_exports->Number_Of_Functions, pe_exports->Number_Of_Names); @@ -94,15 +94,15 @@ void dump_exports(struct PE_Export_Directory * pe_exports) function = (u_long *) (((char *) load_addr) + (int) pe_exports->AddressOfFunctions); name = (u_char **) (((char *) load_addr) + (int) pe_exports->AddressOfNames); - printf("%-32s Ordinal Virt Addr\n", "Function Name"); + dprintf_win32(stddeb,"%-32s Ordinal Virt Addr\n", "Function Name"); for(i=0; i< pe_exports->Number_Of_Functions; i++) { ename = (char *) (((char *) load_addr) + (int) *name++); - printf("%-32s %4d %8.8lx\n", ename, *ordinal++, *function++); + dprintf_win32(stddeb,"%-32s %4d %8.8lx\n", ename, *ordinal++, *function++); } } -void fixup_imports(struct PE_Import_Directory *pe_imports) +void fixup_imports(struct PE_Import_Directory *pe_imports,unsigned int load_addr) { struct PE_Import_Directory * pe_imp; int fixup_failed=0; @@ -115,12 +115,16 @@ void fixup_imports(struct PE_Import_Directory *pe_imports) char * Module; struct pe_import_name * pe_name; unsigned int * import_list, *thunk_list; +#if 0 char * c; +#endif Module = ((char *) load_addr) + pe_imp->ModuleName; dprintf_win32(stddeb, "%s\n", Module); +#if 0 c = strchr(Module, '.'); if (c) *c = 0; +#endif import_list = (unsigned int *) (((unsigned int) load_addr) + pe_imp->Import_List); @@ -185,6 +189,7 @@ static void dump_table(struct w_files *wpnt) HINSTANCE PE_LoadImage(struct w_files *wpnt) { int i, result; + unsigned int load_addr; wpnt->pe = xmalloc(sizeof(struct pe_data)); memset(wpnt->pe,0,sizeof(struct pe_data)); @@ -239,10 +244,11 @@ HINSTANCE PE_LoadImage(struct w_files *wpnt) } } - if(wpnt->pe->pe_import) fixup_imports(wpnt->pe->pe_import); - if(wpnt->pe->pe_export) dump_exports(wpnt->pe->pe_export); + if(wpnt->pe->pe_import) fixup_imports(wpnt->pe->pe_import,load_addr); + if(wpnt->pe->pe_export) dump_exports(wpnt->pe->pe_export,load_addr); wpnt->hinstance = (HINSTANCE)0x8000; + wpnt->load_addr = load_addr; return (wpnt->hinstance); } @@ -264,8 +270,6 @@ HINSTANCE PE_LoadModule(int fd, OFSTRUCT *ofs, LOADPARAMS* params) ALIAS_UseAliases=1; wpnt=xmalloc(sizeof(struct w_files)); - wpnt->next=wine_files; - wine_files=wpnt; wpnt->ofs=*ofs; wpnt->fd=fd; wpnt->type=0; @@ -295,7 +299,7 @@ HINSTANCE PE_LoadModule(int fd, OFSTRUCT *ofs, LOADPARAMS* params) pModule = (NE_MODULE*)GlobalLock(hModule); /* Set all used entries */ - pModule->magic=NE_SIGNATURE; + pModule->magic=PE_SIGNATURE; pModule->count=1; pModule->next=0; pModule->flags=0; @@ -353,6 +357,18 @@ HINSTANCE PE_LoadModule(int fd, OFSTRUCT *ofs, LOADPARAMS* params) hInstance=MODULE_CreateInstance(hModule,NULL /* FIX: NULL? really? */); wpnt->hinstance=hInstance; + if (wpnt->pe->pe_export) { + wpnt->name = xmalloc(strlen(wpnt->pe->pe_export->ModuleName)+1); + strcpy(wpnt->name, wpnt->pe->pe_export->ModuleName); + } else { + wpnt->name = xmalloc(strlen(ofs->szPathName)+1); + strcpy(wpnt->name, ofs->szPathName); + } + + wpnt->next=wine_files; + wine_files=wpnt; + + if (!(wpnt->pe->pe_header->coff.Characteristics & IMAGE_FILE_DLL)) TASK_CreateTask(hModule,hInstance,0, params->hEnvironment,(LPSTR)PTR_SEG_TO_LIN(params->cmdLine), *((WORD*)PTR_SEG_TO_LIN(params->showCmd)+1)); @@ -371,7 +387,7 @@ void PE_Win32CallToStart(struct sigcontext_struct context) InitTask(context); USER_InitApp(wpnt->hModule); __asm__ __volatile__("movw %w0,%%fs"::"r" (fs)); - ((void(*)())(load_addr+wpnt->pe->pe_header->opt_coff.AddressOfEntryPoint))(); + ((void(*)())(wpnt->load_addr+wpnt->pe->pe_header->opt_coff.AddressOfEntryPoint))(); } int PE_UnloadImage(struct w_files *wpnt) diff --git a/loader/resource.c b/loader/resource.c index 42b45cc4347..4ded63636f9 100644 --- a/loader/resource.c +++ b/loader/resource.c @@ -64,7 +64,7 @@ HRSRC FindResource( HMODULE hModule, SEGPTR name, SEGPTR type ) return 0; } #else - return LIBRES_FindResource( hModule, type, name ); + return LIBRES_FindResource( hModule, name, type ); #endif } @@ -103,6 +103,7 @@ HGLOBAL LoadResource( HMODULE hModule, HRSRC hRsrc ) /* 16-bit version */ SEGPTR WIN16_LockResource( HGLOBAL handle ) { +#ifndef WINELIB HMODULE hModule; WORD *pModule; @@ -110,7 +111,6 @@ SEGPTR WIN16_LockResource( HGLOBAL handle ) if (!handle) return (SEGPTR)0; hModule = GetExePtr( handle ); if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0; -#ifndef WINELIB switch(*pModule) { case NE_SIGNATURE: @@ -121,13 +121,14 @@ SEGPTR WIN16_LockResource( HGLOBAL handle ) return 0; } #else - return LIBRES_LockResource( hModule, handle ); + return LIBRES_LockResource( handle ); #endif } /* 32-bit version */ -LPSTR LockResource( HGLOBAL handle ) +LPVOID LockResource( HGLOBAL handle ) { +#ifndef WINELIB HMODULE hModule; WORD *pModule; @@ -135,7 +136,6 @@ LPSTR LockResource( HGLOBAL handle ) if (!handle) return NULL; hModule = GetExePtr( handle ); if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0; -#ifndef WINELIB switch(*pModule) { case NE_SIGNATURE: @@ -146,7 +146,7 @@ LPSTR LockResource( HGLOBAL handle ) return 0; } #else - return LIBRES_LockResource( hModule, handle ); + return LIBRES_LockResource( handle ); #endif } @@ -156,6 +156,7 @@ LPSTR LockResource( HGLOBAL handle ) */ BOOL FreeResource( HGLOBAL handle ) { +#ifndef WINELIB HMODULE hModule; WORD *pModule; @@ -163,7 +164,6 @@ BOOL FreeResource( HGLOBAL handle ) if (!handle) return FALSE; hModule = GetExePtr( handle ); if (!(pModule = (WORD *)GlobalLock( hModule ))) return 0; -#ifndef WINELIB switch(*pModule) { case NE_SIGNATURE: @@ -174,7 +174,7 @@ BOOL FreeResource( HGLOBAL handle ) return FALSE; } #else - return LIBRES_FreeResource( hModule, handle ); + return LIBRES_FreeResource( handle ); #endif } diff --git a/loader/signal.c b/loader/signal.c index 6150f72fb18..1968046833d 100644 --- a/loader/signal.c +++ b/loader/signal.c @@ -56,8 +56,6 @@ static void win_fault(int signal, void *siginfo, ucontext_t *context) static void win_fault(int signal, int code, struct sigcontext *context) { #endif - int i; - if (signal != SIGTRAP) { if (CS_reg(context) == WINE_CODE_SELECTOR) diff --git a/loader/task.c b/loader/task.c index bf383cd6073..345b9f796ba 100644 --- a/loader/task.c +++ b/loader/task.c @@ -14,6 +14,7 @@ #include "debugger.h" #include "global.h" #include "instance.h" +#include "message.h" #include "miscemu.h" #include "module.h" #include "neexe.h" @@ -31,6 +32,7 @@ /* Must not be greater than 64k, or MAKE_SEGPTR won't work */ #define STACK32_SIZE 0x10000 +/* ------ Internal variables ------ */ static HTASK hFirstTask = 0; static HTASK hCurrentTask = 0; @@ -39,6 +41,8 @@ static HTASK hLockedTask = 0; static WORD nTaskCount = 0; static HANDLE hDOSEnvironment = 0; +/* ------ Internal declarations ------ */ + /* TASK_Reschedule() 16-bit entry point */ static FARPROC TASK_RescheduleProc; @@ -48,7 +52,6 @@ static FARPROC TASK_RescheduleProc; #define TASK_SCHEDULE() CallTo16_word_(TASK_RescheduleProc,0) #endif - static HANDLE TASK_CreateDOSEnvironment(void); /*********************************************************************** @@ -565,6 +568,10 @@ static void TASK_DeleteTask( HTASK hTask ) GlobalFreeAll( pTask->hPDB ); + /* Free message queue */ + + MSG_DeleteMsgQueue( pTask->hQueue ); + /* Free the selector aliases */ GLOBAL_FreeBlock( pTask->hCSAlias ); @@ -604,8 +611,12 @@ void TASK_KillCurrentTask( int exitCode ) hTaskToKill = hCurrentTask; hLockedTask = 0; + Yield(); - /* We never return from Yield() */ + /* We should never return from this Yield() */ + + fprintf(stderr,"It's alive! Alive!!!\n"); + exit(1); } diff --git a/misc/Makefile.in b/misc/Makefile.in index 26ac02d4485..f4c201ee481 100644 --- a/misc/Makefile.in +++ b/misc/Makefile.in @@ -14,12 +14,12 @@ C_SRCS = \ keyboard.c \ lstr.c \ main.c \ + network.c \ ole2.c \ ole2disp.c \ ole2nls.c \ olecli.c \ olesvr.c \ - network.c \ profile.c \ rect.c \ shell.c \ diff --git a/misc/commdlg.c b/misc/commdlg.c index 73df1d10f18..d6c881524af 100644 --- a/misc/commdlg.c +++ b/misc/commdlg.c @@ -858,29 +858,30 @@ DWORD CommDlgExtendError(void) */ int GetFileTitle(LPCSTR lpFile, LPSTR lpTitle, UINT cbBuf) { - int i, len; - printf("GetFileTitle(%p %p %d); \n", lpFile, lpTitle, cbBuf); - if (lpFile == NULL || lpTitle == NULL) - return -1; - len = strlen(lpFile); - if (len == 0) - return -1; - if (strpbrk(lpFile, "*[]")) - return -1; - len--; - if (lpFile[len] == '/' || lpFile[len] == '\\' || lpFile[len] == ':') - return -1; - for (i = len; i >= 0; i--) - if (lpFile[i] == '/' || lpFile[i] == '\\' || lpFile[i] == ':') - { + int i, len; + printf("GetFileTitle(%p %p %d); \n", lpFile, lpTitle, cbBuf); + if (lpFile == NULL || lpTitle == NULL) + return -1; + len = strlen(lpFile); + if (len == 0) + return -1; + if (strpbrk(lpFile, "*[]")) + return -1; + len--; + if (lpFile[len] == '/' || lpFile[len] == '\\' || lpFile[len] == ':') + return -1; + for (i = len; i >= 0; i--) + if (lpFile[i] == '/' || lpFile[i] == '\\' || lpFile[i] == ':') + { i++; break; - } - printf("\n---> '%s' ", &lpFile[i]); - len = MIN(cbBuf, strlen(&lpFile[i]) + 1); - strncpy(lpTitle, &lpFile[i], len + 1); - if (len != cbBuf) - return len; - else + } + printf("\n---> '%s' ", &lpFile[i]); + + len = strlen(lpFile+i)+1; + if (cbBuf < len); + return len; + + strncpy(lpTitle, &lpFile[i], len); return 0; } diff --git a/misc/dos_fs.c b/misc/dos_fs.c index 28cdf303b58..0d88d8fea4d 100644 --- a/misc/dos_fs.c +++ b/misc/dos_fs.c @@ -885,12 +885,6 @@ struct dosdirent *DOS_opendir(char *dosdirname) strcpy(dp->unixpath, dirname); dp->entnum = 0; - if ((dp->telldirnum=telldir(ds)) == -1) - { - dp->inuse = 0; - closedir(ds); - return NULL; - } if (closedir(ds) == -1) { dp->inuse = 0; @@ -906,11 +900,16 @@ struct dosdirent *DOS_readdir(struct dosdirent *de) struct dirent *d; struct stat st; DIR *ds; + int i; if (!de->inuse) return NULL; if (!(ds=opendir(de->unixpath))) return NULL; - seekdir(ds,de->telldirnum); /* returns no error value. strange */ + /* skip all already read directory entries. + * the dir has hopefully not been modified in the meantime + */ + for (i=de->entnum;i--;) + readdir(ds); if (de->search_attribute & FA_LABEL) { int drive; @@ -927,13 +926,11 @@ struct dosdirent *DOS_readdir(struct dosdirent *de) } do { + de->entnum++; /* Increment the directory entry number */ if ((d = readdir(ds)) == NULL) { - de->telldirnum=telldir(ds); closedir(ds); return NULL; } - - de->entnum++; /* Increment the directory entry number */ strcpy(de->filename, d->d_name); if (d->d_reclen > 12) de->filename[12] = '\0'; @@ -954,7 +951,6 @@ struct dosdirent *DOS_readdir(struct dosdirent *de) de->filesize = st.st_size; de->filetime = st.st_mtime; - de->telldirnum = telldir(ds); closedir(ds); return de; } diff --git a/misc/keyboard.c b/misc/keyboard.c index ce2c0eca913..8058a7c068f 100644 --- a/misc/keyboard.c +++ b/misc/keyboard.c @@ -124,7 +124,7 @@ int GetKeyNameText(LONG lParam, LPSTR lpBuffer, int nSize) for (i = 0 ; i != KeyTableSize ; i++) if (KeyTable[i].scancode == lParam) { - strncpy(lpBuffer, KeyTable[i].name, nSize); + lstrcpyn(lpBuffer, KeyTable[i].name, nSize); return strlen(lpBuffer); } diff --git a/misc/lstr.c b/misc/lstr.c index b79c3b381de..5d03363441f 100644 --- a/misc/lstr.c +++ b/misc/lstr.c @@ -54,7 +54,6 @@ static const BYTE Ansi2Oem[256] = "\205\240\203\141\204\206\221\207\212\202\210\211\215\241\214\213" "\144\244\225\242\223\157\224\366\157\227\243\226\201\171\137\230"; - /* Funny to divide them between user and kernel. */ /* KERNEL.89 */ @@ -87,10 +86,20 @@ SEGPTR lstrcpy( SEGPTR target, SEGPTR source ) return target; } -/* KERNEL.353 */ -SEGPTR lstrcpyn( SEGPTR target, SEGPTR source, WORD n ) +/* KERNEL.353 32-bit version*/ +char *lstrcpyn(char *dst, char *src, int n) { - strncpy((char *)PTR_SEG_TO_LIN(target), (char *)PTR_SEG_TO_LIN(source), n); + char *tmp = dst; + while(n-- > 1 && *src) + *dst++ = *src++; + *dst = 0; + return tmp; +} + +/* KERNEL.353 16-bit version*/ +SEGPTR WIN16_lstrcpyn( SEGPTR target, SEGPTR source, WORD n ) +{ + lstrcpyn((char *)PTR_SEG_TO_LIN(target), (char *)PTR_SEG_TO_LIN(source),n); return target; } diff --git a/misc/main.c b/misc/main.c index 8f2a4268033..9226c084d80 100644 --- a/misc/main.c +++ b/misc/main.c @@ -23,6 +23,7 @@ #include "winsock.h" #include "options.h" #include "desktop.h" +#include "shell.h" #include "dlls.h" #define DEBUG_DEFINE_VARIABLES #include "stddebug.h" @@ -89,11 +90,11 @@ struct options Options = FALSE, /* Enhanced mode */ FALSE, /* IPC enabled */ #ifdef DEFAULT_LANG - DEFAULT_LANG /* Default language */ + DEFAULT_LANG, /* Default language */ #else - LANG_En + LANG_En, #endif - + FALSE /* Managed windows */ }; @@ -114,7 +115,8 @@ static XrmOptionDescRec optionsTable[] = { "-debugmsg", ".debugmsg", XrmoptionSepArg, (caddr_t)NULL }, { "-dll", ".dll", XrmoptionSepArg, (caddr_t)NULL }, { "-allowreadonly", ".allowreadonly", XrmoptionNoArg, (caddr_t)"on" }, - { "-enhanced", ".enhanced", XrmoptionNoArg, (caddr_t)"off"} + { "-enhanced", ".enhanced", XrmoptionNoArg, (caddr_t)"off"}, + { "-managed", ".managed", XrmoptionNoArg, (caddr_t)"off"} }; #define NB_OPTIONS (sizeof(optionsTable) / sizeof(optionsTable[0])) @@ -130,6 +132,7 @@ static XrmOptionDescRec optionsTable[] = " -ipc Enable IPC facilities\n" \ " -debug Enter debugger before starting application\n" \ " -language xx Set the language (one of En,Es,De,No,Fr,Fi,Da)\n" \ + " -managed Allow the window manager to manage created windows\n" \ " -name name Set the application name\n" \ " -privatemap Use a private color map\n" \ " -fixedmap Use a \"standard\" color map\n" \ @@ -373,6 +376,8 @@ static void MAIN_ParseOptions( int *argc, char *argv[] ) Options.desktopGeometry = value.addr; if (MAIN_GetResource( db, ".language", &value)) MAIN_ParseLanguageOption( (char *)value.addr ); + if (MAIN_GetResource( db, ".managed", &value)) + Options.managed = TRUE; #ifdef DEBUG_RUNTIME if (MAIN_GetResource( db, ".debugoptions", &value)) ParseDebugOptions((char*)value.addr); @@ -530,7 +535,6 @@ static void malloc_error() static void called_at_exit(void) { extern void sync_profiles(void); - extern void SHELL_SaveRegistry(void); sync_profiles(); MAIN_RestoreSetup(); @@ -548,7 +552,6 @@ int main( int argc, char *argv[] ) int *depth_list; extern int _WinMain(int argc, char **argv); - extern void SHELL_LoadRegistry(void); setbuf(stdout,NULL); setbuf(stderr,NULL); @@ -575,6 +578,7 @@ int main( int argc, char *argv[] ) } #endif + SHELL_Init(); SHELL_LoadRegistry(); screen = DefaultScreenOfDisplay( display ); @@ -652,66 +656,67 @@ LONG GetWinFlags(void) */ int SetEnvironment(LPSTR lpPortName, LPSTR lpEnviron, WORD nCount) { - LPENVENTRY lpNewEnv; - LPENVENTRY lpEnv = lpEnvList; - dprintf_env(stddeb, "SetEnvironnement('%s', '%s', %d) !\n", - lpPortName, lpEnviron, nCount); - if (lpPortName == NULL) return -1; - while (lpEnv != NULL) { - if (lpEnv->Name != NULL && strcmp(lpEnv->Name, lpPortName) == 0) { - if (nCount == 0 || lpEnviron == NULL) { - if (lpEnv->Prev != NULL) lpEnv->Prev->Next = lpEnv->Next; - if (lpEnv->Next != NULL) lpEnv->Next->Prev = lpEnv->Prev; - free(lpEnv->Value); - free(lpEnv->Name); - free(lpEnv); - dprintf_env(stddeb, "SetEnvironnement() // entry deleted !\n"); - return -1; - } - free(lpEnv->Value); - lpEnv->Value = malloc(nCount); - if (lpEnv->Value == NULL) { - dprintf_env(stddeb, "SetEnvironment() // Error allocating entry value !\n"); - return 0; - } - memcpy(lpEnv->Value, lpEnviron, nCount); - lpEnv->wSize = nCount; - dprintf_env(stddeb, "SetEnvironnement() // entry modified !\n"); - return nCount; - } - if (lpEnv->Next == NULL) break; - lpEnv = lpEnv->Next; - } - if (nCount == 0 || lpEnviron == NULL) return -1; - dprintf_env(stddeb, "SetEnvironnement() // new entry !\n"); - lpNewEnv = malloc(sizeof(ENVENTRY)); - if (lpNewEnv == NULL) { - dprintf_env(stddeb, "SetEnvironment() // Error allocating new entry !\n"); - return 0; - } - if (lpEnvList == NULL) { - lpEnvList = lpNewEnv; - lpNewEnv->Prev = NULL; - } - else { - lpEnv->Next = lpNewEnv; - lpNewEnv->Prev = lpEnv; - } - lpNewEnv->Next = NULL; - lpNewEnv->Name = malloc(strlen(lpPortName) + 1); - if (lpNewEnv->Name == NULL) { - dprintf_env(stddeb, "SetEnvironment() // Error allocating entry name !\n"); - return 0; - } - strcpy(lpNewEnv->Name, lpPortName); - lpNewEnv->Value = malloc(nCount); - if (lpNewEnv->Value == NULL) { + LPENVENTRY lpNewEnv; + LPENVENTRY lpEnv = lpEnvList; + dprintf_env(stddeb, "SetEnvironment('%s', '%s', %d) !\n", + lpPortName, lpEnviron, nCount); + if (lpPortName == NULL) return -1; + while (lpEnv != NULL) { + if (lpEnv->Name != NULL && strcmp(lpEnv->Name, lpPortName) == 0) { + if (nCount == 0 || lpEnviron == NULL) { + if (lpEnv->Prev != NULL) lpEnv->Prev->Next = lpEnv->Next; + if (lpEnv->Next != NULL) lpEnv->Next->Prev = lpEnv->Prev; + free(lpEnv->Value); + free(lpEnv->Name); + free(lpEnv); + dprintf_env(stddeb, "SetEnvironment() // entry deleted !\n"); + return -1; + } + free(lpEnv->Value); + lpEnv->Value = malloc(nCount); + if (lpEnv->Value == NULL) { dprintf_env(stddeb, "SetEnvironment() // Error allocating entry value !\n"); return 0; - } - memcpy(lpNewEnv->Value, lpEnviron, nCount); - lpNewEnv->wSize = nCount; - return nCount; + } + memcpy(lpEnv->Value, lpEnviron, nCount); + lpEnv->wSize = nCount; + dprintf_env(stddeb, "SetEnvironment() // entry modified !\n"); + return nCount; + } + if (lpEnv->Next == NULL) break; + lpEnv = lpEnv->Next; + } + if (nCount == 0 || lpEnviron == NULL) return -1; + dprintf_env(stddeb, "SetEnvironment() // new entry !\n"); + lpNewEnv = malloc(sizeof(ENVENTRY)); + if (lpNewEnv == NULL) { + dprintf_env(stddeb, "SetEnvironment() // Error allocating new entry !\n"); + return 0; + } + if (lpEnvList == NULL) { + lpEnvList = lpNewEnv; + lpNewEnv->Prev = NULL; + } + else + { + lpEnv->Next = lpNewEnv; + lpNewEnv->Prev = lpEnv; + } + lpNewEnv->Next = NULL; + lpNewEnv->Name = malloc(strlen(lpPortName) + 1); + if (lpNewEnv->Name == NULL) { + dprintf_env(stddeb, "SetEnvironment() // Error allocating entry name !\n"); + return 0; + } + strcpy(lpNewEnv->Name, lpPortName); + lpNewEnv->Value = malloc(nCount); + if (lpNewEnv->Value == NULL) { + dprintf_env(stddeb, "SetEnvironment() // Error allocating entry value !\n"); + return 0; + } + memcpy(lpNewEnv->Value, lpEnviron, nCount); + lpNewEnv->wSize = nCount; + return nCount; } /*********************************************************************** @@ -730,21 +735,21 @@ BOOL SetEnvironmentVariableA(LPSTR lpName, LPSTR lpValue) */ int GetEnvironment(LPSTR lpPortName, LPSTR lpEnviron, WORD nMaxSiz) { - WORD nCount; - LPENVENTRY lpEnv = lpEnvList; - dprintf_env(stddeb, "GetEnvironnement('%s', '%s', %d) !\n", - lpPortName, lpEnviron, nMaxSiz); - while (lpEnv != NULL) { - if (lpEnv->Name != NULL && strcmp(lpEnv->Name, lpPortName) == 0) { - nCount = MIN(nMaxSiz, lpEnv->wSize); - memcpy(lpEnviron, lpEnv->Value, nCount); - dprintf_env(stddeb, "GetEnvironnement() // found '%s' !\n", lpEnviron); - return nCount; - } - lpEnv = lpEnv->Next; - } - dprintf_env(stddeb, "GetEnvironnement() // not found !\n"); - return 0; + WORD nCount; + LPENVENTRY lpEnv = lpEnvList; + dprintf_env(stddeb, "GetEnvironment('%s', '%s', %d) !\n", + lpPortName, lpEnviron, nMaxSiz); + while (lpEnv != NULL) { + if (lpEnv->Name != NULL && strcmp(lpEnv->Name, lpPortName) == 0) { + nCount = MIN(nMaxSiz, lpEnv->wSize); + memcpy(lpEnviron, lpEnv->Value, nCount); + dprintf_env(stddeb, "GetEnvironment() // found '%s' !\n", lpEnviron); + return nCount; + } + lpEnv = lpEnv->Next; + } + dprintf_env(stddeb, "GetEnvironment() // not found !\n"); + return 0; } /*********************************************************************** diff --git a/misc/ole2nls.c b/misc/ole2nls.c index f0dc52fe093..0a20cf99b75 100644 --- a/misc/ole2nls.c +++ b/misc/ole2nls.c @@ -432,7 +432,7 @@ LOCVAL(LOCALE_SABBREVMONTHNAME13,"") } if(retLen>len)retLen=len; - strncpy(buf,retString,len); + lstrcpyn(buf,retString,len); return retLen; } diff --git a/misc/profile.c b/misc/profile.c index 080c3dcd43a..043eb28ebcd 100644 --- a/misc/profile.c +++ b/misc/profile.c @@ -14,9 +14,7 @@ * has a NULL KeyValue returning a list of KeyNames, and a NULL * AppName undefined. I changed GetSetProfile to match. This makes * PROGMAN.EXE do the right thing. - * -static char Copyright [] = "Copyright (C) 1993 Miguel de Icaza"; -*/ + */ #include #include #include @@ -25,15 +23,12 @@ static char Copyright [] = "Copyright (C) 1993 Miguel de Icaza"; #include "wine.h" #include "windows.h" #include "dos_fs.h" -#include "module.h" #include "toolhelp.h" #include "stddebug.h" -/* #define DEBUG_PROFILE */ #include "debug.h" #include "xmalloc.h" #define STRSIZE 255 -#define overflow (next == &CharBuffer [STRSIZE-1]) typedef struct TKeys { char *KeyName; @@ -143,7 +138,12 @@ static TSecHeader *load (char *filename, char **pfullname) if (isspace(c)) continue; - + if (c == ';') { + do { + c = fgetc(f); + } while (!(c == EOF || c == '\n')); + if (c == EOF) goto finished; + } if (c == '[') { TSecHeader *temp = SecHeader; @@ -206,23 +206,26 @@ static TSecHeader *load (char *filename, char **pfullname) skipspc = TRUE; do { c = fgetc(f); - if (c == EOF) break; - if (c != '\n') { - if (!isspace(c) || !skipspc) { - skipspc = FALSE; - bufsize++; - *bufptr++ = c; - if (!isspace(c)) - lastnonspc = bufptr; - } - } else - break; + if (c == EOF || c == '\n' || c == ';') break; + if (!isspace(c) || !skipspc) { + skipspc = FALSE; + bufsize++; + *bufptr++ = c; + if (!isspace(c)) + lastnonspc = bufptr; + } } while(bufsize < STRSIZE-1); *lastnonspc = 0; SecHeader->Keys->Value = strdup (CharBuffer); dprintf_profile (stddeb, "[%s] (%s)=%s\n", SecHeader->AppName, SecHeader->Keys->KeyName, SecHeader->Keys->Value); - + if (c == ';') { + do { + c = fgetc(f); + } while (!(c == EOF || c == '\n')); + if (c == EOF) + goto finished; + } } } @@ -266,6 +269,7 @@ static short GetSetProfile (int set, LPSTR AppName, LPSTR KeyName, section = New->Section; Current = New; } + /* Start search */ for (; section; section = section->link){ if (strcasecmp (section->AppName, AppName)) @@ -280,20 +284,17 @@ static short GetSetProfile (int set, LPSTR AppName, LPSTR KeyName, dprintf_profile(stddeb,"GetSetProfile // KeyName == NULL, Enumeration !\n"); for (key = section->Keys; key; key = key->link){ if (left < 1) { - dprintf_profile(stddeb,"GetSetProfile // No more storage for enum !\n"); - return (Size - 2); + dprintf_profile(stddeb,"GetSetProfile // No more storage for enum !\n"); + return Size - 2; } slen = MIN(strlen(key->KeyName) + 1, left); - dprintf_profile(stddeb,"GetSetProfile // strncpy(%p, %p, %d);\n", - ReturnedString, key->Value, slen); - strncpy (p, key->KeyName, slen); + lstrcpyn(p, key->KeyName, slen); dprintf_profile(stddeb,"GetSetProfile // enum '%s' !\n", p); left -= slen; p += slen; } - *p = '\0'; - dprintf_profile(stddeb,"GetSetProfile // normal end of enum !\n"); - return (Size - 2 - left); + *p = '\0'; + return Size - 2 - left; } for (key = section->Keys; key; key = key->link){ int slen; @@ -305,9 +306,8 @@ static short GetSetProfile (int set, LPSTR AppName, LPSTR KeyName, Current->changed=TRUE; return 1; } - slen = MIN(strlen(key->Value), Size - 1); - ReturnedString[slen] = 0; - strncpy (ReturnedString, key->Value, slen); + slen = MIN(strlen(key->Value)+1, Size); + lstrcpyn(ReturnedString, key->Value, slen); dprintf_profile(stddeb,"GetSetProfile // Return ``%s''\n", ReturnedString); return 1; } @@ -317,13 +317,13 @@ static short GetSetProfile (int set, LPSTR AppName, LPSTR KeyName, if (set) { new_key (section, KeyName, Default); } else { - int slen = MIN(strlen(Default), Size - 1); - ReturnedString[slen] = 0; - strncpy(ReturnedString, Default, slen); + int slen = MIN(strlen(Default)+1, Size); + lstrcpyn(ReturnedString, Default, slen); dprintf_profile(stddeb,"GetSetProfile // Key not found\n"); } return 1; } + /* Non existent section */ if (set){ section = (TSecHeader *) xmalloc (sizeof (TSecHeader)); @@ -334,9 +334,8 @@ static short GetSetProfile (int set, LPSTR AppName, LPSTR KeyName, Current->Section = section; Current->changed = TRUE; } else { - int slen = MIN(strlen(Default), Size - 1); - ReturnedString[slen] = 0; - strncpy(ReturnedString, Default, slen); + int slen = MIN(strlen(Default)+1, Size); + lstrcpyn(ReturnedString, Default, slen); dprintf_profile(stddeb,"GetSetProfile // Section not found\n"); } return 1; diff --git a/misc/shell.c b/misc/shell.c index 86d60ee7b05..5e1911c15a8 100644 --- a/misc/shell.c +++ b/misc/shell.c @@ -25,48 +25,48 @@ LPKEYSTRUCT lphRootKey = NULL,lphTopKey = NULL; static char RootKeyName[]=".classes", TopKeyName[] = "[top-null]"; /************************************************************************* - * SHELL_RegCheckForRoot() internal use only + * SHELL_Init() */ -static LONG SHELL_RegCheckForRoot() +BOOL SHELL_Init() { HKEY hNewKey; - - if (lphRootKey == NULL){ - hNewKey = GlobalAlloc(GMEM_MOVEABLE,sizeof(KEYSTRUCT)); - lphRootKey = (LPKEYSTRUCT) GlobalLock(hNewKey); - if (lphRootKey == NULL) { + + hNewKey = GlobalAlloc(GMEM_MOVEABLE,sizeof(KEYSTRUCT)); + lphRootKey = (LPKEYSTRUCT) GlobalLock(hNewKey); + if (lphRootKey == NULL) { printf("SHELL_RegCheckForRoot: Couldn't allocate root key!\n"); - return ERROR_OUTOFMEMORY; - } - lphRootKey->hKey = (HKEY)1; - lphRootKey->lpSubKey = RootKeyName; - lphRootKey->dwType = 0; - lphRootKey->lpValue = NULL; - lphRootKey->lpSubLvl = lphRootKey->lpNextKey = lphRootKey->lpPrevKey = NULL; - - hNewKey = GlobalAlloc(GMEM_MOVEABLE,sizeof(KEYSTRUCT)); - lphTopKey = (LPKEYSTRUCT) GlobalLock(hNewKey); - if (lphTopKey == NULL) { - printf("SHELL_RegCheckForRoot: Couldn't allocate top key!\n"); - return ERROR_OUTOFMEMORY; - } - lphTopKey->hKey = 0; - lphTopKey->lpSubKey = TopKeyName; - lphTopKey->dwType = 0; - lphTopKey->lpValue = NULL; - lphTopKey->lpSubLvl = lphRootKey; - lphTopKey->lpNextKey = lphTopKey->lpPrevKey = NULL; - - dprintf_reg(stddeb,"SHELL_RegCheckForRoot: Root/Top created\n"); + return FALSE; } - return ERROR_SUCCESS; + lphRootKey->hKey = (HKEY)1; + lphRootKey->lpSubKey = RootKeyName; + lphRootKey->dwType = 0; + lphRootKey->lpValue = NULL; + lphRootKey->lpSubLvl = lphRootKey->lpNextKey = lphRootKey->lpPrevKey = NULL; + + hNewKey = GlobalAlloc(GMEM_MOVEABLE,sizeof(KEYSTRUCT)); + lphTopKey = (LPKEYSTRUCT) GlobalLock(hNewKey); + if (lphTopKey == NULL) { + printf("SHELL_RegCheckForRoot: Couldn't allocate top key!\n"); + return FALSE; + } + lphTopKey->hKey = 0; + lphTopKey->lpSubKey = TopKeyName; + lphTopKey->dwType = 0; + lphTopKey->lpValue = NULL; + lphTopKey->lpSubLvl = lphRootKey; + lphTopKey->lpNextKey = lphTopKey->lpPrevKey = NULL; + + dprintf_reg(stddeb,"SHELL_RegCheckForRoot: Root/Top created\n"); + + return TRUE; } /* FIXME: the loading and saving of the registry database is rather messy. * bad input (while reading) may crash wine. */ void -_DumpLevel(FILE *f,LPKEYSTRUCT lpTKey,int tabs) { +_DumpLevel(FILE *f,LPKEYSTRUCT lpTKey,int tabs) +{ LPKEYSTRUCT lpKey; lpKey=lpTKey->lpSubLvl; @@ -86,7 +86,8 @@ _DumpLevel(FILE *f,LPKEYSTRUCT lpTKey,int tabs) { } static void -_SaveKey(HKEY hKey,char *where) { +_SaveKey(HKEY hKey,char *where) +{ FILE *f; LPKEYSTRUCT lpKey; @@ -106,7 +107,8 @@ _SaveKey(HKEY hKey,char *where) { } void -SHELL_SaveRegistry(void) { +SHELL_SaveRegistry(void) +{ /* FIXME: * -implement win95 additional keytypes here * (HKEY_LOCAL_MACHINE,HKEY_CURRENT_USER or whatever) @@ -117,7 +119,8 @@ SHELL_SaveRegistry(void) { #define BUFSIZE 256 void -_LoadLevel(FILE *f,LPKEYSTRUCT lpKey,int tabsexp,char *buf) { +_LoadLevel(FILE *f,LPKEYSTRUCT lpKey,int tabsexp,char *buf) +{ int i; char *s,*t; HKEY hNewKey; @@ -184,7 +187,8 @@ _LoadLevel(FILE *f,LPKEYSTRUCT lpKey,int tabsexp,char *buf) { } void -_LoadKey(HKEY hKey,char *from) { +_LoadKey(HKEY hKey,char *from) +{ FILE *f; LPKEYSTRUCT lpKey; char buf[BUFSIZE]; /* FIXME: long enough? */ @@ -204,12 +208,8 @@ _LoadKey(HKEY hKey,char *from) { } void -SHELL_LoadRegistry(void) { - DWORD dwRet; - - dwRet=SHELL_RegCheckForRoot(); - if (dwRet!=ERROR_SUCCESS) - return;/*very bad magic, if we can't even allocate the rootkeys*/ +SHELL_LoadRegistry(void) +{ _LoadKey((HKEY)HKEY_CLASSES_ROOT,"/tmp/winereg"); } @@ -221,10 +221,7 @@ LONG RegOpenKey(HKEY hKey, LPCSTR lpSubKey, HKEY FAR *lphKey) LPKEYSTRUCT lpKey,lpNextKey; LPCSTR ptr; char str[128]; - LONG dwRet; - dwRet = SHELL_RegCheckForRoot(); - if (dwRet != ERROR_SUCCESS) return dwRet; dprintf_reg(stddeb, "RegOpenKey(%08lX, %p='%s', %p)\n", (DWORD)hKey, lpSubKey, lpSubKey, lphKey); if (lphKey == NULL) return ERROR_INVALID_PARAMETER; @@ -274,12 +271,9 @@ LONG RegCreateKey(HKEY hKey, LPCSTR lpSubKey, HKEY FAR *lphKey) LPKEYSTRUCT lpNewKey; LPKEYSTRUCT lpKey; LPKEYSTRUCT lpPrevKey; - LONG dwRet; LPCSTR ptr; char str[128]; - dwRet = SHELL_RegCheckForRoot(); - if (dwRet != ERROR_SUCCESS) return dwRet; dprintf_reg(stddeb, "RegCreateKey(%08lX, '%s', %p)\n", (DWORD)hKey, lpSubKey, lphKey); if (lphKey == NULL) return ERROR_INVALID_PARAMETER; switch((DWORD)hKey) { @@ -439,11 +433,8 @@ LONG RegQueryValue(HKEY hKey, LPCSTR lpSubKey, LPSTR lpVal, LONG FAR *lpcb) LONG RegEnumKey(HKEY hKey, DWORD dwSubKey, LPSTR lpBuf, DWORD dwSize) { LPKEYSTRUCT lpKey; - LONG dwRet; LONG len; - dwRet = SHELL_RegCheckForRoot(); - if (dwRet != ERROR_SUCCESS) return dwRet; dprintf_reg(stddeb, "RegEnumKey(%08lX, %ld)\n", (DWORD)hKey, dwSubKey); if (lpBuf == NULL) return ERROR_INVALID_PARAMETER; switch((DWORD)hKey) { @@ -478,11 +469,12 @@ LONG RegEnumKey(HKEY hKey, DWORD dwSubKey, LPSTR lpBuf, DWORD dwSize) */ void DragAcceptFiles(HWND hWnd, BOOL b) { - /* flips WS_EX_ACCEPTFILES bit according to the value of b (TRUE or FALSE) */ + /* flips WS_EX_ACCEPTFILES bit according to the value of b */ + dprintf_reg(stddeb,"DragAcceptFiles("NPFMT", %u) old exStyle %08lx\n", + hWnd,b,GetWindowLong(hWnd,GWL_EXSTYLE)); - dprintf_reg(stddeb,"DragAcceptFiles("NPFMT", %u) old exStyle %08lx\n",hWnd,b,GetWindowLong(hWnd,GWL_EXSTYLE)); - - SetWindowLong(hWnd,GWL_EXSTYLE,GetWindowLong(hWnd,GWL_EXSTYLE) | b*(LONG)WS_EX_ACCEPTFILES); + SetWindowLong(hWnd,GWL_EXSTYLE, + GetWindowLong(hWnd,GWL_EXSTYLE) | b*(LONG)WS_EX_ACCEPTFILES); } @@ -491,42 +483,42 @@ void DragAcceptFiles(HWND hWnd, BOOL b) */ UINT DragQueryFile(HDROP hDrop, WORD wFile, LPSTR lpszFile, WORD wLength) { - /* hDrop is a global memory block allocated with GMEM_SHARE - with DROPFILESTRUCT as a header and filenames following - it, zero length filename is in the end */ - - LPDROPFILESTRUCT lpDropFileStruct; - LPSTR lpCurrent; - WORD i; - - dprintf_reg(stddeb,"DragQueryFile("NPFMT", %i, %p, %u)\n", - hDrop,wFile,lpszFile,wLength); - - lpDropFileStruct = (LPDROPFILESTRUCT) GlobalLock(hDrop); - if(!lpDropFileStruct) + /* hDrop is a global memory block allocated with GMEM_SHARE + * with DROPFILESTRUCT as a header and filenames following + * it, zero length filename is in the end */ + + LPDROPFILESTRUCT lpDropFileStruct; + LPSTR lpCurrent; + WORD i; + + dprintf_reg(stddeb,"DragQueryFile("NPFMT", %i, %p, %u)\n", + hDrop,wFile,lpszFile,wLength); + + lpDropFileStruct = (LPDROPFILESTRUCT) GlobalLock(hDrop); + if(!lpDropFileStruct) { - dprintf_reg(stddeb,"DragQueryFile: unable to lock handle!\n"); - return 0; + dprintf_reg(stddeb,"DragQueryFile: unable to lock handle!\n"); + return 0; } - lpCurrent = (LPSTR) lpDropFileStruct + lpDropFileStruct->wSize; - - i = 0; - while(i++ < wFile) + lpCurrent = (LPSTR) lpDropFileStruct + lpDropFileStruct->wSize; + + i = 0; + while (i++ < wFile) { - while(*lpCurrent++); /* skip filename */ - if(!*lpCurrent) - return (wFile == 0xFFFF)? i : 0; + while (*lpCurrent++); /* skip filename */ + if (!*lpCurrent) + return (wFile == 0xFFFF) ? i : 0; } - - i = strlen(lpCurrent); - if(!lpszFile) return i+1; /* needed buffer size */ - - i = ( wLength > i)? i : wLength-1; - strncpy(lpszFile,lpCurrent,i); - lpszFile[i]='\0'; - - GlobalUnlock(hDrop); - return i; + + i = strlen(lpCurrent); + if (!lpszFile) return i+1; /* needed buffer size */ + + i = (wLength > i) ? i : wLength-1; + strncpy(lpszFile, lpCurrent, i); + lpszFile[i] = '\0'; + + GlobalUnlock(hDrop); + return i; } @@ -535,7 +527,7 @@ UINT DragQueryFile(HDROP hDrop, WORD wFile, LPSTR lpszFile, WORD wLength) */ void DragFinish(HDROP h) { - GlobalFree((HGLOBAL)h); + GlobalFree((HGLOBAL)h); } @@ -544,16 +536,16 @@ void DragFinish(HDROP h) */ BOOL DragQueryPoint(HDROP hDrop, POINT FAR *p) { - LPDROPFILESTRUCT lpDropFileStruct; - BOOL bRet; + LPDROPFILESTRUCT lpDropFileStruct; + BOOL bRet; - lpDropFileStruct = (LPDROPFILESTRUCT) GlobalLock(hDrop); + lpDropFileStruct = (LPDROPFILESTRUCT) GlobalLock(hDrop); - memcpy(p,&lpDropFileStruct->ptMousePos,sizeof(POINT)); - bRet = lpDropFileStruct->fInNonClientArea; + memcpy(p,&lpDropFileStruct->ptMousePos,sizeof(POINT)); + bRet = lpDropFileStruct->fInNonClientArea; - GlobalUnlock(hDrop); - return bRet; + GlobalUnlock(hDrop); + return bRet; } diff --git a/misc/spy.c b/misc/spy.c index 6c9692a65ad..e547e1c023c 100644 --- a/misc/spy.c +++ b/misc/spy.c @@ -25,7 +25,7 @@ const char *MessageTypeNames[SPY_MAX_MSGNUM + 1] = "WM_CREATE", "WM_DESTROY", "WM_MOVE", - "WM_UNUSED0", + "WM_SIZEWAIT", "WM_SIZE", "WM_ACTIVATE", "WM_SETFOCUS", @@ -62,7 +62,7 @@ const char *MessageTypeNames[SPY_MAX_MSGNUM + 1] = "WM_PAINTICON", "WM_ICONERASEBKGND", "WM_NEXTDLGCTL", - "WM_UNUSED4", + "WM_ALTTABACTIVE", "WM_SPOOLERSTATUS", "WM_DRAWITEM", "WM_MEASUREITEM", @@ -70,9 +70,19 @@ const char *MessageTypeNames[SPY_MAX_MSGNUM + 1] = "WM_VKEYTOITEM", "WM_CHARTOITEM", "WM_SETFONT", /* 0x30 */ - "WM_GETFONT", NULL, NULL, NULL, NULL, NULL, - "WM_QUERYDRAGICON", NULL, - "WM_COMPAREITEM", NULL, NULL, NULL, NULL, NULL, NULL, + "WM_GETFONT", + "WM_SETHOTKEY", + "WM_GETHOTKEY", + "WM_FILESYSCHANGE", + "WM_ISACTIVEICON", + "WM_QUERYPARKICON", + "WM_QUERYDRAGICON", + "WM_QUERYSAVESTATE", + "WM_COMPAREITEM", + "WM_TESTING", NULL, + "WM_OTHERWINDOWCREATED", + "WM_OTHERWINDOWDESTROYED", + "WM_ACTIVATESHELLWINDOW", NULL, NULL, /* 0x40 */ "WM_COMPACTING", NULL, NULL, @@ -101,7 +111,8 @@ const char *MessageTypeNames[SPY_MAX_MSGNUM + 1] = "WM_NCPAINT", /* 0x0085 */ "WM_NCACTIVATE", /* 0x0086 */ "WM_GETDLGCODE", /* 0x0087 */ - "WM_SYNCPAINT", NULL, NULL, NULL, NULL, NULL, NULL, NULL, + "WM_SYNCPAINT", + "WM_SYNCTASK", NULL, NULL, NULL, NULL, NULL, NULL, /* 0x0090 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -149,7 +160,10 @@ const char *MessageTypeNames[SPY_MAX_MSGNUM + 1] = "WM_SYSCHAR", /* 0x0106 */ "WM_SYSDEADCHAR", /* 0x0107 */ "WM_KEYLAST", /* 0x0108 */ - NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, + "WM_CONVERTREQUEST", + "WM_CONVERTRESULT", + "WM_INTERIM", NULL, NULL, NULL, "WM_INITDIALOG", /* 0x0110 */ "WM_COMMAND", /* 0x0111 */ @@ -169,8 +183,7 @@ const char *MessageTypeNames[SPY_MAX_MSGNUM + 1] = NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x0130 */ - NULL, - "wm_lbtrackpoint", + NULL, "wm_lbtrackpoint", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -237,7 +250,8 @@ const char *MessageTypeNames[SPY_MAX_MSGNUM + 1] = "WM_PARENTNOTIFY", /* 0x0210 */ "WM_ENTERMENULOOP", /* 0x0211 */ "WM_EXITMENULOOP", /* 0x0212 */ - NULL, NULL, NULL, NULL, NULL, + "WM_NEXTMENU", /* 0x0213 */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "WM_MDICREATE", /* 0x0220 */ @@ -344,10 +358,11 @@ const char *MessageTypeNames[SPY_MAX_MSGNUM + 1] = /* 0x0380 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + "WM_COALESCE_FIRST", + NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, "WM_COALESCE_LAST", - NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, diff --git a/misc/winsocket.c b/misc/winsocket.c index 318c38e1436..536e5db2b49 100644 --- a/misc/winsocket.c +++ b/misc/winsocket.c @@ -35,6 +35,10 @@ static key_t wine_key = 0; static FARPROC BlockFunction; static fd_set fd_in_use; +#ifdef __FreeBSD__ +extern int h_errno; +#endif /* __FreeBSD__ */ + struct ipc_packet { long mtype; HANDLE handle; @@ -48,7 +52,8 @@ struct ipc_packet { #endif #define IPC_PACKET_SIZE (sizeof(struct ipc_packet) - sizeof(long)) -#define MTYPE 0xb0b0eb05 +/*#define MTYPE 0xb0b0eb05*/ +#define MTYPE 0x30b0eb05 /* These structures are Win16 only */ @@ -831,23 +836,32 @@ static HANDLE AllocWSAHandle(void) static void recv_message(int sig) { - struct ipc_packet message; + static struct ipc_packet message; + static int message_is_valid = 0; + BOOL result; -/* FIXME: something about no message of desired type */ - if (msgrcv(wine_key, (struct msgbuf*)&(message), - IPC_PACKET_SIZE, MTYPE, IPC_NOWAIT) == -1) - perror("wine: msgrcv"); - - fprintf(stderr, - "WSA: PostMessage (hwnd "NPFMT", wMsg %d, wParam "NPFMT", lParam %ld)\n", - message.hWnd, - message.wMsg, - message.handle, - message.lParam); - - PostMessage(message.hWnd, message.wMsg, (WPARAM)message.handle, message.lParam); - signal(SIGUSR1, recv_message); + while (1) { + + if (!message_is_valid) { + if (msgrcv(wine_key, (struct msgbuf*)&(message), + IPC_PACKET_SIZE, MTYPE, IPC_NOWAIT) == -1) { + perror("wine: msgrcv"); + break; + } + } + + result = PostMessage(message.hWnd, message.wMsg, + (WPARAM)message.handle, message.lParam); + if (result == FALSE) { + message_is_valid = 1; + break; + } + else + message_is_valid = 0; + + } + } @@ -861,13 +875,8 @@ static void send_message( HWND hWnd, u_int wMsg, HANDLE handle, long lParam) message.wMsg = wMsg; message.lParam = lParam; - fprintf(stderr, - "WSA: send (hwnd "NPFMT", wMsg %d, handle "NPFMT", lParam %ld)\n", - hWnd, wMsg, handle, lParam); - -/* FIXME: something about invalid argument */ if (msgsnd(wine_key, (struct msgbuf*)&(message), - IPC_PACKET_SIZE, IPC_NOWAIT) == -1) + IPC_PACKET_SIZE, 0/*IPC_NOWAIT*/) == -1) perror("wine: msgsnd"); kill(getppid(), SIGUSR1); @@ -1136,12 +1145,14 @@ WSADATA WINSOCK_data = { "WINE Sockets", #ifdef linux "LINUX/i386", -#endif -#ifdef __NetBSD__ +#elif defined(__NetBSD__) "NetBSD/i386", -#endif -#ifdef sunos +#elif defined(sunos) "SunOS", +#elif defined(__FreeBSD__) + "FreeBSD", +#else + "Unknown", #endif 128, 1024, diff --git a/multimedia/mcistring.c b/multimedia/mcistring.c index 3ea208f1199..dc99c2abc13 100644 --- a/multimedia/mcistring.c +++ b/multimedia/mcistring.c @@ -57,16 +57,10 @@ LONG ANIM_DriverProc(DWORD dwDevID, HDRVR hDriv, WORD wMsg, * for use in mciSendString() */ #define _MCI_STR(s) do {\ - int __l__;\ dprintf_mci(stddeb,"->returns \"%s\"",s);\ if (lpstrReturnString) {\ - __l__=strlen(s);\ - if(__l__>uReturnLength) {\ - strncpy(lpstrReturnString,s,uReturnLength-1);\ - lpstrReturnString[uReturnLength-1]='\0';\ - } else\ - strcpy(lpstrReturnString,s);\ - dprintf_mci(stddeb,"-->\"%s\"\n",lpstrReturnString);\ + lstrcpyn(lpstrReturnString,s,uReturnLength);\ + dprintf_mci(stddeb,"-->\"%s\"\n",lpstrReturnString);\ }\ } while(0) diff --git a/multimedia/mmsystem.c b/multimedia/mmsystem.c index 81f1c1b9a92..152ee9a1c43 100644 --- a/multimedia/mmsystem.c +++ b/multimedia/mmsystem.c @@ -284,7 +284,6 @@ DWORD auxOutMessage(UINT uDeviceID, UINT uMessage, DWORD dw1, DWORD dw2) BOOL mciGetErrorString (DWORD wError, LPSTR lpstrBuffer, UINT uLength) { LPSTR msgptr; - int maxbuf; dprintf_mmsys(stddeb, "mciGetErrorString(%08lX, %p, %d);\n", wError, lpstrBuffer, uLength); if ((lpstrBuffer == NULL) || (uLength < 1)) return(FALSE); lpstrBuffer[0] = '\0'; @@ -534,10 +533,8 @@ msg# 543 : tmsf msgptr = "Unknown MCI Error !\n"; break; } - maxbuf = MIN(uLength - 1, strlen(msgptr)); - if (maxbuf > 0) strncpy(lpstrBuffer, msgptr, maxbuf); - lpstrBuffer[maxbuf + 1] = '\0'; - return(TRUE); + lstrcpyn(lpstrBuffer, msgptr, uLength); + return TRUE; } @@ -708,12 +705,10 @@ DWORD mciSysInfo(DWORD dwFlags, LPMCI_SYSINFO_PARMS lpParms) ptr += len; InstalledListLen += len; InstalledCount++; - } - } - if (lpParms->dwRetSize < InstalledListLen) { - strncpy(lpstrReturn, lpInstallNames, lpParms->dwRetSize - 2); - lpstrReturn[lpParms->dwRetSize - 1] = '\0'; } + } + if (lpParms->dwRetSize < InstalledListLen) + lstrcpyn(lpstrReturn, lpInstallNames, lpParms->dwRetSize - 1); else strcpy(lpstrReturn, lpInstallNames); return 0; @@ -781,7 +776,7 @@ DWORD mciSendCommand(UINT wDevID, UINT wMsg, DWORD dwParam1, DWORD dwParam2) } /************************************************************************** -* mciGetDeviceID [MMSYSTEM.703] +* mciGetDeviceID [MMSYSTEM.703] */ UINT mciGetDeviceID (LPCSTR lpstrName) { @@ -860,12 +855,11 @@ UINT midiOutGetErrorText(UINT uError, LPSTR lpText, UINT uSize) /************************************************************************** -* midiGetErrorText [internal] +* midiGetErrorText [internal] */ UINT midiGetErrorText(UINT uError, LPSTR lpText, UINT uSize) { LPSTR msgptr; - int maxbuf; if ((lpText == NULL) || (uSize < 1)) return(FALSE); lpText[0] = '\0'; switch(uError) { @@ -901,17 +895,15 @@ msg# 343 : There are no MIDI devices installed on the system. Use the Drivers op msgptr = "Unknown MIDI Error !\n"; break; } - maxbuf = MIN(uSize - 1, strlen(msgptr)); - if (maxbuf > 0) strncpy(lpText, msgptr, maxbuf); - lpText[maxbuf + 1] = '\0'; - return(TRUE); + lstrcpyn(lpText, msgptr, uSize); + return TRUE; } /************************************************************************** -* midiOutOpen [MMSYSTEM.204] +* midiOutOpen [MMSYSTEM.204] */ UINT midiOutOpen(HMIDIOUT FAR* lphMidiOut, UINT uDeviceID, - DWORD dwCallback, DWORD dwInstance, DWORD dwFlags) + DWORD dwCallback, DWORD dwInstance, DWORD dwFlags) { HMIDI hMidiOut; LPMIDIOPENDESC lpDesc; @@ -925,7 +917,7 @@ UINT midiOutOpen(HMIDIOUT FAR* lphMidiOut, UINT uDeviceID, dprintf_mmsys(stddeb, "midiOutOpen // MIDI_MAPPER mode requested !\n"); bMapperFlg = TRUE; uDeviceID = 0; - } + } hMidiOut = USER_HEAP_ALLOC(sizeof(MIDIOPENDESC)); if (lphMidiOut != NULL) *lphMidiOut = hMidiOut; lp16Desc = (LPMIDIOPENDESC) USER_HEAP_SEG_ADDR(hMidiOut); @@ -1300,7 +1292,6 @@ UINT waveOutGetErrorText(UINT uError, LPSTR lpText, UINT uSize) UINT waveGetErrorText(UINT uError, LPSTR lpText, UINT uSize) { LPSTR msgptr; - int maxbuf; dprintf_mmsys(stddeb, "waveGetErrorText(%04X, %p, %d);\n", uError, lpText, uSize); if ((lpText == NULL) || (uSize < 1)) return(FALSE); lpText[0] = '\0'; @@ -1357,10 +1348,8 @@ UINT waveGetErrorText(UINT uError, LPSTR lpText, UINT uSize) msgptr = "Unknown MMSYSTEM Error !\n"; break; } - maxbuf = MIN(uSize - 1, strlen(msgptr)); - if (maxbuf > 0) strncpy(lpText, msgptr, maxbuf); - lpText[maxbuf + 1] = '\0'; - return(TRUE); + lstrcpyn(lpText, msgptr, uSize); + return TRUE; } /************************************************************************** diff --git a/objects/bitblt.c b/objects/bitblt.c index 89ae404c83b..d6e182cdf04 100644 --- a/objects/bitblt.c +++ b/objects/bitblt.c @@ -1249,8 +1249,8 @@ BOOL PatBlt( HDC hdc, short left, short top, /*********************************************************************** * BitBlt (GDI.34) */ -BOOL BitBlt( HDC hdcDst, short xDst, short yDst, short width, short height, - HDC hdcSrc, short xSrc, short ySrc, DWORD rop ) +BOOL BitBlt( HDC hdcDst, INT xDst, INT yDst, INT width, INT height, + HDC hdcSrc, INT xSrc, INT ySrc, DWORD rop ) { DC *dcDst, *dcSrc; diff --git a/objects/font.c b/objects/font.c index be7ac76c4ff..407d15e8d0b 100644 --- a/objects/font.c +++ b/objects/font.c @@ -484,8 +484,7 @@ INT GetTextFace( HDC hdc, INT count, LPSTR name ) if (!dc) return 0; if (!(font = (FONTOBJ *) GDI_GetObjPtr( dc->w.hFont, FONT_MAGIC ))) return 0; - strncpy( name, font->logfont.lfFaceName, count ); - name[count-1] = '\0'; + lstrcpyn( name, font->logfont.lfFaceName, count ); return strlen(name); } diff --git a/objects/gdiobj.c b/objects/gdiobj.c index 7f0e6a3cf53..bde259bde1e 100644 --- a/objects/gdiobj.c +++ b/objects/gdiobj.c @@ -417,7 +417,7 @@ int EnumObjects(HDC hDC, int nObjType, FARPROC lpEnumFunc, LPSTR lpData) HANDLE hLog; int nRet = 0; - if (lpEnumFunc == NULL) { + if (lpEnumFunc == 0) { fprintf(stderr,"EnumObjects // Bad EnumProc callback address !\n"); return 0; } diff --git a/objects/metafile.c b/objects/metafile.c index 6cc68b62843..297f514dade 100644 --- a/objects/metafile.c +++ b/objects/metafile.c @@ -245,7 +245,8 @@ BOOL PlayMetaFile(HDC hdc, HMETAFILE hmf) return FALSE; /* create the handle table */ - hHT = GlobalAlloc(GMEM_MOVEABLE, sizeof(HANDLETABLE) * mh->mtNoObjects); + hHT = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT, + sizeof(HANDLETABLE) * mh->mtNoObjects); ht = (HANDLETABLE *)GlobalLock(hHT); /* loop through metafile playing records */ diff --git a/rc/winerc.c b/rc/winerc.c index 4e1aa525e76..c01227f7733 100644 --- a/rc/winerc.c +++ b/rc/winerc.c @@ -12,7 +12,7 @@ #include #include #include -#include +/* #include */ #include "parser.h" #include "y.tab.h" @@ -539,16 +539,7 @@ void create_output(gen_res* top) fprintf( header, "/* %s\n" " * This file is automatically generated. Do not edit!\n" " */\n\n" - "#ifndef __RESOURCE_DEFINED__\n" - "#define __RESOURCE_DEFINED__\n" - "struct resource\n" - "{\n" - " int id, type;\n" - " char *name;\n" - " unsigned char *bytes;\n" - " unsigned int size;\n" - "};\n" - "#endif\n", hname ); + "#include \"resource.h\"\n", hname ); /* Declare the resources */ @@ -583,15 +574,15 @@ void create_output(gen_res* top) int type; switch(it->type) { - case acc:type=NE_RSCTYPE_ACCELERATOR;break; - case bmp:type=NE_RSCTYPE_BITMAP;break; - case cur:type=NE_RSCTYPE_CURSOR;break; - case dlg:type=NE_RSCTYPE_DIALOG;break; - case fnt:type=NE_RSCTYPE_FONT;break; - case ico:type=NE_RSCTYPE_ICON;break; - case men:type=NE_RSCTYPE_MENU;break; - case rdt:type=NE_RSCTYPE_RCDATA;break; - case str:type=NE_RSCTYPE_STRING;break; + case acc:type=RT_ACCELERATOR;break; + case bmp:type=RT_BITMAP;break; + case cur:type=RT_CURSOR;break; + case dlg:type=RT_DIALOG;break; + case fnt:type=RT_FONT;break; + case ico:type=RT_ICON;break; + case men:type=RT_MENU;break; + case rdt:type=RT_RCDATA;break; + case str:type=RT_STRING;break; default:fprintf(stderr,"Unknown restype\n");type=-1;break; } if(it->n_type) @@ -610,6 +601,22 @@ void create_output(gen_res* top) for (it=top;it;it=it->next) fprintf( code, " &%s,\n", get_resource_name(it) ); fprintf( code, " 0\n};\n" ); + + /* Perform autoregistration */ + fprintf( code, + "#ifdef WINELIB\n" + "static void DoIt() WINE_CONSTRUCTOR;\n" + "static void DoIt()\n" + "{\n" + "\tLIBRES_RegisterResources(%sTable);\n" + "}\n\n" + "#ifndef HAVE_WINE_CONSTRUCTOR\n" + "void LIBWINE_Register_%s(){\n" + "\tDoIt();\n" + "}\n" + "#endif\n" + "#endif /*WINELIB*/\n" + ,prefix,prefix); } gen_res* make_font(gen_res* res) diff --git a/toolkit/Makefile.in b/toolkit/Makefile.in index a1e6cb008e8..46befbf67ad 100644 --- a/toolkit/Makefile.in +++ b/toolkit/Makefile.in @@ -30,7 +30,7 @@ hello3res.o: hello3res.rc echo WINDOWS_H_ENDS_HERE >>hello3res.rct cat hello3res.rc >>hello3res.rct $(CC) $(ALLCFLAGS) -E -x c -P hello3res.rct | sed -e '1,/^WINDOWS_H_ENDS_HERE/d' | ../rc/winerc -o hello3res -v -p hello3 - gcc -c hello3res.c + gcc -c $(ALLCFLAGS) hello3res.c @MAKE_RULES@ diff --git a/toolkit/heap.c b/toolkit/heap.c index 40e52cbb61d..7bb3afd6a98 100644 --- a/toolkit/heap.c +++ b/toolkit/heap.c @@ -108,7 +108,10 @@ WORD LocalFlags (HANDLE hMem) HANDLE LocalFree (HANDLE hMem) { - void **m = HEAP_FindSlot (hMem); + void **m; + if(!hMem) + return 0; + m = HEAP_FindSlot (hMem); free (*m); *m = 0; @@ -232,7 +235,10 @@ HANDLE HEAP_Alloc (WORD flags, DWORD bytes) HANDLE HEAP_Free (HANDLE hMem) { - HeapData* m=(HeapData*)hMem; + HeapData* m; + if(!hMem) + return 0; + m=(HeapData*)hMem; free(m-1); return 0; } @@ -296,7 +302,6 @@ UINT LocalSize (HANDLE hMem) return HEAP_Size(hMem); } - BOOL LocalUnlock (HANDLE hMem) { return 0; diff --git a/toolkit/hello3.c b/toolkit/hello3.c index 90fadb1c369..5b9cd5118ed 100644 --- a/toolkit/hello3.c +++ b/toolkit/hello3.c @@ -87,7 +87,7 @@ int PASCAL WinMain (HANDLE inst, HANDLE prev, LPSTR cmdline, int show) wnd = CreateWindow ("class", "Test app", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0, - LoadMenuIndirect(hello3_MENU_MAIN.bytes), inst, 0); + LoadMenu(inst,"MAIN"), inst, 0); ShowWindow (wnd, show); UpdateWindow (wnd); diff --git a/toolkit/libres.c b/toolkit/libres.c index c983ff665cc..ae23b415d90 100644 --- a/toolkit/libres.c +++ b/toolkit/libres.c @@ -5,19 +5,12 @@ */ #include -#include "windows.h" - -struct resource /* This needs to coincide with what winerc generates. */ -{ /* It should really only appear in one place. */ - int id, type; - char *name; - unsigned char *bytes; - unsigned int size; -}; +#include +#include "libres.h" typedef struct RLE { - struct resource** Resources /* NULL-terminated array of pointers */ + struct resource** Resources; /* NULL-terminated array of pointers */ struct RLE* next; } ResListE; @@ -28,11 +21,11 @@ void LIBRES_RegisterResources(struct resource** Res) ResListE** Curr; ResListE* n; for(Curr=&ResourceList; *Curr; Curr=&((*Curr)->next)) { } - n=malloc(sizeof(ResListE)); + n=xmalloc(sizeof(ResListE)); if(n) { - n.Resources=Res; - n.next=NULL; + n->Resources=Res; + n->next=NULL; *Curr=n; } else @@ -42,9 +35,48 @@ void LIBRES_RegisterResources(struct resource** Res) /********************************************************************** * LIBRES_FindResource */ -HRSRC LIBRES_FindResource( HMODULE hModule, SEGPTR name, SEGPTR type ) +HRSRC LIBRES_FindResource( HINSTANCE hModule, LPCSTR name, LPCSTR type ) { - WINELIB_UNIMP("LIBRES_FindResource()"); + int nameid=0,typeid; + ResListE* ResBlock; + struct resource** Res; + + if(HIWORD(name)) + { + if(*name=='#') + { + nameid=atoi(name+1); + name=NULL; + } + } + else + { + nameid=LOWORD(name); + name=NULL; + } + if(HIWORD(type)) + { + if(*type=='#') + typeid=atoi(type+1); + else + { + WINELIB_UNIMP("LIBRES_FindResource(*,*,type=string)"); + return 0; + } + } + else + typeid=LOWORD(type); + + for(ResBlock=ResourceList; ResBlock; ResBlock=ResBlock->next) + for(Res=ResBlock->Resources; *Res; Res++) + if(name) + { + if((*Res)->type==typeid && !strcmp((*Res)->name,name)) + return (HRSRC)*Res; + } + else + if((*Res)->type==typeid && (*Res)->id==nameid) + return (HRSRC)*Res; return 0; } @@ -52,7 +84,7 @@ HRSRC LIBRES_FindResource( HMODULE hModule, SEGPTR name, SEGPTR type ) /********************************************************************** * LIBRES_LoadResource */ -HGLOBAL LIBRES_LoadResource( HMODULE hModule, HRSRC hRsrc ) +HGLOBAL LIBRES_LoadResource( HINSTANCE hModule, HRSRC hRsrc ) { return (HGLOBAL)(((struct resource*)hRsrc)->bytes); } @@ -61,7 +93,7 @@ HGLOBAL LIBRES_LoadResource( HMODULE hModule, HRSRC hRsrc ) /********************************************************************** * LIBRES_LockResource */ -LPVOID LIBRES_LockResource( HMODULE hModule, HGLOBAL handle ) +LPVOID LIBRES_LockResource( HGLOBAL handle ) { return handle; } @@ -70,9 +102,10 @@ LPVOID LIBRES_LockResource( HMODULE hModule, HGLOBAL handle ) /********************************************************************** * LIBRES_FreeResource */ -BOOL LIBRES_FreeResource( HMODULE hModule, HGLOBAL handle ) +BOOL LIBRES_FreeResource( HGLOBAL handle ) { - return 0; + WINELIB_UNIMP("LIBRES_FreeResource()"); + return 0; /* Obsolete in Win32 */ } @@ -82,25 +115,25 @@ BOOL LIBRES_FreeResource( HMODULE hModule, HGLOBAL handle ) INT LIBRES_AccessResource( HINSTANCE hModule, HRSRC hRsrc ) { WINELIB_UNIMP("LIBRES_AccessResource()"); - return -1; + return -1; /* Obsolete in Win32 */ } /********************************************************************** * LIBRES_SizeofResource */ -DWORD LIBRES_SizeofResource( HMODULE hModule, HRSRC hRsrc ) +DWORD LIBRES_SizeofResource( HINSTANCE hModule, HRSRC hRsrc ) { - return (HGLOBAL)(((struct resource*)hRsrc)->size); + return (DWORD)(((struct resource*)hRsrc)->size); } /********************************************************************** * LIBRES_AllocResource */ -HGLOBAL LIBRES_AllocResource( HMODULE hModule, HRSRC hRsrc, DWORD size ) +HGLOBAL LIBRES_AllocResource( HINSTANCE hModule, HRSRC hRsrc, DWORD size ) { WINELIB_UNIMP("LIBRES_AllocResource()"); - return 0; + return 0; /* Obsolete in Win32 */ } diff --git a/tools/build.c b/tools/build.c index 499f68818f5..53a0150754d 100644 --- a/tools/build.c +++ b/tools/build.c @@ -789,7 +789,29 @@ static void BuildSpec32Files( char *specname ) case TYPE_CDECL: varargs=0; argc=strlen(fdp->arg_types); - printf( "void %s_%d(", UpperDLLName, i); + if(odp->type == TYPE_STDCALL) + { + /* Output a function prototype with stdcall attribute */ + printf( "void %s_%d(", UpperDLLName, i); + for(argno=0;argnoarg_types[argno]) + { + case 'p': printf( "void *");break; + case 'l': printf( "int ");break; + case '.': printf( "... ");varargs=argno;break; + default: + fprintf(stderr, "Not supported argument type %c\n", + fdp->arg_types[argno]); + exit(1); + } + if(fdp->arg_types[argno]!='.') putchar( 'a'+argno ); + if (argno!=argc-1) putchar( ',' ); + } + printf( ") __attribute((stdcall));" ); + } + + printf( "void %s_%d(", UpperDLLName, i); for(argno=0;argnoarg_types[argno]) @@ -806,7 +828,6 @@ static void BuildSpec32Files( char *specname ) if (argno!=argc-1) putchar( ',' ); } printf( ")" ); - if(odp->type == TYPE_STDCALL) printf(" /*__attribute__ ((stdcall))*/"); printf( "\n{\n" ); if (varargs) printf( "\tva_list valist;\n\n\tva_start(valist, %c);", 'a'+varargs-1 ); diff --git a/win32/advapi.c b/win32/advapi.c index be633d8660c..7c9baf2a101 100644 --- a/win32/advapi.c +++ b/win32/advapi.c @@ -1,14 +1,14 @@ /* * Win32 advapi functions * - * Copyright 1995 Martin von Loewis + * Copyright 1995 Sven Verdoolaege */ #include #include #include "windows.h" #include "winerror.h" -/*#include "kernel32.h"*/ +#include "advapi32.h" #include "stddebug.h" #include "debug.h" @@ -16,7 +16,7 @@ * GetUserNameA (ADVAPI32.67) */ -int GetUserNameA(LPSTR lpszName, LPDWORD lpSize) +BOOL WINAPI GetUserNameA(LPSTR lpszName, LPDWORD lpSize) { size_t len; char *name; @@ -32,3 +32,49 @@ int GetUserNameA(LPSTR lpszName, LPDWORD lpSize) return 1; } +/*********************************************************************** + * RegCreateKeyEx (ADVAPI32.130) + */ +WINAPI LONG RegCreateKeyEx(HKEY key, + const char *subkey, + long dontuse, + const char *keyclass, + DWORD options, + REGSAM sam, + SECURITY_ATTRIBUTES *atts, + HKEY *res, + DWORD *disp) +{ + /* ahum */ + return RegCreateKey(key, subkey, res); +} + +/*********************************************************************** + * RegSetValueEx (ADVAPI32.169) + */ + +WINAPI LONG RegSetValueEx (HKEY key, + const char *name, + DWORD dontuse, + DWORD type, + const void* data, + DWORD len + ) +{ + return 0; +} + +/*********************************************************************** + * RegQueryValueEx (ADVAPI32.157) + */ + +WINAPI LONG RegQueryValueEx(HKEY key, + const char *subkey, + DWORD dontuse, + DWORD *type, + void *ptr, + DWORD *len) +{ + return 0; +} + diff --git a/win32/environment.c b/win32/environment.c index 17e2966c25e..e754f41b978 100644 --- a/win32/environment.c +++ b/win32/environment.c @@ -6,10 +6,12 @@ #include #include +#include #include "windows.h" #include "winerror.h" #include "kernel32.h" #include "task.h" +#include "pe_image.h" #include "stddebug.h" #include "debug.h" @@ -20,8 +22,13 @@ LPSTR GetCommandLineA(void) { static char buffer[256]; + char *cp; PDB *pdb = (PDB *)GlobalLock( GetCurrentPDB() ); - memcpy( buffer, &pdb->cmdLine[1], pdb->cmdLine[0] ); + + strcpy(buffer, wine_files->name); + cp = buffer+strlen(buffer); + *cp++ = ' '; + memcpy( cp, &pdb->cmdLine[1], pdb->cmdLine[0] ); dprintf_win32(stddeb,"CommandLine = %s\n", buffer ); return buffer; } diff --git a/win32/error.c b/win32/error.c index 7204884566c..242bcc02ad0 100644 --- a/win32/error.c +++ b/win32/error.c @@ -5,14 +5,100 @@ */ #include +#include #include "windows.h" #include "winerror.h" #include "kernel32.h" #include "stddebug.h" #include "debug.h" +/* WIN32_LastError contains the last error that occurred in the + * Win32 API. This value should be stored separately for each + * thread, when we eventually get thread support. + */ static int WIN32_LastError; +/* The errno_xlat_table contains the errno-to-Win32 error + * mapping. Since this is a single table, it can't easily + * take into account function-specific differences, so there + * will probably be quite a few points where we don't exactly + * match what NT would return. Then again, neither does + * Windows 95. :-) + */ +typedef struct { + int errno; + DWORD win32err; +} ERRNO_XLAT_TABLE; + +/* The table looks pretty ugly due to the preprocessor stuff, + * but I honestly have no idea how many of these values are + * portable. I'm not even sure how many of them are even + * used at all. :-) + */ +static ERRNO_XLAT_TABLE errno_xlat_table[] = { +#if defined(EPERM) + { EPERM, ERROR_ACCESS_DENIED }, +#endif +#if defined(ENOENT) + { ENOENT, ERROR_FILE_NOT_FOUND }, +#endif +#if defined(ESRCH) + { ESRCH, ERROR_INVALID_PARAMETER }, +#endif +#if defined(EIO) + { EIO, ERROR_IO_DEVICE }, +#endif +#if defined(ENOEXEC) + { ENOEXEC, ERROR_BAD_FORMAT }, +#endif +#if defined(EBADF) + { EBADF, ERROR_INVALID_HANDLE }, +#endif +#if defined(ENOMEM) + { ENOMEM, ERROR_OUTOFMEMORY }, +#endif +#if defined(EACCES) + { EACCES, ERROR_ACCESS_DENIED }, +#endif +#if defined(EBUSY) + { EBUSY, ERROR_BUSY }, +#endif +#if defined(EEXIST) + { EEXIST, ERROR_FILE_EXISTS }, +#endif +#if defined(ENODEV) + { ENODEV, ERROR_BAD_DEVICE }, +#endif +#if defined(EINVAL) + { EINVAL, ERROR_INVALID_PARAMETER }, +#endif +#if defined(EMFILE) + { EMFILE, ERROR_TOO_MANY_OPEN_FILES }, +#endif +#if defined(ETXTBSY) + { ETXTBSY, ERROR_BUSY, }, +#endif +#if defined(ENOSPC) + { ENOSPC, ERROR_DISK_FULL }, +#endif +#if defined(ESPIPE) + { ESPIPE, ERROR_SEEK_ON_DEVICE }, +#endif +#if defined(EPIPE) + { EPIPE, ERROR_BROKEN_PIPE }, +#endif +#if defined(EDEADLK) + { EDEADLK, ERROR_POSSIBLE_DEADLOCK }, +#endif +#if defined(ENAMETOOLONG) + { ENAMETOOLONG, ERROR_FILENAME_EXCED_RANGE }, +#endif +#if defined(ENOTEMPTY) + { ENOTEMPTY, ERROR_DIR_NOT_EMPTY }, +#endif + { -1, 0 } +}; + /********************************************************************** * GetLastError (KERNEL32.227) */ @@ -34,5 +120,18 @@ void SetLastError(DWORD error) DWORD ErrnoToLastError(int errno_num) { - return errno_num; /* Obviously not finished yet. :-) */ + DWORD rc = ERROR_UNKNOWN; + int i = 0; + + while(errno_xlat_table[i].errno != -1) + { + if(errno_xlat_table[i].errno == errno_num) + { + rc = errno_xlat_table[i].win32err; + break; + } + i++; + } + + return rc; } diff --git a/win32/file.c b/win32/file.c index a914e230b5c..91469641d16 100644 --- a/win32/file.c +++ b/win32/file.c @@ -1,7 +1,7 @@ /* * Win32 kernel functions * - * Copyright 1995 Martin von Loewis and Cameron Heide + * Copyright 1995 Martin von Loewis, Sven Verdoolaege, and Cameron Heide */ #include @@ -9,8 +9,10 @@ #include #include #include +#include #include #include +#include #include "windows.h" #include "winerror.h" #include "kernel32.h" @@ -25,31 +27,151 @@ extern FILE_OBJECT *hstdin; extern FILE_OBJECT *hstdout; extern FILE_OBJECT *hstderr; +static void UnixTimeToFileTime(time_t unix_time, FILETIME *filetime); static int TranslateCreationFlags(DWORD create_flags); static int TranslateAccessFlags(DWORD access_flags); /*********************************************************************** - * GetFileInformationByHandle (KERNEL32.219) + * OpenFileMappingA (KERNEL32.397) * */ -HANDLE WINAPI CreateFileA(const char * filename, DWORD a, DWORD b, void * c, - DWORD d, DWORD e, DWORD f) +WINAPI HANDLE32 OpenFileMapping(DWORD access, BOOL inherit,const char *fname) { - dprintf_win32(stderr, "CreateFileA: %s\n", filename); - return -1; + return 0; +} +/*********************************************************************** + * CreateFileMappingA (KERNEL32.46) + * + */ +WINAPI HANDLE32 CreateFileMapping(HANDLE32 h,SECURITY_ATTRIBUTES *ats, + DWORD pot, DWORD sh, DWORD hlow, const char * lpName ) +{ + FILE_OBJECT *file_obj; + FILEMAP_OBJECT *filemap_obj; + int fd; + + if (sh) + { + SetLastError(ErrnoToLastError(errno)); + return INVALID_HANDLE_VALUE; + } + fd = open(lpName, O_CREAT, 0666); + #if 0 + fd = open(DOS_GetUnixFileName(lpName), 0, 0666); + #endif + if(fd == -1) + { + SetLastError(ErrnoToLastError(errno)); + return INVALID_HANDLE_VALUE; + } + file_obj = (FILE_OBJECT *) + CreateKernelObject(sizeof(FILE_OBJECT)); + if(file_obj == NULL) + { + SetLastError(ERROR_UNKNOWN); + return 0; + } + filemap_obj = (FILEMAP_OBJECT *) + CreateKernelObject(sizeof(FILEMAP_OBJECT)); + if(filemap_obj == NULL) + { + ReleaseKernelObject(file_obj); + SetLastError(ERROR_UNKNOWN); + return 0; + } + file_obj->common.magic = KERNEL_OBJECT_FILE; + file_obj->fd = fd; + file_obj->type = FILE_TYPE_DISK; + filemap_obj->common.magic = KERNEL_OBJECT_FILEMAP; + filemap_obj->file_obj = file_obj; + filemap_obj->prot = TranslateProtectionFlags(pot); + filemap_obj->size = hlow; + return (HANDLE32)filemap_obj;; +} + +/*********************************************************************** + * MapViewOfFileEx (KERNEL32.386) + * + */ +WINAPI void *MapViewOfFileEx(HANDLE32 handle, DWORD access, DWORD offhi, + DWORD offlo, DWORD size, DWORD st) +{ + if (!size) size = ((FILEMAP_OBJECT *)handle)->size; + return mmap (st, size, ((FILEMAP_OBJECT *)handle)->prot, + MAP_ANON|MAP_PRIVATE, + ((FILEMAP_OBJECT *)handle)->file_obj->fd, + offlo); } /*********************************************************************** * GetFileInformationByHandle (KERNEL32.219) * */ -DWORD WINAPI GetFileInformationByHandle(HANDLE hFile, +DWORD WINAPI GetFileInformationByHandle(FILE_OBJECT *hFile, BY_HANDLE_FILE_INFORMATION *lpfi) { - memset(lpfi, 0, sizeof(BY_HANDLE_FILE_INFORMATION)); + struct stat file_stat; + int rc; + + if(ValidateKernelObject((HANDLE32)hFile) != 0) + { + SetLastError(ERROR_INVALID_HANDLE); + return 0; + } + if(hFile->common.magic != KERNEL_OBJECT_FILE) + { + SetLastError(ERROR_INVALID_HANDLE); + return 0; + } + + rc = fstat(hFile->fd, &file_stat); + if(rc == -1) + { + SetLastError(ErrnoToLastError(errno)); + return 0; + } + + /* Translate the file attributes. + */ + lpfi->dwFileAttributes = 0; + if(file_stat.st_mode & S_IFREG) + lpfi->dwFileAttributes |= FILE_ATTRIBUTE_NORMAL; + if(file_stat.st_mode & S_IFDIR) + lpfi->dwFileAttributes |= FILE_ATTRIBUTE_DIRECTORY; + if(file_stat.st_mode & S_IWRITE == 0) + lpfi->dwFileAttributes |= FILE_ATTRIBUTE_READONLY; + + /* Translate the file times. Use the last modification time + * for both the creation time and write time. + */ + UnixTimeToFileTime(file_stat.st_mtime, &(lpfi->ftCreationTime)); + UnixTimeToFileTime(file_stat.st_mtime, &(lpfi->ftLastWriteTime)); + UnixTimeToFileTime(file_stat.st_atime, &(lpfi->ftLastAccessTime)); + + lpfi->nFileSizeLow = file_stat.st_size; + lpfi->nNumberOfLinks = file_stat.st_nlink; + lpfi->nFileIndexLow = file_stat.st_ino; + + /* Zero out currently unused fields. + */ + lpfi->dwVolumeSerialNumber = 0; + lpfi->nFileSizeHigh = 0; + lpfi->nFileIndexHigh = 0; + return 1; } + +static void UnixTimeToFileTime(time_t unix_time, FILETIME *filetime) +{ + /* This isn't anywhere close to being correct, but should + * work for now. + */ + filetime->dwLowDateTime = (unix_time & 0x0000FFFF) << 16; + filetime->dwHighDateTime = (unix_time & 0xFFFF0000) >> 16; +} + + /*********************************************************************** * GetFileType (KERNEL32.222) * @@ -95,7 +217,7 @@ HANDLE32 GetStdHandle(DWORD nStdHandle) default: rc = INVALID_HANDLE_VALUE; - SetLastError(ERROR_UNKNOWN); + SetLastError(ERROR_INVALID_HANDLE); break; } @@ -115,12 +237,12 @@ DWORD SetFilePointer(FILE_OBJECT *hFile, LONG distance, LONG *highword, if(ValidateKernelObject((HANDLE32)hFile) != 0) { - SetLastError(ERROR_UNKNOWN); + SetLastError(ERROR_INVALID_HANDLE); return ((DWORD)0xFFFFFFFF); } if(hFile->common.magic != KERNEL_OBJECT_FILE) { - SetLastError(ERROR_UNKNOWN); + SetLastError(ERROR_INVALID_HANDLE); return ((DWORD)0xFFFFFFFF); } @@ -149,12 +271,12 @@ BOOL WriteFile(FILE_OBJECT *hFile, LPVOID lpBuffer, DWORD numberOfBytesToWrite, if(ValidateKernelObject((HANDLE32)hFile) != 0) { - SetLastError(ERROR_UNKNOWN); + SetLastError(ERROR_INVALID_HANDLE); return 0; } if(hFile->common.magic != KERNEL_OBJECT_FILE) { - SetLastError(ERROR_UNKNOWN); + SetLastError(ERROR_INVALID_HANDLE); return 0; } @@ -175,12 +297,12 @@ BOOL ReadFile(FILE_OBJECT *hFile, LPVOID lpBuffer, DWORD numtoread, if(ValidateKernelObject((HANDLE32)hFile) != 0) { - SetLastError(ERROR_UNKNOWN); + SetLastError(ERROR_INVALID_HANDLE); return 0; } if(hFile->common.magic != KERNEL_OBJECT_FILE) { - SetLastError(ERROR_UNKNOWN); + SetLastError(ERROR_INVALID_HANDLE); return 0; } @@ -199,11 +321,12 @@ BOOL ReadFile(FILE_OBJECT *hFile, LPVOID lpBuffer, DWORD numtoread, /************************************************************************* * CreateFile (KERNEL32.45) * - * Doesn't support character devices or pipes yet. + * Doesn't support character devices, pipes, template files, or a + * lot of the 'attributes' flags yet. */ -HANDLE32 CreateFile(LPSTR filename, DWORD access, DWORD sharing, - LPSECURITY_ATTRIBUTES security, DWORD creation, - DWORD attributes, HANDLE32 template) +HANDLE32 CreateFileA(LPSTR filename, DWORD access, DWORD sharing, + LPSECURITY_ATTRIBUTES security, DWORD creation, + DWORD attributes, HANDLE32 template) { int access_flags, create_flags; int fd; @@ -216,7 +339,7 @@ HANDLE32 CreateFile(LPSTR filename, DWORD access, DWORD sharing, create_flags = TranslateCreationFlags(creation); if(template) - printf("CreateFile: template handles not supported.\n"); + dprintf_win32(stddeb, "CreateFile: template handles not supported.\n"); /* If the name starts with '\\?' or '\\.', ignore the first 3 chars. */ @@ -227,7 +350,7 @@ HANDLE32 CreateFile(LPSTR filename, DWORD access, DWORD sharing, */ if(!strncmp(filename, "\\\\", 2)) { - printf("CreateFile: UNC names not supported.\n"); + dprintf_win32(stddeb, "CreateFile: UNC names not supported.\n"); SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return INVALID_HANDLE_VALUE; } @@ -266,7 +389,7 @@ HANDLE32 CreateFile(LPSTR filename, DWORD access, DWORD sharing, file_obj = (FILE_OBJECT *)CreateKernelObject(sizeof(FILE_OBJECT)); if(file_obj == NULL) { - SetLastError(ERROR_UNKNOWN); + SetLastError(ERROR_INVALID_HANDLE); return INVALID_HANDLE_VALUE; } file_obj->common.magic = KERNEL_OBJECT_FILE; diff --git a/win32/init.c b/win32/init.c index b4d3f0dfb83..d2e89369d87 100644 --- a/win32/init.c +++ b/win32/init.c @@ -12,6 +12,7 @@ #include "kernel32.h" #include "handle32.h" #include "stddebug.h" +#define DEBUG_WIN32 #include "debug.h" /* The global error value @@ -48,7 +49,7 @@ BOOL CloseHandle(HANDLE32 handle) break; default: - printf("CloseHandle: type %ld not implemented yet.\n", + dprintf_win32(stddeb, "CloseHandle: type %ld not implemented yet.\n", handle->magic); break; } diff --git a/win32/memory.c b/win32/memory.c index 2ee8eb5060e..78b04fef20a 100644 --- a/win32/memory.c +++ b/win32/memory.c @@ -17,6 +17,10 @@ #include "stddebug.h" #include "debug.h" +#ifndef PROT_NONE /* FreeBSD doesn't define PROT_NONE */ +#define PROT_NONE 0 +#endif + typedef struct { caddr_t ptr; long size; @@ -72,33 +76,8 @@ LPVOID VirtualAlloc(LPVOID lpvAddress, DWORD cbSize, ptr = lpvAddress; } if (fdwAllocationType & MEM_COMMIT) { - switch(fdwProtect & ~(PAGE_GUARD | PAGE_NOCACHE)) { - case PAGE_READONLY: - prot=PROT_READ; - break; - case PAGE_READWRITE: - prot=PROT_READ|PROT_WRITE; - break; - case PAGE_WRITECOPY: - prot=PROT_WRITE; - break; - case PAGE_EXECUTE: - prot=PROT_EXEC; - break; - case PAGE_EXECUTE_READ: - prot=PROT_EXEC|PROT_READ; - break; - case PAGE_EXECUTE_READWRITE: - prot=PROT_EXEC|PROT_READ|PROT_WRITE; - break; - case PAGE_EXECUTE_WRITECOPY: - prot=PROT_EXEC|PROT_WRITE; - break; - case PAGE_NOACCESS: - default: - prot=PROT_NONE; - break; - } + prot = TranslateProtectionFlags(fdwProtect & + ~(PAGE_GUARD | PAGE_NOCACHE)); mprotect(ptr, cbSize, prot); } return ptr; @@ -144,3 +123,36 @@ BOOL VirtualFree(LPVOID lpvAddress, DWORD cbSize, DWORD fdwFreeType) return 1; } +int TranslateProtectionFlags(DWORD protection_flags) +{ + int prot; + + switch(protection_flags) { + case PAGE_READONLY: + prot=PROT_READ; + break; + case PAGE_READWRITE: + prot=PROT_READ|PROT_WRITE; + break; + case PAGE_WRITECOPY: + prot=PROT_WRITE; + break; + case PAGE_EXECUTE: + prot=PROT_EXEC; + break; + case PAGE_EXECUTE_READ: + prot=PROT_EXEC|PROT_READ; + break; + case PAGE_EXECUTE_READWRITE: + prot=PROT_EXEC|PROT_READ|PROT_WRITE; + break; + case PAGE_EXECUTE_WRITECOPY: + prot=PROT_EXEC|PROT_WRITE; + break; + case PAGE_NOACCESS: + default: + prot=PROT_NONE; + break; + } + return prot; +} diff --git a/win32/object_mgt.c b/win32/object_mgt.c index 668a13a0836..07a6ed463a3 100644 --- a/win32/object_mgt.c +++ b/win32/object_mgt.c @@ -14,6 +14,6 @@ int ValidateKernelObject(KERNEL_OBJECT *ptr) { - return 0; + return (!ptr || (short int)ptr==-1); } diff --git a/win32/process.c b/win32/process.c index 3773dbbfdda..8fb8fe4c5b7 100644 --- a/win32/process.c +++ b/win32/process.c @@ -9,6 +9,7 @@ #include "windows.h" #include "winerror.h" #include "kernel32.h" +#include "handle32.h" #include "stddebug.h" #include "debug.h" @@ -21,3 +22,63 @@ void ExitProcess(DWORD status) exit(status); } +/*********************************************************************** + * CreateMutexA (KERNEL32.52) + */ +WINAPI HANDLE32 CreateMutexA (SECURITY_ATTRIBUTES *sa, BOOL on, const char *a) +{ + return 0; +} + +/*********************************************************************** + * ReleaseMutex (KERNEL32.435) + */ +WINAPI BOOL ReleaseMutex (HANDLE32 h) +{ + return 0; +} + +/*********************************************************************** + * CreateEventA (KERNEL32.43) + */ +WINAPI HANDLE32 CreateEventA (SECURITY_ATTRIBUTES *sa, BOOL au, BOOL on, const char +*name) +{ + return 0; +} +/*********************************************************************** + * SetEvent (KERNEL32.487) + */ +WINAPI BOOL SetEvent (HANDLE32 h) +{ + return 0; +} +/*********************************************************************** + * ResetEvent (KERNEL32.439) + */ +WINAPI BOOL ResetEvent (HANDLE32 h) +{ + return 0; +} +/*********************************************************************** + * WaitForSingleObject (KERNEL32.561) + */ +DWORD WINAPI WaitForSingleObject(HANDLE32 h, DWORD a) +{ + return 0; +} +/*********************************************************************** + * DuplicateHandle (KERNEL32.78) + */ +BOOL WINAPI DuplicateHandle(HANDLE32 a, HANDLE32 b, HANDLE32 c, HANDLE32 * d, DWORD e, BOOL f, DWORD g) +{ + *d = b; + return 1; +} +/*********************************************************************** + * GetCurrentProcess (KERNEL32.198) + */ +HANDLE32 WINAPI GetCurrentProcess(void) +{ + return 0; +} diff --git a/win32/thread.c b/win32/thread.c index ec77af59dbc..c88dda42e92 100644 --- a/win32/thread.c +++ b/win32/thread.c @@ -28,4 +28,11 @@ BOOL GetThreadContext(HANDLE hThread, void *lpContext) { return FALSE; } +/*********************************************************************** + * GetCurrentThread (KERNEL32.200) + */ +HANDLE WINAPI GetCurrentThread(void) +{ + return 0; +} diff --git a/win32/time.c b/win32/time.c index 29b20ba8356..04d6780d682 100644 --- a/win32/time.c +++ b/win32/time.c @@ -6,6 +6,7 @@ #include #include +#include #include #include "windows.h" #include "winerror.h" @@ -13,6 +14,29 @@ #include "stddebug.h" #include "debug.h" +/*********************************************************************** + * GetLocalTime (KERNEL32.228) + */ +VOID GetLocalTime(LPSYSTEMTIME systime) +{ + time_t local_time; + struct tm *local_tm; + struct timeval tv; + + time(&local_time); + local_tm = localtime(&local_time); + gettimeofday(&tv, NULL); + + systime->wYear = local_tm->tm_year + 1900; + systime->wMonth = local_tm->tm_mon + 1; + systime->wDayOfWeek = local_tm->tm_wday; + systime->wDay = local_tm->tm_mday; + systime->wHour = local_tm->tm_hour; + systime->wMinute = local_tm->tm_min; + systime->wSecond = local_tm->tm_sec; + systime->wMilliseconds = (tv.tv_usec / 1000) % 1000; +} + /*********************************************************************** * GetTimeZoneInformation (KERNEL32.302) */ diff --git a/windows/dce.c b/windows/dce.c index 7cb9df33138..15ea23276c2 100644 --- a/windows/dce.c +++ b/windows/dce.c @@ -184,7 +184,7 @@ static HRGN DCE_ClipWindows( HWND hwndStart, HWND hwndEnd, * clipped by the client area of all ancestors, and then optionally * by siblings and children. */ -static HRGN DCE_GetVisRgn( HWND hwnd, WORD flags ) +HRGN DCE_GetVisRgn( HWND hwnd, WORD flags ) { RECT rect; HRGN hrgn; diff --git a/windows/defwnd.c b/windows/defwnd.c index 786c0a712ef..bc901b046ea 100644 --- a/windows/defwnd.c +++ b/windows/defwnd.c @@ -39,6 +39,8 @@ void DEFWND_SetText( HWND hwnd, LPSTR text ) wndPtr->hText = USER_HEAP_ALLOC( strlen(text) + 1 ); textPtr = (LPSTR) USER_HEAP_LIN_ADDR( wndPtr->hText ); strcpy( textPtr, text ); + if (wndPtr->window) + XStoreName( display, wndPtr->window, text ); } diff --git a/windows/event.c b/windows/event.c index 28f21e1f43c..301e91fd8a5 100644 --- a/windows/event.c +++ b/windows/event.c @@ -18,6 +18,7 @@ #include "class.h" #include "message.h" #include "clipboard.h" +#include "options.h" #include "winpos.h" #include "registers.h" #include "stackframe.h" @@ -137,6 +138,7 @@ static void EVENT_key( XKeyEvent *event ); static void EVENT_ButtonPress( XButtonEvent *event ); static void EVENT_ButtonRelease( XButtonEvent *event ); static void EVENT_MotionNotify( XMotionEvent *event ); +static void EVENT_FocusIn( HWND hwnd, XFocusChangeEvent *event ); static void EVENT_FocusOut( HWND hwnd, XFocusChangeEvent *event ); static void EVENT_Expose( HWND hwnd, XExposeEvent *event ); static void EVENT_ConfigureNotify( HWND hwnd, XConfigureEvent *event ); @@ -190,6 +192,10 @@ void EVENT_ProcessEvent( XEvent *event ) EVENT_MotionNotify( (XMotionEvent*)event ); break; + case FocusIn: + EVENT_FocusIn( hwnd, (XFocusChangeEvent*)event ); + break; + case FocusOut: EVENT_FocusOut( hwnd, (XFocusChangeEvent*)event ); break; @@ -454,6 +460,17 @@ static void EVENT_ButtonRelease( XButtonEvent *event ) } +/********************************************************************** + * EVENT_FocusIn + */ +static void EVENT_FocusIn (HWND hwnd, XFocusChangeEvent *event ) +{ + if (event->detail == NotifyPointer) return; + if (hwnd != GetActiveWindow()) WINPOS_ChangeActiveWindow( hwnd, FALSE ); + if ((hwnd != GetFocus()) && ! IsChild( hwnd, GetFocus())) SetFocus( hwnd ); +} + + /********************************************************************** * EVENT_FocusOut * @@ -470,12 +487,70 @@ static void EVENT_FocusOut( HWND hwnd, XFocusChangeEvent *event ) /********************************************************************** * EVENT_ConfigureNotify * - * The ConfigureNotify event is only selected on the desktop window. + * The ConfigureNotify event is only selected on the desktop window + * and on top-level windows when the -managed flag is used. */ static void EVENT_ConfigureNotify( HWND hwnd, XConfigureEvent *event ) { - desktopX = event->x; - desktopY = event->y; + if (hwnd == GetDesktopWindow()) + { + desktopX = event->x; + desktopY = event->y; + } + else + { + /* A managed window; most of this code is shamelessly + * stolen from SetWindowPos + */ + + WND *wndPtr; + WINDOWPOS winpos; + RECT newWindowRect, newClientRect; + + if (!(wndPtr = WIN_FindWndPtr( hwnd ))) + { + dprintf_event(stddeb, "ConfigureNotify: invalid HWND "NPFMT"\n", hwnd); + return; + } + + /* Artificial messages */ + SendMessage(hwnd, WM_ENTERSIZEMOVE, 0, 0); + SendMessage(hwnd, WM_EXITSIZEMOVE, 0, 0); + + /* Fill WINDOWPOS struct */ + winpos.flags = SWP_NOACTIVATE | SWP_NOZORDER; + winpos.hwnd = hwnd; + winpos.x = event->x; + winpos.y = event->y; + winpos.cx = event->width; + winpos.cy = event->height; + + /* Check for unchanged attributes */ + if(winpos.x == wndPtr->rectWindow.left && + winpos.y == wndPtr->rectWindow.top) + winpos.flags |= SWP_NOMOVE; + if(winpos.cx == wndPtr->rectWindow.right - wndPtr->rectWindow.left && + winpos.cy == wndPtr->rectWindow.bottom - wndPtr->rectWindow.top) + winpos.flags |= SWP_NOSIZE; + + /* Send WM_WINDOWPOSCHANGING */ + SendMessage(hwnd, WM_WINDOWPOSCHANGING, 0, MAKE_SEGPTR(&winpos)); + + /* Calculate new position and size */ + newWindowRect.left = event->x; + newWindowRect.right = event->x + event->width; + newWindowRect.top = event->y; + newWindowRect.bottom = event->y + event->height; + + WINPOS_SendNCCalcSize( winpos.hwnd, TRUE, &newWindowRect, + &wndPtr->rectWindow, &wndPtr->rectClient, + &winpos, &newClientRect ); + + /* Set new size and position */ + wndPtr->rectWindow = newWindowRect; + wndPtr->rectClient = newClientRect; + SendMessage(hwnd, WM_WINDOWPOSCHANGED, 0, MAKE_SEGPTR(&winpos)); + } } diff --git a/windows/focus.c b/windows/focus.c index 141bedeb5fe..6e8e46a1297 100644 --- a/windows/focus.c +++ b/windows/focus.c @@ -2,16 +2,18 @@ * Focus functions * * Copyright 1993 David Metcalfe - * Copyright 1994 Alexandre Julliard + * 1994 Alexandre Julliard + * 1995 Alex Korobka * -static char Copyright[] = "Copyright David Metcalfe, 1993"; -static char Copyright2[] = "Copyright Alexandre Julliard, 1994"; -*/ + */ #include "win.h" +#include "winpos.h" +#include "hook.h" #include "color.h" -static HWND hWndFocus = 0; + +static HWND hwndFocus = 0; /***************************************************************** * FOCUS_SetXFocus @@ -44,53 +46,67 @@ static void FOCUS_SetXFocus( HWND hwnd ) XInstallColormap( display, COLOR_WinColormap ); } +/***************************************************************** + * FOCUS_SwitchFocus + */ +void FOCUS_SwitchFocus(HWND hFocusFrom, HWND hFocusTo) +{ + hwndFocus = hFocusTo; + + if (hFocusFrom) SendMessage( hFocusFrom, WM_KILLFOCUS, hFocusTo, 0L); + if( !hFocusTo || hFocusTo != hwndFocus ) + return; + + SendMessage( hFocusTo, WM_SETFOCUS, hFocusFrom, 0L); + FOCUS_SetXFocus( hFocusTo ); +} + /***************************************************************** * SetFocus (USER.22) */ - HWND SetFocus(HWND hwnd) { - HWND hWndPrevFocus, hwndParent; - WND *wndPtr; + HWND hWndPrevFocus, hwndTop; + WND *wndPtr = WIN_FindWndPtr( hwndTop = hwnd ); - if (hwnd == hWndFocus) return hWndFocus; /* Nothing to do! */ - - if (hwnd) + if (wndPtr) { /* Check if we can set the focus to this window */ - hwndParent = hwnd; - while ((wndPtr = WIN_FindWndPtr( hwndParent )) != NULL) + while ( (wndPtr->dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD ) { - if ((wndPtr->dwStyle & WS_MINIMIZE) || - (wndPtr->dwStyle & WS_DISABLED)) return 0; - if (!(wndPtr->dwStyle & WS_CHILD)) break; - hwndParent = wndPtr->hwndParent; + if ( wndPtr->dwStyle & ( WS_MINIMIZE | WS_DISABLED) ) + return 0; + + hwndTop = wndPtr->hwndParent; + wndPtr = WIN_FindWndPtr( hwndTop ); + if ( !wndPtr ) + return 0; } - /* Now hwndParent is the top-level ancestor. Activate it. */ + if( hwnd == hwndFocus ) return hwnd; - if (hwndParent != GetActiveWindow()) + /* call hooks */ + if( HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, hwnd, hwndFocus) ) + return 0; + + /* activate hwndTop if needed. */ + if (hwndTop != GetActiveWindow()) { - SetWindowPos( hwndParent, HWND_TOP, 0, 0, 0, 0, - SWP_NOSIZE | SWP_NOMOVE ); + if (!WINPOS_SetActiveWindow(hwndTop, 0, 0)) return 0; + if (!IsWindow( hwnd )) return 0; /* Abort if window destroyed */ } } + else if( HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, 0, hwndFocus ) ) + return 0; /* Change focus and send messages */ + hWndPrevFocus = hwndFocus; + + FOCUS_SwitchFocus( hwndFocus , hwnd ); - hWndPrevFocus = hWndFocus; - hWndFocus = hwnd; - if (hWndPrevFocus) SendMessage( hWndPrevFocus, WM_KILLFOCUS, - (WPARAM)hwnd, 0 ); - if (hwnd == hWndFocus) /* Maybe already changed during WM_KILLFOCUS */ - { - if (hwnd) SendMessage( hWndFocus, WM_SETFOCUS, - (WPARAM)hWndPrevFocus, 0 ); - FOCUS_SetXFocus( hwnd ); - } return hWndPrevFocus; } @@ -98,10 +114,9 @@ HWND SetFocus(HWND hwnd) /***************************************************************** * GetFocus (USER.23) */ - HWND GetFocus(void) { - return hWndFocus; + return hwndFocus; } diff --git a/windows/graphics.c b/windows/graphics.c index d4475ba0bf8..517d74bff63 100644 --- a/windows/graphics.c +++ b/windows/graphics.c @@ -23,15 +23,6 @@ #include "debug.h" #include "xmalloc.h" -static __inline__ void swap_int(int *a, int *b) -{ - int c; - - c = *a; - *a = *b; - *b = c; -} - /*********************************************************************** * LineTo (GDI.19) */ @@ -108,7 +99,7 @@ BOOL MoveToEx( HDC hdc, short x, short y, LPPOINT pt ) static BOOL GRAPH_DrawArc( HDC hdc, int left, int top, int right, int bottom, int xstart, int ystart, int xend, int yend, int lines ) { - int xcenter, ycenter, istart_angle, idiff_angle; + int xcenter, ycenter, istart_angle, idiff_angle, tmp; double start_angle, end_angle; XPoint points[3]; DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); @@ -155,8 +146,8 @@ static BOOL GRAPH_DrawArc( HDC hdc, int left, int top, int right, int bottom, istart_angle = (int)(start_angle * 180 * 64 / PI); idiff_angle = (int)((end_angle - start_angle) * 180 * 64 / PI ); if (idiff_angle <= 0) idiff_angle += 360 * 64; - if (left > right) swap_int( &left, &right ); - if (top > bottom) swap_int( &top, &bottom ); + if (left > right) { tmp=left; left=right; right=tmp; } + if (top > bottom) { tmp=top; top=bottom; bottom=tmp; } /* Fill arc with brush if Chord() or Pie() */ @@ -195,8 +186,8 @@ static BOOL GRAPH_DrawArc( HDC hdc, int left, int top, int right, int bottom, /*********************************************************************** * Arc (GDI.23) */ -BOOL Arc( HDC hdc, int left, int top, int right, int bottom, - int xstart, int ystart, int xend, int yend ) +BOOL Arc( HDC hdc, INT left, INT top, INT right, INT bottom, + INT xstart, INT ystart, INT xend, INT yend ) { return GRAPH_DrawArc( hdc, left, top, right, bottom, xstart, ystart, xend, yend, 0 ); @@ -206,8 +197,8 @@ BOOL Arc( HDC hdc, int left, int top, int right, int bottom, /*********************************************************************** * Pie (GDI.26) */ -BOOL Pie( HDC hdc, int left, int top, int right, int bottom, - int xstart, int ystart, int xend, int yend ) +BOOL Pie( HDC hdc, INT left, INT top, INT right, INT bottom, + INT xstart, INT ystart, INT xend, INT yend ) { return GRAPH_DrawArc( hdc, left, top, right, bottom, xstart, ystart, xend, yend, 2 ); @@ -217,8 +208,8 @@ BOOL Pie( HDC hdc, int left, int top, int right, int bottom, /*********************************************************************** * Chord (GDI.348) */ -BOOL Chord( HDC hdc, int left, int top, int right, int bottom, - int xstart, int ystart, int xend, int yend ) +BOOL Chord( HDC hdc, INT left, INT top, INT right, INT bottom, + INT xstart, INT ystart, INT xend, INT yend ) { return GRAPH_DrawArc( hdc, left, top, right, bottom, xstart, ystart, xend, yend, 1 ); @@ -228,7 +219,7 @@ BOOL Chord( HDC hdc, int left, int top, int right, int bottom, /*********************************************************************** * Ellipse (GDI.24) */ -BOOL Ellipse( HDC hdc, int left, int top, int right, int bottom ) +BOOL Ellipse( HDC hdc, INT left, INT top, INT right, INT bottom ) { DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); if (!dc) @@ -245,11 +236,8 @@ BOOL Ellipse( HDC hdc, int left, int top, int right, int bottom ) bottom = YLPTODP( dc, bottom ); if ((left == right) || (top == bottom)) return FALSE; - if (right < left) - swap_int(&right, &left); - - if (bottom < top) - swap_int(&bottom, &top); + if (right < left) { INT tmp = right; right = left; left = tmp; } + if (bottom < top) { INT tmp = bottom; bottom = top; top = tmp; } if ((dc->u.x.pen.style == PS_INSIDEFRAME) && (dc->u.x.pen.width < right-left-1) && @@ -276,7 +264,7 @@ BOOL Ellipse( HDC hdc, int left, int top, int right, int bottom ) /*********************************************************************** * Rectangle (GDI.27) */ -BOOL Rectangle( HDC hdc, int left, int top, int right, int bottom ) +BOOL Rectangle( HDC hdc, INT left, INT top, INT right, INT bottom ) { DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); if (!dc) @@ -291,11 +279,8 @@ BOOL Rectangle( HDC hdc, int left, int top, int right, int bottom ) right = XLPTODP( dc, right ); bottom = YLPTODP( dc, bottom ); - if (right < left) - swap_int(&right, &left); - - if (bottom < top) - swap_int(&bottom, &top); + if (right < left) { INT tmp = right; right = left; left = tmp; } + if (bottom < top) { INT tmp = bottom; bottom = top; top = tmp; } if ((left == right) || (top == bottom)) { @@ -333,8 +318,8 @@ BOOL Rectangle( HDC hdc, int left, int top, int right, int bottom ) /*********************************************************************** * RoundRect (GDI.28) */ -BOOL RoundRect( HDC hDC, short left, short top, short right, short bottom, - short ell_width, short ell_height ) +BOOL RoundRect( HDC hDC, INT left, INT top, INT right, INT bottom, + INT ell_width, INT ell_height ) { DC * dc = (DC *) GDI_GetObjPtr(hDC, DC_MAGIC); if (!dc) @@ -357,8 +342,8 @@ BOOL RoundRect( HDC hDC, short left, short top, short right, short bottom, /* Fix the coordinates */ - if (left > right) { short t = left; left = right; right = t; } - if (top > bottom) { short t = top; top = bottom; bottom = t; } + if (right < left) { INT tmp = right; right = left; left = tmp; } + if (bottom < top) { INT tmp = bottom; bottom = top; top = tmp; } if (ell_width > right - left) ell_width = right - left; if (ell_height > bottom - top) ell_height = bottom - top; diff --git a/windows/keyboard.c b/windows/keyboard.c index 7610ae9edb2..c8c0e537e83 100644 --- a/windows/keyboard.c +++ b/windows/keyboard.c @@ -17,16 +17,16 @@ extern BYTE AsyncKeyStateTable[256]; */ int GetKeyState(int keycode) { - switch(keycode) { - case VK_LBUTTON: - return MouseButtonsStates[0]; - case VK_MBUTTON: - return MouseButtonsStates[1]; - case VK_RBUTTON: - return MouseButtonsStates[2]; - default: - return KeyStateTable[keycode]; - } + switch(keycode) { + case VK_LBUTTON: + return MouseButtonsStates[0]; + case VK_MBUTTON: + return MouseButtonsStates[1]; + case VK_RBUTTON: + return MouseButtonsStates[2]; + default: + return KeyStateTable[keycode]; + } } /********************************************************************** @@ -47,13 +47,14 @@ void GetKeyboardState(BYTE FAR *lpKeyState) */ void SetKeyboardState(BYTE FAR *lpKeyState) { - if (lpKeyState != NULL) { + if (lpKeyState != NULL) { memcpy(KeyStateTable, lpKeyState, 256); MouseButtonsStates[0] = KeyStateTable[VK_LBUTTON]; MouseButtonsStates[1] = KeyStateTable[VK_MBUTTON]; MouseButtonsStates[2] = KeyStateTable[VK_RBUTTON]; - } + } } + /********************************************************************** * GetAsyncKeyState (USER.249) * @@ -69,31 +70,30 @@ void SetKeyboardState(BYTE FAR *lpKeyState) */ int GetAsyncKeyState(int nKey) { - short retval; + short retval; - switch (nKey) { + switch (nKey) { + case VK_LBUTTON: + retval = AsyncMouseButtonsStates[0] | + (MouseButtonsStates[0] << 8); + break; + case VK_MBUTTON: + retval = AsyncMouseButtonsStates[1] | + (MouseButtonsStates[1] << 8); + break; + case VK_RBUTTON: + retval = AsyncMouseButtonsStates[2] | + (MouseButtonsStates[2] << 8); + break; + default: + retval = AsyncKeyStateTable[nKey] | + (KeyStateTable[nKey] << 8); + break; + } - case VK_LBUTTON: - retval = AsyncMouseButtonsStates[0] | - (MouseButtonsStates[0] << 8); - break; - case VK_MBUTTON: - retval = AsyncMouseButtonsStates[1] | - (MouseButtonsStates[1] << 8); - break; - case VK_RBUTTON: - retval = AsyncMouseButtonsStates[2] | - (MouseButtonsStates[2] << 8); - break; - default: - retval = AsyncKeyStateTable[nKey] | - (KeyStateTable[nKey] << 8); - break; - } + bzero(AsyncMouseButtonsStates, 3); /* all states to false */ + bzero(AsyncKeyStateTable, 256); - bzero(AsyncMouseButtonsStates, 3); /* all states to false */ - bzero(AsyncKeyStateTable, 256); - - return retval; + return retval; } diff --git a/windows/mdi.c b/windows/mdi.c index e1a3ddfab2a..0fe19aa4479 100644 --- a/windows/mdi.c +++ b/windows/mdi.c @@ -1,10 +1,20 @@ /* MDI.C * * Copyright 1994, Bob Amstadt + * 1995, Alex Korobka * * This file contains routines to support MDI features. + * + * Notes: Windows keeps ID of MDI menu item in the wIDenu field + * of corresponding MDI child. + * + * Basic child activation routine is MDI_ChildActivate and + * SetWindowPos(childHwnd,...) implicitly calls it if SWP_NOACTIVATE i + * is not used. */ + #include +#include #include #include #include "windows.h" @@ -17,49 +27,167 @@ #include "stddebug.h" #include "debug.h" -/********************************************************************** - * MDIRecreateMenuList +void ScrollChildren(HWND , UINT , WPARAM , LPARAM ); +void CalcChildScroll(HWND, WORD); + +/* ----------------- declarations ----------------- */ + +static LONG MDI_ChildActivate(WND* ,HWND ); + +/* -------- Miscellaneous service functions ---------- + * + * MDI_GetChildByID */ -void MDIRecreateMenuList(MDICLIENTINFO *ci) + +static HWND MDI_GetChildByID(WND* mdiClient,int id) { - HLOCAL hinfo; + HWND hWnd = mdiClient->hwndChild; + WND* wndPtr = WIN_FindWndPtr( hWnd ); - char buffer[128]; - int id, n, index; + if( !wndPtr ) return 0; - dprintf_mdi(stddeb, "MDIRecreateMenuList: hWindowMenu "NPFMT"\n", - ci->hWindowMenu); - - id = ci->idFirstChild; - while (DeleteMenu(ci->hWindowMenu, id, MF_BYCOMMAND)) - id++; + while( wndPtr ) + { + if( wndPtr->wIDmenu == id ) return hWnd; + wndPtr = WIN_FindWndPtr(hWnd = wndPtr->hwndNext); + } - dprintf_mdi(stddeb, "MDIRecreateMenuList: id %04x, idFirstChild %04x\n", - id, ci->idFirstChild); - - if (!ci->flagMenuAltered) - { - ci->flagMenuAltered = TRUE; - AppendMenu(ci->hWindowMenu, MF_SEPARATOR, 0, NULL); - } - - id = ci->idFirstChild; - index = 1; - for (hinfo = ci->infoActiveChildren; hinfo != 0;) - { - MDICHILDINFO *chi = USER_HEAP_LIN_ADDR(hinfo); - - n = sprintf(buffer, "%d ", index++); - GetWindowText(chi->hwnd, buffer + n, sizeof(buffer) - n - 1); - - dprintf_mdi(stddeb, "MDIRecreateMenuList: id %04x, '%s'\n", - id, buffer); - - AppendMenu(ci->hWindowMenu, MF_STRING, id++, buffer); - hinfo = chi->next; - } + return 0; } +/********************************************************************** + * MDI_MenuAppendItem + */ +static BOOL MDI_MenuAppendItem(WND *clientWnd, HWND hWndChild) +{ + char buffer[128]; + MDICLIENTINFO *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra; + WND *wndPtr = WIN_FindWndPtr(hWndChild); + LPSTR lpWndText = (LPSTR) USER_HEAP_LIN_ADDR(wndPtr->hText); + int n = sprintf(buffer, "%d ", + clientInfo->nActiveChildren); + + if( !clientInfo->hWindowMenu ) return 0; + + if( lpWndText ) + strncpy(buffer + n, lpWndText, sizeof(buffer) - n - 1); + return AppendMenu(clientInfo->hWindowMenu,MF_STRING, + wndPtr->wIDmenu,(LPSTR)buffer); +} + +/********************************************************************** + * MDI_MenuModifyItem + */ +static BOOL MDI_MenuModifyItem(WND* clientWnd, HWND hWndChild ) +{ + char buffer[128]; + MDICLIENTINFO *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra; + WND *wndPtr = WIN_FindWndPtr(hWndChild); + LPSTR lpWndText = (LPSTR) USER_HEAP_LIN_ADDR(wndPtr->hText); + UINT n = sprintf(buffer, "%d ", + wndPtr->wIDmenu - clientInfo->idFirstChild + 1); + BOOL bRet = 0; + + if( !clientInfo->hWindowMenu ) return 0; + + if( lpWndText ) + strncpy(buffer + n, lpWndText, sizeof(buffer) - n - 1); + + n = GetMenuState(clientInfo->hWindowMenu,wndPtr->wIDmenu ,MF_BYCOMMAND); + bRet = ModifyMenu(clientInfo->hWindowMenu , wndPtr->wIDmenu , + MF_BYCOMMAND | MF_STRING, wndPtr->wIDmenu ,(LPSTR)buffer ); + CheckMenuItem(clientInfo->hWindowMenu ,wndPtr->wIDmenu , n & MF_CHECKED); + return bRet; +} + +/********************************************************************** + * MDI_MenuDeleteItem + */ +static BOOL MDI_MenuDeleteItem(WND* clientWnd, HWND hWndChild ) +{ + char buffer[128]; + MDICLIENTINFO *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra; + WND *wndPtr = WIN_FindWndPtr(hWndChild); + LPSTR lpWndText; + INT index = 0,id,n; + + if( !clientInfo->nActiveChildren || + !clientInfo->hWindowMenu ) return 0; + + id = wndPtr->wIDmenu; + DeleteMenu(clientInfo->hWindowMenu,id,MF_BYCOMMAND); + + /* walk the rest of MDI children to prevent gaps in the id + * sequence and in the menu child list + */ + + for( index = id+1; index <= clientInfo->nActiveChildren + + clientInfo->idFirstChild; index++ ) + { + wndPtr = WIN_FindWndPtr(MDI_GetChildByID(clientWnd,index)); + if( !wndPtr ) + { + dprintf_mdi(stddeb,"MDIMenuDeleteItem: no window for id=%i\n",index); + continue; + } + + /* set correct id */ + wndPtr->wIDmenu--; + + n = sprintf(buffer, "%d ",index - clientInfo->idFirstChild); + lpWndText = (LPSTR) USER_HEAP_LIN_ADDR(wndPtr->hText); + + if( lpWndText ) + strncpy(buffer + n, lpWndText, sizeof(buffer) - n - 1); + + /* change menu */ + ModifyMenu(clientInfo->hWindowMenu ,index ,MF_BYCOMMAND | MF_STRING, + index - 1 ,(LPSTR)buffer ); + } + return 1; +} + +/********************************************************************** + * MDI_GetWindow + * + * returns "activateable" child or zero + */ +HWND MDI_GetWindow(WND *clientWnd, HWND hWnd, WORD wTo ) +{ + HWND hWndNext; + MDICLIENTINFO *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra; + WND *wndPtr; + + if( !hWnd ) hWnd = clientInfo->hwndActiveChild; + + if( !(wndPtr = WIN_FindWndPtr(hWnd)) ) return 0; + + hWndNext = hWnd; + wTo = wTo ? GW_HWNDPREV : GW_HWNDNEXT; + + while( hWndNext ) + { + if( clientWnd->hwndChild == hWndNext && wTo == GW_HWNDPREV ) + hWndNext = GetWindow( hWndNext, GW_HWNDLAST); + else if( wndPtr->hwndNext == 0 && wTo == GW_HWNDNEXT ) + hWndNext = clientWnd->hwndChild; + else + hWndNext = GetWindow( hWndNext, wTo ); + + wndPtr = WIN_FindWndPtr( hWndNext ); + + if( (wndPtr->dwStyle & WS_VISIBLE) && + !(wndPtr->dwStyle & WS_DISABLED) ) + break; + + /* check if all windows were iterated through */ + if( hWndNext == hWnd ) break; + } + + return ( hWnd == hWndNext )? 0 : hWndNext; +} + + /********************************************************************** * MDISetMenu * FIXME: This is not complete. @@ -94,7 +222,9 @@ HWND MDICreateChild(WND *w, MDICLIENTINFO *ci, HWND parent, LPARAM lParam ) { MDICREATESTRUCT *cs = (MDICREATESTRUCT *)PTR_SEG_TO_LIN(lParam); HWND hwnd; + WORD wIDmenu = ci->idFirstChild + ci->nActiveChildren; int spacing; + char chDef = '\0'; /* * Create child window @@ -107,133 +237,68 @@ HWND MDICreateChild(WND *w, MDICLIENTINFO *ci, HWND parent, LPARAM lParam ) cs->x = ci->nActiveChildren * spacing; cs->y = ci->nActiveChildren * spacing; + /* this menu is needed to set a check mark in MDI_ChildActivate */ + AppendMenu(ci->hWindowMenu ,MF_STRING ,wIDmenu, (LPSTR)&chDef); + hwnd = CreateWindow( cs->szClass, cs->szTitle, WS_CHILD | WS_BORDER | WS_CAPTION | WS_CLIPSIBLINGS | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SYSMENU | WS_THICKFRAME | WS_VISIBLE | cs->style, - cs->x, cs->y, cs->cx, cs->cy, parent, (HMENU) 0, - w->hInstance, (SEGPTR)lParam); + cs->x, cs->y, cs->cx, cs->cy, parent, + (HMENU) wIDmenu, w->hInstance, (SEGPTR)lParam); if (hwnd) { - HANDLE h = USER_HEAP_ALLOC( sizeof(MDICHILDINFO) ); - MDICHILDINFO *child_info = USER_HEAP_LIN_ADDR(h); - - if (!h) - { - DestroyWindow(hwnd); - return 0; - } - ci->nActiveChildren++; + MDI_MenuModifyItem(w ,hwnd); - child_info->next = ci->infoActiveChildren; - child_info->prev = 0; - child_info->hwnd = hwnd; - - if (ci->infoActiveChildren) { - MDICHILDINFO *nextinfo = USER_HEAP_LIN_ADDR(ci->infoActiveChildren); - nextinfo->prev = h; - } - - ci->infoActiveChildren = h; - - SendMessage(parent, WM_CHILDACTIVATE, 0, 0); + /* FIXME: at this point NC area of hwnd stays inactive */ } + else + DeleteMenu(ci->hWindowMenu,wIDmenu,MF_BYCOMMAND); return hwnd; } /********************************************************************** - * MDIDestroyChild + * MDI_SwitchActiveChild + * + * Notes: SetWindowPos sends WM_CHILDACTIVATE to the child window that is + * being activated + * + * Ideally consecutive SetWindowPos should be replaced by + * BeginDeferWindowPos/EndDeferWindowPos but currently it doesn't + * matter. + * + * wTo is basically lParam of WM_MDINEXT message */ -HWND MDIDestroyChild(WND *w_parent, MDICLIENTINFO *ci, HWND parent, - HWND child, BOOL flagDestroy) +void MDI_SwitchActiveChild(HWND clientHwnd, HWND childHwnd, WORD wTo ) { - MDICHILDINFO *chi; - HLOCAL hinfo; - - hinfo = ci->infoActiveChildren; - while (hinfo != 0) { - chi = (MDICHILDINFO *)USER_HEAP_LIN_ADDR(hinfo); - if (chi->hwnd == child) break; - hinfo = chi->next; - } - - if (hinfo != 0) - { - if (chi->prev) - ((MDICHILDINFO *)USER_HEAP_LIN_ADDR(chi->prev))->next = chi->next; - if (chi->next) - ((MDICHILDINFO *)USER_HEAP_LIN_ADDR(chi->next))->prev = chi->prev; - if (ci->infoActiveChildren == hinfo) - ci->infoActiveChildren = chi->next; - - ci->nActiveChildren--; - - if (chi->hwnd == ci->hwndActiveChild) - SendMessage(parent, WM_CHILDACTIVATE, 0, 0); - - USER_HEAP_FREE(hinfo); - - if (flagDestroy) - DestroyWindow(child); - } - - return 0; -} - -/********************************************************************** - * MDIBringChildToTop - */ -void MDIBringChildToTop(HWND parent, WORD id, WORD by_id, BOOL send_to_bottom) -{ - HLOCAL hinfo; - MDICHILDINFO *chi; + WND *w = WIN_FindWndPtr(clientHwnd); + HWND hwndTo = MDI_GetWindow(w,childHwnd,wTo); + HWND hwndPrev; MDICLIENTINFO *ci; - WND *w; - int i; - w = WIN_FindWndPtr(parent); - ci = (MDICLIENTINFO *) w->wExtra; - dprintf_mdi(stddeb, "MDIBringToTop: id %04x, by_id %d\n", id, by_id); + ci = (MDICLIENTINFO *) w->wExtra; - if (by_id) - id -= ci->idFirstChild; - if (!by_id || id < ci->nActiveChildren) - { - hinfo = ci->infoActiveChildren; + dprintf_mdi(stddeb, "MDI_SwitchActiveChild: "NPFMT", %i\n",childHwnd,wTo); - if (by_id) - { - for (i = 0; i < id; i++) - hinfo = ((MDICHILDINFO *)USER_HEAP_LIN_ADDR(hinfo))->next; - chi = USER_HEAP_LIN_ADDR(hinfo); - } - else - { - while (hinfo != 0) { - chi = (MDICHILDINFO *)USER_HEAP_LIN_ADDR(hinfo); - if (chi->hwnd == (HWND)id) break; - hinfo = chi->next; - } - } + if ( !childHwnd || !hwndTo ) return; - if (hinfo == 0) - return; + hwndPrev = ci->hwndActiveChild; - dprintf_mdi(stddeb, "MDIBringToTop: child "NPFMT"\n", chi->hwnd); - if (hinfo != ci->infoActiveChildren) + if ( hwndTo != hwndPrev ) { if (ci->flagChildMaximized) { RECT rectOldRestore, rect; - w = WIN_FindWndPtr(chi->hwnd); + w = WIN_FindWndPtr(hwndTo); + /* save old window dimensions */ rectOldRestore = ci->rectRestore; - GetWindowRect(chi->hwnd, &ci->rectRestore); + GetWindowRect(hwndTo, &ci->rectRestore); rect.top = (ci->rectMaximize.top - (w->rectClient.top - w->rectWindow.top)); @@ -244,61 +309,99 @@ void MDIBringChildToTop(HWND parent, WORD id, WORD by_id, BOOL send_to_bottom) rect.right = (ci->rectMaximize.right + (w->rectWindow.right - w->rectClient.right)); w->dwStyle |= WS_MAXIMIZE; - SetWindowPos(chi->hwnd, HWND_TOP, rect.left, rect.top, + + /* maximize it */ + ci->flagChildMaximized = childHwnd; /* prevent maximization + * in MDI_ChildActivate + */ + + SetWindowPos( hwndTo, HWND_TOP, rect.left, rect.top, rect.right - rect.left + 1, rect.bottom - rect.top + 1, 0); - SendMessage(chi->hwnd, WM_SIZE, SIZE_MAXIMIZED, + + SendMessage( hwndTo, WM_SIZE, SIZE_MAXIMIZED, MAKELONG(w->rectClient.right-w->rectClient.left, w->rectClient.bottom-w->rectClient.top)); - w = WIN_FindWndPtr(ci->hwndActiveChild); + w = WIN_FindWndPtr(hwndPrev); + + if( w ) + { w->dwStyle &= ~WS_MAXIMIZE; - SetWindowPos(ci->hwndActiveChild, HWND_BOTTOM, + + /* push hwndPrev to the bottom if needed */ + if( !wTo ) + SetWindowPos(hwndPrev, HWND_BOTTOM, rectOldRestore.left, rectOldRestore.top, rectOldRestore.right - rectOldRestore.left + 1, rectOldRestore.bottom - rectOldRestore.top + 1, - SWP_NOACTIVATE | - (send_to_bottom ? 0 : SWP_NOZORDER)); + SWP_NOACTIVATE ); + } } else { - SetWindowPos(chi->hwnd, HWND_TOP, 0, 0, 0, 0, + SetWindowPos( hwndTo, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE ); - if (send_to_bottom) + if( !wTo && hwndPrev ) { - SetWindowPos(ci->hwndActiveChild, HWND_BOTTOM, 0, 0, 0, 0, + SetWindowPos( hwndPrev, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); } } + } - if (chi->next) - ((MDICHILDINFO *)USER_HEAP_LIN_ADDR(chi->next))->prev = chi->prev; +} - if (chi->prev) - ((MDICHILDINFO *)USER_HEAP_LIN_ADDR(chi->prev))->next = chi->next; - chi->prev = 0; - chi->next = ci->infoActiveChildren; - ((MDICHILDINFO *)USER_HEAP_LIN_ADDR(chi->next))->prev = hinfo; - ci->infoActiveChildren = hinfo; +/********************************************************************** + * MDIDestroyChild + */ +HWND MDIDestroyChild(WND *w_parent, MDICLIENTINFO *ci, HWND parent, + HWND child, BOOL flagDestroy) +{ + WND *childPtr = WIN_FindWndPtr(child); - SendMessage(parent, WM_CHILDACTIVATE, 0, 0); + if( childPtr ) + { + if( child == ci->hwndActiveChild ) + { + MDI_SwitchActiveChild(parent,child,0); + + if( child == ci->hwndActiveChild ) + MDI_ChildActivate(w_parent,0); + + MDI_MenuDeleteItem(w_parent, child); } - dprintf_mdi(stddeb, "MDIBringToTop: pos %04x, hwnd "NPFMT"\n", - id, chi->hwnd); + ci->nActiveChildren--; + + if( ci->flagChildMaximized == child ) + ci->flagChildMaximized = 1; + + if (flagDestroy) + { + DestroyWindow(child); + PostMessage(parent,WM_MDICALCCHILDSCROLL,0,0L); + ci->sbRecalc |= (SB_BOTH+1); + } } + + return 0; } + /********************************************************************** * MDIMaximizeChild */ LONG MDIMaximizeChild(HWND parent, HWND child, MDICLIENTINFO *ci) { + WND *w = WIN_FindWndPtr(child); RECT rect; - MDIBringChildToTop(parent, child, FALSE, FALSE); + if( !SendMessage( child, WM_QUERYOPEN, 0, 0L) ) + return 0; + ci->rectRestore = w->rectWindow; rect.top = (ci->rectMaximize.top - @@ -310,15 +413,16 @@ LONG MDIMaximizeChild(HWND parent, HWND child, MDICLIENTINFO *ci) rect.right = (ci->rectMaximize.right + (w->rectWindow.right - w->rectClient.right)); w->dwStyle |= WS_MAXIMIZE; + SetWindowPos(child, 0, rect.left, rect.top, - rect.right - rect.left + 1, rect.bottom - rect.top + 1, - SWP_NOACTIVATE | SWP_NOZORDER); + rect.right - rect.left + 1, rect.bottom - rect.top + 1, 0); - ci->flagChildMaximized = TRUE; + ci->flagChildMaximized = child; SendMessage(child, WM_SIZE, SIZE_MAXIMIZED, MAKELONG(w->rectClient.right-w->rectClient.left, w->rectClient.bottom-w->rectClient.top)); + SendMessage(GetParent(parent), WM_NCPAINT, 0, 0); return 0; @@ -329,64 +433,163 @@ LONG MDIMaximizeChild(HWND parent, HWND child, MDICLIENTINFO *ci) */ LONG MDIRestoreChild(HWND parent, MDICLIENTINFO *ci) { - HWND child; + HWND hWnd; - dprintf_mdi(stddeb,"restoring mdi child\n"); + hWnd = ci->hwndActiveChild; + + dprintf_mdi(stddeb,"MDIRestoreChild: restore "NPFMT"\n", hWnd); - child = ci->hwndActiveChild; ci->flagChildMaximized = FALSE; - ShowWindow(child, SW_RESTORE); /* display the window */ - MDIBringChildToTop(parent, child, FALSE, FALSE); - SendMessage(GetParent(parent), WM_NCPAINT, 0, 0); + ShowWindow(hWnd, SW_RESTORE); /* display the window */ + + hWnd = GetParent(parent); + + SendMessage(hWnd,WM_NCPAINT , 0, 0); return 0; } /********************************************************************** - * MDIChildActivated + * MDI_ChildActivate + * + * Note: hWndChild is NULL when last child is being destroyed */ -LONG MDIChildActivated(WND *w, MDICLIENTINFO *ci, HWND parent) +LONG MDI_ChildActivate(WND *clientPtr, HWND hWndChild) { - HLOCAL hinfo; - MDICHILDINFO *chi; - HWND deact_hwnd; - HWND act_hwnd; - LONG lParam; + MDICLIENTINFO *clientInfo = (MDICLIENTINFO*)clientPtr->wExtra; + HWND prevActiveWnd = clientInfo->hwndActiveChild; + WND *wndPtr = WIN_FindWndPtr( hWndChild ); + WND *wndPrev = WIN_FindWndPtr( prevActiveWnd ); + BOOL isActiveFrameWnd = 0; - dprintf_mdi(stddeb, "MDIChildActivate: top "NPFMT"\n", w->hwndChild); + if( hWndChild == prevActiveWnd ) return 0L; - hinfo = ci->infoActiveChildren; - if (hinfo) + if( wndPtr ) + if( wndPtr->dwStyle & WS_DISABLED ) return 0L; + + dprintf_mdi(stddeb,"MDI_ChildActivate: "NPFMT"\n", hWndChild); + + if( GetActiveWindow() == clientPtr->hwndParent ) + isActiveFrameWnd = TRUE; + + /* deactivate prev. active child */ + if( wndPrev ) { - chi = (MDICHILDINFO *)USER_HEAP_LIN_ADDR(hinfo); - deact_hwnd = ci->hwndActiveChild; - act_hwnd = chi->hwnd; /* FIX: Hack */ - lParam = ((LONG) deact_hwnd << 16) | (LONG)act_hwnd; + SendMessage( prevActiveWnd, WM_NCACTIVATE, FALSE, 0L ); + SendMessage( prevActiveWnd, WM_MDIACTIVATE, FALSE, + MAKELONG(hWndChild,prevActiveWnd)); + /* uncheck menu item */ + if( clientInfo->hWindowMenu ) + CheckMenuItem( clientInfo->hWindowMenu, + wndPrev->wIDmenu, 0); + } - dprintf_mdi(stddeb, "MDIChildActivate: deact "NPFMT", act "NPFMT"\n", - deact_hwnd, act_hwnd); + /* set appearance */ + if( clientInfo->flagChildMaximized ) + if( clientInfo->flagChildMaximized != hWndChild ) + if( hWndChild ) + { + clientInfo->hwndActiveChild = hWndChild; + MDIMaximizeChild(GetParent(hWndChild),hWndChild,clientInfo); + } - ci->hwndActiveChild = act_hwnd; + clientInfo->hwndActiveChild = hWndChild; - if (deact_hwnd != act_hwnd) + /* check if we have any children left */ + if( !hWndChild ) { - MDIRecreateMenuList(ci); - SendMessage(deact_hwnd, WM_NCACTIVATE, FALSE, 0); - SendMessage(deact_hwnd, WM_MDIACTIVATE, FALSE, lParam); + if( isActiveFrameWnd ) + SetFocus( GetParent(hWndChild) ); + return 0; } - SendMessage(act_hwnd, WM_NCACTIVATE, TRUE, 0); - SendMessage(act_hwnd, WM_MDIACTIVATE, TRUE, lParam); + /* check menu item */ + if( clientInfo->hWindowMenu ) + CheckMenuItem( clientInfo->hWindowMenu, + wndPtr->wIDmenu, MF_CHECKED); + + /* bring active child to the top */ + SetWindowPos( hWndChild, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); + + if( isActiveFrameWnd ) + { + SendMessage( hWndChild, WM_NCACTIVATE, TRUE, 0L); + if( GetFocus() == GetParent(hWndChild) ) + SendMessage( GetParent(hWndChild), WM_SETFOCUS, + GetParent(hWndChild), 0L ); + else + SetFocus( GetParent(hWndChild) ); } - if (hinfo || ci->nActiveChildren == 0) + SendMessage( hWndChild, WM_MDIACTIVATE, TRUE, + MAKELONG(prevActiveWnd,hWndChild) ); + + return 1; +} + +/********************************************************************** + * MDI_BuildWCL + * + * iTotal returns number of children available for tiling or cascading + */ +MDIWCL* MDI_BuildWCL(WND* clientWnd, int* iTotal) +{ + MDIWCL *listTop,*listNext; + WND *childWnd; + + if (!(listTop = (MDIWCL*)malloc( sizeof(MDIWCL) ))) return NULL; + + listTop->hChild = clientWnd->hwndChild; + listTop->prev = NULL; + *iTotal = 1; + + /* build linked list from top child to bottom */ + + childWnd = WIN_FindWndPtr( listTop->hChild ); + while( childWnd && childWnd->hwndNext ) { - MDIRecreateMenuList(ci); - SendMessage(GetParent(parent), WM_NCPAINT, 0, 0); - } + listNext = (MDIWCL*)malloc(sizeof(MDIWCL)); + + if( !listNext ) + { + /* quit gracefully */ + listNext = listTop->prev; + while( listTop ) + { + listNext = listTop->prev; + free(listTop); + listTop = listNext; + } + fprintf(stdnimp,"MDICascade: allocation failed\n"); + return NULL; + } - return 0; + if( (childWnd->dwStyle & WS_DISABLED) || + (childWnd->dwStyle & WS_MINIMIZE) || + !(childWnd->dwStyle & WS_VISIBLE) ) + { + listTop->hChild = 0; + (*iTotal)--; + } + + listNext->hChild = childWnd->hwndNext; + listNext->prev = listTop; + listTop = listNext; + (*iTotal)++; + + childWnd = WIN_FindWndPtr( childWnd->hwndNext ); + } + + if( (childWnd->dwStyle & WS_DISABLED) || + (childWnd->dwStyle & WS_MINIMIZE) || + !(childWnd->dwStyle & WS_VISIBLE) ) + { + listTop->hChild = 0; + (*iTotal)--; + } + + return listTop; } /********************************************************************** @@ -394,19 +597,17 @@ LONG MDIChildActivated(WND *w, MDICLIENTINFO *ci, HWND parent) */ LONG MDICascade(HWND parent, MDICLIENTINFO *ci) { - HLOCAL hinfo; - MDICHILDINFO *chi; + WND *clientWnd; + MDIWCL *listTop,*listPrev; RECT rect; int spacing, xsize, ysize; int x, y; + int iToPosition = 0; if (ci->flagChildMaximized) MDIRestoreChild(parent, ci); - /* If there aren't any children, don't even bother. - */ - if (ci->nActiveChildren == 0) - return 0; + if (ci->nActiveChildren == 0) return 0; GetClientRect(parent, &rect); spacing = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CYFRAME); @@ -417,30 +618,34 @@ LONG MDICascade(HWND parent, MDICLIENTINFO *ci) "MDICascade: Client wnd at (%ld,%ld) - (%ld,%ld), spacing %d\n", (LONG)rect.left, (LONG)rect.top, (LONG)rect.right, (LONG)rect.bottom, spacing); - dprintf_mdi(stddeb, "MDICascade: searching for last child\n"); - hinfo = ci->infoActiveChildren; - while(1) { - chi = USER_HEAP_LIN_ADDR(hinfo); - if (chi->next == 0) break; - hinfo = chi->next; - } - dprintf_mdi(stddeb, "MDICascade: last child is "NPFMT"\n", chi->hwnd); + clientWnd = WIN_FindWndPtr( parent ); + + listTop = MDI_BuildWCL(clientWnd,&iToPosition); + + if( !listTop ) return 0; + x = 0; y = 0; - while (hinfo != 0) + + /* walk list and move windows */ + while ( listTop ) { - chi = USER_HEAP_LIN_ADDR(hinfo); dprintf_mdi(stddeb, "MDICascade: move "NPFMT" to (%d,%d) size [%d,%d]\n", - chi->hwnd, x, y, xsize, ysize); - if (IsIconic(chi->hwnd)) continue; - SetWindowPos(chi->hwnd, 0, x, y, xsize, ysize, + listTop->hChild, x, y, xsize, ysize); + + if( listTop->hChild ) + { + SetWindowPos(listTop->hChild, 0, x, y, xsize, ysize, SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER); x += spacing; y += spacing; + } - hinfo = chi->prev; + listPrev = listTop->prev; + free(listTop); + listTop = listPrev; } return 0; @@ -448,57 +653,84 @@ LONG MDICascade(HWND parent, MDICLIENTINFO *ci) /********************************************************************** * MDITile + * */ LONG MDITile(HWND parent, MDICLIENTINFO *ci) { - HLOCAL hinfo; - MDICHILDINFO *chi; + WND *wndClient = WIN_FindWndPtr(parent); + MDIWCL *listTop,*listPrev; RECT rect; int xsize, ysize; int x, y; int rows, columns; int r, c; int i; + int iToPosition = 0; if (ci->flagChildMaximized) MDIRestoreChild(parent, ci); - /* If there aren't any children, don't even bother. - */ - if (ci->nActiveChildren == 0) - return 0; + if (ci->nActiveChildren == 0) return 0; + + listTop = MDI_BuildWCL(wndClient, &iToPosition); + + dprintf_mdi(stddeb,"MDITile: %i windows to tile\n",iToPosition); + + if( !listTop ) return 0; GetClientRect(parent, &rect); - rows = (int) sqrt((double) ci->nActiveChildren); - columns = ci->nActiveChildren / rows; + + rows = (int) sqrt((double) iToPosition); + columns = iToPosition / rows; + + /* hack */ + if( iToPosition != ci->nActiveChildren) + { + y = rect.bottom - 2 * SYSMETRICS_CYICONSPACING - SYSMETRICS_CYICON; + rect.bottom = ( y - SYSMETRICS_CYICON < rect.top )? rect.bottom: y; + } + ysize = rect.bottom / rows; xsize = rect.right / columns; - hinfo = ci->infoActiveChildren; x = 0; i = 0; + for (c = 1; c <= columns; c++) { if (c == columns) { - rows = ci->nActiveChildren - i; + rows = iToPosition - i; ysize = rect.bottom / rows; } y = 0; for (r = 1; r <= rows; r++, i++) { - chi = (MDICHILDINFO *)USER_HEAP_LIN_ADDR(hinfo); - SetWindowPos(chi->hwnd, 0, x, y, xsize, ysize, - SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER); + /* shouldn't happen but... */ + if( !listTop ) + break; + if( listTop->hChild ) + { + SetWindowPos(listTop->hChild, 0, x, y, xsize, ysize, + SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER); y += ysize; - hinfo = chi->next; + } + + listPrev = listTop->prev; + free(listTop); + listTop = listPrev; } x += xsize; } + /* free the rest if any */ + while( listTop ) { + listPrev = listTop->prev; + free(listTop); + listTop = listPrev; } return 0; } @@ -630,19 +862,18 @@ LRESULT MDIClientWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) switch (message) { - case WM_CHILDACTIVATE: - return MDIChildActivated(w, ci, hwnd); - case WM_CREATE: cs = (LPCREATESTRUCT) PTR_SEG_TO_LIN(lParam); ccs = (LPCLIENTCREATESTRUCT) PTR_SEG_TO_LIN(cs->lpCreateParams); ci->hWindowMenu = ccs->hWindowMenu; ci->idFirstChild = ccs->idFirstChild; - ci->infoActiveChildren = 0; - ci->flagMenuAltered = FALSE; ci->flagChildMaximized = FALSE; + ci->sbStop = 0; + w->dwStyle |= WS_CLIPCHILDREN; + AppendMenu(ccs->hWindowMenu,MF_SEPARATOR,0,NULL); + GetClientRect(w->hwndParent, &ci->rectMaximize); MoveWindow(hwnd, 0, 0, ci->rectMaximize.right, ci->rectMaximize.bottom, 1); @@ -650,7 +881,7 @@ LRESULT MDIClientWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) return 0; case WM_MDIACTIVATE: - MDIBringChildToTop(hwnd, wParam, FALSE, FALSE); + SetWindowPos(wParam,0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE ); return 0; case WM_MDICASCADE: @@ -664,16 +895,20 @@ LRESULT MDIClientWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_MDIGETACTIVE: return ((LONG) ci->hwndActiveChild | - ((LONG) ci->flagChildMaximized << 16)); + ((LONG) (ci->flagChildMaximized>0) << 16)); case WM_MDIICONARRANGE: - return MDIIconArrange(hwnd); + ci->sbStop = TRUE; + MDIIconArrange(hwnd); + ci->sbStop = FALSE; + SendMessage(hwnd,WM_MDICALCCHILDSCROLL,0,0L); + return 0; case WM_MDIMAXIMIZE: return MDIMaximizeChild(hwnd, wParam, ci); case WM_MDINEXT: - MDIBringChildToTop(hwnd, wParam, FALSE, TRUE); + MDI_SwitchActiveChild(hwnd, (HWND)wParam, lParam); break; case WM_MDIRESTORE: @@ -683,27 +918,55 @@ LRESULT MDIClientWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) return MDISetMenu(hwnd, wParam, LOWORD(lParam), HIWORD(lParam)); case WM_MDITILE: - return MDITile(hwnd, ci); + ci->sbStop = TRUE; + ShowScrollBar(hwnd,SB_BOTH,FALSE); + MDITile(hwnd, ci); + ci->sbStop = FALSE; + return 0; + + case WM_VSCROLL: + case WM_HSCROLL: + ci->sbStop = TRUE; + ScrollChildren(hwnd,message,wParam,lParam); + ci->sbStop = FALSE; + return 0; + + case WM_SETFOCUS: + if( ci->hwndActiveChild ) + { + w = WIN_FindWndPtr( ci->hwndActiveChild ); + if( !(w->dwStyle & WS_MINIMIZE) ) + SetFocus( ci->hwndActiveChild ); + } + return 0; case WM_NCACTIVATE: + if( ci->hwndActiveChild ) SendMessage(ci->hwndActiveChild, message, wParam, lParam); break; case WM_PARENTNOTIFY: - if (wParam == WM_DESTROY) -#ifdef WINELIB32 - return MDIDestroyChild(w, ci, hwnd, lParam, FALSE); -#else - return MDIDestroyChild(w, ci, hwnd, LOWORD(lParam), FALSE); -#endif - else if (wParam == WM_LBUTTONDOWN) - MDIBringChildToTop(hwnd, ci->hwndHitTest, FALSE, FALSE); + if (wParam == WM_LBUTTONDOWN) + SetWindowPos(ci->hwndHitTest, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE ); break; case WM_SIZE: GetClientRect(w->hwndParent, &ci->rectMaximize); + if( !ci->hwndActiveChild ) + { + PostMessage(hwnd,WM_MDICALCCHILDSCROLL,0,0L); + ci->sbRecalc |= (SB_BOTH+1); + } break; + case WM_MDICALCCHILDSCROLL: + if( !ci->sbStop ) + if( ci->sbRecalc ) + { + CalcChildScroll(hwnd, ci->sbRecalc-1); + ci->sbRecalc = 0; + } + return 0; } return DefWindowProc(hwnd, message, wParam, lParam); @@ -716,12 +979,17 @@ LRESULT MDIClientWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) LRESULT DefFrameProc(HWND hwnd, HWND hwndMDIClient, UINT message, WPARAM wParam, LPARAM lParam) { + HWND childHwnd; + if (hwndMDIClient) { switch (message) { case WM_COMMAND: - MDIBringChildToTop(hwndMDIClient, wParam, TRUE, FALSE); + childHwnd = MDI_GetChildByID( WIN_FindWndPtr(hwndMDIClient), + wParam ); + if( childHwnd ) + SendMessage(hwndMDIClient, WM_MDIACTIVATE, childHwnd , 0L); break; case WM_NCLBUTTONDOWN: @@ -739,7 +1007,7 @@ LRESULT DefFrameProc(HWND hwnd, HWND hwndMDIClient, UINT message, message, wParam, lParam); case WM_SETFOCUS: - SendMessage(hwndMDIClient, WM_SETFOCUS, wParam, lParam); + SetFocus(hwndMDIClient); break; case WM_SIZE: @@ -763,10 +1031,10 @@ LONG DefMDIChildProc(HWND hwnd, WORD message, WORD wParam, LONG lParam) #endif { MDICLIENTINFO *ci; - WND *w; + WND *clientWnd; - w = WIN_FindWndPtr(GetParent(hwnd)); - ci = (MDICLIENTINFO *) w->wExtra; + clientWnd = WIN_FindWndPtr(GetParent(hwnd)); + ci = (MDICLIENTINFO *) clientWnd->wExtra; switch (message) { @@ -774,10 +1042,29 @@ LONG DefMDIChildProc(HWND hwnd, WORD message, WORD wParam, LONG lParam) ci->hwndHitTest = hwnd; break; - case WM_NCPAINT: - NC_DoNCPaint( hwnd, hwnd == ci->hwndActiveChild, FALSE ); + case WM_SETTEXT: + DefWindowProc(hwnd, message, wParam, lParam); + MDI_MenuModifyItem(clientWnd,hwnd); return 0; + case WM_CLOSE: + SendMessage(GetParent(hwnd),WM_MDIDESTROY,hwnd,0L); + return 0; + + case WM_SIZE: + if( ci->hwndActiveChild != hwnd ) + MDI_ChildActivate(clientWnd, hwnd); + break; + + case WM_CHILDACTIVATE: + MDI_ChildActivate(clientWnd, hwnd); + return 0; + + case WM_NCPAINT: + dprintf_mdi(stddeb,"DefMDIChildProc: WM_NCPAINT for "NPFMT", active "NPFMT"\n", + hwnd, ci->hwndActiveChild ); + break; + case WM_SYSCOMMAND: switch (wParam) { @@ -789,6 +1076,34 @@ LONG DefMDIChildProc(HWND hwnd, WORD message, WORD wParam, LONG lParam) } break; + /* should also handle following messages */ + case WM_GETMINMAXINFO: + /* should return rect of MDI client + * so that normal ShowWindow will be able to handle + * actions that are handled by MDIMaximize and MDIRestore */ + + case WM_SETVISIBLE: + if( !ci->sbStop ) + { + PostMessage(GetParent(hwnd),WM_MDICALCCHILDSCROLL,0,0L); + ci->sbRecalc |= (SB_BOTH+1); + } + break; + case WM_SETFOCUS: + if( IsChild( GetActiveWindow(), GetParent(hwnd)) ) + SendMessage(clientWnd->hwndChild,WM_CHILDACTIVATE,0,0L); + if( !ci->sbStop ) + { + PostMessage(GetParent(hwnd),WM_MDICALCCHILDSCROLL,0,0L); + ci->sbRecalc |= (SB_BOTH+1); + } + break; + + case WM_MENUCHAR: + case WM_NEXTMENU: + /* set current menu to child system menu */ + + break; } return DefWindowProc(hwnd, message, wParam, lParam); @@ -836,3 +1151,81 @@ void CalcChildScroll( HWND hwnd, WORD scroll ) SetScrollPos( hwnd, SB_HORZ, clientRect.top - childRect.top, TRUE ); } } + +/*********************************************************************** + * ScrollChildren (USER.463) + */ +void ScrollChildren(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + WND *wndPtr = WIN_FindWndPtr(hWnd); + short newPos; + short curPos; + short length; + short minPos; + short maxPos; + short shift; + + if( !wndPtr ) return; + + if( uMsg == WM_HSCROLL ) + { + GetScrollRange(hWnd,SB_HORZ,&minPos,&maxPos); + curPos = GetScrollPos(hWnd,SB_HORZ); + length = (wndPtr->rectClient.right - wndPtr->rectClient.left)/2; + shift = SYSMETRICS_CYHSCROLL; + } + else if( uMsg == WM_VSCROLL ) + { + GetScrollRange(hWnd,SB_VERT,&minPos,&maxPos); + curPos = GetScrollPos(hWnd,SB_VERT); + length = (wndPtr->rectClient.bottom - wndPtr->rectClient.top)/2; + shift = SYSMETRICS_CXVSCROLL; + } + else return; + + switch( wParam ) + { + case SB_LINEUP: + newPos = curPos - shift; + break; + case SB_LINEDOWN: + newPos = curPos + shift; + break; + case SB_PAGEUP: + newPos = curPos - length; + break; + case SB_PAGEDOWN: + newPos = curPos + length; + break; + + case SB_THUMBPOSITION: + newPos = LOWORD(lParam); + break; + + case SB_THUMBTRACK: + return; + + case SB_TOP: + newPos = minPos; + break; + case SB_BOTTOM: + newPos = maxPos; + break; + case SB_ENDSCROLL: + CalcChildScroll(hWnd,(uMsg == WM_VSCROLL)?SB_VERT:SB_HORZ); + return; + } + + if( newPos > maxPos ) + newPos = maxPos; + else if( newPos < minPos ) + newPos = minPos; + + SetScrollPos(hWnd, (uMsg == WM_VSCROLL)?SB_VERT:SB_HORZ , newPos, TRUE); + + if( uMsg == WM_VSCROLL ) + ScrollWindow(hWnd ,0 ,curPos - newPos, NULL, NULL); + else + ScrollWindow(hWnd ,curPos - newPos, 0, NULL, NULL); +} + diff --git a/windows/message.c b/windows/message.c index 836097450a7..23afe53f92a 100644 --- a/windows/message.c +++ b/windows/message.c @@ -23,20 +23,22 @@ /* #define DEBUG_MSG */ #include "debug.h" - #define HWND_BROADCAST ((HWND)0xffff) - #define MAX_QUEUE_SIZE 120 /* Max. size of a message queue */ extern BOOL TIMER_CheckTimer( LONG *next, MSG *msg, HWND hwnd, BOOL remove ); /* timer.c */ - /* System message queue (for hardware events) */ -static HANDLE hmemSysMsgQueue = 0; -static MESSAGEQUEUE * sysMsgQueue = NULL; +/* ------- Internal Queues ------ */ - /* Double-click time */ +static HANDLE hmemSysMsgQueue = 0; +static MESSAGEQUEUE *sysMsgQueue = NULL; + +HANDLE hActiveQ_G = 0; +static HANDLE hFirstQueue = 0; + +/* ------- Miscellaneous ------ */ static int doubleClickSpeed = 452; @@ -62,6 +64,43 @@ static HANDLE MSG_CreateMsgQueue( int size ) return hQueue; } +/*********************************************************************** + * MSG_DeleteMsgQueue + */ +BOOL MSG_DeleteMsgQueue( HANDLE hQueue ) +{ + MESSAGEQUEUE * msgQueue = (MESSAGEQUEUE*)GlobalLock(hQueue); + + if( !hQueue ) + { + dprintf_msg(stddeb,"DeleteMsgQueue: invalid argument.\n"); + return 0; + } + + if( !msgQueue ) return 0; + + if( hQueue == hFirstQueue ) + hFirstQueue = msgQueue->next; + else if( hFirstQueue ) + { + MESSAGEQUEUE *msgQ = (MESSAGEQUEUE*)GlobalLock(hFirstQueue); + + /* walk up queue list and relink if needed */ + while( msgQ->next ) + { + if( msgQ->next == hQueue ) + msgQ->next = msgQueue->next; + + /* should check for intertask sendmessages here */ + + + msgQ = (MESSAGEQUEUE*)GlobalLock(msgQ->next); + } + } + + GlobalFree( hQueue ); + return 1; +} /*********************************************************************** * MSG_CreateSysMsgQueue @@ -169,6 +208,15 @@ static void MSG_RemoveMsg( MESSAGEQUEUE * msgQueue, int pos ) msgQueue->tempStatus = 0; } +/*********************************************************************** + * MSG_GetQueueTask + */ +HTASK MSG_GetQueueTask( HANDLE hQueue ) +{ + MESSAGEQUEUE *msgQ = GlobalLock( hQueue ); + + return (msgQ) ? msgQ->hTask : 0 ; +} /*********************************************************************** * MSG_GetWindowForEvent @@ -624,7 +672,9 @@ BOOL MSG_GetHardwareMessage( LPMSG msg ) */ BOOL SetMessageQueue( int size ) { - HGLOBAL hQueue; + HGLOBAL hQueue = 0; + HGLOBAL hNextQueue= hFirstQueue; + MESSAGEQUEUE *queuePrev = NULL; MESSAGEQUEUE *queuePtr; if ((size > MAX_QUEUE_SIZE) || (size <= 0)) return TRUE; @@ -632,13 +682,47 @@ BOOL SetMessageQueue( int size ) /* Free the old message queue */ if ((hQueue = GetTaskQueue(0)) != 0) { - GlobalUnlock( hQueue ); - GlobalFree( hQueue ); + MESSAGEQUEUE *queuePtr = (MESSAGEQUEUE *)GlobalLock( hQueue ); + + if( queuePtr ) + { + MESSAGEQUEUE *msgQ = (MESSAGEQUEUE*)GlobalLock(hFirstQueue); + + hNextQueue = queuePtr->next; + + if( msgQ ) + if( hQueue != hFirstQueue ) + while( msgQ->next ) + { + if( msgQ->next == hQueue ) + { + queuePrev = msgQ; + break; + } + msgQ = (MESSAGEQUEUE*)GlobalLock(msgQ->next); + } + GlobalUnlock( hQueue ); + MSG_DeleteMsgQueue( hQueue ); + } + } + + if( !(hQueue = MSG_CreateMsgQueue( size ))) + { + if(queuePrev) + /* it did have a queue */ + queuePrev->next = hNextQueue; + return FALSE; } - if (!(hQueue = MSG_CreateMsgQueue( size ))) return FALSE; queuePtr = (MESSAGEQUEUE *)GlobalLock( hQueue ); queuePtr->hTask = GetCurrentTask(); + queuePtr->next = hNextQueue; + + if( !queuePrev ) + hFirstQueue = hQueue; + else + queuePrev->next = hQueue; + SetTaskQueue( 0, hQueue ); return TRUE; } diff --git a/windows/nonclient.c b/windows/nonclient.c index 086dc181e68..9df7ae5e45f 100644 --- a/windows/nonclient.c +++ b/windows/nonclient.c @@ -19,9 +19,11 @@ #include "nonclient.h" #include "graphics.h" #include "selectors.h" +#include "stackframe.h" #include "stddebug.h" /* #define DEBUG_NONCLIENT */ #include "debug.h" +#include "options.h" static HBITMAP hbitmapClose = 0; @@ -35,12 +37,17 @@ static HBITMAP hbitmapRestoreD = 0; #define SC_ABOUTWINE (SC_SCREENSAVE+1) /* Some useful macros */ +#define IS_MANAGED(style) \ + (Options.managed && !((style) & WS_CHILD)) + #define HAS_DLGFRAME(style,exStyle) \ - (((exStyle) & WS_EX_DLGMODALFRAME) || \ - (((style) & WS_DLGFRAME) && !((style) & WS_BORDER))) + (!(IS_MANAGED(style)) && \ + (((exStyle) & WS_EX_DLGMODALFRAME) || \ + (((style) & WS_DLGFRAME) && !((style) & WS_BORDER)))) #define HAS_THICKFRAME(style) \ - (((style) & WS_THICKFRAME) && \ + (!(IS_MANAGED(style)) && \ + ((style) & WS_THICKFRAME) && \ !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME)) #define HAS_MENU(w) (!((w)->dwStyle & WS_CHILD) && ((w)->wIDmenu != 0)) @@ -63,6 +70,7 @@ static HBITMAP hbitmapRestoreD = 0; static void NC_AdjustRect( LPRECT rect, DWORD style, BOOL menu, DWORD exStyle ) { if (style & WS_ICONIC) return; /* Nothing to change for an icon */ + if (IS_MANAGED(style)) return; if (HAS_DLGFRAME( style, exStyle )) InflateRect( rect, SYSMETRICS_CXDLGFRAME, SYSMETRICS_CYDLGFRAME ); else @@ -118,8 +126,7 @@ void AdjustWindowRectEx( LPRECT rect, DWORD style, BOOL menu, DWORD exStyle ) void NC_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos, POINT *minTrack, POINT *maxTrack ) { - HANDLE minmaxHandle; - MINMAXINFO MinMax, *pMinMax; + MINMAXINFO MinMax; short xinc, yinc; WND *wndPtr = WIN_FindWndPtr( hwnd ); @@ -132,7 +139,9 @@ void NC_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos, MinMax.ptMaxTrackSize.x = SYSMETRICS_CXSCREEN; MinMax.ptMaxTrackSize.y = SYSMETRICS_CYSCREEN; - if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle )) + if (IS_MANAGED(wndPtr->dwStyle)) + xinc = yinc = 0; + else if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle )) { xinc = SYSMETRICS_CXDLGFRAME; yinc = SYSMETRICS_CYDLGFRAME; @@ -165,28 +174,25 @@ void NC_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos, MinMax.ptMaxPosition.y = -yinc; } - minmaxHandle = USER_HEAP_ALLOC( sizeof(MINMAXINFO) ); - if (minmaxHandle) - { - pMinMax = (MINMAXINFO *) USER_HEAP_LIN_ADDR( minmaxHandle ); - memcpy( pMinMax, &MinMax, sizeof(MinMax) ); - SendMessage( hwnd, WM_GETMINMAXINFO, 0, - (LPARAM)USER_HEAP_SEG_ADDR(minmaxHandle) ); - } - else pMinMax = &MinMax; + SendMessage( hwnd, WM_GETMINMAXINFO, 0, MAKE_SEGPTR(&MinMax) ); /* Some sanity checks */ - pMinMax->ptMaxTrackSize.x = MAX( pMinMax->ptMaxTrackSize.x, - pMinMax->ptMinTrackSize.x ); - pMinMax->ptMaxTrackSize.y = MAX( pMinMax->ptMaxTrackSize.y, - pMinMax->ptMinTrackSize.y ); + dprintf_nonclient(stddeb, + "NC_GetMinMaxInfo: %d %d / %d %d / %d %d / %d %d\n", + MinMax.ptMaxSize.x,MinMax.ptMaxSize.y, + MinMax.ptMaxPosition.x,MinMax.ptMaxPosition.y, + MinMax.ptMaxTrackSize.x,MinMax.ptMaxTrackSize.y, + MinMax.ptMinTrackSize.x,MinMax.ptMinTrackSize.y); + MinMax.ptMaxTrackSize.x = MAX( MinMax.ptMaxTrackSize.x, + MinMax.ptMinTrackSize.x ); + MinMax.ptMaxTrackSize.y = MAX( MinMax.ptMaxTrackSize.y, + MinMax.ptMinTrackSize.y ); - 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 ); + if (maxSize) *maxSize = MinMax.ptMaxSize; + if (maxPos) *maxPos = MinMax.ptMaxPosition; + if (minTrack) *minTrack = MinMax.ptMinTrackSize; + if (maxTrack) *maxTrack = MinMax.ptMaxTrackSize; } @@ -233,6 +239,7 @@ void NC_GetInsideRect( HWND hwnd, RECT *rect ) rect->bottom = wndPtr->rectWindow.bottom - wndPtr->rectWindow.top; if (wndPtr->dwStyle & WS_ICONIC) return; /* No border to remove */ + if (IS_MANAGED(wndPtr->dwStyle)) return; /* Remove frame from rectangle */ if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle )) @@ -319,14 +326,16 @@ LONG NC_HandleNCHitTest( HWND hwnd, POINT pt ) { if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle )) InflateRect(&rect, -SYSMETRICS_CXDLGFRAME, -SYSMETRICS_CYDLGFRAME); - else if (wndPtr->dwStyle & WS_BORDER) + else if (!(IS_MANAGED(wndPtr->dwStyle)) && + (wndPtr->dwStyle & WS_BORDER)) InflateRect(&rect, -SYSMETRICS_CXBORDER, -SYSMETRICS_CYBORDER); if (!PtInRect( &rect, pt )) return HTBORDER; } /* Check caption */ - if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION) + if (!(IS_MANAGED(wndPtr->dwStyle)) && + ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION)) { rect.top += SYSMETRICS_CYCAPTION - 1; if (!PtInRect( &rect, pt )) @@ -663,8 +672,9 @@ void NC_DoNCPaint( HWND hwnd, BOOL active, BOOL suppress_menupaint ) SelectObject( hdc, sysColorObjects.hpenWindowFrame ); - if ((wndPtr->dwStyle & WS_BORDER) || (wndPtr->dwStyle & WS_DLGFRAME) || - (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)) + if (((wndPtr->dwStyle & WS_BORDER) || (wndPtr->dwStyle & WS_DLGFRAME) || + (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME)) && + !(IS_MANAGED(wndPtr->dwStyle))) { MoveTo( hdc, 0, 0 ); LineTo( hdc, rect.right-1, 0 ); @@ -676,10 +686,12 @@ void NC_DoNCPaint( HWND hwnd, BOOL active, BOOL suppress_menupaint ) if (HAS_DLGFRAME( wndPtr->dwStyle, wndPtr->dwExStyle )) NC_DrawFrame( hdc, &rect, TRUE, active ); - else if (wndPtr->dwStyle & WS_THICKFRAME) + else if ((wndPtr->dwStyle & WS_THICKFRAME) && + !(IS_MANAGED(wndPtr->dwStyle))) NC_DrawFrame(hdc, &rect, FALSE, active ); - if ((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION) + if (((wndPtr->dwStyle & WS_CAPTION) == WS_CAPTION) && + !(IS_MANAGED(wndPtr->dwStyle))) { RECT r = rect; r.bottom = rect.top + SYSMETRICS_CYSIZE; @@ -721,7 +733,9 @@ void NC_DoNCPaint( HWND hwnd, BOOL active, BOOL suppress_menupaint ) */ LONG NC_HandleNCPaint( HWND hwnd ) { - NC_DoNCPaint( hwnd, hwnd == GetActiveWindow(), FALSE ); + WND *wndPtr = WIN_FindWndPtr(hwnd); + + NC_DoNCPaint( hwnd, wndPtr->flags & WIN_NCACTIVATED, FALSE ); return 0; } @@ -733,6 +747,11 @@ LONG NC_HandleNCPaint( HWND hwnd ) */ LONG NC_HandleNCActivate( HWND hwnd, WPARAM wParam ) { + WND *wndPtr = WIN_FindWndPtr(hwnd); + + if (wParam != 0) wndPtr->flags |= WIN_NCACTIVATED; + else wndPtr->flags &= ~WIN_NCACTIVATED; + NC_DoNCPaint( hwnd, (wParam != 0), FALSE ); return TRUE; } @@ -1026,6 +1045,7 @@ static void NC_DoSizeMove( HWND hwnd, WORD wParam, POINT pt ) if (rootWindow == DefaultRootWindow(display)) XUngrabServer( display ); } SendMessage( hwnd, WM_EXITSIZEMOVE, 0, 0 ); + SendMessage( hwnd, WM_SETVISIBLE, !IsIconic(hwnd), 0L); /* If Esc key, don't move the window */ if ((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) return; @@ -1090,8 +1110,7 @@ static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam ) */ static void NC_TrackScrollBar( HWND hwnd, WORD wParam, POINT pt ) { - MSG *msg; - HLOCAL hMsg; + MSG msg; WORD scrollbar; WND *wndPtr = WIN_FindWndPtr( hwnd ); @@ -1106,8 +1125,6 @@ static void NC_TrackScrollBar( HWND hwnd, WORD wParam, POINT pt ) scrollbar = SB_VERT; } - hMsg = USER_HEAP_ALLOC( sizeof(MSG) ); - msg = (MSG *) USER_HEAP_LIN_ADDR( hMsg ); pt.x -= wndPtr->rectWindow.left; pt.y -= wndPtr->rectWindow.top; SetCapture( hwnd ); @@ -1115,21 +1132,21 @@ static void NC_TrackScrollBar( HWND hwnd, WORD wParam, POINT pt ) do { - GetMessage( (SEGPTR)USER_HEAP_SEG_ADDR(hMsg), 0, 0, 0 ); - switch(msg->message) + GetMessage( MAKE_SEGPTR(&msg), 0, 0, 0 ); + switch(msg.message) { case WM_LBUTTONUP: case WM_MOUSEMOVE: case WM_SYSTIMER: - pt.x = LOWORD(msg->lParam) + wndPtr->rectClient.left - + pt.x = LOWORD(msg.lParam) + wndPtr->rectClient.left - wndPtr->rectWindow.left; - pt.y = HIWORD(msg->lParam) + wndPtr->rectClient.top - + pt.y = HIWORD(msg.lParam) + wndPtr->rectClient.top - wndPtr->rectWindow.top; - SCROLL_HandleScrollEvent( hwnd, scrollbar, msg->message, pt ); + SCROLL_HandleScrollEvent( hwnd, scrollbar, msg.message, pt ); break; default: - TranslateMessage( msg ); - DispatchMessage( msg ); + TranslateMessage( &msg ); + DispatchMessage( &msg ); break; } if (!IsWindow( hwnd )) @@ -1137,8 +1154,7 @@ static void NC_TrackScrollBar( HWND hwnd, WORD wParam, POINT pt ) ReleaseCapture(); break; } - } while (msg->message != WM_LBUTTONUP); - USER_HEAP_FREE( hMsg ); + } while (msg.message != WM_LBUTTONUP); } /*********************************************************************** diff --git a/windows/scroll.c b/windows/scroll.c index b24fcbfe1f1..e8652cffa18 100644 --- a/windows/scroll.c +++ b/windows/scroll.c @@ -2,40 +2,157 @@ * Scroll windows and DCs * * Copyright David W. Metcalfe, 1993 + * Alex Korobka 1995 + * * */ #include -#include "windows.h" +#include "wintypes.h" +#include "class.h" +#include "win.h" #include "gdi.h" -#include "scroll.h" +#include "sysmetrics.h" #include "stddebug.h" /* #define DEBUG_SCROLL */ #include "debug.h" + +extern DCE_GetVisRgn(HWND, WORD); + static int RgnType; +/* ----------------------------------------------------------------------- + * SCROLL_TraceChildren + * + * Returns a region invalidated by children, siblings, and/or ansectors + * in the window rectangle or client rectangle + * + * dcx can have DCX_WINDOW, DCX_CLIPCHILDREN, DCX_CLIPSIBLINGS set + */ + +HRGN SCROLL_TraceChildren( HWND hScroll, short dx, short dy, WORD dcx) +{ + WND *wndScroll = WIN_FindWndPtr( hScroll ); + HRGN hRgnWnd; + HRGN hUpdateRgn,hCombineRgn; + + if( !wndScroll || ( !dx && !dy) ) return 0; + + if( dcx & DCX_WINDOW ) + hRgnWnd = CreateRectRgnIndirect(&wndScroll->rectWindow); + else + { + RECT rect; + + GetClientRect(hScroll,&rect); + hRgnWnd = CreateRectRgnIndirect(&rect); + } + + hUpdateRgn = DCE_GetVisRgn( hScroll, dcx ); + hCombineRgn = CreateRectRgn(0,0,0,0); + + if( !hUpdateRgn || !hCombineRgn ) + { + DeleteObject( hUpdateRgn? hUpdateRgn : hCombineRgn); + DeleteObject(hRgnWnd); + return 0; + } + + OffsetRgn( hUpdateRgn, dx, dy); + CombineRgn(hCombineRgn, hRgnWnd, hUpdateRgn, RGN_DIFF); + + DeleteObject(hRgnWnd); + DeleteObject(hUpdateRgn); + + return hCombineRgn; +} + + +/* ---------------------------------------------------------------------- + * SCROLL_ScrollChildren + */ +BOOL SCROLL_ScrollChildren( HWND hScroll, short dx, short dy) +{ + WND *wndPtr = WIN_FindWndPtr(hScroll); + HWND hWnd = wndPtr->hwndChild; + HRGN hUpdateRgn; + BOOL b = 0; + + if( !wndPtr || ( !dx && !dy )) return 0; + + dprintf_scroll(stddeb,"SCROLL_ScrollChildren: hwnd "NPFMT" dx=%i dy=%i\n",hScroll,dx,dy); + + /* get a region in client rect invalidated by siblings and ansectors */ + hUpdateRgn = SCROLL_TraceChildren(hScroll, dx , dy, DCX_CLIPSIBLINGS); + + /* update children coordinates */ + while( hWnd ) + { + wndPtr = WIN_FindWndPtr( hWnd ); + + /* we can check if window intersects with clipRect parameter + * and do not move it if not - just a thought. - AK + */ + + SetWindowPos(hWnd,0,wndPtr->rectWindow.left + dx, + wndPtr->rectWindow.top + dy, 0,0, SWP_NOZORDER | + SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOREDRAW | + SWP_DEFERERASE ); + + hWnd = wndPtr->hwndNext; + } + + /* invalidate uncovered region and paint frames */ + b = RedrawWindow( hScroll, NULL, hUpdateRgn, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | + RDW_ERASENOW | RDW_ALLCHILDREN ); + + DeleteObject( hUpdateRgn); + return b; +} + + /************************************************************************* * ScrollWindow (USER.61) + * + * FIXME: a bit broken */ void ScrollWindow(HWND hwnd, short dx, short dy, LPRECT rect, LPRECT clipRect) { HDC hdc; - HRGN hrgnUpdate; + HRGN hrgnUpdate,hrgnClip; RECT rc, cliprc; - dprintf_scroll(stddeb,"ScrollWindow: dx=%d, dy=%d, rect=%ld,%ld,%ld,%ld\n", - dx, dy, (LONG)rect->left, (LONG)rect->top, (LONG)rect->right, (LONG)rect->bottom); + dprintf_scroll(stddeb,"ScrollWindow: dx=%d, dy=%d, lpRect =%08lx clipRect=%i,%i,%i,%i\n", + dx, dy, (LONG)rect, (clipRect)?clipRect->left:0, + (clipRect)?clipRect->top:0, + (clipRect)?clipRect->right:0, + (clipRect)?clipRect->bottom:0); - hdc = GetDC(hwnd); - - if (rect == NULL) + /* if rect is NULL children have to be moved */ + if ( !rect ) + { GetClientRect(hwnd, &rc); + hrgnClip = CreateRectRgnIndirect( &rc ); + + /* children will be Blt'ed too */ + hdc = GetDCEx(hwnd, hrgnClip, DCX_CACHE | DCX_CLIPSIBLINGS); + DeleteObject(hrgnClip); + } else + { + GetClientRect(hwnd,&rc); + dprintf_scroll(stddeb,"\trect=%i %i %i %i client=%i %i %i %i\n", + rect->left,rect->top,rect->right,rect->bottom,rc.left,rc.top, + rc.right,rc.bottom); + CopyRect(&rc, rect); + hdc = GetDC(hwnd); + } + if (clipRect == NULL) GetClientRect(hwnd, &cliprc); else @@ -43,13 +160,41 @@ void ScrollWindow(HWND hwnd, short dx, short dy, LPRECT rect, LPRECT clipRect) hrgnUpdate = CreateRectRgn(0, 0, 0, 0); ScrollDC(hdc, dx, dy, &rc, &cliprc, hrgnUpdate, NULL); - InvalidateRgn(hwnd, hrgnUpdate, TRUE); ReleaseDC(hwnd, hdc); + + if( !rect ) + { + /* FIXME: this doesn't take into account hrgnUpdate */ + if( !SCROLL_ScrollChildren(hwnd,dx,dy) ) + InvalidateRgn(hwnd, hrgnUpdate, TRUE); + } + else + { + HRGN hrgnInv = SCROLL_TraceChildren(hwnd,dx,dy,DCX_CLIPCHILDREN | + DCX_CLIPSIBLINGS ); + if( hrgnInv ) + { + HRGN hrgnCombine = CreateRectRgn(0,0,0,0); + + CombineRgn(hrgnCombine,hrgnInv,hrgnUpdate,RGN_OR); + dprintf_scroll(stddeb,"ScrollWindow: hrgnComb="NPFMT" hrgnInv="NPFMT" hrgnUpd="NPFMT"\n", + hrgnCombine,hrgnInv,hrgnUpdate); + + DeleteObject(hrgnUpdate); DeleteObject(hrgnInv); + hrgnUpdate = hrgnCombine; + } + + RedrawWindow( hwnd, NULL, hrgnUpdate, RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW); + } + + DeleteObject(hrgnUpdate); } /************************************************************************* * ScrollDC (USER.221) + * + * FIXME: half-broken */ BOOL ScrollDC(HDC hdc, short dx, short dy, LPRECT rc, LPRECT cliprc, @@ -60,8 +205,11 @@ BOOL ScrollDC(HDC hdc, short dx, short dy, LPRECT rc, LPRECT cliprc, short width, height; DC *dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC); - dprintf_scroll(stddeb, "ScrollDC: dx=%d, dy=%d, rc=%ld,%ld,%ld,%ld\n", dx, dy, - (LONG)rc->left, (LONG)rc->top, (LONG)rc->right, (LONG)rc->bottom); + dprintf_scroll(stddeb,"ScrollDC: dx=%d dy=%d, hrgnUpdate="NPFMT" rc=%i %i %i %i\n", + dx,dy,hrgnUpdate,(rc)?rc->left:0, + (rc)?rc->top:0, + (rc)?rc->right:0, + (rc)?rc->bottom:0); if (rc == NULL) return FALSE; @@ -128,6 +276,10 @@ BOOL ScrollDC(HDC hdc, short dx, short dy, LPRECT rc, LPRECT cliprc, /************************************************************************* * ScrollWindowEx (USER.319) + * + * FIXME: broken + * + * SCROLL_TraceChildren can help */ int ScrollWindowEx(HWND hwnd, short dx, short dy, LPRECT rect, LPRECT clipRect, @@ -136,9 +288,7 @@ int ScrollWindowEx(HWND hwnd, short dx, short dy, LPRECT rect, LPRECT clipRect, HDC hdc; RECT rc, cliprc; - dprintf_scroll(stddeb,"ScrollWindowEx: dx=%d, dy=%d, rect=%ld,%ld,%ld,%ld\n", - dx, dy, (LONG)rect->left, (LONG)rect->top, (LONG)rect->right, - (LONG)rect->bottom); + dprintf_scroll(stddeb,"ScrollWindowEx: dx=%d, dy=%d, wFlags="NPFMT"\n",dx, dy, flags); hdc = GetDC(hwnd); diff --git a/windows/win.c b/windows/win.c index 7153ee625e2..1848a3bd2d1 100644 --- a/windows/win.c +++ b/windows/win.c @@ -28,11 +28,11 @@ /* #define DEBUG_MENU */ #include "debug.h" -static HWND hwndDesktop = 0; -static HWND hWndSysModal = 0; +static HWND hwndDesktop = 0; +static HWND hwndSysModal = 0; -static WORD wDragWidth = 8; -static WORD wDragHeight= 6; +static WORD wDragWidth = 4; +static WORD wDragHeight= 3; extern HCURSOR CURSORICON_IconToCursor(HICON); @@ -395,7 +395,6 @@ HWND CreateWindowEx( DWORD exStyle, SEGPTR className, SEGPTR windowName, wndPtr->ptMaxPos.y = -1; wndPtr->hmemTaskQ = GetTaskQueue(0); wndPtr->hrgnUpdate = 0; - wndPtr->hwndPrevActive = 0; wndPtr->hwndLastActive = hwnd; wndPtr->lpfnWndProc = classPtr->wc.lpfnWndProc; wndPtr->dwStyle = style & ~WS_VISIBLE; @@ -446,10 +445,20 @@ HWND CreateWindowEx( DWORD exStyle, SEGPTR className, SEGPTR windowName, if (!(style & WS_CHILD) && (rootWindow == DefaultRootWindow(display))) { - win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | - PointerMotionMask | ButtonPressMask | - ButtonReleaseMask | FocusChangeMask; - win_attr.override_redirect = TRUE; + if(Options.managed && className != POPUPMENU_CLASS_ATOM) { + win_attr.event_mask = ExposureMask | KeyPressMask | + KeyReleaseMask | PointerMotionMask | + ButtonPressMask | ButtonReleaseMask | + FocusChangeMask | StructureNotifyMask; + win_attr.override_redirect = FALSE; + } + else { + win_attr.event_mask = ExposureMask | KeyPressMask | + KeyReleaseMask | PointerMotionMask | + ButtonPressMask | ButtonReleaseMask | + FocusChangeMask; + win_attr.override_redirect = TRUE; + } win_attr.colormap = COLOR_WinColormap; win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful; win_attr.save_under = ((classPtr->wc.style & CS_SAVEBITS) != 0); @@ -1238,10 +1247,10 @@ BOOL FlashWindow(HWND hWnd, BOOL bInvert) */ HWND SetSysModalWindow(HWND hWnd) { - HWND hWndOldModal = hWndSysModal; - hWndSysModal = hWnd; - dprintf_win(stdnimp,"EMPTY STUB !! SetSysModalWindow("NPFMT") !\n", hWnd); - return hWndOldModal; + HWND hWndOldModal = hwndSysModal; + hwndSysModal = hWnd; + dprintf_win(stdnimp,"EMPTY STUB !! SetSysModalWindow("NPFMT") !\n", hWnd); + return hWndOldModal; } @@ -1250,7 +1259,7 @@ HWND SetSysModalWindow(HWND hWnd) */ HWND GetSysModalWindow(void) { - return hWndSysModal; + return hwndSysModal; } /******************************************************************* diff --git a/windows/winpos.c b/windows/winpos.c index 08a499c0afd..97109b7df83 100644 --- a/windows/winpos.c +++ b/windows/winpos.c @@ -2,12 +2,15 @@ * Window position related functions. * * Copyright 1993, 1994, 1995 Alexandre Julliard + * 1995 Alex Korobka */ #include "sysmetrics.h" +#include "selectors.h" #include "user.h" #include "win.h" #include "event.h" +#include "hook.h" #include "message.h" #include "stackframe.h" #include "winpos.h" @@ -16,7 +19,16 @@ /* #define DEBUG_WIN */ #include "debug.h" -static HWND hwndActive = 0; /* Currently active window */ +/* ----- external functions ----- */ + +void FOCUS_SwitchFocus( HWND , HWND ); + +/* ----- internal variables ----- */ + +static HWND hwndActive = 0; /* Currently active window */ +static HWND hwndPrevActive = 0; /* Previously active window */ + +extern HANDLE hActiveQ_G; /* from message.c */ /*********************************************************************** @@ -226,7 +238,12 @@ void MapWindowPoints( HWND hwndFrom, HWND hwndTo, LPPOINT lppt, WORD count ) /* Translate source window origin to screen coords */ while(hwndFrom) { - wndPtr = WIN_FindWndPtr( hwndFrom ); + if (!(wndPtr = WIN_FindWndPtr( hwndFrom ))) + { + fprintf( stderr, "MapWindowPoints: bad hwndFrom = "NPFMT"\n", + hwndFrom); + return; + } origin.x += wndPtr->rectClient.left; origin.y += wndPtr->rectClient.top; hwndFrom = (wndPtr->dwStyle & WS_CHILD) ? wndPtr->hwndParent : 0; @@ -235,7 +252,11 @@ void MapWindowPoints( HWND hwndFrom, HWND hwndTo, LPPOINT lppt, WORD count ) /* Translate origin to destination window coords */ while(hwndTo) { - wndPtr = WIN_FindWndPtr( hwndTo ); + if (!(wndPtr = WIN_FindWndPtr( hwndTo ))) + { + fprintf(stderr,"MapWindowPoints: bad hwndTo = "NPFMT"\n", hwndTo ); + return; + } origin.x -= wndPtr->rectClient.left; origin.y -= wndPtr->rectClient.top; hwndTo = (wndPtr->dwStyle & WS_CHILD) ? wndPtr->hwndParent : 0; @@ -288,8 +309,11 @@ 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 ); + + if (!wndPtr || (wndPtr->dwStyle & WS_DISABLED) || + !(wndPtr->dwStyle & WS_VISIBLE)) return 0; + + WINPOS_SetActiveWindow( hwnd, 0, 0 ); return prev; } @@ -377,10 +401,19 @@ BOOL ShowWindow( HWND hwnd, int cmd ) /* Store the current position and find the maximized size */ if (!(wndPtr->dwStyle & WS_MINIMIZE)) wndPtr->rectNormal = wndPtr->rectWindow; + NC_GetMinMaxInfo( hwnd, &maxSize, &wndPtr->ptMaxPos, NULL, NULL ); x = wndPtr->ptMaxPos.x; y = wndPtr->ptMaxPos.y; + + if( wndPtr->dwStyle & WS_MINIMIZE ) + if( !SendMessage( hwnd, WM_QUERYOPEN, 0, 0L ) ) + { + swpflags |= SWP_NOSIZE; + break; + } + cx = maxSize.x; cy = maxSize.y; wndPtr->dwStyle &= ~WS_MINIMIZE; @@ -403,8 +436,14 @@ BOOL ShowWindow( HWND hwnd, int cmd ) case SW_SHOWNORMAL: /* same as SW_NORMAL: */ case SW_RESTORE: swpflags |= SWP_SHOWWINDOW | SWP_FRAMECHANGED; + if (wndPtr->dwStyle & WS_MINIMIZE) { + if( !SendMessage( hwnd, WM_QUERYOPEN, 0, 0L) ) + { + swpflags |= SWP_NOSIZE; + break; + } wndPtr->ptIconPos.x = wndPtr->rectWindow.left; wndPtr->ptIconPos.y = wndPtr->rectWindow.top; wndPtr->dwStyle &= ~WS_MINIMIZE; @@ -530,49 +569,210 @@ BOOL SetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl ) return TRUE; } +/******************************************************************* + * ACTIVATEAPP_callback + */ +BOOL ACTIVATEAPP_callback(HWND hWnd, LPARAM lParam) +{ + ACTIVATESTRUCT *lpActStruct = (ACTIVATESTRUCT*)lParam; + WND *wndPtr = WIN_FindWndPtr( hWnd ); + + if( !wndPtr || hWnd == GetDesktopWindow()) return 1; + + if( MSG_GetQueueTask(wndPtr->hmemTaskQ) != lpActStruct->hTaskSendTo ) + return 1; + + SendMessage( hWnd, WM_ACTIVATEAPP, lpActStruct->wFlag, + (LPARAM)(lpActStruct->hWindowTask)?lpActStruct->hWindowTask:0); + return 1; +} + /******************************************************************* - * WINPOS_ChangeActiveWindow + * WINPOS_SetActiveWindow * - * Change the active window and send the corresponding messages. + * back-end to SetActiveWindow */ -HWND WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg ) +BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus ) { - HWND prevActive = hwndActive; - if (hwnd == hwndActive) return 0; - if (hwndActive) + WND *wndPtr = WIN_FindWndPtr(hWnd); + WND *wndTemp = WIN_FindWndPtr(hwndActive); + CBTACTIVATESTRUCT cbtStruct = { fMouse , hwndActive }; + FARPROC enumCallback = (FARPROC)GetWndProcEntry16("ActivateAppProc"); + ACTIVATESTRUCT actStruct; + WORD wIconized=0,wRet= 0; + + /* paranoid checks */ + if( !hWnd || hWnd == GetDesktopWindow() || hWnd == hwndActive ) + return 0; + + if( GetTaskQueue(0) != wndPtr->hmemTaskQ ) + return 0; + + if( wndTemp ) + wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE); + else + dprintf_win(stddeb,"WINPOS_ActivateWindow: no current active window.\n"); + + /* call CBT hook chain */ + wRet = HOOK_CallHooks(WH_CBT, HCBT_ACTIVATE, hWnd, + (LPARAM)MAKE_SEGPTR(&cbtStruct)); + + if( wRet ) return wRet; + + /* set prev active wnd to current active wnd and send notification */ + if( (hwndPrevActive = hwndActive) ) { - if (!SendMessage( hwndActive, WM_NCACTIVATE, FALSE, 0 )) return 0; + if( !SendMessage(hwndPrevActive, WM_NCACTIVATE, 0, MAKELONG(hWnd,wIconized)) ) + { + if (GetSysModalWindow() != hWnd) return 0; + /* disregard refusal if hWnd is sysmodal */ + } + #ifdef WINELIB32 SendMessage( hwndActive, WM_ACTIVATE, - MAKEWPARAM( WA_INACTIVE, IsIconic(hwndActive) ), - (LPARAM)hwnd ); + MAKEWPARAM( WA_INACTIVE, wIconized ), + (LPARAM)hWnd ); #else - SendMessage( hwndActive, WM_ACTIVATE, WA_INACTIVE, - MAKELONG( IsIconic(hwndActive), hwnd ) ); + SendMessage(hwndPrevActive, WM_ACTIVATE, WA_INACTIVE, + MAKELONG(hWnd,wIconized)); #endif - /* Send WM_ACTIVATEAPP here */ + + /* check if something happened during message processing */ + if( hwndPrevActive != hwndActive ) return 0; } - hwndActive = hwnd; - if (hwndActive) + /* set active wnd */ + hwndActive = hWnd; + + /* send palette messages */ + if( SendMessage( hWnd, WM_QUERYNEWPALETTE, 0, 0L) ) + SendMessage((HWND)-1, WM_PALETTEISCHANGING, hWnd, 0L ); + + /* if prev wnd is minimized redraw icon title + if( hwndPrevActive ) { - WND *wndPtr = WIN_FindWndPtr( hwndActive ); - wndPtr->hwndPrevActive = prevActive; + wndTemp = WIN_FindWndPtr( WIN_GetTopParent( hwndPrevActive ) ); + if(wndTemp) + if(wndTemp->dwStyle & WS_MINIMIZE) + RedrawIconTitle(hwndPrevActive); + } + */ + if (!(wndPtr->dwStyle & WS_CHILD) ) + { + /* check Z-order and bring hWnd to the top */ + wndTemp = WIN_FindWndPtr( GetDesktopWindow() ); - /* Send WM_ACTIVATEAPP here */ - SendMessage( hwnd, WM_NCACTIVATE, TRUE, 0 ); -#ifdef WINELIB32 - SendMessage( hwnd, WM_ACTIVATE, - MAKEWPARAM( mouseMsg ? WA_CLICKACTIVE : WA_ACTIVE, - IsIconic(hwnd) ) - , (LPARAM)prevActive ); -#else - SendMessage( hwnd, WM_ACTIVATE, mouseMsg ? WA_CLICKACTIVE : WA_ACTIVE, - MAKELONG( IsIconic(hwnd), prevActive ) ); -#endif + for( ; wndTemp; wndTemp = WIN_FindWndPtr( wndTemp->hwndNext )) + if( wndTemp->dwStyle & WS_VISIBLE ) + break; + + if( wndTemp != wndPtr ) + SetWindowPos(hWnd, HWND_TOP, 0,0,0,0, + SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE ); } - return prevActive; + + if( !IsWindow(hWnd) ) return 0; + + /* send WM_ACTIVATEAPP if necessary */ + if( hActiveQ_G != wndPtr->hmemTaskQ ) + { + HTASK hT = MSG_GetQueueTask( hActiveQ_G ); + + actStruct.wFlag = 0; /* deactivate */ + actStruct.hWindowTask = MSG_GetQueueTask(wndPtr->hmemTaskQ); + actStruct.hTaskSendTo = hT; + + /* send WM_ACTIVATEAPP to top-level windows + * that belong to the actStruct.hTaskSendTo task + */ + EnumWindows( enumCallback , (LPARAM)&actStruct ); + + /* change active queue */ + hActiveQ_G = wndPtr->hmemTaskQ; + + actStruct.wFlag = 1; /* activate */ + actStruct.hWindowTask = hT; + actStruct.hTaskSendTo = MSG_GetQueueTask( hActiveQ_G ); + + EnumWindows( enumCallback , (LPARAM)&actStruct ); + + if( !IsWindow(hWnd) ) return 0; + } + + /* walk up to the first unowned window */ + wndTemp = wndPtr; + + while(wndTemp->hwndOwner) + { + wndTemp = WIN_FindWndPtr(wndTemp->hwndOwner); + if( !wndTemp) + { + /* there must be an unowned window in hierarchy */ + dprintf_win(stddeb,"WINPOS_ActivateWindow: broken owner list\n"); + wndTemp = wndPtr; + break; + } + } + /* and set last active owned popup */ + wndTemp->hwndLastActive = hWnd; + + wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE); + SendMessage( hWnd, WM_NCACTIVATE, 1, + MAKELONG(hwndPrevActive,wIconized)); +#ifdef WINELIB32 + SendMessage( hWnd, WM_ACTIVATE, + MAKEWPARAM( (fMouse)?WA_CLICKACTIVE:WA_ACTIVE, wIconized), + (LPARAM)hwndPrevActive ); +#else + SendMessage( hWnd, WM_ACTIVATE, (fMouse)? WA_CLICKACTIVE : WA_ACTIVE, + MAKELONG(hwndPrevActive,wIconized)); +#endif + + if( !IsWindow(hWnd) ) return 0; + + /* change focus if possible */ + if( fChangeFocus && GetFocus() ) + if( WIN_GetTopParent(GetFocus()) != hwndActive ) + FOCUS_SwitchFocus( GetFocus(), + (wndPtr->dwStyle & WS_MINIMIZE)? 0: hwndActive); + + /* if active wnd is minimized redraw icon title + if( hwndActive ) + { + wndPtr = WIN_FindWndPtr(hwndActive); + if(wndPtr->dwStyle & WS_MINIMIZE) + RedrawIconTitle(hwndActive); + } + */ + return (hWnd == hwndActive); +} + + +/******************************************************************* + * WINPOS_ChangeActiveWindow + * + */ +HWND WINPOS_ChangeActiveWindow( HWND hWnd, BOOL mouseMsg ) +{ + WND *wndPtr = WIN_FindWndPtr(hWnd); + + if( !wndPtr ) return 0; + + /* minors are not allowed */ + if( (wndPtr->dwStyle & WS_CHILD) && !( wndPtr->dwStyle & WS_POPUP)) + return SendMessage(hWnd, WM_CHILDACTIVATE, 0, 0L); + + if( hWnd == hwndActive ) return 0; + + if( !WINPOS_SetActiveWindow(hWnd ,mouseMsg ,TRUE) ) + return 0; + + /* switch desktop queue to current active here */ + if( wndPtr->hwndParent == GetDesktopWindow()) + { } + + return 1; } @@ -600,6 +800,9 @@ LONG WINPOS_SendNCCalcSize( HWND hwnd, BOOL calcValidRect, RECT *newWindowRect, } result = SendMessage( hwnd, WM_NCCALCSIZE, calcValidRect, MAKE_SEGPTR( ¶ms ) ); + dprintf_win(stddeb, "WINPOS_SendNCCalcSize: %d %d %d %d\n", + params.rgrc[0].top, params.rgrc[0].left, + params.rgrc[0].bottom, params.rgrc[0].right); *newClientRect = params.rgrc[0]; return result; } @@ -859,7 +1062,7 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y, if (!(flags & SWP_NOREDRAW) && (!(flags & SWP_NOSIZE) || !(flags & SWP_NOMOVE) || - !(flags & SWP_NOZORDER))) + (!(flags & SWP_NOZORDER) && (hwndInsertAfter != HWND_TOP)))) { HRGN hrgn1 = CreateRectRgnIndirect( &oldWindowRect ); HRGN hrgn2 = CreateRectRgnIndirect( &wndPtr->rectWindow ); @@ -867,12 +1070,22 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y, CombineRgn( hrgn3, hrgn1, hrgn2, RGN_DIFF ); RedrawWindow( wndPtr->hwndParent, NULL, hrgn3, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE ); + + /* DCE_GetVisRgn should be called for old coordinates + * and for new, then OffsetRgn and CombineRgn - + * voila, a nice update region to use here - AK. + */ if ((oldWindowRect.left != wndPtr->rectWindow.left) || (oldWindowRect.top != wndPtr->rectWindow.top)) { RedrawWindow( winpos.hwnd, NULL, 0, RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE ); } + else + if( CombineRgn( hrgn3, hrgn2, hrgn1, RGN_DIFF) != NULLREGION ) + RedrawWindow( winpos.hwnd, NULL, hrgn3, RDW_INVALIDATE | + RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE ); + DeleteObject( hrgn1 ); DeleteObject( hrgn2 ); DeleteObject( hrgn3 ); @@ -890,7 +1103,8 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y, { if (!(flags & SWP_NOREDRAW)) RedrawWindow( winpos.hwnd, NULL, 0, - RDW_INVALIDATE | RDW_FRAME | RDW_ERASE ); + RDW_INVALIDATE | RDW_ALLCHILDREN | + RDW_FRAME | RDW_ERASE ); } } else if (flags & SWP_HIDEWINDOW) @@ -907,15 +1121,17 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y, RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE ); } + if ((winpos.hwnd == GetFocus()) || IsChild(winpos.hwnd, GetFocus())) SetFocus( GetParent(winpos.hwnd) ); /* Revert focus to parent */ + if (winpos.hwnd == hwndActive) { /* Activate previously active window if possible */ - HWND newActive = wndPtr->hwndPrevActive; + HWND newActive = hwndPrevActive; if (!IsWindow(newActive) || (newActive == winpos.hwnd)) { - newActive = GetTopWindow(GetDesktopWindow()); + newActive = GetTopWindow( GetDesktopWindow() ); if (newActive == winpos.hwnd) newActive = wndPtr->hwndNext; } WINPOS_ChangeActiveWindow( newActive, FALSE ); @@ -925,15 +1141,14 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y, /* Activate the window */ if (!(flags & SWP_NOACTIVATE)) - { - if (!(wndPtr->dwStyle & WS_CHILD)) WINPOS_ChangeActiveWindow( winpos.hwnd, FALSE ); - } /* Repaint the window */ if (wndPtr->window) MSG_Synchronize(); /* Wait for all expose events */ + EVENT_DummyMotionNotify(); /* Simulate a mouse event to set the cursor */ + if ((flags & SWP_FRAMECHANGED) && !(flags & SWP_NOREDRAW)) RedrawWindow( winpos.hwnd, NULL, 0, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE );