diff --git a/ANNOUNCE b/ANNOUNCE index 703bde4ed4c..2f3d6e13e51 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,13 +1,15 @@ -This is release 960114 of Wine the MS Windows emulator. This is still a +This is release 960131 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-960114: (see ChangeLog for details) - - Complete rewrite of the file handling; still has a few bugs. - - Tons of new Win32 code. +WHAT'S NEW with Wine-960131: (see ChangeLog for details) + - New format for drives configuration in wine.conf; please + check your configuration files. + - Many MDI improvements. + - Even more Win32 code. - Lots of bug fixes. See the README file in the distribution for installation instructions. @@ -16,10 +18,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-960114.tar.gz - tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960114.tar.gz - ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960114.tar.gz - aris.com:/pub/linux/ALPHA/Wine/development/Wine-960114.tar.gz + sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-960131.tar.gz + tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960131.tar.gz + ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960131.tar.gz + aris.com:/pub/linux/ALPHA/Wine/development/Wine-960131.tar.gz It should also be available from any site that mirrors tsx-11 or sunsite. diff --git a/ChangeLog b/ChangeLog index d7a84c28048..e5a42a0dc5b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,280 @@ ---------------------------------------------------------------------- +Wed Jan 31 10:58:00 1996 Alexandre Julliard + + * [configure.in] + Added --with-dll option to build libwine.so. + + * [controls/listbox.c] + Fixed ListBoxDirectory(), DlgDirSelect() and + DlgDirList(). Hopefully their behavior is correct now. + + * [controls/menu.c] + Use SEGPTRs in ChangeMenu(), InsertMenu(), AppendMenu() and + ModifyMenu() for the item data, to avoid corrupting the pointer + for owner-drawn items. + + * [controls/static.c] + Attempt to load OEM icons for SS_ICON controls. Probably not + entirely correct. + Don't clip the text output. + + * [files/directory.c] + Add temp dir and Windows dir to environment. + + * [files/dos_fs.c] + Fixed a few path handling bugs in DOSFS_GetUnixFileName(). + Cache last used directory in DOSFS_FindNext() to avoid quadratic + search time. + + * [files/drive.c] + New format for drives configuration in wine.conf; allows + specifying the type, label and serial number of a drive. + + * [files/file.c] + New function FILE_OpenUnixFile to make sure we don't open a + directory instead of a file. + Fixed DOSFS_GetUnixFileName() check_last flag in FILE_MakeDir(). + + * [files/profile.c] + Rewrote profile handling. Should be closer to Windows behavior now. + New function PROFILE_GetWineIniString() to get a string from wine.conf. + Support environment variables in wine.conf. + + * [loader/task.c] + Fixed the order of deletion in TASK_DeleteTask() to avoid memory + corruption. + + * [memory/global.c] + Create a discarded block on GlobalAlloc() if the size is 0; thanks + to John Harvey for noticing this. + + * [memory/local.c] + LOCAL_GetHeap: make sure the pointer is valid before checking + magic number. + + * [misc/main.c] + Moved profile and registry saving to ExitWindows(), so we don't + try to save them in case of a crash. + + * [miscemu/int21.c] + INT21_GetFreeDiskSpace: try to compute the cluster size from the + filesystem size instead of hard-coding it to 64. + Fixed functions 0x3f and 0x40 to use _hread and _hwrite to allow + reading or writing 65535 bytes (thanks to Bruce Milner for this one). + + * [windows/message.c] + Fixed bug in linked-list handling in MSG_DeleteQueue(). + Simplified SetMessageQueue(). + + * [wine.ini] [wine.man] + Updated for new drives configuration format. + +Tue Jan 30 11:24:46 1996 William Magro + + * [controls/edit.c] + Implemented ES_PASSWORD style, EM_SETPASSWORDCHAR and + EM_GETPASSWORDCHAR messages. + + * [controls/widgets.c] + Adjusted class creation flags to better match values Windows uses. + + * [include/windows.h] + Fixed ES_NOHIDESEL typo. + + * [loader/ne_image.c] + Added detection for zero offset in RADDR fixups. Quicken + was in an infinite loop here. + +Mon Jan 29 20:12:22 1996 Albrecht Kleine + + * [files/dos_fs.c] + Bugfix: range error in month value (0..11 set to 1..12). + + * [windows/caret.c] + Changed ROP2-mode to R2_NOTXORPEN in CARET_Callback for pulsed + appearance of the caret. + + * [windows/mdi.c] [include/mdi.h] + Changed MDITile(): added a new parameter WORD wParam for + WM_MDITILE second tiling method (MDITILE_HORIZONTAL in wParam) as + used in Win3.1 + +Sun Jan 28 14:20:00 1996 Cameron Heide + + * [miscemu/int2f.c] + Added a small bit of MSCDEX emulation. + + * [windows/alias.c] + ALIAS_RegisterAlias was returning the hash value when it should + have been returning the record number. + +Sat Jan 27 10:53:51 1996 Jim Peterson + + * [include/shell.h] [include/wintypes.h] + Moved definition of HKEY and LPHKEY types to include/wintypes.h. + Declared FONTENUMPROC in wintypes.h. + + * [include/windows.h] + Added definition of KERNINGPAIR and LPKERNINGPAIR types. Added + declarations for CopyCursor(), CopyIcon(), EnumFontFamilies(), + ExtractIcon(), FatalAppExit(), FindExecutable(), GetClipCursor(), + GetKerningPairs(), GetQueueStatus(), GetRasterizerCaps(), + IsGDIObject(), IsMenu(), IsTask(), RegCloseKey(), RegCreateKey(), + RegDeleteKey(), RegEnumKey(), RegOpenKey(), RegQueryValue(), + RegSetValue(), ResetDC(), ShellExecute(), SystemParametersInfo(), + and wsprintf(). + + * [tools/makehtml.pl] [documentation/apiw.index] + New files that scan windows.h, commdlg.h, and toolhelp.h and output + an HTML sorted list with optional links to www.willows.com and a + tally of unimplemented APIW functions. + + * [objects/cursoricon.c] + Added Win32 versions of CopyIcon() and CopyCursor() for use in + libwine. + + * [win32/resource.c] [win32/winprocs.c] + Added '#include "libres.h"' and explicit declarations of windows + procs in order to avoid warnings. + + * [windows/utility.c] + Added Win32 version of MulDiv() for libwine. + + * [*/*] [include/windows.h] + Changed several function declarations to comply more strictly to + the windows API (without, hopefully, altering their functionality). + + * [controls/menu.c] + Made the return value of CheckMenuItem be the previous state of + the menu item if it was found, otherwise -1 as specified in the + SDK. This conflicts with the APIW specification, which says it + should return TRUE if successful, otherwise FALSE. + + * [include/windows.h] + Added obsolete WM_SIZE message wParam names for compatibility. + Added WinHelp() command constants, even though they are not yet + supported. + + * [rc/winerc.c] + Tidied up transform_binary_file(). In argument checking, flattened + any invalid characters specified with the prefix argument. + + * [library/libres.c] + Made FindResource() case-insensitive when parameter 'name' is a string. + +Sat Jan 27 02:30 1996 Uwe Bonnes + + * [loader/pe_image.c] + fixup_imports: Find builtins for Borland style entries, too + +Fri Jan 26 10:24:00 1996 Martin von Loewis + + * [controls/menu.c] + LoadMenu: branch to Win32 for PE modules + + * [if1632/gdi.spec][if1632/kernel32.spec][if1632/user32.spec] + DeleteObject, GetPixel, SetPixel,WritePrivateProfileStringA, + WriteProfileStringA, EmptyClipboard, EnableMenuItem, EnableScrollBar, + EnableWindow, InvalidateRect, SetWindowTextA, WinHelpA: new relays + DrawTextA, MoveToEx, GetClientRect, InvalidateRect, LoadBitmapA/W, + LoadAcceleratorsA/W, LoadMenu[Indirect]A/W, LoadStringA/W: changed + to convert parameters or naming convention + + * [include/kernel32.h][include/wintypes.h] + moved WCHAR, defined LPWSTR + + * [include/string32.h][win32/string32.c][include/struct32.h] + New files + + * [loader/module.h] + LoadModule: exit after returning from PE_LoadModule + + * [loader/pe_image.c] + my_wcstombs: isascii does not work on Linux for Unicode + PE_LoadImage: Handle directories + + * [misc/user32.c] + USER32_RECT32to16, USER32_RECT16to32: new functions + implemented new user32 relays + + * [misc/newfns.c] + WIN32_WinHelpA: new function + + * [win32/param32.c] + New file + + * [win32/resource.c] + GetResDirEntry: added support for named entries + WIN32_LoadAcceleratorsW: invoke *32 resource functions + WIN32_LoadBitmapA: convert name to unicode if appropriate + WIN32_ParseMenu: new function + implemented new resource functions from user32.spec + +Wed Jan 24 18:09:00 1996 Alex Korobka + + * [objects/cursoricon.c] + GetIconId() and LoadIconHandler() functions. + + * [windows/mdi.c] + Better maximization support, TranslateMDISysAccel() function, + misc improvements. + + * [windows/defwnd.c] + Fix for WM_WINDOWPOSCHANGED message handler. + + * [windows/winpos.c] + Rewrote WindowFromPoint() function. + +Sun Jan 21 1996 17:05:09 Marcus Meissner + + * [include/toolhelp.h] [misc/toolhelp.c] + Added Notify(Un)Register, but no callbacks yet. + +Fri Jan 19 01:43:37 1996 Victor Schneider + + * [Makefile.in] + Added target for libwine.so.1.0. + + * [library/winmain.c] + For WINELIBDLL, _WinMain just returns hInstance instead of calling + WinMain(). + + * [misc/main.c] + For WINELIBDLL, renamed main() to _wine_main() for calling from the + stub main function. + + * [library/winestub.c] (new file) + Provides a stub main() function for using libwine.so. + +Tue Jan 16 11:04:34 1996 Anand Kumria + + * [winsocket.c] + Fix EPERM problem. + + * [global.c] + Attempt to do some sanity checking in MemManInfo(). + + * [Changelog] + Fix changelog oversight for previous entry. + +--------------------------------------------------------------------- Sun Jan 14 13:45:22 1996 Alexandre Julliard * [configure.in] @@ -113,6 +389,9 @@ Tue Jan 02 14:00:00 1996 Anand Kumria [misc/user.c] [windows/message.c] Implement TOOLHELP.80 TimerCount. Fix GetTickCount. + * [winsocket.c] + Fixed ENOENT error. + * [miscemu/dpmi.c] Implement DPMI Get Page Size (AX=0604, INT 31) diff --git a/Make.rules.in b/Make.rules.in index a6d40638711..d871a6f6038 100644 --- a/Make.rules.in +++ b/Make.rules.in @@ -73,10 +73,7 @@ depend:: $(C_SRCS) mv tmp_make Makefile clean:: - $(RM) *.o \#*\# *~ *.bak *.flc tmp_make winerctmp.c - -distclean:: clean - $(RM) Makefile + $(RM) *.o \#*\# *~ *.bak *.orig *.rej *.flc tmp_make winerctmp.c dummy: diff --git a/Makefile.in b/Makefile.in index 0e3459b9112..dbbe50ed88e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -113,6 +113,12 @@ libwine.a: $(COMMONSUBDIRS) $(LIBSUBDIRS) dummy install_libwine.a: dummy $(INSTALL_DATA) libwine.a $(libdir) +libwine.so.1.0: $(COMMONSUBDIRS) $(LIBSUBDIRS) dummy + $(CC) -shared -Wl,-soname,libwine.so.1 -o$@ $(COMMONOBJS) $(LIBOBJS) $(LDOPTIONS) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LDLIBS) + +install_libwine.so.1.0: dummy + $(INSTALL_DATA) libwine.so.1.0 $(libdir) + $(ALLSUBDIRS): dummy @cd $@; $(SUBMAKE) @@ -124,13 +130,12 @@ etags: clean: for i in $(ALLSUBDIRS); do (cd $$i; $(MAKE) clean); done - $(RM) *.o \#*\# *~ *.bak *.flc wine wine.sym libwine.a TAGS - $(RM) include/\#*\# include/*~ include/*.bak include/*.flc + $(RM) *.o \#*\# *~ *.bak *.orig *.rej *.flc + $(RM) wine wine.sym libwine.a libwine.so.1.0 TAGS + (cd include; $(RM) *.o \#*\# *~ *.bak *.orig *.rej *.flc) -distclean: - for i in $(ALLSUBDIRS); do (cd $$i; $(MAKE) distclean); done - $(RM) *.o \#*\# *~ *.bak wine wine.sym libwine.a TAGS - $(RM) include/\#*\# include/*~ include/*.bak include/*.flc - $(RM) config.* include/config.h Make.rules Makefile +distclean: clean + $(RM) config.* Make.rules + $(RM) `find . \( -name Makefile -o -size 0 \) -print` dummy: diff --git a/README b/README index e00a1776415..54543850fcd 100644 --- a/README +++ b/README @@ -38,81 +38,15 @@ run "make depend; make". 3. SETUP +Once Wine has been built correctly, you can do "make install"; this +will install the wine executable and the man page. + Wine requires you to have a file /usr/local/etc/wine.conf (you can supply a different name when configuring wine) or a file called .winerc in your home directory. -The format of this config file is just like a Windows .ini file. -The file wine.ini contains a config file example. - -Here's an explanation of each section: - -* [drives] - -format: = -default: none - -This section is used to specify the root directory of each `dos'drive -as Windows' applications require a dos/mswindows based diskdrive & -directory scheme. - -If you mounted your dos-partition as /dos and installed Microsoft Windows -in c:\windows than you should specify c=/dos in the drives section. - -* [wine] - -format: windows = -default: c:\windows - -Used to specify an different windows directory. - -format: system = -default: c:\windows\system - -Used to specify an different system directory. - -format: temp = -default: c:\temp - -Used to specify a directory where Windows applications can store temporary -files. - -format: path = -default: c:\windows;c:\windows\system - -Used to specify the path which will be used to find executables and DLL's. - -format: symboltablefile = -default: wine.sym - -Used to specify the path and file name of the symbol table used by the -built-in debugger. - -* [serialports] - -format: com[12345678] = -default: none - -Used to specify the devices which are used as com1 - com8. - -* [parallelports] - -format: lpt[12345678] = -default: none - -Used to specify the devices which are used as lpt1 - lpt8. - -* [spy] - -format: exclude = -default: none - -Used to specify which messages will be excluded from the message logging. - -format: include = -default: none - -Used to specify which messages will be included in the message logging. +The format of this file is explained in the man page. The file +wine.ini contains a config file example. 4. RUNNING PROGRAMS diff --git a/configure b/configure index 0689562737d..ba6c93e45f7 100755 --- a/configure +++ b/configure @@ -14,6 +14,8 @@ ac_default_prefix=/usr/local # Any additions from configure.in: ac_help="$ac_help --with-library build Wine as a library instead of an emulator" +ac_help="$ac_help + --with-dll build Wine as a DLL instead of an emulator" ac_help="$ac_help --with-ipc use inter-process communication for DDE" ac_help="$ac_help @@ -562,6 +564,20 @@ else fi +# Check whether --with-dll or --without-dll was given. +if test "${with_dll+set}" = set; then + withval="$with_dll" + cat >> confdefs.h <<\EOF +#define WINELIB 1 +EOF + cat >> confdefs.h <<\EOF +#define WINELIBDLL 1 +EOF + + MAIN_TARGET="libwine.so.1.0" CFLAGS="$CFLAGS -fPIC" +fi + + # Check whether --with-ipc or --without-ipc was given. if test "${with_ipc+set}" = set; then @@ -700,7 +716,7 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error @@ -714,7 +730,7 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error @@ -820,7 +836,7 @@ test -z "$x_direct_test_library" && x_direct_test_library=Xt test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h cat > conftest.$ac_ext < EOF @@ -883,7 +899,7 @@ rm -f conftest* ac_save_LIBS="$LIBS" LIBS="-l$x_direct_test_library $LIBS" cat > conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext <&6 else cat > conftest.$ac_ext <&6 else cat > conftest.$ac_ext < EOF @@ -1574,7 +1590,7 @@ if eval "test \"`echo '$''{'ac_cv_header_stat_broken'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -1629,7 +1645,7 @@ if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&6 else cat > conftest.$ac_ext < #include @@ -1725,7 +1741,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -1743,7 +1759,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -1764,7 +1780,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -1799,7 +1815,7 @@ if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS diff --git a/configure.in b/configure.in index d8a94c0254d..9fbbd129d93 100644 --- a/configure.in +++ b/configure.in @@ -15,6 +15,11 @@ dnl **** Command-line arguments **** AC_ARG_WITH(library, [ --with-library build Wine as a library instead of an emulator], [AC_DEFINE(WINELIB) MAIN_TARGET="libwine.a"],[MAIN_TARGET="wine"]) + +AC_ARG_WITH(dll, +[ --with-dll build Wine as a DLL instead of an emulator], +[AC_DEFINE(WINELIB) AC_DEFINE(WINELIBDLL) + MAIN_TARGET="libwine.so.1.0" CFLAGS="$CFLAGS -fPIC"]) AC_SUBST(MAIN_TARGET) AC_ARG_WITH(ipc, diff --git a/controls/edit.c b/controls/edit.c index 98c28419f09..c0f7222db29 100644 --- a/controls/edit.c +++ b/controls/edit.c @@ -71,7 +71,8 @@ typedef struct unsigned short *TabStops;/* tab stops buffer */ BOOL HaveFocus; /* TRUE if this edit has the focus */ int ClientWidth; /* computed from the window's ClientRect */ - int ClientHeight; /* dito */ + int ClientHeight; /* ditto */ + char PasswordChar; /* The password character */ } EDITSTATE; #define EditBufStartLen(hwnd) (GetWindowLong(hwnd,GWL_STYLE) & ES_MULTILINE \ @@ -509,11 +510,11 @@ static void EDIT_WriteText(HWND hwnd, char *lp, int off, int len, int row, es->BlankLine[(es->ClientWidth / es->CharWidths[32]) + 1] = 0; } - if ((GetWindowLong( hwnd, GWL_STYLE ) & ES_PASSWORD)) + if ((es->PasswordChar && GetWindowLong( hwnd, GWL_STYLE ) & ES_PASSWORD)) { int len = strlen(str); char *buff = xmalloc( len+1 ); - memset( buff, '*', len ); + memset( buff, es->PasswordChar, len ); buff[len] = '\0'; TextOut( hdc, col - diff, row * es->txtht, buff, len ); } @@ -2269,6 +2270,7 @@ static long EDIT_WM_NCCreate(HWND hwnd, LONG lParam) es->ClientWidth = es->ClientHeight = 1; /* --- text buffer */ es->MaxTextLen = MAXTEXTLEN + 1; + es->PasswordChar = '*'; /* * Hack - If there is no local heap then hwnd should be a globalHeap block * and the local heap needs to be initilised to the same size(minus something) @@ -2758,7 +2760,8 @@ LRESULT EditWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) break; case EM_GETPASSWORDCHAR: - fprintf(stdnimp,"edit: cannot process EM_GETPASSWORDCHAR message\n"); + /* FIXME: is this the right place to return the character? */ + lResult = es->PasswordChar; break; case EM_GETRECT: @@ -2820,7 +2823,7 @@ LRESULT EditWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) break; case EM_SETPASSWORDCHAR: - fprintf(stdnimp,"edit: cannot process EM_SETPASSWORDCHAR message\n"); + es->PasswordChar = (char) wParam; break; case EM_SETREADONLY: diff --git a/controls/listbox.c b/controls/listbox.c index 7ecd806afc8..fc9ba605292 100644 --- a/controls/listbox.c +++ b/controls/listbox.c @@ -25,6 +25,7 @@ #include "listbox.h" #include "dos_fs.h" #include "drive.h" +#include "file.h" #include "stackframe.h" #include "stddebug.h" #include "debug.h" @@ -338,7 +339,7 @@ LPLISTSTRUCT ListBoxCreateItem(LPHEADLIST lphl, int id) } -int ListBoxInsertString(LPHEADLIST lphl, UINT uIndex, LPSTR newstr) +int ListBoxInsertString(LPHEADLIST lphl, UINT uIndex, LPCSTR newstr) { LPLISTSTRUCT *lppls, lplsnew, lpls; HANDLE hStr; @@ -401,7 +402,7 @@ int ListBoxInsertString(LPHEADLIST lphl, UINT uIndex, LPSTR newstr) } -int ListBoxAddString(LPHEADLIST lphl, LPSTR newstr) +int ListBoxAddString(LPHEADLIST lphl, LPCSTR newstr) { LONG dwStyle = GetWindowLong(lphl->hSelf,GWL_STYLE); UINT pos = (UINT) -1; @@ -424,7 +425,7 @@ int ListBoxGetText(LPHEADLIST lphl, UINT uIndex, LPSTR OutStr) dprintf_listbox(stddeb, "ListBoxGetText // OutStr==NULL\n"); return 0; } - + *OutStr = '\0'; lpls = ListBoxGetItem (lphl, uIndex); if (lpls == NULL) return LB_ERR; @@ -633,55 +634,42 @@ int ListBoxGetSel(LPHEADLIST lphl, WORD wIndex) /* ------------------------- dir listing ------------------------ */ -int ListBoxDirectory(LPHEADLIST lphl, UINT attrib, LPSTR filespec) +LONG ListBoxDirectory(LPHEADLIST lphl, UINT attrib, LPCSTR filespec) { - const char *pathPtr, *maskPtr; - char mask[12], path[MAX_PATHNAME_LEN]; + char temp[16], mask[13]; + char *path, *p; + const char *ptr; int skip, count; + LONG ret; DOS_DIRENT entry; - char temp[256]; - int drive; - LPSTR tstr; - - dprintf_listbox(stddeb,"ListBoxDirectory: %s, %4x\n",filespec,attrib); - - if (strchr(filespec, '\\') || strchr(filespec, ':')) { - if (filespec[1] == ':') { - drive = toupper(filespec[0]) - 'A'; - filespec += 2; + dprintf_listbox(stddeb, "ListBoxDirectory: '%s' %04x\n", filespec, attrib); + if (!filespec) return LB_ERR; + if (!(ptr = DOSFS_GetUnixFileName( filespec, FALSE ))) return LB_ERR; + path = xstrdup(ptr); + p = strrchr( path, '/' ); + *p++ = '\0'; + if (!(ptr = DOSFS_ToDosFCBFormat( p ))) + { + free( path ); + return LB_ERR; } - else drive = DRIVE_GetCurrentDrive(); - strcpy(temp,filespec); - tstr = strrchr(temp, '\\'); - if (tstr != NULL) { - *(tstr+1) = 0; - filespec += tstr - temp + 1; - if (!DRIVE_Chdir( drive, temp )) return 0; - } - DRIVE_SetCurrentDrive( drive ); - dprintf_listbox(stddeb,"Changing directory to %c:%s, filemask is %s\n", - drive+'A', temp, filespec); - } + strcpy( mask, ptr ); + dprintf_listbox(stddeb, "ListBoxDirectory: path=%s mask=%s\n", path, mask); - if (!(maskPtr = DOSFS_ToDosFCBFormat( filespec ))) return 0; - strcpy( mask, maskPtr ); - if (!(pathPtr = DOSFS_GetUnixFileName( ".", TRUE ))) return 0; - lstrcpyn( path, pathPtr, sizeof(path) ); - skip = 0; - drive = DRIVE_GetCurrentDrive(); - - while ((count = DOSFS_FindNext( path, mask, drive, - attrib, skip, &entry )) > 0) + skip = ret = 0; + attrib &= ~FA_LABEL; + while ((count = DOSFS_FindNext( path, mask, 0, attrib, skip, &entry )) > 0) { skip += count; if (entry.attr & FA_DIRECTORY) { - if ((attrib & DDL_DIRECTORY) && strcmp(entry.name, ".")) + if ((attrib & DDL_DIRECTORY) && strcmp(entry.name, ". ")) { - sprintf(temp, "[%s]", entry.name); - if (ListBoxAddString(lphl, temp) == LB_ERR) break; + sprintf(temp, "[%s]", DOSFS_ToDosDTAFormat( entry.name ) ); + AnsiLower( temp ); + if ((ret = ListBoxAddString(lphl, temp)) == LB_ERR) break; } } else /* not a directory */ @@ -690,24 +678,23 @@ int ListBoxDirectory(LPHEADLIST lphl, UINT attrib, LPSTR filespec) ((attrib & (FA_RDONLY|FA_HIDDEN|FA_SYSTEM|FA_ARCHIVE)) == (entry.attr & (FA_RDONLY|FA_HIDDEN|FA_SYSTEM|FA_ARCHIVE)))) { - if (ListBoxAddString(lphl, entry.name) == LB_ERR) break; + strcpy( temp, DOSFS_ToDosDTAFormat( entry.name ) ); + AnsiLower( temp ); + if ((ret = ListBoxAddString(lphl, temp)) == LB_ERR) break; } } } - if (attrib & DDL_DRIVES) { int x; - for (x = 0; x < MAX_DOS_DRIVES; x++) + strcpy( temp, "[-a-]" ); + for (x = 0; x < MAX_DOS_DRIVES; x++, temp[2]++) { if (DRIVE_IsValid(x)) - { - sprintf(temp, "[-%c-]", 'a'+x); - if (ListBoxInsertString(lphl, (UINT)-1, temp) == LB_ERR) break; - } + if ((ret = ListBoxAddString(lphl, temp)) == LB_ERR) break; } } - return 1; + return ret; } /* ------------------------- dimensions ------------------------- */ @@ -1372,13 +1359,13 @@ static LONG LBResetContent(HWND hwnd, WORD wParam, LONG lParam) */ static LONG LBDir(HWND hwnd, WORD wParam, LONG lParam) { - WORD wRet; - LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); - dprintf_listbox(stddeb,"ListBox LB_DIR !\n"); + LONG ret; + LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); + dprintf_listbox(stddeb,"ListBox LB_DIR !\n"); - wRet = ListBoxDirectory(lphl, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam)); - ListBoxUpdateWindow(hwnd, lphl, TRUE); - return wRet; + ret = ListBoxDirectory(lphl, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam)); + ListBoxUpdateWindow(hwnd, lphl, TRUE); + return ret; } /*********************************************************************** @@ -1390,9 +1377,9 @@ static LONG LBAddString(HWND hwnd, WORD wParam, LONG lParam) LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); if (lphl->HasStrings) - wRet = ListBoxAddString(lphl, (LPSTR)PTR_SEG_TO_LIN(lParam)); + wRet = ListBoxAddString(lphl, (LPCSTR)PTR_SEG_TO_LIN(lParam)); else - wRet = ListBoxAddString(lphl, (LPSTR)lParam); + wRet = ListBoxAddString(lphl, (LPCSTR)lParam); ListBoxUpdateWindow(hwnd,lphl,TRUE); return wRet; @@ -1421,9 +1408,9 @@ static LONG LBInsertString(HWND hwnd, WORD wParam, LONG lParam) LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); if (lphl->HasStrings) - wRet = ListBoxInsertString(lphl, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam)); + wRet = ListBoxInsertString(lphl, wParam, (LPCSTR)PTR_SEG_TO_LIN(lParam)); else - wRet = ListBoxInsertString(lphl, wParam, (LPSTR)lParam); + wRet = ListBoxInsertString(lphl, wParam, (LPCSTR)lParam); ListBoxUpdateWindow(hwnd,lphl,TRUE); return wRet; @@ -1895,70 +1882,126 @@ LRESULT ListBoxWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) return DefWindowProc(hwnd, message, wParam, lParam); } -/************************************************************************ - * DlgDirSelect [USER.99] + +/********************************************************************** + * DlgDirSelect (USER.99) */ -BOOL DlgDirSelect(HWND hDlg, LPSTR lpStr, int nIDLBox) +BOOL DlgDirSelect( HWND hDlg, LPSTR lpStr, int id ) { - HWND hwnd; - LPHEADLIST lphl; - char s[130]; + char buffer[20]; + INT i; - dprintf_listbox( stddeb, "DlgDirSelect("NPFMT", '%s', %d) \n", hDlg, lpStr, - nIDLBox ); - - hwnd = GetDlgItem(hDlg, nIDLBox); - lphl = ListBoxGetStorageHeader(hwnd); - if(lphl->ItemFocused == -1) { - dprintf_listbox(stddeb, "Nothing selected!\n"); - return FALSE; - } - ListBoxGetText(lphl, lphl->ItemFocused, s); - dprintf_listbox(stddeb, "Selection is %s\n", s); - if( s[0] == '[' ) { - if( s[1] == '-' ) { - strncpy( lpStr, s+2, strlen(s)-4 ); /* device name */ - lpStr[ strlen(s)-4 ] = 0; - strcat( lpStr, ":" ); + dprintf_listbox( stddeb, "DlgDirSelect: "NPFMT" '%s' %d\n", + hDlg, lpStr, id ); + if ((i = SendDlgItemMessage( hDlg, id, LB_GETCURSEL, 0, 0 )) == LB_ERR) + return FALSE; + SendDlgItemMessage( hDlg, id, LB_GETTEXT, i, MAKE_SEGPTR(buffer) ); + if (buffer[0] == '[') /* drive or directory */ + { + if (buffer[1] == '-') /* drive */ + { + lpStr[0] = buffer[2]; + lpStr[1] = ':'; + lpStr[2] = '\0'; + dprintf_listbox( stddeb, "Returning drive '%s'\n", lpStr ); + return TRUE; + } + strcpy( lpStr, buffer + 1 ); + lpStr[strlen(lpStr)-1] = '\\'; + dprintf_listbox( stddeb, "Returning directory '%s'\n", lpStr ); + return TRUE; } - else { - strncpy( lpStr, s+1, strlen(s)-2 ); /* directory name */ - lpStr[ strlen(s)-2 ] = 0; - strcat( lpStr, "\\" ); - } - dprintf_listbox( stddeb, "Returning %s\n", lpStr ); - return TRUE; - } else { - strcpy( lpStr, s ); /* file name */ - dprintf_listbox( stddeb, "Returning %s\n", lpStr ); + strcpy( lpStr, buffer ); + dprintf_listbox( stddeb, "Returning file '%s'\n", lpStr ); return FALSE; - } } -/************************************************************************ - * DlgDirList [USER.100] +/********************************************************************** + * DlgDirList (USER.100) */ -INT DlgDirList( HWND hDlg, SEGPTR path, INT idLBox, INT idStatic, WORD wType ) +INT DlgDirList( HWND hDlg, SEGPTR spec, INT idLBox, INT idStatic, WORD attrib ) { - INT ret = 0; - - dprintf_listbox( stddeb, "DlgDirList("NPFMT", %08lx, %d, %d, %04X) \n", - hDlg, (DWORD)path, idLBox, idStatic, wType ); - if (idLBox) + char *filespec = (char *)PTR_SEG_TO_LIN( spec ); + int drive; + HWND hwnd; + +#define SENDMSG(msg,wparam,lparam) \ + ((attrib & DDL_POSTMSGS) ? PostMessage( hwnd, msg, wparam, lparam ) \ + : SendMessage( hwnd, msg, wparam, lparam )) + + dprintf_listbox( stddeb, "DlgDirList: "NPFMT" '%s' %d %d %04x\n", + hDlg, filespec ? filespec : "NULL", + idLBox, idStatic, attrib ); + + if (filespec && (filespec[1] == ':')) { - SendDlgItemMessage( hDlg, idLBox, LB_RESETCONTENT, 0, 0 ); - ret = (SendDlgItemMessage( hDlg, idLBox, LB_DIR, wType, path ) >= 0); + drive = toupper( filespec[0] ) - 'A'; + filespec += 2; + if (!DRIVE_SetCurrentDrive( drive )) return FALSE; } - if (idStatic) + else drive = DRIVE_GetCurrentDrive(); + + if (idLBox && ((hwnd = GetDlgItem( hDlg, idLBox )) != 0)) + { + char mask[20]; + char temp[] = "*.*"; + + if (!filespec[0]) strcpy( mask, "*.*" ); + else + { + const char *ptr; + BYTE attr; + if (((ptr = DOSFS_GetUnixFileName( filespec, TRUE )) != NULL) && + FILE_Stat( ptr, &attr, NULL, NULL, NULL ) && + (attr & FA_DIRECTORY)) + { + /* If the path exists and is a directory, chdir to it */ + if (!DRIVE_Chdir( drive, filespec )) return FALSE; + strcpy( mask, "*.*" ); + } + else + { + char *p, *p2; + p = filespec; + if ((p2 = strrchr( p, '\\' ))) p = p2 + 1; + if ((p2 = strrchr( p, '/' ))) p = p2 + 1; + lstrcpyn( mask, p, sizeof(mask) ); + if (p != filespec) + { + p[-1] = '\0'; + if (!DRIVE_Chdir( drive, filespec )) return FALSE; + } + } + } + + strcpy( (char *)PTR_SEG_TO_LIN(spec), mask ); + + dprintf_listbox(stddeb, "ListBoxDirectory: path=%c:\\%s mask=%s\n", + 'A' + drive, DRIVE_GetDosCwd(drive), mask); + + SENDMSG( LB_RESETCONTENT, 0, 0 ); + if ((attrib & DDL_DIRECTORY) && !(attrib & DDL_EXCLUSIVE)) + { + if (SENDMSG( LB_DIR, attrib & ~(DDL_DIRECTORY | DDL_DRIVES), + (LPARAM)spec ) == LB_ERR) return FALSE; + if (SENDMSG( LB_DIR, (attrib & (DDL_DIRECTORY | DDL_DRIVES)) | DDL_EXCLUSIVE, + (LPARAM)MAKE_SEGPTR(temp) ) == LB_ERR) return FALSE; + } + else + { + if (SENDMSG( LB_DIR, attrib, (LPARAM)spec) == LB_ERR) return FALSE; + } + } + + if (idStatic && ((hwnd = GetDlgItem( hDlg, idStatic )) != 0)) { char temp[256]; - int drive = DRIVE_GetCurrentDrive(); strcpy( temp, "A:\\" ); temp[0] += drive; lstrcpyn( temp+3, DRIVE_GetDosCwd(drive), 253 ); - SendDlgItemMessage( hDlg, idStatic, WM_SETTEXT, - 0, (LPARAM)MAKE_SEGPTR(temp) ); - } - return ret; + AnsiLower( temp ); + SENDMSG( WM_SETTEXT, 0, (LPARAM)MAKE_SEGPTR(temp) ); + } + return TRUE; } diff --git a/controls/menu.c b/controls/menu.c index e820d181913..23982342b90 100644 --- a/controls/menu.c +++ b/controls/menu.c @@ -19,11 +19,14 @@ #include "syscolor.h" #include "sysmetrics.h" #include "menu.h" +#include "module.h" +#include "neexe.h" #include "user.h" #include "win.h" #include "message.h" #include "graphics.h" #include "resource.h" +#include "stackframe.h" #include "stddebug.h" #include "debug.h" @@ -51,14 +54,17 @@ static BOOL fEndMenuCalled = FALSE; #define IS_STRING_ITEM(flags) (!((flags) & (MF_BITMAP | MF_OWNERDRAW | \ MF_MENUBARBREAK | MF_MENUBREAK | MF_SEPARATOR))) +#define SET_OWNERDRAW_DATA(item,data) \ + ((item)->hText = LOWORD((DWORD)(data)), (item)->xTab = HIWORD((DWORD)(data))) + +#define GET_OWNERDRAW_DATA(item) \ + ((DWORD)MAKELONG( (WORD)(item)->hText, (item)->xTab )) extern void NC_DrawSysButton(HWND hwnd, HDC hdc, BOOL down); /* nonclient.c */ static HBITMAP hStdCheck = 0; static HBITMAP hStdMnArrow = 0; -WORD * ParseMenuResource(WORD *first_item, int level, HMENU hMenu); - /*********************************************************************** * MENU_Init @@ -111,7 +117,7 @@ static HMENU MENU_CopySysMenu(void) POPUPMENU *menu; if (!(handle = SYSRES_LoadResource( SYSRES_MENU_SYSMENU ))) return 0; - hMenu = LoadMenuIndirect( GlobalLock( handle ) ); + hMenu = LoadMenuIndirect( WIN16_GlobalLock( handle ) ); SYSRES_FreeResource( handle ); if (!hMenu) { @@ -240,7 +246,7 @@ static UINT MENU_FindItemByKey( HWND hwndOwner, HMENU hmenu, UINT key ) { if (IS_STRING_ITEM(lpitem->item_flags)) { - char *p = strchr( lpitem->item_text, '&' ); + char *p = strchr( (char *)USER_HEAP_LIN_ADDR(lpitem->hText), '&' ); if (p && (p[1] != '&') && (toupper(p[1]) == key)) return i; } } @@ -269,27 +275,21 @@ static void MENU_CalcItemSize( HDC hdc, LPMENUITEM lpitem, HWND hwndOwner, char *p; SetRect( &lpitem->rect, orgX, orgY, orgX, orgY ); - lpitem->xTab = 0; - if (lpitem->item_flags & MF_OWNERDRAW) { - static HANDLE mistrh = 0; - static SEGPTR mistrsegp = 0; - static LPMEASUREITEMSTRUCT mistruct=NULL; - if (mistruct == NULL) { - mistrh = GlobalAlloc(0,sizeof(MEASUREITEMSTRUCT)); - mistrsegp = (SEGPTR)WIN16_GlobalLock(mistrh); - mistruct = PTR_SEG_TO_LIN(mistrsegp); - } - mistruct->CtlType = ODT_MENU; - mistruct->itemID = lpitem->item_id; - mistruct->itemData = (long int)lpitem->item_text; - mistruct->itemHeight = 16; - mistruct->itemWidth = 30; - SendMessage(hwndOwner,WM_MEASUREITEM,0,(LPARAM)mistrsegp); - lpitem->rect.bottom += mistruct->itemHeight; - lpitem->rect.right += mistruct->itemWidth; - dprintf_menu(stddeb,"DrawMenuItem: MeasureItem %04x %d:%d!\n", - lpitem->item_id,mistruct->itemWidth, mistruct->itemHeight); - return; + + if (lpitem->item_flags & MF_OWNERDRAW) + { + MEASUREITEMSTRUCT mis; + mis.CtlType = ODT_MENU; + mis.itemID = lpitem->item_id; + mis.itemData = GET_OWNERDRAW_DATA(lpitem); + mis.itemHeight = 16; + mis.itemWidth = 30; + SendMessage( hwndOwner, WM_MEASUREITEM, 0, (LPARAM)MAKE_SEGPTR(&mis) ); + lpitem->rect.bottom += mis.itemHeight; + lpitem->rect.right += mis.itemWidth; + dprintf_menu( stddeb, "DrawMenuItem: MeasureItem %04x %dx%d!\n", + lpitem->item_id, mis.itemWidth, mis.itemHeight ); + return; } if (lpitem->item_flags & MF_SEPARATOR) @@ -308,33 +308,38 @@ static void MENU_CalcItemSize( HDC hdc, LPMENUITEM lpitem, HWND hwndOwner, if (lpitem->item_flags & MF_BITMAP) { BITMAP bm; - GetObject( (HBITMAP)lpitem->hText, sizeof(BITMAP), (LPSTR)&bm ); - lpitem->rect.right += bm.bmWidth; - lpitem->rect.bottom += bm.bmHeight; + if (GetObject( (HBITMAP)lpitem->hText, sizeof(BITMAP), (LPSTR)&bm )) + { + lpitem->rect.right += bm.bmWidth; + lpitem->rect.bottom += bm.bmHeight; + } return; } - /* If we get here, then it is a text item */ + /* If we get here, then it must be a text item */ - dwSize = (lpitem->item_text == NULL) ? 0 : GetTextExtent( hdc, lpitem->item_text, strlen(lpitem->item_text)); - lpitem->rect.right += LOWORD(dwSize); - lpitem->rect.bottom += MAX( HIWORD(dwSize), SYSMETRICS_CYMENU ); + if (IS_STRING_ITEM( lpitem->item_flags )) + { + const char *text = (const char *)USER_HEAP_LIN_ADDR( lpitem->hText ); + dwSize = GetTextExtent( hdc, text, strlen(text) ); + lpitem->rect.right += LOWORD(dwSize); + lpitem->rect.bottom += MAX( HIWORD(dwSize), SYSMETRICS_CYMENU ); + lpitem->xTab = 0; - if (menuBar) lpitem->rect.right += MENU_BAR_ITEMS_SPACE; - else if ( ( lpitem->item_text != NULL ) && (p = strchr( lpitem->item_text, '\t' )) != NULL) - { - /* Item contains a tab (only meaningful in popup menus) */ - lpitem->xTab = check_bitmap_width + MENU_TAB_SPACE + - LOWORD( GetTextExtent( hdc, lpitem->item_text, - (int)(p - lpitem->item_text) )); - lpitem->rect.right += MENU_TAB_SPACE; - } - else - { - if( ( lpitem->item_text != NULL ) && strchr( lpitem->item_text, '\b' )) - lpitem->rect.right += MENU_TAB_SPACE; - lpitem->xTab = lpitem->rect.right - check_bitmap_width - - arrow_bitmap_width; + if (menuBar) lpitem->rect.right += MENU_BAR_ITEMS_SPACE; + else if ((p = strchr( text, '\t' )) != NULL) + { + /* Item contains a tab (only meaningful in popup menus) */ + lpitem->xTab = check_bitmap_width + MENU_TAB_SPACE + + LOWORD( GetTextExtent( hdc, text, (int)(p - text) )); + lpitem->rect.right += MENU_TAB_SPACE; + } + else + { + if (strchr( text, '\b' )) lpitem->rect.right += MENU_TAB_SPACE; + lpitem->xTab = lpitem->rect.right - check_bitmap_width + - arrow_bitmap_width; + } } } @@ -372,7 +377,7 @@ static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop, HWND hwndOwner ) if (lpitem->item_flags & MF_MENUBARBREAK) orgX++; maxX = MAX( maxX, lpitem->rect.right ); orgY = lpitem->rect.bottom; - if (lpitem->xTab) + if (IS_STRING_ITEM(lpitem->item_flags) && lpitem->xTab) { maxTab = MAX( maxTab, lpitem->xTab ); maxTabWidth = MAX(maxTabWidth,lpitem->rect.right-lpitem->xTab); @@ -384,7 +389,8 @@ static void MENU_PopupMenuCalcSize( LPPOPUPMENU lppop, HWND hwndOwner ) for (lpitem = &items[start]; start < i; start++, lpitem++) { lpitem->rect.right = maxX; - if (lpitem->xTab) lpitem->xTab = maxTab; + if (IS_STRING_ITEM(lpitem->item_flags) && lpitem->xTab) + lpitem->xTab = maxTab; } lppop->Height = MAX( lppop->Height, orgY ); } @@ -407,7 +413,7 @@ static void MENU_MenuBarCalcSize( HDC hdc, LPRECT lprect, LPPOPUPMENU lppop, if ((lprect == NULL) || (lppop == NULL)) return; if (lppop->nItems == 0) return; - dprintf_menucalc(stddeb,"MenuBarCalcSize left=%ld top=%ld right=%ld bottom=%ld !\n", + dprintf_menu(stddeb,"MENU_MenuBarCalcSize left=%ld top=%ld right=%ld bottom=%ld !\n", (LONG)lprect->left, (LONG)lprect->top, (LONG)lprect->right, (LONG)lprect->bottom); items = (MENUITEM *)USER_HEAP_LIN_ADDR( lppop->hItems ); lppop->Width = lprect->right - lprect->left; @@ -473,30 +479,26 @@ static void MENU_DrawMenuItem( HWND hwnd, HDC hdc, LPMENUITEM lpitem, { RECT rect; - if (lpitem->item_flags & MF_OWNERDRAW) { - static HANDLE distrh = 0; - static SEGPTR distrsegp = 0; - static LPDRAWITEMSTRUCT distruct=NULL; - if (distruct == NULL) { - distrh = GlobalAlloc(0,sizeof(DRAWITEMSTRUCT)); - distrsegp = (SEGPTR)WIN16_GlobalLock(distrh); - distruct = PTR_SEG_TO_LIN(distrsegp); - } - dprintf_menu(stddeb,"DrawMenuItem: Ownerdraw!\n"); - distruct->CtlType = ODT_MENU; - distruct->itemID = lpitem->item_id; - distruct->itemData = (long int)lpitem->item_text; - distruct->itemState = 0; - if (lpitem->item_flags & MF_CHECKED) distruct->itemState |= ODS_CHECKED; - if (lpitem->item_flags & MF_GRAYED) distruct->itemState |= ODS_GRAYED; - if (lpitem->item_flags & MF_HILITE) distruct->itemState |= ODS_SELECTED; - distruct->itemAction = ODA_DRAWENTIRE | ODA_SELECT | ODA_FOCUS; - distruct->hwndItem = hwnd; - distruct->hDC = hdc; - distruct->rcItem = lpitem->rect; - SendMessage(hwnd,WM_DRAWITEM,0,(LPARAM)distrsegp); - return; + if (lpitem->item_flags & MF_OWNERDRAW) + { + DRAWITEMSTRUCT dis; + + dprintf_menu( stddeb, "DrawMenuItem: Ownerdraw!\n" ); + dis.CtlType = ODT_MENU; + dis.itemID = lpitem->item_id; + dis.itemData = GET_OWNERDRAW_DATA(lpitem); + dis.itemState = 0; + if (lpitem->item_flags & MF_CHECKED) dis.itemState |= ODS_CHECKED; + if (lpitem->item_flags & MF_GRAYED) dis.itemState |= ODS_GRAYED; + if (lpitem->item_flags & MF_HILITE) dis.itemState |= ODS_SELECTED; + dis.itemAction = ODA_DRAWENTIRE | ODA_SELECT | ODA_FOCUS; + dis.hwndItem = hwnd; + dis.hDC = hdc; + dis.rcItem = lpitem->rect; + SendMessage( hwnd, WM_DRAWITEM, 0, MAKE_SEGPTR(&dis) ); + return; } + if (menuBar && (lpitem->item_flags & MF_SEPARATOR)) return; rect = lpitem->rect; @@ -583,35 +585,34 @@ static void MENU_DrawMenuItem( HWND hwnd, HDC hdc, LPMENUITEM lpitem, return; } /* No bitmap - process text if present */ - else if ((lpitem->item_text) != ((char *) NULL)) + else if (IS_STRING_ITEM(lpitem->item_flags)) { register int i; + const char *text = (const char *)USER_HEAP_LIN_ADDR( lpitem->hText ); if (menuBar) { rect.left += MENU_BAR_ITEMS_SPACE / 2; rect.right -= MENU_BAR_ITEMS_SPACE / 2; - i = strlen( lpitem->item_text ); + i = strlen( text ); } else { - for (i = 0; lpitem->item_text[i]; i++) - if ((lpitem->item_text[i] == '\t') || - (lpitem->item_text[i] == '\b')) break; + for (i = 0; text[i]; i++) + if ((text[i] == '\t') || (text[i] == '\b')) break; } - DrawText( hdc, lpitem->item_text, i, &rect, - DT_LEFT | DT_VCENTER | DT_SINGLELINE ); + DrawText( hdc, text, i, &rect, DT_LEFT | DT_VCENTER | DT_SINGLELINE ); - if (lpitem->item_text[i]) /* There's a tab or flush-right char */ + if (text[i]) /* There's a tab or flush-right char */ { - if (lpitem->item_text[i] == '\t') + if (text[i] == '\t') { rect.left = lpitem->xTab; - DrawText( hdc, lpitem->item_text + i + 1, -1, &rect, + DrawText( hdc, text + i + 1, -1, &rect, DT_LEFT | DT_VCENTER | DT_SINGLELINE ); } - else DrawText( hdc, lpitem->item_text + i + 1, -1, &rect, + else DrawText( hdc, text + i + 1, -1, &rect, DT_RIGHT | DT_VCENTER | DT_SINGLELINE ); } } @@ -887,6 +888,149 @@ static void MENU_SelectPrevItem( HWND hwndOwner, HMENU hmenu ) } +/********************************************************************** + * MENU_SetItemData + * + * Set an item flags, id and text ptr. + */ +static BOOL MENU_SetItemData( MENUITEM *item, UINT flags, UINT id, SEGPTR data) +{ + item->item_flags = flags & ~(MF_HILITE | MF_MOUSESELECT); + item->item_id = id; + + SetRectEmpty( &item->rect ); + if (IS_STRING_ITEM(flags)) + { + char *str = (char *)PTR_SEG_TO_LIN(data); + HANDLE hText; + + /* Item beginning with a backspace is a help item */ + if (*str == '\b') + { + item->item_flags |= MF_HELP; + str++; + } + if (!(hText = USER_HEAP_ALLOC( strlen(str)+1 ))) return FALSE; + item->hText = hText; + strcpy( (char *)USER_HEAP_LIN_ADDR( hText ), str ); + } + else if (flags & MF_BITMAP) item->hText = (HANDLE)(DWORD)data; + else if (flags & MF_OWNERDRAW) SET_OWNERDRAW_DATA( item, data ); + return TRUE; +} + + +/********************************************************************** + * MENU_InsertItem + * + * Insert a new item into a menu. + */ +static MENUITEM *MENU_InsertItem( HMENU hMenu, UINT pos, UINT flags ) +{ + HANDLE hNewItems; + MENUITEM *newItems; + POPUPMENU *menu; + + if (!(menu = (POPUPMENU *)USER_HEAP_LIN_ADDR(hMenu))) + { + dprintf_menu( stddeb, "MENU_InsertItem: "NPFMT" not a menu handle\n", + hMenu ); + return NULL; + } + + /* Find where to insert new item */ + + if ((flags & MF_BYPOSITION) && + ((pos == (UINT)-1) || (pos == menu->nItems))) + { + /* Special case: append to menu */ + /* Some programs specify the menu length to do that */ + pos = menu->nItems; + } + else + { + if (!MENU_FindItem( &hMenu, &pos, flags )) + { + dprintf_menu( stddeb, "MENU_InsertItem: item %x not found\n", + pos ); + return NULL; + } + if (!(menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu))) + { + dprintf_menu(stddeb,"MENU_InsertItem: "NPFMT" not a menu handle\n", + hMenu); + return NULL; + } + } + + /* Create new items array */ + + hNewItems = USER_HEAP_ALLOC( sizeof(MENUITEM) * (menu->nItems+1) ); + if (!hNewItems) + { + dprintf_menu( stddeb, "MENU_InsertMenu: allocation failed\n" ); + return NULL; + } + newItems = (MENUITEM *) USER_HEAP_LIN_ADDR( hNewItems ); + if (menu->nItems > 0) + { + /* Copy the old array into the new */ + MENUITEM *oldItems = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems ); + if (pos > 0) memcpy( newItems, oldItems, pos * sizeof(MENUITEM) ); + if (pos < menu->nItems) memcpy( &newItems[pos+1], &oldItems[pos], + (menu->nItems-pos)*sizeof(MENUITEM) ); + + USER_HEAP_FREE( menu->hItems ); + } + menu->hItems = hNewItems; + menu->nItems++; + return &newItems[pos]; +} + + +/********************************************************************** + * MENU_ParseResource + * + * Parse a menu resource and add items to the menu. + * Return a pointer to the end of the resource. + */ +static SEGPTR MENU_ParseResource( SEGPTR res, HMENU hMenu ) +{ + WORD flags, id = 0; + SEGPTR data; + + do + { + flags = *(WORD *)PTR_SEG_TO_LIN( res ); + res += sizeof(WORD); + if (!(flags & MF_POPUP)) + { + id = *(WORD *)PTR_SEG_TO_LIN( res ); + res += sizeof(WORD); + } + data = res; + res += strlen( (char *)PTR_SEG_TO_LIN(data) ) + 1; + if (!IS_STRING_ITEM(flags)) + fprintf( stderr, "MENU_ParseResource: not a string item %04x\n", + flags ); + if (flags & MF_POPUP) + { + HMENU hSubMenu = CreatePopupMenu(); + if (!hSubMenu) return (SEGPTR)0; + if (!(res = MENU_ParseResource( res, hSubMenu ))) return (SEGPTR)0; + AppendMenu( hMenu, flags, (UINT)hSubMenu, data ); + } + else + { + if (!id && !flags && !*(char *)PTR_SEG_TO_LIN(data)) + flags |= MF_SEPARATOR; /* FIXME: do this in InsertMenu? */ + AppendMenu( hMenu, flags, id, data ); + } + } while (!(flags & MF_END)); + return res; +} + + /*********************************************************************** * MENU_GetSubPopup * @@ -1560,47 +1704,53 @@ UINT MENU_GetMenuBarHeight( HWND hwnd, UINT menubarWidth, int orgX, int orgY ) } -/********************************************************************** - * ChangeMenu [USER.153] +/******************************************************************* + * ChangeMenu (USER.153) */ -BOOL ChangeMenu(HMENU hMenu, UINT nPos, LPSTR lpNewItem, - UINT wItemID, UINT wFlags) +BOOL ChangeMenu( HMENU hMenu, UINT pos, SEGPTR data, UINT id, UINT flags ) { - dprintf_menu(stddeb,"ChangeMenu: menu="NPFMT" pos=%d ptr=%p item=%04x flags=%04x\n", - hMenu, nPos, lpNewItem, wItemID, wFlags); - if (wFlags & MF_APPEND) { - return AppendMenu(hMenu, wFlags & ~MF_APPEND, wItemID, lpNewItem); - } - if (wFlags & MF_DELETE) { - /* FIXME: Word passes the item id in nPos and 0 or 0xffff as id */ - /* for MF_DELETE. We should check the parameters for all others */ - /* MF_* actions also (anybody got a doc on ChangeMenu?). */ - return DeleteMenu(hMenu, nPos, wFlags & ~MF_DELETE); - } - if (wFlags & MF_CHANGE) { - return ModifyMenu(hMenu, nPos, wFlags & ~MF_CHANGE, wItemID, lpNewItem); - } - if (wFlags & MF_REMOVE) { - return RemoveMenu(hMenu, wFlags & MF_BYPOSITION ? nPos : wItemID, - wFlags & ~MF_REMOVE); - } - /* Default: MF_INSERT */ - return InsertMenu(hMenu, nPos, wFlags, wItemID, lpNewItem); + dprintf_menu( stddeb,"ChangeMenu: menu="NPFMT" pos=%d data=%08lx id=%04x flags=%04x\n", + hMenu, pos, data, id, flags ); + if (flags & MF_APPEND) + { + return AppendMenu( hMenu, flags & ~MF_APPEND, id, data ); + } + if (flags & MF_DELETE) + { + /* FIXME: Word passes the item id in 'pos' and 0 or 0xffff as id */ + /* for MF_DELETE. We should check the parameters for all others */ + /* MF_* actions also (anybody got a doc on ChangeMenu?). */ + return DeleteMenu( hMenu, pos, flags & ~MF_DELETE ); + } + if (flags & MF_CHANGE) + { + return ModifyMenu( hMenu, pos, flags & ~MF_CHANGE, id, data ); + } + if (flags & MF_REMOVE) + { + return RemoveMenu( hMenu, flags & MF_BYPOSITION ? pos : id, + flags & ~MF_REMOVE ); + } + /* Default: MF_INSERT */ + return InsertMenu( hMenu, pos, flags, id, data ); } -/********************************************************************** - * CheckMenuItem [USER.154] +/******************************************************************* + * CheckMenuItem (USER.154) */ -BOOL CheckMenuItem(HMENU hMenu, UINT wItemID, UINT wFlags) +INT CheckMenuItem( HMENU hMenu, UINT id, UINT flags ) { - LPMENUITEM lpitem; - dprintf_menu(stddeb,"CheckMenuItem ("NPFMT", %04X, %04X) !\n", - hMenu, wItemID, wFlags); - if (!(lpitem = MENU_FindItem(&hMenu, &wItemID, wFlags))) return FALSE; - if (wFlags & MF_CHECKED) lpitem->item_flags |= MF_CHECKED; - else lpitem->item_flags &= ~MF_CHECKED; - return TRUE; + MENUITEM *item; + INT ret; + + dprintf_menu( stddeb,"CheckMenuItem: "NPFMT" %04x %04x\n", + hMenu, id, flags ); + if (!(item = MENU_FindItem( &hMenu, &id, flags ))) return -1; + ret = item->item_flags & MF_CHECKED; + if (flags & MF_CHECKED) item->item_flags |= MF_CHECKED; + else item->item_flags &= ~MF_CHECKED; + return ret; } @@ -1644,12 +1794,10 @@ int GetMenuString( HMENU hMenu, UINT wItemID, if (!str || !nMaxSiz) return 0; str[0] = '\0'; if (!(lpitem = MENU_FindItem( &hMenu, &wItemID, wFlags ))) return 0; - if (!lpitem->item_text || !IS_STRING_ITEM(lpitem->item_flags)) return 0; - nMaxSiz = MIN( nMaxSiz-1, strlen(lpitem->item_text) ); - strncpy( str, lpitem->item_text, nMaxSiz ); - str[nMaxSiz] = '\0'; + if (!IS_STRING_ITEM(lpitem->item_flags)) return 0; + lstrcpyn( str, (char *)USER_HEAP_LIN_ADDR(lpitem->hText), nMaxSiz ); dprintf_menu( stddeb, "GetMenuString: returning '%s'\n", str ); - return nMaxSiz; + return strlen(str); } @@ -1722,117 +1870,47 @@ UINT GetMenuItemID(HMENU hMenu, int nPos) } -/********************************************************************** - * InsertMenu [USER.410] +/******************************************************************* + * InsertMenu (USER.410) */ -BOOL InsertMenu(HMENU hMenu, UINT nPos, UINT wFlags, UINT wItemID, LPSTR lpNewItem) +BOOL InsertMenu( HMENU hMenu, UINT pos, UINT flags, UINT id, SEGPTR data ) { - HANDLE hNewItems; - MENUITEM *lpitem, *newItems; - LPPOPUPMENU menu; + MENUITEM *item; - if (IS_STRING_ITEM(wFlags)) + if (IS_STRING_ITEM(flags)) { - dprintf_menu(stddeb,"InsertMenu ("NPFMT", %04X, %04X, %04X, '%s') !\n", - hMenu, nPos, wFlags, wItemID, - lpNewItem ? lpNewItem : "(null)"); - if (!lpNewItem) return FALSE; + dprintf_menu( stddeb, "InsertMenu: "NPFMT" %d %04x %04x '%s'\n", + hMenu, pos, flags, id, + data ? (char *)PTR_SEG_TO_LIN(data) : "#NULL#" ); + if (!data) return FALSE; } - else - dprintf_menu(stddeb,"InsertMenu ("NPFMT", %04X, %04X, %04X, %p) !\n", - hMenu, nPos, wFlags, wItemID, lpNewItem); + else dprintf_menu( stddeb, "InsertMenu: "NPFMT" %d %04x %04x %08lx\n", + hMenu, pos, flags, id, (DWORD)data ); - /* Find where to insert new item */ + if (!(item = MENU_InsertItem( hMenu, pos, flags ))) return FALSE; - if ((wFlags & MF_BYPOSITION) && - ((nPos == (UINT)-1) || (nPos == (UINT)GetMenuItemCount(hMenu)))) + if (!(MENU_SetItemData( item, flags, id, data ))) { - /* Special case: append to menu - Some programs specify the menu length to do that */ - if (!(menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu))) - { - dprintf_menu(stddeb,"InsertMenu: "NPFMT" not a menu handle\n", hMenu); - return FALSE; - } - nPos = menu->nItems; - } - else - { - if (!MENU_FindItem( &hMenu, &nPos, wFlags )) - { - dprintf_menu(stddeb,"InsertMenu: Item %X not found\n", nPos); - return FALSE; - } - if (!(menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu))) - { - dprintf_menu(stddeb,"InsertMenu: "NPFMT" not a menu handle\n", hMenu); - return FALSE; - } - } - - /* Create new items array */ - - hNewItems = USER_HEAP_ALLOC( sizeof(MENUITEM) * (menu->nItems+1) ); - if (!hNewItems) - { - dprintf_menu(stddeb,"InsertMenu: allocation failed\n"); + item->hText = 0; + RemoveMenu( hMenu, pos, flags ); return FALSE; } - newItems = (MENUITEM *) USER_HEAP_LIN_ADDR( hNewItems ); - if (menu->nItems > 0) - { - /* Copy the old array into the new */ - MENUITEM *oldItems = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems ); - if (nPos > 0) memcpy( newItems, oldItems, nPos * sizeof(MENUITEM) ); - if (nPos < menu->nItems) memcpy( &newItems[nPos+1], &oldItems[nPos], - (menu->nItems-nPos)*sizeof(MENUITEM) ); - USER_HEAP_FREE( menu->hItems ); - } - menu->hItems = hNewItems; - menu->nItems++; + if (flags & MF_POPUP) /* Set the MF_POPUP flag on the popup-menu */ + ((POPUPMENU *)USER_HEAP_LIN_ADDR((HMENU)id))->wFlags |= MF_POPUP; - /* Store the new item data */ - - lpitem = &newItems[nPos]; - lpitem->item_flags = wFlags & ~(MF_HILITE | MF_MOUSESELECT); - lpitem->item_id = wItemID; - - if (IS_STRING_ITEM(wFlags)) - { - /* Item beginning with a backspace is a help item */ - if (lpNewItem[0] == '\b') - { - lpitem->item_flags |= MF_HELP; - lpNewItem++; - } - lpitem->hText = USER_HEAP_ALLOC( strlen(lpNewItem)+1 ); - lpitem->item_text = (char *)USER_HEAP_LIN_ADDR( lpitem->hText ); - strcpy( lpitem->item_text, lpNewItem ); - } -#ifdef WINELIB32 - else if (wFlags & MF_BITMAP) lpitem->hText = (HANDLE)lpNewItem; -#else - else if (wFlags & MF_BITMAP) lpitem->hText = LOWORD((DWORD)lpNewItem); -#endif - else lpitem->item_text = lpNewItem; - - if (wFlags & MF_POPUP) /* Set the MF_POPUP flag on the popup-menu */ - ((POPUPMENU *)USER_HEAP_LIN_ADDR((HMENU)wItemID))->wFlags |= MF_POPUP; - - SetRectEmpty( &lpitem->rect ); - lpitem->hCheckBit = hStdCheck; - lpitem->hUnCheckBit = 0; + item->hCheckBit = hStdCheck; + item->hUnCheckBit = 0; return TRUE; } -/********************************************************************** - * AppendMenu [USER.411] +/******************************************************************* + * AppendMenu (USER.411) */ -BOOL AppendMenu(HMENU hMenu, UINT wFlags, UINT wItemID, LPSTR lpNewItem) +BOOL AppendMenu( HMENU hMenu, UINT flags, UINT id, SEGPTR data ) { - return InsertMenu( hMenu, -1, wFlags | MF_BYPOSITION, wItemID, lpNewItem ); + return InsertMenu( hMenu, -1, flags | MF_BYPOSITION, id, data ); } @@ -1885,40 +1963,29 @@ BOOL DeleteMenu(HMENU hMenu, UINT nPos, UINT wFlags) } -/********************************************************************** - * ModifyMenu [USER.414] +/******************************************************************* + * ModifyMenu (USER.414) */ -BOOL ModifyMenu(HMENU hMenu, UINT nPos, UINT wFlags, UINT wItemID, LPSTR lpNewItem) +BOOL ModifyMenu( HMENU hMenu, UINT pos, UINT flags, UINT id, SEGPTR data ) { - LPMENUITEM lpitem; - if (IS_STRING_ITEM(wFlags)) + MENUITEM *item; + HANDLE hText = 0; + + if (IS_STRING_ITEM(flags)) { - dprintf_menu(stddeb,"ModifyMenu ("NPFMT", %04X, %04X, %04X, '%s') !\n", - hMenu, nPos, wFlags, wItemID, lpNewItem ? lpNewItem : "(null)"); - if (!lpNewItem) return FALSE; + dprintf_menu( stddeb, "ModifyMenu: "NPFMT" %d %04x %04x '%s'\n", + hMenu, pos, flags, id, + data ? (char *)PTR_SEG_TO_LIN(data) : "#NULL#"); + if (!data) return FALSE; } else - dprintf_menu(stddeb,"ModifyMenu ("NPFMT", %04X, %04X, %04X, %p) !\n", - hMenu, nPos, wFlags, wItemID, lpNewItem); - if (!(lpitem = MENU_FindItem( &hMenu, &nPos, wFlags ))) return FALSE; - - if (IS_STRING_ITEM(lpitem->item_flags)) USER_HEAP_FREE( lpitem->hText ); - lpitem->item_flags = wFlags & ~(MF_HILITE | MF_MOUSESELECT); - lpitem->item_id = wItemID; + dprintf_menu( stddeb, "ModifyMenu: "NPFMT" %d %04x %04x %08lx\n", + hMenu, pos, flags, id, (DWORD)data ); + if (!(item = MENU_FindItem( &hMenu, &pos, flags ))) return FALSE; - if (IS_STRING_ITEM(wFlags)) - { - lpitem->hText = USER_HEAP_ALLOC( strlen(lpNewItem)+1 ); - lpitem->item_text = (char *)USER_HEAP_LIN_ADDR( lpitem->hText ); - strcpy( lpitem->item_text, lpNewItem ); - } -#ifdef WINELIB32 - else if (wFlags & MF_BITMAP) lpitem->hText = (HANDLE)lpNewItem; -#else - else if (wFlags & MF_BITMAP) lpitem->hText = LOWORD((DWORD)lpNewItem); -#endif - else lpitem->item_text = lpNewItem; - SetRectEmpty( &lpitem->rect ); + if (IS_STRING_ITEM(item->item_flags)) hText = item->hText; + if (!MENU_SetItemData( item, flags, id, data )) return FALSE; + if (hText) USER_HEAP_FREE( hText ); return TRUE; } @@ -2045,14 +2112,17 @@ HMENU GetSystemMenu(HWND hWnd, BOOL bRevert) return wndPtr->hSysMenu; } -/********************************************************************** - * SetSystemMenu [USER.280] + +/******************************************************************* + * SetSystemMenu (USER.280) */ -BOOL SetSystemMenu(HWND hWnd, HMENU newHmenu) +BOOL SetSystemMenu( HWND hwnd, HMENU hMenu ) { WND *wndPtr; - if ((wndPtr = WIN_FindWndPtr(hWnd)) != NULL) wndPtr->hSysMenu = newHmenu; + if (!(wndPtr = WIN_FindWndPtr(hwnd))) return FALSE; + if (wndPtr->hSysMenu) DestroyMenu( wndPtr->hSysMenu ); + wndPtr->hSysMenu = hMenu; return TRUE; } @@ -2146,7 +2216,7 @@ void DrawMenuBar(HWND hWnd) */ void EndMenu(void) { - /* Note: this won't work when we have multiple tasks... */ + /* FIXME: this won't work when we have multiple tasks... */ fEndMenuCalled = TRUE; } @@ -2181,68 +2251,36 @@ HMENU LoadMenu( HINSTANCE instance, SEGPTR name ) if (!name) return 0; - if (!(hRsrc = FindResource( instance, name, RT_MENU ))) return 0; + if (!(hRsrc = FindResource( instance, name, RT_MENU ))) { + /* check for Win32 module */ + instance = GetExePtr( instance ); + if(((NE_MODULE*)GlobalLock(instance))->magic == PE_SIGNATURE) + return WIN32_LoadMenuA(instance,PTR_SEG_TO_LIN(name)); + return 0; + } if (!(handle = LoadResource( instance, hRsrc ))) return 0; - hMenu = LoadMenuIndirect( LockResource(handle) ); + hMenu = LoadMenuIndirect( WIN16_LockResource(handle) ); FreeResource( handle ); return hMenu; } /********************************************************************** - * LoadMenuIndirect [USER.220] + * LoadMenuIndirect (USER.220) */ -HMENU LoadMenuIndirect(LPSTR menu_template) +HMENU LoadMenuIndirect( SEGPTR template ) { - HMENU hMenu; - MENU_HEADER *menu_desc; - dprintf_menu(stddeb,"LoadMenuIndirect: menu_template '%p'\n", - menu_template); - hMenu = CreateMenu(); - menu_desc = (MENU_HEADER *)menu_template; - ParseMenuResource((WORD *)(menu_desc + 1), 0, hMenu); - return hMenu; -} + HMENU hMenu; - -/********************************************************************** - * ParseMenuResource (from Resource or Template) - */ -WORD * ParseMenuResource(WORD *first_item, int level, HMENU hMenu) -{ - WORD *item; - WORD *next_item; - HMENU hSubMenu; - int i; - - level++; - next_item = first_item; - i = 0; - do { - i++; - item = next_item; - if (*item & MF_POPUP) { - MENU_POPUPITEM *popup_item = (MENU_POPUPITEM *) item; - next_item = (WORD *) (popup_item->item_text + - strlen(popup_item->item_text) + 1); - hSubMenu = CreatePopupMenu(); - next_item = ParseMenuResource(next_item, level, hSubMenu); - AppendMenu(hMenu, popup_item->item_flags, - (UINT)hSubMenu, popup_item->item_text); - } - else - { - MENUITEMTEMPLATE *normal_item = (MENUITEMTEMPLATE *) item; - WORD flags = normal_item->item_flags; - next_item = (WORD *) (normal_item->item_text + - strlen(normal_item->item_text) + 1); - if (!normal_item->item_text[0] && !normal_item->item_id) - flags |= MF_SEPARATOR; /* FIXME: do this in InsertMenu? */ - AppendMenu( hMenu, flags, normal_item->item_id, - normal_item->item_text ); - } - } while (!(*item & MF_END)); - return next_item; + dprintf_menu(stddeb,"LoadMenuIndirect: %08lx\n", (DWORD)template ); + if (!(hMenu = CreateMenu())) return (HMENU)0; + template += sizeof(MENU_HEADER); + if (!MENU_ParseResource( template, hMenu )) + { + DestroyMenu( hMenu ); + return (HMENU)0; + } + return hMenu; } diff --git a/controls/static.c b/controls/static.c index ce812523766..0e9cf1a433d 100644 --- a/controls/static.c +++ b/controls/static.c @@ -88,8 +88,13 @@ LONG StaticWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CREATESTRUCT * createStruct = (CREATESTRUCT *)PTR_SEG_TO_LIN(lParam); if (createStruct->lpszName) - STATIC_SetIcon( hWnd, LoadIcon( createStruct->hInstance, - (SEGPTR)createStruct->lpszName )); + { + HICON hicon = LoadIcon( createStruct->hInstance, + (SEGPTR)createStruct->lpszName ); + if (!hicon) /* Try OEM icon (FIXME: is this right?) */ + hicon = LoadIcon( 0, (SEGPTR)createStruct->lpszName ); + STATIC_SetIcon( hWnd, hicon ); + } return 1; } return DefWindowProc(hWnd, uMsg, wParam, lParam); @@ -195,23 +200,23 @@ static void PaintTextfn( HWND hwnd, HDC hdc ) switch (style & 0x0000000F) { case SS_LEFT: - wFormat = DT_LEFT | DT_EXPANDTABS | DT_WORDBREAK; + wFormat = DT_LEFT | DT_EXPANDTABS | DT_WORDBREAK | DT_NOCLIP; break; case SS_CENTER: - wFormat = DT_CENTER | DT_EXPANDTABS | DT_WORDBREAK; + wFormat = DT_CENTER | DT_EXPANDTABS | DT_WORDBREAK | DT_NOCLIP; break; case SS_RIGHT: - wFormat = DT_RIGHT | DT_EXPANDTABS | DT_WORDBREAK; + wFormat = DT_RIGHT | DT_EXPANDTABS | DT_WORDBREAK | DT_NOCLIP; break; case SS_SIMPLE: - wFormat = DT_LEFT | DT_SINGLELINE | DT_VCENTER; + wFormat = DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_NOCLIP; break; case SS_LEFTNOWORDWRAP: - wFormat = DT_LEFT | DT_SINGLELINE | DT_EXPANDTABS | DT_VCENTER; + wFormat = DT_LEFT | DT_SINGLELINE | DT_EXPANDTABS | DT_VCENTER | DT_NOCLIP; break; default: diff --git a/controls/widgets.c b/controls/widgets.c index 5559dd1c223..ccbe8c8565a 100644 --- a/controls/widgets.c +++ b/controls/widgets.c @@ -23,16 +23,16 @@ static WNDCLASS WIDGETS_BuiltinClasses[] = sizeof(BUTTONINFO), 0, 0, 0, 0, 0, (SEGPTR)"BUTTON" }, { CS_GLOBALCLASS | CS_PARENTDC, (WNDPROC)"StaticWndProc", 0, sizeof(STATICINFO), 0, 0, 0, 0, 0, (SEGPTR)"STATIC" }, - { CS_GLOBALCLASS | CS_PARENTDC, (WNDPROC)"ScrollBarWndProc", 0, + { CS_GLOBALCLASS | CS_HREDRAW | CS_VREDRAW | CS_PARENTDC , (WNDPROC)"ScrollBarWndProc", 0, sizeof(SCROLLINFO), 0, 0, 0, 0, 0, (SEGPTR)"SCROLLBAR" }, { CS_GLOBALCLASS | CS_PARENTDC | CS_DBLCLKS, (WNDPROC)"ListBoxWndProc", 0, 8, 0, 0, 0, 0, 0, (SEGPTR)"LISTBOX" }, { CS_GLOBALCLASS | CS_PARENTDC, (WNDPROC)"ComboBoxWndProc", 0, 8, 0, 0, 0, 0, 0, (SEGPTR)"COMBOBOX" }, - { CS_GLOBALCLASS | CS_PARENTDC | CS_DBLCLKS, (WNDPROC)"ComboLBoxWndProc", + { CS_GLOBALCLASS | CS_PARENTDC | CS_DBLCLKS | CS_SAVEBITS, (WNDPROC)"ComboLBoxWndProc", 0, 8, 0, 0, 0, 0, 0, (SEGPTR)"COMBOLBOX" }, - { CS_GLOBALCLASS, (WNDPROC)"EditWndProc", 0, sizeof(DWORD), - 0, 0, 0, 0, 0, (SEGPTR)"EDIT" }, + { CS_GLOBALCLASS | CS_PARENTDC | CS_DBLCLKS, (WNDPROC)"EditWndProc", + 0, sizeof(DWORD), 0, 0, 0, 0, 0, (SEGPTR)"EDIT" }, { CS_GLOBALCLASS | CS_SAVEBITS, (WNDPROC)"PopupMenuWndProc", 0, 8, 0, 0, 0, 0, 0, (SEGPTR)POPUPMENU_CLASS_NAME }, { CS_GLOBALCLASS, (WNDPROC)"DesktopWndProc", 0, sizeof(DESKTOPINFO), diff --git a/debugger/break.c b/debugger/break.c index 8e9fbb865ca..78e4cc67822 100644 --- a/debugger/break.c +++ b/debugger/break.c @@ -12,7 +12,6 @@ #include "debugger.h" #define INT3 0xcc /* int 3 opcode */ -#define STEP_FLAG 0x100 /* single-step flag */ #define MAX_BREAKPOINTS 25 diff --git a/debugger/dbg.y b/debugger/dbg.y index 0d9f94c0c77..d42eac74288 100644 --- a/debugger/dbg.y +++ b/debugger/dbg.y @@ -215,8 +215,8 @@ void wine_debug( int signal, struct sigcontext_struct *regs ) if (!loaded_symbols) { loaded_symbols++; - GetPrivateProfileString("wine", "SymbolTableFile", "wine.sym", - SymbolTableFile, sizeof(SymbolTableFile), WINE_INI); + PROFILE_GetWineIniString( "wine", "SymbolTableFile", "wine.sym", + SymbolTableFile, sizeof(SymbolTableFile) ); DEBUG_ReadSymbolTable( SymbolTableFile ); DEBUG_LoadEntryPoints(); } diff --git a/documentation/apiw.index b/documentation/apiw.index new file mode 100644 index 00000000000..23868bb2fdf --- /dev/null +++ b/documentation/apiw.index @@ -0,0 +1,594 @@ +AbortDoc:2_15_01 +AccessResource:3_07_01 +AddAtom:1_12_01 +AddFontResource:2_13_01 +AllocResource:3_07_13 +AnimatePalette:2_04_01 +AnsiLower:4_03_01 +AnsiLowerBuff:4_03_01 +AnsiNext:4_03_03 +AnsiPrev:4_03_03 +AnsiToOem:4_03_14 +AnsiToOemBuff:4_03_14 +AnsiUpper:4_03_02 +AnsiUpperBuff:4_03_02 +AppendMenu:1_05_01 +Arc:2_11_01 +ArrangeIconicWindows:1_03_03 +BeginPaint:1_14_01 +BitBlt:2_12_09 +BringWindowToTop:1_03_05 +BuildCommDCB:3_08_01 +CallWindowProc:1_01_01 +CallWndProc:1_11_06 +Catch:3_05_01 +CheckMenuItem:1_05_07 +CheckRadioButton:1_13_02 +ChildWindowFromPoint:1_04_07 +ChooseColor:4_09_01 +ChooseFont:4_09_02 +Chord:2_11_01 +ClassFirst:3_11_01 +ClassNext:3_11_01 +ClearCommBreak:3_08_02 +ClientToScreen:2_07_10 +ClipCursor:1_08_06 +CloseComm:3_08_03 +CloseWindow:1_03_06 +CombineRgn:2_08_01 +CommDlgExtendedError:4_09_07 +CopyCursor:1_08_08 +CopyIcon:2_02_01 +CopyLZFile:4_07_01 +CopyMetaFile:2_05_02 +CopyRect:4_04_01 +CreateBitmap:2_12_01 +CreateBitmapIndirect:2_12_01 +CreateCompatibleBitmap:2_12_03 +CreateDC:2_01_02 +CreateDIBPatternBrush:2_10_02 +CreateDialog:1_13_03 +CreateDialogIndirect:1_13_03 +CreateDialogIndirectParam:1_13_04 +CreateDialogParam:1_13_04 +CreateDiscardableBitmap:2_12_03 +CreateEllipticRgn:2_08_02 +CreateEllipticRgnIndirect:2_08_02 +CreateFont:2_13_03 +CreateFontIndirect:2_13_03 +CreateHatchBrush:2_10_03 +CreateIC:2_01_02 +CreateIcon:2_02_04 +CreateMenu:1_05_03 +CreatePalette:2_04_02 +CreatePatternBrush:2_10_08 +CreatePolyPolygonRgn:2_08_03 +CreatePolygonRgn:2_08_03 +CreatePopupMenu:1_05_03 +CreateRectRgn:2_08_04 +CreateRectRgnIndirect:2_08_04 +CreateRoundRectRgn:2_08_05 +CreateSolidBrush:2_10_04 +DPtoLP:2_07_01 +DebugOutput:4_05_02 +DefDlgProc:1_02_10 +DefFrameProc:1_02_11 +DefMDIChildProc:1_02_12 +DefWindowProc:1_02_13 +DeleteAtom:1_12_02 +DeleteDC:2_01_04 +DeleteMenu:1_05_02 +DeleteMetaFile:2_05_03 +DeleteObject:2_03_04 +DestroyIcon:2_02_03 +DestroyMenu:1_05_02 +DestroyWindow:1_02_08 +DeviceCapabilities:2_15_02 +DeviceMode:2_15_03 +DialogBox:1_13_05 +DialogBoxIndirect:1_13_05 +DialogBoxIndirectParam:1_13_06 +DialogBoxParam:1_13_06 +DirectedYield:3_05_02 +DispatchMessage:1_01_02 +DlgDirList:1_13_07 +DlgDirListComboBox:1_13_07 +DlgDirSelect:1_13_08 +DlgDirSelectComboBox:1_13_08 +DlgDirSelectComboBox:1_13_20 +DlgDirSelectComboBoxEx:1_13_20 +DlgDirSelectEx:1_13_21 +DrawFocusRect:2_11_07 +DrawIcon:2_02_02 +DrawMenuBar:1_05_05 +Ellipse:2_11_05 +EnableCommNotification:3_08_04 +EnableHardwareInput:3_06_01 +EnableMenuItem:1_05_07 +EnableScrollBar:1_06_05 +EnableWindow:1_03_10 +EndDialog:1_13_09 +EndDoc:2_15_04 +EndPage:2_15_05 +EndPaint:1_14_02 +EnumChildWindows:1_04_05 +EnumFontFamilies:2_13_05 +EnumFonts:2_13_05 +EnumMetaFile:2_05_04 +EnumObjects:2_03_05 +EnumTaskWindows:3_05_08 +EnumWindows:1_04_04 +EqualRect:4_04_02 +EqualRgn:2_08_06 +Escape:2_15_06 +EscapeCommFunction:3_08_05 +ExcludeUpdateRgn:1_14_03 +ExitWindows:3_05_11 +ExtDeviceMode:2_15_07 +ExtFloodFill:2_11_09 +ExtTextOut:2_14_02 +ExtractIcon:4_01_01 +FatalAppExit:4_05_03 +FatalExit:4_05_04 +FillRect:2_11_08 +FillRgn:2_11_06 +FindAtom:1_12_03 +FindExecutable:4_01_02 +FindResource:3_07_02 +FindText:4_09_03 +FindWindow:1_04_06 +FlashWindow:4_06_01 +FloodFill:2_11_09 +FlushComm:3_08_06 +FrameRect:2_11_08 +FrameRgn:2_11_06 +FreeLibrary:3_03_01 +FreeProcInstance:3_03_05 +FreeResource:3_07_03 +GetActiveWindow:1_03_11 +GetAspectRatioFilter:2_13_12 +GetAspectRatioFilterEx:2_13_12 +GetAsyncKeyState:3_06_02 +GetAsyncKeyState:3_06_03 +GetAtomName:1_12_04 +GetBitmapBits:2_12_04 +GetBkColor:1_14_14 +GetBkMode:1_14_15 +GetBoundsRect:1_14_16 +GetBrushOrg:2_10_06 +GetBrushOrgEx:2_10_06 +GetCapture:1_03_12 +GetCaretBlinkTime:1_07_02 +GetCaretPos:1_07_03 +GetCharABCWidths:2_13_06 +GetCharWidth:2_13_06 +GetClassInfo:1_02_02 +GetClassLong:1_02_05 +GetClassName:1_02_03 +GetClassWord:1_02_04 +GetClientRect:1_04_02 +GetClipCursor:1_08_07 +GetClipboardData:1_10_05 +GetClipboardFormatName:1_10_03 +GetCommError:3_08_07 +GetCommEventMask:3_08_08 +GetCommState:3_08_09 +GetCurrentPosition:1_14_17 +GetCurrentPositionEx:1_14_17 +GetCurrentTask:3_05_03 +GetCurrentTime:3_02_03 +GetCursor:1_08_05 +GetCursorPos:1_08_03 +GetDC:2_01_03 +GetDCEx:2_01_03 +GetDCOrg:2_01_08 +GetDIBits:2_12_05 +GetDOSEnvironment:3_01_06 +GetDesktopWindow:1_03_21 +GetDeviceCaps:2_15_08 +GetDialogBaseUnits:1_13_10 +GetDlgCtrlID:1_13_11 +GetDlgItem:1_13_12 +GetDlgItemInt:1_13_13 +GetDlgItemText:1_13_14 +GetDoubleClickTime:3_02_02 +GetDriveType:3_09_01 +GetExpandedName:4_07_02 +GetFileTitle:4_09_05 +GetFocus:1_03_13 +GetFontData:2_13_07 +GetFreeSpace:3_04_01 +GetGlyphOutline:2_13_08 +GetInstanceData:3_03_08 +GetKBCodePage:3_06_07 +GetKerningPairs:2_13_09 +GetKeyNameText:3_06_05 +GetKeyState:3_06_06 +GetKeyboardType:3_06_12 +GetLastActivePopup:1_03_16 +GetMapMode:1_14_11 +GetMenu:1_05_04 +GetMenuCheckMarkDimensions:1_05_11 +GetMenuItemCount:1_05_10 +GetMenuItemID:1_05_08 +GetMenuState:1_05_09 +GetMenuString:1_05_09 +GetMessage:1_01_03 +GetMessageExtraInfo:1_01_14 +GetMessagePos:1_01_05 +GetMessageTime:1_01_05 +GetMetaFile:2_05_05 +GetModuleFileName:3_03_03 +GetModuleFileName:3_03_09 +GetModuleHandle:3_03_03 +GetModuleHandle:3_03_09 +GetModuleUsage:3_03_03 +GetModuleUsage:3_03_09 +GetMsgProc:1_11_07 +GetNearestColor:2_04_03 +GetNearestPaletteIndex:2_04_03 +GetNextWindow:1_03_19 +GetNumTasks:3_05_04 +GetObject:2_03_06 +GetOpenFileName:4_09_04 +GetOutlineTextMetrics:2_13_10 +GetParent:1_03_18 +GetPolyFillMode:1_14_12 +GetPrivateProfileInt:4_02_03 +GetPrivateProfileString:4_02_01 +GetProcAddress:3_03_04 +GetProfileInt:4_02_03 +GetProfileString:4_02_01 +GetQueueStatus:1_01_15 +GetROP2:1_14_13 +GetRasterizerCaps:2_13_11 +GetRgnBox:2_08_07 +GetSaveFileName:4_09_04 +GetScrollRange:1_06_02 +GetStockObject:2_03_07 +GetStretchBltMode:2_12_10 +GetSubMenu:1_05_08 +GetSysColor:2_04_08 +GetSysModalWindow:1_03_14 +GetSystemDirectory:3_09_02 +GetSystemMenu:1_05_06 +GetSystemMetrics:3_01_04 +GetSystemPaletteUse:2_04_05 +GetTabbedTextExtent:2_14_03 +GetTempDrive:3_09_03 +GetTempFileName:3_09_04 +GetTextAlign:2_14_04 +GetTextColor:2_14_06 +GetTextExtent:2_14_03 +GetTextExtentPoint:2_14_03 +GetTextFace:2_14_07 +GetTextMetrics:2_14_08 +GetTickCount:3_02_03 +GetTimerResoultion:3_02_04 +GetTopWindow:1_03_19 +GetUpdateRgn:1_14_05 +GetVersion:3_01_05 +GetWinFlags:3_01_03 +GetWindow:1_03_19 +GetWindowDC:2_01_03 +GetWindowExt:2_07_02 +GetWindowExtEx:2_07_02 +GetWindowLong:1_02_15 +GetWindowOrg:2_07_03 +GetWindowOrgEx:2_07_03 +GetWindowPlacement:1_03_22 +GetWindowRect:1_04_02 +GetWindowTask:3_05_05 +GetWindowText:1_04_03 +GetWindowTextLength:1_04_03 +GetWindowWord:1_02_14 +GetWindowsDirectory:3_09_05 +GlobalAddAtom:1_12_01 +GlobalAlloc:3_04_02 +GlobalCompact:3_04_03 +GlobalDeleteAtom:1_12_02 +GlobalEntryHandle:3_11_03 +GlobalEntryModule:3_11_03 +GlobalFindAtom:1_12_03 +GlobalFirst:3_11_02 +GlobalFix:3_04_04 +GlobalFlags:3_04_05 +GlobalFree:3_04_02 +GlobalGetAtomName:1_12_04 +GlobalHandle:3_04_06 +GlobalHandleToSel:3_11_04 +GlobalInfo:3_11_05 +GlobalLRUNewest:3_04_08 +GlobalLRUOldest:3_04_08 +GlobalLock:3_04_07 +GlobalNext:3_11_02 +GlobalNotify:3_04_09 +GlobalReAlloc:3_04_10 +GlobalSize:3_04_11 +GlobalUnfix:3_04_04 +GlobalUnlock:3_04_07 +GrayString:2_14_09 +GrayStringProc:2_14_09 +HideCaret:1_07_04 +HiliteMenuItem:1_05_07 +InSendMessage:1_01_06 +InflateRect:4_04_01 +InitAtomTable:1_12_05 +InsertMenu:1_05_01 +InterruptRegister:3_11_19 +InterruptUnRegister:3_11_19 +IntersectClipRect:2_09_02 +IntersectRect:4_04_03 +InvalidateRect:1_14_18 +InvalidateRgn:1_14_08 +InvertRect:1_14_06 +InvertRgn:2_11_06 +IsBadCodePtr:3_12_01 +IsBadHugeWritePtr:3_12_03 +IsBadReadPtr:3_12_04 +IsBadStringPtr:3_12_05 +IsBadWritePtr:3_12_06 +IsCharAlpha:4_03_04 +IsCharAlphaNumeric:4_03_05 +IsCharLower:4_03_06 +IsCharUpper:4_03_07 +IsDBCSLeadByte:4_03_12 +IsDialogMessage:1_13_16 +IsDlgButtonChecked:1_03_17 +IsGDIObject:2_03_08 +IsIconic:1_03_07 +IsMenu:1_05_15 +IsRectEmpty:4_04_02 +IsTask:3_05_06 +IsWindow:1_03_09 +IsWindowEnabled:1_03_10 +IsWindowVisible:1_03_02 +IsZoomed:1_03_07 +LPtoDP:2_07_01 +LZClose:4_07_03 +LZCopy:4_07_10 +LZDone:4_07_04 +LZInit:4_07_05 +LZOpenFile:4_07_06 +LZRead:4_07_07 +LZSeek:4_07_08 +LZStart:4_07_09 +LimitEmsPages:3_04_14 +LineDDA:2_11_02 +LineTo:2_11_03 +LoadAccelerators:3_07_12 +LoadBitmap:3_07_07 +LoadCursor:1_08_02 +LoadIcon:3_07_06 +LoadLibrary:3_03_01 +LoadMenu:3_07_10 +LoadMenuIndirect:3_07_11 +LoadResource:3_07_03 +LoadString:3_07_05 +LocalAlloc:3_04_02 +LocalCompact:3_04_03 +LocalFirst:3_11_06 +LocalFlags:3_04_05 +LocalFree:3_04_02 +LocalHandle:3_04_06 +LocalInfo:3_11_07 +LocalInit:3_04_13 +LocalLock:3_04_07 +LocalNext:3_11_06 +LocalReAlloc:3_04_10 +LocalShrink:3_04_13 +LocalSize:3_04_11 +LocalUnlock:3_04_07 +LockInput:4_05_06 +LockWindowUpdate:1_14_10 +MakeProcInstance:3_03_05 +MapDialogRect:1_13_18 +MapVirtualKey:3_06_09 +MapWindowPoints:2_07_08 +MemManInfo:3_11_08 +MemoryRead:3_11_09 +MemoryWrite:3_11_09 +MessageBeep:4_06_02 +MessageBox:4_06_03 +ModifyMenu:1_05_01 +ModuleFindHandle:3_11_13 +ModuleFindName:3_11_13 +ModuleFirst:3_11_12 +ModuleNext:3_11_12 +MoveTo:2_11_03 +MoveToEx:2_11_03 +MoveWindow:1_03_20 +NotifyRegister:3_11_20 +NotifyUnregister:3_11_20 +OemKeyScan:3_06_08 +OffsetClipRgn:2_09_03 +OffsetRect:4_04_01 +OffsetRgn:2_08_08 +OffsetViewportOrg:2_06_03 +OffsetViewportOrgEx:2_06_03 +OffsetWindowOrg:2_07_04 +OffsetWindowOrgEx:2_07_04 +OpenComm:3_08_03 +OpenFile:3_09_06 +OpenIcon:1_03_04 +OutputDebugString:4_05_01 +PaintRgn:2_11_06 +PatBlt:2_12_08 +PeekMessage:1_01_03 +Pie:2_11_01 +PlayMetaFile:2_05_07 +PlayMetaFileRecord:2_05_07 +PolyPolygon:2_11_04 +Polygon:2_11_04 +Polyline:2_11_03 +PostAppMessage:1_01_07 +PostMessage:1_01_07 +PostQuitMessage:1_01_07 +PrintDlg:4_09_06 +PtInRect:4_04_02 +PtInRegion:2_08_09 +PtVisible:2_03_02 +QueryAbort:2_15_13 +QuerySendMessage:4_05_05 +ReadComm:3_08_10 +RealizePalette:2_04_06 +RectInRegion:2_08_10 +RectVisible:2_03_02 +RectVisible:2_03_03 +Rectangle:2_11_05 +RedrawWindow:1_14_09 +RegCloseKey:3_10_01 +RegCreateKey:3_10_02 +RegDeleteKey:3_10_03 +RegEnumKey:3_10_04 +RegOpenKey:3_10_02 +RegQueryValue:3_10_05 +RegSetValue:3_10_05 +RegisterClass:1_02_01 +RegisterClipboardFormat:1_10_03 +RegisterWindowMessage:1_01_13 +ReleaseCapture:1_03_12 +ReleaseDC:2_01_05 +RemoveFontResource:2_13_02 +RemoveMenu:1_05_02 +RemoveProp:1_09_02 +ReplaceText:4_09_03 +ReplyMessage:1_01_06 +ResetDC:2_01_07 +ResizePalette:2_04_11 +RoundRect:2_11_05 +ScaleViewportExt:2_06_04 +ScaleViewportExtEx:2_06_04 +ScaleWindowExt:2_07_05 +ScaleWindowExtEx:2_07_05 +ScreenToClient:2_07_10 +ScrollDC:1_06_06 +ScrollWindow:1_06_04 +SelectClipRect:2_09_04 +SelectPalette:2_04_07 +SendDlgItemMessage:1_13_19 +SendMessage:1_01_08 +SetAbortProc:2_15_09 +SetActiveWindow:1_03_11 +SetBitmapBits:2_12_04 +SetBkColor:1_14_14 +SetBkMode:1_14_15 +SetBoundsRect:1_14_16 +SetBrushOrg:2_10_07 +SetCapture:1_03_12 +SetCaretBlinkTime:1_07_02 +SetCaretPos:1_07_03 +SetClassLong:1_02_05 +SetClassWord:1_02_04 +SetClipboardData:1_10_05 +SetCommBreak:3_08_02 +SetCommEventMask:3_08_08 +SetCommState:3_08_09 +SetCursor:1_08_05 +SetCursorPos:1_08_03 +SetDIBits:2_12_05 +SetDIBitsToDevice:2_12_06 +SetDlgItemInt:1_13_13 +SetDlgItemText:1_13_14 +SetDoubleClickTime:3_02_02 +SetFocus:1_03_13 +SetHandleCount:3_09_07 +SetMapMode:1_14_11 +SetMapperFlags:2_13_13 +SetMenu:1_05_14 +SetMenuItemBitmaps:1_05_12 +SetMessageQueue:1_01_09 +SetParent:1_03_18 +SetPolyFillMode:1_14_12 +SetROP2:1_14_13 +SetRect:4_04_01 +SetRectEmpty:4_04_01 +SetRectRgn:2_08_11 +SetResourceHandler:3_07_08 +SetScrollRange:1_06_02 +SetStretchBltMode:2_12_10 +SetSysColors:2_04_09 +SetSysModalWindow:1_03_14 +SetSystemPaletteUse:2_04_05 +SetTextAlign:2_14_04 +SetTextColor:2_14_06 +SetTextJustification:2_14_10 +SetViewportExt:2_06_05 +SetViewportExtEx:2_06_05 +SetWindowExt:2_07_06 +SetWindowExtEx:2_07_06 +SetWindowLong:1_01_01 +SetWindowLong:1_02_06 +SetWindowOrg:2_07_07 +SetWindowOrgEx:2_07_07 +SetWindowPlacement:1_03_22 +SetWindowText:1_04_03 +SetWindowWord:1_02_16 +ShellExecute:4_01_03 +ShowCaret:1_07_04 +ShowCursor:1_08_04 +ShowOwnedPopups:1_03_08 +ShowScrollBar:1_06_03 +ShowWindow:1_03_02 +SizeofResource:3_07_09 +SpoolFile:2_15_10 +StackTraceCSIPFirst:3_11_11 +StackTraceFirst:3_11_11 +StackTraceNext:3_11_11 +StartDoc:2_15_11 +StartPage:2_15_12 +StretchBlt:2_12_09 +StretchDIBits:2_12_07 +SubtractRect:4_04_03 +SystemHeapInfo:3_11_10 +SystemParametersInfo:3_01_02 +TabbedTextOut:2_14_02 +TaskFindHandle:3_11_21 +TaskFirst:3_11_14 +TaskGetCSIP:3_11_15 +TaskNext:3_11_14 +TaskSetCSIP:3_11_15 +TaskSwitch:3_11_16 +TerminateApp:3_11_17 +TextOut:2_14_02 +Throw:3_05_01 +TimerCount:3_11_18 +ToAscii:4_03_13 +TrackPopupMenu:1_05_13 +TranslateAccelerator:1_01_10 +TranslateMDISysAccel:1_01_11 +TranslateMessage:1_01_12 +TransmitCommChar:3_08_11 +UngetCommChar:3_08_11 +UnionRect:4_04_03 +UnrealizeObject:2_03_01 +UnregisterClass:1_02_01 +UpdateColors:2_04_10 +UpdateWindow:1_14_07 +ValidateRect:1_14_18 +ValidateRgn:1_14_08 +VkKeyScan:3_06_10 +VkKeyScan:3_06_11 +WaitMessage:1_01_04 +WinExec:3_05_09 +WinHelp:3_05_07 +WindowFromPoint:2_07_09 +WriteComm:3_08_10 +WritePrivateProfileString:4_02_02 +WriteProfileString:4_02_02 +Yield:3_05_02 +_hread:3_09_09 +_lclose:3_09_08 +_lcreat:3_09_10 +_llseek:3_09_11 +_lopen:3_09_12 +_lread:3_09_09 +hmemcpy:3_04_12 +lstrcat:4_03_09 +lstrcmp:4_03_08 +lstrcmpi:4_03_08 +lstrcpy:4_03_09 +lstrcpyn:4_03_09 +lstrlen:4_03_10 +wsprintf:4_03_11 +wvsprintf:4_03_11 diff --git a/files/Makefile.in b/files/Makefile.in index 5fee0609b18..cf17c1c2e02 100644 --- a/files/Makefile.in +++ b/files/Makefile.in @@ -5,7 +5,8 @@ C_SRCS = \ directory.c \ dos_fs.c \ drive.c \ - file.c + file.c \ + profile.c all: $(MODULE).o diff --git a/files/directory.c b/files/directory.c index 9de0c5289f6..5365bd60b6c 100644 --- a/files/directory.c +++ b/files/directory.c @@ -13,6 +13,7 @@ #include "drive.h" #include "file.h" #include "msdos.h" +#include "options.h" #include "xmalloc.h" #include "stddebug.h" #include "debug.h" @@ -42,8 +43,7 @@ static int DIR_GetPath( const char *keyname, const char *defval, const char *dos_name ,*unix_name; BYTE attr; - GetPrivateProfileString( "wine", keyname, defval, - path, sizeof(path), WineIniFileName() ); + PROFILE_GetWineIniString( "wine", keyname, defval, path, sizeof(path) ); if (!(unix_name = DOSFS_GetUnixFileName( path, TRUE )) || !FILE_Stat( unix_name, &attr, NULL, NULL, NULL ) || !(attr & FA_DIRECTORY)) @@ -117,7 +117,7 @@ void DIR_ParseWindowsPath( char *path ) */ int DIR_Init(void) { - char path[MAX_PATHNAME_LEN]; + char path[MAX_PATHNAME_LEN], *env_p; int drive; const char *cwd; @@ -153,14 +153,26 @@ int DIR_Init(void) DRIVE_Chdir( drive, DIR_WindowsDosDir + 2 ); } - GetPrivateProfileString( "wine", "path", "c:\\windows;c:\\windows\\system", - path, sizeof(path), WineIniFileName() ); + PROFILE_GetWineIniString("wine", "path", "c:\\windows;c:\\windows\\system", + path, sizeof(path) ); DIR_ParseWindowsPath( path ); dprintf_dosfs( stddeb, "WindowsDir = %s\nSystemDir = %s\n", DIR_WindowsDosDir, DIR_SystemDosDir ); dprintf_dosfs( stddeb, "TempDir = %s\nCwd = %c:\\%s\n", DIR_TempDosDir, 'A' + drive, DRIVE_GetDosCwd( drive ) ); + + /* Put the temp and Windows directories into the environment */ + + env_p = (char *)xmalloc( strlen(DIR_TempDosDir) + 5 ); + strcpy( env_p, "TEMP=" ); + strcpy( env_p + 5, DIR_TempDosDir ); + putenv( env_p ); + env_p = (char *)xmalloc( strlen(DIR_WindowsDosDir) + 7 ); + strcpy( env_p, "windir=" ); + strcpy( env_p + 7, DIR_WindowsDosDir ); + putenv( env_p ); + return 1; } diff --git a/files/dos_fs.c b/files/dos_fs.c index 6f4e921edbb..29131eca3ac 100644 --- a/files/dos_fs.c +++ b/files/dos_fs.c @@ -25,7 +25,7 @@ #include "debug.h" /* Chars we don't want to see in DOS file names */ -#define INVALID_DOS_CHARS "*?<>|\"+=,; " +#define INVALID_DOS_CHARS "*?<>|\"+=,;[] \345" static const char *DOSFS_Devices[][2] = { @@ -264,7 +264,8 @@ void DOSFS_ToDosDateTime( time_t *unixtime, WORD *pDate, WORD *pTime ) if (pTime) *pTime = (tm->tm_hour << 11) + (tm->tm_min << 5) + (tm->tm_sec / 2); if (pDate) - *pDate = ((tm->tm_year - 80) << 9) + (tm->tm_mon << 5) + tm->tm_mday; + *pDate = ((tm->tm_year - 80) << 9) + ((tm->tm_mon + 1) << 5) + + tm->tm_mday; } @@ -506,7 +507,7 @@ const char * DOSFS_GetUnixFileName( const char * name, int check_last ) p += strlen(p); while (!IS_END_OF_NAME(*name)) name++; } - else + else if (!check_last) { *p++ = '/'; for (len--; !IS_END_OF_NAME(*name) && (len > 1); name++, len--) @@ -517,16 +518,16 @@ const char * DOSFS_GetUnixFileName( const char * name, int check_last ) } if (!found) { - if (*name) /* Not last */ - { - DOS_ERROR( ER_PathNotFound, EC_NotFound, SA_Abort, EL_Disk ); - return NULL; - } if (check_last) { DOS_ERROR( ER_FileNotFound, EC_NotFound, SA_Abort, EL_Disk ); return NULL; } + if (*name) /* Not last */ + { + DOS_ERROR( ER_PathNotFound, EC_NotFound, SA_Abort, EL_Disk ); + return NULL; + } } if (!buffer[0]) strcpy( buffer, "/" ); dprintf_dosfs( stddeb, "DOSFS_GetUnixFileName: returning %s\n", buffer ); @@ -571,19 +572,20 @@ const char * DOSFS_GetDosTrueName( const char *name, int unix_format ) return NULL; } - strcpy( buffer, "A:\\" ); - buffer[0] += drive; - if ((name[0] == '\\') || (name[0] == '/')) + p = buffer; + *p++ = 'A' + drive; + *p++ = ':'; + if (IS_END_OF_NAME(*name)) { while ((*name == '\\') || (*name == '/')) name++; - p = buffer + 2; } else { - lstrcpyn( buffer + 3, DRIVE_GetDosCwd(drive), len - 3 ); - if (buffer[3]) p = buffer + strlen(buffer); - else p = buffer + 2; + *p++ = '\\'; + lstrcpyn( p, DRIVE_GetDosCwd(drive), sizeof(buffer) - 3 ); + if (*p) p += strlen(p); else p--; } + *p = '\0'; len = MAX_PATHNAME_LEN - (int)(p - buffer); while (*name) @@ -616,10 +618,10 @@ const char * DOSFS_GetDosTrueName( const char *name, int unix_format ) name++; len--; } + *p = '\0'; } while ((*name == '\\') || (*name == '/')) name++; } - *p = '\0'; if (!buffer[2]) { buffer[2] = '\\'; @@ -639,10 +641,12 @@ const char * DOSFS_GetDosTrueName( const char *name, int unix_format ) int DOSFS_FindNext( const char *path, const char *mask, int drive, BYTE attr, int skip, DOS_DIRENT *entry ) { - DIR *dir; + static DIR *dir = NULL; struct dirent *dirent; int count = 0; - char buffer[MAX_PATHNAME_LEN], *p; + static char buffer[MAX_PATHNAME_LEN]; + static int cur_pos = 0; + char *p; const char *hash_name; if ((attr & ~(FA_UNUSED | FA_ARCHIVE | FA_RDONLY)) == FA_LABEL) @@ -656,8 +660,17 @@ int DOSFS_FindNext( const char *path, const char *mask, int drive, return 1; } - if (!(dir = opendir( path ))) return 0; - strcpy( buffer, path ); + /* Check the cached directory */ + if (dir && !strcmp( buffer, path ) && (cur_pos <= skip)) skip -= cur_pos; + else /* Not in the cache, open it anew */ + { + dprintf_dosfs( stddeb, "DOSFS_FindNext: cache miss, path=%s skip=%d buf=%s cur=%d\n", + path, skip, buffer, cur_pos ); + cur_pos = skip; + if (dir) closedir(dir); + if (!(dir = opendir( path ))) return 0; + lstrcpyn( buffer, path, sizeof(buffer) - 1 ); + } strcat( buffer, "/" ); p = buffer + strlen(buffer); attr |= FA_UNUSED | FA_ARCHIVE | FA_RDONLY; @@ -668,7 +681,7 @@ int DOSFS_FindNext( const char *path, const char *mask, int drive, count++; hash_name = DOSFS_Hash( dirent->d_name, TRUE ); if (!DOSFS_Match( mask, hash_name )) continue; - strcpy( p, dirent->d_name ); + lstrcpyn( p, dirent->d_name, sizeof(buffer) - (int)(p - buffer) ); if (!FILE_Stat( buffer, &entry->attr, &entry->size, &entry->date, &entry->time )) @@ -681,9 +694,11 @@ int DOSFS_FindNext( const char *path, const char *mask, int drive, lstrcpyn( entry->unixname, dirent->d_name, sizeof(entry->unixname) ); dprintf_dosfs( stddeb, "DOSFS_FindNext: returning %s %02x %ld\n", entry->name, entry->attr, entry->size ); - closedir( dir ); + cur_pos += count; + p[-1] = '\0'; /* Remove trailing slash in buffer */ return count; } closedir( dir ); + dir = NULL; return 0; /* End of directory */ } diff --git a/files/drive.c b/files/drive.c index ae2558d6af7..5c72a545dfd 100644 --- a/files/drive.c +++ b/files/drive.c @@ -1,5 +1,5 @@ /* - * DOS drive handling functions + * DOS drives handling functions * * Copyright 1993 Erik Bos * Copyright 1996 Alexandre Julliard @@ -7,12 +7,26 @@ #include #include +#include + +#if defined(__linux__) || defined(sun) +#include +#endif +#if defined(__NetBSD__) || defined(__FreeBSD__) +#include +#include +#include +#endif +#ifdef __svr4__ +#include +#endif #include "windows.h" #include "dos_fs.h" #include "drive.h" #include "file.h" #include "msdos.h" +#include "options.h" #include "task.h" #include "xmalloc.h" #include "stddebug.h" @@ -20,74 +34,128 @@ typedef struct { - char *root; /* root dir in Unix format without trailing '/' */ - char *dos_cwd; /* cwd in DOS format without leading or trailing '\' */ - char *unix_cwd; /* cwd in Unix format without leading or trailing '/' */ - char label[12]; /* drive label */ - DWORD serial; /* drive serial number */ - WORD type; /* drive type */ - BYTE disabled; /* disabled flag */ + char *root; /* root dir in Unix format without trailing / */ + char *dos_cwd; /* cwd in DOS format without leading or trailing \ */ + char *unix_cwd; /* cwd in Unix format without leading or trailing / */ + char label[12]; /* drive label */ + DWORD serial; /* drive serial number */ + DRIVETYPE type; /* drive type */ + BYTE disabled; /* disabled flag */ } DOSDRIVE; + +static const char *DRIVE_Types[] = +{ + "floppy", /* TYPE_FLOPPY */ + "hd", /* TYPE_HD */ + "cdrom", /* TYPE_CDROM */ + "network" /* TYPE_NETWORK */ +}; + + static DOSDRIVE DOSDrives[MAX_DOS_DRIVES]; -static int DRIVE_CurDrive = 0; +static int DRIVE_CurDrive = -1; static HTASK DRIVE_LastTask = 0; + +/*********************************************************************** + * DRIVE_GetDriveType + */ +static DRIVETYPE DRIVE_GetDriveType( const char *name ) +{ + char buffer[20]; + int i; + + PROFILE_GetWineIniString( name, "Type", "hd", buffer, sizeof(buffer) ); + for (i = 0; i < sizeof(DRIVE_Types)/sizeof(DRIVE_Types[0]); i++) + { + if (!lstrcmpi( buffer, DRIVE_Types[i] )) return (DRIVETYPE)i; + } + fprintf( stderr, "%s: unknown type '%s', defaulting to 'hd'.\n", + name, buffer ); + return TYPE_HD; +} + + /*********************************************************************** * DRIVE_Init */ int DRIVE_Init(void) { - int i, count = 0; - char drive[2] = "A"; + int i, len, count = 0; + char name[] = "Drive A"; char path[MAX_PATHNAME_LEN]; + char buffer[20]; char *p; + DOSDRIVE *drive; - for (i = 0; i < MAX_DOS_DRIVES; i++, drive[0]++) + for (i = 0, drive = DOSDrives; i < MAX_DOS_DRIVES; i++, name[6]++, drive++) { - GetPrivateProfileString( "drives", drive, "", - path, sizeof(path)-1, WineIniFileName() ); + PROFILE_GetWineIniString( name, "Path", "", path, sizeof(path)-1 ); if (path[0]) { p = path + strlen(path) - 1; while ((p > path) && ((*p == '/') || (*p == '\\'))) *p-- = '\0'; - DOSDrives[i].root = xstrdup( path ); - DOSDrives[i].dos_cwd = xstrdup( "" ); - DOSDrives[i].unix_cwd = xstrdup( "" ); - sprintf( DOSDrives[i].label, "DRIVE-%c ", drive[0] ); - DOSDrives[i].serial = 0x12345678; - DOSDrives[i].type = (i < 2) ? DRIVE_REMOVABLE : DRIVE_FIXED; - DOSDrives[i].disabled = 0; + drive->root = xstrdup( path ); + drive->dos_cwd = xstrdup( "" ); + drive->unix_cwd = xstrdup( "" ); + drive->type = DRIVE_GetDriveType( name ); + drive->disabled = 0; + + /* Get the drive label */ + PROFILE_GetWineIniString( name, "Label", name, drive->label, 12 ); + if ((len = strlen(drive->label)) < 11) + { + /* Pad label with spaces */ + memset( drive->label + len, ' ', 11 - len ); + drive->label[12] = '\0'; + } + + /* Get the serial number */ + PROFILE_GetWineIniString( name, "Serial", "12345678", + buffer, sizeof(buffer) ); + drive->serial = strtoul( buffer, NULL, 16 ); + + /* Make the first hard disk the current drive */ + if ((DRIVE_CurDrive == -1) && (drive->type == TYPE_HD)) + DRIVE_CurDrive = i; + count++; + dprintf_dosfs( stddeb, "%s: path=%s type=%s label='%s' serial=%08lx\n", + name, path, DRIVE_Types[drive->type], + drive->label, drive->serial ); } - dprintf_dosfs( stddeb, "Drive %c -> %s\n", 'A' + i, - path[0] ? path : "** None **" ); + else dprintf_dosfs( stddeb, "%s: not defined\n", name ); } if (!count) { fprintf( stderr, "Warning: no valid DOS drive found\n" ); /* Create a C drive pointing to Unix root dir */ - DOSDrives[i].root = xstrdup( "/" ); - DOSDrives[i].dos_cwd = xstrdup( "" ); - DOSDrives[i].unix_cwd = xstrdup( "" ); - sprintf( DOSDrives[i].label, "DRIVE-%c ", drive[0] ); - DOSDrives[i].serial = 0x12345678; - DOSDrives[i].type = DRIVE_FIXED; - DOSDrives[i].disabled = 0; + DOSDrives[2].root = xstrdup( "/" ); + DOSDrives[2].dos_cwd = xstrdup( "" ); + DOSDrives[2].unix_cwd = xstrdup( "" ); + strcpy( DOSDrives[2].label, "Drive C " ); + DOSDrives[2].serial = 0x12345678; + DOSDrives[2].type = TYPE_HD; + DOSDrives[2].disabled = 0; + DRIVE_CurDrive = 2; } - /* Make the first hard disk the current drive */ - for (i = 0; i < MAX_DOS_DRIVES; i++, drive[0]++) + /* Make sure the current drive is valid */ + if (DRIVE_CurDrive == -1) { - if (DOSDrives[i].root && !DOSDrives[i].disabled && - DOSDrives[i].type != DRIVE_REMOVABLE) + for (i = 0, drive = DOSDrives; i < MAX_DOS_DRIVES; i++, drive++) { - DRIVE_CurDrive = i; - break; + if (drive->root && !drive->disabled) + { + DRIVE_CurDrive = i; + break; + } } } + return 1; } @@ -143,7 +211,7 @@ int DRIVE_SetCurrentDrive( int drive ) */ int DRIVE_FindDriveRoot( const char **path ) { - int drive; + int drive, rootdrive = -1; const char *p1, *p2; dprintf_dosfs( stddeb, "DRIVE_FindDriveRoot: searching '%s'\n", *path ); @@ -154,6 +222,13 @@ int DRIVE_FindDriveRoot( const char **path ) p2 = DOSDrives[drive].root; dprintf_dosfs( stddeb, "DRIVE_FindDriveRoot: checking %c: '%s'\n", 'A' + drive, p2 ); + + while (*p2 == '/') p2++; + if (!*p2) + { + rootdrive = drive; + continue; /* Look if there's a better match */ + } for (;;) { while ((*p1 == '\\') || (*p1 == '/')) p1++; @@ -175,7 +250,7 @@ int DRIVE_FindDriveRoot( const char **path ) break; /* No match, go to next drive */ } } - return -1; + return rootdrive; } @@ -262,6 +337,16 @@ int DRIVE_SetSerialNumber( int drive, DWORD serial ) } +/*********************************************************************** + * DRIVE_GetType + */ +DRIVETYPE DRIVE_GetType( int drive ) +{ + if (!DRIVE_IsValid( drive )) return TYPE_INVALID; + return DOSDrives[drive].type; +} + + /*********************************************************************** * DRIVE_Chdir */ @@ -338,12 +423,53 @@ int DRIVE_Enable( int drive ) } +/*********************************************************************** + * DRIVE_GetFreeSpace + */ +int DRIVE_GetFreeSpace( int drive, DWORD *size, DWORD *available ) +{ + struct statfs info; + + if (!DRIVE_IsValid(drive)) + { + DOS_ERROR( ER_InvalidDrive, EC_MediaError, SA_Abort, EL_Disk ); + return 0; + } + +#ifdef __svr4__ + if (statfs( DOSDrives[drive].root, &info, 0, 0) < 0) +#else + if (statfs( DOSDrives[drive].root, &info) < 0) +#endif + { + FILE_SetDosError(); + fprintf(stderr,"dosfs: cannot do statfs(%s)\n", DOSDrives[drive].root); + return 0; + } + + *size = info.f_bsize * info.f_blocks; +#ifdef __svr4__ + *available = info.f_bfree * info.f_bsize; +#else + *available = info.f_bavail * info.f_bsize; +#endif + return 1; +} + + /*********************************************************************** * GetDriveType (KERNEL.136) */ WORD GetDriveType( INT drive ) { dprintf_dosfs( stddeb, "GetDriveType(%c:)\n", 'A' + drive ); - if (!DRIVE_IsValid(drive)) return 0; - return DOSDrives[drive].type; + switch(DRIVE_GetType(drive)) + { + case TYPE_FLOPPY: return DRIVE_REMOVABLE; + case TYPE_HD: return DRIVE_FIXED; + case TYPE_CDROM: return DRIVE_REMOVABLE; + case TYPE_NETWORK: return DRIVE_REMOTE; + case TYPE_INVALID: + default: return DRIVE_CANNOTDETERMINE; + } } diff --git a/files/file.c b/files/file.c index 19cc6fb7f57..3d00a25bc00 100644 --- a/files/file.c +++ b/files/file.c @@ -34,6 +34,7 @@ */ void FILE_SetDosError(void) { + dprintf_file(stddeb, "FILE_SetDosError: errno = %d\n", errno ); switch (errno) { case EAGAIN: @@ -44,18 +45,18 @@ void FILE_SetDosError(void) break; case ENOSPC: DOS_ERROR( ER_DiskFull, EC_MediaError, SA_Abort, EL_Disk ); - break; + break; case EACCES: case EPERM: case EROFS: - DOS_ERROR( ER_WriteProtected, EC_AccessDenied, SA_Abort, EL_Disk ); + DOS_ERROR( ER_AccessDenied, EC_AccessDenied, SA_Abort, EL_Disk ); break; case EBUSY: DOS_ERROR( ER_LockViolation, EC_AccessDenied, SA_Abort, EL_Disk ); - break; + break; case ENOENT: DOS_ERROR( ER_FileNotFound, EC_NotFound, SA_Abort, EL_Disk ); - break; + break; case EISDIR: DOS_ERROR( ER_CanNotMakeDir, EC_AccessDenied, SA_Abort, EL_Unknown ); break; @@ -65,7 +66,7 @@ void FILE_SetDosError(void) break; case EEXIST: DOS_ERROR( ER_FileExists, EC_Exists, SA_Abort, EL_Disk ); - break; + break; default: perror( "int21: unknown errno" ); DOS_ERROR( ER_GeneralFailure, EC_SystemFailure, SA_Abort, EL_Unknown ); @@ -98,6 +99,9 @@ static HFILE FILE_AllocTaskHandle( int handle ) return -1; } *fp = (BYTE)handle; + dprintf_file(stddeb, + "FILE_AllocTaskHandle: returning %d for handle %d file %d of %d \n", + (fp - files),handle,pdb->nbFiles - i, pdb->nbFiles ); return (HFILE)(fp - files); } @@ -118,6 +122,8 @@ static void FILE_FreeTaskHandle( HFILE handle ) exit(1); } files = PTR_SEG_TO_LIN( pdb->fileHandlesPtr ); + dprintf_file( stddeb,"FILE_FreeTaskHandle: dos=%d unix=%d\n", + handle, files[handle]); if ((handle<0) || (handle >= (INT)pdb->nbFiles) || (files[handle] == 0xff)) { fprintf( stderr, "FILE_FreeTaskHandle: invalid file handle %d\n", @@ -166,6 +172,7 @@ void FILE_CloseAllFiles( HANDLE hPDB ) if (!pdb) return; files = PTR_SEG_TO_LIN( pdb->fileHandlesPtr ); + fprintf(stderr,"FILE_CloseAllFiles: closing %d files\n",pdb->nbFiles); for (count = pdb->nbFiles; count > 0; count--, files++) { if (*files != 0xff) @@ -177,13 +184,47 @@ void FILE_CloseAllFiles( HANDLE hPDB ) } +/*********************************************************************** + * FILE_OpenUnixFile + */ +static int FILE_OpenUnixFile( const char *name, int mode ) +{ + int handle; + struct stat st; + + if ((handle = open( name, mode )) == -1) + { + if (Options.allowReadOnly && (mode == O_RDWR)) + { + if ((handle = open( name, O_RDONLY )) != -1) + fprintf( stderr, "Warning: could not open %s for writing, opening read-only.\n", name ); + } + } + if (handle != -1) /* Make sure it's not a directory */ + { + if ((fstat( handle, &st ) == -1)) + { + FILE_SetDosError(); + close( handle ); + handle = -1; + } + else if (S_ISDIR(st.st_mode)) + { + DOS_ERROR( ER_AccessDenied, EC_AccessDenied, SA_Abort, EL_Disk ); + close( handle ); + handle = -1; + } + } + return handle; +} + + /*********************************************************************** * FILE_Open */ int FILE_Open( LPCSTR path, int mode ) { const char *unixName; - int handle; dprintf_file(stddeb, "FILE_Open: '%s' %04x\n", path, mode ); if ((unixName = DOSFS_IsDevice( path )) != NULL) @@ -191,26 +232,13 @@ int FILE_Open( LPCSTR path, int mode ) dprintf_file( stddeb, "FILE_Open: opening device '%s'\n", unixName ); if (!unixName[0]) /* Non-existing device */ { + dprintf_file(stddeb, "FILE_Open: Non-existing device\n"); DOS_ERROR( ER_FileNotFound, EC_NotFound, SA_Abort, EL_Disk ); return -1; } - handle = open( unixName, mode ); } - else - { - if (!(unixName = DOSFS_GetUnixFileName( path, TRUE ))) return -1; - - if ((handle = open( unixName, mode )) == -1) - { - if (Options.allowReadOnly && (mode == O_RDWR)) - { - if ((handle = open( unixName, O_RDONLY )) != -1) - fprintf( stderr, "Warning: could not open %s for writing, opening read-only.\n", unixName ); - } - } - } - if (handle == -1) FILE_SetDosError(); - return handle; + else if (!(unixName = DOSFS_GetUnixFileName( path, TRUE ))) return -1; + return FILE_OpenUnixFile( unixName, mode ); } @@ -327,7 +355,7 @@ int FILE_MakeDir( LPCSTR path ) DOS_ERROR( ER_AccessDenied, EC_AccessDenied, SA_Abort, EL_Disk ); return 0; } - if (!(unixName = DOSFS_GetUnixFileName( path, TRUE ))) return 0; + if (!(unixName = DOSFS_GetUnixFileName( path, FALSE ))) return 0; if ((mkdir( unixName, 0777 ) == -1) && (errno != EEXIST)) { FILE_SetDosError(); @@ -373,6 +401,7 @@ HFILE FILE_Dup( HFILE hFile ) HFILE dosHandle; if ((handle = FILE_GetUnixHandle( hFile )) == -1) return HFILE_ERROR; + dprintf_file( stddeb, "FILE_Dup for handle %d\n",handle); if ((newhandle = dup(handle)) == -1) { FILE_SetDosError(); @@ -380,6 +409,7 @@ HFILE FILE_Dup( HFILE hFile ) } if ((dosHandle = FILE_AllocTaskHandle( newhandle )) == HFILE_ERROR) close( newhandle ); + dprintf_file( stddeb, "FILE_Dup return handle %d\n",dosHandle); return dosHandle; } @@ -396,6 +426,7 @@ HFILE FILE_Dup2( HFILE hFile1, HFILE hFile2 ) int handle, newhandle; if ((handle = FILE_GetUnixHandle( hFile1 )) == -1) return HFILE_ERROR; + dprintf_file( stddeb, "FILE_Dup2 for handle %d\n",handle); if ((hFile2 < 0) || (hFile2 >= (INT)pdb->nbFiles)) { DOS_ERROR( ER_InvalidHandle, EC_ProgramError, SA_Abort, EL_Disk ); @@ -414,8 +445,14 @@ HFILE FILE_Dup2( HFILE hFile1, HFILE hFile2 ) return HFILE_ERROR; } files = PTR_SEG_TO_LIN( pdb->fileHandlesPtr ); - if (files[hFile2] != 0xff) close( files[hFile2] ); + if (files[hFile2] != 0xff) + { + dprintf_file( stddeb, "FILE_Dup2 closing old handle2 %d\n", + files[hFile2]); + close( files[hFile2] ); + } files[hFile2] = (BYTE)newhandle; + dprintf_file( stddeb, "FILE_Dup2 return handle2 %d\n",newhandle); return hFile2; } @@ -435,7 +472,7 @@ int FILE_OpenFile( LPCSTR name, OFSTRUCT *ofs, UINT mode ) ofs->cBytes = sizeof(OFSTRUCT); ofs->nErrCode = 0; if (mode & OF_REOPEN) name = ofs->szPathName; - dprintf_file( stddeb, "Openfile: %s %04x\n", name, mode ); + dprintf_file( stddeb, "FILE_Openfile: %s %04x\n", name, mode ); /* OF_PARSE simply fills the structure */ @@ -444,10 +481,12 @@ int FILE_OpenFile( LPCSTR name, OFSTRUCT *ofs, UINT mode ) if (!(dosName = DOSFS_GetDosTrueName( name, FALSE ))) { ofs->nErrCode = DOS_ExtendedError; + dprintf_file( stddeb, "FILE_Openfile: %s return = -1\n", name); return -1; } lstrcpyn( ofs->szPathName, dosName, sizeof(ofs->szPathName) ); ofs->fFixedDisk = (GetDriveType( dosName[0]-'A' ) != DRIVE_REMOVABLE); + dprintf_file( stddeb, "FILE_Openfile: %s return = 0\n", name); return 0; } @@ -459,18 +498,21 @@ int FILE_OpenFile( LPCSTR name, OFSTRUCT *ofs, UINT mode ) if ((unixName = DOSFS_GetUnixFileName( name, FALSE )) == NULL) { ofs->nErrCode = DOS_ExtendedError; + dprintf_file( stddeb, "FILE_Openfile: %s return = -1\n", name); return -1; } - dprintf_file( stddeb, "OpenFile: creating '%s'\n", unixName ); + dprintf_file( stddeb, "FILE_OpenFile: creating '%s'\n", unixName ); handle = open( unixName, O_TRUNC | O_RDWR | O_CREAT, 0666 ); if (handle == -1) { FILE_SetDosError(); ofs->nErrCode = DOS_ExtendedError; + dprintf_file( stddeb, "FILE_Openfile: %s return = -1\n", name); return -1; } lstrcpyn( ofs->szPathName, DOSFS_GetDosTrueName( name, FALSE ), sizeof(ofs->szPathName) ); + dprintf_file( stddeb, "FILE_Openfile: %s return = %d \n", name, handle); return handle; } @@ -540,21 +582,26 @@ int FILE_OpenFile( LPCSTR name, OFSTRUCT *ofs, UINT mode ) } not_found: - dprintf_file( stddeb, "OpenFile: '%s' not found\n", name ); + dprintf_file( stddeb, "FILE_OpenFile: '%s' not found\n", name ); DOS_ERROR( ER_FileNotFound, EC_NotFound, SA_Abort, EL_Disk ); ofs->nErrCode = ER_FileNotFound; + dprintf_file( stddeb, "FILE_Openfile: %s return =-1\n", name); return -1; found: - dprintf_file( stddeb, "OpenFile: found '%s'\n", unixName ); + dprintf_file( stddeb, "FILE_OpenFile: found '%s'\n", unixName ); lstrcpyn( ofs->szPathName, DOSFS_GetDosTrueName( ofs->szPathName, FALSE ), sizeof(ofs->szPathName) ); - if (mode & OF_PARSE) return 0; - + if (mode & OF_PARSE) + { + dprintf_file( stddeb, "FILE_Openfile: %s return = 0\n", name); + return 0; + } if (mode & OF_DELETE) { if (unlink( unixName ) == -1) goto not_found; + dprintf_file( stddeb, "FILE_Openfile: %s return = 0\n", name); return 0; } @@ -569,27 +616,24 @@ found: unixMode = O_RDONLY; break; } - if ((handle = open( unixName, unixMode )) == -1) - { - if (Options.allowReadOnly && (unixMode == O_RDWR)) - { - if ((handle = open( unixName, O_RDONLY )) != -1) - fprintf( stderr, "Warning: could not open %s for writing, opening read-only.\n", unixName ); - } - } - if (handle == -1) goto not_found; + if ((handle = FILE_OpenUnixFile( unixName, unixMode )) == -1) + goto not_found; if (fstat( handle, &st ) != -1) { if ((mode & OF_VERIFY) && (mode & OF_REOPEN)) { if (memcmp( ofs->reserved, &st.st_mtime, sizeof(ofs->reserved) )) + { + dprintf_file( stddeb, "FILE_Openfile: %s return = -1\n", name); return -1; + } } memcpy( ofs->reserved, &st.st_mtime, sizeof(ofs->reserved) ); } if (mode & OF_EXIST) close( handle ); + dprintf_file( stddeb, "FILE_Openfile: %s return = %d\n", name,handle); return handle; } @@ -654,6 +698,7 @@ HFILE OpenFile( LPCSTR name, OFSTRUCT *ofs, UINT mode ) int unixHandle; HFILE handle; + dprintf_file( stddeb, "OpenFile %s \n",name); if ((unixHandle = FILE_OpenFile( name, ofs, mode )) == -1) return HFILE_ERROR; if ((handle = FILE_AllocTaskHandle( unixHandle )) == HFILE_ERROR) @@ -673,9 +718,9 @@ HFILE _lclose( HFILE hFile ) { int handle; - dprintf_file( stddeb, "_lclose: handle %d\n", hFile ); if ((handle = FILE_GetUnixHandle( hFile )) == -1) return HFILE_ERROR; + dprintf_file( stddeb, "_lclose: doshandle %d unixhandle %d\n", hFile,handle ); if (handle <= 2) { fprintf( stderr, "_lclose: internal error: closing handle %d\n", handle ); @@ -738,7 +783,7 @@ INT _lcreat_uniq( LPCSTR path, INT attr ) LONG _llseek( HFILE hFile, LONG lOffset, INT nOrigin ) { int handle, origin, result; - + dprintf_file( stddeb, "_llseek: handle %d, offset %ld, origin %d\n", hFile, lOffset, nOrigin); @@ -805,10 +850,10 @@ LONG _hread( HFILE hFile, LPSTR buffer, LONG count ) dprintf_file( stddeb, "_hread: %d %p %ld\n", hFile, buffer, count ); - if ((handle = FILE_GetUnixHandle( hFile )) == -1) return HFILE_ERROR; + if ((handle = FILE_GetUnixHandle( hFile )) == -1) return -1; if (!count) return 0; if ((result = read( handle, buffer, count )) == -1) FILE_SetDosError(); - return (result == -1) ? HFILE_ERROR : result; + return result; } diff --git a/files/profile.c b/files/profile.c new file mode 100644 index 00000000000..50816e13a8b --- /dev/null +++ b/files/profile.c @@ -0,0 +1,686 @@ +/* + * Profile functions + * + * Copyright 1993 Miguel de Icaza + * Copyright 1996 Alexandre Julliard + */ + +#include +#include +#include + +#include "dos_fs.h" +#include "windows.h" +#include "xmalloc.h" +#include "stddebug.h" +#include "debug.h" + +typedef struct tagPROFILEKEY +{ + char *name; + char *value; + struct tagPROFILEKEY *next; +} PROFILEKEY; + +typedef struct tagPROFILESECTION +{ + char *name; + struct tagPROFILEKEY *key; + struct tagPROFILESECTION *next; +} PROFILESECTION; + + +typedef struct +{ + int changed; + PROFILESECTION *section; + char *dos_name; +} PROFILE; + + +/* Cached profile file */ +static PROFILE CurProfile = { FALSE, NULL, NULL }; + +/* wine.ini profile content */ +static PROFILESECTION *WineProfile; + +#define PROFILE_MAX_LINE_LEN 1024 + +/* Wine profile name in $HOME directory; must begin with slash */ +static const char PROFILE_WineIniName[] = "/.winerc"; + +/* Check for comments in profile */ +#define IS_ENTRY_COMMENT(str) ((str)[0] == ';') + + +/*********************************************************************** + * PROFILE_CopyEntry + * + * Copy the content of an entry into a buffer, removing quotes, and possibly + * translating environment variables. + */ +static void PROFILE_CopyEntry( char *buffer, const char *value, int len, + int handle_env ) +{ + char quote = '\0'; + const char *p; + + if ((*value == '\'') || (*value == '\"')) + { + if (value[1] && (value[strlen(value)-1] == *value)) quote = *value++; + } + + if (!handle_env) + { + lstrcpyn( buffer, value, len ); + if (quote && (len >= strlen(value))) buffer[strlen(buffer)-1] = '\0'; + return; + } + + for (p = value; (*p && (len > 1)); *buffer++ = *p++, len-- ) + { + if ((*p == '$') && (p[1] == '{')) + { + char env_val[1024]; + const char *env_p; + const char *p2 = strchr( p, '}' ); + if (!p2) continue; /* ignore it */ + lstrcpyn( env_val, p + 2, MIN( sizeof(env_val), (int)(p2-p)-1 ) ); + if ((env_p = getenv( env_val )) != NULL) + { + lstrcpyn( buffer, env_p, len ); + buffer += strlen( buffer ); + len -= strlen( buffer ); + } + p = p2 + 1; + } + } + *buffer = '\0'; +} + + +/*********************************************************************** + * PROFILE_Save + * + * Save a profile tree to a file. + */ +static void PROFILE_Save( FILE *file, PROFILESECTION *section ) +{ + PROFILEKEY *key; + + for ( ; section; section = section->next) + { + if (section->name) fprintf( file, "[%s]\n", section->name ); + for (key = section->key; key; key = key->next) + { + fprintf( file, "%s", key->name ); + if (key->value) fprintf( file, "=%s", key->value ); + fprintf( file, "\n" ); + } + } +} + + +/*********************************************************************** + * PROFILE_Free + * + * Free a profile tree. + */ +static void PROFILE_Free( PROFILESECTION *section ) +{ + PROFILESECTION *next_section; + PROFILEKEY *key, *next_key; + + for ( ; section; section = next_section) + { + if (section->name) free( section->name ); + for (key = section->key; key; key = next_key) + { + next_key = key->next; + if (key->name) free( key->name ); + if (key->value) free( key->value ); + free( key ); + } + next_section = section->next; + free( section ); + } +} + + +/*********************************************************************** + * PROFILE_Load + * + * Load a profile tree from a file. + */ +static PROFILESECTION *PROFILE_Load( FILE *file ) +{ + char buffer[PROFILE_MAX_LINE_LEN]; + char *p, *p2; + int line = 0; + PROFILESECTION *section, *first_section; + PROFILESECTION **prev_section; + PROFILEKEY *key, **prev_key; + + first_section = (PROFILESECTION *)xmalloc( sizeof(*section) ); + first_section->name = NULL; + first_section->key = NULL; + first_section->next = NULL; + prev_section = &first_section->next; + prev_key = &first_section->key; + + while (fgets( buffer, PROFILE_MAX_LINE_LEN, file )) + { + line++; + p = buffer + strlen(buffer) - 1; + while ((p > buffer) && ((*p == '\n') || isspace(*p))) *p-- = '\0'; + p = buffer; + while (*p && isspace(*p)) p++; + if (*p == '[') /* section start */ + { + if (!(p2 = strrchr( p, ']' ))) + { + fprintf( stderr, "PROFILE_Load: Invalid section header at line %d: '%s'\n", + line, p ); + } + else + { + *p2 = '\0'; + p++; + section = (PROFILESECTION *)xmalloc( sizeof(*section)); + section->name = xstrdup( p ); + section->key = NULL; + section->next = NULL; + *prev_section = section; + prev_section = §ion->next; + prev_key = §ion->key; + continue; + } + } + if ((p2 = strchr( p, '=' )) != NULL) + { + char *p3 = p2 - 1; + while ((p3 > p) && isspace(*p3)) *p3-- = '\0'; + *p2++ = '\0'; + while (*p2 && isspace(*p2)) p2++; + } + key = (PROFILEKEY *)xmalloc( sizeof(*key) ); + key->name = xstrdup( p ); + key->value = p2 ? xstrdup( p2 ) : NULL; + key->next = NULL; + *prev_key = key; + prev_key = &key->next; + } + if (debugging_profile) + { + fprintf( stddeb, "PROFILE_Load:\n" ); + PROFILE_Save( stddeb, first_section ); + fprintf( stddeb, "PROFILE_Load finished.\n" ); + } + return first_section; +} + + +/*********************************************************************** + * PROFILE_DeleteSection + * + * Delete a section from a profile tree. + */ +static BOOL PROFILE_DeleteSection( PROFILESECTION **section, const char *name ) +{ + while (*section) + { + if ((*section)->name && !lstrcmpi( (*section)->name, name )) + { + PROFILESECTION *to_del = *section; + *section = to_del->next; + to_del->next = NULL; + PROFILE_Free( to_del ); + return TRUE; + } + section = &(*section)->next; + } + return FALSE; +} + + +/*********************************************************************** + * PROFILE_DeleteKey + * + * Delete a key from a profile tree. + */ +static BOOL PROFILE_DeleteKey( PROFILESECTION **section, + const char *section_name, const char *key_name ) +{ + while (*section) + { + if ((*section)->name && !lstrcmpi( (*section)->name, section_name )) + { + PROFILEKEY **key = &(*section)->key; + while (*key) + { + if (!lstrcmpi( (*key)->name, key_name )) + { + PROFILEKEY *to_del = *key; + *key = to_del->next; + if (to_del->name) free( to_del->name ); + if (to_del->value) free( to_del->value ); + free( to_del ); + return TRUE; + } + key = &(*key)->next; + } + } + section = &(*section)->next; + } + return FALSE; +} + + +/*********************************************************************** + * PROFILE_Find + * + * Find a key in a profile tree, optionally creating it. + */ +static PROFILEKEY *PROFILE_Find( PROFILESECTION **section, + const char *section_name, + const char *key_name, int create ) +{ + while (*section) + { + if ((*section)->name && !lstrcmpi( (*section)->name, section_name )) + { + PROFILEKEY **key = &(*section)->key; + while (*key) + { + if (!lstrcmpi( (*key)->name, key_name )) return *key; + key = &(*key)->next; + } + if (!create) return NULL; + *key = (PROFILEKEY *)xmalloc( sizeof(PROFILEKEY) ); + (*key)->name = xstrdup( key_name ); + (*key)->value = NULL; + (*key)->next = NULL; + return *key; + } + section = &(*section)->next; + } + if (!create) return NULL; + *section = (PROFILESECTION *)xmalloc( sizeof(PROFILESECTION) ); + (*section)->name = xstrdup(section_name); + (*section)->next = NULL; + (*section)->key = (PROFILEKEY *)xmalloc( sizeof(PROFILEKEY) ); + (*section)->key->name = xstrdup( key_name ); + (*section)->key->value = NULL; + (*section)->key->next = NULL; + return (*section)->key; +} + + +/*********************************************************************** + * PROFILE_FlushFile + * + * Flush the current profile to disk if changed. + */ +static BOOL PROFILE_FlushFile(void) +{ + char *p, buffer[MAX_PATHNAME_LEN]; + const char *unix_name; + FILE *file = NULL; + + if (!CurProfile.changed || !CurProfile.dos_name) return TRUE; + if (!(unix_name = DOSFS_GetUnixFileName( CurProfile.dos_name, FALSE )) || + !(file = fopen( unix_name, "w" ))) + { + /* Try to create it in $HOME/.wine */ + /* FIXME: this will need a more general solution */ + if ((p = getenv( "HOME" )) != NULL) + { + strcpy( buffer, p ); + strcat( buffer, "/.wine/" ); + p = buffer + strlen(buffer); + strcpy( p, strrchr( CurProfile.dos_name, '\\' ) + 1 ); + AnsiLower( p ); + file = fopen( buffer, "w" ); + unix_name = buffer; + } + } + + if (!file) + { + fprintf( stderr, "Warning: could not save profile file %s\n", + CurProfile.dos_name ); + return FALSE; + } + + dprintf_profile( stddeb, "Saving '%s' into '%s'\n", + CurProfile.dos_name, unix_name ); + PROFILE_Save( file, CurProfile.section ); + fclose( file ); + CurProfile.changed = FALSE; + return TRUE; +} + + +/*********************************************************************** + * PROFILE_Open + * + * Open a profile file, checking the cached file first. + */ +static BOOL PROFILE_Open( const char *filename ) +{ + char buffer[MAX_PATHNAME_LEN]; + const char *dos_name, *unix_name; + char *newdos_name, *p; + FILE *file = NULL; + + if (strchr( filename, '/' ) || strchr( filename, '\\' ) || + strchr( filename, ':' )) + { + if (!(dos_name = DOSFS_GetDosTrueName( filename, FALSE))) return FALSE; + } + else + { + GetWindowsDirectory( buffer, sizeof(buffer) ); + strcat( buffer, "\\" ); + strcat( buffer, filename ); + if (!(dos_name = DOSFS_GetDosTrueName( buffer, FALSE ))) return FALSE; + } + if (CurProfile.dos_name && !strcmp( dos_name, CurProfile.dos_name )) + { + dprintf_profile( stddeb, "PROFILE_Open(%s): already opened\n", + filename ); + return TRUE; + } + + /* Flush the previous profile */ + + newdos_name = xstrdup( dos_name ); + PROFILE_FlushFile(); + PROFILE_Free( CurProfile.section ); + if (CurProfile.dos_name) free( CurProfile.dos_name ); + CurProfile.section = NULL; + CurProfile.dos_name = newdos_name; + + /* Try to open the profile file, first in $HOME/.wine */ + + /* FIXME: this will need a more general solution */ + if ((p = getenv( "HOME" )) != NULL) + { + strcpy( buffer, p ); + strcat( buffer, "/.wine/" ); + p = buffer + strlen(buffer); + strcpy( p, strrchr( newdos_name, '\\' ) + 1 ); + AnsiLower( p ); + if ((file = fopen( buffer, "r" ))) + dprintf_profile( stddeb, "Found it in %s\n", buffer ); + } + + if (!file && ((unix_name = DOSFS_GetUnixFileName( dos_name, TRUE )))) + { + if ((file = fopen( unix_name, "r" ))) + dprintf_profile( stddeb, "Found it in %s\n", unix_name ); + } + + if (file) + { + CurProfile.section = PROFILE_Load( file ); + fclose( file ); + } + else + fprintf( stderr, "Warning: profile file %s not found\n", newdos_name ); + dprintf_profile( stddeb, "PROFILE_Open(%s): successful\n", filename ); + return TRUE; +} + + +/*********************************************************************** + * PROFILE_GetSection + * + * Enumerate all the keys of a section. + */ +static INT PROFILE_GetSection( PROFILESECTION *section, + const char *section_name, + char *buffer, INT len, int handle_env ) +{ + PROFILEKEY *key; + while (section) + { + if (section->name && !lstrcmpi( section->name, section_name )) + { + for (key = section->key; key; key = key->next) + { + if (len <= 2) break; + if (IS_ENTRY_COMMENT(key->name)) continue; /* Skip comments */ + PROFILE_CopyEntry( buffer, key->name, len - 1, handle_env ); + len -= strlen(buffer) - 1; + buffer += strlen(buffer) + 1; + } + *buffer = '\0'; + return len - 1; + } + section = section->next; + } + buffer[0] = buffer[1] = '\0'; + return len - 2; +} + + +/*********************************************************************** + * PROFILE_GetString + * + * Get a profile string. + */ +static INT PROFILE_GetString( const char *section, const char *key_name, + const char *def_val, char *buffer, INT len ) +{ + PROFILEKEY *key = NULL; + + if (!def_val) def_val = ""; + if (key_name) + { + key = PROFILE_Find( &CurProfile.section, section, key_name, FALSE ); + PROFILE_CopyEntry( buffer, (key && key->value) ? key->value : def_val, + len, FALSE ); + dprintf_profile( stddeb, "PROFILE_GetString('%s','%s','%s'): returning '%s'\n", + section, key_name, def_val, buffer ); + return strlen( buffer ); + } + return PROFILE_GetSection(CurProfile.section, section, buffer, len, FALSE); +} + + +/*********************************************************************** + * PROFILE_SetString + * + * Set a profile string. + */ +static BOOL PROFILE_SetString( const char *section_name, const char *key_name, + const char *value ) +{ + BOOL ret; + + if (!key_name) /* Delete a whole section */ + { + dprintf_profile(stddeb, "PROFILE_DeleteSection('%s')\n", section_name); + ret = PROFILE_DeleteSection( &CurProfile.section, section_name ); + CurProfile.changed |= ret; + return ret; + } + else if (!value) /* Delete a key */ + { + dprintf_profile( stddeb, "PROFILE_DeleteKey('%s','%s')\n", + section_name, key_name ); + ret = PROFILE_DeleteKey( &CurProfile.section, section_name, key_name ); + CurProfile.changed |= ret; + return ret; + } + else /* Set the key value */ + { + PROFILEKEY *key = PROFILE_Find( &CurProfile.section, section_name, + key_name, TRUE ); + dprintf_profile( stddeb, "PROFILE_SetString('%s','%s','%s'): ", + section_name, key_name, value ); + if (key->value) + { + if (!strcmp( key->value, value )) + { + dprintf_profile( stddeb, "no change needed\n" ); + return TRUE; /* No change needed */ + } + dprintf_profile( stddeb, "replacing '%s'\n", key->value ); + free( key->value ); + } + else dprintf_profile( stddeb, "creating key\n" ); + key->value = xstrdup( value ); + CurProfile.changed = TRUE; + return TRUE; + } +} + + +/*********************************************************************** + * PROFILE_GetWineIniString + * + * Get a config string from the wine.ini file. + */ +int PROFILE_GetWineIniString( const char *section, const char *key_name, + const char *def, char *buffer, int len ) +{ + if (key_name) + { + PROFILEKEY *key = PROFILE_Find(&WineProfile, section, key_name, FALSE); + PROFILE_CopyEntry( buffer, (key && key->value) ? key->value : def, + len, TRUE ); + dprintf_profile( stddeb, "PROFILE_GetWineIniString('%s','%s','%s'): returning '%s'\n", + section, key_name, def, buffer ); + return strlen( buffer ); + } + return PROFILE_GetSection( WineProfile, section, buffer, len, TRUE ); +} + + +/*********************************************************************** + * PROFILE_LoadWineIni + * + * Load the wine.ini file. + */ +int PROFILE_LoadWineIni(void) +{ + char buffer[MAX_PATHNAME_LEN]; + const char *p; + FILE *f; + + if ((p = getenv( "HOME" )) != NULL) + { + lstrcpyn( buffer, p, MAX_PATHNAME_LEN - sizeof(PROFILE_WineIniName) ); + strcat( buffer, PROFILE_WineIniName ); + if ((f = fopen( buffer, "r" )) != NULL) + { + WineProfile = PROFILE_Load( f ); + fclose( f ); + return 1; + } + } + else fprintf( stderr, "Warning: could not get $HOME value for config file.\n" ); + + /* Try global file */ + + if ((f = fopen( WINE_INI_GLOBAL, "r" )) != NULL) + { + WineProfile = PROFILE_Load( f ); + fclose( f ); + return 1; + } + fprintf( stderr, "Can't open configuration file %s or $HOME%s\n", + WINE_INI_GLOBAL, PROFILE_WineIniName ); + return 0; +} + + +/*********************************************************************** + * GetProfileInt (KERNEL.57) + */ +UINT GetProfileInt( LPCSTR section, LPCSTR entry, INT def_val ) +{ + return GetPrivateProfileInt( section, entry, def_val, "win.ini" ); +} + + +/*********************************************************************** + * GetProfileString (KERNEL.58) + */ +INT GetProfileString( LPCSTR section, LPCSTR entry, LPCSTR def_val, + LPSTR buffer, INT len ) +{ + return GetPrivateProfileString( section, entry, def_val, + buffer, len, "win.ini" ); +} + + +/*********************************************************************** + * WriteProfileString (KERNEL.59) + */ +BOOL WriteProfileString( LPCSTR section, LPCSTR entry, LPCSTR string ) +{ + return WritePrivateProfileString( section, entry, string, "win.ini" ); +} + + +/*********************************************************************** + * GetPrivateProfileInt (KERNEL.127) + */ +UINT GetPrivateProfileInt( LPCSTR section, LPCSTR entry, INT def_val, + LPCSTR filename ) +{ + char buffer[20]; + char *p; + long result; + + GetPrivateProfileString( section, entry, "", + buffer, sizeof(buffer), filename ); + if (!buffer[0]) return (UINT)def_val; + result = strtol( buffer, &p, 0 ); + if (p == buffer) return 0; /* No digits at all */ +#ifdef WINELIB32 + return (UINT)result; +#else + if (result > 65535) return 65535; + if (result >= 0) return (UINT)result; + if (result < -32768) return -32768; + return (UINT)(INT)result; +#endif +} + + +/*********************************************************************** + * GetPrivateProfileString (KERNEL.128) + */ +INT GetPrivateProfileString( LPCSTR section, LPCSTR entry, LPCSTR def_val, + LPSTR buffer, INT len, LPCSTR filename ) +{ + if (PROFILE_Open( filename )) + return PROFILE_GetString( section, entry, def_val, buffer, len ); + lstrcpyn( buffer, def_val, len ); + return strlen( buffer ); +} + + +/*********************************************************************** + * WritePrivateProfileString (KERNEL.129) + */ +BOOL WritePrivateProfileString( LPCSTR section, LPCSTR entry, LPCSTR string, + LPCSTR filename ) +{ + if (!PROFILE_Open( filename )) return FALSE; + if (!section) return PROFILE_FlushFile(); + return PROFILE_SetString( section, entry, string ); +} + + +/*********************************************************************** + * WriteOutProfiles (KERNEL.315) + */ +void WriteOutProfiles(void) +{ + PROFILE_FlushFile(); +} diff --git a/if1632/callback.c b/if1632/callback.c index 27d236c510a..346289e735a 100644 --- a/if1632/callback.c +++ b/if1632/callback.c @@ -46,7 +46,7 @@ LONG CallWindowProc( WNDPROC func, HWND hwnd, WORD message, /********************************************************************** * Catch (KERNEL.55) */ -int Catch( LPCATCHBUF lpbuf ) +INT Catch( LPCATCHBUF lpbuf ) { STACK16FRAME *pFrame = CURRENT_STACK16; diff --git a/if1632/gdi32.spec b/if1632/gdi32.spec index 86bd082a710..43d7586d8bb 100644 --- a/if1632/gdi32.spec +++ b/if1632/gdi32.spec @@ -71,7 +71,7 @@ base 1 0067 stdcall DeleteDC(long) DeleteDC 0068 stub DeleteEnhMetaFile 0069 stub DeleteMetaFile -0070 stub DeleteObject +0070 stdcall DeleteObject(long) DeleteObject 0071 stub DescribePixelFormat 0072 stub DeviceCapabilitiesExA 0073 stub DeviceCapabilitiesExW @@ -212,7 +212,7 @@ base 1 0208 stub GetOutlineTextMetricsW 0209 stub GetPaletteEntries 0210 stub GetPath -0211 stub GetPixel +0211 stdcall GetPixel(long long long) GetPixel 0212 stub GetPixelFormat 0213 stub GetPolyFillMode 0214 stub GetROP2 @@ -255,7 +255,7 @@ base 1 0251 stub LoadImageColorMatcherW 0252 stub MaskBlt 0253 stub ModifyWorldTransform -0254 stdcall MoveToEx(long long long ptr) MoveToEx +0254 stdcall MoveToEx(long long long ptr) WIN32_MoveToEx 0255 stub OffsetClipRgn 0256 stub OffsetRgn 0257 stub OffsetViewportOrgEx @@ -328,7 +328,7 @@ base 1 0324 stub SetMetaRgn 0325 stub SetMiterLimit 0326 stub SetPaletteEntries -0327 stub SetPixel +0327 stdcall SetPixel(long long long long) SetPixel 0328 stub SetPixelFormat 0329 stub SetPixelV 0330 stub SetPolyFillMode diff --git a/if1632/kernel.spec b/if1632/kernel.spec index d4e789857ad..01fa49f9487 100644 --- a/if1632/kernel.spec +++ b/if1632/kernel.spec @@ -53,7 +53,7 @@ id 1 54 pascal16 GetInstanceData(word word word) GetInstanceData 55 pascal16 Catch(ptr) Catch 56 pascal16 Throw(ptr word) Throw -57 pascal16 GetProfileInt(ptr ptr word) GetProfileInt +57 pascal16 GetProfileInt(ptr ptr s_word) GetProfileInt 58 pascal16 GetProfileString(ptr ptr ptr ptr word) GetProfileString 59 pascal16 WriteProfileString(ptr ptr ptr) WriteProfileString 60 pascal16 FindResource(word segptr segptr) FindResource @@ -124,7 +124,7 @@ id 1 125 return DisableKernel 0 0 126 stub MemoryFreed 127 pascal16 GetPrivateProfileInt(ptr ptr s_word ptr) GetPrivateProfileInt -128 pascal16 GetPrivateProfileString(ptr ptr ptr ptr s_word ptr) +128 pascal16 GetPrivateProfileString(ptr ptr ptr ptr word ptr) GetPrivateProfileString 129 pascal16 WritePrivateProfileString(ptr ptr ptr ptr) WritePrivateProfileString @@ -228,7 +228,7 @@ id 1 310 pascal16 LocalHandleDelta(word) LocalHandleDelta 311 stub GetSetKernelDosProc 314 stub DebugDefineSegment -315 pascal WriteOutProfiles() sync_profiles +315 pascal16 WriteOutProfiles() WriteOutProfiles 316 stub GetFreeMemInfo 318 stub FatalExitHook 319 stub FlushCachedFileHandle diff --git a/if1632/kernel32.spec b/if1632/kernel32.spec index b1c7193c103..a660700773e 100644 --- a/if1632/kernel32.spec +++ b/if1632/kernel32.spec @@ -584,12 +584,12 @@ base 1 0579 stub WriteFileEx 0580 stub WritePrivateProfileSectionA 0581 stub WritePrivateProfileSectionW -0582 stub WritePrivateProfileStringA +0582 stdcall WritePrivateProfileStringA(ptr ptr ptr ptr) WritePrivateProfileString 0583 stub WritePrivateProfileStringW 0584 stub WriteProcessMemory 0585 stub WriteProfileSectionA 0586 stub WriteProfileSectionW -0587 stub WriteProfileStringA +0587 stdcall WriteProfileStringA(ptr ptr ptr) WriteProfileString 0588 stub WriteProfileStringW 0589 stub WriteTapemark 0590 stub _hread diff --git a/if1632/relay.c b/if1632/relay.c index 6f6f7c89abc..b5f1a2b85b9 100644 --- a/if1632/relay.c +++ b/if1632/relay.c @@ -246,6 +246,6 @@ void RELAY_DebugCall16( int* stack, int nbargs ) printf( "CallTo16(func=%04x:%04x,ds=%04x", HIWORD(stack[0]), LOWORD(stack[0]), LOWORD(stack[1]) ); stack += 2; - while (nbargs--) printf( ",0x%x", *stack++ ); + while (nbargs--) printf( ",0x%04x", *stack++ ); printf( ")\n" ); } diff --git a/if1632/relay32.c b/if1632/relay32.c index 7da3a475181..a380483df2b 100644 --- a/if1632/relay32.c +++ b/if1632/relay32.c @@ -85,8 +85,10 @@ void *RELAY32_GetEntryPoint(char *dll_name, char *item, int hint) dprintf_module(stddeb, "Looking for %s in %s, hint %x\n", item ? item: "(no name)", dll_name, hint); dll=RELAY32_GetBuiltinDLL(dll_name); - /* This should deal with built-in DLLs only. See pe_module on loading - PE DLLs */ + /* FIXME: This should deal with built-in DLLs only. See pe_module on + loading PE DLLs */ + if(!dll) + return 0; #if 0 if(!dll) { if(!wine_files || !wine_files->name || diff --git a/if1632/toolhelp.spec b/if1632/toolhelp.spec index 9bfe141b23f..1c590d4cf50 100644 --- a/if1632/toolhelp.spec +++ b/if1632/toolhelp.spec @@ -24,8 +24,8 @@ id 12 70 pascal16 ClassNext(ptr) ClassNext 71 pascal16 SystemHeapInfo(ptr) SystemHeapInfo 72 pascal16 MemManInfo(ptr) MemManInfo -73 stub NOTIFYREGISTER -74 stub NOTIFYUNREGISTER +73 pascal16 NotifyRegister(word segptr word) NotifyRegister +74 pascal16 NotifyUnregister(word) NotifyUnregister 75 return INTERRUPTREGISTER 6 0 76 return INTERRUPTUNREGISTER 2 0 77 stub TERMINATEAPP diff --git a/if1632/user.spec b/if1632/user.spec index 240daa54bf5..9d4f57bb9cb 100644 --- a/if1632/user.spec +++ b/if1632/user.spec @@ -98,7 +98,7 @@ id 2 97 pascal16 CheckDlgButton(word word word) CheckDlgButton 98 pascal16 IsDlgButtonChecked(word word) IsDlgButtonChecked 99 pascal16 DlgDirSelect(word ptr word) DlgDirSelect -100 pascal16 DlgDirList(word ptr word word word) DlgDirList +100 pascal16 DlgDirList(word segptr word word word) DlgDirList 101 pascal SendDlgItemMessage(word word word word long) SendDlgItemMessage 102 pascal16 AdjustWindowRect(ptr long word) AdjustWindowRect 103 pascal16 MapDialogRect(word ptr) MapDialogRect @@ -151,7 +151,7 @@ id 2 150 pascal16 LoadMenu(word segptr) LoadMenu 151 pascal16 CreateMenu() CreateMenu 152 pascal16 DestroyMenu(word) DestroyMenu -153 pascal16 ChangeMenu(word word ptr word word) ChangeMenu +153 pascal16 ChangeMenu(word word segptr word word) ChangeMenu 154 pascal16 CheckMenuItem(word word word) CheckMenuItem 155 pascal16 EnableMenuItem(word word word) EnableMenuItem 156 pascal16 GetSystemMenu(word word) GetSystemMenu @@ -219,7 +219,7 @@ id 2 217 pascal16 LookupMenuHandle(word s_word) LookupMenuHandle 218 pascal16 DialogBoxIndirect(word word word segptr) DialogBoxIndirect 219 pascal16 CreateDialogIndirect(word segptr word segptr) CreateDialogIndirect -220 pascal16 LoadMenuIndirect(ptr) LoadMenuIndirect +220 pascal16 LoadMenuIndirect(segptr) LoadMenuIndirect 221 pascal16 ScrollDC(word s_word s_word ptr ptr word ptr) ScrollDC 222 pascal16 GetKeyboardState(ptr) GetKeyboardState 223 pascal16 SetKeyboardState(ptr) SetKeyboardState @@ -362,11 +362,11 @@ id 2 408 pascal16 CreateCursorIconIndirect(word ptr ptr ptr) CreateCursorIconIndirect 409 stub InitThreadInput -410 pascal16 InsertMenu(word word word word ptr) InsertMenu -411 pascal16 AppendMenu(word word word ptr) AppendMenu +410 pascal16 InsertMenu(word word word word segptr) InsertMenu +411 pascal16 AppendMenu(word word word segptr) AppendMenu 412 pascal16 RemoveMenu(word word word) RemoveMenu 413 pascal16 DeleteMenu(word word word) DeleteMenu -414 pascal16 ModifyMenu(word word word word ptr) ModifyMenu +414 pascal16 ModifyMenu(word word word word segptr) ModifyMenu 415 pascal16 CreatePopupMenu() CreatePopupMenu 416 pascal16 TrackPopupMenu(word word word word word word ptr) TrackPopupMenu 417 pascal GetMenuCheckMarkDimensions() GetMenuCheckMarkDimensions diff --git a/if1632/user32.spec b/if1632/user32.spec index 50f41ee71cf..1a56acc52b1 100644 --- a/if1632/user32.spec +++ b/if1632/user32.spec @@ -165,15 +165,15 @@ base 1 0160 stdcall DrawMenuBar(long) DrawMenuBar 0161 stub DrawStateA 0162 stub DrawStateW -0163 stdcall DrawTextA(long ptr long ptr long) DrawText +0163 stdcall DrawTextA(long ptr long ptr long) USER32_DrawTextA 0164 stub DrawTextExA 0165 stub DrawTextExW 0166 stub DrawTextW 0167 stub EditWndProc -0168 stub EmptyClipboard -0169 stub EnableMenuItem -0170 stub EnableScrollBar -0171 stub EnableWindow +0168 stdcall EmptyClipboard() EmptyClipboard +0169 stdcall EnableMenuItem(long long long) EnableMenuItem +0170 stdcall EnableScrollBar(long long long) EnableScrollBar +0171 stdcall EnableWindow(long long) EnableWindow 0172 stub EndDeferWindowPos 0173 stub EndDialog 0174 stub EndMenu @@ -221,7 +221,7 @@ base 1 0216 stub GetClassNameA 0217 stub GetClassNameW 0218 stub GetClassWord -0219 stdcall GetClientRect(long long) GetClientRect +0219 stdcall GetClientRect(long long) USER32_GetClientRect 0220 stub GetClipCursor 0221 stub GetClipboardData 0222 stub GetClipboardFormatNameA @@ -329,7 +329,7 @@ base 1 0324 stub InsertMenuW 0325 stub InternalGetWindowText 0326 stub IntersectRect -0327 stub InvalidateRect +0327 stdcall InvalidateRect(long ptr long) USER32_InvalidateRect 0328 stub InvalidateRgn 0329 stub InvertRect 0330 stub IsCharAlphaA @@ -356,10 +356,10 @@ base 1 0351 stub IsZoomed 0352 stub KillSystemTimer 0353 stub KillTimer -0354 stdcall LoadAcceleratorsA(long ptr) LoadAccelerators32 -0355 stub LoadAcceleratorsW -0356 stdcall LoadBitmapA(long ptr) LoadBitmapA32 -0357 stdcall LoadBitmapW(long ptr) LoadBitmapW32 +0354 stdcall LoadAcceleratorsA(long ptr) WIN32_LoadAcceleratorsA +0355 stdcall LoadAcceleratorsW(long ptr) WIN32_LoadAcceleratorsW +0356 stdcall LoadBitmapA(long ptr) WIN32_LoadBitmapA +0357 stdcall LoadBitmapW(long ptr) WIN32_LoadBitmapW 0357 stub LoadBitmapW 0358 stdcall LoadCursorA(long ptr) LoadCursor 0359 stub LoadCursorFromFileA @@ -372,13 +372,13 @@ base 1 0366 stub LoadKeyboardLayoutA 0367 stub LoadKeyboardLayoutW 0368 stub LoadLocalFonts -0369 stub LoadMenuA -0370 stub LoadMenuIndirectA -0371 stub LoadMenuIndirectW -0372 stub LoadMenuW +0369 stdcall LoadMenuA(long ptr) WIN32_LoadMenuA +0370 stdcall LoadMenuIndirectA(long ptr) WIN32_LoadMenuIndirectA +0371 stdcall LoadMenuIndirectW(long ptr) WIN32_LoadMenuIndirectW +0372 stdcall LoadMenuW(long ptr) WIN32_LoadMenuW 0373 stub LoadRemoteFonts -0374 stdcall LoadStringA(long long ptr long) LoadStringA32 -0375 stdcall LoadStringW(long long ptr long) LoadString32 +0374 stdcall LoadStringA(long long ptr long) WIN32_LoadStringA +0375 stdcall LoadStringW(long long ptr long) WIN32_LoadStringW 0376 stub LockWindowStation 0377 stub LockWindowUpdate 0378 stub LookupIconIdFromDirectory @@ -524,7 +524,7 @@ base 1 0518 stub SetWindowPlacement 0519 stub SetWindowPos 0520 stub SetWindowStationUser -0521 stub SetWindowTextA +0521 stdcall SetWindowTextA(long ptr) SetWindowText 0522 stub SetWindowTextW 0523 stub SetWindowWord 0524 stub SetWindowsHookA @@ -581,7 +581,7 @@ base 1 0575 stub VkKeyScanW 0576 stub WaitForInputIdle 0577 stub WaitMessage -0578 stub WinHelpA +0578 stdcall WinHelpA(long ptr long long) WIN32_WinHelpA 0579 stub WinHelpW 0580 stub WindowFromDC 0581 stub WindowFromPoint diff --git a/include/debug.h b/include/debug.h index 928922e788b..82e08ebddd7 100644 --- a/include/debug.h +++ b/include/debug.h @@ -54,13 +54,11 @@ #undef DEBUG_LDT #undef DEBUG_LISTBOX #undef DEBUG_LOCAL -#undef DEBUG_MALLOC #undef DEBUG_MCI #undef DEBUG_MCIANIM #undef DEBUG_MCIWAVE #undef DEBUG_MDI #undef DEBUG_MENU -#undef DEBUG_MENUCALC #undef DEBUG_MESSAGE #undef DEBUG_METAFILE #undef DEBUG_MIDI @@ -134,13 +132,11 @@ #define DEBUG_LDT #define DEBUG_LISTBOX #define DEBUG_LOCAL -#define DEBUG_MALLOC #define DEBUG_MCI #define DEBUG_MCIANIM #define DEBUG_MCIWAVE #define DEBUG_MDI #define DEBUG_MENU -#define DEBUG_MENUCALC #define DEBUG_MESSAGE #define DEBUG_METAFILE #define DEBUG_MIDI @@ -368,11 +364,6 @@ short debug_msg_enabled[]={ #else 0, #endif -#ifdef DEBUG_MALLOC - 1, -#else - 0, -#endif #ifdef DEBUG_MCI 1, #else @@ -398,11 +389,6 @@ short debug_msg_enabled[]={ #else 0, #endif -#ifdef DEBUG_MENUCALC - 1, -#else - 0, -#endif #ifdef DEBUG_MESSAGE 1, #else @@ -1065,21 +1051,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_malloc if(!debug_msg_enabled[38]) ; else fprintf -#define debugging_malloc debug_msg_enabled[38] -#else -#ifdef DEBUG_MALLOC -#define dprintf_malloc fprintf -#define debugging_malloc 1 -#else -#define dprintf_malloc while(0) fprintf -#define debugging_malloc 0 -#endif -#endif - -#ifdef DEBUG_RUNTIME -#define dprintf_mci if(!debug_msg_enabled[39]) ; else fprintf -#define debugging_mci debug_msg_enabled[39] +#define dprintf_mci if(!debug_msg_enabled[38]) ; else fprintf +#define debugging_mci debug_msg_enabled[38] #else #ifdef DEBUG_MCI #define dprintf_mci fprintf @@ -1091,8 +1064,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_mcianim if(!debug_msg_enabled[40]) ; else fprintf -#define debugging_mcianim debug_msg_enabled[40] +#define dprintf_mcianim if(!debug_msg_enabled[39]) ; else fprintf +#define debugging_mcianim debug_msg_enabled[39] #else #ifdef DEBUG_MCIANIM #define dprintf_mcianim fprintf @@ -1104,8 +1077,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_mciwave if(!debug_msg_enabled[41]) ; else fprintf -#define debugging_mciwave debug_msg_enabled[41] +#define dprintf_mciwave if(!debug_msg_enabled[40]) ; else fprintf +#define debugging_mciwave debug_msg_enabled[40] #else #ifdef DEBUG_MCIWAVE #define dprintf_mciwave fprintf @@ -1117,8 +1090,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_mdi if(!debug_msg_enabled[42]) ; else fprintf -#define debugging_mdi debug_msg_enabled[42] +#define dprintf_mdi if(!debug_msg_enabled[41]) ; else fprintf +#define debugging_mdi debug_msg_enabled[41] #else #ifdef DEBUG_MDI #define dprintf_mdi fprintf @@ -1130,8 +1103,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_menu if(!debug_msg_enabled[43]) ; else fprintf -#define debugging_menu debug_msg_enabled[43] +#define dprintf_menu if(!debug_msg_enabled[42]) ; else fprintf +#define debugging_menu debug_msg_enabled[42] #else #ifdef DEBUG_MENU #define dprintf_menu fprintf @@ -1143,21 +1116,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_menucalc if(!debug_msg_enabled[44]) ; else fprintf -#define debugging_menucalc debug_msg_enabled[44] -#else -#ifdef DEBUG_MENUCALC -#define dprintf_menucalc fprintf -#define debugging_menucalc 1 -#else -#define dprintf_menucalc while(0) fprintf -#define debugging_menucalc 0 -#endif -#endif - -#ifdef DEBUG_RUNTIME -#define dprintf_message if(!debug_msg_enabled[45]) ; else fprintf -#define debugging_message debug_msg_enabled[45] +#define dprintf_message if(!debug_msg_enabled[43]) ; else fprintf +#define debugging_message debug_msg_enabled[43] #else #ifdef DEBUG_MESSAGE #define dprintf_message fprintf @@ -1169,8 +1129,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_metafile if(!debug_msg_enabled[46]) ; else fprintf -#define debugging_metafile debug_msg_enabled[46] +#define dprintf_metafile if(!debug_msg_enabled[44]) ; else fprintf +#define debugging_metafile debug_msg_enabled[44] #else #ifdef DEBUG_METAFILE #define dprintf_metafile fprintf @@ -1182,8 +1142,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_midi if(!debug_msg_enabled[47]) ; else fprintf -#define debugging_midi debug_msg_enabled[47] +#define dprintf_midi if(!debug_msg_enabled[45]) ; else fprintf +#define debugging_midi debug_msg_enabled[45] #else #ifdef DEBUG_MIDI #define dprintf_midi fprintf @@ -1195,8 +1155,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_mmio if(!debug_msg_enabled[48]) ; else fprintf -#define debugging_mmio debug_msg_enabled[48] +#define dprintf_mmio if(!debug_msg_enabled[46]) ; else fprintf +#define debugging_mmio debug_msg_enabled[46] #else #ifdef DEBUG_MMIO #define dprintf_mmio fprintf @@ -1208,8 +1168,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_mmsys if(!debug_msg_enabled[49]) ; else fprintf -#define debugging_mmsys debug_msg_enabled[49] +#define dprintf_mmsys if(!debug_msg_enabled[47]) ; else fprintf +#define debugging_mmsys debug_msg_enabled[47] #else #ifdef DEBUG_MMSYS #define dprintf_mmsys fprintf @@ -1221,8 +1181,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_mmtime if(!debug_msg_enabled[50]) ; else fprintf -#define debugging_mmtime debug_msg_enabled[50] +#define dprintf_mmtime if(!debug_msg_enabled[48]) ; else fprintf +#define debugging_mmtime debug_msg_enabled[48] #else #ifdef DEBUG_MMTIME #define dprintf_mmtime fprintf @@ -1234,8 +1194,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_module if(!debug_msg_enabled[51]) ; else fprintf -#define debugging_module debug_msg_enabled[51] +#define dprintf_module if(!debug_msg_enabled[49]) ; else fprintf +#define debugging_module debug_msg_enabled[49] #else #ifdef DEBUG_MODULE #define dprintf_module fprintf @@ -1247,8 +1207,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_msg if(!debug_msg_enabled[52]) ; else fprintf -#define debugging_msg debug_msg_enabled[52] +#define dprintf_msg if(!debug_msg_enabled[50]) ; else fprintf +#define debugging_msg debug_msg_enabled[50] #else #ifdef DEBUG_MSG #define dprintf_msg fprintf @@ -1260,8 +1220,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_nonclient if(!debug_msg_enabled[53]) ; else fprintf -#define debugging_nonclient debug_msg_enabled[53] +#define dprintf_nonclient if(!debug_msg_enabled[51]) ; else fprintf +#define debugging_nonclient debug_msg_enabled[51] #else #ifdef DEBUG_NONCLIENT #define dprintf_nonclient fprintf @@ -1273,8 +1233,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_ole if(!debug_msg_enabled[54]) ; else fprintf -#define debugging_ole debug_msg_enabled[54] +#define dprintf_ole if(!debug_msg_enabled[52]) ; else fprintf +#define debugging_ole debug_msg_enabled[52] #else #ifdef DEBUG_OLE #define dprintf_ole fprintf @@ -1286,8 +1246,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_palette if(!debug_msg_enabled[55]) ; else fprintf -#define debugging_palette debug_msg_enabled[55] +#define dprintf_palette if(!debug_msg_enabled[53]) ; else fprintf +#define debugging_palette debug_msg_enabled[53] #else #ifdef DEBUG_PALETTE #define dprintf_palette fprintf @@ -1299,8 +1259,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_profile if(!debug_msg_enabled[56]) ; else fprintf -#define debugging_profile debug_msg_enabled[56] +#define dprintf_profile if(!debug_msg_enabled[54]) ; else fprintf +#define debugging_profile debug_msg_enabled[54] #else #ifdef DEBUG_PROFILE #define dprintf_profile fprintf @@ -1312,8 +1272,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_prop if(!debug_msg_enabled[57]) ; else fprintf -#define debugging_prop debug_msg_enabled[57] +#define dprintf_prop if(!debug_msg_enabled[55]) ; else fprintf +#define debugging_prop debug_msg_enabled[55] #else #ifdef DEBUG_PROP #define dprintf_prop fprintf @@ -1325,8 +1285,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_reg if(!debug_msg_enabled[58]) ; else fprintf -#define debugging_reg debug_msg_enabled[58] +#define dprintf_reg if(!debug_msg_enabled[56]) ; else fprintf +#define debugging_reg debug_msg_enabled[56] #else #ifdef DEBUG_REG #define dprintf_reg fprintf @@ -1338,8 +1298,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_region if(!debug_msg_enabled[59]) ; else fprintf -#define debugging_region debug_msg_enabled[59] +#define dprintf_region if(!debug_msg_enabled[57]) ; else fprintf +#define debugging_region debug_msg_enabled[57] #else #ifdef DEBUG_REGION #define dprintf_region fprintf @@ -1351,8 +1311,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_relay if(!debug_msg_enabled[60]) ; else fprintf -#define debugging_relay debug_msg_enabled[60] +#define dprintf_relay if(!debug_msg_enabled[58]) ; else fprintf +#define debugging_relay debug_msg_enabled[58] #else #ifdef DEBUG_RELAY #define dprintf_relay fprintf @@ -1364,8 +1324,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_resource if(!debug_msg_enabled[61]) ; else fprintf -#define debugging_resource debug_msg_enabled[61] +#define dprintf_resource if(!debug_msg_enabled[59]) ; else fprintf +#define debugging_resource debug_msg_enabled[59] #else #ifdef DEBUG_RESOURCE #define dprintf_resource fprintf @@ -1377,8 +1337,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_scroll if(!debug_msg_enabled[62]) ; else fprintf -#define debugging_scroll debug_msg_enabled[62] +#define dprintf_scroll if(!debug_msg_enabled[60]) ; else fprintf +#define debugging_scroll debug_msg_enabled[60] #else #ifdef DEBUG_SCROLL #define dprintf_scroll fprintf @@ -1390,8 +1350,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_selector if(!debug_msg_enabled[63]) ; else fprintf -#define debugging_selector debug_msg_enabled[63] +#define dprintf_selector if(!debug_msg_enabled[61]) ; else fprintf +#define debugging_selector debug_msg_enabled[61] #else #ifdef DEBUG_SELECTOR #define dprintf_selector fprintf @@ -1403,8 +1363,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_sem if(!debug_msg_enabled[64]) ; else fprintf -#define debugging_sem debug_msg_enabled[64] +#define dprintf_sem if(!debug_msg_enabled[62]) ; else fprintf +#define debugging_sem debug_msg_enabled[62] #else #ifdef DEBUG_SEM #define dprintf_sem fprintf @@ -1416,8 +1376,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_shm if(!debug_msg_enabled[65]) ; else fprintf -#define debugging_shm debug_msg_enabled[65] +#define dprintf_shm if(!debug_msg_enabled[63]) ; else fprintf +#define debugging_shm debug_msg_enabled[63] #else #ifdef DEBUG_SHM #define dprintf_shm fprintf @@ -1429,8 +1389,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_stress if(!debug_msg_enabled[66]) ; else fprintf -#define debugging_stress debug_msg_enabled[66] +#define dprintf_stress if(!debug_msg_enabled[64]) ; else fprintf +#define debugging_stress debug_msg_enabled[64] #else #ifdef DEBUG_STRESS #define dprintf_stress fprintf @@ -1442,8 +1402,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_syscolor if(!debug_msg_enabled[67]) ; else fprintf -#define debugging_syscolor debug_msg_enabled[67] +#define dprintf_syscolor if(!debug_msg_enabled[65]) ; else fprintf +#define debugging_syscolor debug_msg_enabled[65] #else #ifdef DEBUG_SYSCOLOR #define dprintf_syscolor fprintf @@ -1455,8 +1415,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_task if(!debug_msg_enabled[68]) ; else fprintf -#define debugging_task debug_msg_enabled[68] +#define dprintf_task if(!debug_msg_enabled[66]) ; else fprintf +#define debugging_task debug_msg_enabled[66] #else #ifdef DEBUG_TASK #define dprintf_task fprintf @@ -1468,8 +1428,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_text if(!debug_msg_enabled[69]) ; else fprintf -#define debugging_text debug_msg_enabled[69] +#define dprintf_text if(!debug_msg_enabled[67]) ; else fprintf +#define debugging_text debug_msg_enabled[67] #else #ifdef DEBUG_TEXT #define dprintf_text fprintf @@ -1481,8 +1441,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_timer if(!debug_msg_enabled[70]) ; else fprintf -#define debugging_timer debug_msg_enabled[70] +#define dprintf_timer if(!debug_msg_enabled[68]) ; else fprintf +#define debugging_timer debug_msg_enabled[68] #else #ifdef DEBUG_TIMER #define dprintf_timer fprintf @@ -1494,8 +1454,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_toolhelp if(!debug_msg_enabled[71]) ; else fprintf -#define debugging_toolhelp debug_msg_enabled[71] +#define dprintf_toolhelp if(!debug_msg_enabled[69]) ; else fprintf +#define debugging_toolhelp debug_msg_enabled[69] #else #ifdef DEBUG_TOOLHELP #define dprintf_toolhelp fprintf @@ -1507,8 +1467,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_utility if(!debug_msg_enabled[72]) ; else fprintf -#define debugging_utility debug_msg_enabled[72] +#define dprintf_utility if(!debug_msg_enabled[70]) ; else fprintf +#define debugging_utility debug_msg_enabled[70] #else #ifdef DEBUG_UTILITY #define dprintf_utility fprintf @@ -1520,8 +1480,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_vxd if(!debug_msg_enabled[73]) ; else fprintf -#define debugging_vxd debug_msg_enabled[73] +#define dprintf_vxd if(!debug_msg_enabled[71]) ; else fprintf +#define debugging_vxd debug_msg_enabled[71] #else #ifdef DEBUG_VXD #define dprintf_vxd fprintf @@ -1533,8 +1493,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_win if(!debug_msg_enabled[74]) ; else fprintf -#define debugging_win debug_msg_enabled[74] +#define dprintf_win if(!debug_msg_enabled[72]) ; else fprintf +#define debugging_win debug_msg_enabled[72] #else #ifdef DEBUG_WIN #define dprintf_win fprintf @@ -1546,8 +1506,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_win32 if(!debug_msg_enabled[75]) ; else fprintf -#define debugging_win32 debug_msg_enabled[75] +#define dprintf_win32 if(!debug_msg_enabled[73]) ; else fprintf +#define debugging_win32 debug_msg_enabled[73] #else #ifdef DEBUG_WIN32 #define dprintf_win32 fprintf @@ -1559,8 +1519,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_winsock if(!debug_msg_enabled[76]) ; else fprintf -#define debugging_winsock debug_msg_enabled[76] +#define dprintf_winsock if(!debug_msg_enabled[74]) ; else fprintf +#define debugging_winsock debug_msg_enabled[74] #else #ifdef DEBUG_WINSOCK #define dprintf_winsock fprintf @@ -1613,13 +1573,11 @@ static char *debug_msg_name[] = { "ldt", "listbox", "local", - "malloc", "mci", "mcianim", "mciwave", "mdi", "menu", - "menucalc", "message", "metafile", "midi", diff --git a/include/debugger.h b/include/debugger.h index deb92faf4dd..42b42064d42 100644 --- a/include/debugger.h +++ b/include/debugger.h @@ -11,6 +11,8 @@ #include "registers.h" #include "wine.h" +#define STEP_FLAG 0x100 /* single step flag */ + typedef struct { DWORD seg; /* 0xffffffff means current default segment (cs or ds) */ diff --git a/include/drive.h b/include/drive.h index ab9fa9d9dc0..b386b85aa13 100644 --- a/include/drive.h +++ b/include/drive.h @@ -11,6 +11,15 @@ #define MAX_DOS_DRIVES 26 +typedef enum +{ + TYPE_FLOPPY, + TYPE_HD, + TYPE_CDROM, + TYPE_NETWORK, + TYPE_INVALID +} DRIVETYPE; + extern int DRIVE_Init(void); extern int DRIVE_IsValid( int drive ); extern int DRIVE_GetCurrentDrive(void); @@ -22,8 +31,10 @@ extern const char * DRIVE_GetUnixCwd( int drive ); extern const char * DRIVE_GetLabel( int drive ); extern DWORD DRIVE_GetSerialNumber( int drive ); extern int DRIVE_SetSerialNumber( int drive, DWORD serial ); +extern DRIVETYPE DRIVE_GetType( int drive ); extern int DRIVE_Chdir( int drive, const char *path ); extern int DRIVE_Disable( int drive ); extern int DRIVE_Enable( int drive ); +extern int DRIVE_GetFreeSpace( int drive, DWORD *size, DWORD *available ); #endif /* __WINE_DRIVE_H */ diff --git a/include/kernel32.h b/include/kernel32.h index ecb4fc60945..12e5761785e 100644 --- a/include/kernel32.h +++ b/include/kernel32.h @@ -11,11 +11,6 @@ int KERN32_Init(void); void SetLastError(DWORD error); DWORD ErrnoToLastError(int errno_num); -/* Linux's wchar_t is unsigned long but Win32 wants unsigned short - */ -typedef unsigned short WCHAR; -typedef WCHAR *LPTSTR; - /* Code page information. */ typedef struct { @@ -57,8 +52,6 @@ typedef struct { HANDLE hStdError; } STARTUPINFO, *LPSTARTUPINFO; -/* SYSTEMTIME, and LPSYSTEMTIME moved to include/windows.h (JBP) */ - typedef struct { LONG Bias; WCHAR StandardName[32]; diff --git a/include/listbox.h b/include/listbox.h index e266b8a72d5..5430172307e 100644 --- a/include/listbox.h +++ b/include/listbox.h @@ -47,8 +47,8 @@ extern void ListBoxSendNotification(LPHEADLIST lphl, WORD code); extern LPLISTSTRUCT ListBoxGetItem(LPHEADLIST lphl, UINT uIndex); extern int ListMaxFirstVisible(LPHEADLIST lphl); extern int ListBoxScrollToFocus(LPHEADLIST lphl); -extern int ListBoxAddString(LPHEADLIST lphl, LPSTR newstr); -extern int ListBoxInsertString(LPHEADLIST lphl, UINT uIndex, LPSTR newstr); +extern int ListBoxAddString(LPHEADLIST lphl, LPCSTR newstr); +extern int ListBoxInsertString(LPHEADLIST lphl, UINT uIndex, LPCSTR newstr); extern int ListBoxGetText(LPHEADLIST lphl, UINT uIndex, LPSTR OutStr); extern DWORD ListBoxGetItemData(LPHEADLIST lphl, UINT uIndex); extern int ListBoxSetItemData(LPHEADLIST lphl, UINT uIndex, DWORD ItemData); @@ -58,7 +58,7 @@ extern int ListBoxResetContent(LPHEADLIST lphl); extern int ListBoxSetCurSel(LPHEADLIST lphl, WORD wIndex); extern int ListBoxSetSel(LPHEADLIST lphl, WORD wIndex, WORD state); extern int ListBoxGetSel(LPHEADLIST lphl, WORD wIndex); -extern int ListBoxDirectory(LPHEADLIST lphl, UINT attrib, LPSTR filespec); +extern LONG ListBoxDirectory(LPHEADLIST lphl, UINT attrib, LPCSTR filespec); extern int ListBoxGetItemRect(LPHEADLIST lphl, WORD wIndex, LPRECT rect); extern int ListBoxSetItemHeight(LPHEADLIST lphl, WORD wIndex, long height); extern int ListBoxFindNextMatch(LPHEADLIST lphl, WORD wChar); diff --git a/include/mdi.h b/include/mdi.h index e7c257325f9..a34c1d05b55 100644 --- a/include/mdi.h +++ b/include/mdi.h @@ -12,6 +12,11 @@ #include "windows.h" #define MDI_MAXLISTLENGTH 0x40 +#define MDI_MAXTITLELENGTH 0xA1 + +#define MDI_NOFRAMEREPAINT 0 +#define MDI_REPAINTFRAMENOW 1 +#define MDI_REPAINTFRAME 2 #define WM_MDICALCCHILDSCROLL 0x10AC /* this is exactly what Windows uses */ @@ -31,12 +36,13 @@ typedef struct HWND hwndActiveChild; HMENU hWindowMenu; WORD idFirstChild; /* order is 3.1-like up to this point */ + HANDLE hFrameTitle; WORD sbStop; WORD sbRecalc; + HBITMAP obmClose; + HBITMAP obmRestore; HWND hwndHitTest; - RECT rectMaximize; - RECT rectRestore; + HWND self; } MDICLIENTINFO; - #endif /* MDI_H */ diff --git a/include/menu.h b/include/menu.h index 5a25e1e7172..41f2047f778 100644 --- a/include/menu.h +++ b/include/menu.h @@ -26,7 +26,6 @@ typedef struct tagMENUITEM HBITMAP hCheckBit; /* Bitmap for checked item */ HBITMAP hUnCheckBit; /* Bitmap for unchecked item */ HANDLE hText; /* Handle to item string or bitmap */ - char *item_text; } MENUITEM, *LPMENUITEM; diff --git a/include/miscemu.h b/include/miscemu.h index 99186e760d6..33d7648ae56 100644 --- a/include/miscemu.h +++ b/include/miscemu.h @@ -27,7 +27,7 @@ extern void INT_SetHandler( BYTE intnum, SEGPTR handler ); extern DWORD INT1A_GetTicksSinceMidnight(void); /* miscemu/int21.c */ -extern void INT21_Init(void); +extern BOOL INT21_Init(void); /* miscemu/ioports.c */ extern DWORD inport( int port, int count ); diff --git a/include/options.h b/include/options.h index 7d3bbf1a9f9..684aa6b9000 100644 --- a/include/options.h +++ b/include/options.h @@ -39,4 +39,10 @@ struct options extern struct options Options; +/* Profile functions */ + +extern int PROFILE_LoadWineIni(void); +extern int PROFILE_GetWineIniString( const char *section, const char *key_name, + const char *def, char *buffer, int len ); + #endif diff --git a/include/resource32.h b/include/resource32.h index 6a2ac433327..bcddc21c50b 100644 --- a/include/resource32.h +++ b/include/resource32.h @@ -16,7 +16,8 @@ LPVOID LockResource32( HANDLE32 handle ); BOOL FreeResource32( HANDLE32 handle ); INT AccessResource32( HINSTANCE hModule, HRSRC hRsrc ); DWORD SizeofResource32( HINSTANCE hModule, HRSRC hRsrc ); -int LoadString32(HINSTANCE instance, DWORD resource_id, LPTSTR buffer, int buflen); +int WIN32_LoadStringW(HINSTANCE instance, DWORD resource_id, LPWSTR buffer, int buflen); +int WIN32_LoadStringA(HINSTANCE instance, DWORD resource_id, LPSTR buffer, int buflen); typedef struct _IMAGE_RESOURCE_DIRECTORY { DWORD Characteristics; diff --git a/include/shell.h b/include/shell.h index 88ca4b1fbaa..481f149329c 100644 --- a/include/shell.h +++ b/include/shell.h @@ -1,6 +1,12 @@ /* * Shell Library definitions */ +#include "wintypes.h" + +#ifndef __WINE_SHELL_H +#define __WINE_SHELL_H + +#include "windows.h" extern INT ShellAbout(HWND hWnd, LPCSTR szApp, LPCSTR szOtherStuff, HICON hIcon); extern void SHELL_LoadRegistry(); @@ -21,13 +27,6 @@ extern BOOL SHELL_Init(); #define HKEY_CLASSES_ROOT 1 -#ifdef WINELIB32 -typedef void* HKEY; -#else -typedef DWORD HKEY; -#endif -typedef HKEY FAR* LPHKEY; - typedef struct tagKEYSTRUCT { HKEY hKey; LPSTR lpSubKey; @@ -54,3 +53,4 @@ typedef struct { /* structure for dropped files */ LRESULT AboutDlgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam); +#endif /* __WINE_SHELL_H */ diff --git a/include/stddebug.h b/include/stddebug.h index b5c89178fad..54cc9d2777f 100644 --- a/include/stddebug.h +++ b/include/stddebug.h @@ -114,13 +114,11 @@ #undef DEBUG_LDT #undef DEBUG_LISTBOX #undef DEBUG_LOCAL -#undef DEBUG_MALLOC #undef DEBUG_MCI #undef DEBUG_MCIANIM #undef DEBUG_MCIWAVE #undef DEBUG_MDI #undef DEBUG_MENU -#undef DEBUG_MENUCALC #undef DEBUG_MESSAGE #undef DEBUG_METAFILE #undef DEBUG_MIDI @@ -194,13 +192,11 @@ #define DEBUG_LDT #define DEBUG_LISTBOX #define DEBUG_LOCAL -#define DEBUG_MALLOC #define DEBUG_MCI #define DEBUG_MCIANIM #define DEBUG_MCIWAVE #define DEBUG_MDI #define DEBUG_MENU -#define DEBUG_MENUCALC #define DEBUG_MESSAGE #define DEBUG_METAFILE #define DEBUG_MIDI diff --git a/include/string32.h b/include/string32.h new file mode 100644 index 00000000000..b598c0efe83 --- /dev/null +++ b/include/string32.h @@ -0,0 +1,20 @@ +/* + * Unicode string management + * + * Copyright 1995 Martin von Loewis + * + */ + +#ifndef _STRING32_H +#define _STRING32_H + +#include "wintypes.h" + +int STRING32_UniLen(LPWSTR s); +void STRING32_UniToAnsi(LPSTR dest,LPCWSTR src); +void STRING32_AnsiToUni(LPWSTR dest,LPCSTR src); +LPSTR STRING32_DupUniToAnsi(LPWSTR src); +LPWSTR STRING32_DupAnsiToUni(LPSTR src); +LPWSTR STRING32_lstrcmpnW(LPCWSTR a,LPCWSTR b,DWORD len); + +#endif diff --git a/include/struct32.h b/include/struct32.h new file mode 100644 index 00000000000..f9394cda59d --- /dev/null +++ b/include/struct32.h @@ -0,0 +1,25 @@ +/* Structure definitions for Win32 -- used only internally */ +#ifndef _STRUCT32_H +#define _STRUCT32_H + +typedef struct tagRECT32 +{ + LONG left; + LONG top; + LONG right; + LONG bottom; +} RECT32; + +void USER32_RECT32to16(const RECT32*,RECT*); +void USER32_RECT16to32(const RECT*,RECT32*); + +typedef struct tagPOINT32 +{ + LONG x; + LONG y; +} POINT32; + +void PARAM32_POINT32to16(const POINT32*,POINT*); +void PARAM32_POINT16to32(const POINT*,POINT32*); + +#endif diff --git a/include/toolhelp.h b/include/toolhelp.h index 43d0e7f3128..722d7355d9b 100644 --- a/include/toolhelp.h +++ b/include/toolhelp.h @@ -261,5 +261,87 @@ BOOL ClassNext( CLASSENTRY *pClassEntry ); DWORD MemoryRead( WORD sel, DWORD offset, void *buffer, DWORD count ); DWORD MemoryWrite( WORD sel, DWORD offset, void *buffer, DWORD count ); +/* flags to NotifyRegister() */ +#define NF_NORMAL 0 /* everything except taskswitches, debugerrors, + * debugstrings + */ +#define NF_TASKSWITCH 1 /* get taskswitch information */ +#define NF_RIP 2 /* get debugerrors of system */ +BOOL NotifyRegister(HTASK htask,FARPROC lpfnCallback,WORD wFlags); + +#define NFY_UNKNOWN 0 +#define NFY_LOADSEG 1 +/* DATA is a pointer to following struct: */ +struct { + DWORD dwSize; + WORD wSelector; + WORD wSegNum; + WORD wType; /* bit 0 set if this is a code segment */ + WORD wcInstance; /* only valid for data segment */ +} NFYLOADSEG; +/* called when freeing a segment. LOWORD(dwData) is the freed selector */ +#define NFY_FREESEG 2 + +/* called when loading/starting a DLL */ +#define NFY_STARTDLL 3 +struct { + DWORD dwSize; + HMODULE hModule; + WORD wCS; + WORD wIP; +} NFYSTARTDLL; + +/* called when starting a task. dwData is CS:IP */ +#define NFY_STARTTASK 4 + +/* called when a task terminates. dwData is the return code */ +#define NFY_EXITTASK 5 + +/* called when module is removed. LOWORD(dwData) is the handle */ +#define NFY_DELMODULE 6 + +/* RIP? debugevent */ +#define NFY_RIP 7 +struct { + DWORD dwSize; + WORD wIP; + WORD wCS; + WORD wSS; + WORD wBP; + WORD wExitCode; +} NFYRIP; + +/* called before (after?) switching to a task + * no data, callback should call GetCurrentTask + */ +#define NFY_TASKIN 8 + +/* called before(after?) switching from a task + * no data, callback should call GetCurrentTask +*/ +#define NFY_TASKOUT 9 + +/* returns ASCII input value, dwData not set */ +#define NFY_INCHAR 10 + +/* output debugstring (pointed to by dwData) */ +#define NFY_OUTSTRING 11 + +/* log errors */ +#define NFY_LOGERROR 12 +struct { + DWORD dwSize; + UINT wErrCode; + VOID FAR* lpInfo; /* depends on wErrCode */ +} NFYLOGERROR; + +/* called for parameter errors? */ +#define NFY_LOGPARAMERROR 13 +struct { + DWORD dwSize; + UINT wErrCode; + FARPROC lpfnErrorAddr; + void FAR* FAR* lpBadParam; +} NFYLOGPARAMERROR; #endif /* __TOOLHELP_H */ diff --git a/include/windows.h b/include/windows.h index b7f82984e71..0e2ce322a56 100644 --- a/include/windows.h +++ b/include/windows.h @@ -36,6 +36,12 @@ typedef RECT *PRECT; #define MAKELPARAM(low, high) ((LONG)(((WORD)(low)) | \ (((DWORD)((WORD)(high))) << 16))) +typedef struct tagKERNINGPAIR { + WORD wFirst; + WORD wSecond; + INT iKernAmount; +} KERNINGPAIR, *LPKERNINGPAIR; + typedef struct { HDC hdc; BOOL fErase; @@ -125,6 +131,9 @@ typedef struct LONG lParam WINE_PACKED; } MDICREATESTRUCT, *LPMDICREATESTRUCT; +#define MDITILE_VERTICAL 0 +#define MDITILE_HORIZONTAL 1 + /* Offsets for GetWindowLong() and GetWindowWord() */ #define GWL_EXSTYLE (-20) #define GWL_STYLE (-16) @@ -1697,6 +1706,7 @@ typedef struct tagDRAGINFO { #define SW_RESTORE 9 #define SW_SHOWDEFAULT 10 #define SW_MAX 10 +#define SW_NORMALNA 0xCC /* undoc. flag in MinMaximize */ /* WM_SIZE message wParam values */ #define SIZE_RESTORED 0 @@ -1704,6 +1714,11 @@ typedef struct tagDRAGINFO { #define SIZE_MAXIMIZED 2 #define SIZE_MAXSHOW 3 #define SIZE_MAXHIDE 4 +#define SIZENORMAL SIZE_RESTORED +#define SIZEICONIC SIZE_MINIMIZED +#define SIZEFULLSCREEN SIZE_MAXIMIZED +#define SIZEZOOMSHOW SIZE_MAXSHOW +#define SIZEZOOMHIDE SIZE_MAXHIDE /* SetWindowPos() and WINDOWPOS flags */ #define SWP_NOSIZE 0x0001 @@ -2100,7 +2115,7 @@ typedef struct tagDRAGINFO { #define ES_PASSWORD 0x00000020L #define ES_AUTOVSCROLL 0x00000040L #define ES_AUTOHSCROLL 0x00000080L -#define ES_NOHISESEL 0x00000100L +#define ES_NOHIDESEL 0x00000100L #define ES_OEMCONVERT 0x00000400L #define ES_READONLY 0x00000800L #define ES_WANTRETURN 0x00001000L @@ -2536,6 +2551,21 @@ typedef struct { WORD wMilliseconds; } SYSTEMTIME, *LPSYSTEMTIME; +#define HELP_CONTEXT 0x0001 +#define HELP_QUIT 0x0002 +#define HELP_INDEX 0x0003 +#define HELP_CONTENTS 0x0003 +#define HELP_HELPONHELP 0x0004 +#define HELP_SETINDEX 0x0005 +#define HELP_SETCONTENTS 0x0005 +#define HELP_CONTEXTPOPUP 0x0008 +#define HELP_FORCEFILE 0x0009 +#define HELP_KEY 0x0101 +#define HELP_COMMAND 0x0102 +#define HELP_PARTIALKEY 0x0105 +#define HELP_MULTIKEY 0x0201 +#define HELP_SETWINPOS 0x0203 + #ifndef WINELIB #pragma pack(4) #endif @@ -2543,86 +2573,93 @@ typedef struct { INT AccessResource(HINSTANCE,HRSRC); ATOM AddAtom(SEGPTR); INT AddFontResource(LPCSTR); -void AdjustWindowRect(LPRECT,DWORD,BOOL); -void AdjustWindowRectEx(LPRECT,DWORD,BOOL,DWORD); +BOOL AdjustWindowRect(LPRECT,DWORD,BOOL); +BOOL AdjustWindowRectEx(LPRECT,DWORD,BOOL,DWORD); WORD AllocCStoDSAlias(WORD); WORD AllocDStoCSAlias(WORD); HGLOBAL AllocResource(HINSTANCE,HRSRC,DWORD); WORD AllocSelector(WORD); WORD AllocSelectorArray(WORD); -void AnimatePalette(HPALETTE,UINT,UINT,LPPALETTEENTRY); +BOOL AnimatePalette(HPALETTE,UINT,UINT,LPPALETTEENTRY); LPSTR AnsiLower(LPSTR); UINT AnsiLowerBuff(LPSTR,UINT); SEGPTR AnsiNext(SEGPTR); SEGPTR AnsiPrev(SEGPTR,SEGPTR); INT AnsiToOem(LPSTR,LPSTR); -void AnsiToOemBuff(LPSTR,LPSTR,INT); +void AnsiToOemBuff(LPCSTR,LPSTR,UINT); LPSTR AnsiUpper(LPSTR); UINT AnsiUpperBuff(LPSTR,UINT); BOOL AnyPopup(void); -BOOL AppendMenu(HMENU,UINT,UINT,LPSTR); +BOOL AppendMenu(HMENU,UINT,UINT,SEGPTR); BOOL Arc(HDC,INT,INT,INT,INT,INT,INT,INT,INT); -WORD ArrangeIconicWindows(HWND); +UINT ArrangeIconicWindows(HWND); HDWP BeginDeferWindowPos(INT); HDC BeginPaint(HWND,LPPAINTSTRUCT); BOOL BitBlt(HDC,INT,INT,INT,INT,HDC,INT,INT,DWORD); BOOL BringWindowToTop(HWND); -int BuildCommDCB(LPSTR,DCB*); +BOOL BuildCommDCB(LPCSTR,DCB*); void CalcChildScroll(HWND,WORD); -BOOL CallMsgFilter(SEGPTR,short); -DWORD CallNextHookEx(HHOOK,short,WPARAM,LPARAM); -LONG CallWindowProc(WNDPROC,HWND,UINT,WPARAM,LPARAM); -int Catch(LPCATCHBUF); +BOOL CallMsgFilter(SEGPTR,INT); +LRESULT CallNextHookEx(HHOOK,INT,WPARAM,LPARAM); +LRESULT CallWindowProc(WNDPROC,HWND,UINT,WPARAM,LPARAM); +INT Catch(LPCATCHBUF); BOOL ChangeClipboardChain(HWND,HWND); -BOOL ChangeMenu(HMENU,UINT,LPSTR,UINT,UINT); +BOOL ChangeMenu(HMENU,UINT,SEGPTR,UINT,UINT); WORD ChangeSelector(WORD,WORD); -void CheckDlgButton(HWND,WORD,WORD); -BOOL CheckMenuItem(HMENU,UINT,UINT); -void CheckRadioButton(HWND,WORD,WORD,WORD); +BOOL CheckDlgButton(HWND,INT,UINT); +INT CheckMenuItem(HMENU,UINT,UINT); +BOOL CheckRadioButton(HWND,UINT,UINT,UINT); HWND ChildWindowFromPoint(HWND,POINT); BOOL Chord(HDC,INT,INT,INT,INT,INT,INT,INT,INT); int ClearCommBreak(int); -void ClientToScreen(HWND,LPPOINT); -void ClipCursor(LPRECT); +BOOL ClientToScreen(HWND,LPPOINT); +BOOL ClipCursor(LPRECT); BOOL CloseClipboard(void); int CloseComm(int); -HMETAFILE CloseMetaFile(HANDLE); +HMETAFILE CloseMetaFile(HDC); void CloseSound(void); -void CloseWindow(HWND); -int CombineRgn(HRGN,HRGN,HRGN,short); +BOOL CloseWindow(HWND); +INT CombineRgn(HRGN,HRGN,HRGN,INT); int ConvertRequest(HWND,LPKANJISTRUCT); -HANDLE CopyMetaFile(HANDLE,LPSTR); -void CopyRect(LPRECT,LPRECT); -int CountClipboardFormats(void); -int CountVoiceNotes(int); -HBITMAP CreateBitmap(short,short,BYTE,BYTE,LPSTR); -HBITMAP CreateBitmapIndirect(BITMAP*); -HBRUSH CreateBrushIndirect(LOGBRUSH*); -void CreateCaret(HWND,HBITMAP,short,short); -HBITMAP CreateCompatibleBitmap(HDC,short,short); +#ifdef WINELIB32 +HCURSOR CopyCursor(HCURSOR); /* Win32 */ +HICON CopyIcon(HICON); /* Win32 */ +#else +HCURSOR CopyCursor(HINSTANCE,HCURSOR); /* Win16 */ +HICON CopyIcon(HINSTANCE,HICON); /* Win16 */ +#endif +HMETAFILE CopyMetaFile(HMETAFILE,LPCSTR); +BOOL CopyRect(LPRECT,LPRECT); +INT CountClipboardFormats(void); +INT CountVoiceNotes(INT); +HBITMAP CreateBitmap(INT,INT,UINT,UINT,LPVOID); +HBITMAP CreateBitmapIndirect(const BITMAP*); +HBRUSH CreateBrushIndirect(const LOGBRUSH*); +BOOL CreateCaret(HWND,HBITMAP,INT,INT); +HBITMAP CreateCompatibleBitmap(HDC,INT,INT); HDC CreateCompatibleDC(HDC); -HCURSOR CreateCursor(HANDLE,INT,INT,INT,INT,LPSTR,LPSTR); +HCURSOR CreateCursor(HANDLE,INT,INT,INT,INT,LPVOID,LPVOID); HANDLE CreateCursorIconIndirect(HANDLE,CURSORICONINFO*,LPSTR,LPSTR); -HDC CreateDC(LPSTR,LPSTR,LPSTR,LPSTR); -HBRUSH CreateDIBPatternBrush(HANDLE,WORD); -HBITMAP CreateDIBitmap(HDC,LPBITMAPINFOHEADER,DWORD,LPSTR,LPBITMAPINFO,WORD); -HWND CreateDialog(HANDLE,SEGPTR,HWND,WNDPROC); -HWND CreateDialogIndirect(HANDLE,SEGPTR,HWND,WNDPROC); -HWND CreateDialogIndirectParam(HANDLE,SEGPTR,HWND,WNDPROC,LPARAM); -HWND CreateDialogParam(HANDLE,SEGPTR,HWND,WNDPROC,LPARAM); -HBITMAP CreateDiscardableBitmap(HDC,short,short); -HRGN CreateEllipticRgn(short,short,short,short); +HDC CreateDC(LPCSTR,LPCSTR,LPCSTR,LPCSTR); +HBRUSH CreateDIBPatternBrush(HGLOBAL,UINT); +HBITMAP CreateDIBitmap(HDC,BITMAPINFOHEADER*,DWORD,LPVOID,BITMAPINFO*,UINT); +HWND CreateDialog(HANDLE,SEGPTR,HWND,DLGPROC); +HWND CreateDialogIndirect(HANDLE,SEGPTR,HWND,DLGPROC); +HWND CreateDialogIndirectParam(HANDLE,SEGPTR,HWND,DLGPROC,LPARAM); +HWND CreateDialogParam(HANDLE,SEGPTR,HWND,DLGPROC,LPARAM); +HBITMAP CreateDiscardableBitmap(HDC,INT,INT); +HRGN CreateEllipticRgn(INT,INT,INT,INT); HRGN CreateEllipticRgnIndirect(LPRECT); -HFONT CreateFont(int,int,int,int,int,BYTE,BYTE,BYTE,BYTE,BYTE,BYTE,BYTE,BYTE,LPSTR); -HFONT CreateFontIndirect(LOGFONT*); -HBRUSH CreateHatchBrush(short,COLORREF); +HFONT CreateFont(INT,INT,INT,INT,INT,BYTE,BYTE,BYTE,BYTE,BYTE,BYTE,BYTE,BYTE,LPCSTR); +HFONT CreateFontIndirect(const LOGFONT*); +HBRUSH CreateHatchBrush(INT,COLORREF); HDC CreateIC(LPSTR,LPSTR,LPSTR,LPSTR); HICON CreateIcon(HANDLE,INT,INT,BYTE,BYTE,LPSTR,LPSTR); HMENU CreateMenu(void); HANDLE CreateMetaFile(LPSTR); HPALETTE CreatePalette(LPLOGPALETTE); HBRUSH CreatePatternBrush(HBITMAP); -HPEN CreatePen(short,short,COLORREF); +HPEN CreatePen(INT,INT,COLORREF); HPEN CreatePenIndirect(LOGPEN*); HRGN CreatePolyPolygonRgn(LPPOINT,LPINT,INT,INT); HRGN CreatePolygonRgn(LPPOINT,INT,INT); @@ -2667,7 +2704,7 @@ 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); +int DrawText(HDC,LPCSTR,int,LPRECT,WORD); DWORD DumpIcon(SEGPTR,WORD*,SEGPTR*,SEGPTR*); BOOL Ellipse(HDC,INT,INT,INT,INT); BOOL EmptyClipboard(void); @@ -2680,6 +2717,7 @@ void EndDialog(HWND,short); void EndPaint(HWND,LPPAINTSTRUCT); BOOL EnumChildWindows(HWND,FARPROC,LONG); WORD EnumClipboardFormats(WORD); +int EnumFontFamilies(HDC,LPSTR,FONTENUMPROC,LPARAM); int EnumFonts(HDC,LPSTR,FARPROC,LPSTR); BOOL EnumMetaFile(HDC,LOCALHANDLE,FARPROC,BYTE*); int EnumObjects(HDC,int,FARPROC,LPARAM); @@ -2696,13 +2734,16 @@ int ExcludeVisRect(HDC,short,short,short,short); BOOL ExitWindows(DWORD,WORD); BOOL ExtFloodFill(HDC,INT,INT,COLORREF,WORD); BOOL ExtTextOut(HDC,short,short,WORD,LPRECT,LPSTR,WORD,LPINT); +HICON ExtractIcon(HINSTANCE,LPCSTR,UINT); WORD FarGetOwner(HANDLE); void FarSetOwner(HANDLE,WORD); +void FatalAppExit(UINT,LPCSTR); void FatalExit(int); int FillRect(HDC,LPRECT,HBRUSH); BOOL FillRgn(HDC,HRGN,HBRUSH); void FillWindow(HWND,HWND,HDC,HBRUSH); ATOM FindAtom(SEGPTR); +HINSTANCE FindExecutable(LPCSTR,LPCSTR,LPSTR); HRSRC FindResource(HINSTANCE,SEGPTR,SEGPTR); HWND FindWindow(SEGPTR,LPSTR); BOOL FlashWindow(HWND,BOOL); @@ -2739,6 +2780,7 @@ int GetClassName(HWND,LPSTR,short); WORD GetClassWord(HWND,short); void GetClientRect(HWND,LPRECT); int GetClipBox(HDC,LPRECT); +void GetClipCursor(LPRECT); HRGN GetClipRgn(HDC); HANDLE GetClipboardData(WORD); int GetClipboardFormatName(WORD,LPSTR,short); @@ -2782,12 +2824,13 @@ BOOL GetInputState(void); int GetInstanceData(HANDLE,WORD,int); WORD GetInternalWindowPos(HWND,LPRECT,LPPOINT); int GetKBCodePage(void); +int GetKerningPairs(HDC,int,LPKERNINGPAIR); int GetKeyNameText(LONG,LPSTR,int); int GetKeyState(int); void GetKeyboardState(BYTE*); int GetKeyboardType(int); HWND GetLastActivePopup(HWND); -VOID GetLocalTime(LPSYSTEMTIME); /* Win32 */ +VOID GetLocalTime(LPSYSTEMTIME); /* Win32 */ WORD GetMapMode(HDC); HMENU GetMenu(HWND); DWORD GetMenuCheckMarkDimensions(void); @@ -2818,12 +2861,14 @@ HWND GetParent(HWND); DWORD GetPixel(HDC,short,short); WORD GetPolyFillMode(HDC); int GetPriorityClipboardFormat(WORD*,short); -WORD GetPrivateProfileInt(LPCSTR,LPCSTR,short,LPCSTR); -short GetPrivateProfileString(LPCSTR,LPCSTR,LPCSTR,LPSTR,short,LPCSTR); +UINT GetPrivateProfileInt(LPCSTR,LPCSTR,INT,LPCSTR); +INT GetPrivateProfileString(LPCSTR,LPCSTR,LPCSTR,LPSTR,INT,LPCSTR); FARPROC GetProcAddress(HANDLE,SEGPTR); -WORD GetProfileInt(LPCSTR,LPCSTR,int); -int GetProfileString(LPCSTR,LPCSTR,LPCSTR,LPSTR,int); +UINT GetProfileInt(LPCSTR,LPCSTR,INT); +INT GetProfileString(LPCSTR,LPCSTR,LPCSTR,LPSTR,INT); HANDLE GetProp(HWND,SEGPTR); +DWORD GetQueueStatus(UINT); +BOOL GetRasterizerCaps(LPRASTERIZER_STATUS,UINT); WORD GetROP2(HDC); WORD GetRelAbs(HDC); int GetRgnBox(HRGN,LPRECT); @@ -2841,7 +2886,7 @@ HMENU GetSystemMenu(HWND,BOOL); int GetSystemMetrics(WORD); WORD GetSystemPaletteEntries(HDC,WORD,WORD,LPPALETTEENTRY); WORD GetSystemPaletteUse(HDC); -VOID GetSystemTime(LPSYSTEMTIME); /* Win32 */ +VOID GetSystemTime(LPSYSTEMTIME); /* Win32 */ DWORD GetTabbedTextExtent(HDC,LPSTR,int,int,LPINT); HINSTANCE GetTaskDS(void); HGLOBAL GetTaskQueue(HTASK); @@ -2850,8 +2895,8 @@ INT GetTempFileName(BYTE,LPCSTR,UINT,LPSTR); WORD GetTextAlign(HDC); short GetTextCharacterExtra(HDC); COLORREF GetTextColor(HDC); -DWORD GetTextExtent(HDC,LPSTR,short); -BOOL GetTextExtentPoint(HDC,LPSTR,short,LPSIZE); +DWORD GetTextExtent(HDC,LPCSTR,short); +BOOL GetTextExtentPoint(HDC,LPCSTR,short,LPSIZE); INT GetTextFace(HDC,INT,LPSTR); BOOL GetTextMetrics(HDC,LPTEXTMETRIC); LPINT GetThresholdEvent(void); @@ -2883,9 +2928,7 @@ WORD GetWindowWord(HWND,short); UINT GetWindowsDirectory(LPSTR,UINT); ATOM GlobalAddAtom(SEGPTR); HGLOBAL GlobalAlloc(WORD,DWORD); -#ifndef WINELIB32 /* Obsolete in Win32 */ DWORD GlobalCompact(DWORD); -#endif DWORD GlobalDOSAlloc(DWORD); WORD GlobalDOSFree(WORD); ATOM GlobalDeleteAtom(ATOM); @@ -2896,9 +2939,9 @@ HGLOBAL GlobalFree(HGLOBAL); void GlobalFreeAll(HANDLE); WORD GlobalGetAtomName(ATOM,LPSTR,short); #ifdef WINELIB32 -HGLOBAL GlobalHandle(LPCVOID); +HGLOBAL GlobalHandle(LPCVOID); /* Win32 */ #else -DWORD GlobalHandle(UINT); +DWORD GlobalHandle(UINT); /* Win16 */ #endif HGLOBAL GlobalLRUNewest(HGLOBAL); HGLOBAL GlobalLRUOldest(HGLOBAL); @@ -2919,7 +2962,7 @@ BOOL InSendMessage(void); void InflateRect(LPRECT,short,short); WORD InitAtomTable(WORD); HRGN InquireVisRgn(HDC); -BOOL InsertMenu(HMENU,UINT,UINT,UINT,LPSTR); +BOOL InsertMenu(HMENU,UINT,UINT,UINT,SEGPTR); int IntersectClipRect(HDC,short,short,short,short); BOOL IntersectRect(LPRECT,LPRECT,LPRECT); int IntersectVisRect(HDC,short,short,short,short); @@ -2941,10 +2984,12 @@ BOOL IsChild(HWND,HWND); BOOL IsClipboardFormatAvailable(WORD); BOOL IsDialogMessage(HWND,LPMSG); WORD IsDlgButtonChecked(HWND,WORD); +BOOL IsGDIObject(HANDLE); BOOL IsIconic(HWND); +BOOL IsMenu(HMENU); BOOL IsRectEmpty(LPRECT); +BOOL IsTask(HTASK); HTASK IsTaskLocked(void); -BOOL IsTwoByteCharPrefix(char); BOOL IsWindow(HWND); BOOL IsWindowEnabled(HWND); BOOL IsWindowVisible(HWND); @@ -2961,14 +3006,12 @@ HCURSOR LoadCursor(HANDLE,SEGPTR); HICON LoadIcon(HANDLE,SEGPTR); HANDLE LoadLibrary(LPCSTR); HMENU LoadMenu(HANDLE,SEGPTR); -HMENU LoadMenuIndirect(LPSTR); +HMENU LoadMenuIndirect(SEGPTR); HANDLE LoadModule(LPCSTR,LPVOID); HGLOBAL LoadResource(HINSTANCE,HRSRC); int LoadString(HANDLE,WORD,LPSTR,int); HANDLE LocalAlloc(WORD,WORD); -#ifndef WINELIB32 /* Obsolete in Win32 */ UINT LocalCompact(WORD); -#endif UINT LocalFlags(HLOCAL); HANDLE LocalFree(HANDLE); HANDLE LocalHandle(WORD); @@ -2976,9 +3019,7 @@ BOOL LocalInit(HANDLE,WORD,WORD); NPVOID LocalLock(HLOCAL); FARPROC LocalNotify(FARPROC); HANDLE LocalReAlloc(HANDLE,WORD,WORD); -#ifndef WINELIB32 /* Obsolete in Win32 */ UINT LocalShrink(HANDLE,WORD); -#endif UINT LocalSize(HLOCAL); BOOL LocalUnlock(HANDLE); LPVOID LockResource(HGLOBAL); @@ -2989,12 +3030,12 @@ void MapDialogRect(HWND,LPRECT); WORD MapVirtualKey(WORD,WORD); void MapWindowPoints(HWND,HWND,LPPOINT,WORD); void MessageBeep(WORD); -int MessageBox(HWND,LPSTR,LPSTR,WORD); -BOOL ModifyMenu(HMENU,UINT,UINT,UINT,LPSTR); +int MessageBox(HWND,LPCSTR,LPCSTR,WORD); +BOOL ModifyMenu(HMENU,UINT,UINT,UINT,SEGPTR); DWORD MoveTo(HDC,short,short); BOOL MoveToEx(HDC,short,short,LPPOINT); BOOL MoveWindow(HWND,short,short,short,short,BOOL); -int MulDiv(int,int,int); +INT MulDiv(INT,INT,INT); DWORD OemKeyScan(WORD); BOOL OemToAnsi(LPSTR,LPSTR); void OemToAnsiBuff(LPSTR,LPSTR,INT); @@ -3006,7 +3047,7 @@ BOOL OffsetViewportOrgEx(HDC,short,short,LPPOINT); DWORD OffsetWindowOrg(HDC,short,short); BOOL OffsetWindowOrgEx(HDC,short,short,LPPOINT); BOOL OpenClipboard(HWND); -int OpenComm(LPSTR,UINT,UINT); +int OpenComm(LPCSTR,UINT,UINT); HFILE OpenFile(LPCSTR,OFSTRUCT*,UINT); BOOL OpenIcon(HWND); int OpenSound(void); @@ -3043,6 +3084,13 @@ BOOL RectInRegion(HRGN,LPRECT); BOOL RectVisible(HDC,LPRECT); BOOL Rectangle(HDC,INT,INT,INT,INT); BOOL RedrawWindow(HWND,LPRECT,HRGN,UINT); +LONG RegCloseKey(HKEY); +LONG RegCreateKey(HKEY,LPCSTR,LPHKEY); +LONG RegDeleteKey(HKEY,LPCSTR); +LONG RegEnumKey(HKEY,DWORD,LPSTR,DWORD); +LONG RegOpenKey(HKEY,LPCSTR,LPHKEY); +LONG RegQueryValue(HKEY,LPCSTR,LPSTR,LPLONG); +LONG RegSetValue(HKEY,LPCSTR,DWORD,LPCSTR,DWORD); ATOM RegisterClass(LPWNDCLASS); WORD RegisterClipboardFormat(LPCSTR); WORD RegisterWindowMessage(SEGPTR); @@ -3052,6 +3100,7 @@ BOOL RemoveFontResource(LPSTR); BOOL RemoveMenu(HMENU,UINT,UINT); HANDLE RemoveProp(HWND,SEGPTR); void ReplyMessage(LONG); +HDC ResetDC(HDC,LPVOID); BOOL ResizePalette(HPALETTE,UINT); BOOL RestoreDC(HDC,short); int RestoreVisRgn(HDC); @@ -3161,17 +3210,18 @@ DWORD SetWindowOrg(HDC,short,short); BOOL SetWindowOrgEx(HDC,short,short,LPPOINT); BOOL SetWindowPlacement(HWND,LPWINDOWPLACEMENT); BOOL SetWindowPos(HWND,HWND,INT,INT,INT,INT,WORD); -void SetWindowText(HWND,LPSTR); +void SetWindowText(HWND,LPCSTR); WORD SetWindowWord(HWND,short,WORD); FARPROC SetWindowsHook(short,FARPROC); HHOOK SetWindowsHookEx(short,HOOKPROC,HINSTANCE,HTASK); +HINSTANCE ShellExecute(HWND,LPCSTR,LPCSTR,LPSTR,LPCSTR,INT); void ShowCaret(HWND); int ShowCursor(BOOL); void ShowOwnedPopups(HWND,BOOL); void ShowScrollBar(HWND,WORD,BOOL); BOOL ShowWindow(HWND,int); DWORD SizeofResource(HINSTANCE,HRSRC); -VOID Sleep(DWORD); /* Win32 */ +VOID Sleep(DWORD); /* Win32 */ int StartSound(void); int StopSound(void); BOOL StretchBlt(HDC,short,short,short,short,HDC,short,short,short,short,DWORD); @@ -3182,6 +3232,7 @@ void SwapRecording(WORD); void SwitchStackBack(void); void SwitchStackTo(WORD,WORD,WORD); int SyncAllVoices(void); +BOOL SystemParametersInfo(UINT,UINT,LPVOID,UINT); LONG TabbedTextOut(HDC,short,short,LPSTR,short,short,LPINT,short); BOOL TextOut(HDC,short,short,LPSTR,short); int Throw(LPCATCHBUF,int); @@ -3214,8 +3265,9 @@ HANDLE WinExec(LPSTR,WORD); BOOL WinHelp(HWND,LPSTR,WORD,DWORD); HWND WindowFromPoint(POINT); int WriteComm(int,LPSTR,int); -BOOL WritePrivateProfileString(LPSTR,LPSTR,LPSTR,LPSTR); -BOOL WriteProfileString(LPSTR,LPSTR,LPSTR); +void WriteOutProfiles(void); +BOOL WritePrivateProfileString(LPCSTR,LPCSTR,LPCSTR,LPCSTR); +BOOL WriteProfileString(LPCSTR,LPCSTR,LPCSTR); void Yield(void); LONG _hread(HFILE,LPSTR,LONG); LONG _hwrite(HFILE,LPCSTR,LONG); @@ -3225,13 +3277,15 @@ LONG _llseek(HFILE,LONG,INT); HFILE _lopen(LPCSTR,INT); INT _lread(HFILE,LPSTR,WORD); INT _lwrite(HFILE,LPCSTR,WORD); +void hmemcpy(LPVOID,LPCVOID,LONG); SEGPTR lstrcat(SEGPTR,SEGPTR); INT lstrcmp(LPCSTR,LPCSTR); INT lstrcmpi(LPCSTR,LPCSTR); INT lstrncmpi(LPCSTR,LPCSTR,int); SEGPTR lstrcpy(SEGPTR,SEGPTR); -char * lstrcpyn(char *,const char *,int); +LPSTR lstrcpyn(LPSTR,LPCSTR,int); INT lstrlen(LPCSTR); +int wsprintf(LPSTR,LPSTR,...); int wvsprintf(LPSTR,LPSTR,LPSTR); #ifdef WINELIB diff --git a/include/wine.h b/include/wine.h index 8feab5476c1..e8b4cfadc39 100644 --- a/include/wine.h +++ b/include/wine.h @@ -1,10 +1,6 @@ #ifndef __WINE_WINE_H #define __WINE_WINE_H -extern char *WineIniFileName(void); - -#define WINE_INI WineIniFileName() - #ifdef i386 extern int runtime_cpu (void); #else diff --git a/include/wintypes.h b/include/wintypes.h index f0cc840eda0..30da7789b6c 100644 --- a/include/wintypes.h +++ b/include/wintypes.h @@ -24,6 +24,10 @@ typedef unsigned long DWORD; typedef unsigned short BOOL; typedef unsigned char BYTE; typedef long LONG; +typedef unsigned char CHAR; +/* Some systems might have wchar_t, but we really need 16 bit characters */ +typedef unsigned short WCHAR; + #ifdef WINELIB32 typedef int INT; typedef unsigned int UINT; @@ -53,6 +57,8 @@ typedef DWORD HHOOK; typedef char *LPSTR; typedef const char *LPCSTR; typedef LPCSTR LPCTSTR; +typedef WCHAR *LPWSTR; +typedef const WCHAR *LPCWSTR; typedef char *NPSTR; typedef INT *LPINT; typedef UINT *LPUINT; @@ -90,7 +96,12 @@ DECLARE_HANDLE(HRSRC); DECLARE_HANDLE(HTASK); DECLARE_HANDLE(HWND); DECLARE_HANDLE(LOCALHANDLE); - +#ifdef WINELIB32 +DECLARE_HANDLE(HKEY); +#else +typedef DWORD HKEY; +#endif +typedef HKEY* LPHKEY; typedef HGLOBAL GLOBALHANDLE; #ifdef WINELIB @@ -101,6 +112,7 @@ typedef SEGPTR FARPROC; typedef SEGPTR WNDPROC; #endif typedef FARPROC DLGPROC; +typedef FARPROC FONTENUMPROC; typedef FARPROC HOOKPROC; #define TRUE 1 @@ -108,6 +120,7 @@ typedef FARPROC HOOKPROC; #define CW_USEDEFAULT ((INT)0x8000) #define FAR #define NEAR +#define _near #define PASCAL #define VOID void #define WINAPI PASCAL diff --git a/ipc/shm_fragment_test.c b/ipc/shm_fragment_test.c index 708dad4fc35..c27061bf2e9 100644 --- a/ipc/shm_fragment_test.c +++ b/ipc/shm_fragment_test.c @@ -81,7 +81,7 @@ int main() fprintf(stddeb, "NULL\n"); else { fprintf(stddeb, "0x%06x\n", (int)ret-(int)block); - bzero (ret,size); /* test boundaries */ + memset( ret,0, size ); /* test boundaries */ } } else { /* free */ /* free shm fragment */ diff --git a/library/heap.c b/library/heap.c index 6148c532430..c27389b4351 100644 --- a/library/heap.c +++ b/library/heap.c @@ -82,8 +82,7 @@ HANDLE LocalAlloc (WORD flags, WORD bytes) if ((m = malloc (bytes))) { *slot = m; - if (flags & LMEM_ZEROINIT) - bzero (m, bytes); + if (flags & LMEM_ZEROINIT) memset( m, 0, bytes ); #ifdef DEBUG_HEAP printf ("Handle %d [%d] = %p\n", hMem+1, bytes, m); @@ -220,8 +219,7 @@ HANDLE HEAP_Alloc (WORD flags, DWORD bytes) bytes+=sizeof(HeapData); if ((m = malloc (bytes))) { - if (flags & LMEM_ZEROINIT) - bzero (m, bytes); + if (flags & LMEM_ZEROINIT) memset( m, 0, bytes ); } m->Size=bytes-sizeof(HeapData); return m+1; @@ -253,7 +251,7 @@ HANDLE HEAP_ReAlloc(HANDLE hMem,DWORD bytes,UINT flags) } m=realloc (m-1, bytes+sizeof(HeapData)); if(flags & LMEM_ZEROINIT && bytes > m->Size) - bzero ((char*)m+sizeof(HeapData)+m->Size, bytes-m->Size); + memset( (char*)m+sizeof(HeapData)+m->Size, 0, bytes-m->Size ); m->Size=bytes; return m+1; } diff --git a/library/libres.c b/library/libres.c index 0d1511ec79f..15a34342067 100644 --- a/library/libres.c +++ b/library/libres.c @@ -68,7 +68,7 @@ HRSRC LIBRES_FindResource( HINSTANCE hModule, LPCSTR name, LPCSTR type ) for(Res=ResBlock->Resources; *Res; Res++) if(name) { - if((*Res)->type==typeid && !strcmp((*Res)->name,name)) + if((*Res)->type==typeid && !lstrcmpi((*Res)->name,name)) return (HRSRC)*Res; } else diff --git a/library/winestub.c b/library/winestub.c new file mode 100644 index 00000000000..2f5e7228435 --- /dev/null +++ b/library/winestub.c @@ -0,0 +1,52 @@ +/* Sample winestub.c file for compiling programs with libwine.so. */ + +#include "windows.h" +#include "wine.h" +#ifdef WIN_DEBUG +#include +#endif + +extern int PASCAL WinMain(HINSTANCE,HINSTANCE,LPSTR,int); +/* This is the renamed main() subroutine in misc/main.c. */ +/* Note that the libdll `init()' won't work: */ +extern HINSTANCE _wine_main(int, char *[]); + +int main (int argc, char *argv []) +{ + HINSTANCE hInstance; + char szCmdParam[256] = {0}; + int index, buffer_pos; + char *arg_holder; + /* "Wired-in" command-line options for Wine: */ + /*char *wine_argv[] = {argv[0], "-managed", "-dll", "+commdlg", + "-dll", "+shell", ""};*/ + char *wine_argv[] = {argv[0], ""}; + + /* Initialize the library dll: */ + hInstance = (HINSTANCE)_wine_main((sizeof(wine_argv)/sizeof(char *))-1, wine_argv); + +#ifdef WIN_DEBUG + fprintf(stderr,"In winestub, reporting hInstance = %d\n", hInstance); +#endif + + /* Move things from argv to the szCmdParam that WinMain expects: */ + for (index = 1, buffer_pos = 0; + (index < argc) && (buffer_pos < 255); + index++, buffer_pos++) + { + for (arg_holder = argv[index]; ; buffer_pos++, arg_holder++) + if ((szCmdParam[buffer_pos] = *arg_holder) == '\0') break; + szCmdParam[buffer_pos] = ' '; + }; + szCmdParam[buffer_pos] = '\0'; + +#ifdef WIN_DEBUG + fprintf(stderr,"In winestub, Program Name: %s, Parameters: %s\n", + progname, szCmdParam); +#endif + + return WinMain (hInstance, /* hInstance */ + 0, /* hPrevInstance */ + (LPSTR)szCmdParam, /* lpszCmdParam */ + SW_NORMAL); /* nCmdShow */ +} diff --git a/library/winmain.c b/library/winmain.c index f132725674e..b94554eadb2 100644 --- a/library/winmain.c +++ b/library/winmain.c @@ -11,13 +11,11 @@ extern int PASCAL WinMain(HINSTANCE,HINSTANCE,LPSTR,int); extern void TASK_Reschedule(void); extern int USER_InitApp(HINSTANCE); -char* progname=NULL; int _WinMain (int argc, char *argv []) { HINSTANCE hInstance; - progname=*argv; if(!MAIN_Init()) return 0; /* JBP: Needed for DosDrives[] structure, etc. */ hInstance = WinExec( *argv, SW_SHOWNORMAL ); TASK_Reschedule(); @@ -26,8 +24,12 @@ int _WinMain (int argc, char *argv []) if (!WIDGETS_Init()) return -1; if (!WIN_CreateDesktopWindow()) return -1; +#ifdef WINELIBDLL + return (int)hInstance; +#else return WinMain (hInstance, /* hInstance */ 0, /* hPrevInstance */ "", /* lpszCmdParam */ SW_NORMAL); /* nCmdShow */ +#endif } diff --git a/loader/main.c b/loader/main.c index 8ee5a4e145a..e1bcee8b72f 100644 --- a/loader/main.c +++ b/loader/main.c @@ -51,6 +51,9 @@ int MAIN_Init(void) int queueSize; + /* Load the configuration file */ + if (!PROFILE_LoadWineIni()) return 0; + SpyInit(); #ifndef WINELIB @@ -89,7 +92,7 @@ int MAIN_Init(void) #ifndef WINELIB /* Initialize the DOS memory */ - INT21_Init(); + if (!INT21_Init()) return 0; /* Create USER heap */ if (!USER_HeapInit()) return 0; diff --git a/loader/module.c b/loader/module.c index 5c9557a0aa2..e97c806e504 100644 --- a/loader/module.c +++ b/loader/module.c @@ -954,14 +954,16 @@ HINSTANCE LoadModule( LPCSTR name, LPVOID paramBlock ) /* Create the module structure */ hModule = MODULE_LoadExeHeader( fd, &ofs ); - if (hModule == 21) hModule = PE_LoadModule( fd, &ofs, paramBlock ); - close( fd ); if (hModule < 32) { - fprintf( stderr, "LoadModule: can't load '%s', error=%d\n", - name, hModule ); + if (hModule == 21) hModule = PE_LoadModule( fd, &ofs, paramBlock ); + close(fd); + if (hModule < 32) + fprintf( stderr, "LoadModule: can't load '%s', error=%d\n", + name, hModule ); return hModule; } + close( fd ); pModule = (NE_MODULE *)GlobalLock( hModule ); /* Allocate the segments for this module */ diff --git a/loader/ne_image.c b/loader/ne_image.c index 80eea87e9ab..da9675d5a39 100644 --- a/loader/ne_image.c +++ b/loader/ne_image.c @@ -320,7 +320,8 @@ BOOL NE_LoadSegment( HMODULE hModule, WORD segnum ) if(additive && offset) fprintf(stderr,"Additive selector to %4.4x.Please report\n",offset); } - while (offset != 0xffff && !additive); + /* FIXME: Quicken 5 has a zero offset fixup. This seems to work */ + while (offset && offset != 0xffff && !additive); break; default: diff --git a/loader/pe_image.c b/loader/pe_image.c index f7f3f72fdcc..3d749c11ce9 100644 --- a/loader/pe_image.c +++ b/loader/pe_image.c @@ -38,7 +38,9 @@ struct w_files *wine_files = NULL; void my_wcstombs(char * result, u_short * source, int len) { while(len--) { - if(isascii(*source)) *result++ = *source++; + /* this used to be isascii, but see isascii implementation in Linux' + ctype.h */ + if(*source<255) *result++ = *source++; else { printf("Unable to handle unicode right now\n"); exit(0); @@ -206,7 +208,7 @@ void fixup_imports(struct w_files* wpnt) } dprintf_win32(stddeb, "--- %s %s.%d\n", pe_name->Name, Module, pe_name->Hint); #ifndef WINELIB /* FIXME: JBP: Should this happen in libwine.a? */ - /* Both calls should be unified into GetProcAddress */ + /* FIXME: Both calls should be unified into GetProcAddress */ *thunk_list=(unsigned int)RELAY32_GetEntryPoint(Module,pe_name->Name,pe_name->Hint); if(*thunk_list == 0) *thunk_list = WIN32_GetProcAddress(MODULE_FindModule(Module), @@ -236,7 +238,11 @@ void fixup_imports(struct w_files* wpnt) } dprintf_win32(stddeb, "--- %s %s.%d\n", pe_name->Name, Module, pe_name->Hint); #ifndef WINELIB /* FIXME: JBP: Should this happen in libwine.a? */ + /* FIXME: Both calls should be unified into GetProcAddress */ *thunk_list=(unsigned int)RELAY32_GetEntryPoint(Module,pe_name->Name,pe_name->Hint); + if(*thunk_list == 0) + *thunk_list = WIN32_GetProcAddress(MODULE_FindModule(Module), + pe_name->Name); #else fprintf(stderr,"JBP: Call to RELAY32_GetEntryPoint being ignored.\n"); #endif @@ -346,6 +352,7 @@ static HINSTANCE PE_LoadImage( int fd, struct w_files *wpnt ) { int i, result; unsigned int load_addr; + struct Directory dir; wpnt->pe = xmalloc(sizeof(struct pe_data)); memset(wpnt->pe,0,sizeof(struct pe_data)); @@ -426,17 +433,89 @@ static HINSTANCE PE_LoadImage( int fd, struct w_files *wpnt ) if(strcmp(wpnt->pe->pe_seg[i].Name, ".rsrc") == 0) { wpnt->pe->pe_resource = (struct PE_Resource_Directory *) result; - +#if 0 +/* FIXME pe->resource_offset should be deleted from structure if this + ifdef doesn't break anything */ /* save offset for PE_FindResource */ wpnt->pe->resource_offset = wpnt->pe->pe_seg[i].Virtual_Address - wpnt->pe->pe_seg[i].PointerToRawData; +#endif } - if(strcmp(wpnt->pe->pe_seg[i].Name, ".reloc") == 0) wpnt->pe->pe_reloc = (struct PE_Reloc_Block *) result; } + /* There is word that the actual loader does not care about the + section names, and only goes for the DataDirectory */ + dir=wpnt->pe->pe_header->opt_coff.DataDirectory[IMAGE_FILE_EXPORT_DIRECTORY]; + if(dir.Size) + { + if(wpnt->pe->pe_export && + wpnt->pe->pe_export!=load_addr+dir.Virtual_address) + fprintf(stderr,"wrong export directory??\n"); + else + wpnt->pe->pe_export = load_addr+dir.Virtual_address; + } + + dir=wpnt->pe->pe_header->opt_coff.DataDirectory[IMAGE_FILE_IMPORT_DIRECTORY]; + if(dir.Size) + { + if(wpnt->pe->pe_import && + wpnt->pe->pe_import!=load_addr+dir.Virtual_address) + fprintf(stderr,"wrong export directory??\n"); + else + wpnt->pe->pe_import = load_addr+dir.Virtual_address; + } + + dir=wpnt->pe->pe_header->opt_coff.DataDirectory[IMAGE_FILE_RESOURCE_DIRECTORY]; + if(dir.Size) + { + if(wpnt->pe->pe_resource && + wpnt->pe->pe_resource!=load_addr+dir.Virtual_address) + fprintf(stderr,"wrong resource directory??\n"); + else + wpnt->pe->pe_resource = load_addr+dir.Virtual_address; + } + + dir=wpnt->pe->pe_header->opt_coff.DataDirectory[IMAGE_FILE_BASE_RELOCATION_TABLE]; + if(dir.Size) + { + if(wpnt->pe->pe_reloc && + wpnt->pe->pe_reloc!=load_addr+dir.Virtual_address) + fprintf(stderr,"wrong export directory??\n"); + else + wpnt->pe->pe_reloc = load_addr+dir.Virtual_address; + } + + if(wpnt->pe->pe_header->opt_coff.DataDirectory + [IMAGE_FILE_EXCEPTION_DIRECTORY].Size) + dprintf_win32(stdnimp,"Exception directory ignored\n"); + + if(wpnt->pe->pe_header->opt_coff.DataDirectory + [IMAGE_FILE_SECURITY_DIRECTORY].Size) + dprintf_win32(stdnimp,"Security directory ignored\n"); + + if(wpnt->pe->pe_header->opt_coff.DataDirectory + [IMAGE_FILE_DEBUG_DIRECTORY].Size) + dprintf_win32(stdnimp,"Debug directory ignored\n"); + + if(wpnt->pe->pe_header->opt_coff.DataDirectory + [IMAGE_FILE_DESCRIPTION_STRING].Size) + dprintf_win32(stdnimp,"Description string ignored\n"); + + if(wpnt->pe->pe_header->opt_coff.DataDirectory + [IMAGE_FILE_MACHINE_VALUE].Size) + dprintf_win32(stdnimp,"Machine Value ignored\n"); + + if(wpnt->pe->pe_header->opt_coff.DataDirectory + [IMAGE_FILE_THREAD_LOCAL_STORAGE].Size) + dprintf_win32(stdnimp,"Thread local storage ignored\n"); + + if(wpnt->pe->pe_header->opt_coff.DataDirectory + [IMAGE_FILE_CALLBACK_DIRECTORY].Size) + dprintf_win32(stdnimp,"Callback directory ignored\n"); + if(wpnt->pe->pe_import) fixup_imports(wpnt); if(wpnt->pe->pe_export) dump_exports(wpnt->pe->pe_export,load_addr); diff --git a/loader/signal.c b/loader/signal.c index 1968046833d..adc2c648588 100644 --- a/loader/signal.c +++ b/loader/signal.c @@ -68,6 +68,17 @@ static void win_fault(int signal, int code, struct sigcontext *context) fprintf( stderr,"In win_fault %x:%lx\n", CS_reg(context), EIP_reg(context) ); } + + /* If SIGTRAP not caused by breakpoint or single step + don't jump into the debugger */ + if ((signal == SIGTRAP) && !(EFL_reg(context) & STEP_FLAG)) + { + DBG_ADDR addr; + addr.seg = CS_reg(context); + addr.off = EIP_reg(context) - 1; + if (DEBUG_FindBreakpoint(&addr) == -1) return; + } + XUngrabPointer(display, CurrentTime); XUngrabServer(display); XFlush(display); diff --git a/loader/task.c b/loader/task.c index 5e45faf3dec..08d730c04d5 100644 --- a/loader/task.c +++ b/loader/task.c @@ -77,7 +77,7 @@ static HANDLE TASK_CreateDOSEnvironment(void) { static const char program_name[] = "KRNL386.EXE"; char **e, *p; - int initial_size, size, i, winpathlen, windirlen, sysdirlen; + int initial_size, size, i, winpathlen, sysdirlen; HANDLE handle; extern char **environ; @@ -88,7 +88,6 @@ static HANDLE TASK_CreateDOSEnvironment(void) * ... * ASCIIZ string n * ASCIIZ PATH=xxx - * ASCIIZ windir=xxx * BYTE 0 * WORD 1 * ASCIIZ program name (e.g. C:\WINDOWS\SYSTEM\KRNL386.EXE) @@ -103,10 +102,8 @@ static HANDLE TASK_CreateDOSEnvironment(void) winpathlen += len + 1; } if (!winpathlen) winpathlen = 1; - windirlen = GetWindowsDirectory( NULL, 0 ) + 1; sysdirlen = GetSystemDirectory( NULL, 0 ) + 1; initial_size = 5 + winpathlen + /* PATH=xxxx */ - 7 + windirlen + /* windir=xxxx */ 1 + /* BYTE 0 at end */ sizeof(WORD) + /* WORD 1 */ sysdirlen + /* program directory */ @@ -148,7 +145,7 @@ static HANDLE TASK_CreateDOSEnvironment(void) } } - /* Now add the path and Windows directory */ + /* Now add the path */ strcpy( p, "PATH=" ); for (i = 0, p += 5; ; i++) @@ -160,10 +157,6 @@ static HANDLE TASK_CreateDOSEnvironment(void) if (p[-1] == ';') p[-1] = '\0'; else p++; - strcpy( p, "windir=" ); - GetWindowsDirectory( p + 7, windirlen ); - p += 7 + windirlen; - /* Now add the program name */ *p++ = '\0'; @@ -575,34 +568,36 @@ HTASK TASK_CreateTask( HMODULE hModule, HANDLE hInstance, HANDLE hPrevInstance, static void TASK_DeleteTask( HTASK hTask ) { TDB *pTask; + HANDLE hPDB; if (!(pTask = (TDB *)GlobalLock( hTask ))) return; + hPDB = pTask->hPDB; + + /* Free the task module */ + + FreeModule( pTask->hModule ); /* Close all open files of this task */ FILE_CloseAllFiles( pTask->hPDB ); - /* Free the task module */ - - FreeModule( pTask->hModule ); - - /* Free all memory used by this task (including the 32-bit stack, */ - /* the environment block and the thunk segments). */ - - GlobalFreeAll( pTask->hPDB ); - - /* Free message queue */ + /* Free the message queue */ MSG_DeleteMsgQueue( pTask->hQueue ); - /* Free the selector aliases */ + /* Free the selector aliases */ GLOBAL_FreeBlock( pTask->hCSAlias ); GLOBAL_FreeBlock( pTask->hPDB ); - /* Free the task structure itself */ + /* Free the task structure itself */ GlobalFree( hTask ); + + /* Free all memory used by this task (including the 32-bit stack, */ + /* the environment block and the thunk segments). */ + + GlobalFreeAll( hPDB ); } @@ -626,7 +621,7 @@ void TASK_KillCurrentTask( int exitCode ) if (nTaskCount <= 1) { dprintf_task( stddeb, "Killing the last task, exiting\n" ); - exit(0); + ExitWindows( 0, 0 ); } /* Remove the task from the list to be sure we never switch back to it */ @@ -792,13 +787,13 @@ void InitTask( struct sigcontext_struct context ) ESI_reg(&context) = (DWORD)pTask->hPrevInstance; EDI_reg(&context) = (DWORD)pTask->hInstance; ES_reg (&context) = (WORD)pTask->hPDB; -#endif /* Initialize the local heap */ if ( pModule->heap_size ) { LocalInit( pTask->hInstance, 0, pModule->heap_size ); } +#endif /* Initialize the INSTANCEDATA structure */ diff --git a/memory/global.c b/memory/global.c index 680e9fb1053..4b5c4e6b911 100644 --- a/memory/global.c +++ b/memory/global.c @@ -22,7 +22,7 @@ /* Global arena block */ typedef struct { - DWORD base; /* Base address */ + DWORD base; /* Base address (0 if discarded) */ DWORD size; /* Size in bytes (0 indicates a free block) */ HGLOBAL handle; /* Handle for this block */ HGLOBAL hOwner; /* Owner of this block */ @@ -30,7 +30,9 @@ typedef struct BYTE pageLockCount; /* Count of GlobalPageLock() calls */ BYTE flags; /* Allocation flags */ BYTE selCount; /* Number of selectors allocated for this block */ +#ifdef CONFIG_IPC int shmid; +#endif } GLOBALARENA; /* Flags definitions */ @@ -116,6 +118,8 @@ HGLOBAL GLOBAL_CreateBlock( WORD flags, const void *ptr, DWORD size, pArena->base = (DWORD)ptr; pArena->size = GET_SEL_LIMIT(sel) + 1; + +#ifdef CONFIG_IPC if ((flags & GMEM_DDESHARE) && Options.ipc) { pArena->handle = shmdata->handle; @@ -127,6 +131,9 @@ HGLOBAL GLOBAL_CreateBlock( WORD flags, const void *ptr, DWORD size, pArena->handle = (flags & GMEM_MOVEABLE) ? sel - 1 : sel; pArena->shmid = 0; } +#else + pArena->handle = (flags & GMEM_MOVEABLE) ? sel - 1 : sel; +#endif pArena->hOwner = hOwner; pArena->lockCount = 0; pArena->pageLockCount = 0; @@ -174,11 +181,15 @@ HGLOBAL GLOBAL_Alloc( WORD flags, DWORD size, HGLOBAL hOwner, dprintf_global( stddeb, "GlobalAlloc: %ld flags=%04x\n", size, flags ); - /* Fixup the size */ + /* If size is 0, create a discarded block */ + + if (size == 0) return GLOBAL_CreateBlock( flags, NULL, 1, hOwner, isCode, + is32Bit, isReadOnly, NULL ); + + /* Fixup the size */ if (size >= GLOBAL_MAX_ALLOC_SIZE - 0x1f) return 0; - if (size == 0) size = 0x20; - else size = (size + 0x1f) & ~0x1f; + size = (size + 0x1f) & ~0x1f; /* Allocate the linear memory */ @@ -770,7 +781,7 @@ BOOL MemManInfo( MEMMANINFO *pInfo ) if ((meminfo = fopen("/proc/meminfo", "r")) < 0) { perror("wine: open"); - exit(1); + return FALSE; } fgets(buf, 80, meminfo); /* read first line */ @@ -782,18 +793,20 @@ BOOL MemManInfo( MEMMANINFO *pInfo ) } fprintf(stderr,"MemManInfo called with dwSize = %ld\n",pInfo->dwSize); - pInfo->wPageSize = getpagesize(); - pInfo->dwLargestFreeBlock = availmem; - pInfo->dwTotalLinearSpace = totalmem / pInfo->wPageSize; - pInfo->dwMaxPagesAvailable = pInfo->dwLargestFreeBlock / pInfo->wPageSize; - pInfo->dwMaxPagesLockable = pInfo->dwMaxPagesLockable; - /* FIXME: the next three are not quite correct */ - pInfo->dwTotalUnlockedPages = pInfo->dwMaxPagesAvailable; - pInfo->dwFreePages = pInfo->dwMaxPagesAvailable; - pInfo->dwTotalPages = pInfo->dwMaxPagesAvailable; - /* FIXME: the three above are not quite correct */ - pInfo->dwFreeLinearSpace = pInfo->dwMaxPagesAvailable; - pInfo->dwSwapFilePages = 0L; + if (pInfo->dwSize) { + pInfo->wPageSize = getpagesize(); + pInfo->dwLargestFreeBlock = availmem; + pInfo->dwTotalLinearSpace = totalmem / pInfo->wPageSize; + pInfo->dwMaxPagesAvailable = pInfo->dwLargestFreeBlock / pInfo->wPageSize; + pInfo->dwMaxPagesLockable = pInfo->dwMaxPagesLockable; + /* FIXME: the next three are not quite correct */ + pInfo->dwTotalUnlockedPages = pInfo->dwMaxPagesAvailable; + pInfo->dwFreePages = pInfo->dwMaxPagesAvailable; + pInfo->dwTotalPages = pInfo->dwMaxPagesAvailable; + /* FIXME: the three above are not quite correct */ + pInfo->dwFreeLinearSpace = pInfo->dwMaxPagesAvailable; + pInfo->dwSwapFilePages = 0L; + } return TRUE; #else return TRUE; diff --git a/memory/local.c b/memory/local.c index e20bd9c3354..d1235a3087f 100644 --- a/memory/local.c +++ b/memory/local.c @@ -107,7 +107,9 @@ static LOCALHEAPINFO *LOCAL_GetHeap( WORD ds ) LOCALHEAPINFO *pInfo; INSTANCEDATA *ptr = (INSTANCEDATA *)PTR_SEG_OFF_TO_LIN( ds, 0 ); dprintf_local( stddeb, "Heap at %p, %04x\n", ptr, ptr->heap ); - if (!ptr->heap) return 0; + if (!ptr->heap) return NULL; + if (IsBadReadPtr((SEGPTR)MAKELONG( ptr->heap, ds ), sizeof(LOCALHEAPINFO))) + return NULL; pInfo = (LOCALHEAPINFO*)((char*)ptr + ptr->heap); if (pInfo->magic != LOCAL_HEAP_MAGIC) return NULL; return pInfo; diff --git a/misc/Makefile.in b/misc/Makefile.in index 7d0a5467431..b9939f39912 100644 --- a/misc/Makefile.in +++ b/misc/Makefile.in @@ -6,7 +6,6 @@ C_SRCS = \ comm.c \ commdlg.c \ compobj.c \ - dos_fs.c \ driver.c \ exec.c \ escape.c \ @@ -20,14 +19,13 @@ C_SRCS = \ olecli.c \ olesvr.c \ port.c \ - profile.c \ rect.c \ shell.c \ sound.c \ spy.c \ stress.c \ + toolhelp.c \ user.c \ - user32.c \ winsocket.c \ xmalloc.c diff --git a/misc/clipboard.c b/misc/clipboard.c index 68f5fe76c55..41bab8230be 100644 --- a/misc/clipboard.c +++ b/misc/clipboard.c @@ -165,7 +165,7 @@ HANDLE GetClipboardData(WORD wFormat) /************************************************************************** * CountClipboardFormats [USER.143] */ -int CountClipboardFormats() +INT CountClipboardFormats() { int FormatCount = 0; LPCLIPFORMAT lpFormat = ClipFormats; diff --git a/misc/comm.c b/misc/comm.c index 107ec99f32d..467912d082d 100644 --- a/misc/comm.c +++ b/misc/comm.c @@ -16,9 +16,9 @@ #endif #include -#include "wine.h" #include "windows.h" #include "comm.h" +#include "options.h" #include "stddebug.h" /* #define DEBUG_COMM */ /* #undef DEBUG_COMM */ @@ -40,11 +40,12 @@ void COMM_Init(void) option[3] = '1' + x; option[4] = '\0'; - GetPrivateProfileString("serialports", option, "*", temp, sizeof(temp), WINE_INI); + PROFILE_GetWineIniString( "serialports", option, "*", + temp, sizeof(temp) ); if (!strcmp(temp, "*") || *temp == '\0') COM[x].devicename = NULL; else { - btemp = index(temp,','); + btemp = strchr(temp,','); if (btemp != NULL) { *btemp++ = '\0'; COM[x].baudrate = atoi(btemp); @@ -69,7 +70,8 @@ void COMM_Init(void) option[3] = '1' + x; option[4] = '\0'; - GetPrivateProfileString("parallelports", option, "*", temp, sizeof(temp), WINE_INI); + PROFILE_GetWineIniString( "parallelports", option, "*", + temp, sizeof(temp) ); if (!strcmp(temp, "*") || *temp == '\0') LPT[x].devicename = NULL; else { @@ -124,7 +126,7 @@ int WinError(void) } } -int BuildCommDCB(LPSTR device, DCB FAR *lpdcb) +BOOL BuildCommDCB(LPCSTR device, LPDCB lpdcb) { /* "COM1:9600,n,8,1" */ /* 012345 */ @@ -219,7 +221,7 @@ int BuildCommDCB(LPSTR device, DCB FAR *lpdcb) return 0; } -int OpenComm(LPSTR device, UINT cbInQueue, UINT cbOutQueue) +int OpenComm(LPCSTR device, UINT cbInQueue, UINT cbOutQueue) { int port, fd; diff --git a/misc/dos_fs.c b/misc/dos_fs.c deleted file mode 100644 index b01f6b01770..00000000000 --- a/misc/dos_fs.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * DOS-FS - * NOV 1993 Erik Bos - * - * FindFile by Bob, hacked for dos & unixpaths by Erik. - * - * Bugfix by dash@ifi.uio.no: ToUnix() was called to often - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(__linux__) || defined(sun) -#include -#endif -#if defined(__NetBSD__) || defined(__FreeBSD__) -#include -#include -#include -#endif -#ifdef __svr4__ -#include -#endif -#include "wine.h" -#include "windows.h" -#include "msdos.h" -#include "dos_fs.h" -#include "comm.h" -#include "task.h" -#include "stddebug.h" -#include "debug.h" -#include "xmalloc.h" - -#define WINE_INI_USER "~/.winerc" - - -static void ExpandTildeString(char *s) -{ - struct passwd *entry; - char temp[1024], *ptr = temp; - - strcpy(temp, s); - - while (*ptr) - { - if (*ptr != '~') - { - *s++ = *ptr++; - continue; - } - - ptr++; - - if ( (entry = getpwuid(getuid())) == NULL) - { - continue; - } - - strcpy(s, entry->pw_dir); - s += strlen(entry->pw_dir); - } - *s = 0; -} - - - -int DOS_GetFreeSpace(int drive, long *size, long *available) -{ - struct statfs info; - const char *root; - - if (!DRIVE_IsValid(drive)) return 0; - root = DRIVE_GetRoot(drive); - -#ifdef __svr4__ - if (statfs( root, &info, 0, 0) < 0) { -#else - if (statfs( root, &info) < 0) { -#endif - fprintf(stderr,"dosfs: cannot do statfs(%s)\n", root ); - return 0; - } - - *size = info.f_bsize * info.f_blocks; -#ifdef __svr4__ - *available = info.f_bfree * info.f_bsize; -#else - *available = info.f_bavail * info.f_bsize; -#endif - return 1; -} - -/********************************************************************** - * WineIniFileName - */ -char *WineIniFileName(void) -{ - int fd; - static char *filename = NULL; - static char name[256]; - - if (filename) - return filename; - - strcpy(name, WINE_INI_USER); - ExpandTildeString(name); - if ((fd = open(name, O_RDONLY)) != -1) { - close(fd); - filename = name; - return filename; - } - if ((fd = open(WINE_INI_GLOBAL, O_RDONLY)) != -1) { - close(fd); - filename = WINE_INI_GLOBAL; - return filename; - } - fprintf(stderr,"wine: can't open configuration file %s or %s !\n", - WINE_INI_GLOBAL, WINE_INI_USER); - exit(1); -} - diff --git a/misc/exec.c b/misc/exec.c index 12356610193..5c494870b5d 100644 --- a/misc/exec.c +++ b/misc/exec.c @@ -9,6 +9,7 @@ #include #include "neexe.h" #include "dlls.h" +#include "shell.h" #include "windows.h" #include "callback.h" #include "stddebug.h" @@ -41,6 +42,11 @@ BOOL ExitWindows(DWORD dwReturnCode, WORD wReserved) dprintf_exec( stdnimp,"PARTIAL STUB ExitWindows(%08lX, %04X)\n", dwReturnCode, wReserved); + /* Do the clean-up stuff */ + + WriteOutProfiles(); + SHELL_SaveRegistry(); + exit( LOWORD(dwReturnCode) ); } diff --git a/misc/lstr.c b/misc/lstr.c index 5f7c90adde4..5bc9032c96b 100644 --- a/misc/lstr.c +++ b/misc/lstr.c @@ -106,7 +106,7 @@ SEGPTR lstrcpy( SEGPTR target, SEGPTR source ) } /* KERNEL.353 32-bit version*/ -char *lstrcpyn( char *dst, const char *src, int n ) +LPSTR lstrcpyn( LPSTR dst, LPCSTR src, int n ) { char *tmp = dst; while(n-- > 1 && *src) @@ -293,7 +293,7 @@ BOOL OemToAnsi(LPSTR lpOemStr, LPSTR lpAnsiStr) } /* AnsiToOemBuff Keyboard.134 */ -void AnsiToOemBuff(LPSTR lpAnsiStr, LPSTR lpOemStr, INT nLength) +void AnsiToOemBuff(LPCSTR lpAnsiStr, LPSTR lpOemStr, UINT nLength) { int i; for(i=0;i -#include #include #ifndef HAVE_USLEEP diff --git a/misc/profile.c b/misc/profile.c deleted file mode 100644 index 4790c015548..00000000000 --- a/misc/profile.c +++ /dev/null @@ -1,496 +0,0 @@ -/* - * Initialization-File Functions. - * - * Copyright (c) 1993 Miguel de Icaza - * - * 1/Dec o Corrected return values for Get*ProfileString - * - * o Now, if AppName == NULL in Get*ProfileString it returns a list - * of the KeyNames (as documented in the MS-SDK). - * - * o if KeyValue == NULL now clears the value in Get*ProfileString - * - * 20/Apr SL - I'm not sure where these definitions came from, but my SDK - * 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. - */ -#include -#include -#include -#include - -#include "wine.h" -#include "windows.h" -#include "dos_fs.h" -#include "toolhelp.h" -#include "stddebug.h" -#include "debug.h" -#include "xmalloc.h" - -#define STRSIZE 255 - -typedef struct TKeys { - char *KeyName; - char *Value; - struct TKeys *link; -} TKeys; - -typedef struct TSecHeader { - char *AppName; - TKeys *Keys; - struct TSecHeader *link; -} TSecHeader; - -typedef struct TProfile { - char *FileName; - char *FullName; - TSecHeader *Section; - struct TProfile *link; - int changed; -} TProfile; - -TProfile *Current = 0; -TProfile *Base = 0; - -static TSecHeader *is_loaded (char *FileName) -{ - TProfile *p = Base; - - while (p){ - if (!lstrcmpi( FileName, p->FileName)){ - Current = p; - return p->Section; - } - p = p->link; - } - return 0; -} - -#define WIN_INI WinIniFileName() - -static char *WinIniFileName(void) -{ - static char *name = NULL; - int len; - const char *unixName; - - if (name) return name; - - len = GetWindowsDirectory( NULL, 0 ) + 9; - name = xmalloc( len ); - GetWindowsDirectory( name, len ); - strcat( name, "/win.ini" ); - if (!(unixName = DOSFS_GetUnixFileName( name, TRUE ))) return NULL; - free( name ); - name = strdup( unixName ); - return name; -} - -static char *GetIniFileName(char *name, char *dir) -{ - char temp[256]; - - if (strchr(name, '/')) - return name; - - if (strlen(dir)) { - strcpy(temp, dir); - strcat(temp, "\\"); - strcat(temp, name); - } - else - strcpy(temp, name); - return DOSFS_GetUnixFileName(temp,TRUE); -} - -static TSecHeader *load (char *filename, char **pfullname) -{ - FILE *f; - TSecHeader *SecHeader = 0; - char CharBuffer [STRSIZE]; - char *bufptr; - char *lastnonspc; - int bufsize; - char *file, *purefilename; - int c; - char path[MAX_PATH+1]; - BOOL firstbrace; - - *pfullname = NULL; - - dprintf_profile(stddeb,"Trying to load file %s \n", filename); - - /* First try it as is */ - file = GetIniFileName(filename, ""); - if (!file || !(f = fopen(file, "r"))) - { - if ((purefilename = strrchr( filename, '\\' ))) - purefilename++; - else if ((purefilename = strrchr( filename, '/' ))) - purefilename++; - else - purefilename = filename; - - /* Now try the Windows directory */ - GetWindowsDirectory(path, sizeof(path)); - if ((file = GetIniFileName(purefilename, path))) - { - dprintf_profile(stddeb,"Trying to load in windows directory file %s\n", - file); - f = fopen(file, "r"); - } - else f = NULL; - - if (f == NULL) - { /* Try the path of the current executable */ - - if (GetCurrentTask()) - { - char *p; - GetModuleFileName( GetCurrentTask(), path, MAX_PATH ); - if ((p = strrchr( path, '\\' ))) - { - p[0] = '\0'; /* Remove trailing slash */ - if ((file = GetIniFileName(purefilename, path))) - { - dprintf_profile(stddeb, - "Trying to load in current directory%s\n", - file); - f = fopen(file, "r"); - } - } - } - } - if (f == NULL) { /* And now in $HOME/.wine */ - - strcpy(path,getenv("HOME")); - strcat(path, "/.wine/"); - strcat(path, purefilename); - dprintf_profile(stddeb,"Trying to load in user-directory %s\n", path); - file = path; - f = fopen(file, "r"); - } - - if (f == NULL) { - /* FIXED: we ought to create it now (in which directory?) */ - /* lets do it in ~/.wine */ - strcpy(path,getenv("HOME")); - strcat(path, "/.wine/"); - strcat(path, purefilename); - dprintf_profile(stddeb,"Creating %s\n", path); - file = path; - f = fopen(file, "w+"); - if (f == NULL) { - fprintf(stderr, "profile.c: load() can't find file %s\n", filename); - return NULL; - } - } - } - - *pfullname = xstrdup(file); - dprintf_profile(stddeb,"Loading %s\n", file); - - firstbrace = TRUE; - for(;;) { - c = fgetc(f); - if (c == EOF) goto finished; - - 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; - - SecHeader = (TSecHeader *) xmalloc (sizeof (TSecHeader)); - SecHeader->link = temp; - SecHeader->Keys = NULL; - do { - c = fgetc(f); - if (c == EOF) goto bad_file; - } while (isspace(c)); - bufptr = lastnonspc = CharBuffer; - bufsize = 0; - do { - if (c != ']') { - bufsize++; - *bufptr++ = c; - if (!isspace(c)) - lastnonspc = bufptr; - } else - break; - c = fgetc(f); - if (c == EOF) goto bad_file; - } while(bufsize < STRSIZE-1); - *lastnonspc = 0; - if (!strlen(CharBuffer)) - fprintf(stderr, "warning: empty section name in ini file\n"); - SecHeader->AppName = xstrdup (CharBuffer); - dprintf_profile(stddeb,"%s: section %s\n", file, CharBuffer); - firstbrace = FALSE; - } else if (SecHeader) { - TKeys *temp = SecHeader->Keys; - BOOL skipspc; - - if (firstbrace) - goto bad_file; - bufptr = lastnonspc = CharBuffer; - bufsize = 0; - do { - if (c != '=') { - bufsize++; - *bufptr++ = c; - if (!isspace(c)) - lastnonspc = bufptr; - } else - break; - c = fgetc(f); - if (c == EOF) goto bad_file; - } while(bufsize < STRSIZE-1); - *lastnonspc = 0; - if (!strlen(CharBuffer)) - fprintf(stderr, "warning: empty key name in ini file\n"); - SecHeader->Keys = (TKeys *) xmalloc (sizeof (TKeys)); - SecHeader->Keys->link = temp; - SecHeader->Keys->KeyName = xstrdup (CharBuffer); - - dprintf_profile(stddeb,"%s: key %s\n", file, CharBuffer); - - bufptr = lastnonspc = CharBuffer; - bufsize = 0; - skipspc = TRUE; - do { - c = fgetc(f); - if (c == EOF || c == '\n') break; - if (!isspace(c) || !skipspc) { - skipspc = FALSE; - bufsize++; - *bufptr++ = c; - if (!isspace(c)) - lastnonspc = bufptr; - } - } while(bufsize < STRSIZE-1); - *lastnonspc = 0; - SecHeader->Keys->Value = xstrdup (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; - } - } - - } -bad_file: - fprintf(stderr, "warning: bad ini file\n"); -finished: - return SecHeader; -} - -static void new_key (TSecHeader *section, char *KeyName, char *Value) -{ - TKeys *key; - - key = (TKeys *) xmalloc (sizeof (TKeys)); - key->KeyName = xstrdup (KeyName); - key->Value = xstrdup (Value); - key->link = section->Keys; - section->Keys = key; -} - -static short GetSetProfile (int set, LPSTR AppName, LPSTR KeyName, - LPSTR Default, LPSTR ReturnedString, short Size, - LPSTR FileName) - -{ - TProfile *New; - TSecHeader *section; - TKeys *key; - - /* Supposedly Default should NEVER be NULL. But sometimes it is. */ - if (Default == NULL) - Default = ""; - - if (!(section = is_loaded (FileName))){ - New = (TProfile *) xmalloc (sizeof (TProfile)); - New->link = Base; - New->FileName = xstrdup (FileName); - New->Section = load (FileName, &New->FullName); - New->changed = FALSE; - Base = New; - section = New->Section; - Current = New; - } - - /* Start search */ - for (; section; section = section->link){ - if (lstrcmpi(section->AppName, AppName)) - continue; - - /* If no key value given, then list all the keys */ - if ((!KeyName) && (!set)){ - char *p = ReturnedString; - int left = Size - 2; - int slen; - - 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; - } - slen = MIN(strlen(key->KeyName) + 1, left); - lstrcpyn(p, key->KeyName, slen); - dprintf_profile(stddeb,"GetSetProfile // enum '%s' !\n", p); - left -= slen; - p += slen; - } - *p = '\0'; - return Size - 2 - left; - } - for (key = section->Keys; key; key = key->link){ - int slen; - if (lstrcmpi(key->KeyName, KeyName)) - continue; - if (set){ - free (key->Value); - key->Value = xstrdup (Default ? Default : ""); - Current->changed=TRUE; - return 1; - } - slen = MIN(strlen(key->Value)+1, Size); - lstrcpyn(ReturnedString, key->Value, slen); - dprintf_profile(stddeb,"GetSetProfile // Return ``%s''\n", ReturnedString); - return 1; - } - /* If Getting the information, then don't write the information - to the INI file, need to run a couple of tests with windog */ - /* No key found */ - if (set) { - new_key (section, KeyName, Default); - } else { - 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)); - section->AppName = xstrdup (AppName); - section->Keys = 0; - new_key (section, KeyName, Default); - section->link = Current->Section; - Current->Section = section; - Current->changed = TRUE; - } else { - int slen = MIN(strlen(Default)+1, Size); - lstrcpyn(ReturnedString, Default, slen); - dprintf_profile(stddeb,"GetSetProfile // Section not found\n"); - } - return 1; -} - -short GetPrivateProfileString (LPCSTR AppName, LPCSTR KeyName, - LPCSTR Default, LPSTR ReturnedString, - short Size, LPCSTR FileName) -{ - int v; - - dprintf_profile(stddeb,"GetPrivateProfileString ('%s', '%s', '%s', %p, %d, %s\n", - AppName, KeyName, Default, ReturnedString, Size, FileName); - v = GetSetProfile (0,AppName,KeyName,Default,ReturnedString,Size,FileName); - if (AppName) - return strlen (ReturnedString); - else - return Size - v; -} - -int GetProfileString (LPCSTR AppName, LPCSTR KeyName, LPCSTR Default, - LPSTR ReturnedString, int Size) -{ - return GetPrivateProfileString (AppName, KeyName, Default, - ReturnedString, Size, WIN_INI ); -} - -WORD GetPrivateProfileInt (LPCSTR AppName, LPCSTR KeyName, short Default, - LPCSTR File) -{ - static char IntBuf[10]; - static char buf[10]; - - sprintf (buf, "%d", Default); - - /* Check the exact semantic with the SDK */ - GetPrivateProfileString (AppName, KeyName, buf, IntBuf, 10, File); - if (!lstrcmpi(IntBuf, "true")) - return 1; - if (!lstrcmpi(IntBuf, "yes")) - return 1; - return strtoul( IntBuf, NULL, 0 ); -} - -WORD GetProfileInt (LPCSTR AppName, LPCSTR KeyName, int Default) -{ - return GetPrivateProfileInt (AppName, KeyName, Default, WIN_INI); -} - -BOOL WritePrivateProfileString (LPSTR AppName, LPSTR KeyName, LPSTR String, - LPSTR FileName) -{ - if (!AppName || !KeyName || !String) /* Flush file to disk */ - return TRUE; - return GetSetProfile (1, AppName, KeyName, String, "", 0, FileName); -} - -BOOL WriteProfileString (LPSTR AppName, LPSTR KeyName, LPSTR String) -{ - return (WritePrivateProfileString (AppName, KeyName, String, WIN_INI)); -} - -static void dump_keys (FILE *profile, TKeys *p) -{ - if (!p) - return; - dump_keys (profile, p->link); - fprintf (profile, "%s=%s\r\n", p->KeyName, p->Value); -} - -static void dump_sections (FILE *profile, TSecHeader *p) -{ - if (!p) - return; - dump_sections (profile, p->link); - fprintf (profile, "\r\n[%s]\r\n", p->AppName); - dump_keys (profile, p->Keys); -} - -static void dump_profile (TProfile *p) -{ - FILE *profile; - - if (!p) - return; - dump_profile (p->link); - if(!p->changed) - return; - if (p->FullName && (profile = fopen (p->FullName, "w")) != NULL){ - dump_sections (profile, p->Section); - fclose (profile); - } -} - -void sync_profiles (void) -{ - dump_profile (Base); -} diff --git a/misc/rect.c b/misc/rect.c index c5d79854350..0ae8b0cc5f4 100644 --- a/misc/rect.c +++ b/misc/rect.c @@ -33,9 +33,10 @@ void SetRectEmpty( LPRECT rect ) /*********************************************************************** * CopyRect (USER.74) */ -void CopyRect( LPRECT dest, LPRECT src ) +BOOL CopyRect( LPRECT dest, LPRECT src ) { *dest = *src; + return TRUE; } diff --git a/misc/shell.c b/misc/shell.c index 0d486989619..802ee7bf406 100644 --- a/misc/shell.c +++ b/misc/shell.c @@ -215,7 +215,7 @@ SHELL_LoadRegistry(void) /************************************************************************* * RegOpenKey [SHELL.1] */ -LONG RegOpenKey(HKEY hKey, LPCSTR lpSubKey, HKEY FAR *lphKey) +LONG RegOpenKey(HKEY hKey, LPCSTR lpSubKey, LPHKEY lphKey) { LPKEYSTRUCT lpKey,lpNextKey; LPCSTR ptr; @@ -264,7 +264,7 @@ LONG RegOpenKey(HKEY hKey, LPCSTR lpSubKey, HKEY FAR *lphKey) /************************************************************************* * RegCreateKey [SHELL.2] */ -LONG RegCreateKey(HKEY hKey, LPCSTR lpSubKey, HKEY FAR *lphKey) +LONG RegCreateKey(HKEY hKey, LPCSTR lpSubKey, LPHKEY lphKey) { HKEY hNewKey; LPKEYSTRUCT lpNewKey; @@ -391,7 +391,7 @@ LONG RegSetValue(HKEY hKey, LPCSTR lpSubKey, DWORD dwType, /************************************************************************* * RegQueryValue [SHELL.6] */ -LONG RegQueryValue(HKEY hKey, LPCSTR lpSubKey, LPSTR lpVal, LONG FAR *lpcb) +LONG RegQueryValue(HKEY hKey, LPCSTR lpSubKey, LPSTR lpVal, LPLONG lpcb) { HKEY hRetKey; LPKEYSTRUCT lpKey; @@ -552,7 +552,7 @@ BOOL DragQueryPoint(HDROP hDrop, POINT FAR *p) /************************************************************************* * ShellExecute [SHELL.20] */ -HINSTANCE ShellExecute(HWND hWnd, LPCSTR lpOperation, LPCSTR lpFile, LPCSTR lpParameters, LPCSTR lpDirectory, int iShowCmd) +HINSTANCE ShellExecute(HWND hWnd, LPCSTR lpOperation, LPCSTR lpFile, LPSTR lpParameters, LPCSTR lpDirectory, INT iShowCmd) { char cmd[400]; char *p,*x; diff --git a/misc/sound.c b/misc/sound.c index 8b8696db3e8..990bb727b91 100644 --- a/misc/sound.c +++ b/misc/sound.c @@ -77,7 +77,7 @@ int SyncAllVoices(void) return 0; } -int CountVoiceNotes(int x) +INT CountVoiceNotes(INT x) { fprintf(stderr, "CountVoiceNotes(%d)\n", x); return 0; diff --git a/misc/spy.c b/misc/spy.c index 3a92d62a0b4..81f2852bbee 100644 --- a/misc/spy.c +++ b/misc/spy.c @@ -10,7 +10,6 @@ #include #include #include "windows.h" -#include "wine.h" #include "options.h" #include "stddebug.h" #include "debug.h" @@ -529,7 +528,8 @@ void SpyInit(void) for(i=0; i <= SPY_MAX_MSGNUM; i++) SpyFilters[i] = SpyIncludes[i] = FALSE; - GetPrivateProfileString("spy", "Exclude", "",lpstrBuffer ,511 , WINE_INI); + PROFILE_GetWineIniString( "spy", "Exclude", "", + lpstrBuffer, sizeof(lpstrBuffer) ); dprintf_message(stddeb,"SpyInit: Exclude=%s\n",lpstrBuffer); if( *lpstrBuffer != 0 ) if(strstr(lpstrBuffer,"EXCLUDEALL")) @@ -539,7 +539,8 @@ void SpyInit(void) if(MessageTypeNames[i]) if(strstr(lpstrBuffer,MessageTypeNames[i])) SpyFilters[i] = TRUE; - GetPrivateProfileString("spy", "Include", "INCLUDEALL",lpstrBuffer ,511 , WINE_INI); + PROFILE_GetWineIniString( "spy", "Include", "INCLUDEALL", + lpstrBuffer, sizeof(lpstrBuffer) ); dprintf_message(stddeb,"SpyInit: Include=%s\n",lpstrBuffer); if( *lpstrBuffer != 0 ) if(strstr(lpstrBuffer,"INCLUDEALL")) diff --git a/misc/toolhelp.c b/misc/toolhelp.c new file mode 100644 index 00000000000..ccde79a8f02 --- /dev/null +++ b/misc/toolhelp.c @@ -0,0 +1,70 @@ +/* + * Misc Toolhelp functions + * + * Copyright 1996 Marcus Meissner + */ + +#include +#include +#include +#include +#include +#include "windows.h" +#include "win.h" +#include "toolhelp.h" +#include "stddebug.h" +#include "debug.h" +#include "xmalloc.h" + +/* FIXME: to make this working, we have to callback all these registered + * functions from all over the WINE code. Someone with more knowledge than + * me please do that. -Marcus + */ +static struct notify +{ + HTASK htask; + FARPROC lpfnCallback; + WORD wFlags; +} *notifys = NULL; + +static int nrofnotifys = 0; + +BOOL +NotifyRegister(HTASK htask,FARPROC lpfnCallback,WORD wFlags) +{ + int i; + + dprintf_toolhelp( stddeb, "NotifyRegister(%x,%lx,%x) called.\n", + htask, (DWORD)lpfnCallback, wFlags ); + for (i=0;i #include -#include "atom.h" -#include "comm.h" -#include "gdi.h" -#include "desktop.h" -#include "dlls.h" -#include "dos_fs.h" -#include "sysmetrics.h" -#include "menu.h" -#include "dce.h" -#include "dialog.h" -#include "syscolor.h" -#include "win.h" #include "windows.h" +#include "gdi.h" #include "user.h" +#include "win.h" #include "message.h" #include "toolhelp.h" diff --git a/misc/winsocket.c b/misc/winsocket.c index 0586e5260d7..05e1ecfc516 100644 --- a/misc/winsocket.c +++ b/misc/winsocket.c @@ -652,7 +652,16 @@ SOCKET WINSOCK_socket(INT af, INT type, INT protocol) dprintf_winsock(stddeb, "WSA_socket: af=%d type=%d protocol=%d\n", af, type, protocol); if ((sock = socket(af, type, protocol)) < 0) { + if (errno != EPERM) { errno_to_wsaerrno(); + } else { + /* NOTE: EPERM does not always map to WSAESOCKTNOSUPPORT + * so this is done as a special case + */ + /* non super-user wants a raw socket */ + dprintf_winsock(stderr, "WSA_socket: not enough privileges\n"); + WSASetLastError(WSAESOCKTNOSUPPORT); + } dprintf_winsock(stddeb, "WSA_socket: failed !\n"); return INVALID_SOCKET; } @@ -1177,7 +1186,7 @@ INT WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData) return WSASYSNOTREADY; Heap = (struct WinSockHeap *) GlobalLock(HeapHandle); - bcopy(&WINSOCK_data, lpWSAData, sizeof(WINSOCK_data)); + memcpy(lpWSAData, &WINSOCK_data, sizeof(WINSOCK_data)); /* ipc stuff */ diff --git a/miscemu/cpu.c b/miscemu/cpu.c index bde9e366c64..a17f63505cb 100644 --- a/miscemu/cpu.c +++ b/miscemu/cpu.c @@ -7,6 +7,7 @@ #include #include #include +#include "windows.h" int runtime_cpu (void) { diff --git a/miscemu/dpmi.c b/miscemu/dpmi.c index 760be10304d..2b3c0f862db 100644 --- a/miscemu/dpmi.c +++ b/miscemu/dpmi.c @@ -10,6 +10,7 @@ #include #include "windows.h" #include "ldt.h" +#include "module.h" #include "registers.h" #include "wine.h" #include "miscemu.h" @@ -40,6 +41,8 @@ typedef struct WORD ss; } REALMODECALL; +extern void do_mscdex(struct sigcontext_struct *context); + /********************************************************************** * INT_Int31Handler * @@ -69,6 +72,34 @@ void INT_Int31Handler( struct sigcontext_struct context ) } break; + case 0x0002: /* Real mode segment to descriptor */ + { + WORD entryPoint = 0; /* KERNEL entry point for descriptor */ + switch(BX_reg(&context)) + { + case 0x0000: entryPoint = 183; break; /* __0000H */ + case 0x0040: entryPoint = 193; break; /* __0040H */ + case 0xa000: entryPoint = 174; break; /* __A000H */ + case 0xb000: entryPoint = 181; break; /* __B000H */ + case 0xb800: entryPoint = 182; break; /* __B800H */ + case 0xc000: entryPoint = 195; break; /* __C000H */ + case 0xd000: entryPoint = 179; break; /* __D000H */ + case 0xe000: entryPoint = 190; break; /* __E000H */ + case 0xf000: entryPoint = 194; break; /* __F000H */ + default: + fprintf( stderr, "DPMI: real-mode seg to descriptor %04x not possible\n", + BX_reg(&context) ); + AX_reg(&context) = 0x8011; + SET_CFLAG(&context); + break; + } + if (entryPoint) + AX_reg(&context) = LOWORD(MODULE_GetEntryPoint( + GetModuleHandle( "KERNEL" ), + entryPoint )); + } + break; + case 0x0003: /* Get next selector increment */ AX_reg(&context) = __AHINCR; break; @@ -162,7 +193,25 @@ void INT_Int31Handler( struct sigcontext_struct context ) " ESI=%08lx EDI=%08lx ES=%04x DS=%04x\n", BL_reg(&context), p->eax, p->ebx, p->ecx, p->edx, p->esi, p->edi, p->es, p->ds ); - SET_CFLAG(&context); + + /* Compton's 1995 encyclopedia does its MSCDEX calls through + * this interrupt. Why? Who knows... + */ + if ((BL_reg(&context) == 0x2f) && ((p->eax & 0xFF00) == 0x1500)) + { + struct sigcontext_struct context2; + EAX_reg(&context2) = p->eax; + EBX_reg(&context2) = p->ebx; + ECX_reg(&context2) = p->ecx; + EDX_reg(&context2) = p->edx; + ES_reg(&context2) = p->es; + do_mscdex(&context2); + p->eax = EAX_reg(&context2); + p->ebx = EBX_reg(&context2); + p->ecx = ECX_reg(&context2); + p->edx = EDX_reg(&context2); + } + else SET_CFLAG(&context); } break; diff --git a/miscemu/int21.c b/miscemu/int21.c index 16b5f8f9864..a7d9ec09b97 100644 --- a/miscemu/int21.c +++ b/miscemu/int21.c @@ -83,12 +83,6 @@ WORD sharing_pause = 1; /* pause between retries */ extern char TempDirectory[]; -static int Error(int e, int class, int el) -{ - return DOS_ERROR( e, class, SA_Abort, el ); -} - - BYTE *GetCurrentDTA(void) { TDB *pTask = (TDB *)GlobalLock( GetCurrentTask() ); @@ -140,61 +134,30 @@ static void CreateBPB(int drive, BYTE *data) } } -static void GetFreeDiskSpace(struct sigcontext_struct *context) +static int INT21_GetFreeDiskSpace(struct sigcontext_struct *context) { - long size,available; + DWORD size, available; int drive = DOS_GET_DRIVE( DL_reg(context) ); - if (!DRIVE_IsValid(drive)) - { - DOS_ERROR( ER_InvalidDrive, EC_MediaError, SA_Abort, EL_Disk ); - AX_reg(context) = 0xffff; - return; - } - - if (!DOS_GetFreeSpace(drive, &size, &available)) { - DOS_ERROR( ER_GeneralFailure, EC_MediaError, SA_Abort, EL_Disk ); - AX_reg(context) = 0xffff; - return; - } + if (!DRIVE_GetFreeSpace(drive, &size, &available)) return 0; - AX_reg(context) = (drive < 2) ? 1 : 64; /* 64 for hard-disks, 1 for diskettes */ - CX_reg(context) = 512; - BX_reg(context) = (available / (CX_reg(context) * AX_reg(context))); - DX_reg(context) = (size / (CX_reg(context) * AX_reg(context))); - Error (0,0,0); + CX_reg(context) = 512; /* bytes per sector */ + size /= 512; + available /= 512; + AX_reg(context) = 1; /* sectors per cluster */ + while (AX_reg(context) * 65530 < size) AX_reg(context) *= 2; + BX_reg(context) = available / AX_reg(context); /* free clusters */ + DX_reg(context) = size / AX_reg(context); /* total clusters */ + return 1; } -static void GetDriveAllocInfo(struct sigcontext_struct *context) +static int INT21_GetDriveAllocInfo(struct sigcontext_struct *context) { - long size, available; - int drive = DOS_GET_DRIVE( DL_reg(context) ); - - if (!DRIVE_IsValid(drive)) - { - AX_reg(context) = 4; - CX_reg(context) = 512; - DX_reg(context) = 0; - DOS_ERROR( ER_InvalidDrive, EC_MediaError, SA_Abort, EL_Disk ); - return; - } - - if (!DOS_GetFreeSpace(drive, &size, &available)) - { - DOS_ERROR( ER_GeneralFailure, EC_MediaError, SA_Abort, EL_Disk ); - AX_reg(context) = 0xffff; - return; - } - - AX_reg(context) = (drive < 2) ? 1 : 64; /* 64 for hard-disks, 1 for diskettes */ - CX_reg(context) = 512; - DX_reg(context) = (size / (CX_reg(context) * AX_reg(context))); - - heap->mediaID = 0xf0; - - DS_reg(context) = DosHeapHandle; - BX_reg(context) = (int)&heap->mediaID - (int)heap; - Error (0,0,0); + if (!INT21_GetFreeDiskSpace( context )) return 0; + heap->mediaID = 0xf0; + DS_reg(context) = DosHeapHandle; + BX_reg(context) = (int)&heap->mediaID - (int)heap; + return 1; } static void GetDrivePB(struct sigcontext_struct *context, int drive) @@ -242,40 +205,15 @@ static void GetDrivePB(struct sigcontext_struct *context, int drive) static void ioctlGetDeviceInfo(struct sigcontext_struct *context) { - - dprintf_int (stddeb, "int21: ioctl (%d, GetDeviceInfo)\n", BX_reg(context)); - - switch (BX_reg(context)) - { - case 0: - case 1: - DX_reg(context) = 2; /* FIXME */ - break; - case 2: - DX_reg(context) = 0x80d0 | (1 << (BX_reg(context) != 0)); - RESET_CFLAG(context); - break; - - default: - { - struct stat sbuf; - - if (fstat(BX_reg(context), &sbuf) < 0) - { - INT_BARF( context, 0x21 ); - SET_CFLAG(context); - return; - } - - DX_reg(context) = 0x0943; - /* bits 0-5 are current drive - * bit 6 - file has NOT been written..FIXME: correct? - * bit 8 - generate int24 if no diskspace on write/ read past end of file - * bit 11 - media not removable - */ - } - } - RESET_CFLAG(context); + dprintf_int (stddeb, "int21: ioctl (%d, GetDeviceInfo)\n", BX_reg(context)); + + DX_reg(context) = 0x0942; + /* bits 0-5 are current drive + * bit 6 - file has NOT been written..FIXME: correct? + * bit 8 - generate int24 if no diskspace on write/ read past end of file + * bit 11 - media not removable + */ + RESET_CFLAG(context); } static void ioctlGenericBlkDevReq(struct sigcontext_struct *context) @@ -454,6 +392,7 @@ static void CloseFile(struct sigcontext_struct *context) void ExtendedOpenCreateFile(struct sigcontext_struct *context) { + BYTE action=DL_reg(context); dprintf_int(stddeb, "int21: extended open/create: file= %s \n", DOSFS_GetUnixFileName(PTR_SEG_OFF_TO_LIN(DS_reg(context),SI_reg(context)),FALSE)); /* Shuffle arguments to call OpenExistingFile */ @@ -466,7 +405,7 @@ void ExtendedOpenCreateFile(struct sigcontext_struct *context) dprintf_int(stddeb, "int21: extended open/create %s exists \n", DOSFS_GetUnixFileName(PTR_SEG_OFF_TO_LIN(DS_reg(context),SI_reg(context)),TRUE)); /* Now decide what do do */ - if ((DL_reg(context) & 0x0007)== 0) + if ((action & 0x07)== 0) { BX_reg(context) = AX_reg(context); CloseFile(context); @@ -476,7 +415,7 @@ void ExtendedOpenCreateFile(struct sigcontext_struct *context) dprintf_int(stddeb, "int21: extended open/create: failed because file exixts \n"); return; } - if ((DL_reg(context) & 0x0007)== 2) { + if ((action & 0x07)== 2) { /* Truncate it, but first check if opend for write */ if ((BL_reg(context) & 0x0007)== 0) { BX_reg(context) = AX_reg(context); @@ -516,9 +455,10 @@ void ExtendedOpenCreateFile(struct sigcontext_struct *context) } else /* file does not exist */ { + RESET_CFLAG(context); /* was set by OpenExistingFile(context) */ dprintf_int(stddeb, "int21: extended open/create %s dosen't exists \n", DOSFS_GetUnixFileName(PTR_SEG_OFF_TO_LIN(DS_reg(context),SI_reg(context)),FALSE)); - if ((DL_reg(context) & 0x00F0)== 0) { + if ((action & 0xF0)== 0) { CX_reg(context) = 0; SET_CFLAG(context); dprintf_int(stddeb, "int21: extended open/create: failed, file dosen't exist\n"); @@ -1102,11 +1042,11 @@ void DOS3Call( struct sigcontext_struct context ) case 0x1b: /* GET ALLOCATION INFORMATION FOR DEFAULT DRIVE */ DL_reg(&context) = 0; - GetDriveAllocInfo(&context); + if (!INT21_GetDriveAllocInfo(&context)) AX_reg(&context) = 0xffff; break; case 0x1c: /* GET ALLOCATION INFORMATION FOR SPECIFIC DRIVE */ - GetDriveAllocInfo(&context); + if (!INT21_GetDriveAllocInfo(&context)) AX_reg(&context) = 0xffff; break; case 0x1f: /* GET DRIVE PARAMETER BLOCK FOR DEFAULT DRIVE */ @@ -1205,7 +1145,7 @@ void DOS3Call( struct sigcontext_struct context ) break; case 0x36: /* GET FREE DISK SPACE */ - GetFreeDiskSpace(&context); + if (!INT21_GetFreeDiskSpace(&context)) AX_reg(&context) = 0xffff; break; case 0x38: /* GET COUNTRY-SPECIFIC INFORMATION */ @@ -1258,22 +1198,32 @@ void DOS3Call( struct sigcontext_struct context ) break; case 0x3f: /* "READ" - READ FROM FILE OR DEVICE */ - if ((AX_reg(&context) = _lread( BX_reg(&context), - PTR_SEG_OFF_TO_LIN( DS_reg(&context),DX_reg(&context) ), - CX_reg(&context))) == (WORD)HFILE_ERROR) { - AX_reg(&context) = DOS_ExtendedError; - SET_CFLAG(&context); + LONG result = _hread( BX_reg(&context), + PTR_SEG_OFF_TO_LIN( DS_reg(&context), + DX_reg(&context) ), + CX_reg(&context) ); + if (result == -1) + { + AX_reg(&context) = DOS_ExtendedError; + SET_CFLAG(&context); + } + else AX_reg(&context) = (WORD)result; } break; case 0x40: /* "WRITE" - WRITE TO FILE OR DEVICE */ - if ((AX_reg(&context) = _lwrite( BX_reg(&context), - PTR_SEG_OFF_TO_LIN( DS_reg(&context),DX_reg(&context) ), - CX_reg(&context))) == (WORD)HFILE_ERROR) { - AX_reg(&context) = DOS_ExtendedError; - SET_CFLAG(&context); + LONG result = _hwrite( BX_reg(&context), + PTR_SEG_OFF_TO_LIN( DS_reg(&context), + DX_reg(&context) ), + CX_reg(&context) ); + if (result == -1) + { + AX_reg(&context) = DOS_ExtendedError; + SET_CFLAG(&context); + } + else AX_reg(&context) = (WORD)result; } break; @@ -1680,12 +1630,12 @@ void DOS3Call( struct sigcontext_struct context ) } -void INT21_Init(void) +BOOL INT21_Init(void) { if ((DosHeapHandle = GlobalAlloc(GMEM_FIXED,sizeof(struct DosHeap))) == 0) { fprintf( stderr, "INT21_Init: Out of memory\n"); - exit(1); + return FALSE; } heap = (struct DosHeap *) GlobalLock(DosHeapHandle); @@ -1693,4 +1643,5 @@ void INT21_Init(void) dpbsegptr = MAKELONG( (int)&heap->dpb - (int)heap, DosHeapHandle ); heap->InDosFlag = 0; strcpy(heap->biosdate, "01/01/80"); + return TRUE; } diff --git a/miscemu/int2f.c b/miscemu/int2f.c index 7501c76720b..e8d0948ba7d 100644 --- a/miscemu/int2f.c +++ b/miscemu/int2f.c @@ -1,8 +1,11 @@ #include #include +#include #include #include "registers.h" +#include "ldt.h" #include "wine.h" +#include "drive.h" #include "msdos.h" #include "miscemu.h" #include "module.h" @@ -15,6 +18,7 @@ #define VXD_BASE 400 static void do_int2f_16(struct sigcontext_struct *context); +void do_mscdex(struct sigcontext_struct *context); /********************************************************************** * INT_Int2fHandler @@ -30,7 +34,7 @@ void INT_Int2fHandler( struct sigcontext_struct context ) break; case 0x15: /* mscdex */ - /* ignore requests */ + do_mscdex(&context); break; case 0x16: @@ -128,3 +132,50 @@ static void do_int2f_16(struct sigcontext_struct *context) INT_BARF( context, 0x2f ); } } + +void do_mscdex(struct sigcontext_struct *context) +{ + int drive, count; + char *p; + + switch(AL_reg(context)) + { + case 0x00: /* Installation check */ + /* Count the number of contiguous CDROM drives + */ + for (drive = count = 0; drive < MAX_DOS_DRIVES; drive++) + { + if (DRIVE_GetType(drive) == TYPE_CDROM) + { + while (DRIVE_GetType(drive + count) == TYPE_CDROM) count++; + break; + } + } + + BX_reg(context) = count; + CX_reg(context) = (drive < MAX_DOS_DRIVES) ? drive : 0; + break; + + case 0x0B: /* drive check */ + AX_reg(context) = (DRIVE_GetType(CX_reg(context)) == TYPE_CDROM); + BX_reg(context) = 0xADAD; + break; + + case 0x0C: /* get version */ + BX_reg(context) = 0x020a; + break; + + case 0x0D: /* get drive letters */ + p = PTR_SEG_OFF_TO_LIN(ES_reg(context), BX_reg(context)); + memset( p, 0, MAX_DOS_DRIVES ); + for (drive = 0; drive < MAX_DOS_DRIVES; drive++) + { + if (DRIVE_GetType(drive) == TYPE_CDROM) *p++ = drive; + } + break; + + default: + fprintf(stderr, "Unimplemented MSCDEX function 0x%02.2X.\n", AL_reg(context)); + break; + } +} diff --git a/multimedia/audio.c b/multimedia/audio.c index 4c968093691..ce8da4c32c2 100644 --- a/multimedia/audio.c +++ b/multimedia/audio.c @@ -321,7 +321,6 @@ static DWORD WAVE_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms) dprintf_mciwave(stddeb,"WAVE_mciPlay // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback); mciDriverNotify((HWND)LOWORD(lpParms->dwCallback), MCIWavDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL); - exit(0); } return 0; } diff --git a/multimedia/midi.c b/multimedia/midi.c index 00941155c36..c571c9c4ea4 100644 --- a/multimedia/midi.c +++ b/multimedia/midi.c @@ -485,7 +485,9 @@ static DWORD MIDI_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms) dprintf_midi(stddeb, "MIDI_mciPlay // MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback); mciDriverNotify((HWND)LOWORD(lpParms->dwCallback), MCIMidiDev[wDevID].wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL); +#if 0 exit(1); +#endif } return 0; #else diff --git a/objects/bitmap.c b/objects/bitmap.c index 7408f3b0d89..d534d5d7b66 100644 --- a/objects/bitmap.c +++ b/objects/bitmap.c @@ -75,8 +75,7 @@ static XImage *BITMAP_BmpToImage( BITMAP * bmp, void * bmpData ) /*********************************************************************** * CreateBitmap (GDI.48) */ -HBITMAP CreateBitmap( short width, short height, - BYTE planes, BYTE bpp, LPSTR bits ) +HBITMAP CreateBitmap( INT width, INT height, UINT planes, UINT bpp, LPVOID bits ) { BITMAPOBJ * bmpObjPtr; HBITMAP hbitmap; @@ -121,7 +120,7 @@ HBITMAP CreateBitmap( short width, short height, /*********************************************************************** * CreateCompatibleBitmap (GDI.51) */ -HBITMAP CreateCompatibleBitmap( HDC hdc, short width, short height ) +HBITMAP CreateCompatibleBitmap( HDC hdc, INT width, INT height ) { DC * dc; dprintf_gdi(stddeb, "CreateCompatibleBitmap: "NPFMT" %dx%d\n", @@ -134,7 +133,7 @@ HBITMAP CreateCompatibleBitmap( HDC hdc, short width, short height ) /*********************************************************************** * CreateBitmapIndirect (GDI.49) */ -HBITMAP CreateBitmapIndirect( BITMAP * bmp ) +HBITMAP CreateBitmapIndirect( const BITMAP * bmp ) { return CreateBitmap( bmp->bmWidth, bmp->bmHeight, bmp->bmPlanes, bmp->bmBitsPixel, PTR_SEG_TO_LIN( bmp->bmBits ) ); @@ -310,7 +309,7 @@ HBITMAP BITMAP_SelectObject( HDC hdc, DC * dc, HBITMAP hbitmap, /*********************************************************************** * CreateDiscardableBitmap (GDI.156) */ -HBITMAP CreateDiscardableBitmap(HDC hdc, short width, short height) +HBITMAP CreateDiscardableBitmap(HDC hdc, INT width, INT height) { dprintf_bitmap(stddeb,"CreateDiscardableBitmap("NPFMT", %d, %d); " "// call CreateCompatibleBitmap() for now!\n", diff --git a/objects/brush.c b/objects/brush.c index 1034c40af39..0bca76df60e 100644 --- a/objects/brush.c +++ b/objects/brush.c @@ -141,7 +141,7 @@ Pixmap BRUSH_DitherColor( DC *dc, COLORREF color ) /*********************************************************************** * CreateBrushIndirect (GDI.50) */ -HBRUSH CreateBrushIndirect( LOGBRUSH * brush ) +HBRUSH CreateBrushIndirect( const LOGBRUSH * brush ) { BRUSHOBJ * brushPtr; HBRUSH hbrush = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC ); @@ -155,7 +155,7 @@ HBRUSH CreateBrushIndirect( LOGBRUSH * brush ) /*********************************************************************** * CreateHatchBrush (GDI.58) */ -HBRUSH CreateHatchBrush( short style, COLORREF color ) +HBRUSH CreateHatchBrush( INT style, COLORREF color ) { LOGBRUSH logbrush = { BS_HATCHED, color, style }; dprintf_gdi(stddeb, "CreateHatchBrush: %d %06lx\n", style, color ); @@ -194,7 +194,7 @@ HBRUSH CreatePatternBrush( HBITMAP hbitmap ) /*********************************************************************** * CreateDIBPatternBrush (GDI.445) */ -HBRUSH CreateDIBPatternBrush( HANDLE hbitmap, WORD coloruse ) +HBRUSH CreateDIBPatternBrush( HGLOBAL hbitmap, UINT coloruse ) { LOGBRUSH logbrush = { BS_DIBPATTERN, coloruse, 0 }; BITMAPINFO *info, *newInfo; diff --git a/objects/cursoricon.c b/objects/cursoricon.c index 4098051b845..75258556af1 100644 --- a/objects/cursoricon.c +++ b/objects/cursoricon.c @@ -227,47 +227,22 @@ static BOOL CURSORICON_LoadDirEntry(HANDLE hInstance, SEGPTR name, /********************************************************************** - * CURSORICON_Load + * CURSORICON_LoadHandler * - * Load a cursor or icon. + * Create a cursor or icon from a resource. */ -static HANDLE CURSORICON_Load( HANDLE hInstance, SEGPTR name, int width, - int height, int colors, BOOL fCursor ) +static HANDLE CURSORICON_LoadHandler( HANDLE handle, HINSTANCE hInstance, + BOOL fCursor ) { - HANDLE handle, hAndBits, hXorBits; - HRSRC hRsrc; + HANDLE hAndBits, hXorBits; HDC hdc; int size, sizeAnd, sizeXor; POINT hotspot = { 0 ,0 }; BITMAPOBJ *bmpXor, *bmpAnd; BITMAPINFO *bmi, *pInfo; CURSORICONINFO *info; - CURSORICONDIRENTRY dirEntry; char *bits; - if (!hInstance) /* OEM cursor/icon */ - { - if (HIWORD(name)) /* Check for '#xxx' name */ - { - char *ptr = PTR_SEG_TO_LIN( name ); - if (ptr[0] != '#') return 0; - if (!(name = (SEGPTR)atoi( ptr + 1 ))) return 0; - } - return OBM_LoadCursorIcon( LOWORD(name), fCursor ); - } - - /* Find the best entry in the directory */ - - if (!CURSORICON_LoadDirEntry( hInstance, name, width, height, - colors, fCursor, &dirEntry )) return 0; - - /* Load the resource */ - - if (!(hRsrc = FindResource( hInstance, - MAKEINTRESOURCE( dirEntry.icon.wResId ), - fCursor ? RT_CURSOR : RT_ICON ))) return 0; - if (!(handle = LoadResource( hInstance, hRsrc ))) return 0; - if (fCursor) /* If cursor, get the hotspot */ { POINT *pt = (POINT *)LockResource( handle ); @@ -289,7 +264,6 @@ static HANDLE CURSORICON_Load( HANDLE hInstance, SEGPTR name, int width, if (pInfo->bmiHeader.biCompression != BI_RGB) { fprintf(stderr,"Unknown size for compressed icon bitmap.\n"); - FreeResource( handle ); free( pInfo ); return 0; } @@ -304,7 +278,6 @@ static HANDLE CURSORICON_Load( HANDLE hInstance, SEGPTR name, int width, { fprintf( stderr, "CURSORICON_Load: Unknown bitmap length %ld!\n", pInfo->bmiHeader.biSize ); - FreeResource( handle ); free( pInfo ); return 0; } @@ -313,7 +286,6 @@ static HANDLE CURSORICON_Load( HANDLE hInstance, SEGPTR name, int width, if (!(hdc = GetDC( 0 ))) { - FreeResource( handle ); free( pInfo ); return 0; } @@ -351,7 +323,6 @@ static HANDLE CURSORICON_Load( HANDLE hInstance, SEGPTR name, int width, hAndBits = CreateDIBitmap( hdc, &pInfo->bmiHeader, CBM_INIT, bits, pInfo, DIB_RGB_COLORS ); ReleaseDC( 0, hdc ); - FreeResource( handle ); /* Now create the CURSORICONINFO structure */ @@ -367,8 +338,10 @@ static HANDLE CURSORICON_Load( HANDLE hInstance, SEGPTR name, int width, DeleteObject( hAndBits ); return 0; } + /* Make it owned by the module */ - FarSetOwner( handle, (WORD)(DWORD)GetExePtr( hInstance ) ); + if (hInstance) FarSetOwner( handle, (WORD)(DWORD)GetExePtr(hInstance) ); + info = (CURSORICONINFO *)GlobalLock( handle ); info->ptHotSpot.x = hotspot.x; info->ptHotSpot.y = hotspot.y; @@ -388,6 +361,46 @@ static HANDLE CURSORICON_Load( HANDLE hInstance, SEGPTR name, int width, return handle; } +/********************************************************************** + * CURSORICON_Load + * + * Load a cursor or icon. + */ +static HANDLE CURSORICON_Load( HANDLE hInstance, SEGPTR name, int width, + int height, int colors, BOOL fCursor ) +{ + HANDLE handle,hRet; + HRSRC hRsrc; + CURSORICONDIRENTRY dirEntry; + + if (!hInstance) /* OEM cursor/icon */ + { + if (HIWORD(name)) /* Check for '#xxx' name */ + { + char *ptr = PTR_SEG_TO_LIN( name ); + if (ptr[0] != '#') return 0; + if (!(name = (SEGPTR)atoi( ptr + 1 ))) return 0; + } + return OBM_LoadCursorIcon( LOWORD(name), fCursor ); + } + + /* Find the best entry in the directory */ + + if (!CURSORICON_LoadDirEntry( hInstance, name, width, height, + colors, fCursor, &dirEntry )) return 0; + + /* Load the resource */ + + if (!(hRsrc = FindResource( hInstance, + MAKEINTRESOURCE( dirEntry.icon.wResId ), + fCursor ? RT_CURSOR : RT_ICON ))) return 0; + if (!(handle = LoadResource( hInstance, hRsrc ))) return 0; + + hRet = CURSORICON_LoadHandler( handle, hInstance, fCursor ); + FreeResource(handle); + return hRet; +} + /*********************************************************************** * CURSORICON_Copy @@ -485,8 +498,8 @@ HICON LoadIcon( HANDLE hInstance, SEGPTR name ) /*********************************************************************** * CreateCursor (USER.406) */ -HICON CreateCursor( HANDLE hInstance, INT xHotSpot, INT yHotSpot, - INT nWidth, INT nHeight, LPSTR lpANDbits, LPSTR lpXORbits) +HCURSOR CreateCursor( HINSTANCE hInstance, INT xHotSpot, INT yHotSpot, + INT nWidth, INT nHeight, LPVOID lpANDbits, LPVOID lpXORbits) { CURSORICONINFO info = { { xHotSpot, yHotSpot }, nWidth, nHeight, 0, 1, 1 }; @@ -540,21 +553,37 @@ HANDLE CreateCursorIconIndirect( HANDLE hInstance, CURSORICONINFO *info, /*********************************************************************** * CopyIcon (USER.368) */ +#ifdef WINELIB32 +HICON CopyIcon( HICON hIcon ) +{ + dprintf_icon( stddeb, "CopyIcon: "NPFMT"\n", hIcon ); + return CURSORICON_Copy( 0, hIcon ); +} +#else HICON CopyIcon( HANDLE hInstance, HICON hIcon ) { dprintf_icon( stddeb, "CopyIcon: "NPFMT" "NPFMT"\n", hInstance, hIcon ); return CURSORICON_Copy( hInstance, hIcon ); } +#endif /*********************************************************************** * CopyCursor (USER.369) */ +#ifdef WINELIB32 +HCURSOR CopyCursor( HCURSOR hCursor ) +{ + dprintf_cursor( stddeb, "CopyCursor: "NPFMT"\n", hCursor ); + return CURSORICON_Copy( 0, hCursor ); +} +#else HCURSOR CopyCursor( HANDLE hInstance, HCURSOR hCursor ) { dprintf_cursor( stddeb, "CopyCursor: "NPFMT" "NPFMT"\n", hInstance, hCursor ); return CURSORICON_Copy( hInstance, hCursor ); } +#endif /*********************************************************************** @@ -836,10 +865,11 @@ HCURSOR GetCursor(void) /*********************************************************************** * ClipCursor (USER.16) */ -void ClipCursor( RECT *rect ) +BOOL ClipCursor( RECT *rect ) { if (!rect) SetRectEmpty( &CURSOR_ClipRect ); else CopyRect( &CURSOR_ClipRect, rect ); + return TRUE; } @@ -880,8 +910,35 @@ void GetClipCursor( RECT *rect ) */ WORD GetIconID( HANDLE hResource, DWORD resType ) { - fprintf( stderr, "GetIconId("NPFMT",%ld): empty stub!\n", - hResource, resType ); + CURSORICONDIR *lpDir = LockResource(hResource); + + if (!lpDir || lpDir->idReserved || + ((lpDir->idType != 1) && (lpDir->idType != 2))) + { + dprintf_cursor(stddeb,"GetIconID: invalid resource directory\n"); + return 0; + } + + dprintf_cursor( stddeb, "GetIconID: hRes="NPFMT", entries=%i\n", + hResource, lpDir->idCount ); + + switch(resType) + { + case 1: /* cursor */ + { + CURSORDIRENTRY *entry = CURSORICON_FindBestCursor( lpDir, + SYSMETRICS_CXCURSOR, SYSMETRICS_CYCURSOR ); + return entry ? entry->wResId : 0; + } + case 3: /* icon */ + { + ICONDIRENTRY *entry = CURSORICON_FindBestIcon( lpDir, + SYSMETRICS_CXICON, SYSMETRICS_CYICON, + MIN( 16, 1 << screenDepth ) ); + return entry ? entry->wResId : 0; + } + } + fprintf( stderr, "GetIconID: invalid res type %ld\n", resType ); return 0; } @@ -891,7 +948,12 @@ WORD GetIconID( HANDLE hResource, DWORD resType ) */ HICON LoadIconHandler( HANDLE hResource, BOOL bNew ) { - fprintf( stderr, "LoadIconHandle("NPFMT",%d): empty stub!\n", - hResource, bNew ); - return 0; + dprintf_cursor(stddeb,"LoadIconHandler: hRes="NPFMT"\n",hResource); + + if( !bNew ) + { + fprintf(stdnimp,"LoadIconHandler: 2.xx resources are not supported\n"); + return 0; + } + return CURSORICON_LoadHandler( hResource, 0, FALSE); } diff --git a/objects/dc.c b/objects/dc.c index 68e7ff3bc20..27c1303d2a6 100644 --- a/objects/dc.c +++ b/objects/dc.c @@ -450,7 +450,7 @@ BOOL RestoreDC( HDC hdc, short level ) /*********************************************************************** * CreateDC (GDI.53) */ -HDC CreateDC( LPSTR driver, LPSTR device, LPSTR output, LPSTR initData ) +HDC CreateDC( LPCSTR driver, LPCSTR device, LPCSTR output, LPCSTR initData ) { DC * dc; HANDLE handle; diff --git a/objects/dib.c b/objects/dib.c index 3c020462f4f..26ef98ec858 100644 --- a/objects/dib.c +++ b/objects/dib.c @@ -774,7 +774,7 @@ int GetDIBits( HDC hdc, HBITMAP hbitmap, WORD startscan, WORD lines, * CreateDIBitmap (GDI.442) */ HBITMAP CreateDIBitmap( HDC hdc, BITMAPINFOHEADER * header, DWORD init, - LPSTR bits, BITMAPINFO * data, WORD coloruse ) + LPVOID bits, BITMAPINFO * data, UINT coloruse ) { HBITMAP handle; BOOL fColor; diff --git a/objects/font.c b/objects/font.c index b3df1a2160a..95c8332af96 100644 --- a/objects/font.c +++ b/objects/font.c @@ -3,8 +3,7 @@ * * Copyright 1993 Alexandre Julliard * -static char Copyright[] = "Copyright Alexandre Julliard, 1993"; -*/ + */ #include #include @@ -12,8 +11,8 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include #include "font.h" #include "metafile.h" -#include "wine.h" #include "callback.h" +#include "options.h" #include "xmalloc.h" #include "stddebug.h" #include "debug.h" @@ -65,17 +64,20 @@ BOOL FONT_Init( void ) LPSTR ptr; int i; - if( GetPrivateProfileString("fonts", NULL, "*", temp, sizeof(temp), WINE_INI) > 2 ) { + if (PROFILE_GetWineIniString( "fonts", NULL, "*", temp, sizeof(temp) ) > 2 ) + { for( ptr = temp, i = 1; strlen(ptr) != 0; ptr += strlen(ptr) + 1 ) if( strcmp( ptr, "default" ) ) FontNames[i++].window = xstrdup( ptr ); FontSize = i; - for( i = 1; i < FontSize; i++ ) { - GetPrivateProfileString("fonts", FontNames[i].window, "*", temp, sizeof(temp), WINE_INI); - FontNames[i].x11 = xstrdup( temp ); + for( i = 1; i < FontSize; i++ ) + { + PROFILE_GetWineIniString( "fonts", FontNames[i].window, "*", + temp, sizeof(temp) ); + FontNames[i].x11 = xstrdup( temp ); } - GetPrivateProfileString("fonts", "default", "*", temp, sizeof(temp), WINE_INI); + PROFILE_GetWineIniString( "fonts", "default", "*", temp, sizeof(temp) ); FontNames[0].x11 = xstrdup( temp ); } else { @@ -291,7 +293,7 @@ BOOL CreateScalableFontResource( UINT fHidden,LPSTR lpszResourceFile, /*********************************************************************** * CreateFontIndirect (GDI.57) */ -HFONT CreateFontIndirect( LOGFONT * font ) +HFONT CreateFontIndirect( const LOGFONT * font ) { FONTOBJ * fontPtr; HFONT hfont = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC ); @@ -307,10 +309,10 @@ HFONT CreateFontIndirect( LOGFONT * font ) /*********************************************************************** * CreateFont (GDI.56) */ -HFONT CreateFont( int height, int width, int esc, int orient, int weight, +HFONT CreateFont( INT height, INT width, INT esc, INT orient, INT weight, BYTE italic, BYTE underline, BYTE strikeout, BYTE charset, BYTE outpres, BYTE clippres, BYTE quality, BYTE pitch, - LPSTR name ) + LPCSTR name ) { LOGFONT logfont = { height, width, esc, orient, weight, italic, underline, strikeout, charset, outpres, clippres, quality, pitch, }; @@ -493,7 +495,7 @@ INT GetTextFace( HDC hdc, INT count, LPSTR name ) /*********************************************************************** * GetTextExtent (GDI.91) */ -DWORD GetTextExtent( HDC hdc, LPSTR str, short count ) +DWORD GetTextExtent( HDC hdc, LPCSTR str, short count ) { SIZE size; if (!GetTextExtentPoint( hdc, str, count, &size )) return 0; @@ -504,7 +506,7 @@ DWORD GetTextExtent( HDC hdc, LPSTR str, short count ) /*********************************************************************** * GetTextExtentPoint (GDI.471) */ -BOOL GetTextExtentPoint( HDC hdc, LPSTR str, short count, LPSIZE size ) +BOOL GetTextExtentPoint( HDC hdc, LPCSTR str, short count, LPSIZE size ) { int dir, ascent, descent; XCharStruct info; @@ -802,7 +804,7 @@ int EnumFonts(HDC hDC, LPSTR lpFaceName, FARPROC lpEnumFunc, LPSTR lpData) /************************************************************************* * EnumFontFamilies [GDI.330] */ -int EnumFontFamilies(HDC hDC, LPSTR lpszFamily, FARPROC lpEnumFunc, LPSTR lpData) +int EnumFontFamilies(HDC hDC, LPSTR lpszFamily, FONTENUMPROC lpEnumFunc, LPARAM lpData) { HANDLE hLog; HANDLE hMet; @@ -815,7 +817,7 @@ int EnumFontFamilies(HDC hDC, LPSTR lpszFamily, FARPROC lpEnumFunc, LPSTR lpData int nRet = 0; int i; - dprintf_font(stddeb,"EnumFontFamilies("NPFMT", %p, %08lx, %p)\n", + dprintf_font(stddeb,"EnumFontFamilies("NPFMT", %p, %08lx, %08lx)\n", hDC, lpszFamily, (DWORD)lpEnumFunc, lpData); if (lpEnumFunc == 0) return 0; hLog = GDI_HEAP_ALLOC( sizeof(ENUMLOGFONT) ); @@ -859,7 +861,7 @@ int EnumFontFamilies(HDC hDC, LPSTR lpszFamily, FARPROC lpEnumFunc, LPSTR lpData nRet = CallEnumFontFamProc( lpEnumFunc, GDI_HEAP_SEG_ADDR(hLog), GDI_HEAP_SEG_ADDR(hMet), - 0, (LONG)lpData ); + 0, lpData ); if (nRet == 0) { dprintf_font(stddeb,"EnumFontFamilies // EnumEnd requested by application !\n"); break; @@ -874,7 +876,7 @@ int EnumFontFamilies(HDC hDC, LPSTR lpszFamily, FARPROC lpEnumFunc, LPSTR lpData * GetRasterizerCaps [GDI.313] */ -BOOL GetRasterizerCaps(LPRASTERIZER_STATUS lprs, WORD cbNumBytes) +BOOL GetRasterizerCaps(LPRASTERIZER_STATUS lprs, UINT cbNumBytes) { /* This is not much more than a dummy */ RASTERIZER_STATUS rs; @@ -887,9 +889,8 @@ BOOL GetRasterizerCaps(LPRASTERIZER_STATUS lprs, WORD cbNumBytes) /************************************************************************* * GetKerningPairs [GDI.332] - * FIXME: The last parameter is actually LPKERNINGPAIR */ -int GetKerningPairs(WORD hDC,int cBufLen,LPVOID lpKerningPairs) +int GetKerningPairs(HDC hDC,int cBufLen,LPKERNINGPAIR lpKerningPairs) { /* Wine fonts are ugly and don't support kerning :) */ return 0; diff --git a/objects/palette.c b/objects/palette.c index f49f066b674..1945bdf1e23 100644 --- a/objects/palette.c +++ b/objects/palette.c @@ -142,10 +142,11 @@ BOOL ResizePalette(HPALETTE hPal, UINT cEntries) /*********************************************************************** * AnimatePalette (GDI.367) */ -void AnimatePalette(HPALETTE hPal, UINT StartIndex, UINT NumEntries, +BOOL AnimatePalette(HPALETTE hPal, UINT StartIndex, UINT NumEntries, LPPALETTEENTRY PaletteColors) { fprintf(stdnimp,"AnimatePalette: empty stub! \n"); + return TRUE; } /*********************************************************************** diff --git a/objects/pen.c b/objects/pen.c index adf02e62f5e..13c2f80a321 100644 --- a/objects/pen.c +++ b/objects/pen.c @@ -13,7 +13,7 @@ /*********************************************************************** * CreatePen (GDI.61) */ -HPEN CreatePen( short style, short width, COLORREF color ) +HPEN CreatePen( INT style, INT width, COLORREF color ) { LOGPEN logpen = { style, { width, 0 }, color }; dprintf_gdi(stddeb, "CreatePen: %d %d %06lx\n", style, width, color ); diff --git a/objects/region.c b/objects/region.c index 73adc51a825..13b37995d97 100644 --- a/objects/region.c +++ b/objects/region.c @@ -220,7 +220,7 @@ HRGN CreateRoundRectRgn( short left, short top, short right, short bottom, /*********************************************************************** * CreateEllipticRgn (GDI.54) */ -HRGN CreateEllipticRgn( short left, short top, short right, short bottom ) +HRGN CreateEllipticRgn( INT left, INT top, INT right, INT bottom ) { return CreateRoundRectRgn( left, top, right, bottom, right-left, bottom-top ); @@ -402,7 +402,7 @@ BOOL REGION_FrameRgn( HRGN hDest, HRGN hSrc, int x, int y ) /*********************************************************************** * CombineRgn (GDI.451) */ -int CombineRgn( HRGN hDest, HRGN hSrc1, HRGN hSrc2, short mode ) +INT CombineRgn( HRGN hDest, HRGN hSrc1, HRGN hSrc2, INT mode ) { RGNOBJ *destObj, *src1Obj, *src2Obj; diff --git a/objects/text.c b/objects/text.c index 3b6ec2240b1..6b4f8e63569 100644 --- a/objects/text.c +++ b/objects/text.c @@ -3,8 +3,8 @@ * * Copyright 1993, 1994 Alexandre Julliard * -static char Copyright[] = "Copyright Alexandre Julliard, 1993, 1994"; -*/ + */ + #include #include #include "windows.h" @@ -31,8 +31,8 @@ static int spacewidth; static int prefix_offset; -static char *TEXT_NextLine(HDC hdc, char *str, int *count, char *dest, - int *len, int width, WORD format) +static const char *TEXT_NextLine( HDC hdc, const char *str, int *count, + char *dest, int *len, int width, WORD format) { /* Return next line of text from a string. * @@ -184,10 +184,10 @@ static char *TEXT_NextLine(HDC hdc, char *str, int *count, char *dest, /*********************************************************************** * DrawText (USER.85) */ -int DrawText( HDC hdc, LPSTR str, int count, LPRECT rect, WORD flags ) +int DrawText( HDC hdc, LPCSTR str, int count, LPRECT rect, WORD flags ) { SIZE size; - char *strPtr; + const char *strPtr; static char line[1024]; int len, lh; int prefix_x = 0; diff --git a/rc/winerc.c b/rc/winerc.c index f5ec38074bd..7642ff2aed0 100644 --- a/rc/winerc.c +++ b/rc/winerc.c @@ -4,6 +4,7 @@ * */ +#include #include #include #include @@ -53,6 +54,7 @@ int main(int argc,char *argv[]) { extern int yydebug; extern char* optarg; + char* tmpc; int optc,lose,ret,binary; lose=binary=0; while((optc=getopt(argc,argv,"bcdp:vo:"))!=EOF) @@ -65,7 +67,12 @@ int main(int argc,char *argv[]) setbuf(stdout,0); setbuf(stderr,0); break; - case 'p':prefix=optarg;break; + case 'p':prefix=strdup(optarg); + if(!isalpha(*prefix))*prefix='_'; + for(tmpc=prefix;*tmpc;tmpc++) + if( !isalnum(*tmpc) && *tmpc!='_') + *tmpc='_'; + break; case 'c':constant=1;break; case 'v':verbose=1; setbuf(stderr,0); @@ -105,7 +112,7 @@ int transform_binary_file() if(i%16==0)fputc('\n',code); fprintf(code,"%3d,",c); } - fprintf(code,"\n0}\nint _Aplication_resources_size=%d;\n",i); + fprintf(code,"\n 0};\nint _Application_resources_size=%d;\n",i); return 0; } diff --git a/tools/makehtml.pl b/tools/makehtml.pl new file mode 100644 index 00000000000..cfd8408c461 --- /dev/null +++ b/tools/makehtml.pl @@ -0,0 +1,80 @@ +#!/usr/bin/perl +open(APIW,"./apiw.index"); +while() +{ + ($func,$link)=split /:/; + chop $link; + $link=~m/(\d*)/; + $apiw{$func}="http://www.willows.com/apiw/chapter$1/p$link.html"; +} +close(APIW); + +open(WINDOWS,"../include/windows.h"); +while() { add_func($_) if /AccessResource/../wvsprintf/; } +close(WINDOWS); +open(TOOLHELP,"../include/toolhelp.h"); +while() { add_func($_) if /GlobalInfo/../MemoryWrite/; } +close(TOOLHELP); +open(COMMDLG,"../include/commdlg.h"); +while() { add_func($_) if /ChooseColor/../ReplaceText/; } +close(COMMDLG); + +print "\n"; + +print "

Windows API Functions

\n"; +print "The following API functions were found by searching windows.h,\n"; +print "toolhelp.h, and commdlg.h. Where possible, help links pointing\n"; +print "to www.willows.com are included.

\n"; +print "\n"; +print "\n"; +foreach $func (sort(keys %funcs)) +{ + $funcs{$func}=~m/(.*) +(\w*)(\(.*)/; + print "\n\n"; + print "\n"; + print "\n"; + print "\n"; + print "\n"; +} +print "
Help-linkFunction
"; + if($apiw{$2}) + { + print "
APIW
"; + $impl{$2}=1; + $impl++; + } + $numfuncs++; + print "
$1$2$3

\n"; +print "(Approximately ",sprintf("%3.1f",$impl/(1.0*$numfuncs)*100.0), + "% of the functions above are in the APIW standard.)

\n"; + +print "


\n"; +print "

Unimplemented APIW functions

\n"; +print "Here's a list of the API functions in the APIW standard which were not found\n"; +print "in windows.h, commdlg.h, or toolhelp.h:

\n"; +foreach $func (sort (keys %apiw)) +{ + if(!$impl{$func}) + { + print "$func\n"; + $unimpl++; + } + $numapiw++; +} +print "

(This comprises approximately ",sprintf("%3.1f",$unimpl/(1.0*$numapiw)*100.0), + "% of the APIW.)\n"; + +print "\n"; + +sub add_func +{ + $line=shift; + chop $line; + $line=~s/\s+/ /g; + ($func)=$line=~m/ (\w*)\(/; + if($func) + { + while($funcs{$func}) { $func.=" "; } + $funcs{$func}=$line; + } +} diff --git a/win32/Makefile.in b/win32/Makefile.in index 9851ec68166..2300885422c 100644 --- a/win32/Makefile.in +++ b/win32/Makefile.in @@ -13,10 +13,13 @@ C_SRCS = \ memory.c \ newfns.c \ object_mgt.c \ + param32.c \ process.c \ resource.c \ + string32.c \ thread.c \ time.c \ + user32.c \ winprocs.c all: $(MODULE).o diff --git a/win32/newfns.c b/win32/newfns.c index 2f2fe449d78..0192cb0f6b6 100644 --- a/win32/newfns.c +++ b/win32/newfns.c @@ -8,6 +8,7 @@ at a later date. */ #include +#include "module.h" #include "windows.h" #include "winerror.h" #include "kernel32.h" @@ -31,6 +32,7 @@ WINAPI VOID RaiseException(DWORD dwExceptionCode, * GetProcAddress (KERNEL32.257) * */ + /* FIXME: This is currently not used, see WIN32_GetProcAddress */ WINAPI FARPROC W32_GetProcAddress(HMODULE hModule, LPCSTR lpszProc) { @@ -45,3 +47,12 @@ WINAPI FARPROC W32_GetProcAddress(HMODULE hModule, return RELAY32_GetEntryPoint(modulename, (char *) NULL, (int) lpszProc); } +/*********************************************************************** + * WinHelpA (USER32.578) + */ +BOOL WIN32_WinHelpA(HWND hWnd,LPCSTR lpszHelp,UINT uCommand, DWORD dwData) +{ + /* Should do parameter conversion here, but WinHelp is not working, + anyways */ + return WinHelp(hWnd,lpszHelp,uCommand,dwData); +} diff --git a/win32/param32.c b/win32/param32.c new file mode 100644 index 00000000000..d2c10f2ef80 --- /dev/null +++ b/win32/param32.c @@ -0,0 +1,30 @@ +/* + * Win32 relay functions + * The implementations here perform only parameter conversions, and + * call the Win16 counterparts + * + * Copyright 1996 Martin von Loewis + */ + +#include +#include "windows.h" +#include "winerror.h" +#include "struct32.h" +#include "stddebug.h" +#include "debug.h" + +void PARAM32_POINT32to16(const POINT32* p32,POINT* p16) +{ + p16->x = p32->x; + p16->y = p32->y; +} + +/**************************************************************** + * MoveToEx (GDI32.254) + */ +BOOL WIN32_MoveToEx(HDC hdc,int x,int y,POINT32* p32) +{ + POINT p; + PARAM32_POINT32to16(p32,&p); + return MoveToEx(hdc,x,y,&p); +} diff --git a/win32/process.c b/win32/process.c index b8e244db9aa..a7a86c82209 100644 --- a/win32/process.c +++ b/win32/process.c @@ -5,6 +5,7 @@ */ #include +#include #include #include "windows.h" #include "winerror.h" diff --git a/win32/resource.c b/win32/resource.c index 5add4406039..2e2dd751c27 100644 --- a/win32/resource.c +++ b/win32/resource.c @@ -2,6 +2,7 @@ * Win32 Resources * * Copyright 1995 Thomas Sandford + * Copyright 1996 Martin von Loewis * * Based on the Win16 resource handling code in loader/resource.c * Copyright 1993 Robert J. Amstadt @@ -16,10 +17,13 @@ #include "kernel32.h" #include "pe_image.h" #include "handle32.h" +#include "libres.h" #include "resource32.h" +#include "stackframe.h" #include "neexe.h" #include "accel.h" #include "xmalloc.h" +#include "string32.h" #include "stddebug.h" #include "debug.h" @@ -38,19 +42,31 @@ int language = 0x0409; * */ PIMAGE_RESOURCE_DIRECTORY GetResDirEntry(PIMAGE_RESOURCE_DIRECTORY resdirptr, - LPCSTR name, + LPCWSTR name, DWORD root) { int entrynum; PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable; + int namelen; if (HIWORD(name)) { /* FIXME: what about #xxx names? */ entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ( (BYTE *) resdirptr + sizeof(IMAGE_RESOURCE_DIRECTORY)); + namelen = STRING32_lstrlenW(name); for (entrynum = 0; entrynum < resdirptr->NumberOfNamedEntries; entrynum++) - /* do what??? */ ; + { + PIMAGE_RESOURCE_DIR_STRING_U str = + (PIMAGE_RESOURCE_DIR_STRING_U) (root + + (entryTable[entrynum].Name & 0x7fffffff)); + if(namelen != str->Length) + continue; + if(STRING32_lstrcmpniW(name,str->NameString,str->Length)==0) + return (PIMAGE_RESOURCE_DIRECTORY) ( + root + + (entryTable[entrynum].OffsetToData & 0x7fffffff)); + } return NULL; } else { entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ( @@ -200,11 +216,11 @@ DWORD SizeofResource32( HINSTANCE hModule, HRSRC hRsrc ) /********************************************************************** * LoadAccelerators [USER.177] */ -HANDLE LoadAccelerators32(HINSTANCE instance, LPCTSTR lpTableName) +HANDLE32 WIN32_LoadAcceleratorsW(HINSTANCE instance, LPCWSTR lpTableName) { - HANDLE hAccel; - HANDLE rsc_mem; - HRSRC hRsrc; + HANDLE32 hAccel; + HANDLE32 rsc_mem; + HANDLE32 hRsrc; BYTE *lp; ACCELHEADER *lpAccelTbl; int i, n; @@ -216,11 +232,11 @@ HANDLE LoadAccelerators32(HINSTANCE instance, LPCTSTR lpTableName) dprintf_accel( stddeb, "LoadAccelerators: "NPFMT" %04x\n", instance, LOWORD(lpTableName) ); - if (!(hRsrc = FindResource( instance, lpTableName, RT_ACCELERATOR ))) + if (!(hRsrc = FindResource32( instance, lpTableName, RT_ACCELERATOR ))) return 0; - if (!(rsc_mem = LoadResource( instance, hRsrc ))) return 0; + if (!(rsc_mem = LoadResource32( instance, hRsrc ))) return 0; - lp = (BYTE *)LockResource(rsc_mem); + lp = (BYTE *)LockResource32(rsc_mem); n = SizeofResource( instance, hRsrc ) / sizeof(ACCELENTRY); hAccel = GlobalAlloc(GMEM_MOVEABLE, sizeof(ACCELHEADER) + (n + 1)*sizeof(ACCELENTRY)); @@ -243,12 +259,20 @@ HANDLE LoadAccelerators32(HINSTANCE instance, LPCTSTR lpTableName) FreeResource( rsc_mem ); return hAccel; } + +HANDLE32 WIN32_LoadAcceleratorsA(HINSTANCE instance, LPCSTR lpTableName) +{ + LPWSTR uni=STRING32_DupAnsiToUni(lpTableName); + HANDLE32 result=WIN32_LoadAcceleratorsW(instance,uni); + free(uni); + return result; +} /********************************************************************** * LoadString */ int -LoadString32(HINSTANCE instance, DWORD resource_id, LPTSTR buffer, int buflen) +WIN32_LoadStringW(HINSTANCE instance, DWORD resource_id, LPWSTR buffer, int buflen) { HANDLE32 hmem, hrsrc; WCHAR *p; @@ -292,10 +316,10 @@ LoadString32(HINSTANCE instance, DWORD resource_id, LPTSTR buffer, int buflen) * LoadStringA */ int -LoadStringA32(HINSTANCE instance, DWORD resource_id, LPSTR buffer, int buflen) +WIN32_LoadStringA(HINSTANCE instance, DWORD resource_id, LPSTR buffer, int buflen) { WCHAR *buffer2 = xmalloc(buflen*2); - int retval = LoadString32(instance, resource_id, buffer2, buflen); + int retval = WIN32_LoadStringW(instance, resource_id, buffer2, buflen); while (*buffer2) *buffer++ = (char) *buffer2++; @@ -317,7 +341,7 @@ HICON LoadIconA32(HINSTANCE hinst, LPCTSTR lpszIcon) /********************************************************************** * LoadBitmapW */ -HBITMAP LoadBitmapW32( HANDLE instance, LPCTSTR name ) +HBITMAP WIN32_LoadBitmapW( HANDLE instance, LPCTSTR name ) { HBITMAP hbitmap = 0; HDC hdc; @@ -347,7 +371,105 @@ HBITMAP LoadBitmapW32( HANDLE instance, LPCTSTR name ) /********************************************************************** * LoadBitmapA */ -HBITMAP LoadBitmapA32( HANDLE instance, LPCTSTR name ) +HBITMAP WIN32_LoadBitmapA( HANDLE instance, LPCTSTR name ) { - return LoadBitmapW32(instance, name); + HBITMAP res; + if(!HIWORD(name)) + res = WIN32_LoadBitmapW(instance,name); + else{ + LPWSTR uni=STRING32_DupAnsiToUni(name); + res=WIN32_LoadBitmapW(instance,uni); + free(uni); + } + return res; +} + +/********************************************************************** + * WIN32_ParseMenu + * LoadMenu helper function + */ +BYTE* WIN32_ParseMenu(HMENU hMenu,BYTE *it) +{ + char entry[200]; /* buffer for ANSI names */ + int bufsize=100; + int len; + WORD flags; + WORD wMenuID; + WCHAR *utext; + do{ + flags=*(WORD*)it; + it+=sizeof(WORD); + /* POPUP entries have no ID, but a sub menu */ + if(flags & MF_POPUP) + { + wMenuID = CreatePopupMenu(); + len = STRING32_lstrlenW(it); + utext = it; + it += sizeof(WCHAR)*(len+1); + it = WIN32_ParseMenu(wMenuID,it); + } else { + wMenuID=*(WORD*)it; + it+=sizeof(WORD); + utext = it; + len = STRING32_lstrlenW(it); + it += sizeof(WCHAR)*(len+1); + if(!wMenuID && !*utext) + flags |= MF_SEPARATOR; + } + if(len>=bufsize) continue; /* hack hack */ + STRING32_UniToAnsi(entry,utext); + AppendMenu(hMenu,flags,wMenuID,MAKE_SEGPTR(entry)); + }while(!(flags & MF_END)); + return it; +} + +/***************************************************************** + * LoadMenuIndirectW (USER32.371) + */ +HMENU WIN32_LoadMenuIndirectW(void *menu) +{ + BYTE *it=menu; + HMENU hMenu = CreateMenu(); + /*skip menu header*/ + if(*(DWORD*)it) + fprintf(stderr,"Unknown menu header\n"); + it+=2*sizeof(WORD); + WIN32_ParseMenu(hMenu,it); + return hMenu; +} + +/***************************************************************** + * LoadMenuW (USER32.372) + */ +HMENU WIN32_LoadMenuW(HANDLE instance, LPCWSTR name) +{ + HANDLE32 hrsrc; + hrsrc=FindResource32(instance,name,RT_MENU); + if(!hrsrc)return 0; + return WIN32_LoadMenuIndirectW(LoadResource32(instance, hrsrc)); +} + +/***************************************************************** + * LoadMenuIndirectA (USER32.370) + */ +HMENU WIN32_LoadMenuIndirectA(void *menu) +{ + fprintf(stderr,"WIN32_LoadMenuIndirectA not implemented\n"); + return 0; +} + +/***************************************************************** + * LoadMenuA (USER32.370) + */ +HMENU WIN32_LoadMenuA(HANDLE instance,LPCSTR name) +{ + HMENU res; + if(!HIWORD(name)) + res = WIN32_LoadMenuW(instance,name); + else{ + LPWSTR uni=STRING32_DupAnsiToUni(name); + res=WIN32_LoadMenuW(instance,uni); + free(uni); + } + return res; } diff --git a/win32/string32.c b/win32/string32.c new file mode 100644 index 00000000000..e9af8cbe78f --- /dev/null +++ b/win32/string32.c @@ -0,0 +1,94 @@ +/* + * Unicode string management + * + * Copyright 1996 Martin von Loewis + * + * Conversion between Unicode and ISO-8859-1 is inherently lossy, + * so the conversion code should be called only if it does not matter + * + */ + +#include +#include +#include +#include "string32.h" +#include "xmalloc.h" + +int STRING32_UniLen(LPWSTR s) +{ + int i; + for(i=0;*s;s++); + i++; + return i; +} + +void STRING32_UniToAnsi(LPSTR dest,LPCWSTR src) +{ + static int have_warned=0; + while(*src) + { + if(*src>255 && !have_warned) + { + fprintf(stderr,"Cannot deal with non-ANSI characters\n"); + have_warned=1; + } + *dest++=*src++; + } + /* copy the terminator */ + *dest = *src; +} + +void STRING32_AnsiToUni(LPWSTR dest,LPCSTR src) +{ + while(*src) + *dest++=*src++; + *dest = *src; +} + +LPSTR STRING32_DupUniToAnsi(LPWSTR src) +{ + LPSTR dest=xmalloc(STRING32_UniLen(src)+1); + STRING32_UniToAnsi(dest,src); + return dest; +} + +LPWSTR STRING32_DupAnsiToUni(LPSTR src) +{ + LPWSTR dest=xmalloc(2*strlen(src)+2); + STRING32_AnsiToUni(dest,src); + return dest; +} + +DWORD STRING32_lstrlenW(LPCWSTR str) +{ + int len; + for(len=0;*str;str++) + len++; + return len; +} + +/* not an API function */ + +WCHAR STRING32_tolowerW(WCHAR c) +{ + /* FIXME: Unicode */ + return tolower(c); +} + +LPWSTR STRING32_lstrcmpniW(LPCWSTR a,LPCWSTR b,DWORD len) +{ + while(len--) + { + WCHAR c1,c2; + c1 = STRING32_tolowerW(*a); + c2 = STRING32_tolowerW(*b); + if(c1c2)return 1; + if(c1==0 && c2==0)return 0; + if(c1==0)return -1; + if(c2==0)return 1; + a++; + b++; + } + return 0; +} diff --git a/misc/user32.c b/win32/user32.c similarity index 81% rename from misc/user32.c rename to win32/user32.c index 5097b8c231b..d3b2a4c0161 100644 --- a/misc/user32.c +++ b/win32/user32.c @@ -14,6 +14,7 @@ #include "alias.h" #include "stackframe.h" #include "xmalloc.h" +#include "struct32.h" /* Structure copy functions */ static void MSG16to32(MSG *msg16,struct WIN32_MSG *msg32) @@ -38,6 +39,22 @@ static void MSG32to16(struct WIN32_MSG *msg32,MSG *msg16) msg16->pt.y=msg32->pt.y; } +void USER32_RECT32to16(const RECT32* r32,RECT *r16) +{ + r16->left = r32->left; + r16->right = r32->right; + r16->top = r32->top; + r16->bottom = r32->bottom; +} + +void USER32_RECT16to32(const RECT* r16,RECT32 *r32) +{ + r32->left = r16->left; + r32->right = r16->right; + r32->top = r16->top; + r32->bottom = r16->bottom; +} + /*********************************************************************** * RegisterClassA (USER32.426) */ @@ -195,3 +212,38 @@ DWORD USER32_CreateWindowExA(long flags,char* class,char *title, GlobalFree(titleh); return retval; } + +/*********************************************************************** + * InvalidateRect (USER32.327) + */ +BOOL USER32_InvalidateRect(HWND hWnd,const RECT32 *lpRect,BOOL bErase) +{ + RECT r; + USER32_RECT32to16(lpRect,&r); + InvalidateRect(hWnd,&r,bErase); + /* FIXME: Return value */ + return 0; +} + +/*********************************************************************** + * DrawTextA (USER32.163) + */ +int USER32_DrawTextA(HDC hdc,LPCSTR lpStr,int count,RECT32* r32,UINT uFormat) +{ + RECT r; + USER32_RECT32to16(r32,&r); + return DrawText(hdc,lpStr,count,&r,uFormat); +} + +/*********************************************************************** + * GetClientRect (USER32.219) + */ +BOOL USER32_GetClientRect(HWND hwnd,RECT32 *r32) +{ + RECT r; + GetClientRect(hwnd,&r); + USER32_RECT16to32(&r,r32); + /* FIXME: return value */ + return 0; +} + diff --git a/win32/winprocs.c b/win32/winprocs.c index 1d9d5a232ae..9b2d364752c 100644 --- a/win32/winprocs.c +++ b/win32/winprocs.c @@ -8,6 +8,9 @@ #include #include "windows.h" + +#ifndef WINELIB32 + #include "winerror.h" #include "kernel32.h" #include "wincon.h" @@ -32,6 +35,25 @@ BOOL UsesLParamPtr(DWORD message) } } +extern LRESULT AboutDlgProc(HWND,UINT,WPARAM,LPARAM); +extern LRESULT ButtonWndProc(HWND,UINT,WPARAM,LPARAM); +extern LRESULT ColorDlgProc(HWND,UINT,WPARAM,LPARAM); +extern LRESULT ComboBoxWndProc(HWND,UINT,WPARAM,LPARAM); +extern LRESULT DesktopWndProc(HWND,UINT,WPARAM,LPARAM); +extern LRESULT EditWndProc(HWND,UINT,WPARAM,LPARAM); +extern LRESULT FileOpenDlgProc(HWND,UINT,WPARAM,LPARAM); +extern LRESULT FileSaveDlgProc(HWND,UINT,WPARAM,LPARAM); +extern LRESULT FindTextDlgProc(HWND,UINT,WPARAM,LPARAM); +extern LRESULT ListBoxWndProc(HWND,UINT,WPARAM,LPARAM); +extern LRESULT MDIClientWndProc(HWND,UINT,WPARAM,LPARAM); +extern LRESULT PopupMenuWndProc(HWND,UINT,WPARAM,LPARAM); +extern LRESULT PrintDlgProc(HWND,UINT,WPARAM,LPARAM); +extern LRESULT PrintSetupDlgProc(HWND,UINT,WPARAM,LPARAM); +extern LRESULT ReplaceTextDlgProc(HWND,UINT,WPARAM,LPARAM); +extern LRESULT ScrollBarWndProc(HWND,UINT,WPARAM,LPARAM); +extern LRESULT StaticWndProc(HWND,UINT,WPARAM,LPARAM); +extern LRESULT SystemMessageBoxProc(HWND,UINT,WPARAM,LPARAM); + LRESULT USER32_DefWindowProcA(DWORD hwnd, DWORD msg, DWORD wParam, DWORD lParam) { @@ -238,4 +260,4 @@ LRESULT ComboLBoxWndProc32(DWORD hwnd, DWORD msg, DWORD wParam, DWORD lParam) else return ComboLBoxWndProc((HWND)hwnd, msg, wParam, lParam); } - +#endif diff --git a/windows/alias.c b/windows/alias.c index 59d25ce02de..df873193fb0 100644 --- a/windows/alias.c +++ b/windows/alias.c @@ -48,17 +48,17 @@ void ALIAS_RegisterAlias(DWORD Wine,DWORD Win16, DWORD Win32) if (Wine) { whash=ALIAS_LocateHash(Wine); - recno=AliasTable[whash].used?AliasTable[whash].used:0; + recno=AliasTable[whash].used?AliasTable[whash].recno:0; } if (Win16) { w16hash=ALIAS_LocateHash(Win16); - recno=AliasTable[w16hash].used?AliasTable[w16hash].used:0; + recno=AliasTable[w16hash].used?AliasTable[w16hash].recno:0; } if (Win32) { w32hash=ALIAS_LocateHash(Win32); - recno=AliasTable[w32hash].used?AliasTable[w32hash].used:0; + recno=AliasTable[w32hash].used?AliasTable[w32hash].recno:0; } if (!recno) { diff --git a/windows/caret.c b/windows/caret.c index 8cf00ca769d..983cdee32fe 100644 --- a/windows/caret.c +++ b/windows/caret.c @@ -54,7 +54,7 @@ WORD CARET_Callback(HWND hwnd, WORD msg, WORD timerid, LONG ctime) else hBrush = CreatePatternBrush(Caret.bitmap); SelectObject(hdc, (HANDLE)hBrush); - SetROP2(hdc, R2_XORPEN); + SetROP2(hdc, R2_NOTXORPEN); rgn = CreateRectRgn(Caret.x, Caret.y, Caret.x + Caret.width, Caret.y + Caret.height); @@ -116,9 +116,9 @@ static void CARET_Initialize() * CreateCaret (USER.163) */ -void CreateCaret(HWND hwnd, HBITMAP bitmap, short width, short height) +BOOL CreateCaret(HWND hwnd, HBITMAP bitmap, INT width, INT height) { - if (!hwnd) return; + if (!hwnd) return FALSE; /* if cursor already exists, destroy it */ @@ -157,6 +157,7 @@ void CreateCaret(HWND hwnd, HBITMAP bitmap, short width, short height) dprintf_caret(stddeb,"CreateCaret: hwnd="NPFMT", timerid=%d\n", hwnd, Caret.timerid); + return TRUE; } diff --git a/windows/defdlg.c b/windows/defdlg.c index 4f152fb8301..90a0a6d5be1 100644 --- a/windows/defdlg.c +++ b/windows/defdlg.c @@ -122,9 +122,6 @@ LRESULT DefDlgProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) if (!wndPtr) return 0; dlgInfo = (DIALOGINFO *)&wndPtr->wExtra; - dprintf_dialog(stddeb, "DefDlgProc: "NPFMT" %04x %ld %08lx\n", - hwnd, msg, (DWORD)wParam, lParam ); - dlgInfo->msgResult = 0; if (dlgInfo->dlgProc) { diff --git a/windows/defwnd.c b/windows/defwnd.c index 42aad583b46..21acb8db3d7 100644 --- a/windows/defwnd.c +++ b/windows/defwnd.c @@ -138,15 +138,27 @@ LRESULT DefWindowProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) case WM_WINDOWPOSCHANGED: { + /* Note: Windoze uses unknown SWP flags 0x1000 and 0x0800 to + * decide whether to send WM_MOVE or/and WM_SIZE respectively + */ + WINDOWPOS * winPos = (WINDOWPOS *)PTR_SEG_TO_LIN(lParam); + WPARAM wp = SIZE_RESTORED; + if (!(winPos->flags & SWP_NOMOVE)) SendMessage( hwnd, WM_MOVE, 0, MAKELONG( wndPtr->rectClient.left, wndPtr->rectClient.top )); if (!(winPos->flags & SWP_NOSIZE)) - SendMessage( hwnd, WM_SIZE, SIZE_RESTORED, - MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left, - wndPtr->rectClient.bottom-wndPtr->rectClient.top)); + { + if( wndPtr->dwStyle & WS_MAXIMIZE ) wp = SIZE_MAXIMIZED; + else if(wndPtr->dwStyle & WS_MINIMIZE ) wp = SIZE_MINIMIZED; + + SendMessage( hwnd, WM_SIZE, wp, + MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left, + wndPtr->rectClient.bottom-wndPtr->rectClient.top)); + + } return 0; } diff --git a/windows/dialog.c b/windows/dialog.c index 1ed5fe1d733..8a982b4e3b6 100644 --- a/windows/dialog.c +++ b/windows/dialog.c @@ -201,7 +201,7 @@ static void DIALOG_DisplayTemplate( DLGTEMPLATE * result ) * CreateDialog (USER.89) */ HWND CreateDialog( HINSTANCE hInst, SEGPTR dlgTemplate, - HWND owner, WNDPROC dlgProc ) + HWND owner, DLGPROC dlgProc ) { return CreateDialogParam( hInst, dlgTemplate, owner, dlgProc, 0 ); } @@ -211,7 +211,7 @@ HWND CreateDialog( HINSTANCE hInst, SEGPTR dlgTemplate, * CreateDialogParam (USER.241) */ HWND CreateDialogParam( HINSTANCE hInst, SEGPTR dlgTemplate, - HWND owner, WNDPROC dlgProc, LPARAM param ) + HWND owner, DLGPROC dlgProc, LPARAM param ) { HWND hwnd = 0; HRSRC hRsrc; @@ -234,7 +234,7 @@ HWND CreateDialogParam( HINSTANCE hInst, SEGPTR dlgTemplate, * CreateDialogIndirect (USER.219) */ HWND CreateDialogIndirect( HINSTANCE hInst, SEGPTR dlgTemplate, - HWND owner, WNDPROC dlgProc ) + HWND owner, DLGPROC dlgProc ) { return CreateDialogIndirectParam( hInst, dlgTemplate, owner, dlgProc, 0 ); } @@ -244,7 +244,7 @@ HWND CreateDialogIndirect( HINSTANCE hInst, SEGPTR dlgTemplate, * CreateDialogIndirectParam (USER.242) */ HWND CreateDialogIndirectParam( HINSTANCE hInst, SEGPTR dlgTemplate, - HWND owner, WNDPROC dlgProc, LPARAM param ) + HWND owner, DLGPROC dlgProc, LPARAM param ) { HMENU hMenu = 0; HFONT hFont = 0; @@ -789,9 +789,10 @@ WORD GetDlgItemInt( HWND hwnd, WORD id, BOOL * translated, BOOL fSigned ) /*********************************************************************** * CheckDlgButton (USER.97) */ -void CheckDlgButton( HWND hwnd, WORD id, WORD check ) +BOOL CheckDlgButton( HWND hwnd, INT id, UINT check ) { SendDlgItemMessage( hwnd, id, BM_SETCHECK, check, 0 ); + return TRUE; } @@ -807,28 +808,29 @@ WORD IsDlgButtonChecked( HWND hwnd, WORD id ) /*********************************************************************** * CheckRadioButton (USER.96) */ -void CheckRadioButton( HWND hwndDlg, WORD firstID, WORD lastID, WORD checkID ) +BOOL CheckRadioButton( HWND hwndDlg, UINT firstID, UINT lastID, UINT checkID ) { HWND button = GetWindow( hwndDlg, GW_CHILD ); WND *wndPtr; while (button) { - if (!(wndPtr = WIN_FindWndPtr( button ))) return; + if (!(wndPtr = WIN_FindWndPtr( button ))) return FALSE; if ((wndPtr->wIDmenu == firstID) || (wndPtr->wIDmenu == lastID)) break; button = wndPtr->hwndNext; } - if (!button) return; + if (!button) return FALSE; if (wndPtr->wIDmenu == lastID) lastID = firstID; /* Buttons are in reverse order */ while (button) { - if (!(wndPtr = WIN_FindWndPtr( button ))) return; + if (!(wndPtr = WIN_FindWndPtr( button ))) return FALSE; SendMessage( button, BM_SETCHECK, (wndPtr->wIDmenu == checkID), 0 ); if (wndPtr->wIDmenu == lastID) break; button = wndPtr->hwndNext; } + return TRUE; } diff --git a/windows/hook.c b/windows/hook.c index abb6c7f8356..ad3d0f4b2c1 100644 --- a/windows/hook.c +++ b/windows/hook.c @@ -277,7 +277,7 @@ DWORD DefHookProc( short code, WORD wParam, DWORD lParam, HHOOK *hhook ) /*********************************************************************** * CallMsgFilter (USER.123) */ -BOOL CallMsgFilter( SEGPTR msg, short code ) +BOOL CallMsgFilter( SEGPTR msg, INT code ) { if (GetSysModalWindow()) return FALSE; if (HOOK_CallHooks( WH_SYSMSGFILTER, code, 0, (LPARAM)msg )) return TRUE; @@ -316,7 +316,7 @@ BOOL UnhookWindowsHookEx( HHOOK hhook ) /*********************************************************************** * CallNextHookEx (USER.293) */ -DWORD CallNextHookEx( HHOOK hhook, short code, WPARAM wParam, LPARAM lParam ) +LRESULT CallNextHookEx( HHOOK hhook, INT code, WPARAM wParam, LPARAM lParam ) { HANDLE next; #ifdef WINELIB32 diff --git a/windows/keyboard.c b/windows/keyboard.c index c8c0e537e83..0c1ae3e4abc 100644 --- a/windows/keyboard.c +++ b/windows/keyboard.c @@ -91,8 +91,8 @@ int GetAsyncKeyState(int nKey) break; } - bzero(AsyncMouseButtonsStates, 3); /* all states to false */ - bzero(AsyncKeyStateTable, 256); + memset( AsyncMouseButtonsStates, 0, 3 ); /* all states to false */ + memset( AsyncKeyStateTable, 0, 256 ); return retval; } diff --git a/windows/mdi.c b/windows/mdi.c index 86d54132a36..38e09449844 100644 --- a/windows/mdi.c +++ b/windows/mdi.c @@ -1,7 +1,7 @@ /* MDI.C * * Copyright 1994, Bob Amstadt - * 1995, Alex Korobka + * 1995,1996 Alex Korobka * * This file contains routines to support MDI features. * @@ -9,8 +9,11 @@ * of corresponding MDI child. * * Basic child activation routine is MDI_ChildActivate and - * SetWindowPos(childHwnd,...) implicitly calls it if SWP_NOACTIVATE i + * SetWindowPos(childHwnd,...) implicitly calls it if SWP_NOACTIVATE * is not used. + * + * To fix: + * Sticky client crollbars */ #include @@ -23,10 +26,15 @@ #include "mdi.h" #include "user.h" #include "menu.h" +#include "stackframe.h" #include "sysmetrics.h" #include "stddebug.h" #include "debug.h" +void MDI_UpdateFrameText(HWND, HWND, BOOL, LPCSTR); +BOOL MDI_AugmentFrameMenu(MDICLIENTINFO*, HWND, HWND); +BOOL MDI_RestoreFrameMenu(HWND, HWND); + void ScrollChildren(HWND , UINT , WPARAM , LPARAM ); void CalcChildScroll(HWND, WORD); @@ -41,10 +49,8 @@ static LONG MDI_ChildActivate(WND* ,HWND ); static HWND MDI_GetChildByID(WND* mdiClient,int id) { - HWND hWnd = mdiClient->hwndChild; - WND* wndPtr = WIN_FindWndPtr( hWnd ); - - if( !wndPtr ) return 0; + HWND hWnd = mdiClient->hwndChild; + WND* wndPtr = WIN_FindWndPtr( hWnd ); while( wndPtr ) { @@ -61,7 +67,7 @@ static HWND MDI_GetChildByID(WND* mdiClient,int id) #ifdef SUPERFLUOUS_FUNCTIONS static BOOL MDI_MenuAppendItem(WND *clientWnd, HWND hWndChild) { - char buffer[128]; + char buffer[128]; MDICLIENTINFO *clientInfo = (MDICLIENTINFO*)clientWnd->wExtra; WND *wndPtr = WIN_FindWndPtr(hWndChild); LPSTR lpWndText = (LPSTR) USER_HEAP_LIN_ADDR(wndPtr->hText); @@ -73,7 +79,7 @@ static BOOL MDI_MenuAppendItem(WND *clientWnd, HWND hWndChild) if( lpWndText ) strncpy(buffer + n, lpWndText, sizeof(buffer) - n - 1); return AppendMenu(clientInfo->hWindowMenu,MF_STRING, - wndPtr->wIDmenu,(LPSTR)buffer); + wndPtr->wIDmenu, MAKE_SEGPTR(buffer) ); } #endif @@ -92,13 +98,13 @@ static BOOL MDI_MenuModifyItem(WND* clientWnd, HWND hWndChild ) if( !clientInfo->hWindowMenu ) return 0; - if( lpWndText ) - strncpy(buffer + n, lpWndText, sizeof(buffer) - n - 1); + if( lpWndText ) lstrcpyn(buffer + n, lpWndText, sizeof(buffer) - n ); 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); + MF_BYCOMMAND | MF_STRING, wndPtr->wIDmenu , + MAKE_SEGPTR(buffer) ); + CheckMenuItem(clientInfo->hWindowMenu ,wndPtr->wIDmenu , n & MF_CHECKED); return bRet; } @@ -144,7 +150,7 @@ static BOOL MDI_MenuDeleteItem(WND* clientWnd, HWND hWndChild ) /* change menu */ ModifyMenu(clientInfo->hWindowMenu ,index ,MF_BYCOMMAND | MF_STRING, - index - 1 ,(LPSTR)buffer ); + index - 1 , MAKE_SEGPTR(buffer) ); } return 1; } @@ -217,6 +223,10 @@ WORD MDIIconArrange(HWND parent) /* -DRP */ } + +/* ------------------ MDI child window functions ---------------------- */ + + /********************************************************************** * MDICreateChild */ @@ -240,7 +250,7 @@ HWND MDICreateChild(WND *w, MDICLIENTINFO *ci, HWND parent, LPARAM lParam ) 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); + AppendMenu(ci->hWindowMenu ,MF_STRING ,wIDmenu, MAKE_SEGPTR(&chDef) ); hwnd = CreateWindow( cs->szClass, cs->szTitle, WS_CHILD | WS_BORDER | WS_CAPTION | WS_CLIPSIBLINGS | @@ -255,7 +265,6 @@ HWND MDICreateChild(WND *w, MDICLIENTINFO *ci, HWND parent, LPARAM lParam ) ci->nActiveChildren++; MDI_MenuModifyItem(w ,hwnd); - /* FIXME: at this point NC area of hwnd stays inactive */ } else DeleteMenu(ci->hWindowMenu,wIDmenu,MF_BYCOMMAND); @@ -263,96 +272,73 @@ HWND MDICreateChild(WND *w, MDICLIENTINFO *ci, HWND parent, LPARAM lParam ) return hwnd; } +/********************************************************************** + * MDI_ChildGetMinMaxInfo + * + */ +void MDI_ChildGetMinMaxInfo(WND* clientWnd, HWND hwnd, MINMAXINFO* lpMinMax ) +{ + WND* childWnd = WIN_FindWndPtr(hwnd); + RECT rect = clientWnd->rectClient; + + MapWindowPoints(clientWnd->hwndParent, + ((MDICLIENTINFO*)clientWnd->wExtra)->self, (LPPOINT)&rect, 2); + AdjustWindowRectEx(&rect, childWnd->dwStyle, 0, childWnd->dwExStyle); + + lpMinMax->ptMaxSize.x = rect.right -= rect.left; + lpMinMax->ptMaxSize.y = rect.bottom -= rect.top; + + lpMinMax->ptMaxPosition.x = rect.left; + lpMinMax->ptMaxPosition.y = rect.top; +} + /********************************************************************** * 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 + * wTo is basically lParam of WM_MDINEXT message or explicit + * window handle */ -void MDI_SwitchActiveChild(HWND clientHwnd, HWND childHwnd, WORD wTo ) +void MDI_SwitchActiveChild(HWND clientHwnd, HWND childHwnd, BOOL wTo ) { WND *w = WIN_FindWndPtr(clientHwnd); - HWND hwndTo = MDI_GetWindow(w,childHwnd,wTo); - HWND hwndPrev; + HWND hwndTo = 0; + HWND hwndPrev = 0; MDICLIENTINFO *ci; - + hwndTo = MDI_GetWindow(w,childHwnd,(WORD)wTo); + ci = (MDICLIENTINFO *) w->wExtra; - dprintf_mdi(stddeb, "MDI_SwitchActiveChild: "NPFMT", %i\n",childHwnd,wTo); + dprintf_mdi(stddeb, "MDI_SwitchActiveChild: from "NPFMT", to "NPFMT"\n",childHwnd,hwndTo); - if ( !childHwnd || !hwndTo ) return; + if ( !hwndTo ) return; hwndPrev = ci->hwndActiveChild; if ( hwndTo != hwndPrev ) { - if (ci->flagChildMaximized) + BOOL bSA = 0; + + if( ci->flagChildMaximized ) { - RECT rectOldRestore, rect; - - w = WIN_FindWndPtr(hwndTo); - - /* save old window dimensions */ - rectOldRestore = ci->rectRestore; - GetWindowRect(hwndTo, &ci->rectRestore); - - rect.top = (ci->rectMaximize.top - - (w->rectClient.top - w->rectWindow.top)); - rect.bottom = (ci->rectMaximize.bottom + - (w->rectWindow.bottom - w->rectClient.bottom)); - rect.left = (ci->rectMaximize.left - - (w->rectClient.left - w->rectWindow.left)); - rect.right = (ci->rectMaximize.right + - (w->rectWindow.right - w->rectClient.right)); - w->dwStyle |= WS_MAXIMIZE; - - /* 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( hwndTo, WM_SIZE, SIZE_MAXIMIZED, - MAKELONG(w->rectClient.right-w->rectClient.left, - w->rectClient.bottom-w->rectClient.top)); - - w = WIN_FindWndPtr(hwndPrev); - - if( w ) - { - w->dwStyle &= ~WS_MAXIMIZE; - - /* 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 ); - } + bSA = 1; + w->dwStyle &= ~WS_VISIBLE; } - else + + SetWindowPos( hwndTo, HWND_TOP, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE ); + if( !wTo && hwndPrev ) { - SetWindowPos( hwndTo, HWND_TOP, 0, 0, 0, 0, - SWP_NOMOVE | SWP_NOSIZE ); - if( !wTo && hwndPrev ) - { - SetWindowPos( hwndPrev, HWND_BOTTOM, 0, 0, 0, 0, - SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); - } + SetWindowPos( hwndPrev, HWND_BOTTOM, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); } - } - + + if( bSA ) + ShowWindow( clientHwnd, SW_SHOW ); + } } @@ -371,15 +357,23 @@ HWND MDIDestroyChild(WND *w_parent, MDICLIENTINFO *ci, HWND parent, MDI_SwitchActiveChild(parent,child,0); if( child == ci->hwndActiveChild ) - MDI_ChildActivate(w_parent,0); + { + ShowWindow( child, SW_HIDE); + if( child == ci->flagChildMaximized ) + { + MDI_RestoreFrameMenu(w_parent->hwndParent, child); + ci->flagChildMaximized = 0; + MDI_UpdateFrameText(w_parent->hwndParent,parent,TRUE,NULL); + } + MDI_ChildActivate(w_parent,0); + } MDI_MenuDeleteItem(w_parent, child); } ci->nActiveChildren--; - if( ci->flagChildMaximized == child ) - ci->flagChildMaximized = (HWND)1; + /* WM_MDISETMENU ? */ if (flagDestroy) { @@ -393,66 +387,6 @@ HWND MDIDestroyChild(WND *w_parent, MDICLIENTINFO *ci, HWND parent, } -/********************************************************************** - * MDIMaximizeChild - */ -LONG MDIMaximizeChild(HWND parent, HWND child, MDICLIENTINFO *ci) -{ - - WND *w = WIN_FindWndPtr(child); - RECT rect; - - if( !SendMessage( child, WM_QUERYOPEN, 0, 0L) ) - return 0; - - ci->rectRestore = w->rectWindow; - - rect.top = (ci->rectMaximize.top - - (w->rectClient.top - w->rectWindow.top)); - rect.bottom = (ci->rectMaximize.bottom + - (w->rectWindow.bottom - w->rectClient.bottom)); - rect.left = (ci->rectMaximize.left - - (w->rectClient.left - w->rectWindow.left)); - 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, 0); - - 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; -} - -/********************************************************************** - * MDIRestoreChild - */ -LONG MDIRestoreChild(HWND parent, MDICLIENTINFO *ci) -{ - HWND hWnd; - - hWnd = ci->hwndActiveChild; - - dprintf_mdi(stddeb,"MDIRestoreChild: restore "NPFMT"\n", hWnd); - - ci->flagChildMaximized = FALSE; - - ShowWindow(hWnd, SW_RESTORE); /* display the window */ - - hWnd = GetParent(parent); - - SendMessage(hWnd,WM_NCPAINT , 0, 0); - - return 0; -} - /********************************************************************** * MDI_ChildActivate * @@ -499,8 +433,11 @@ LONG MDI_ChildActivate(WND *clientPtr, HWND hWndChild) if( hWndChild ) { clientInfo->hwndActiveChild = hWndChild; - MDIMaximizeChild(GetParent(hWndChild),hWndChild,clientInfo); + ShowWindow( hWndChild, SW_SHOWMAXIMIZED); } + else + ShowWindow( clientInfo->hwndActiveChild, + SW_SHOWNORMAL ); clientInfo->hwndActiveChild = hWndChild; @@ -508,7 +445,7 @@ LONG MDI_ChildActivate(WND *clientPtr, HWND hWndChild) if( !hWndChild ) { if( isActiveFrameWnd ) - SetFocus( GetParent(hWndChild) ); + SetFocus( clientInfo->self ); return 0; } @@ -523,11 +460,11 @@ LONG MDI_ChildActivate(WND *clientPtr, HWND hWndChild) if( isActiveFrameWnd ) { SendMessage( hWndChild, WM_NCACTIVATE, TRUE, 0L); - if( GetFocus() == GetParent(hWndChild) ) - SendMessage( GetParent(hWndChild), WM_SETFOCUS, - (WPARAM)GetParent(hWndChild), 0L ); + if( GetFocus() == clientInfo->self ) + SendMessage( clientInfo->self, WM_SETFOCUS, + (WPARAM)clientInfo->self, 0L ); else - SetFocus( GetParent(hWndChild) ); + SetFocus( clientInfo->self ); } #ifdef WINELIB32 @@ -574,7 +511,7 @@ MDIWCL* MDI_BuildWCL(WND* clientWnd, int* iTotal) free(listTop); listTop = listNext; } - fprintf(stdnimp,"MDICascade: allocation failed\n"); + dprintf_mdi(stddeb,"MDICascade: allocation failed\n"); return NULL; } @@ -605,8 +542,39 @@ MDIWCL* MDI_BuildWCL(WND* clientWnd, int* iTotal) return listTop; } + +/* -------------------- MDI client window functions ------------------- */ + /********************************************************************** - * MDICascade + * CreateMDIMenuBitmap + */ +HBITMAP CreateMDIMenuBitmap(void) +{ + HDC hDCSrc = CreateCompatibleDC(0); + HDC hDCDest = CreateCompatibleDC(hDCSrc); + HBITMAP hbClose = LoadBitmap(0, MAKEINTRESOURCE(OBM_CLOSE) ); + HBITMAP hbCopy,hb_src,hb_dest; + + hb_src = SelectObject(hDCSrc,hbClose); + hbCopy = CreateCompatibleBitmap(hDCSrc,SYSMETRICS_CXSIZE, SYSMETRICS_CYSIZE); + hb_dest = SelectObject(hDCDest,hbCopy); + + BitBlt(hDCDest, 0, 0, SYSMETRICS_CXSIZE, SYSMETRICS_CYSIZE, + hDCSrc, SYSMETRICS_CXSIZE, 0, SRCCOPY); + + SelectObject(hDCSrc,hb_src); + SelectObject(hDCDest,hb_dest); + + DeleteObject(hbClose); + + DeleteDC(hDCDest); + DeleteDC(hDCSrc); + + return hbCopy; +} + +/********************************************************************** + * MDICascade */ LONG MDICascade(HWND parent, MDICLIENTINFO *ci) { @@ -618,7 +586,7 @@ LONG MDICascade(HWND parent, MDICLIENTINFO *ci) int iToPosition = 0; if (ci->flagChildMaximized) - MDIRestoreChild(parent, ci); + ShowWindow( ci->flagChildMaximized, SW_NORMAL); if (ci->nActiveChildren == 0) return 0; @@ -661,6 +629,9 @@ LONG MDICascade(HWND parent, MDICLIENTINFO *ci) listTop = listPrev; } + if( iToPosition < ci->nActiveChildren ) + ArrangeIconicWindows( parent ); + return 0; } @@ -668,7 +639,7 @@ LONG MDICascade(HWND parent, MDICLIENTINFO *ci) * MDITile * */ -LONG MDITile(HWND parent, MDICLIENTINFO *ci) +LONG MDITile(HWND parent, MDICLIENTINFO *ci,WORD wParam) { WND *wndClient = WIN_FindWndPtr(parent); MDIWCL *listTop,*listPrev; @@ -681,7 +652,7 @@ LONG MDITile(HWND parent, MDICLIENTINFO *ci) int iToPosition = 0; if (ci->flagChildMaximized) - MDIRestoreChild(parent, ci); + ShowWindow(ci->flagChildMaximized, SW_NORMAL); if (ci->nActiveChildren == 0) return 0; @@ -691,178 +662,240 @@ LONG MDITile(HWND parent, MDICLIENTINFO *ci) if( !listTop ) return 0; - /* just free memory and return if zero windows to tile */ - if ( iToPosition == 0 ) - goto MDITile_free; + /* tile children */ + if ( iToPosition ) + { - GetClientRect(parent, &rect); + GetClientRect(parent, &rect); - rows = (int) sqrt((double) iToPosition); - columns = iToPosition / rows; + rows = (int) sqrt((double) iToPosition); + columns = iToPosition / rows; - /* hack */ - if( iToPosition != ci->nActiveChildren) + if (wParam == MDITILE_HORIZONTAL) /* version >= 3.1 */ { - y = rect.bottom - 2 * SYSMETRICS_CYICONSPACING - SYSMETRICS_CYICON; - rect.bottom = ( y - SYSMETRICS_CYICON < rect.top )? rect.bottom: y; - } + i=rows; + rows=columns; /* exchange r and c */ + columns=i; + } - ysize = rect.bottom / rows; - xsize = rect.right / columns; + /* 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; - x = 0; - i = 0; + x = 0; + i = 0; - for (c = 1; c <= columns; c++) - { - if (c == columns) - { - rows = iToPosition - i; - ysize = rect.bottom / rows; - } + for (c = 1; c <= columns; c++) + { + if (c == columns) + { + rows = iToPosition - i; + ysize = rect.bottom / rows; + } - y = 0; - for (r = 1; r <= rows; r++, i++) - { - /* 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; - } - - listPrev = listTop->prev; - free(listTop); - listTop = listPrev; - } - - x += xsize; + y = 0; + for (r = 1; r <= rows; r++, i++) + { + /* 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; + } + listPrev = listTop->prev; + free(listTop); + listTop = listPrev; + } + x += xsize; + } } - - MDITile_free: + /* free the rest if any */ - while( listTop ) { - listPrev = listTop->prev; - free(listTop); - listTop = listPrev; } - - return 0; -} - -/********************************************************************** - * MDIHandleLButton - */ -BOOL MDIHandleLButton(HWND hwndFrame, HWND hwndClient, - WORD wParam, LONG lParam) -{ - MDICLIENTINFO *ci; - WND *w; - RECT rect; - WORD x; - - w = WIN_FindWndPtr(hwndClient); - ci = (MDICLIENTINFO *) w->wExtra; - - if (wParam == HTMENU && ci->flagChildMaximized) + while( listTop ) { - x = LOWORD(lParam); - - NC_GetInsideRect(hwndFrame, &rect); - if (x < rect.left + SYSMETRICS_CXSIZE) - { - SendMessage(ci->hwndActiveChild, WM_SYSCOMMAND, - SC_CLOSE, lParam); - return TRUE; - } - else if (x >= rect.right - SYSMETRICS_CXSIZE) - { - SendMessage(ci->hwndActiveChild, WM_SYSCOMMAND, - SC_RESTORE, lParam); - return TRUE; - } + listPrev = listTop->prev; + free(listTop); + listTop = listPrev; } - - return FALSE; -} - -/********************************************************************** - * MDIPaintMaximized - */ -LONG MDIPaintMaximized(HWND hwndFrame, HWND hwndClient, WORD message, - WORD wParam, LONG lParam) -{ - static HBITMAP hbitmapClose = 0; - static HBITMAP hbitmapMaximized = 0; - MDICLIENTINFO *ci; - WND *w; - HDC hdc, hdcMem; - RECT rect; - WND *wndPtr = WIN_FindWndPtr(hwndFrame); - - w = WIN_FindWndPtr(hwndClient); - ci = (MDICLIENTINFO *) w->wExtra; - - dprintf_mdi(stddeb, "MDIPaintMaximized: frame "NPFMT", client "NPFMT - ", max flag %d, menu %04x\n", hwndFrame, hwndClient, - (int)ci->flagChildMaximized, wndPtr ? wndPtr->wIDmenu : 0); - - if (ci->flagChildMaximized && wndPtr && wndPtr->wIDmenu != 0) - { - NC_DoNCPaint(hwndFrame, wParam, TRUE); - - hdc = GetDCEx(hwndFrame, 0, DCX_CACHE | DCX_WINDOW); - if (!hdc) return 0; - - hdcMem = CreateCompatibleDC(hdc); - - if (hbitmapClose == 0) - { - hbitmapClose = LoadBitmap(0, MAKEINTRESOURCE(OBM_OLD_CLOSE)); - hbitmapMaximized = LoadBitmap(0, MAKEINTRESOURCE(OBM_RESTORE)); - } - - dprintf_mdi(stddeb, - "MDIPaintMaximized: hdcMem "NPFMT", close bitmap "NPFMT", " - "maximized bitmap "NPFMT"\n", - hdcMem, hbitmapClose, hbitmapMaximized); - - NC_GetInsideRect(hwndFrame, &rect); - rect.top += (wndPtr->dwStyle & WS_CAPTION) ? SYSMETRICS_CYSIZE + 1 : 0; - SelectObject(hdcMem, hbitmapClose); - BitBlt(hdc, rect.left, rect.top + 1, - SYSMETRICS_CXSIZE, SYSMETRICS_CYSIZE, - hdcMem, 1, 1, SRCCOPY); - - NC_GetInsideRect(hwndFrame, &rect); - rect.top += (wndPtr->dwStyle & WS_CAPTION) ? SYSMETRICS_CYSIZE + 1 : 0; - rect.left = rect.right - SYSMETRICS_CXSIZE; - SelectObject(hdcMem, hbitmapMaximized); - BitBlt(hdc, rect.left, rect.top + 1, - SYSMETRICS_CXSIZE, SYSMETRICS_CYSIZE, - hdcMem, 1, 1, SRCCOPY); - - NC_GetInsideRect(hwndFrame, &rect); - rect.top += (wndPtr->dwStyle & WS_CAPTION) ? SYSMETRICS_CYSIZE + 1 : 0; - rect.left += SYSMETRICS_CXSIZE; - rect.right -= SYSMETRICS_CXSIZE; - rect.bottom = rect.top + SYSMETRICS_CYMENU; - - MENU_DrawMenuBar(hdc, &rect, hwndFrame, FALSE); - - DeleteDC(hdcMem); - ReleaseDC(hwndFrame, hdc); - } - else - return DefWindowProc(hwndFrame, message, wParam, lParam); + if (iToPosition < ci->nActiveChildren ) + ArrangeIconicWindows( parent ); return 0; } +/* ----------------------- Frame window ---------------------------- */ + + +/********************************************************************** + * MDI_AugmentFrameMenu + */ +BOOL MDI_AugmentFrameMenu(MDICLIENTINFO* ci, HWND hFrame, HWND hChild) +{ + WND* frame = WIN_FindWndPtr(hFrame); + WND* child = WIN_FindWndPtr(hChild); + HMENU hSysPopup = 0; + + dprintf_mdi(stddeb,"MDI_AugmentFrameMenu: frame "NPFMT",child "NPFMT"\n",hFrame,hChild); + + if( !frame->wIDmenu || !child->hSysMenu ) return 0; + + hSysPopup = GetSystemMenu(hChild,FALSE); + + dprintf_mdi(stddeb,"got popup "NPFMT"\n in sysmenu "NPFMT"",hSysPopup,child->hSysMenu); + + if( !InsertMenu(frame->wIDmenu,0,MF_BYPOSITION | MF_BITMAP | MF_POPUP, + hSysPopup, (SEGPTR)(DWORD)ci->obmClose) ) + return 0; + + if( !AppendMenu(frame->wIDmenu,MF_HELP | MF_BITMAP, + SC_RESTORE, (SEGPTR)(DWORD)ci->obmRestore) ) + { + RemoveMenu(frame->wIDmenu,0,MF_BYPOSITION); + return 0; + } + + EnableMenuItem(hSysPopup, SC_SIZE, MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(hSysPopup, SC_MOVE, MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(hSysPopup, SC_MAXIMIZE, MF_BYCOMMAND | MF_GRAYED); + + child->dwStyle &= ~WS_SYSMENU; + + /* redraw frame */ + SetWindowPos(hFrame, 0,0,0,0,0, SWP_FRAMECHANGED | SWP_NOSIZE | + SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER ); + + return 1; +} + +/********************************************************************** + * MDI_RestoreFrameMenu + */ +BOOL MDI_RestoreFrameMenu(HWND hFrame, HWND hChild) +{ + WND* frameWnd = WIN_FindWndPtr(hFrame); + WND* child = WIN_FindWndPtr(hChild); + INT nItems = GetMenuItemCount(frameWnd->wIDmenu) - 1; + + dprintf_mdi(stddeb,"MDI_RestoreFrameMenu: for child "NPFMT"\n",hChild); + + if( GetMenuItemID(frameWnd->wIDmenu,nItems) != SC_RESTORE ) + return 0; + + child->dwStyle |= WS_SYSMENU; + + RemoveMenu(frameWnd->wIDmenu,0,MF_BYPOSITION); + DeleteMenu(frameWnd->wIDmenu,nItems-1,MF_BYPOSITION); + + /* redraw frame */ + SetWindowPos(hChild, 0,0,0,0,0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | + SWP_NOACTIVATE | SWP_NOZORDER ); + return 1; +} + +/********************************************************************** + * MDI_UpdateFrameText + * + * used when child window is maximized/restored + * + * Note: lpTitle can be NULL + */ +void MDI_UpdateFrameText(HWND hFrame, HWND hClient, BOOL repaint, LPCSTR lpTitle) +{ + char lpBuffer[MDI_MAXTITLELENGTH+1]; + LPSTR lpText = NULL; + WND* clientWnd = WIN_FindWndPtr(hClient); + WND* frameWnd = WIN_FindWndPtr(hFrame); + + MDICLIENTINFO *ci = (MDICLIENTINFO *) clientWnd->wExtra; + + dprintf_mdi(stddeb, "MDI: repaint %i, frameText %s\n", repaint, (lpTitle)?lpTitle:"NULL"); + + /* store new "default" title if lpTitle is not NULL */ + if( lpTitle ) + { + if( ci->hFrameTitle ) + USER_HEAP_FREE( ci->hFrameTitle ); + ci->hFrameTitle = USER_HEAP_ALLOC( strlen(lpTitle) + 1 ); + lpText = (LPSTR) USER_HEAP_LIN_ADDR( ci->hFrameTitle ); + strcpy( lpText, lpTitle ); + } + else + lpText = (LPSTR) USER_HEAP_LIN_ADDR(ci->hFrameTitle); + + if( ci->hFrameTitle ) + { + WND* childWnd = WIN_FindWndPtr( ci->flagChildMaximized ); + + if( childWnd && childWnd->hText ) + { + /* combine frame title and child title if possible */ + + LPCSTR lpBracket = " - ["; + LPCSTR lpChildText = (LPCSTR) USER_HEAP_LIN_ADDR( childWnd->hText ); + + int i_frame_text_length = strlen(lpText); + int i_child_text_length = strlen(lpChildText); + + strncpy( lpBuffer, lpText, MDI_MAXTITLELENGTH); + lpBuffer[MDI_MAXTITLELENGTH] = '\0'; + + if( i_frame_text_length + 5 < MDI_MAXTITLELENGTH ) + { + strcat( lpBuffer, lpBracket ); + + if( i_frame_text_length + i_child_text_length + 5 < MDI_MAXTITLELENGTH ) + { + strcat( lpBuffer, lpChildText ); + *(short*)(lpBuffer + i_frame_text_length + i_child_text_length + 4) = (short)']'; + } + else + { + memcpy( lpBuffer + i_frame_text_length + 4, + lpChildText, + MDI_MAXTITLELENGTH - i_frame_text_length - 4); + *(short*)(lpBuffer + MDI_MAXTITLELENGTH - 1) = (short)']'; + } + } + } + else + { + strncpy(lpBuffer, lpText, MDI_MAXTITLELENGTH ); + lpBuffer[MDI_MAXTITLELENGTH]='\0'; + } + } + else + lpBuffer[0] = '\0'; + + if( frameWnd->hText ) + USER_HEAP_FREE( frameWnd->hText ); + + frameWnd->hText = USER_HEAP_ALLOC( strlen(lpBuffer) + 1 ); + lpText = (LPSTR) USER_HEAP_LIN_ADDR( frameWnd->hText ); + strcpy( lpText, lpBuffer ); + + if( frameWnd->window ) + XStoreName( display, frameWnd->window, lpBuffer ); + + if( repaint == MDI_REPAINTFRAME) + SetWindowPos(hFrame, 0,0,0,0,0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | + SWP_NOACTIVATE | SWP_NOZORDER ); +} + + +/* ----------------------------- Interface ---------------------------- */ + + /********************************************************************** * MDIClientWndProc * @@ -873,9 +906,10 @@ LRESULT MDIClientWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) LPCREATESTRUCT cs; LPCLIENTCREATESTRUCT ccs; MDICLIENTINFO *ci; - WND *w; + RECT rect; + WND *w = WIN_FindWndPtr(hwnd); + WND *frameWnd = WIN_FindWndPtr( w->hwndParent ); - w = WIN_FindWndPtr(hwnd); ci = (MDICLIENTINFO *) w->wExtra; switch (message) @@ -883,23 +917,46 @@ LRESULT MDIClientWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 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->flagChildMaximized = FALSE; + ci->flagChildMaximized = 0; + ci->hFrameTitle = frameWnd->hText; ci->sbStop = 0; - + ci->self = hwnd; + ci->obmClose = CreateMDIMenuBitmap(); + ci->obmRestore = LoadBitmap(0, MAKEINTRESOURCE(OBM_RESTORE)); w->dwStyle |= WS_CLIPCHILDREN; + frameWnd->hText = 0; /* will be restored in UpdateFrameText */ - AppendMenu(ccs->hWindowMenu,MF_SEPARATOR,0,NULL); + MDI_UpdateFrameText( w->hwndParent, hwnd, MDI_NOFRAMEREPAINT, NULL); - GetClientRect(w->hwndParent, &ci->rectMaximize); - MoveWindow(hwnd, 0, 0, - ci->rectMaximize.right, ci->rectMaximize.bottom, 1); + AppendMenu(ccs->hWindowMenu,MF_SEPARATOR,0,(SEGPTR)0); + + GetClientRect(w->hwndParent, &rect); + NC_HandleNCCalcSize(hwnd, (NCCALCSIZE_PARAMS*) &rect); + w->rectClient = rect; + + return 0; + + case WM_DESTROY: + if( ci->flagChildMaximized ) + MDI_RestoreFrameMenu(hwnd, w->hwndParent); + + if(ci->obmClose) DeleteObject(ci->obmClose); + if(ci->obmRestore) DeleteObject(ci->obmRestore); + + ci->idFirstChild = GetMenuItemCount(ci->hWindowMenu) - 1; + ci->nActiveChildren++; /* to delete a separator */ + + while( ci->nActiveChildren-- ) + DeleteMenu(ci->hWindowMenu,MF_BYPOSITION,ci->idFirstChild--); return 0; case WM_MDIACTIVATE: - SetWindowPos((HWND)wParam,0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE ); + if( ci->hwndActiveChild != (HWND)wParam ) + SetWindowPos((HWND)wParam, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE ); return 0; case WM_MDICASCADE: @@ -923,14 +980,16 @@ LRESULT MDIClientWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) return 0; case WM_MDIMAXIMIZE: - return MDIMaximizeChild(hwnd, (HWND)wParam, ci); + ShowWindow((HWND)wParam, SW_MAXIMIZE); + return 0; case WM_MDINEXT: - MDI_SwitchActiveChild(hwnd, (HWND)wParam, lParam); + MDI_SwitchActiveChild(hwnd, (HWND)wParam, (lParam)?1:0); break; case WM_MDIRESTORE: - return MDIRestoreChild(hwnd, ci); + ShowWindow( (HWND)wParam, SW_NORMAL); + return 0; case WM_MDISETMENU: #ifdef WINELIB32 @@ -942,7 +1001,7 @@ LRESULT MDIClientWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_MDITILE: ci->sbStop = TRUE; ShowScrollBar(hwnd,SB_BOTH,FALSE); - MDITile(hwnd, ci); + MDITile(hwnd, ci,wParam); ci->sbStop = FALSE; return 0; @@ -964,17 +1023,25 @@ LRESULT MDIClientWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_NCACTIVATE: if( ci->hwndActiveChild ) - SendMessage(ci->hwndActiveChild, message, wParam, lParam); + SendMessage(ci->hwndActiveChild, message, wParam, lParam); break; case WM_PARENTNOTIFY: - if (wParam == WM_LBUTTONDOWN) + if (wParam == WM_LBUTTONDOWN && (ci->hwndHitTest != ci->hwndActiveChild) ) SetWindowPos(ci->hwndHitTest, 0,0,0,0,0, SWP_NOSIZE | SWP_NOMOVE ); break; case WM_SIZE: - GetClientRect(w->hwndParent, &ci->rectMaximize); - if( !ci->hwndActiveChild ) + if( ci->flagChildMaximized ) + { + WND* child = WIN_FindWndPtr(ci->flagChildMaximized); + RECT rect = { 0, 0, LOWORD(lParam), HIWORD(lParam) }; + + AdjustWindowRectEx(&rect, child->dwStyle, 0, child->dwExStyle); + MoveWindow(ci->flagChildMaximized, rect.left, rect.top, + rect.right - rect.left, rect.bottom - rect.top, 1); + } + else { PostMessage(hwnd,WM_MDICALCCHILDSCROLL,0,0L); ci->sbRecalc |= (SB_BOTH+1); @@ -1001,36 +1068,57 @@ LRESULT MDIClientWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) LRESULT DefFrameProc(HWND hwnd, HWND hwndMDIClient, UINT message, WPARAM wParam, LPARAM lParam) { - HWND childHwnd; + HWND childHwnd; + MDICLIENTINFO* ci; + WND* wndPtr; if (hwndMDIClient) { switch (message) { case WM_COMMAND: - childHwnd = MDI_GetChildByID( WIN_FindWndPtr(hwndMDIClient), + wndPtr = WIN_FindWndPtr(hwndMDIClient); + ci = (MDICLIENTINFO*)wndPtr->wExtra; + + /* check for possible system command codes */ + + if( wParam < ci->idFirstChild || + wParam >= ci->idFirstChild + ci->nActiveChildren ) + { + if( (wParam - 0xF000) & 0xF00F ) break; + switch( wParam ) + { + case SC_SIZE: + case SC_MOVE: + case SC_MINIMIZE: + case SC_MAXIMIZE: + case SC_NEXTWINDOW: + case SC_PREVWINDOW: + case SC_CLOSE: + case SC_RESTORE: + if( ci->flagChildMaximized ) + return SendMessage( ci->flagChildMaximized, WM_SYSCOMMAND, + wParam, lParam); + } + } + else + { + childHwnd = MDI_GetChildByID( WIN_FindWndPtr(hwndMDIClient), wParam ); - if( childHwnd ) -#ifdef WINELIB32 /* FIXME: need to find out the equivalent Win32 message */ - SendMessage(hwndMDIClient, WM_MDIACTIVATE, 0 , 0); -#else - SendMessage(hwndMDIClient, WM_MDIACTIVATE, childHwnd , 0L); -#endif + if( childHwnd ) + SendMessage(hwndMDIClient, WM_MDIACTIVATE, (WPARAM)childHwnd , 0L); + } break; - case WM_NCLBUTTONDOWN: - if (MDIHandleLButton(hwnd, hwndMDIClient, wParam, lParam)) - return 0; - break; - case WM_NCACTIVATE: SendMessage(hwndMDIClient, message, wParam, lParam); - return MDIPaintMaximized(hwnd, hwndMDIClient, - message, wParam, lParam); + break; - case WM_NCPAINT: - return MDIPaintMaximized(hwnd, hwndMDIClient, - message, wParam, lParam); + case WM_SETTEXT: + MDI_UpdateFrameText(hwnd, hwndMDIClient, + MDI_REPAINTFRAME, + (LPCSTR)PTR_SEG_TO_LIN(lParam)); + return 0; case WM_SETFOCUS: SetFocus(hwndMDIClient); @@ -1061,7 +1149,7 @@ LONG DefMDIChildProc(HWND hwnd, WORD message, WORD wParam, LONG lParam) clientWnd = WIN_FindWndPtr(GetParent(hwnd)); ci = (MDICLIENTINFO *) clientWnd->wExtra; - + switch (message) { case WM_NCHITTEST: @@ -1071,13 +1159,16 @@ LONG DefMDIChildProc(HWND hwnd, WORD message, WORD wParam, LONG lParam) case WM_SETTEXT: DefWindowProc(hwnd, message, wParam, lParam); MDI_MenuModifyItem(clientWnd,hwnd); + if( ci->flagChildMaximized == hwnd ) + MDI_UpdateFrameText( clientWnd->hwndParent, ci->self, + MDI_REPAINTFRAME, NULL ); return 0; case WM_CLOSE: - SendMessage(GetParent(hwnd),WM_MDIDESTROY,(WPARAM)hwnd,0L); + SendMessage(ci->self,WM_MDIDESTROY,(WPARAM)hwnd,0L); return 0; - case WM_SIZE: + case WM_SETFOCUS: if( ci->hwndActiveChild != hwnd ) MDI_ChildActivate(clientWnd, hwnd); break; @@ -1092,35 +1183,82 @@ LONG DefMDIChildProc(HWND hwnd, WORD message, WORD wParam, LONG lParam) break; case WM_SYSCOMMAND: - switch (wParam) - { - case SC_MAXIMIZE: - return SendMessage(GetParent(hwnd), WM_MDIMAXIMIZE, (WPARAM)hwnd, 0); - - case SC_RESTORE: - return SendMessage(GetParent(hwnd), WM_MDIRESTORE, (WPARAM)hwnd, 0); - } + switch( wParam ) + { + case SC_MOVE: + if( ci->flagChildMaximized == hwnd) return 0; + break; + case SC_MAXIMIZE: + if( ci->flagChildMaximized == hwnd) + return SendMessage( clientWnd->hwndParent, message, wParam, lParam); + break; + case SC_NEXTWINDOW: + SendMessage( ci->self, WM_MDINEXT, 0, 0); + return 0; + case SC_PREVWINDOW: + SendMessage( ci->self, WM_MDINEXT, 0, 1); + return 0; + } 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 */ + MDI_ChildGetMinMaxInfo(clientWnd, hwnd, (MINMAXINFO*) PTR_SEG_TO_LIN(lParam)); + return 0; case WM_SETVISIBLE: - if( !ci->sbStop ) + if( !ci->sbStop && !ci->flagChildMaximized) { - PostMessage(GetParent(hwnd),WM_MDICALCCHILDSCROLL,0,0L); + PostMessage(ci->self,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); + + case WM_SIZE: + /* do not change */ + + if( ci->hwndActiveChild == hwnd && wParam != SIZE_MAXIMIZED ) + { + ci->flagChildMaximized = 0; + + MDI_RestoreFrameMenu( clientWnd->hwndParent, hwnd); + MDI_UpdateFrameText( clientWnd->hwndParent, ci->self, + MDI_REPAINTFRAME, NULL ); + } + + if( wParam == SIZE_MAXIMIZED ) + { + HWND hMaxChild = ci->flagChildMaximized; + + if( hMaxChild == hwnd ) break; + + if( hMaxChild) + { + SendMessage( hMaxChild, WM_SETREDRAW, FALSE, 0L ); + + MDI_RestoreFrameMenu( clientWnd->hwndParent, hMaxChild); + ShowWindow( hMaxChild, SW_SHOWNOACTIVATE); + + SendMessage( hMaxChild, WM_SETREDRAW, TRUE, 0L ); + } + + ci->flagChildMaximized = hwnd; /* !!! */ + + MDI_AugmentFrameMenu( ci, clientWnd->hwndParent, hwnd); + MDI_UpdateFrameText( clientWnd->hwndParent, ci->self, + MDI_REPAINTFRAME, NULL ); + } + + if( wParam == SIZE_MINIMIZED ) + { + HWND switchTo = MDI_GetWindow(clientWnd, hwnd, 0); + + if( switchTo ) + SendMessage( switchTo, WM_CHILDACTIVATE, 0, 0L); + } + if( !ci->sbStop ) { - PostMessage(GetParent(hwnd),WM_MDICALCCHILDSCROLL,0,0L); + PostMessage(ci->self,WM_MDICALCCHILDSCROLL,0,0L); ci->sbRecalc |= (SB_BOTH+1); } break; @@ -1141,7 +1279,38 @@ LONG DefMDIChildProc(HWND hwnd, WORD message, WORD wParam, LONG lParam) */ BOOL TranslateMDISysAccel(HWND hwndClient, LPMSG msg) { + WND* clientWnd = WIN_FindWndPtr( hwndClient); + WND* wnd; + MDICLIENTINFO *ci = NULL; + WPARAM wParam = 0; + + if( (msg->message != WM_KEYDOWN && msg->message != WM_SYSKEYDOWN) || !clientWnd ) return 0; + + ci = (MDICLIENTINFO*) clientWnd->wExtra; + wnd = WIN_FindWndPtr(ci->hwndActiveChild); + + if( !wnd ) return 0; + + if( wnd->dwStyle & WS_DISABLED ) return 0; + + if( GetKeyState(VK_CONTROL) && !GetKeyState(VK_MENU) ) + switch( msg->wParam ) + { + case VK_F6: + case VK_SEPARATOR: + wParam = (GetKeyState(VK_SHIFT))? SC_NEXTWINDOW: SC_PREVWINDOW; + break; + case VK_RBUTTON: + wParam = SC_CLOSE; + default: + return 0; + } + + dprintf_mdi(stddeb,"TranslateMDISysAccel: wParam = "NPFMT"\n", wParam); + + SendMessage(ci->hwndActiveChild,WM_SYSCOMMAND, wParam, (LPARAM)msg->wParam); + return 1; } diff --git a/windows/message.c b/windows/message.c index 458232c9307..a197f379519 100644 --- a/windows/message.c +++ b/windows/message.c @@ -36,8 +36,6 @@ DWORD MSG_WineStartTicks; /* Ticks at Wine startup */ static HANDLE hmemSysMsgQueue = 0; static MESSAGEQUEUE *sysMsgQueue = NULL; - -HANDLE hActiveQ_G = 0; static HANDLE hFirstQueue = 0; /* ------- Miscellaneous ------ */ @@ -47,7 +45,7 @@ static int doubleClickSpeed = 452; /*********************************************************************** * MSG_CreateMsgQueue * - * Create a message queue. + * Creates a message queue. Doesn't link it into queue list! */ static HANDLE MSG_CreateMsgQueue( int size ) { @@ -66,44 +64,35 @@ static HANDLE MSG_CreateMsgQueue( int size ) return hQueue; } + /*********************************************************************** * MSG_DeleteMsgQueue + * + * Unlinks and deletes a message queue. */ BOOL MSG_DeleteMsgQueue( HANDLE hQueue ) { - MESSAGEQUEUE * msgQueue = (MESSAGEQUEUE*)GlobalLock(hQueue); + MESSAGEQUEUE * msgQueue = (MESSAGEQUEUE*)GlobalLock(hQueue); + HANDLE *pPrev; - if( !hQueue ) - { + if (!hQueue || !msgQueue) + { 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; + pPrev = &hFirstQueue; + while (*pPrev && (*pPrev != hQueue)) + { + MESSAGEQUEUE *msgQ = (MESSAGEQUEUE*)GlobalLock(*pPrev); + pPrev = &msgQ->next; + } + if (*pPrev) *pPrev = msgQueue->next; + GlobalFree( hQueue ); + return 1; } + /*********************************************************************** * MSG_CreateSysMsgQueue * @@ -674,58 +663,27 @@ BOOL MSG_GetHardwareMessage( LPMSG msg ) */ BOOL SetMessageQueue( int size ) { - HGLOBAL hQueue = 0; - HGLOBAL hNextQueue= hFirstQueue; - MESSAGEQUEUE *queuePrev = NULL; + HANDLE hQueue, hNewQueue; MESSAGEQUEUE *queuePtr; if ((size > MAX_QUEUE_SIZE) || (size <= 0)) return TRUE; - /* Free the old message queue */ - if ((hQueue = GetTaskQueue(0)) != 0) + if( !(hNewQueue = MSG_CreateMsgQueue( size ))) { - 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; + dprintf_msg(stddeb,"SetMessageQueue: failed!\n"); return FALSE; } - - queuePtr = (MESSAGEQUEUE *)GlobalLock( hQueue ); + + /* Free the old message queue */ + if ((hQueue = GetTaskQueue(0)) != 0) MSG_DeleteMsgQueue( hQueue ); + + /* Link new queue into list */ + queuePtr = (MESSAGEQUEUE *)GlobalLock( hNewQueue ); queuePtr->hTask = GetCurrentTask(); - queuePtr->next = hNextQueue; + queuePtr->next = hFirstQueue; + hFirstQueue = hNewQueue; - if( !queuePrev ) - hFirstQueue = hQueue; - else - queuePrev->next = hQueue; - - SetTaskQueue( 0, hQueue ); + SetTaskQueue( 0, hNewQueue ); return TRUE; } @@ -761,7 +719,7 @@ void PostQuitMessage( int exitCode ) /*********************************************************************** * GetQueueStatus (USER.334) */ -DWORD GetQueueStatus( int flags ) +DWORD GetQueueStatus( UINT flags ) { MESSAGEQUEUE *queue; DWORD ret; diff --git a/windows/msgbox.c b/windows/msgbox.c index a83b8cc647c..59f61cc6fd2 100644 --- a/windows/msgbox.c +++ b/windows/msgbox.c @@ -15,8 +15,8 @@ #include "task.h" typedef struct { - LPSTR title; - LPSTR text; + LPCSTR title; + LPCSTR text; WORD type; } MSGBOX, *LPMSGBOX; @@ -179,7 +179,7 @@ LRESULT SystemMessageBoxProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam) * MessageBox [USER.1] */ -int MessageBox(HWND hWnd, LPSTR text, LPSTR title, WORD type) +int MessageBox(HWND hWnd, LPCSTR text, LPCSTR title, WORD type) { HANDLE handle; MSGBOX mbox; @@ -214,7 +214,7 @@ int MessageBox(HWND hWnd, LPSTR text, LPSTR title, WORD type) * FatalAppExit [USER.137] */ -void FatalAppExit(WORD wAction, LPSTR str) +void FatalAppExit(UINT fuAction, LPCSTR str) { MessageBox(0, str, NULL, MB_SYSTEMMODAL | MB_OK); TASK_KillCurrentTask(0); diff --git a/windows/nonclient.c b/windows/nonclient.c index 863b1c17495..e19ccf66e30 100644 --- a/windows/nonclient.c +++ b/windows/nonclient.c @@ -93,16 +93,16 @@ static void NC_AdjustRect( LPRECT rect, DWORD style, BOOL menu, DWORD exStyle ) /*********************************************************************** * AdjustWindowRect (USER.102) */ -void AdjustWindowRect( LPRECT rect, DWORD style, BOOL menu ) +BOOL AdjustWindowRect( LPRECT rect, DWORD style, BOOL menu ) { - AdjustWindowRectEx( rect, style, menu, 0 ); + return AdjustWindowRectEx( rect, style, menu, 0 ); } /*********************************************************************** * AdjustWindowRectEx (USER.454) */ -void AdjustWindowRectEx( LPRECT rect, DWORD style, BOOL menu, DWORD exStyle ) +BOOL AdjustWindowRectEx( LPRECT rect, DWORD style, BOOL menu, DWORD exStyle ) { /* Correct the window style */ @@ -115,6 +115,7 @@ void AdjustWindowRectEx( LPRECT rect, DWORD style, BOOL menu, DWORD exStyle ) style, menu, exStyle ); NC_AdjustRect( rect, style, menu, exStyle ); + return TRUE; } diff --git a/windows/utility.c b/windows/utility.c index d0cb29948a1..e3e17800b1c 100644 --- a/windows/utility.c +++ b/windows/utility.c @@ -28,14 +28,30 @@ * and divides by a third integer. */ -int MulDiv(int foo, int bar, int baz) +#ifdef WINELIB32 +INT MulDiv(INT foo, INT bar, INT baz) +{ +#ifdef __GNUC__ + long long ret; + if (!baz) return -1; + ret = ((long long)foo * bar) / baz; + if ((ret > 2147483647) || (ret < -2147483647)) return -1; + return ret; +#else + if (!baz) return -1; + return (foo * bar) / baz; +#endif +} +#else /* WINELIB32 */ +INT MulDiv(INT foo, INT bar, INT baz) { int ret; if (!baz) return -32768; ret = (foo * bar) / baz; if ((ret > 32767) || (ret < -32767)) return -32768; return ret; -}; +} +#endif /* UTILITY_strip015() removes \015 (^M, CR) from a string; * this is done to convert a MS-DOS-style string to a more diff --git a/windows/win.c b/windows/win.c index 1c7d8953601..d9aaa3ab764 100644 --- a/windows/win.c +++ b/windows/win.c @@ -601,11 +601,12 @@ BOOL DestroyWindow( HWND hwnd ) /*********************************************************************** * CloseWindow (USER.43) */ -void CloseWindow(HWND hWnd) +BOOL CloseWindow(HWND hWnd) { WND * wndPtr = WIN_FindWndPtr(hWnd); - if (wndPtr->dwStyle & WS_CHILD) return; + if (wndPtr->dwStyle & WS_CHILD) return TRUE; ShowWindow(hWnd, SW_MINIMIZE); + return TRUE; } @@ -850,7 +851,7 @@ void WIN16_SetWindowText( HWND hwnd, SEGPTR lpString ) SendMessage( hwnd, WM_SETTEXT, 0, (DWORD)lpString ); } -void SetWindowText( HWND hwnd, LPSTR lpString ) +void SetWindowText( HWND hwnd, LPCSTR lpString ) { HANDLE handle; @@ -1395,8 +1396,6 @@ DWORD DragObject(HWND hwndScope, HWND hWnd, WORD wObj, HANDLE hOfStruct, HWND hCurrentWnd = 0; WORD btemp; - fprintf(stdnimp,"DragObject: experimental\n"); - lpDragInfo = (LPDRAGINFO) GlobalLock(hDragInfo); spDragInfo = (SEGPTR) WIN16_GlobalLock(hDragInfo); diff --git a/windows/winpos.c b/windows/winpos.c index 3a7eb9f7262..04dcb66ee8b 100644 --- a/windows/winpos.c +++ b/windows/winpos.c @@ -2,7 +2,7 @@ * Window position related functions. * * Copyright 1993, 1994, 1995 Alexandre Julliard - * 1995 Alex Korobka + * 1995,1996 Alex Korobka */ #include "sysmetrics.h" @@ -28,8 +28,6 @@ void FOCUS_SwitchFocus( HWND , HWND ); static HWND hwndActive = 0; /* Currently active window */ static HWND hwndPrevActive = 0; /* Previously active window */ -extern HANDLE hActiveQ_G; /* from message.c */ - /*********************************************************************** * WINPOS_FindIconPos @@ -89,11 +87,11 @@ void WINPOS_FindIconPos( HWND hwnd ) /*********************************************************************** * ArrangeIconicWindows (USER.170) */ -WORD ArrangeIconicWindows( HWND parent ) +UINT ArrangeIconicWindows( HWND parent ) { RECT rectParent; HWND hwndChild; - short x, y, xspacing, yspacing; + INT x, y, xspacing, yspacing; GetClientRect( parent, &rectParent ); x = rectParent.left; @@ -153,9 +151,10 @@ void GetClientRect( HWND hwnd, LPRECT rect ) /******************************************************************* * ClientToScreen (USER.28) */ -void ClientToScreen( HWND hwnd, LPPOINT lppnt ) +BOOL ClientToScreen( HWND hwnd, LPPOINT lppnt ) { MapWindowPoints( hwnd, 0, lppnt, 1 ); + return TRUE; } @@ -168,39 +167,82 @@ void ScreenToClient( HWND hwnd, LPPOINT lppnt ) } +/******************************************************************* + * WINPOS_WindowFromPoint + * + * The Right Thing + */ +HWND WINPOS_WindowFromPoint( HWND hScope, POINT pt, WORD* lpht ) +{ + WORD wRet; + WND* wndPtr = WIN_FindWndPtr( hScope ); + + if( !wndPtr || !(wndPtr->dwStyle & WS_VISIBLE) ) return 0; + + if ((pt.x < wndPtr->rectWindow.left) || + (pt.x >= wndPtr->rectWindow.right) || + (pt.y < wndPtr->rectWindow.top) || + (pt.y >= wndPtr->rectWindow.bottom)) return 0; + + /* pt is inside hScope window */ + + if( wndPtr->dwStyle & WS_DISABLED ) + if( wndPtr->dwStyle & (WS_POPUP | WS_CHILD) == WS_CHILD ) + return 0; + else + { + if( lpht ) *lpht = HTERROR; + return hScope; + } + + if( wndPtr->dwStyle & WS_MINIMIZE ) + { + if( lpht ) *lpht = HTCAPTION; + return hScope; + } + + if( PtInRect(&wndPtr->rectClient, pt)) + { + /* look among children */ + HWND hwnd = wndPtr->hwndChild; + WND* wndChild = WIN_FindWndPtr(hwnd); + POINT ptChild = { pt.x - wndPtr->rectClient.left, + pt.y - wndPtr->rectClient.top }; + + while( wndChild ) + { + if( (hwnd = WINPOS_WindowFromPoint(hwnd, ptChild, lpht)) ) + return hwnd; + + hwnd = wndChild->hwndNext; + wndChild = WIN_FindWndPtr( hwnd ); + } + } + + /* don't do intertask sendmessage */ + if( wndPtr->hmemTaskQ == GetTaskQueue(0) ) + { + if( wndPtr->dwStyle & WS_CHILD ) + MapWindowPoints( hScope, GetDesktopWindow(), &pt, 1); + + wRet = SendMessage( hScope, WM_NCHITTEST, 0, MAKELONG( pt.x, pt.y )); + if( wRet == (WORD)HTTRANSPARENT ) + return 0; + } + else + wRet = HTCLIENT; + + if( lpht ) *lpht = wRet; + return hScope; +} + + /******************************************************************* * WindowFromPoint (USER.30) */ HWND WindowFromPoint( POINT pt ) { - HWND hwndRet = 0; - HWND hwnd = GetDesktopWindow(); - - while(hwnd) - { - /* If point is in window, and window is visible, */ - /* not disabled and not transparent, then explore */ - /* its children. Otherwise, go to the next window. */ - - WND *wndPtr = WIN_FindWndPtr( hwnd ); - if ((pt.x >= wndPtr->rectWindow.left) && - (pt.x < wndPtr->rectWindow.right) && - (pt.y >= wndPtr->rectWindow.top) && - (pt.y < wndPtr->rectWindow.bottom) && - !(wndPtr->dwStyle & WS_DISABLED) && - (wndPtr->dwStyle & WS_VISIBLE) && - !(wndPtr->dwExStyle & WS_EX_TRANSPARENT)) - { - hwndRet = hwnd; - /* If window is minimized, ignore its children */ - if (wndPtr->dwStyle & WS_MINIMIZE) break; - pt.x -= wndPtr->rectClient.left; - pt.y -= wndPtr->rectClient.top; - hwnd = wndPtr->hwndChild; - } - else hwnd = wndPtr->hwndNext; - } - return hwndRet; + return WINPOS_WindowFromPoint( GetDesktopWindow(), pt , NULL ); } @@ -235,6 +277,8 @@ void MapWindowPoints( HWND hwndFrom, HWND hwndTo, LPPOINT lppt, WORD count ) POINT origin = { 0, 0 }; WORD i; + if( hwndFrom == hwndTo ) return; + /* Translate source window origin to screen coords */ while(hwndFrom) { @@ -602,6 +646,7 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus ) FARPROC enumCallback = (FARPROC)GetWndProcEntry16("ActivateAppProc"); ACTIVATESTRUCT actStruct; WORD wIconized=0,wRet= 0; + HANDLE hActiveQ = 0; /* paranoid checks */ if( !hWnd || hWnd == GetDesktopWindow() || hWnd == hwndActive ) @@ -676,10 +721,16 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus ) if( !IsWindow(hWnd) ) return 0; - /* send WM_ACTIVATEAPP if necessary */ - if( hActiveQ_G != wndPtr->hmemTaskQ ) + if (hwndPrevActive) { - HTASK hT = MSG_GetQueueTask( hActiveQ_G ); + wndTemp = WIN_FindWndPtr( hwndPrevActive ); + if (wndTemp) hActiveQ = wndTemp->hmemTaskQ; + } + + /* send WM_ACTIVATEAPP if necessary */ + if (hActiveQ != wndPtr->hmemTaskQ) + { + HTASK hT = MSG_GetQueueTask( hActiveQ ); actStruct.wFlag = 0; /* deactivate */ actStruct.hWindowTask = MSG_GetQueueTask(wndPtr->hmemTaskQ); @@ -690,12 +741,9 @@ BOOL WINPOS_SetActiveWindow( HWND hWnd, BOOL fMouse, BOOL fChangeFocus ) */ EnumWindows( enumCallback , (LPARAM)&actStruct ); - /* change active queue */ - hActiveQ_G = wndPtr->hmemTaskQ; - actStruct.wFlag = 1; /* activate */ actStruct.hWindowTask = hT; - actStruct.hTaskSendTo = MSG_GetQueueTask( hActiveQ_G ); + actStruct.hTaskSendTo = MSG_GetQueueTask( wndPtr->hmemTaskQ ); EnumWindows( enumCallback , (LPARAM)&actStruct ); @@ -964,6 +1012,11 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y, if (hwnd == GetDesktopWindow()) return FALSE; if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE; + /* Check for windows that may not be resized + FIXME: this should be done only for Windows 3.0 programs */ + if (flags ==(SWP_SHOWWINDOW) || flags ==(SWP_HIDEWINDOW ) ) + flags |= SWP_NOSIZE | SWP_NOMOVE; + /* Check dimensions */ if (cx <= 0) cx = 1; diff --git a/wine.ini b/wine.ini index faa56fcad39..51a6745e713 100644 --- a/wine.ini +++ b/wine.ini @@ -1,36 +1,59 @@ - -[drives] -A=/mnt/fd0 -C=/dos -D=/usr/windows -E=/home/bob/wine/work -F=/home/bob/test - -[wine] -Windows=c:\windows -System=c:\windows\system -Temp=c:\temp -Path=c:\windows;c:\windows\system;e:\;e:\test;f:\ -SymbolTableFile=./wine.sym - -[fonts] -system=*-helvetica -mssansserif=*-helvetica -msserif=*-times -fixedsys=*-fixed -arial=*-helvetica -helv=*-helvetica -roman=*-times -default=*-* - -[serialports] -Com1=/dev/cua0 -Com2=/dev/cua1 -Com3=/dev/modem,38400 -Com4=/dev/modem - -[parallelports] -Lpt1=/dev/lp0 - -[spy] -Exclude=WM_SIZE;WM_TIMER; +;; +;; MS-DOS drives configuration +;; +;; Each section has the following format: +;; [Drive X] +;; Path=xxx (Unix path for drive root) +;; Type=xxx (supported types are 'floppy', 'hd', 'cdrom' and 'network') +;; Label=xxx (drive label, at most 11 characters) +;; Serial=xxx (serial number, 8 characters hexadecimal number) +;; +[Drive A] +Path=/mnt/fd0 +Type=floppy +Label=Floppy +Serial=87654321 + +[Drive C] +Path=/c +Type=hd +Label=MS-DOS + +[Drive D] +Path=/cdrom +Type=cdrom +Label=CD-Rom + +[Drive E] +Path=/tmp +Type=hd +Label=Tmp Drive + +[wine] +Windows=c:\windows +System=c:\windows\system +Temp=e:\ +Path=c:\windows;c:\windows\system;e:\;e:\test;f:\ +SymbolTableFile=./wine.sym + +[fonts] +system=*-helvetica +mssansserif=*-helvetica +msserif=*-times +fixedsys=*-fixed +arial=*-helvetica +helv=*-helvetica +roman=*-times +default=*-* + +[serialports] +Com1=/dev/cua0 +Com2=/dev/cua1 +Com3=/dev/modem,38400 +Com4=/dev/modem + +[parallelports] +Lpt1=/dev/lp0 + +[spy] +Exclude=WM_SIZE;WM_TIMER; diff --git a/wine.man b/wine.man index f585a534afb..11a4ad8b6ca 100644 --- a/wine.man +++ b/wine.man @@ -44,12 +44,16 @@ must be installed. (It is probably available from the same site was, or the sources may be FTP'd from ftp.x.org). .SH INSTALLATION To install -.B wine, +.B Wine, run "./configure", which will detect your specific setup and create the Makefiles. You can run "./configure --help" to see the available configuration options. Then do "make depend; make" to build the .B wine -executable. +executable, and then "make install" to install it. By default, +.B wine +is installed in /usr/local/bin; you can specify a different path with +the --prefix option when running +.B configure. .SH OPTIONS .TP .I -depth n @@ -115,7 +119,7 @@ OLECLI, OLESVR, COMPOBJ, STORAGE, WINPROCS, DDEML Read only files may be opened in write mode .TP .I -enhanced -Starts wine in Enhanced mode (not guaranteed to work yet) +Starts wine in Enhanced mode .PD 1 .SH PROGRAM/ARGUMENTS The program name may be specified in DOS format (C:\\WINDOWS\\SOL.EXE) or in @@ -130,31 +134,70 @@ them together in quotation marks. Multiple applications may be started by placing all of them on the command line (such as: wine notepad clock). .SH CONFIGURATION FILE .B wine -expects a configuration file (/usr/local/etc/wine.conf), -which should conform to the following rules. The actual file name may -be specified during the execution of the +expects a configuration file (/usr/local/etc/wine.conf), which should +conform to the following rules (the format is just like a Windows .ini +file). The actual file name may be specified during the execution of +the .B configure script. Alternatively, you may have a .I .winerc file of this format in your home directory. .SH CONFIGURATION FILE FORMAT -.B [drives] +All entries are grouped in sections; a section begins with the line .br -.I format: = +.I [section name] .br -default: none +and continues until the next section starts. Individual entries +consist of lines of the form .br -This section is used to specify the root directory of each +.I entry=value +.br +The value can be any text string, optionally included in single or +double quotes; it can also contain references to environment variables +surrounded by +.I ${}. +Supported section names and entries are listed below. +.PP +.B [Drive X] +.br +This section is used to specify the root directory and type of each .B DOS drive, since most Windows applications require a DOS/MS-Windows based -disk drive & directory scheme. +disk drive & directory scheme. There is one such section for every +drive you want to configure. +.PP +.I format: Path = +.br +default: none .br If you mounted your dos partition as .I /dos and installed Microsoft Windows in C:\\WINDOWS then you should specify -.I c=/dos -in the drives section. +.I Path=/dos +in the +.I [Drive C] +section. +.PP +.I format: Type = +.br +default: hd +.br +Used to specify the drive type; supported types are floppy, hd, cdrom +and network. +.PP +.I format: Label =