From fa68b75badd3ebff62a2d309174e5728ec5fbad0 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard <julliard@winehq.org> Date: Mon, 3 Apr 1995 16:55:37 +0000 Subject: [PATCH] Release 950403 Sun Apr 2 18:31:12 1995 Alexandre Julliard (julliard@sunsite.unc.edu) * [Configure] [if1632/Imakefile] Removed new build and short names options. * [if1632/*.c] [tools/build.c] Implemented compiled call-back functions for better performance; all the relay code is now done in assembly code generated by the build program. Relay code is no longer dependent on being loaded below 64K. * [loader/resource.c] Fixed memory leak in LoadString(). A fix will also be needed for other resources. * [memory/global.c] Implemented global heap arenas, so we can store informations about global blocks, like lock counts or owner handle. Implemented FarGetOwner() and FarSetOwner(). Implemented global heap TOOLHELP functions. * [memory/selector.c] Bug fix: it was not possible to re-use a free selector. Sun Apr 2 01:34:52 1995 Constantine Sapuntzakis (csapuntz@mit.edu) * [controls/listbox.c] Major work on listbox code - Many bugs fixed (still many bugs) - More messages supported - Code simplified Fri Mar 31 03:27:16 EST 1995 William Magro (wmagro@tc.cornell.edu) * [controls/edit.c] Lots of bug fixes related to diappearing text, lost carets, highlighting, segmentation faults, occurance of random characters, insertion of characters over selection, misplaced caret location, display corruption, end of line behavior, etc. * [controls/widgets.c] EDIT class doesn't want to use CS_PARENTDC flag. Thu Mar 30 20:58:25 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de> * [loader/selector.c] FixupFunctionPrologs() should also handle multiple data modules. (this bug only became visible because MakeProcInstance() was fixed in 950319) * [misc/dosfs.c] Simplified DOS_SimplifyPath. Small fix to DOS_opendir to reuse an entry if an open directory is opened again, to prevent "too many open directories" messages. Thu Mar 30 12:05:05 1995 Martin von Loewis <loewis@informatik.hu-berlin.de> * [if1632/compobj.spec][include/compobj.h][misc/compobj.c] CoDisconnectObject: new stub function * [include/msdos.h] fix DOSVERSION * [loader/ne_image.c] NE_FixupSegment: Be more generous on additive fixups * [if1632/user.spec][misc/network.c] Add more WNet* stubs Wed Mar 29 11:47:22 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de> * [controls/listbox.c] DlgDirList(): send segptr instead of linear pointer in message to static control * [controls/menu.c] Tried to implement ownerdrawn menuitems. Doesn't work. * [if1632/gdi.spec] [include/windows.h] [objects/font.c] Provide a stub for GetRasterizerCaps() * [loader/selector.c] Pass end address instead of length to LocalInit() in CreateSelectors() * [memory/local.c] LocalInit(): If there's already a local heap in the segment, do nothing and return TRUE * [objects/linedda.c] Replaced buggy LineDDA() with a Bresenham algorithm. Should work now. * [windows/cursor.c] LoadCursor()/CreateCursor(): Cleaned up the mess. Needs some more work still. Tue Mar 21 17:54:43 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de> * [if1632/relay.c] [if1632/callback.c] [include/dlls.h] [if1632/winprocs.spec] [if1632/winprocs.c] [include/winprocs.h] [controls/widgets.c] [misc/shell.c] [misc/commdlg.c] [windows/nonclient.c] [misc/message.c] Added a new builtin DLL that provides 16 bit entry points for all the Def*Procs (DefDlgProc, ButtonProc etc.). OWL programs work again. * [misc/shell.c] RegOpenKey()/RegCreateKey() bugs fixed. * [loader/ne_image.c] Skipping the initialization of a DLL when CS == 0 was broken. --- ANNOUNCE | 24 +- ChangeLog | 106 ++ Configure | 26 +- Imakefile | 6 +- RELEASE-NOTES | 3 - Wine.tmpl | 31 - controls/edit.c | 160 ++- controls/listbox.c | 2928 ++++++++++++++++++++++++++--------------- controls/menu.c | 55 +- controls/widgets.c | 49 +- debugger/info.c | 5 +- if1632/Imakefile | 83 +- if1632/call.S | 530 -------- if1632/callback.c | 192 +-- if1632/compobj.spec | 2 +- if1632/gdi.spec | 2 +- if1632/kernel.spec | 8 +- if1632/olecli.spec | 4 +- if1632/relay.c | 420 +++--- if1632/toolhelp.spec | 12 +- if1632/user.spec | 52 +- if1632/winprocs.spec | 27 + include/callback.h | 94 +- include/compobj.h | 5 + include/debug.h | 57 +- include/dlls.h | 132 +- include/global.h | 16 + include/hook.h | 4 +- include/if1632.h | 7 +- include/listbox.h | 8 +- include/local.h | 6 +- include/msdos.h | 2 +- include/neexe.h | 14 +- include/registers.h | 2 + include/selectors.h | 14 +- include/stackframe.h | 22 +- include/stddebug.h | 2 - include/toolhelp.h | 70 +- include/windows.h | 13 +- include/wine.h | 9 +- loader/dump.c | 4 +- loader/library.c | 10 +- loader/ne_image.c | 62 +- loader/resource.c | 14 +- loader/selector.c | 191 ++- loader/signal.c | 34 - loader/task.c | 8 +- memory/global.c | 292 +++- memory/local.c | 23 +- memory/selector.c | 18 +- misc/Imakefile | 1 + misc/commdlg.c | 22 +- misc/compobj.c | 25 + misc/dos_fs.c | 68 +- misc/exec.c | 6 +- misc/file.c | 8 - misc/main.c | 15 +- misc/message.c | 5 +- misc/network.c | 257 ++++ misc/property.c | 11 +- misc/shell.c | 5 +- miscemu/emulate.c | 19 +- miscemu/int21.c | 6 +- miscemu/kernel.c | 22 +- multimedia/mmsystem.c | 11 +- objects/font.c | 37 +- objects/gdiobj.c | 29 +- objects/linedda.c | 59 +- toolkit/sup.c | 15 - tools/Imakefile | 4 - tools/build-spec.txt | 35 +- tools/build.c | 1261 +++++++++++------- tools/newbuild.c | 958 -------------- windows/caret.c | 11 +- windows/cursor.c | 149 ++- windows/message.c | 6 +- windows/nonclient.c | 3 +- windows/utility.c | 7 +- windows/win.c | 56 +- 79 files changed, 4489 insertions(+), 4480 deletions(-) delete mode 100644 if1632/call.S create mode 100644 if1632/winprocs.spec create mode 100644 include/compobj.h create mode 100644 include/global.h create mode 100644 misc/compobj.c delete mode 100644 tools/newbuild.c diff --git a/ANNOUNCE b/ANNOUNCE index 8b5e5191df9..f1033c99228 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,17 +1,17 @@ -This is release 950319 of Wine the MS Windows emulator. This is still a +This is release 950403 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 Sunday. -WHAT'S NEW with Wine-950319: (see ChangeLog for details) - - New memory management scheme. This will probably cause many - new problems, please report them. I'm particularly interested - to hear how it works for the *BSD people. - - Many fixes in file and directory handling. - - Handling of additive fixup records. - - Lots of bug fixes +WHAT'S NEW with Wine-950403: (see ChangeLog for details) + - Compiled callbacks for better performance. + - Many listbox fixes. + - Many edit control fixes. + - 16-bit entry points for built-in window procedures to make + Borland programs happy. + - Lots of bug fixes. See the README file in the distribution for installation instructions. @@ -19,10 +19,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-950319.tar.gz - tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-950319.tar.gz - ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-950319.tar.gz - ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-950319.tar.gz + sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-950403.tar.gz + tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-950403.tar.gz + ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-950403.tar.gz + ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-950403.tar.gz It should also be available from any site that mirrors tsx-11 or sunsite. diff --git a/ChangeLog b/ChangeLog index 1f66b98a3a3..dae439c7adb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,109 @@ +---------------------------------------------------------------------- +Sun Apr 2 18:31:12 1995 Alexandre Julliard (julliard@sunsite.unc.edu) + + * [Configure] [if1632/Imakefile] + Removed new build and short names options. + + * [if1632/*.c] [tools/build.c] + Implemented compiled call-back functions for better performance; + all the relay code is now done in assembly code generated by the + build program. + Relay code is no longer dependent on being loaded below 64K. + + * [loader/resource.c] + Fixed memory leak in LoadString(). A fix will also be needed for + other resources. + + * [memory/global.c] + Implemented global heap arenas, so we can store informations about + global blocks, like lock counts or owner handle. + Implemented FarGetOwner() and FarSetOwner(). + Implemented global heap TOOLHELP functions. + + * [memory/selector.c] + Bug fix: it was not possible to re-use a free selector. + +Sun Apr 2 01:34:52 1995 Constantine Sapuntzakis (csapuntz@mit.edu) + + * [controls/listbox.c] + Major work on listbox code + - Many bugs fixed (still many bugs) + - More messages supported + - Code simplified + +Fri Mar 31 03:27:16 EST 1995 William Magro (wmagro@tc.cornell.edu) + + * [controls/edit.c] + Lots of bug fixes related to diappearing text, lost carets, + highlighting, segmentation faults, occurance of random + characters, insertion of characters over selection, misplaced + caret location, display corruption, end of line behavior, etc. + + * [controls/widgets.c] + EDIT class doesn't want to use CS_PARENTDC flag. + +Thu Mar 30 20:58:25 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de> + + * [loader/selector.c] + FixupFunctionPrologs() should also handle multiple data modules. + (this bug only became visible because MakeProcInstance() was fixed + in 950319) + + * [misc/dosfs.c] + Simplified DOS_SimplifyPath. + Small fix to DOS_opendir to reuse an entry if an open directory + is opened again, to prevent "too many open directories" messages. + +Thu Mar 30 12:05:05 1995 Martin von Loewis <loewis@informatik.hu-berlin.de> + + * [if1632/compobj.spec][include/compobj.h][misc/compobj.c] + CoDisconnectObject: new stub function + + * [include/msdos.h] + fix DOSVERSION + + * [loader/ne_image.c] + NE_FixupSegment: Be more generous on additive fixups + + * [if1632/user.spec][misc/network.c] + Add more WNet* stubs + +Wed Mar 29 11:47:22 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de> + + * [controls/listbox.c] + DlgDirList(): send segptr instead of linear pointer + in message to static control + * [controls/menu.c] + Tried to implement ownerdrawn menuitems. Doesn't work. + * [if1632/gdi.spec] [include/windows.h] [objects/font.c] + Provide a stub for GetRasterizerCaps() + * [loader/selector.c] + Pass end address instead of length to LocalInit() in + CreateSelectors() + * [memory/local.c] + LocalInit(): If there's already a local heap in the segment, do + nothing and return TRUE + * [objects/linedda.c] + Replaced buggy LineDDA() with a Bresenham algorithm. Should work + now. + * [windows/cursor.c] + LoadCursor()/CreateCursor(): Cleaned up the mess. Needs some + more work still. + +Tue Mar 21 17:54:43 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de> + + * [if1632/relay.c] [if1632/callback.c] [include/dlls.h] + [if1632/winprocs.spec] [if1632/winprocs.c] [include/winprocs.h] + [controls/widgets.c] [misc/shell.c] [misc/commdlg.c] + [windows/nonclient.c] [misc/message.c] + Added a new builtin DLL that provides 16 bit entry points for all + the Def*Procs (DefDlgProc, ButtonProc etc.). OWL programs work + again. + * [misc/shell.c] + RegOpenKey()/RegCreateKey() bugs fixed. + * [loader/ne_image.c] + Skipping the initialization of a DLL when CS == 0 was broken. + ---------------------------------------------------------------------- Sun Mar 19 16:30:20 1995 Alexandre Julliard (julliard@sunsite.unc.edu) diff --git a/Configure b/Configure index b1b4a6d62f1..892e481a8ba 100644 --- a/Configure +++ b/Configure @@ -6,9 +6,7 @@ : ${PAGER:=more} WINELIB='' -SHORTNAMES='' LANGUAGE=not_matching -NEWBUILD='' ALLDEFINES='' # Ask question 'str' and set 'var' to reply (defaulting to 'def' on CR) @@ -28,6 +26,7 @@ prompt () fi } +echo echo Read the RELEASE-NOTES for an explanation of the various flags echo @@ -39,15 +38,6 @@ then ALLDEFINES="$ALLDEFINES -DWINELIB" fi -echo -echo -n 'Short filenames (Y/N) [N]? ' -read input -if [ "$input" = 'y' -o "$input" = 'Y' ] -then - SHORTNAMES='#define ShortNames -DSHORTNAMES' - ALLDEFINES="$ALLDEFINES -DSHORTNAMES" -fi - LANGS=`echo En rc/sysres_*.rc | sed -e 's/rc\/sysres_//g' -e 's/\.rc//g' -e 's/ /\//g;'` while expr "$LANGS" : ".*$LANGUAGE" = 0 > /dev/null do @@ -68,18 +58,6 @@ else MALLOC_DEBUGGING='' fi -if [ "`(domainname)`" = 'amscons.com' ] -then - echo - echo -n 'New build program (Y/N) [N]? ' - read input - if [ "$input" = 'y' -o "$input" = 'Y' ] - then - NEWBUILD='#define NewBuild -DNEWBUILD' - ALLDEFINES="$ALLDEFINES -DNEWBUILD" - fi -fi - prompt "Global configfile name" WINE_CONFIGFILE /usr/local/etc/wine.conf if [ -r $WINE_CONFIGFILE ] @@ -197,8 +175,6 @@ fi cat > autoconf.h << EOF /* autoconf.h generated automatically. Run Configure. */ $WINELIB -$SHORTNAMES -$NEWBUILD $MALLOC_DEBUGGING #define WINE_INI_GLOBAL "$WINE_CONFIGFILE" #define AutoDefines $ALLDEFINES diff --git a/Imakefile b/Imakefile index 8405d0a350a..33ee8876824 100644 --- a/Imakefile +++ b/Imakefile @@ -58,13 +58,9 @@ COMMONOBJS = \ rc/rc.o \ windows/windows.o -/* - * WARNING: if1632.o must be the first object file because its code must be - * linked at the lowest possible addresses. - */ EMUOBJS = \ - if1632/if1632.o \ debugger/debugger.o \ + if1632/if1632.o \ memory/memory.o \ miscemu/miscemu.o diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 8d53b913a31..85028b1035c 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -15,9 +15,6 @@ sure to analyze the problem before you report it to the newsgroup. Emulator/Library: You need an emulator when you want to run MS-Win binaries. You need a library when you want to compile the source code of a Windows program. -Short filenames: Some file systems are limited to 11 characters per -file name. Files generated in if1632 will get gracefully translated -names. Language: Wine can present the system menu in multiple languages. Select one of English, German, or Norwegian here. Malloc debugging: When enabled, the mtrace and mcheck GNU libc functions diff --git a/Wine.tmpl b/Wine.tmpl index e1f7e0b6287..1cc33203f2d 100644 --- a/Wine.tmpl +++ b/Wine.tmpl @@ -1,38 +1,7 @@ -XCOMM $Id$ - INCLUDES = -I$(TOP)/include -I$(TOP) XCOMM Imake rules go here -XCOMM First, dll description to files etc -#ifndef MakeDllFromSpec -#ifndef NewBuild -#ifndef ShortNames -#define MakeDllFromSpec(name) @@\ -Concat(dll_,name.S) Concat3(dll_,name,_tab.c): name.spec $(TOP)/tools/build @@\ - $(TOP)/tools/build name.spec @@\ - -#else /* ShortNames */ -#define MakeDllFromSpec(name) @@\ -Concat(dll_,name.S) Concat(dtb_,name.c): name.spec $(TOP)/tools/build @@\ - $(TOP)/tools/build name.spec @@\ - -#endif /* ShortNames */ -#else /* NewBuild */ -#ifndef ShortNames -#define MakeDllFromSpec(name) @@\ -Concat(dll_,name.S) Concat(rly_,name.S) Concat3(dll_,name,_tab.c): name.spec $(TOP)/tools/newbuild @@\ - $(TOP)/tools/newbuild name.spec @@\ - -#else /* ShortNames */ -#define MakeDllFromSpec(name) @@\ -Concat(dll_,name.S) Concat(rly_,name.S) Concat(dtb_,name.c): name.spec $(TOP)/tools/newbuild @@\ - $(TOP)/tools/newbuild name.spec @@\ - -#endif /* ShortNames */ -#endif /* NewBuild */ -#endif /* MakeDllFromSpec */ - /* * WineRelocatableTarget - generate rules to produce a relocatable object * file instead of a library. diff --git a/controls/edit.c b/controls/edit.c index 5a42a133d57..2109aa3a564 100644 --- a/controls/edit.c +++ b/controls/edit.c @@ -4,6 +4,7 @@ * Copyright David W. Metcalfe, 1994 * * Release 3, July 1994 + * April 1995 bug fixes (William Magro) static char Copyright[] = "Copyright David W. Metcalfe, 1994"; */ @@ -65,6 +66,7 @@ typedef struct int DeletedCurrCol; /* starting col from which text was deleted */ int NumTabStops; /* number of tab stops in buffer hTabStops */ HANDLE hTabStops; /* handle of tab stops buffer */ + BOOL HaveFocus; /* TRUE if this edit has the focus */ } EDITSTATE; @@ -147,7 +149,7 @@ void EDIT_DeleteSel(HWND hwnd); void EDIT_ClearSel(HWND hwnd); int EDIT_TextLineNumber(HWND hwnd, char *lp); void EDIT_SetAnchor(HWND hwnd, int row, int col); -void EDIT_ExtendSel(HWND hwnd, int x, int y); +void EDIT_ExtendSel(HWND hwnd, INT x, INT y); void EDIT_WriteSel(HWND hwnd, int y, int start, int end); void EDIT_StopMarking(HWND hwnd); LONG EDIT_GetLineMsg(HWND hwnd, WORD wParam, LONG lParam); @@ -380,29 +382,32 @@ LONG EditWndProc(HWND hwnd, WORD uMsg, WORD wParam, LONG lParam) break; case WM_KILLFOCUS: + es->HaveFocus = FALSE; DestroyCaret(); + if (SelMarked(es)) EDIT_ClearSel(hwnd); NOTIFY_PARENT(hwnd, EN_KILLFOCUS); break; case WM_LBUTTONDOWN: HideCaret(hwnd); SetFocus(hwnd); + SetCapture(hwnd); EDIT_LButtonDownMsg(hwnd, wParam, lParam); SetCaretPos(es->WndCol, es->WndRow * es->txtht); ShowCaret(hwnd); break; case WM_LBUTTONUP: + if (GetCapture() != hwnd) break; + ReleaseCapture(); ButtonDown = FALSE; if (TextMarking) EDIT_StopMarking(hwnd); break; case WM_MOUSEMOVE: - HideCaret(hwnd); - EDIT_MouseMoveMsg(hwnd, wParam, lParam); - SetCaretPos(es->WndCol, es->WndRow * es->txtht); - ShowCaret(hwnd); + if (es->HaveFocus) + EDIT_MouseMoveMsg(hwnd, wParam, lParam); break; case WM_MOVE: @@ -422,6 +427,7 @@ LONG EditWndProc(HWND hwnd, WORD uMsg, WORD wParam, LONG lParam) break; case WM_SETFOCUS: + es->HaveFocus = TRUE; CreateCaret(hwnd, 0, 2, es->txtht); SetCaretPos(es->WndCol, es->WndRow * es->txtht); ShowCaret(hwnd); @@ -506,6 +512,8 @@ long EDIT_NCCreateMsg(HWND hwnd, LONG lParam) es->wlines = 0; es->textwidth = 0; EDIT_ClearTextPointers(hwnd); + if(IsMultiLine()) strcpy(text, "\r\n"); + EDIT_BuildTextPointers(hwnd); } else { @@ -516,14 +524,18 @@ long EDIT_NCCreateMsg(HWND hwnd, LONG lParam) es->hText = EDIT_HeapAlloc(hwnd, EditBufLen(wndPtr) + 2); text = EDIT_HeapAddr(hwnd, es->hText); strcpy(text, windowName); + if(IsMultiLine()) strcat(text, "\r\n"); + es->textlen += 2; *(text + es->textlen) = '\0'; } else { - es->hText = EDIT_HeapAlloc(hwnd, strlen(windowName) + 2); + es->hText = EDIT_HeapAlloc(hwnd, strlen(windowName) + 4); text = EDIT_HeapAddr(hwnd, es->hText); strcpy(text, windowName); - es->textlen = strlen(windowName) + 1; + if(IsMultiLine()) strcat(text, "\r\n"); + es->textlen = strlen(windowName) + 3; + *(text + es->textlen) = '\0'; } *(text + es->textlen + 1) = '\0'; EDIT_BuildTextPointers(hwnd); @@ -727,7 +739,7 @@ void EDIT_PaintMsg(HWND hwnd) for (y = (rc.top / es->txtht); y <= (rc.bottom / es->txtht); y++) { - if (y < es->wlines - es->wtop) + if (y < (IsMultiLine() ? es->wlines : 1) - es->wtop) EDIT_WriteTextLine(hwnd, &rc, y + es->wtop); } @@ -885,17 +897,23 @@ void EDIT_WriteTextLine(HWND hwnd, RECT *rect, int y) lnlen1 = lnlen; /* build the line to display */ - if (lnlen < es->wleft) + if (lnlen < (es->wleft + rc.left)) + { lnlen = 0; + return; + } else + { off += es->wleft; + lnlen -= off; + } if (lnlen > rc.left) { off += rc.left; lnlen = lnlen1 - off; - len = min(lnlen, rc.right - rc.left); } + len = min(lnlen, rc.right - rc.left); if (SelMarked(es)) { @@ -1141,7 +1159,7 @@ HANDLE EDIT_GetStr(HWND hwnd, char *lp, int off, int len, int *diff) str = (char *)EDIT_HeapAddr(hwnd, hStr); for (i = ch1, j = 0; i < ch; i++, j++) str[j] = lp[i]; - str[++j] = '\0'; + str[j] = '\0'; dprintf_edit(stddeb,"EDIT_GetStr: returning %s\n", str); return hStr; } @@ -1193,7 +1211,7 @@ void EDIT_KeyTyped(HWND hwnd, short ch) EDITSTATE *es = (EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra))); char *text = EDIT_HeapAddr(hwnd, es->hText); - char *currchar = CurrChar; + char *currchar; RECT rc; BOOL FullPaint = FALSE; @@ -1203,6 +1221,9 @@ void EDIT_KeyTyped(HWND hwnd, short ch) if (SelMarked(es)) EDIT_DeleteSel(hwnd); + /* currchar must be assigned after deleting the selection */ + currchar = CurrChar; + /* test for typing at end of maximum buffer size */ if (currchar == text + es->MaxTextLen) { @@ -1271,7 +1292,6 @@ void EDIT_KeyTyped(HWND hwnd, short ch) else es->textwidth = max(es->textwidth, EDIT_StrLength(hwnd, text, strlen(text), 0)); - EDIT_WriteTextLine(hwnd, NULL, es->wtop + es->WndRow); if (ch == '\n') { @@ -1306,6 +1326,7 @@ void EDIT_KeyTyped(HWND hwnd, short ch) } es->WndCol += EDIT_CharWidth(hwnd, (BYTE)ch, es->WndCol + es->wleft); es->CurrCol++; + EDIT_WriteTextLine(hwnd, NULL, es->wtop + es->WndRow); SetCaretPos(es->WndCol, es->WndRow * es->txtht); ShowCaret(hwnd); NOTIFY_PARENT(hwnd, EN_CHANGE); @@ -1382,8 +1403,11 @@ void EDIT_Forward(HWND hwnd) if (*CurrChar == '\r') { - EDIT_Home(hwnd); - EDIT_Downward(hwnd); + if (es->CurrLine < (es->wlines - 1)) + { + EDIT_Home(hwnd); + EDIT_Downward(hwnd); + } } else { @@ -1549,7 +1573,7 @@ void EDIT_StickEnd(HWND hwnd) (EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra))); int len = EDIT_LineLength(hwnd, es->CurrLine); char *cp = EDIT_TextLine(hwnd, es->CurrLine); - char currpel; + int currpel; es->CurrCol = min(len, es->CurrCol); es->WndCol = min(EDIT_StrLength(hwnd, cp, len, 0) - es->wleft, es->WndCol); @@ -2150,22 +2174,22 @@ void EDIT_LButtonDownMsg(HWND hwnd, WORD wParam, LONG lParam) EDIT_ClearSel(hwnd); es->WndRow = HIWORD(lParam) / es->txtht; - if (es->WndRow > es->wlines - es->wtop - 1) + if (!IsMultiLine()) + es->WndRow = 0; + else if (es->WndRow > es->wlines - es->wtop - 1) { - if (es->wlines) - es->WndRow = es->wlines - es->wtop - 1; - else - es->WndRow = 0; + es->WndRow = es->wlines - es->wtop - 1; end = TRUE; } es->CurrLine = es->wtop + es->WndRow; cp = EDIT_TextLine(hwnd, es->CurrLine); len = EDIT_LineLength(hwnd, es->CurrLine); - es->WndCol = LOWORD(lParam); - if (es->WndCol > EDIT_StrLength(hwnd, cp, len, 0) - es->wleft || end) - es->WndCol = EDIT_StrLength(hwnd, cp, len, 0) - es->wleft; + es->WndCol = LOWORD(lParam) + es->wleft; + if (es->WndCol > EDIT_StrLength(hwnd, cp, len, 0) || end) + es->WndCol = EDIT_StrLength(hwnd, cp, len, 0); es->CurrCol = EDIT_PixelToChar(hwnd, es->CurrLine, &(es->WndCol)); + es->WndCol -= es->wleft; ButtonDown = TRUE; ButtonRow = es->CurrLine; @@ -2179,9 +2203,14 @@ void EDIT_LButtonDownMsg(HWND hwnd, WORD wParam, LONG lParam) void EDIT_MouseMoveMsg(HWND hwnd, WORD wParam, LONG lParam) { + WND *wndPtr = WIN_FindWndPtr(hwnd); + EDITSTATE *es = + (EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra))); + if (wParam != MK_LBUTTON) return; + HideCaret(hwnd); if (ButtonDown) { EDIT_SetAnchor(hwnd, ButtonRow, ButtonCol); @@ -2190,7 +2219,11 @@ void EDIT_MouseMoveMsg(HWND hwnd, WORD wParam, LONG lParam) } if (TextMarking) + { EDIT_ExtendSel(hwnd, LOWORD(lParam), HIWORD(lParam)); + SetCaretPos(es->WndCol, es->WndRow * es->txtht); + } + ShowCaret(hwnd); } @@ -2297,7 +2330,7 @@ void EDIT_ClearText(HWND hwnd) void EDIT_SetSelMsg(HWND hwnd, WORD wParam, LONG lParam) { - int so, eo; + INT so, eo; WND *wndPtr = WIN_FindWndPtr(hwnd); EDITSTATE *es = (EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra))); @@ -2313,7 +2346,7 @@ void EDIT_SetSelMsg(HWND hwnd, WORD wParam, LONG lParam) if (so == eo) /* if so == eo, set caret only */ { - EDIT_GetLineCol(hwnd, so, &(es->CurrLine), &(es->CurrCol)); + EDIT_GetLineCol(hwnd, (int) so, &(es->CurrLine), &(es->CurrCol)); es->WndRow = es->CurrLine - es->wtop; if (!wParam) @@ -2340,11 +2373,16 @@ void EDIT_SetSelMsg(HWND hwnd, WORD wParam, LONG lParam) } else /* otherwise set selection */ { - if (so > eo) - swap(&so, &eo); + if (eo >= 0 && so > eo) /* eo == -1 flag to extend to end of text */ + { + INT tmp; + tmp = so; + so = eo; + eo = tmp; + } - EDIT_GetLineCol(hwnd, so, &(es->SelBegLine), &(es->SelBegCol)); - EDIT_GetLineCol(hwnd, eo, &(es->SelEndLine), &(es->SelEndCol)); + EDIT_GetLineCol(hwnd, (int) so, &(es->SelBegLine), &(es->SelBegCol)); + EDIT_GetLineCol(hwnd, (int) eo, &(es->SelEndLine), &(es->SelEndCol)); es->CurrLine = es->SelEndLine; es->CurrCol = es->SelEndCol; es->WndRow = es->SelEndLine - es->wtop; @@ -2407,7 +2445,7 @@ void EDIT_GetLineCol(HWND hwnd, int off, int *line, int *col) return; } - if (off > strlen(text)) off = strlen(text); + if (off < 0 || off > strlen(text)) off = strlen(text); cp1 = text; for (lineno = 0; lineno < es->wlines; lineno++) { @@ -2536,8 +2574,10 @@ void EDIT_SetAnchor(HWND hwnd, int row, int col) (EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra))); if (SelMarked(es)) + { sel = TRUE; - EDIT_ClearSel(hwnd); + EDIT_ClearSel(hwnd); + } es->SelBegLine = es->SelEndLine = row; es->SelBegCol = es->SelEndCol = col; if (sel) @@ -2554,12 +2594,11 @@ void EDIT_SetAnchor(HWND hwnd, int row, int col) * Extend selection to the given screen co-ordinates. */ -void EDIT_ExtendSel(HWND hwnd, int x, int y) +void EDIT_ExtendSel(HWND hwnd, INT x, INT y) { int bbl, bel, bbc, bec; char *cp; int len, line; - BOOL end = FALSE; WND *wndPtr = WIN_FindWndPtr(hwnd); EDITSTATE *es = (EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra))); @@ -2568,28 +2607,31 @@ void EDIT_ExtendSel(HWND hwnd, int x, int y) bbl = es->SelEndLine; bbc = es->SelEndCol; - line = es->wtop + y / es->txtht; - if (line > es->wlines) - line = es->wlines; + y = max(y,0); + if (IsMultiLine()) + { + if ((line = es->wtop + y / es->txtht) >= es->wlines) + line = es->wlines - 1; + } + else + line = 0; + cp = EDIT_TextLine(hwnd, line); len = EDIT_LineLength(hwnd, line); es->WndRow = y / es->txtht; - if (es->WndRow > es->wlines - es->wtop - 1) - { - if (es->wlines) - es->WndRow = es->wlines - es->wtop - 1; - else + if (!IsMultiLine()) es->WndRow = 0; - end = TRUE; - } + else if (es->WndRow > es->wlines - es->wtop - 1) + es->WndRow = es->wlines - es->wtop - 1; es->CurrLine = es->wtop + es->WndRow; es->SelEndLine = es->CurrLine; - es->WndCol = x; - if (es->WndCol > EDIT_StrLength(hwnd, cp, len, 0) - es->wleft || end) - es->WndCol = EDIT_StrLength(hwnd, cp, len, 0) - es->wleft; + es->WndCol = es->wleft + max(x,0); + if (es->WndCol > EDIT_StrLength(hwnd, cp, len, 0)) + es->WndCol = EDIT_StrLength(hwnd, cp, len, 0); es->CurrCol = EDIT_PixelToChar(hwnd, es->CurrLine, &(es->WndCol)); + es->WndCol -= es->wleft; es->SelEndCol = es->CurrCol; bel = es->SelEndLine; @@ -2631,12 +2673,10 @@ void EDIT_ExtendSel(HWND hwnd, int x, int y) void EDIT_WriteSel(HWND hwnd, int y, int start, int end) { - RECT rc; + RECT rc, rcInvert; int scol, ecol; char *cp; HDC hdc; - HBRUSH hbrush, holdbrush; - int olddm; WND *wndPtr = WIN_FindWndPtr(hwnd); EDITSTATE *es = (EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra))); @@ -2660,20 +2700,19 @@ void EDIT_WriteSel(HWND hwnd, int y, int start, int end) * lines. I have kludged this by adding on two pixels to ecol and * to the line height in the call to Rectangle. */ - scol = EDIT_StrLength(hwnd, cp, start, 0); + scol = EDIT_StrLength(hwnd, cp, start, 0) - es->wleft; if (scol > rc.right) return; if (scol < rc.left) scol = rc.left; - ecol = EDIT_StrLength(hwnd, cp, end, 0) + 2; /* ??? */ + ecol = EDIT_StrLength(hwnd, cp, end, 0) - es->wleft; if (ecol < rc.left) return; if (ecol > rc.right) ecol = rc.right; hdc = GetDC(hwnd); - hbrush = GetStockObject(BLACK_BRUSH); - holdbrush = (HBRUSH)SelectObject(hdc, (HANDLE)hbrush); - olddm = SetROP2(hdc, R2_XORPEN); - Rectangle(hdc, scol, y * es->txtht, ecol, (y + 1) * es->txtht + 2); - SetROP2(hdc, olddm); - SelectObject(hdc, (HANDLE)holdbrush); + rcInvert.left = scol; + rcInvert.top = y * es->txtht; + rcInvert.right = ecol; + rcInvert.bottom = (y + 1) * es->txtht; + InvertRect(hdc, (LPRECT) &rcInvert); ReleaseDC(hwnd, hdc); } @@ -2931,7 +2970,10 @@ void EDIT_SaveDeletedText(HWND hwnd, char *deltext, int len, EDITSTATE *es = (EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra))); - es->hDeletedText = GlobalReAlloc(es->hDeletedText, len, GMEM_MOVEABLE); + if (!es->hDeletedText) + es->hDeletedText = GlobalAlloc( GMEM_MOVEABLE, len ); + else + es->hDeletedText = GlobalReAlloc(es->hDeletedText, len, GMEM_MOVEABLE); if (!es->hDeletedText) return; text = (char *)GlobalLock(es->hDeletedText); memcpy(text, deltext, len); diff --git a/controls/listbox.c b/controls/listbox.c index ebfab3aa566..58d204c762b 100644 --- a/controls/listbox.c +++ b/controls/listbox.c @@ -2,6 +2,7 @@ * Interface code to listbox widgets * * Copyright Martin Ayotte, 1993 + * Copyright Constantine Sapuntzakis, 1995 * static char Copyright[] = "Copyright Martin Ayotte, 1993"; */ @@ -23,11 +24,11 @@ static char Copyright[] = "Copyright Martin Ayotte, 1993"; #define GMEM_ZEROINIT 0x0040 - +LPLISTSTRUCT ListBoxGetItem (HWND hwnd, UINT uIndex); +int ListBoxScrolltoFocus(HWND hwnd); LPHEADLIST ListBoxGetWindowAndStorage(HWND hwnd, WND **wndPtr); LPHEADLIST ListBoxGetStorageHeader(HWND hwnd); -void StdDrawListBox(HWND hwnd); -void OwnerDrawListBox(HWND hwnd); +void RepaintListBox(HWND hwnd); int ListBoxFindMouse(HWND hwnd, int X, int Y); int CreateListBoxStruct(HWND hwnd); void ListBoxAskMeasure(WND *wndPtr, LPHEADLIST lphl, LPLISTSTRUCT lpls); @@ -50,10 +51,13 @@ int ListBoxFindNextMatch(HWND hwnd, WORD wChar); int ListMaxFirstVisible(LPHEADLIST lphl); void ListBoxSendNotification(HWND hwnd, WORD code); -#define HasStrings(wndPtr) ( \ - ( ((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) != LBS_OWNERDRAWFIXED) && \ - ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) != LBS_OWNERDRAWVARIABLE) ) || \ - ((wndPtr->dwStyle & LBS_HASSTRINGS) == LBS_HASSTRINGS) ) +#define OWNER_DRAWN(wndPtr) \ + ((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) || \ + (wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE)) + +#define HasStrings(wndPtr) ( \ + (! OWNER_DRAWN (wndPtr)) || \ + (wndPtr->dwStyle & LBS_HASSTRINGS)) #if 0 #define LIST_HEAP_ALLOC(lphl,f,size) ((int)HEAP_Alloc(&lphl->Heap,f,size) & 0xffff) @@ -68,724 +72,1436 @@ void ListBoxSendNotification(HWND hwnd, WORD code); #define LIST_HEAP_SIZE 0x10000 +/* Design notes go here */ + +LONG LBCreate( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBGetDlgCode( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBDestroy( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBVScroll( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBHScroll( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBLButtonDown( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBLButtonUp( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBRButtonUp( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBMouseMove( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBKeyDown( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBSetFont( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBSetRedraw( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBPaint( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBSetFocus( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBKillFocus( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBResetContent( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBDir( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBAddString( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBGetText( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBInsertString( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBDeleteString( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBFindString( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBGetCaretIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBGetCount( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBGetCurSel( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBGetHorizontalExtent(HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBGetItemData( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBGetItemHeight( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBGetItemRect( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBGetSel( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBGetSelCount( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBGetSelItems( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBGetTextLen( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBGetTopIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBSelectString( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBSelItemRange( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBSetCaretIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBSetColumnWidth( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBSetHorizontalExtent(HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBSetItemData( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBSetTabStops( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBSetCurSel( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBSetSel( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBSetTopIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +LONG LBSetItemHeight( HWND hwnd, WORD message, WORD wParam, LONG lParam ); + + +typedef struct { + WORD message; + LONG (*handler)(HWND, WORD, WPARAM, LPARAM); +} msg_tbl; + +static msg_tbl methods[] = { + {WM_CREATE, LBCreate}, + {WM_DESTROY, LBDestroy}, + {WM_GETDLGCODE, LBGetDlgCode}, + {WM_VSCROLL, LBVScroll}, + {WM_HSCROLL, LBHScroll}, + {WM_LBUTTONDOWN, LBLButtonDown}, + {WM_LBUTTONUP, LBLButtonUp}, + {WM_RBUTTONUP, LBRButtonUp}, + {WM_LBUTTONDBLCLK, LBRButtonUp}, + {WM_MOUSEMOVE, LBMouseMove}, + {WM_KEYDOWN, LBKeyDown}, + {WM_SETFONT, LBSetFont}, + {WM_SETREDRAW, LBSetRedraw}, + {WM_PAINT, LBPaint}, + {WM_SETFOCUS, LBSetFocus}, + {WM_KILLFOCUS, LBKillFocus}, + {LB_RESETCONTENT, LBResetContent}, + {LB_DIR, LBDir}, + {LB_ADDSTRING, LBAddString}, + {LB_INSERTSTRING, LBInsertString}, + {LB_DELETESTRING, LBDeleteString}, + {LB_FINDSTRING, LBFindString}, + {LB_GETCARETINDEX, LBGetCaretIndex}, + {LB_GETCOUNT, LBGetCount}, + {LB_GETCURSEL, LBGetCurSel}, + {LB_GETHORIZONTALEXTENT, LBGetHorizontalExtent}, + {LB_GETITEMDATA, LBGetItemData}, + {LB_GETITEMHEIGHT, LBGetItemHeight}, + {LB_GETITEMRECT, LBGetItemRect}, + {LB_GETSEL, LBGetSel}, + {LB_GETSELCOUNT, LBGetSelCount}, + {LB_GETSELITEMS, LBGetSelItems}, + {LB_GETTEXT, LBGetText}, + {LB_GETTEXTLEN, LBGetTextLen}, + {LB_GETTOPINDEX, LBGetTopIndex}, + {LB_SELECTSTRING, LBSelectString}, + {LB_SELITEMRANGE, LBSelItemRange}, + {LB_SETCARETINDEX, LBSetCaretIndex}, + {LB_SETCOLUMNWIDTH, LBSetColumnWidth}, + {LB_SETHORIZONTALEXTENT, LBSetHorizontalExtent}, + {LB_SETITEMDATA, LBSetItemData}, + {LB_SETTABSTOPS, LBSetTabStops}, + {LB_SETCURSEL, LBSetCurSel}, + {LB_SETSEL, LBSetSel}, + {LB_SETTOPINDEX, LBSetTopIndex}, + {LB_SETITEMHEIGHT, LBSetItemHeight} +}; + /*********************************************************************** - * ListBoxWndProc + * LBCreate */ -LONG ListBoxWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) -{ - WND *wndPtr; - LPHEADLIST lphl; - HWND hWndCtl; - WORD wRet; - LONG lRet; - RECT rect; - int y; - CREATESTRUCT *createStruct; - static RECT rectsel; - switch(message) { - case WM_CREATE: - CreateListBoxStruct(hwnd); - lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - dprintf_listbox(stddeb,"ListBox WM_CREATE %p !\n", lphl); - if (lphl == NULL) return 0; - createStruct = (CREATESTRUCT *)PTR_SEG_TO_LIN(lParam); - if (HIWORD(createStruct->lpCreateParams) != 0) - lphl->hWndLogicParent = (HWND)HIWORD(createStruct->lpCreateParams); - else - lphl->hWndLogicParent = GetParent(hwnd); - lphl->hFont = GetStockObject(SYSTEM_FONT); - lphl->ColumnsWidth = wndPtr->rectClient.right - wndPtr->rectClient.left; - SetScrollRange(hwnd, SB_VERT, 1, ListMaxFirstVisible(lphl), TRUE); - SetScrollRange(hwnd, SB_HORZ, 1, 1, TRUE); - if ((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) == LBS_OWNERDRAWFIXED) { - } - return 0; - case WM_DESTROY: - lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - if (lphl == NULL) return 0; - ListBoxResetContent(hwnd); - /* XXX need to free lphl->Heap */ - free(lphl); - *((LPHEADLIST *)&wndPtr->wExtra[1]) = 0; - dprintf_listbox(stddeb,"ListBox WM_DESTROY %p !\n", lphl); - return 0; - - case WM_VSCROLL: - dprintf_listbox(stddeb,"ListBox WM_VSCROLL w=%04X l=%08lX !\n", - wParam, lParam); - lphl = ListBoxGetStorageHeader(hwnd); - if (lphl == NULL) return 0; - y = lphl->FirstVisible; - switch(wParam) { - case SB_LINEUP: - if (lphl->FirstVisible > 1) - lphl->FirstVisible--; - break; - case SB_LINEDOWN: - if (lphl->FirstVisible < ListMaxFirstVisible(lphl)) - lphl->FirstVisible++; - break; - case SB_PAGEUP: - if (lphl->FirstVisible > 1) - lphl->FirstVisible -= lphl->ItemsVisible; - break; - case SB_PAGEDOWN: - if (lphl->FirstVisible < ListMaxFirstVisible(lphl)) - lphl->FirstVisible += lphl->ItemsVisible; - break; - case SB_THUMBTRACK: - lphl->FirstVisible = LOWORD(lParam); - break; - } - if (lphl->FirstVisible < 1) lphl->FirstVisible = 1; - if (lphl->FirstVisible > ListMaxFirstVisible(lphl)) - lphl->FirstVisible = ListMaxFirstVisible(lphl); - if (y != lphl->FirstVisible) { - SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - } - return 0; - - case WM_HSCROLL: - dprintf_listbox(stddeb,"ListBox WM_HSCROLL w=%04X l=%08lX !\n", - wParam, lParam); - lphl = ListBoxGetStorageHeader(hwnd); - if (lphl == NULL) return 0; - y = lphl->FirstVisible; - switch(wParam) { - case SB_LINEUP: - if (lphl->FirstVisible > 1) - lphl->FirstVisible -= lphl->ItemsPerColumn; - break; - case SB_LINEDOWN: - if (lphl->FirstVisible < ListMaxFirstVisible(lphl)) - lphl->FirstVisible += lphl->ItemsPerColumn; - break; - case SB_PAGEUP: - if (lphl->FirstVisible > 1 && lphl->ItemsPerColumn != 0) - lphl->FirstVisible -= lphl->ItemsVisible / - lphl->ItemsPerColumn * lphl->ItemsPerColumn; - break; - case SB_PAGEDOWN: - if (lphl->FirstVisible < ListMaxFirstVisible(lphl) && - lphl->ItemsPerColumn != 0) - lphl->FirstVisible += lphl->ItemsVisible / - lphl->ItemsPerColumn * lphl->ItemsPerColumn; - break; - case SB_THUMBTRACK: - lphl->FirstVisible = lphl->ItemsPerColumn * - (LOWORD(lParam) - 1) + 1; - break; - } - if (lphl->FirstVisible < 1) lphl->FirstVisible = 1; - if (lphl->FirstVisible > ListMaxFirstVisible(lphl)) - lphl->FirstVisible = ListMaxFirstVisible(lphl); - if (lphl->ItemsPerColumn != 0) { - lphl->FirstVisible = lphl->FirstVisible / - lphl->ItemsPerColumn * lphl->ItemsPerColumn + 1; - if (y != lphl->FirstVisible) { - SetScrollPos(hwnd, SB_HORZ, lphl->FirstVisible / - lphl->ItemsPerColumn + 1, TRUE); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - } - } - return 0; - - case WM_LBUTTONDOWN: - SetFocus(hwnd); - SetCapture(hwnd); - lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - if (lphl == NULL) return 0; - lphl->PrevFocused = lphl->ItemFocused; - y = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam)); - if (y==-1) - return 0; - if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) { - lphl->ItemFocused = y; - wRet = ListBoxGetSel(hwnd, y); - ListBoxSetSel(hwnd, y, !wRet); - } - else - ListBoxSetCurSel(hwnd, y); - if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) - ListBoxSendNotification( hwnd, LBN_SELCHANGE ); - ListBoxGetItemRect(hwnd, y, &rectsel); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - return 0; - case WM_LBUTTONUP: - ReleaseCapture(); - lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - if (lphl == NULL) return 0; - if (lphl->PrevFocused != lphl->ItemFocused) - ListBoxSendNotification( hwnd, LBN_SELCHANGE ); - return 0; - case WM_RBUTTONUP: - case WM_LBUTTONDBLCLK: - lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - if (lphl == NULL) return 0; - SendMessage(lphl->hWndLogicParent, WM_COMMAND, wndPtr->wIDmenu, - MAKELONG(hwnd, LBN_DBLCLK)); - return 0; - case WM_MOUSEMOVE: - lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - if (lphl == NULL) return 0; - if ((wParam & MK_LBUTTON) != 0) { - y = HIWORD(lParam); - if (y < 4) { - if (lphl->FirstVisible > 1) { - lphl->FirstVisible--; - SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - break; - } - } - GetClientRect(hwnd, &rect); - if (y > (rect.bottom - 4)) { - if (lphl->FirstVisible < ListMaxFirstVisible(lphl)) { - lphl->FirstVisible++; - SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - break; - } - } - if ((y > 0) && (y < (rect.bottom - 4))) { - if ((y < rectsel.top) || (y > rectsel.bottom)) { - wRet = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam)); - if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) { - lphl->ItemFocused = wRet; - ListBoxSendNotification(hwnd, LBN_SELCHANGE); - } - else - ListBoxSetCurSel(hwnd, wRet); - ListBoxGetItemRect(hwnd, wRet, &rectsel); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - } - } - } - break; - case WM_KEYDOWN: - lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - if (lphl == NULL) return 0; - switch(wParam) { - case VK_TAB: - hWndCtl = GetNextDlgTabItem(lphl->hWndLogicParent, - hwnd, !(GetKeyState(VK_SHIFT) < 0)); - SetFocus(hWndCtl); - if(debugging_listbox){ - if ((GetKeyState(VK_SHIFT) < 0)) - dprintf_listbox(stddeb,"ListBox PreviousDlgTabItem %04X !\n", hWndCtl); - else - dprintf_listbox(stddeb,"ListBox NextDlgTabItem %04X !\n", hWndCtl); - } - break; - case VK_HOME: - lphl->ItemFocused = 0; - break; - case VK_END: - lphl->ItemFocused = lphl->ItemsCount - 1; - break; - case VK_LEFT: - if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) { - lphl->ItemFocused -= lphl->ItemsPerColumn; - } - break; - case VK_UP: - lphl->ItemFocused--; - break; - case VK_RIGHT: - if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) { - lphl->ItemFocused += lphl->ItemsPerColumn; - } - break; - case VK_DOWN: - lphl->ItemFocused++; - break; - case VK_PRIOR: - lphl->ItemFocused -= lphl->ItemsVisible; - break; - case VK_NEXT: - lphl->ItemFocused += lphl->ItemsVisible; - break; - case VK_SPACE: - wRet = ListBoxGetSel(hwnd, lphl->ItemFocused); - ListBoxSetSel(hwnd, lphl->ItemFocused, !wRet); - break; - default: - ListBoxFindNextMatch(hwnd, wParam); - return 0; - } - if (lphl->ItemFocused < 0) lphl->ItemFocused = 0; - if (lphl->ItemFocused >= lphl->ItemsCount) - lphl->ItemFocused = lphl->ItemsCount - 1; - lphl->FirstVisible = lphl->ItemFocused / lphl->ItemsVisible * - lphl->ItemsVisible + 1; - if (lphl->FirstVisible < 1) lphl->FirstVisible = 1; - if ((wndPtr->dwStyle & LBS_MULTIPLESEL) != LBS_MULTIPLESEL) { - ListBoxSetCurSel(hwnd, lphl->ItemFocused); - ListBoxSendNotification(hwnd, LBN_SELCHANGE); - } - SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - break; - case WM_SETFONT: - lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - if (lphl == NULL) return 0; - if (wParam == 0) - lphl->hFont = GetStockObject(SYSTEM_FONT); - else - lphl->hFont = wParam; - if (wParam == 0) break; - break; - case WM_SETREDRAW: - dprintf_listbox(stddeb,"ListBox WM_SETREDRAW hWnd=%04X w=%04X !\n", hwnd, wParam); - lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - if (lphl == NULL) return 0; - lphl->bRedrawFlag = wParam; - break; - case WM_PAINT: - wndPtr = WIN_FindWndPtr(hwnd); - if ((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) == LBS_OWNERDRAWFIXED) { - OwnerDrawListBox(hwnd); - break; - } - if ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) == LBS_OWNERDRAWVARIABLE) { - OwnerDrawListBox(hwnd); - break; - } - StdDrawListBox(hwnd); - break; - case WM_SETFOCUS: - dprintf_listbox(stddeb,"ListBox WM_SETFOCUS !\n"); - lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - break; - case WM_KILLFOCUS: - dprintf_listbox(stddeb,"ListBox WM_KILLFOCUS !\n"); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - break; +LONG LBCreate( HWND hwnd, WORD message, WORD wParam, LONG lParam ) - case LB_RESETCONTENT: - dprintf_listbox(stddeb,"ListBox LB_RESETCONTENT !\n"); - ListBoxResetContent(hwnd); - return 0; - case LB_DIR: - dprintf_listbox(stddeb,"ListBox LB_DIR !\n"); - wRet = ListBoxDirectory(hwnd, wParam, - (LPSTR)PTR_SEG_TO_LIN(lParam)); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - return wRet; - case LB_ADDSTRING: - wRet = ListBoxAddString(hwnd, (LPSTR)PTR_SEG_TO_LIN(lParam)); - return wRet; - case LB_GETTEXT: - dprintf_listbox(stddeb, "LB_GETTEXT wParam=%d\n",wParam); - wRet = ListBoxGetText(hwnd, wParam, - (LPSTR)PTR_SEG_TO_LIN(lParam), FALSE); - return wRet; - case LB_INSERTSTRING: - wRet = ListBoxInsertString(hwnd, wParam, - (LPSTR)PTR_SEG_TO_LIN(lParam)); - return wRet; - case LB_DELETESTRING: - wRet = ListBoxDeleteString(hwnd, wParam); - return wRet; - case LB_FINDSTRING: - wRet = ListBoxFindString(hwnd, wParam, - (LPSTR)PTR_SEG_TO_LIN(lParam)); - return wRet; - case LB_GETCARETINDEX: - return wRet; - case LB_GETCOUNT: - lphl = ListBoxGetStorageHeader(hwnd); - return lphl->ItemsCount; - case LB_GETCURSEL: - lphl = ListBoxGetStorageHeader(hwnd); - dprintf_listbox(stddeb,"ListBox LB_GETCURSEL %u !\n", - lphl->ItemFocused); - return lphl->ItemFocused; - case LB_GETHORIZONTALEXTENT: - return wRet; - case LB_GETITEMDATA: - dprintf_listbox(stddeb, "LB_GETITEMDATA wParam=%x\n", wParam); - lRet = ListBoxGetText(hwnd, wParam, - (LPSTR)PTR_SEG_TO_LIN(lParam), TRUE); - return lRet; - case LB_GETITEMHEIGHT: - ListBoxGetItemRect(hwnd, wParam, &rect); - return (rect.bottom - rect.top); - case LB_GETITEMRECT: - ListBoxGetItemRect(hwnd,wParam,(LPRECT)PTR_SEG_TO_LIN(lParam)); - return 0; - case LB_GETSEL: - wRet = ListBoxGetSel(hwnd, wParam); - return wRet; - case LB_GETSELCOUNT: - lphl = ListBoxGetStorageHeader(hwnd); - if (lphl == NULL) return LB_ERR; - return lphl->SelCount; - case LB_GETSELITEMS: - return wRet; - case LB_GETTEXTLEN: - return wRet; - case LB_GETTOPINDEX: - lphl = ListBoxGetStorageHeader(hwnd); - if (lphl == NULL) return LB_ERR; - return lphl->FirstVisible; - case LB_SELECTSTRING: - return wRet; - case LB_SELITEMRANGE: - return wRet; - case LB_SETCARETINDEX: - return wRet; - case LB_SETCOLUMNWIDTH: - lphl = ListBoxGetStorageHeader(hwnd); - if (lphl == NULL) return LB_ERR; - lphl->ColumnsWidth = wParam; - break; - case LB_SETHORIZONTALEXTENT: - return wRet; - case LB_SETITEMDATA: - dprintf_listbox(stddeb, "LB_SETITEMDATA wParam=%x lParam=%lx\n", wParam, lParam); - wRet = ListBoxSetItemData(hwnd, wParam, lParam); - return wRet; - case LB_SETTABSTOPS: - lphl = ListBoxGetStorageHeader(hwnd); - if (lphl == NULL) return LB_ERR; - lphl->FirstVisible = wParam; - return 0; - case LB_SETCURSEL: - dprintf_listbox(stddeb,"ListBox LB_SETCURSEL wParam=%x !\n", - wParam); - wRet = ListBoxSetCurSel(hwnd, wParam); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - return wRet; - case LB_SETSEL: - dprintf_listbox(stddeb,"ListBox LB_SETSEL wParam=%x lParam=%lX !\n", wParam, lParam); - wRet = ListBoxSetSel(hwnd, LOWORD(lParam), wParam); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - return wRet; - case LB_SETTOPINDEX: - dprintf_listbox(stddeb,"ListBox LB_SETTOPINDEX wParam=%x !\n", - wParam); - lphl = ListBoxGetStorageHeader(hwnd); - lphl->FirstVisible = wParam; - SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - break; - case LB_SETITEMHEIGHT: - dprintf_listbox(stddeb,"ListBox LB_SETITEMHEIGHT wParam=%x lParam=%lX !\n", wParam, lParam); - wRet = ListBoxSetItemHeight(hwnd, wParam, lParam); - return wRet; +{ + LPHEADLIST lphl; + CREATESTRUCT *createStruct; + WND *wndPtr; - default: - return DefWindowProc( hwnd, message, wParam, lParam ); - } -return 0; + CreateListBoxStruct(hwnd); + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + + dprintf_listbox(stddeb,"ListBox WM_CREATE %p !\n", lphl); + + if (lphl == NULL) return 0; + + createStruct = (CREATESTRUCT *)PTR_SEG_TO_LIN(lParam); + + if (HIWORD(createStruct->lpCreateParams) != 0) + lphl->hWndLogicParent = (HWND)HIWORD(createStruct->lpCreateParams); + else + lphl->hWndLogicParent = GetParent(hwnd); + + lphl->hFont = GetStockObject(SYSTEM_FONT); + lphl->ColumnsWidth = wndPtr->rectClient.right - wndPtr->rectClient.left; + + SetScrollRange(hwnd, SB_VERT, 1, ListMaxFirstVisible(lphl), TRUE); + SetScrollRange(hwnd, SB_HORZ, 1, 1, TRUE); + + return 0; } +int CreateListBoxStruct(HWND hwnd) -LPHEADLIST ListBoxGetWindowAndStorage(HWND hwnd, WND **wndPtr) { - WND *Ptr; - LPHEADLIST lphl; - *(wndPtr) = Ptr = WIN_FindWndPtr(hwnd); - lphl = *((LPHEADLIST *)&Ptr->wExtra[1]); - return lphl; + WND *wndPtr; + LPHEADLIST lphl; + + wndPtr = WIN_FindWndPtr(hwnd); + + lphl = (LPHEADLIST)malloc(sizeof(HEADLIST)); + *((LPHEADLIST *)&wndPtr->wExtra[1]) = lphl; + + lphl->lpFirst = NULL; + lphl->ItemsCount = 0; + lphl->ItemsVisible = 0; + lphl->FirstVisible = 1; + lphl->ColumnsVisible = 1; + lphl->ItemsPerColumn = 0; + lphl->StdItemHeight = 15; + lphl->ItemFocused = -1; + lphl->PrevFocused = -1; + lphl->DrawCtlType = ODT_LISTBOX; + lphl->bRedrawFlag = TRUE; + lphl->iNumStops = 0; + lphl->TabStops = NULL; + + if (OWNER_DRAWN(wndPtr)) + lphl->hDrawItemStruct = USER_HEAP_ALLOC(sizeof(DRAWITEMSTRUCT)); + else + lphl->hDrawItemStruct = 0; + +#if 0 + HeapHandle = GlobalAlloc(GMEM_FIXED, LIST_HEAP_SIZE); + HeapBase = GlobalLock(HeapHandle); + HEAP_Init(&lphl->Heap, HeapBase, LIST_HEAP_SIZE); +#endif + return TRUE; } -LPHEADLIST ListBoxGetStorageHeader(HWND hwnd) +/*********************************************************************** + * LBDestroy + */ +LONG LBDestroy( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + { - WND *wndPtr; - LPHEADLIST lphl; - wndPtr = WIN_FindWndPtr(hwnd); - lphl = *((LPHEADLIST *)&wndPtr->wExtra[1]); - return lphl; + LPHEADLIST lphl; + WND *wndPtr; + + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + + if (lphl == NULL) return 0; + ListBoxResetContent(hwnd); + + if (lphl->hDrawItemStruct) + USER_HEAP_FREE(lphl->hDrawItemStruct); + + /* XXX need to free lphl->Heap */ + free(lphl); + *((LPHEADLIST *)&wndPtr->wExtra[1]) = 0; + dprintf_listbox(stddeb,"ListBox WM_DESTROY %p !\n", lphl); + return 0; } +/* get the maximum value of lphl->FirstVisible */ +int ListMaxFirstVisible(LPHEADLIST lphl) +{ + int m = lphl->ItemsCount-lphl->ItemsVisible+1; + return (m < 1) ? 1 : m; +} + + +/*********************************************************************** + * LBVScroll + */ +LONG LBVScroll( HWND hwnd, WORD message, WORD wParam, LONG lParam ) -void StdDrawListBox(HWND hwnd) { - WND *wndPtr; - LPHEADLIST lphl; - LPLISTSTRUCT lpls; - PAINTSTRUCT ps; - HBRUSH hBrush; - int OldBkMode; - DWORD dwOldTextColor; - HDC hdc; - RECT rect; - int i, h, h2, maxwidth, ipc; - h = 0; - hdc = BeginPaint( hwnd, &ps ); - if (!IsWindowVisible(hwnd)) { - EndPaint( hwnd, &ps ); - return; - } - lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - if (lphl == NULL) goto EndOfPaint; - if (!lphl->bRedrawFlag) goto EndOfPaint; - SelectObject(hdc, lphl->hFont); - hBrush = SendMessage(lphl->hWndLogicParent, WM_CTLCOLOR, (WORD)hdc, - MAKELONG(hwnd, CTLCOLOR_LISTBOX)); - if (hBrush == (HBRUSH)NULL) hBrush = GetStockObject(WHITE_BRUSH); - GetClientRect(hwnd, &rect); - FillRect(hdc, &rect, hBrush); - maxwidth = rect.right; - rect.right = lphl->ColumnsWidth; - if (lphl->ItemsCount == 0) goto EndOfPaint; - lpls = lphl->lpFirst; - if (lpls == NULL) goto EndOfPaint; - lphl->ItemsVisible = 0; - lphl->ItemsPerColumn = ipc = 0; - for(i = 1; i <= lphl->ItemsCount; i++) { - if (i >= lphl->FirstVisible) { - if (lpls == NULL) break; - if ((h + lpls->dis.rcItem.bottom - lpls->dis.rcItem.top) > rect.bottom) { - if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) { - lphl->ItemsPerColumn = max(lphl->ItemsPerColumn, ipc); - ipc = 0; - h = 0; - rect.left += lphl->ColumnsWidth; - rect.right += lphl->ColumnsWidth; - if (rect.left > maxwidth) break; - } - else - break; - } - h2 = lpls->dis.rcItem.bottom - lpls->dis.rcItem.top; - lpls->dis.rcItem.top = h; - lpls->dis.rcItem.bottom = h + h2; - lpls->dis.rcItem.left = rect.left; - lpls->dis.rcItem.right = rect.right; - OldBkMode = SetBkMode(hdc, TRANSPARENT); - if (lpls->dis.itemState != 0) { - dwOldTextColor = SetTextColor(hdc, 0x00FFFFFFL); - FillRect(hdc, &lpls->dis.rcItem, GetStockObject(BLACK_BRUSH)); - } - TextOut(hdc, rect.left + 5, h + 2, (char *)lpls->itemText, - strlen((char *)lpls->itemText)); - if (lpls->dis.itemState != 0) { - SetTextColor(hdc, dwOldTextColor); - } - SetBkMode(hdc, OldBkMode); - if ((lphl->ItemFocused == i - 1) && GetFocus() == hwnd) { - DrawFocusRect(hdc, &lpls->dis.rcItem); - } - h += h2; - lphl->ItemsVisible++; - ipc++; - } - if (lpls->lpNext == NULL) goto EndOfPaint; - lpls = (LPLISTSTRUCT)lpls->lpNext; - } -EndOfPaint: - EndPaint( hwnd, &ps ); + LPHEADLIST lphl; + int y; + + dprintf_listbox(stddeb,"ListBox WM_VSCROLL w=%04X l=%08lX !\n", + wParam, lParam); + lphl = ListBoxGetStorageHeader(hwnd); + if (lphl == NULL) return 0; + y = lphl->FirstVisible; + + switch(wParam) { + case SB_LINEUP: + if (lphl->FirstVisible > 1) + lphl->FirstVisible--; + break; + + case SB_LINEDOWN: + if (lphl->FirstVisible < ListMaxFirstVisible(lphl)) + lphl->FirstVisible++; + break; + + case SB_PAGEUP: + if (lphl->FirstVisible > 1) + lphl->FirstVisible -= lphl->ItemsVisible; + break; + + case SB_PAGEDOWN: + if (lphl->FirstVisible < ListMaxFirstVisible(lphl)) + lphl->FirstVisible += lphl->ItemsVisible; + break; + + case SB_THUMBTRACK: + lphl->FirstVisible = LOWORD(lParam); + break; + } + + if (lphl->FirstVisible < 1) lphl->FirstVisible = 1; + if (lphl->FirstVisible > ListMaxFirstVisible(lphl)) + lphl->FirstVisible = ListMaxFirstVisible(lphl); + + if (y != lphl->FirstVisible) { + SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + } + return 0; } +/*********************************************************************** + * LBHScroll + */ +LONG LBHScroll( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + LPHEADLIST lphl; + int y; + + dprintf_listbox(stddeb,"ListBox WM_HSCROLL w=%04X l=%08lX !\n", + wParam, lParam); + lphl = ListBoxGetStorageHeader(hwnd); + if (lphl == NULL) return 0; + y = lphl->FirstVisible; + switch(wParam) { + case SB_LINEUP: + if (lphl->FirstVisible > 1) + lphl->FirstVisible -= lphl->ItemsPerColumn; + break; + case SB_LINEDOWN: + if (lphl->FirstVisible < ListMaxFirstVisible(lphl)) + lphl->FirstVisible += lphl->ItemsPerColumn; + break; + case SB_PAGEUP: + if (lphl->FirstVisible > 1 && lphl->ItemsPerColumn != 0) + lphl->FirstVisible -= lphl->ItemsVisible / + lphl->ItemsPerColumn * lphl->ItemsPerColumn; + break; + case SB_PAGEDOWN: + if (lphl->FirstVisible < ListMaxFirstVisible(lphl) && + lphl->ItemsPerColumn != 0) + lphl->FirstVisible += lphl->ItemsVisible / + lphl->ItemsPerColumn * lphl->ItemsPerColumn; + break; + case SB_THUMBTRACK: + lphl->FirstVisible = lphl->ItemsPerColumn * + (LOWORD(lParam) - 1) + 1; + break; + } + if (lphl->FirstVisible < 1) lphl->FirstVisible = 1; + if (lphl->FirstVisible > ListMaxFirstVisible(lphl)) + lphl->FirstVisible = ListMaxFirstVisible(lphl); + + if (lphl->ItemsPerColumn != 0) { + lphl->FirstVisible = lphl->FirstVisible / + lphl->ItemsPerColumn * lphl->ItemsPerColumn + 1; + if (y != lphl->FirstVisible) { + SetScrollPos(hwnd, SB_HORZ, lphl->FirstVisible / + lphl->ItemsPerColumn + 1, TRUE); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + } + } + return 0; +} +/*********************************************************************** + * LBLButtonDown + */ +LONG LBLButtonDown( HWND hwnd, WORD message, WORD wParam, LONG lParam ) -void OwnerDrawListBox(HWND hwnd) { - WND *wndPtr,*ParentWndPtr; - LPHEADLIST lphl; - LPLISTSTRUCT lpls; - PAINTSTRUCT ps; - HBRUSH hBrush; - DWORD itemData; - HDC hdc; - RECT rect; - int i, h, h2, maxwidth; - HANDLE hDrawItemStruct; - h = 0; - hdc = BeginPaint(hwnd, &ps); - if (!IsWindowVisible(hwnd)) { - EndPaint( hwnd, &ps ); - return; - } - lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - if (lphl == NULL) goto EndOfPaint; - if (!lphl->bRedrawFlag) goto EndOfPaint; - hBrush = SendMessage(lphl->hWndLogicParent, WM_CTLCOLOR, (WORD)hdc, - MAKELONG(hwnd, CTLCOLOR_LISTBOX)); - if (hBrush == (HBRUSH)NULL) hBrush = GetStockObject(WHITE_BRUSH); - GetClientRect(hwnd, &rect); - FillRect(hdc, &rect, hBrush); - maxwidth = rect.right; - rect.right = lphl->ColumnsWidth; - if (lphl->ItemsCount == 0) goto EndOfPaint; - lpls = lphl->lpFirst; - if (lpls == NULL) goto EndOfPaint; - lphl->ItemsVisible = 0; - hDrawItemStruct = USER_HEAP_ALLOC( sizeof(DRAWITEMSTRUCT) ); - for (i = 1; i <= lphl->ItemsCount; i++) { - if (i >= lphl->FirstVisible) { - lpls->dis.hDC = hdc; - lpls->dis.hwndItem = hwnd; - lpls->dis.CtlType = ODT_LISTBOX; - lpls->dis.itemID = i - 1; - if ((!lpls->dis.CtlID) && (lphl->hWndLogicParent)) { - ParentWndPtr = WIN_FindWndPtr(lphl->hWndLogicParent); - lpls->dis.CtlID = ParentWndPtr->wIDmenu; - } - h2 = lpls->dis.rcItem.bottom - lpls->dis.rcItem.top; - lpls->dis.rcItem.top = h; - lpls->dis.rcItem.bottom = h + h2; - lpls->dis.rcItem.left = rect.left; - lpls->dis.rcItem.right = rect.right; - lpls->dis.itemAction = ODA_DRAWENTIRE; -/* if (lpls->dis.itemState != 0) { - lpls->dis.itemAction |= ODA_SELECT; - } - if (lphl->ItemFocused == i - 1) { - lpls->dis.itemAction |= ODA_FOCUS; - }*/ - dprintf_listbox(stddeb,"LBOX WM_DRAWITEM #%d left=%d top=%d right=%d bottom=%d !\n", - i-1, lpls->dis.rcItem.left, lpls->dis.rcItem.top, - lpls->dis.rcItem.right, lpls->dis.rcItem.bottom); - dprintf_listbox(stddeb,"LBOX WM_DRAWITEM &dis=%lX CtlID=%u !\n", - (LONG)&lpls->dis, lpls->dis.CtlID); - dprintf_listbox(stddeb,"LBOX WM_DRAWITEM %08lX!\n",lpls->dis.itemData); - if (HasStrings(wndPtr)) - dprintf_listbox(stddeb," '%s'\n",lpls->itemText); - if (HasStrings(wndPtr)) { - itemData = lpls->dis.itemData; - lpls->dis.itemData = (DWORD)lpls->itemText; - } - memcpy( USER_HEAP_LIN_ADDR(hDrawItemStruct), &lpls->dis, - sizeof(DRAWITEMSTRUCT) ); - SendMessage(lphl->hWndLogicParent, WM_DRAWITEM, - i-1, (LPARAM)USER_HEAP_SEG_ADDR(hDrawItemStruct)); - if (HasStrings(wndPtr)) - lpls->dis.itemData = itemData; - -/* if (lpls->dis.itemState != 0) { - InvertRect(hdc, &lpls->dis.rcItem); - } */ - h += h2; - lphl->ItemsVisible++; - /* if (h > rect.bottom) goto EndOfPaint;*/ - } - if (lpls->lpNext == NULL) break; - lpls = (LPLISTSTRUCT)lpls->lpNext; - } - USER_HEAP_FREE( hDrawItemStruct ); -EndOfPaint: - EndPaint( hwnd, &ps ); + LPHEADLIST lphl; + WND *wndPtr; + WORD wRet; + int y; + RECT rectsel; + + SetFocus(hwnd); + SetCapture(hwnd); + + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == NULL) return 0; + + lphl->PrevFocused = lphl->ItemFocused; + + y = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam)); + if (y==-1) + return 0; + + if (wndPtr->dwStyle & LBS_MULTIPLESEL) { + lphl->ItemFocused = y; + wRet = ListBoxGetSel(hwnd, y); + ListBoxSetSel(hwnd, y, !wRet); + } + else + ListBoxSetCurSel(hwnd, y); + + if (wndPtr->dwStyle & LBS_MULTIPLESEL) + ListBoxSendNotification( hwnd, LBN_SELCHANGE ); + + ListBoxGetItemRect(hwnd, y, &rectsel); + + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + + return 0; } +/*********************************************************************** + * LBLButtonUp + */ +LONG LBLButtonUp( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + LPHEADLIST lphl; + WND *wndPtr; + ReleaseCapture(); + + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == NULL) return 0; + if (lphl->PrevFocused != lphl->ItemFocused) + ListBoxSendNotification( hwnd, LBN_SELCHANGE ); + + return 0; +} + +/*********************************************************************** + * LBRButtonUp + */ +LONG LBRButtonUp( HWND hwnd, WORD message, WORD wParam, LONG lParam ) -int ListBoxFindMouse(HWND hwnd, int X, int Y) { - WND *wndPtr; - LPHEADLIST lphl; - LPLISTSTRUCT lpls; - RECT rect; - int i, h, h2, w, w2; - lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - if (lphl == NULL) return LB_ERR; - if (lphl->ItemsCount == 0) return LB_ERR; - lpls = lphl->lpFirst; - if (lpls == NULL) return LB_ERR; + LPHEADLIST lphl; + WND *wndPtr; + + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == NULL) return 0; + SendMessage(lphl->hWndLogicParent, WM_COMMAND, wndPtr->wIDmenu, + MAKELONG(hwnd, LBN_DBLCLK)); + + return 0; +} + +/*********************************************************************** + * LBMouseMove + */ +LONG LBMouseMove( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + LPHEADLIST lphl; + WND *wndPtr; + int y; + WORD wRet; + RECT rect, rectsel; /* XXX Broken */ + + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == NULL) return 0; + if ((wParam & MK_LBUTTON) != 0) { + y = HIWORD(lParam); + if (y < 4) { + if (lphl->FirstVisible > 1) { + lphl->FirstVisible--; + SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + return 0; + } + } GetClientRect(hwnd, &rect); - h = w2 = 0; - w = lphl->ColumnsWidth; - for(i = 1; i <= lphl->ItemsCount; i++) { - if (i >= lphl->FirstVisible) { - h2 = h; - h += lpls->dis.rcItem.bottom - lpls->dis.rcItem.top; - if ((Y > h2) && (Y < h) && - (X > w2) && (X < w)) return(i - 1); - if (h > rect.bottom) { - if ((wndPtr->dwStyle & LBS_MULTICOLUMN) != LBS_MULTICOLUMN) return LB_ERR; - h = 0; - w2 = w; - w += lphl->ColumnsWidth; - if (w2 > rect.right) return LB_ERR; - } - } - if (lpls->lpNext == NULL) return LB_ERR; - lpls = (LPLISTSTRUCT)lpls->lpNext; + if (y > (rect.bottom - 4)) { + if (lphl->FirstVisible < ListMaxFirstVisible(lphl)) { + lphl->FirstVisible++; + SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + return 0; + } + } + if ((y > 0) && (y < (rect.bottom - 4))) { + if ((y < rectsel.top) || (y > rectsel.bottom)) { + wRet = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam)); + if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) { + lphl->ItemFocused = wRet; + ListBoxSendNotification(hwnd, LBN_SELCHANGE); } - return(LB_ERR); + else + ListBoxSetCurSel(hwnd, wRet); + ListBoxGetItemRect(hwnd, wRet, &rectsel); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + } + } + } + + return 0; } +/*********************************************************************** + * LBKeyDown + */ +LONG LBKeyDown( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + LPHEADLIST lphl; + WND *wndPtr; + HWND hWndCtl; + WORD wRet; + + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == NULL) return 0; + switch(wParam) { + case VK_TAB: + hWndCtl = GetNextDlgTabItem(lphl->hWndLogicParent, + hwnd, !(GetKeyState(VK_SHIFT) < 0)); + SetFocus(hWndCtl); + if(debugging_listbox){ + if ((GetKeyState(VK_SHIFT) < 0)) + dprintf_listbox(stddeb,"ListBox PreviousDlgTabItem %04X !\n", hWndCtl); + else + dprintf_listbox(stddeb,"ListBox NextDlgTabItem %04X !\n", hWndCtl); + } + break; + case VK_HOME: + lphl->ItemFocused = 0; + break; + case VK_END: + lphl->ItemFocused = lphl->ItemsCount - 1; + break; + case VK_LEFT: + if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) { + lphl->ItemFocused -= lphl->ItemsPerColumn; + } + break; + case VK_UP: + lphl->ItemFocused--; + break; + case VK_RIGHT: + if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) { + lphl->ItemFocused += lphl->ItemsPerColumn; + } + break; + case VK_DOWN: + lphl->ItemFocused++; + break; + case VK_PRIOR: + lphl->ItemFocused -= lphl->ItemsVisible; + break; + case VK_NEXT: + lphl->ItemFocused += lphl->ItemsVisible; + break; + case VK_SPACE: + wRet = ListBoxGetSel(hwnd, lphl->ItemFocused); + ListBoxSetSel(hwnd, lphl->ItemFocused, !wRet); + break; + default: + ListBoxFindNextMatch(hwnd, wParam); + return 0; + } + + if (lphl->ItemFocused < 0) lphl->ItemFocused = 0; + if (lphl->ItemFocused >= lphl->ItemsCount) + lphl->ItemFocused = lphl->ItemsCount - 1; + if (lphl->ItemsVisible != 0) + lphl->FirstVisible = lphl->ItemFocused / lphl->ItemsVisible * + lphl->ItemsVisible + 1; + + if (lphl->FirstVisible < 1) lphl->FirstVisible = 1; + if (lphl->FirstVisible > ListMaxFirstVisible(lphl)) + lphl->FirstVisible = ListMaxFirstVisible(lphl); + + if ((wndPtr->dwStyle & LBS_MULTIPLESEL) != LBS_MULTIPLESEL) { + ListBoxSetCurSel(hwnd, lphl->ItemFocused); + ListBoxSendNotification(hwnd, LBN_SELCHANGE); + } + + SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + + return 0; +} + +/*********************************************************************** + * LBSetRedraw + */ +LONG LBSetRedraw( HWND hwnd, WORD message, WORD wParam, LONG lParam ) -int CreateListBoxStruct(HWND hwnd) { - WND *wndPtr; - LPHEADLIST lphl; - wndPtr = WIN_FindWndPtr(hwnd); - lphl = (LPHEADLIST)malloc(sizeof(HEADLIST)); - lphl->lpFirst = NULL; - *((LPHEADLIST *)&wndPtr->wExtra[1]) = lphl; /* HEAD of List */ - lphl->ItemsCount = 0; - lphl->ItemsVisible = 0; - lphl->FirstVisible = 1; - lphl->ColumnsVisible = 1; - lphl->ItemsPerColumn = 0; - lphl->StdItemHeight = 15; - lphl->ItemFocused = 0; - lphl->PrevFocused = 0; - lphl->SelCount = 0; - lphl->DrawCtlType = ODT_LISTBOX; - lphl->bRedrawFlag = TRUE; -#if 0 - HeapHandle = GlobalAlloc(GMEM_FIXED, LIST_HEAP_SIZE); - HeapBase = GlobalLock(HeapHandle); - HEAP_Init(&lphl->Heap, HeapBase, LIST_HEAP_SIZE); -#endif - return TRUE; + LPHEADLIST lphl; + WND *wndPtr; + + dprintf_listbox(stddeb,"ListBox WM_SETREDRAW hWnd=%04X w=%04X !\n", hwnd, wParam); + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == NULL) return 0; + lphl->bRedrawFlag = wParam; + + return 0; } +/*********************************************************************** + * LBSetFont + */ + +LONG LBSetFont( HWND hwnd, WORD message, WORD wParam, LONG lParam ) -void ListBoxAskMeasure(WND *wndPtr, LPHEADLIST lphl, LPLISTSTRUCT lpls) { - MEASUREITEMSTRUCT *lpmeasure; - HANDLE hTemp = USER_HEAP_ALLOC( sizeof(MEASUREITEMSTRUCT) ); - lpmeasure = (MEASUREITEMSTRUCT *) USER_HEAP_LIN_ADDR(hTemp); - if (lpmeasure == NULL) { - fprintf(stderr,"ListBoxAskMeasure() // Bad allocation of Measure struct !\n"); - return; - } - lpmeasure->CtlType = ODT_LISTBOX; - lpmeasure->CtlID = wndPtr->wIDmenu; - lpmeasure->itemID = lpls->dis.itemID; - lpmeasure->itemWidth = wndPtr->rectWindow.right - wndPtr->rectWindow.left; - lpmeasure->itemHeight = 0; - if (HasStrings(wndPtr)) - lpmeasure->itemData = (DWORD)lpls->itemText; - else - lpmeasure->itemData = lpls->dis.itemData; - SendMessage(lphl->hWndLogicParent, WM_MEASUREITEM, - 0, USER_HEAP_SEG_ADDR(hTemp)); - lpls->dis.rcItem.right = lpls->dis.rcItem.left + lpmeasure->itemWidth; - lpls->dis.rcItem.bottom = lpls->dis.rcItem.top + lpmeasure->itemHeight; - USER_HEAP_FREE(hTemp); + LPHEADLIST lphl; + WND *wndPtr; + + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == NULL) return 0; + + if (wParam == 0) + lphl->hFont = GetStockObject(SYSTEM_FONT); + else + lphl->hFont = wParam; + + return 0; } +/*********************************************************************** + * LBPaint + */ +LONG LBPaint( HWND hwnd, WORD message, WORD wParam, LONG lParam ) -int ListBoxAddString(HWND hwnd, LPSTR newstr) { - LPHEADLIST lphl; - UINT pos = (UINT) -1; - WND *wndPtr; - - lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - if (lphl == NULL) return LB_ERR; + RepaintListBox(hwnd); + return 0; +} + +/*********************************************************************** + * LBSetFocus + */ +LONG LBSetFocus( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + LPHEADLIST lphl; + WND *wndPtr; + + dprintf_listbox(stddeb,"ListBox WM_SETFOCUS !\n"); + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + + return 0; +} + +/*********************************************************************** + * LBKillFocus + */ +LONG LBKillFocus( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + dprintf_listbox(stddeb,"ListBox WM_KILLFOCUS !\n"); + + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + + return 0; +} + +/*********************************************************************** + * LBResetContent + */ +LONG LBResetContent( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + dprintf_listbox(stddeb,"ListBox LB_RESETCONTENT !\n"); + ListBoxResetContent(hwnd); + + return 0; +} + +/*********************************************************************** + * LBDir + */ +LONG LBDir( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + WORD wRet; + dprintf_listbox(stddeb,"ListBox LB_DIR !\n"); + + wRet = ListBoxDirectory(hwnd, wParam, + (LPSTR)PTR_SEG_TO_LIN(lParam)); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + return wRet; +} + +/*********************************************************************** + * LBAddString + */ +LONG LBAddString( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + WORD wRet; + WND *wndPtr; + + wndPtr = WIN_FindWndPtr(hwnd); + + if (HasStrings(wndPtr)) + wRet = ListBoxAddString(hwnd, (LPSTR)PTR_SEG_TO_LIN(lParam)); + else + wRet = ListBoxAddString(hwnd, (LPSTR)lParam); + + return wRet; +} + +/*********************************************************************** + * LBGetText + */ +LONG LBGetText( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + LONG wRet; + + dprintf_listbox(stddeb, "LB_GETTEXT wParam=%d\n",wParam); + wRet = ListBoxGetText(hwnd, wParam, + (LPSTR)PTR_SEG_TO_LIN(lParam), FALSE); + + return wRet; +} + +/*********************************************************************** + * LBInsertString + */ +LONG LBInsertString( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + WORD wRet; + WND *wndPtr; + + wndPtr = WIN_FindWndPtr(hwnd); + + if (HasStrings(wndPtr)) + wRet = ListBoxInsertString(hwnd, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam)); + else + wRet = ListBoxInsertString(hwnd, wParam, (LPSTR)lParam); + + return wRet; +} + +/*********************************************************************** + * LBDeleteString + */ +LONG LBDeleteString( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + return ListBoxDeleteString(hwnd, wParam); +} + +/*********************************************************************** + * LBFindString + */ +LONG LBFindString( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + return ListBoxFindString(hwnd, wParam, + (LPSTR)PTR_SEG_TO_LIN(lParam)); +} + +/*********************************************************************** + * LBGetCaretIndex + */ +LONG LBGetCaretIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + LPHEADLIST lphl; + + lphl = ListBoxGetStorageHeader(hwnd); + if (lphl == NULL) return LB_ERR; + + return lphl->ItemFocused; +} + +/*********************************************************************** + * LBGetCount + */ +LONG LBGetCount( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + LPHEADLIST lphl; + + lphl = ListBoxGetStorageHeader(hwnd); + return lphl->ItemsCount; +} + +/*********************************************************************** + * LBGetCurSel + */ +LONG LBGetCurSel( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + LPHEADLIST lphl; + + lphl = ListBoxGetStorageHeader(hwnd); + dprintf_listbox(stddeb,"ListBox LB_GETCURSEL %u !\n", + lphl->ItemFocused); + return lphl->ItemFocused; +} + +/*********************************************************************** + * LBGetHorizontalExtent + */ +LONG LBGetHorizontalExtent( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + return 0; +} + +/*********************************************************************** + * LBGetItemData + */ +LONG LBGetItemData( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + dprintf_listbox(stddeb, "LB_GETITEMDATA wParam=%x\n", wParam); + return ListBoxGetText(hwnd, wParam, + (LPSTR)PTR_SEG_TO_LIN(lParam), TRUE); +} + +/*********************************************************************** + * LBGetItemHeight + */ +LONG LBGetItemHeight( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + RECT rect; + + ListBoxGetItemRect(hwnd, wParam, &rect); + return (rect.bottom - rect.top); +} + +/*********************************************************************** + * LBGetItemRect + */ +LONG LBGetItemRect( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + return ListBoxGetItemRect (hwnd, wParam, PTR_SEG_TO_LIN(lParam)); +} + +/*********************************************************************** + * LBGetSel + */ +LONG LBGetSel( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + return ListBoxGetSel (hwnd, wParam); +} + +/*********************************************************************** + * LBGetSelCount + */ +LONG LBGetSelCount( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + LPHEADLIST lphl; + LPLISTSTRUCT lpls; + int cnt = 0; + WND *wndPtr; + + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == NULL) return LB_ERR; + + if (!(wndPtr->dwStyle & LBS_MULTIPLESEL)) return LB_ERR; + + lpls = lphl->lpFirst; + + while (lpls != NULL) { + if (lpls->dis.itemState > 0) cnt++; + + lpls = lpls->lpNext; + } + + return cnt; +} + +/*********************************************************************** + * LBGetSelItems + */ +LONG LBGetSelItems( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + LPHEADLIST lphl; + LPLISTSTRUCT lpls; + int cnt, idx; + WND *wndPtr; + int *lpItems = PTR_SEG_TO_LIN(lParam); + + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == NULL) return LB_ERR; + + if (!(wndPtr->dwStyle & LBS_MULTIPLESEL)) return LB_ERR; + + if (wParam == 0) return 0; + + lpls = lphl->lpFirst; + cnt = 0; idx = 0; + + while (lpls != NULL) { + if (lpls->dis.itemState > 0) lpItems[cnt++] = idx; + + if (cnt == wParam) break; + idx++; + lpls = lpls->lpNext; + } + + return cnt; +} + +/*********************************************************************** + * LBGetTextLen + */ +LONG LBGetTextLen( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + LPHEADLIST lphl; + LPLISTSTRUCT lpls; + WND *wndPtr; + int cnt = 0; + + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == NULL) return LB_ERR; + + if (!HasStrings(wndPtr)) return LB_ERR; + + if (wParam >= lphl->ItemsCount) return LB_ERR; + + lpls = lphl->lpFirst; + + while (cnt++ < wParam) lpls = lpls->lpNext; + + return strlen(lpls->itemText); +} + +/*********************************************************************** + * LBGetDlgCode + */ +LONG LBGetDlgCode( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + return DLGC_WANTALLKEYS; +} + +/*********************************************************************** + * LBGetTopIndex + */ +LONG LBGetTopIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + LPHEADLIST lphl; + + lphl = ListBoxGetStorageHeader(hwnd); + if (lphl == NULL) return LB_ERR; + + return (lphl->FirstVisible - 1); +} + + +/*********************************************************************** + * LBSelectString + */ +LONG LBSelectString( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + WND *wndPtr; + WORD wRet; + + wndPtr = WIN_FindWndPtr(hwnd); + + wRet = ListBoxFindString(hwnd, wParam, + (LPSTR)PTR_SEG_TO_LIN(lParam)); + + /* XXX add functionality here */ + + return 0; +} + +/*********************************************************************** + * LBSelItemRange + */ +LONG LBSelItemRange( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + LPHEADLIST lphl; + LPLISTSTRUCT lpls; + WND *wndPtr; + WORD cnt; + WORD first = LOWORD(lParam); + WORD last = HIWORD(lParam); + BOOL select = wParam; + + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == NULL) return LB_ERR; + + if (!(wndPtr->dwStyle & LBS_MULTIPLESEL)) return LB_ERR; + + if (first >= lphl->ItemsCount || + last >= lphl->ItemsCount) return LB_ERR; + + lpls = lphl->lpFirst; + cnt = 0; + + while (lpls != NULL) { + if (cnt++ >= first) + lpls->dis.itemState = select ? ODS_SELECTED : 0; + + if (cnt > last) + break; + + lpls = lpls->lpNext; + } + + return 0; +} + +/*********************************************************************** + * LBSetCaretIndex + */ +LONG LBSetCaretIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + LPHEADLIST lphl; + WND *wndPtr; + + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == NULL) return LB_ERR; + + if (!(wndPtr->dwStyle & LBS_MULTIPLESEL)) return 0; + if (wParam >= lphl->ItemsCount) return LB_ERR; + + lphl->ItemFocused = wParam; + ListBoxScrolltoFocus (hwnd); + + SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + return 0; +} + +/*********************************************************************** + * LBSetColumnWidth + */ +LONG LBSetColumnWidth( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + LPHEADLIST lphl; + + lphl = ListBoxGetStorageHeader(hwnd); + if (lphl == NULL) return LB_ERR; + lphl->ColumnsWidth = wParam; + + return 0; +} + +/*********************************************************************** + * LBSetHorizontalExtent + */ +LONG LBSetHorizontalExtent( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + return 0; +} + +/*********************************************************************** + * LBSetItemData + */ +LONG LBSetItemData( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + dprintf_listbox(stddeb, "LB_SETITEMDATA wParam=%x lParam=%lx\n", wParam, lParam); + return ListBoxSetItemData(hwnd, wParam, lParam); +} + +/*********************************************************************** + * LBSetTabStops + */ +LONG LBSetTabStops( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + LPHEADLIST lphl; + + lphl = ListBoxGetStorageHeader(hwnd); + + if (lphl->TabStops != NULL) { + lphl->iNumStops = 0; + free (lphl->TabStops); + } + + lphl->TabStops = malloc (wParam * sizeof (short)); + if (lphl->TabStops) { + lphl->iNumStops = wParam; + memcpy (lphl->TabStops, PTR_SEG_TO_LIN(lParam), wParam * sizeof (short)); + return TRUE; + } + + return FALSE; +} + +/*********************************************************************** + * LBSetCurSel + */ +LONG LBSetCurSel( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + LPHEADLIST lphl; + WORD wRet; + + lphl = ListBoxGetStorageHeader(hwnd); + if (lphl == NULL) return LB_ERR; + + dprintf_listbox(stddeb,"ListBox LB_SETCURSEL wParam=%x !\n", + wParam); + + wRet = ListBoxSetCurSel(hwnd, wParam); + + SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + + return wRet; +} + +/*********************************************************************** + * LBSetSel + */ +LONG LBSetSel( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + WORD wRet; + + dprintf_listbox(stddeb,"ListBox LB_SETSEL wParam=%x lParam=%lX !\n", wParam, lParam); + + wRet = ListBoxSetSel(hwnd, LOWORD(lParam), wParam); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + + return wRet; +} + +/*********************************************************************** + * LBSetTopIndex + */ +LONG LBSetTopIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + LPHEADLIST lphl; + + dprintf_listbox(stddeb,"ListBox LB_SETTOPINDEX wParam=%x !\n", + wParam); + lphl = ListBoxGetStorageHeader(hwnd); + lphl->FirstVisible = wParam; + SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); + + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + + return 0; +} + +/*********************************************************************** + * LBSetItemHeight + */ +LONG LBSetItemHeight( HWND hwnd, WORD message, WORD wParam, LONG lParam) + +{ + WORD wRet; + + dprintf_listbox(stddeb,"ListBox LB_SETITEMHEIGHT wParam=%x lParam=%lX !\n", wParam, lParam); + wRet = ListBoxSetItemHeight(hwnd, wParam, lParam); + return wRet; +} + + +/*********************************************************************** + * ListBoxWndProc + */ + +LONG ListBoxWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + int idx = 0; + int table_size = sizeof (methods) / sizeof (msg_tbl); + + while (idx < table_size) { + if (message == methods[idx].message) { + return (*(methods[idx].handler))(hwnd, message, wParam, lParam); + } + idx++; + } + + return DefWindowProc (hwnd, message, wParam, lParam); +} + + +LPLISTSTRUCT ListBoxGetItem(HWND hwnd, UINT uIndex) + +{ + LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd); + LPLISTSTRUCT lpls; + UINT Count = 0; + + if (uIndex >= lphl->ItemsCount) return NULL; + + lpls = lphl->lpFirst; + + while (Count++ < uIndex) lpls = lpls->lpNext; + + return lpls; +} + + +LPHEADLIST ListBoxGetWindowAndStorage(HWND hwnd, WND **wndPtr) +{ + WND *Ptr; + LPHEADLIST lphl; + *(wndPtr) = Ptr = WIN_FindWndPtr(hwnd); + lphl = *((LPHEADLIST *)&Ptr->wExtra[1]); + return lphl; +} + + +LPHEADLIST ListBoxGetStorageHeader(HWND hwnd) +{ + WND *wndPtr; + LPHEADLIST lphl; + wndPtr = WIN_FindWndPtr(hwnd); + lphl = *((LPHEADLIST *)&wndPtr->wExtra[1]); + return lphl; +} + + +void ListBoxDrawItem (HWND hwnd, HDC hdc, LPLISTSTRUCT lpls, + WORD itemAction, WORD itemState) + +{ + LPHEADLIST lphl; + WND *wndPtr; + + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + + if (OWNER_DRAWN(wndPtr)) { + DRAWITEMSTRUCT *dis = USER_HEAP_LIN_ADDR(lphl->hDrawItemStruct); + + memcpy (dis, &lpls->dis, sizeof(DRAWITEMSTRUCT)); + + dis->CtlType = ODT_LISTBOX; + dis->hDC = hdc; + + if ((!dis->CtlID) && lphl->hWndLogicParent) { + WND *ParentWndPtr; + + ParentWndPtr = WIN_FindWndPtr(lphl->hWndLogicParent); + dis->CtlID = ParentWndPtr->wIDmenu; + } + + if (HasStrings(wndPtr)) dis->itemData = (DWORD)lpls->itemText; + + dis->itemAction = itemAction; + dis->itemState = itemState; + + SendMessage(lphl->hWndLogicParent, WM_DRAWITEM, + 0, (LPARAM)USER_HEAP_SEG_ADDR(lphl->hDrawItemStruct)); + } + else { + + if (itemAction == ODA_DRAWENTIRE || + itemAction == ODA_SELECT) { + int OldBkMode; + DWORD dwOldTextColor; + + OldBkMode = SetBkMode(hdc, TRANSPARENT); + + if (itemState != 0) { + dwOldTextColor = SetTextColor(hdc, 0x00FFFFFFL); + FillRect(hdc, &lpls->dis.rcItem, GetStockObject(BLACK_BRUSH)); + } + + if (wndPtr->dwStyle & LBS_USETABSTOPS) + TabbedTextOut(hdc, lpls->dis.rcItem.left + 5, + lpls->dis.rcItem.top + 2, + (char *)lpls->itemText, + strlen((char *)lpls->itemText), lphl->iNumStops, + lphl->TabStops, 0); + else + TextOut(hdc, lpls->dis.rcItem.left + 5, lpls->dis.rcItem.top + 2, + (char *)lpls->itemText, strlen((char *)lpls->itemText)); + + if (itemState != 0) { + SetTextColor(hdc, dwOldTextColor); + } + + SetBkMode(hdc, OldBkMode); + } else DrawFocusRect(hdc, &lpls->dis.rcItem); + } + + return; +} + +void RepaintListBox(HWND hwnd) + +{ + WND *wndPtr; + LPHEADLIST lphl; + LPLISTSTRUCT lpls; + PAINTSTRUCT ps; + HBRUSH hBrush; + + HDC hdc; + RECT rect; + int i, top, height, maxwidth, ipc; + + top = 0; + + hdc = BeginPaint( hwnd, &ps ); + + if (!IsWindowVisible(hwnd)) { + EndPaint( hwnd, &ps ); + return; + } + + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == NULL) goto EndOfPaint; + if (!lphl->bRedrawFlag) goto EndOfPaint; + + SelectObject(hdc, lphl->hFont); + + hBrush = SendMessage(lphl->hWndLogicParent, WM_CTLCOLOR, (WORD)hdc, + MAKELONG(hwnd, CTLCOLOR_LISTBOX)); + + if (hBrush == (HBRUSH)NULL) hBrush = GetStockObject(WHITE_BRUSH); + + GetClientRect(hwnd, &rect); + FillRect(hdc, &rect, hBrush); + + maxwidth = rect.right; + rect.right = lphl->ColumnsWidth; + + if (lphl->ItemsCount == 0) goto EndOfPaint; + + lpls = lphl->lpFirst; + + lphl->ItemsVisible = 0; + lphl->ItemsPerColumn = ipc = 0; + + for(i = 0; i < lphl->ItemsCount; i++) { + if (lpls == NULL) goto EndOfPaint; + + if (i >= lphl->FirstVisible - 1) { + height = lpls->dis.rcItem.bottom - lpls->dis.rcItem.top; + + if (top > rect.bottom) { + if ((wndPtr->dwStyle & LBS_MULTICOLUMN) == LBS_MULTICOLUMN) { + lphl->ItemsPerColumn = max(lphl->ItemsPerColumn, ipc); + ipc = 0; + top = 0; + rect.left += lphl->ColumnsWidth; + rect.right += lphl->ColumnsWidth; + if (rect.left > maxwidth) break; + } + else + break; + } + + lpls->dis.rcItem.top = top; + lpls->dis.rcItem.bottom = top + height; + lpls->dis.rcItem.left = rect.left; + lpls->dis.rcItem.right = rect.right; + + if (OWNER_DRAWN(wndPtr)) { + ListBoxDrawItem (hwnd, hdc, lpls, ODA_DRAWENTIRE, 0); + if (lpls->dis.itemState) + ListBoxDrawItem (hwnd, hdc, lpls, ODA_SELECT, ODS_SELECTED); + } + else + ListBoxDrawItem (hwnd, hdc, lpls, ODA_DRAWENTIRE, lpls->dis.itemState); + + if ((lphl->ItemFocused == i) && GetFocus() == hwnd) + ListBoxDrawItem (hwnd, hdc, lpls, ODA_FOCUS, ODS_FOCUS); + + top += height; + lphl->ItemsVisible++; + ipc++; + } + + lpls = lpls->lpNext; + } + EndOfPaint: + EndPaint( hwnd, &ps ); +} + +int ListBoxFindMouse(HWND hwnd, int X, int Y) + +{ + WND *wndPtr; + LPHEADLIST lphl; + LPLISTSTRUCT lpls; + RECT rect; + int i, h, h2, w, w2; + + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + + if (lphl == NULL) return LB_ERR; + if (lphl->ItemsCount == 0) return LB_ERR; + + lpls = lphl->lpFirst; + if (lpls == NULL) return LB_ERR; + GetClientRect(hwnd, &rect); + h = w2 = 0; + w = lphl->ColumnsWidth; + + for(i = 1; i <= lphl->ItemsCount; i++) { + if (i >= lphl->FirstVisible) { + h2 = h; + h += lpls->dis.rcItem.bottom - lpls->dis.rcItem.top; + if ((Y > h2) && (Y < h) && + (X > w2) && (X < w)) return(i - 1); + if (h > rect.bottom) { + if ((wndPtr->dwStyle & LBS_MULTICOLUMN) != LBS_MULTICOLUMN) return LB_ERR; + h = 0; + w2 = w; + w += lphl->ColumnsWidth; + if (w2 > rect.right) return LB_ERR; + } + } + if (lpls->lpNext == NULL) return LB_ERR; + lpls = (LPLISTSTRUCT)lpls->lpNext; + } + return(LB_ERR); +} + +void ListBoxAskMeasure(WND *wndPtr, LPHEADLIST lphl, LPLISTSTRUCT lpls) + +{ + MEASUREITEMSTRUCT *lpmeasure; + + HANDLE hTemp = USER_HEAP_ALLOC( sizeof(MEASUREITEMSTRUCT) ); + + lpmeasure = (MEASUREITEMSTRUCT *) USER_HEAP_LIN_ADDR(hTemp); + + if (lpmeasure == NULL) { + fprintf(stderr,"ListBoxAskMeasure() // Bad allocation of Measure struct !\n"); + return; + } + + lpmeasure->CtlType = ODT_LISTBOX; + lpmeasure->CtlID = wndPtr->wIDmenu; + lpmeasure->itemID = lpls->dis.itemID; + lpmeasure->itemWidth = wndPtr->rectWindow.right - wndPtr->rectWindow.left; + lpmeasure->itemHeight = 0; + + if (HasStrings(wndPtr)) + lpmeasure->itemData = (DWORD)lpls->itemText; + else + lpmeasure->itemData = lpls->dis.itemData; + + SendMessage(lphl->hWndLogicParent, WM_MEASUREITEM, + 0, USER_HEAP_SEG_ADDR(hTemp)); + + if (wndPtr->dwStyle & LBS_OWNERDRAWFIXED) { + lphl->StdItemHeight = lpmeasure->itemHeight; + } + + lpls->dis.rcItem.right = lpls->dis.rcItem.left + lpmeasure->itemWidth; + lpls->dis.rcItem.bottom = lpls->dis.rcItem.top + lpmeasure->itemHeight; + USER_HEAP_FREE(hTemp); +} + + +int ListBoxAddString(HWND hwnd, LPSTR newstr) +{ + LPHEADLIST lphl; + UINT pos = (UINT) -1; + WND *wndPtr; + + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == NULL) return LB_ERR; + if (HasStrings(wndPtr) && (wndPtr->dwStyle & LBS_SORT)) { LPLISTSTRUCT lpls = lphl->lpFirst; for (pos = 0; lpls; lpls = lpls->lpNext, pos++) @@ -796,193 +1512,230 @@ int ListBoxAddString(HWND hwnd, LPSTR newstr) } int ListBoxInsertString(HWND hwnd, UINT uIndex, LPSTR newstr) + { - WND *wndPtr; - LPHEADLIST lphl; - LPLISTSTRUCT *lppls, lplsnew; - HANDLE hItem; - HANDLE hStr; - LPSTR str; - UINT Count; + WND *wndPtr; + LPHEADLIST lphl; + LPLISTSTRUCT *lppls, lplsnew; + HANDLE hItem; + HANDLE hStr; + LPSTR str; + UINT Count; - dprintf_listbox(stddeb,"ListBoxInsertString(%04X, %d, %p);\n", - hwnd, uIndex, newstr); + dprintf_listbox(stddeb,"ListBoxInsertString(%04X, %d, %p);\n", + hwnd, uIndex, newstr); - lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - if (lphl == NULL) return LB_ERR; + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == NULL) return LB_ERR; - if (uIndex == (UINT)-1) - uIndex = lphl->ItemsCount; - if (uIndex > lphl->ItemsCount) return LB_ERR; - lppls = (LPLISTSTRUCT *) &lphl->lpFirst; + if (uIndex == (UINT)-1) + uIndex = lphl->ItemsCount; + + if (uIndex > lphl->ItemsCount) return LB_ERR; + + lppls = (LPLISTSTRUCT *) &lphl->lpFirst; - for(Count = 0; Count < uIndex; Count++) { - if (*lppls == NULL) return LB_ERR; - lppls = (LPLISTSTRUCT *) &(*lppls)->lpNext; - } + for(Count = 0; Count < uIndex; Count++) { + if (*lppls == NULL) return LB_ERR; + lppls = (LPLISTSTRUCT *) &(*lppls)->lpNext; + } - hItem = LIST_HEAP_ALLOC(lphl, GMEM_MOVEABLE, sizeof(LISTSTRUCT)); - lplsnew = (LPLISTSTRUCT) LIST_HEAP_ADDR(lphl, hItem); - if (lplsnew == NULL) { - printf("ListBoxInsertString() // Bad allocation of new item !\n"); - return LB_ERRSPACE; - } - ListBoxDefaultItem(hwnd, wndPtr, lphl, lplsnew); - lplsnew->hMem = hItem; - lplsnew->lpNext = *lppls; - *lppls = lplsnew; - lphl->ItemsCount++; - hStr = 0; - - if (HasStrings(wndPtr)) { - hStr = LIST_HEAP_ALLOC(lphl, GMEM_MOVEABLE, strlen(newstr) + 1); - str = (LPSTR)LIST_HEAP_ADDR(lphl, hStr); - if (str == NULL) return LB_ERRSPACE; - strcpy(str, newstr); - newstr = str; - lplsnew->itemText = str; - dprintf_listbox(stddeb,"ListBoxInsertString // LBS_HASSTRINGS after strcpy '%s'\n", str); - } - else { - lplsnew->itemText = NULL; - lplsnew->dis.itemData = (DWORD)newstr; - } - lplsnew->dis.itemID = lphl->ItemsCount; - lplsnew->hData = hStr; - if (((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) == LBS_OWNERDRAWVARIABLE) || - ((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) == LBS_OWNERDRAWFIXED)) - ListBoxAskMeasure(wndPtr, lphl, lplsnew); - SetScrollRange(hwnd, SB_VERT, 1, ListMaxFirstVisible(lphl), - (lphl->FirstVisible != 1 && lphl->bRedrawFlag)); - if (lphl->ItemsPerColumn != 0) - SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / - lphl->ItemsPerColumn + 1, - (lphl->FirstVisible != 1 && lphl->bRedrawFlag)); - if ((lphl->FirstVisible <= uIndex) && - ((lphl->FirstVisible + lphl->ItemsVisible) >= uIndex)) { - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - } - dprintf_listbox(stddeb,"ListBoxInsertString // count=%d\n", lphl->ItemsCount); - return uIndex; + hItem = LIST_HEAP_ALLOC(lphl, GMEM_MOVEABLE, sizeof(LISTSTRUCT)); + lplsnew = (LPLISTSTRUCT) LIST_HEAP_ADDR(lphl, hItem); + + if (lplsnew == NULL) { + printf("ListBoxInsertString() // Bad allocation of new item !\n"); + return LB_ERRSPACE; + } + + ListBoxDefaultItem(hwnd, wndPtr, lphl, lplsnew); + lplsnew->hMem = hItem; + lplsnew->lpNext = *lppls; + *lppls = lplsnew; + lphl->ItemsCount++; + hStr = 0; + + if (HasStrings(wndPtr)) { + hStr = LIST_HEAP_ALLOC(lphl, GMEM_MOVEABLE, strlen(newstr) + 1); + str = (LPSTR)LIST_HEAP_ADDR(lphl, hStr); + if (str == NULL) return LB_ERRSPACE; + strcpy(str, newstr); + newstr = str; + lplsnew->itemText = str; + dprintf_listbox(stddeb,"ListBoxInsertString // LBS_HASSTRINGS after strcpy '%s'\n", str); + } + else { + lplsnew->itemText = NULL; + lplsnew->dis.itemData = (DWORD)newstr; + } + + lplsnew->dis.itemID = lphl->ItemsCount; + lplsnew->hData = hStr; + + if ((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) && (lphl->ItemsCount == 1)) { + ListBoxAskMeasure(wndPtr, lphl, lplsnew); + } + + if (wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) + ListBoxAskMeasure(wndPtr, lphl, lplsnew); + + SetScrollRange(hwnd, SB_VERT, 1, ListMaxFirstVisible(lphl), + (lphl->FirstVisible != 1 && lphl->bRedrawFlag)); + + if (lphl->ItemsPerColumn != 0) + SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / + lphl->ItemsPerColumn + 1, + (lphl->FirstVisible != 1 && lphl->bRedrawFlag)); + + if ((lphl->FirstVisible <= uIndex) && + ((lphl->FirstVisible + lphl->ItemsVisible) >= uIndex)) { + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + } + + dprintf_listbox(stddeb,"ListBoxInsertString // count=%d\n", lphl->ItemsCount); + return uIndex; } int ListBoxGetText(HWND hwnd, UINT uIndex, LPSTR OutStr, BOOL bItemData) + { - WND *wndPtr; - LPHEADLIST lphl; - LPLISTSTRUCT lpls; - UINT Count; - if ((!OutStr)&&(!bItemData)) - fprintf(stderr, "ListBoxGetText // OutStr==NULL\n"); - if (!bItemData) *OutStr=0; - lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - if (lphl == NULL) return LB_ERR; - if (uIndex >= lphl->ItemsCount) return LB_ERR; - lpls = lphl->lpFirst; - if (lpls == NULL) return LB_ERR; - if (uIndex > lphl->ItemsCount) return LB_ERR; - for(Count = 0; Count < uIndex; Count++) { - if (lpls->lpNext == NULL) return LB_ERR; - lpls = (LPLISTSTRUCT)lpls->lpNext; - } - if (bItemData) - return lpls->dis.itemData; - if (!(HasStrings(wndPtr)) ) - { - *((long *)OutStr) = lpls->dis.itemData; - return 4; - } + WND *wndPtr; + LPLISTSTRUCT lpls; + + wndPtr = WIN_FindWndPtr(hwnd); + + if (!OutStr && !bItemData) { + dprintf_listbox(stddeb, "ListBoxGetText // OutStr==NULL\n"); + return 0; + } + + if (!bItemData) *OutStr=0; + + if ((lpls = ListBoxGetItem (hwnd, uIndex)) == NULL) + return 0; + + if (bItemData) + return lpls->dis.itemData; + + if (!HasStrings(wndPtr)) { + *((long *)OutStr) = lpls->dis.itemData; + return 4; + } - strcpy(OutStr, lpls->itemText); - return strlen(OutStr); + strcpy(OutStr, lpls->itemText); + return strlen(OutStr); } int ListBoxSetItemData(HWND hwnd, UINT uIndex, DWORD ItemData) + { - WND *wndPtr; - LPHEADLIST lphl; - LPLISTSTRUCT lpls; - UINT Count; - lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - if (lphl == NULL) return LB_ERR; - if (uIndex >= lphl->ItemsCount) return LB_ERR; - lpls = lphl->lpFirst; - if (lpls == NULL) return LB_ERR; - if (uIndex > lphl->ItemsCount) return LB_ERR; - for(Count = 0; Count < uIndex; Count++) { - if (lpls->lpNext == NULL) return LB_ERR; - lpls = (LPLISTSTRUCT)lpls->lpNext; - } - lpls->dis.itemData = ItemData; - return 1; + LPLISTSTRUCT lpls; + + if ((lpls = ListBoxGetItem(hwnd, uIndex)) == NULL) + return 0; + + lpls->dis.itemData = ItemData; + return 1; } int ListBoxDeleteString(HWND hwnd, UINT uIndex) + { - WND *wndPtr; - LPHEADLIST lphl; - LPLISTSTRUCT lpls, lpls2; - UINT Count; - lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - if (lphl == NULL) return LB_ERR; - if (uIndex >= lphl->ItemsCount) return LB_ERR; - lpls = lphl->lpFirst; - if (lpls == NULL) return LB_ERR; - if (uIndex > lphl->ItemsCount) return LB_ERR; - if( uIndex == 0 ) - lphl->lpFirst = lpls->lpNext; - else { - for(Count = 0; Count < uIndex; Count++) { - if (lpls->lpNext == NULL) return LB_ERR; - lpls2 = lpls; - lpls = (LPLISTSTRUCT)lpls->lpNext; - } - lpls2->lpNext = (LPLISTSTRUCT)lpls->lpNext; + WND *wndPtr; + LPHEADLIST lphl; + LPLISTSTRUCT lpls, lpls2; + UINT Count; + + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == NULL) return LB_ERR; + + if (uIndex >= lphl->ItemsCount) return LB_ERR; + + lpls = lphl->lpFirst; + if (lpls == NULL) return LB_ERR; + + if( uIndex == 0 ) + lphl->lpFirst = lpls->lpNext; + else { + for(Count = 0; Count < uIndex; Count++) { + if (lpls->lpNext == NULL) return LB_ERR; + + lpls2 = lpls; + lpls = (LPLISTSTRUCT)lpls->lpNext; } - lphl->ItemsCount--; - if (lpls->hData != 0) LIST_HEAP_FREE(lphl, lpls->hData); - if (lpls->hMem != 0) LIST_HEAP_FREE(lphl, lpls->hMem); - SetScrollRange(hwnd, SB_VERT, 1, ListMaxFirstVisible(lphl), TRUE); - if (lphl->ItemsPerColumn != 0) - SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / - lphl->ItemsPerColumn + 1, TRUE); - if ((lphl->FirstVisible <= uIndex) && - ((lphl->FirstVisible + lphl->ItemsVisible) >= uIndex)) { - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - } - return lphl->ItemsCount; + lpls2->lpNext = (LPLISTSTRUCT)lpls->lpNext; + } + + lphl->ItemsCount--; + + if (lpls->hData != 0) LIST_HEAP_FREE(lphl, lpls->hData); + if (lpls->hMem != 0) LIST_HEAP_FREE(lphl, lpls->hMem); + + SetScrollRange(hwnd, SB_VERT, 1, ListMaxFirstVisible(lphl), TRUE); + if (lphl->ItemsPerColumn != 0) + SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / + lphl->ItemsPerColumn + 1, TRUE); + + if ((lphl->FirstVisible <= uIndex) && + ((lphl->FirstVisible + lphl->ItemsVisible) >= uIndex)) { + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + } + + return lphl->ItemsCount; } int ListBoxFindString(HWND hwnd, UINT nFirst, LPSTR MatchStr) { - WND *wndPtr; - LPHEADLIST lphl; - LPLISTSTRUCT lpls; - UINT Count; - lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - if (lphl == NULL) return LB_ERR; - if (nFirst > lphl->ItemsCount) return LB_ERR; - lpls = lphl->lpFirst; - if (lpls == NULL) return LB_ERR; - Count = 0; - while(lpls != NULL) { - if (HasStrings(wndPtr)) - { - if (strcmp(lpls->itemText, MatchStr) == 0) return Count; - } - else - { - if (lpls->dis.itemData == (DWORD)MatchStr) return Count; - } - lpls = (LPLISTSTRUCT)lpls->lpNext; - Count++; + WND *wndPtr; + LPHEADLIST lphl; + LPLISTSTRUCT lpls; + UINT Count; + UINT First = nFirst + 1; + + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + + if (lphl == NULL) return LB_ERR; + + if (First > lphl->ItemsCount) return LB_ERR; + + lpls = ListBoxGetItem(hwnd, First); + Count = 0; + while(lpls != NULL) { + if (HasStrings(wndPtr)) { + if (strstr(lpls->itemText, MatchStr) == lpls->itemText) return Count; + } else if (wndPtr->dwStyle & LBS_SORT) { + /* XXX Do a compare item */ + } + else + if (lpls->dis.itemData == (DWORD)MatchStr) return Count; + + lpls = lpls->lpNext; + Count++; + } + + /* Start over at top */ + Count = 0; + lpls = lphl->lpFirst; + + while (Count < First) { + if (HasStrings(wndPtr)) { + if (strstr(lpls->itemText, MatchStr) == lpls->itemText) return Count; + } else if (wndPtr->dwStyle & LBS_SORT) { + /* XXX Do a compare item */ } - return LB_ERR; + else + if (lpls->dis.itemData == (DWORD)MatchStr) return Count; + + lpls = lpls->lpNext; + Count++; + } + + return LB_ERR; } @@ -990,112 +1743,123 @@ int ListBoxResetContent(HWND hwnd) { WND *wndPtr; LPHEADLIST lphl; - LPLISTSTRUCT lpls, lpls2; + LPLISTSTRUCT lpls; UINT i; + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); if (lphl == NULL) return LB_ERR; + + if (lphl->ItemsCount == 0) return 0; + lpls = lphl->lpFirst; - if (lpls == NULL) return LB_ERR; + dprintf_listbox(stddeb, "ListBoxResetContent // ItemCount = %d\n", lphl->ItemsCount); - for(i = 0; i <= lphl->ItemsCount; i++) { - lpls2 = lpls; - lpls = (LPLISTSTRUCT)lpls->lpNext; - if (i != 0) { - dprintf_listbox(stddeb,"ResetContent #%u\n", i); - if (lpls2->hData != 0 && lpls2->hData != lpls2->hMem) - LIST_HEAP_FREE(lphl, lpls2->hData); - if (lpls2->hMem != 0) LIST_HEAP_FREE(lphl, lpls2->hMem); - } - if (lpls == NULL) break; + + for(i = 0; i < lphl->ItemsCount; i++) { + LPLISTSTRUCT lpls2; + + if (lpls == NULL) return LB_ERR; + + lpls2 = lpls->lpNext; + + if (i != 0) { + dprintf_listbox(stddeb,"ResetContent #%u\n", i); + if (lpls->hData != 0 && lpls->hData != lpls->hMem) + LIST_HEAP_FREE(lphl, lpls->hData); + + if (lpls->hMem != 0) LIST_HEAP_FREE(lphl, lpls->hMem); + } + + lpls = lpls2; } - lphl->lpFirst = NULL; + + lphl->lpFirst = NULL; lphl->FirstVisible = 1; - lphl->ItemsCount = 0; - lphl->ItemFocused = -1; - lphl->PrevFocused = -1; + lphl->ItemsCount = 0; + lphl->ItemFocused = -1; + lphl->PrevFocused = -1; + SetScrollRange(hwnd, SB_VERT, 1, ListMaxFirstVisible(lphl), TRUE); + if (lphl->ItemsPerColumn != 0) SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / lphl->ItemsPerColumn + 1, TRUE); + InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); + return TRUE; } int ListBoxSetCurSel(HWND hwnd, WORD wIndex) + { - WND *wndPtr; - LPHEADLIST lphl; - LPLISTSTRUCT lpls, lpls2; - UINT i; - lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - if (lphl == NULL) return LB_ERR; - if( (wIndex != (WORD)(-1)) && (wIndex > lphl->ItemsCount) ) - return LB_ERR; - lphl->ItemFocused = LB_ERR; - if (wIndex >= lphl->ItemsCount) return LB_ERR; - lpls = lphl->lpFirst; - if (lpls == NULL) return LB_ERR; - for(i = 0; i < lphl->ItemsCount; i++) { - lpls2 = lpls; - lpls = (LPLISTSTRUCT)lpls->lpNext; - if (i == wIndex) - lpls2->dis.itemState = 1; - else - if (lpls2->dis.itemState != 0) - lpls2->dis.itemState = 0; - if (lpls == NULL) break; - } + WND *wndPtr; + LPHEADLIST lphl; + LPLISTSTRUCT lpls; + + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == NULL) return LB_ERR; + + if (wndPtr->dwStyle & LBS_MULTIPLESEL) return 0; + + if (lphl->ItemFocused != -1) { + lpls = ListBoxGetItem(hwnd, lphl->ItemFocused); + lpls->dis.itemState = 0; + } + + if (wIndex != (UINT)-1) { lphl->ItemFocused = wIndex; - return wIndex; -} + lpls = ListBoxGetItem(hwnd, wIndex); + lpls->dis.itemState = ODS_SELECTED | ODS_FOCUS; + return 0; + } + return LB_ERR; +} int ListBoxSetSel(HWND hwnd, WORD wIndex, WORD state) + { - LPHEADLIST lphl; - LPLISTSTRUCT lpls, lpls2; - UINT i; - lphl = ListBoxGetStorageHeader(hwnd); - if (lphl == NULL) return LB_ERR; - if (wIndex >= lphl->ItemsCount) return LB_ERR; + LPHEADLIST lphl; + LPLISTSTRUCT lpls; + WND *wndPtr; + + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == NULL) return LB_ERR; + + if (!(wndPtr->dwStyle & LBS_MULTIPLESEL)) return 0; + + if (wIndex == (UINT)-1) { lpls = lphl->lpFirst; - if (lpls == NULL) return LB_ERR; - for(i = 0; i < lphl->ItemsCount; i++) { - lpls2 = lpls; - lpls = (LPLISTSTRUCT)lpls->lpNext; - if ((i == wIndex) || (wIndex == (WORD)-1)) { - lpls2->dis.itemState = state; - break; - } - if (lpls == NULL) break; + + while (lpls != NULL) { + lpls->dis.itemState = state; + lpls = lpls->lpNext; } - return LB_ERR; + + return 0; + } + + if (wIndex >= lphl->ItemsCount) return LB_ERR; + + lpls = ListBoxGetItem(hwnd, wIndex); + lpls->dis.itemState = state; + + return 0; } int ListBoxGetSel(HWND hwnd, WORD wIndex) { - LPHEADLIST lphl; - LPLISTSTRUCT lpls, lpls2; - UINT i; - lphl = ListBoxGetStorageHeader(hwnd); - if (lphl == NULL) return LB_ERR; - if (wIndex >= lphl->ItemsCount) return LB_ERR; - lpls = lphl->lpFirst; - if (lpls == NULL) return LB_ERR; - for(i = 0; i < lphl->ItemsCount; i++) { - lpls2 = lpls; - lpls = (LPLISTSTRUCT)lpls->lpNext; - if (i == wIndex) { - return lpls2->dis.itemState; - } - if (lpls == NULL) break; - } - return LB_ERR; + LPLISTSTRUCT lpls; + + if ((lpls = ListBoxGetItem(hwnd, wIndex)) == NULL) return LB_ERR; + + return lpls->dis.itemState; } @@ -1184,145 +1948,136 @@ int ListBoxDirectory(HWND hwnd, UINT attrib, LPSTR filespec) int ListBoxGetItemRect(HWND hwnd, WORD wIndex, LPRECT lprect) + { - LPHEADLIST lphl; - LPLISTSTRUCT lpls, lpls2; - UINT i; - lphl = ListBoxGetStorageHeader(hwnd); - if (lphl == NULL) return LB_ERR; - if (wIndex > lphl->ItemsCount) return LB_ERR; - lpls = lphl->lpFirst; - if (lpls == NULL) return LB_ERR; - for(i = 0; i < lphl->ItemsCount; i++) { - lpls2 = lpls; - lpls = (LPLISTSTRUCT)lpls->lpNext; - if (i == wIndex) { - *(lprect) = lpls2->dis.rcItem; - break; - } - if (lpls == NULL) break; - } - return LB_ERR; -} + LPLISTSTRUCT lpls; + if ((lpls = ListBoxGetItem(hwnd, wIndex)) == NULL) return LB_ERR; + + *(lprect) = lpls->dis.rcItem; + + return 0; +} int ListBoxSetItemHeight(HWND hwnd, WORD wIndex, long height) + { - LPHEADLIST lphl; - LPLISTSTRUCT lpls, lpls2; - UINT i; - lphl = ListBoxGetStorageHeader(hwnd); - if (lphl == NULL) return LB_ERR; - if (wIndex > lphl->ItemsCount) return LB_ERR; - lpls = lphl->lpFirst; - if (lpls == NULL) return LB_ERR; - for(i = 0; i < lphl->ItemsCount; i++) { - lpls2 = lpls; - lpls = (LPLISTSTRUCT)lpls->lpNext; - if (i == wIndex) { - lpls2->dis.rcItem.bottom = lpls2->dis.rcItem.top + (short)height; - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - break; - } - if (lpls == NULL) break; - } - return LB_ERR; -} + LPHEADLIST lphl; + WND *wndPtr; + LPLISTSTRUCT lpls; + + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == NULL) return LB_ERR; + if (!(wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE)) { + lphl->StdItemHeight = (short)height; + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + return 0; + } + if ((lpls = ListBoxGetItem(hwnd, wIndex)) == NULL) return LB_ERR; + + lpls->dis.rcItem.bottom = lpls->dis.rcItem.top + (short)height; + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + return 0; +} int ListBoxDefaultItem(HWND hwnd, WND *wndPtr, LPHEADLIST lphl, LPLISTSTRUCT lpls) + { - RECT rect; - if (wndPtr == NULL || lphl == NULL || lpls == NULL) { - fprintf(stderr,"ListBoxDefaultItem() // Bad Pointers !\n"); - return FALSE; - } - GetClientRect(hwnd, &rect); - SetRect(&lpls->dis.rcItem, 0, 0, rect.right, lphl->StdItemHeight); - lpls->dis.CtlType = lphl->DrawCtlType; - lpls->dis.CtlID = wndPtr->wIDmenu; - lpls->dis.itemID = 0; - lpls->dis.itemAction = 0; - lpls->dis.itemState = 0; - lpls->dis.hwndItem = hwnd; - lpls->dis.hDC = 0; - lpls->dis.itemData = 0; - return TRUE; + RECT rect; + + if (wndPtr == NULL || lphl == NULL || lpls == NULL) { + fprintf(stderr,"ListBoxDefaultItem() // Bad Pointers !\n"); + return FALSE; + } + + GetClientRect(hwnd, &rect); + SetRect(&lpls->dis.rcItem, 0, 0, rect.right, lphl->StdItemHeight); + + lpls->dis.CtlType = lphl->DrawCtlType; + lpls->dis.CtlID = wndPtr->wIDmenu; + lpls->dis.itemID = 0; + lpls->dis.itemAction = 0; + lpls->dis.itemState = 0; + lpls->dis.hwndItem = hwnd; + lpls->dis.hDC = 0; + lpls->dis.itemData = 0; + + return TRUE; } int ListBoxFindNextMatch(HWND hwnd, WORD wChar) + { - WND *wndPtr; - LPHEADLIST lphl; - LPLISTSTRUCT lpls; - UINT Count; - lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - if (lphl == NULL) return LB_ERR; - lpls = lphl->lpFirst; - if (lpls == NULL) return LB_ERR; - if (wChar < ' ') return LB_ERR; - if (((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) == LBS_OWNERDRAWFIXED) || - ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) == LBS_OWNERDRAWVARIABLE)) { - if ((wndPtr->dwStyle & LBS_HASSTRINGS) != LBS_HASSTRINGS) { - return LB_ERR; - } + WND *wndPtr; + LPHEADLIST lphl; + LPLISTSTRUCT lpls; + UINT Count; + + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + if (lphl == NULL) return LB_ERR; + lpls = lphl->lpFirst; + if (lpls == NULL) return LB_ERR; + if (wChar < ' ') return LB_ERR; + + if (!HasStrings(wndPtr)) return LB_ERR; + + Count = 0; + while(lpls != NULL) { + if (Count > lphl->ItemFocused) { + if (*(lpls->itemText) == (char)wChar) { + if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) { + lphl->ItemFocused = Count; + ListBoxScrolltoFocus(hwnd); } - Count = 0; - while(lpls != NULL) { - if (Count > lphl->ItemFocused) { - if (*(lpls->itemText) == (char)wChar) { - lphl->FirstVisible = Count - lphl->ItemsVisible / 2; - if (lphl->FirstVisible < 1) lphl->FirstVisible = 1; - if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) { - lphl->ItemFocused = Count; - } - else { - ListBoxSetCurSel(hwnd, Count); - } - SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - return Count; - } - } - lpls = (LPLISTSTRUCT)lpls->lpNext; - Count++; + else { + ListBoxSetCurSel(hwnd, Count); } - Count = 0; - lpls = lphl->lpFirst; - while(lpls != NULL) { - if (*(lpls->itemText) == (char)wChar) { - if (Count == lphl->ItemFocused) return LB_ERR; - lphl->FirstVisible = Count - lphl->ItemsVisible / 2; - if (lphl->FirstVisible < 1) lphl->FirstVisible = 1; - if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) { - lphl->ItemFocused = Count; - } - else { - ListBoxSetCurSel(hwnd, Count); - } - SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); - InvalidateRect(hwnd, NULL, TRUE); - UpdateWindow(hwnd); - return Count; - } - lpls = (LPLISTSTRUCT)lpls->lpNext; - Count++; - } - return LB_ERR; + SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + return Count; + } + } + lpls = (LPLISTSTRUCT)lpls->lpNext; + Count++; + } + Count = 0; + lpls = lphl->lpFirst; + while(lpls != NULL) { + if (*(lpls->itemText) == (char)wChar) { + if (Count == lphl->ItemFocused) return LB_ERR; + + if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) { + lphl->ItemFocused = Count; + ListBoxScrolltoFocus(hwnd); + } + else { + ListBoxSetCurSel(hwnd, Count); + } + SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE); + InvalidateRect(hwnd, NULL, TRUE); + UpdateWindow(hwnd); + return Count; + } + lpls = lpls->lpNext; + Count++; + } + return LB_ERR; } /************************************************************************ - * DlgDirSelect [USER.99] + * DlgDirSelect [USER.99] */ BOOL DlgDirSelect(HWND hDlg, LPSTR lpStr, int nIDLBox) { @@ -1364,53 +2119,85 @@ BOOL DlgDirSelect(HWND hDlg, LPSTR lpStr, int nIDLBox) /************************************************************************ - * DlgDirList [USER.100] + * DlgDirList [USER.100] */ int DlgDirList(HWND hDlg, LPSTR lpPathSpec, int nIDLBox, int nIDStat, WORD wType) { - HWND hWnd; - int ret; - dprintf_listbox(stddeb,"DlgDirList(%04X, '%s', %d, %d, %04X) \n", - hDlg, lpPathSpec, nIDLBox, nIDStat, wType); - if (nIDLBox) - hWnd = GetDlgItem(hDlg, nIDLBox); - else - hWnd = 0; - if (hWnd) - ListBoxResetContent(hWnd); - if (hWnd) - ret=ListBoxDirectory(hWnd, wType, lpPathSpec); - else - ret=0; - if (nIDStat) - { - int drive; - char temp[255]; - drive = DOS_GetDefaultDrive(); - strcpy( temp+3, DOS_GetCurrentDir(drive) ); - if( temp[3] == '\\' ) { - temp[1] = 'A'+drive; - temp[2] = ':'; - SendDlgItemMessage(hDlg, nIDStat, WM_SETTEXT, 0, (LONG)(temp+1)); - } - else { - temp[0] = 'A'+drive; - temp[1] = ':'; - temp[2] = '\\'; - SendDlgItemMessage(hDlg, nIDStat, WM_SETTEXT, 0, (LONG) temp ); - } - } - return ret; + HWND hWnd; + int ret; + dprintf_listbox(stddeb,"DlgDirList(%04X, '%s', %d, %d, %04X) \n", + hDlg, lpPathSpec, nIDLBox, nIDStat, wType); + if (nIDLBox) + hWnd = GetDlgItem(hDlg, nIDLBox); + else + hWnd = 0; + if (hWnd) + ListBoxResetContent(hWnd); + if (hWnd) + ret=ListBoxDirectory(hWnd, wType, lpPathSpec); + else + ret=0; + if (nIDStat) + { + int drive; + HANDLE hTemp; + char *temp; + drive = DOS_GetDefaultDrive(); + hTemp = USER_HEAP_ALLOC( 256 ); + temp = (char *) USER_HEAP_LIN_ADDR( hTemp ); + strcpy( temp+3, DOS_GetCurrentDir(drive) ); + if( temp[3] == '\\' ) { + temp[1] = 'A'+drive; + temp[2] = ':'; + SendDlgItemMessage( hDlg, nIDStat, WM_SETTEXT, 0, + USER_HEAP_SEG_ADDR(hTemp) + 1 ); + } + else { + temp[0] = 'A'+drive; + temp[1] = ':'; + temp[2] = '\\'; + SendDlgItemMessage( hDlg, nIDStat, WM_SETTEXT, 0, + USER_HEAP_SEG_ADDR(hTemp) ); + } + USER_HEAP_FREE( hTemp ); + } + return ret; } -/* get the maximum value of lphl->FirstVisible */ -int ListMaxFirstVisible(LPHEADLIST lphl) + +/* Returns: 0 if nothing needs to be changed */ +/* 1 if FirstVisible changed */ + +int ListBoxScrolltoFocus(HWND hwnd) + { - int m = lphl->ItemsCount-lphl->ItemsVisible+1; - return (m < 1) ? 1 : m; -} + WND *wndPtr; + LPHEADLIST lphl; + short end; + + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); + + if (lphl->ItemsCount == 0) return 0; + if (lphl->ItemFocused == -1) return 0; + + end = lphl->FirstVisible + lphl->ItemsVisible - 2; + if (lphl->ItemFocused < lphl->FirstVisible - 1) { + lphl->FirstVisible = lphl->ItemFocused + 1; + } + else if (lphl->ItemFocused > end) { + UINT maxFirstVisible = ListMaxFirstVisible(lphl); + + lphl->FirstVisible = lphl->ItemFocused; + + if (lphl->FirstVisible > maxFirstVisible) { + lphl->FirstVisible = maxFirstVisible; + } + } else return 0; + + return 1; +} /* Send notification "code" as part of a WM_COMMAND-message if hwnd has the LBS_NOTIFY style */ @@ -1419,7 +2206,8 @@ void ListBoxSendNotification(HWND hwnd, WORD code) WND *wndPtr; LPHEADLIST lphl; lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - if( wndPtr && ( (wndPtr->dwStyle && LBS_NOTIFY) != 0) ) + + if (wndPtr && (wndPtr->dwStyle & LBS_NOTIFY)) SendMessage(lphl->hWndLogicParent, WM_COMMAND, wndPtr->wIDmenu, MAKELONG(hwnd, code)); -} +} diff --git a/controls/menu.c b/controls/menu.c index ac118e902e1..2b20dbeaa7a 100644 --- a/controls/menu.c +++ b/controls/menu.c @@ -246,6 +246,27 @@ static void MENU_CalcItemSize( HDC hdc, LPMENUITEM lpitem, HWND hwndOwner, 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 = 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,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_SEPARATOR) { @@ -422,11 +443,35 @@ static void MENU_MenuBarCalcSize( HDC hdc, LPRECT lprect, LPPOPUPMENU lppop, * * Draw a single menu item. */ -static void MENU_DrawMenuItem( HDC hdc, LPMENUITEM lpitem, +static void MENU_DrawMenuItem( HWND hwnd, HDC hdc, LPMENUITEM lpitem, WORD height, BOOL menuBar ) { 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 = 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,distrsegp); + return; + } if (menuBar && (lpitem->item_flags & MF_SEPARATOR)) return; rect = lpitem->rect; @@ -566,7 +611,7 @@ static void MENU_DrawPopupMenu( HWND hwnd, HDC hdc, HMENU hmenu ) if (!menu || !menu->nItems) return; item = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems ); for (i = menu->nItems; i > 0; i--, item++) - MENU_DrawMenuItem( hdc, item, menu->Height, FALSE ); + MENU_DrawMenuItem( hwnd, hdc, item, menu->Height, FALSE ); } @@ -599,7 +644,7 @@ WORD MENU_DrawMenuBar(HDC hDC, LPRECT lprect, HWND hwnd, BOOL suppress_draw) lpitem = (MENUITEM *) USER_HEAP_LIN_ADDR( lppop->hItems ); for (i = 0; i < lppop->nItems; i++, lpitem++) { - MENU_DrawMenuItem( hDC, lpitem, lppop->Height, TRUE ); + MENU_DrawMenuItem( hwnd, hDC, lpitem, lppop->Height, TRUE ); } return lppop->Height; } @@ -677,7 +722,7 @@ static void MENU_SelectItem( HMENU hmenu, WORD wIndex ) else { items[lppop->FocusedItem].item_flags &=~(MF_HILITE|MF_MOUSESELECT); - MENU_DrawMenuItem( hdc, &items[lppop->FocusedItem], lppop->Height, + MENU_DrawMenuItem( lppop->hWnd, hdc, &items[lppop->FocusedItem], lppop->Height, !(lppop->wFlags & MF_POPUP) ); } } @@ -691,7 +736,7 @@ static void MENU_SelectItem( HMENU hmenu, WORD wIndex ) else { items[lppop->FocusedItem].item_flags |= MF_HILITE; - MENU_DrawMenuItem( hdc, &items[lppop->FocusedItem], lppop->Height, + MENU_DrawMenuItem( lppop->hWnd, hdc, &items[lppop->FocusedItem], lppop->Height, !(lppop->wFlags & MF_POPUP) ); SendMessage(lppop->hWnd, WM_MENUSELECT, items[lppop->FocusedItem].item_id, diff --git a/controls/widgets.c b/controls/widgets.c index 20e22dcc515..a2f17a9b8be 100644 --- a/controls/widgets.c +++ b/controls/widgets.c @@ -14,37 +14,31 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "mdi.h" #include "gdi.h" #include "user.h" - -LONG ListBoxWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam ); -LONG ComboBoxWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam ); -LONG EditWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam ); -LONG PopupMenuWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam ); -LONG DesktopWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam ); -LONG MDIClientWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam ); +#include "selectors.h" static WNDCLASS WIDGETS_BuiltinClasses[] = { - { CS_GLOBALCLASS | CS_PARENTDC, ButtonWndProc, 0, sizeof(BUTTONINFO), - 0, 0, 0, 0, NULL, "BUTTON" }, - { CS_GLOBALCLASS | CS_PARENTDC, StaticWndProc, 0, sizeof(STATICINFO), - 0, 0, 0, 0, NULL, "STATIC" }, - { CS_GLOBALCLASS | CS_PARENTDC, ScrollBarWndProc, 0, sizeof(SCROLLINFO), - 0, 0, 0, 0, NULL, "SCROLLBAR" }, - { CS_GLOBALCLASS | CS_PARENTDC | CS_DBLCLKS, ListBoxWndProc, 0, 8, - 0, 0, 0, 0, NULL, "LISTBOX" }, - { CS_GLOBALCLASS | CS_PARENTDC | CS_DBLCLKS, ComboBoxWndProc, 0, 8, - 0, 0, 0, 0, NULL, "COMBOBOX" }, - { CS_GLOBALCLASS | CS_PARENTDC, EditWndProc, 0, sizeof(WORD), - 0, 0, 0, 0, NULL, "EDIT" }, - { CS_GLOBALCLASS | CS_SAVEBITS, PopupMenuWndProc, 0, 8, - 0, 0, 0, 0, NULL, POPUPMENU_CLASS_NAME }, - { CS_GLOBALCLASS, DesktopWndProc, 0, sizeof(DESKTOPINFO), - 0, 0, 0, 0, NULL, DESKTOP_CLASS_NAME }, - { CS_GLOBALCLASS | CS_SAVEBITS, DefDlgProc, 0, DLGWINDOWEXTRA, - 0, 0, 0, 0, NULL, DIALOG_CLASS_NAME }, - { CS_GLOBALCLASS, MDIClientWndProc, 0, sizeof(MDICLIENTINFO), - 0, 0, 0, STOCK_LTGRAY_BRUSH, NULL, "MDICLIENT" } + { CS_GLOBALCLASS | CS_PARENTDC, (WNDPROC)"ButtonWndProc", 0, + sizeof(BUTTONINFO), 0, 0, 0, 0, NULL, "BUTTON" }, + { CS_GLOBALCLASS | CS_PARENTDC, (WNDPROC)"StaticWndProc", 0, + sizeof(STATICINFO), 0, 0, 0, 0, NULL, "STATIC" }, + { CS_GLOBALCLASS | CS_PARENTDC, (WNDPROC)"ScrollBarWndProc", 0, + sizeof(SCROLLINFO), 0, 0, 0, 0, NULL, "SCROLLBAR" }, + { CS_GLOBALCLASS | CS_PARENTDC | CS_DBLCLKS, (WNDPROC)"ListBoxWndProc", 0, + 8, 0, 0, 0, 0, NULL, "LISTBOX" }, + { CS_GLOBALCLASS | CS_PARENTDC | CS_DBLCLKS, (WNDPROC)"ComboBoxWndProc", 0, + 8, 0, 0, 0, 0, NULL, "COMBOBOX" }, + { CS_GLOBALCLASS, (WNDPROC)"EditWndProc", 0, + sizeof(WORD), 0, 0, 0, 0, NULL, "EDIT" }, + { CS_GLOBALCLASS | CS_SAVEBITS, (WNDPROC)"PopupMenuWndProc", 0, + 8, 0, 0, 0, 0, NULL, POPUPMENU_CLASS_NAME }, + { CS_GLOBALCLASS, (WNDPROC)"DesktopWndProc", 0, + sizeof(DESKTOPINFO), 0, 0, 0, 0, NULL, DESKTOP_CLASS_NAME }, + { CS_GLOBALCLASS | CS_SAVEBITS, (WNDPROC)"DefDlgProc", 0, + DLGWINDOWEXTRA, 0, 0, 0, 0, NULL, DIALOG_CLASS_NAME }, + { CS_GLOBALCLASS, (WNDPROC)"MDIClientWndProc", 0, + sizeof(MDICLIENTINFO), 0, 0, 0, STOCK_LTGRAY_BRUSH, NULL, "MDICLIENT" } }; #define NB_BUILTIN_CLASSES \ @@ -70,6 +64,7 @@ BOOL WIDGETS_Init(void) strcpy( name, class->lpszClassName ); class->lpszClassName = (LPSTR)USER_HEAP_SEG_ADDR( hName ); class->hCursor = LoadCursor( 0, IDC_ARROW ); + class->lpfnWndProc = GetWndProcEntry16( (char *)class->lpfnWndProc ); if (!RegisterClass( class )) return FALSE; } USER_HEAP_FREE( hName ); diff --git a/debugger/info.c b/debugger/info.c index 950624077d1..8b1604ffbd8 100644 --- a/debugger/info.c +++ b/debugger/info.c @@ -277,11 +277,12 @@ void dbg_bt(){ while((cs & 3) == 3) { /* See if in 32 bit mode or not. Assume GDT means 32 bit. */ if ((cs & 7) != 7) { - void CallTo32(); + extern int main(); fprintf(stderr,"%d ",frameno++); print_address(frame->u.win32.saved_ip,stderr,32); fprintf( stderr, "\n" ); - if(frame->u.win32.saved_ip<((unsigned long)CallTo32+1000))break; + if (frame->u.win32.saved_ip >= ((unsigned long)main) && + frame->u.win32.saved_ip <= ((unsigned long)main+1000)) break; frame = (struct frame *) frame->u.win32.saved_bp; } else { if (frame->u.win16.saved_bp & 1) cs = frame->u.win16.saved_cs; diff --git a/if1632/Imakefile b/if1632/Imakefile index 85ef1ea08b1..99e872bdac6 100644 --- a/if1632/Imakefile +++ b/if1632/Imakefile @@ -9,40 +9,45 @@ SRCS = \ #ifdef WINELIB CALLOBJS = -DLLOBJS = +DLLS = #else -CALLOBJS = call.o -DLLOBJS = \ - dll_commdlg.o \ - dll_compobj.o \ - dll_gdi.o \ - dll_kernel.o \ - dll_keyboard.o \ - dll_mmsystem.o \ - dll_mouse.o \ - dll_ole2.o \ - dll_ole2conv.o \ - dll_ole2disp.o \ - dll_ole2nls.o \ - dll_ole2prox.o \ - dll_olecli.o \ - dll_olesvr.o \ - dll_shell.o \ - dll_sound.o \ - dll_storage.o \ - dll_stress.o \ - dll_system.o \ - dll_toolhelp.o \ - dll_user.o \ - dll_win87em.o \ - dll_winsock.o +CALLOBJS = \ + call16.o \ + call32.o +DLLS = \ + commdlg \ + compobj \ + gdi \ + kernel \ + keyboard \ + mmsystem \ + mouse \ + ole2 \ + ole2conv \ + ole2disp \ + ole2nls \ + ole2prox \ + olecli \ + olesvr \ + shell \ + sound \ + storage \ + stress \ + system \ + toolhelp \ + user \ + win87em \ + winprocs \ + winsock #endif -#ifndef NewBuild -OBJS = $(CALLOBJS) $(DLLOBJS) $(SRCS:.c=.o) $(DLLOBJS:.o=_tab.o) -#else -OBJS = $(CALLOBJS) $(DLLOBJS) $(SRCS:.c=.o) $(DLLOBJS:.o=_tab.o) $(DLLOBJS:dll_.rly_) -#endif +OBJS = $(DLLS:%=dll_%.o) $(CALLOBJS) $(SRCS:.c=.o) $(DLLS:%=tab_%.o) + +BUILD = $(TOP)/tools/build + +#define MakeDllFromSpec(name) @@\ +Concat(dll_,name.S) Concat(tab_,name.c): name.spec $(BUILD) @@\ + $(BUILD) -spec name.spec @@\ /* * If you add a new spec file, copy one of these lines @@ -69,23 +74,25 @@ MakeDllFromSpec(system) MakeDllFromSpec(toolhelp) MakeDllFromSpec(user) MakeDllFromSpec(win87em) +MakeDllFromSpec(winprocs) MakeDllFromSpec(winsock) WineRelocatableTarget($(MODULE),,$(OBJS)) DependTarget() #ifndef WINELIB -pop.h: $(TOP)/tools/build - $(TOP)/tools/build -p -call.o: call.S pop.h - $(CC) -I. -c -o call.o call.S -#endif +call32.S: $(BUILD) $(DLLS:%=dll_%.S) + $(BUILD) -call32 `cat $(DLLS:%=dll_%.S) | grep CallTo32_ | sed 's/.*CallTo32_\(.*\)/\1/' | sort | uniq` > call32.S + +call16.S: $(BUILD) $(TOP)/include/callback.h + $(BUILD) -call16 `cat $(TOP)/include/callback.h | grep "extern.*CallTo16_" | sed 's/.*CallTo16_\(.*\)(.*/\1/' | sort | uniq` > call16.S + +#endif /* WINELIB */ includes:: - touch pop.h install:: clean:: - $(RM) dll* dtb* pop.h call.s + $(RM) dll_* tab_* call32.S call16.S diff --git a/if1632/call.S b/if1632/call.S deleted file mode 100644 index e6ab7b3eb0c..00000000000 --- a/if1632/call.S +++ /dev/null @@ -1,530 +0,0 @@ -/* - * Copyright Robert J. Amstadt, 1993 - */ -#ifdef linux -#define UDATASEL 0x2b -#endif -#if defined(__NetBSD__) || defined(__FreeBSD__) -#define UDATASEL 0x27 -#endif -#ifdef __ELF__ -#define A(addr) addr -#else -#define A(addr) _##addr -#endif - .data -jump_target: -return_value: - .long 0 - -/********************************************************************** - * Places to keep info about the current 32-bit stack frame. - */ - .globl A( IF1632_Saved32_esp), A(IF1632_Saved32_ebp), A(IF1632_Saved32_ss) -A(IF1632_Saved32_esp:) - .long 0 -A(IF1632_Saved32_ebp:) - .long 0 -A(IF1632_Saved32_ss:) - .word 0 -#ifdef __ELF__ -A(IF1632_ELF_KLUDGE:) - .long 0 - .word 0x0f -#endif - -/********************************************************************** - * Places to keep info about the current 16-bit stack frame. - */ - .globl A(IF1632_Saved16_sp),A(IF1632_Saved16_bp),A(IF1632_Saved16_ss) -A(IF1632_Saved16_sp:) - .word 0 -A(IF1632_Saved16_bp:) - .word 0 -A(IF1632_Saved16_ss:) - .word 0 - -nbytes: - .word 0 -selector: - .word 0 -offset: - .word 0 - - .text - -/********************************************************************** - * int CallToInit16(unsigned long csip, unsigned long sssp, - * unsigned short ds) - * - * Stack: 0 ebp - * 4 eip - * 8 target ip - * 10 target cs - * 12 target sp - * 14 target ss - * 16 target ds - */ - .align 4 - .globl A(CallToInit16) -A(CallToInit16:) - pushl %ebp - movl %esp,%ebp - - /* - * Save our registers - */ - pushal - pushl A(IF1632_Saved32_esp) - pushl A(IF1632_Saved32_ebp) - pushw A(IF1632_Saved32_ss) - -#ifdef __ELF__ - /* change to the other code segment */ - movw $0x0f, %ax - movw %ax, A(IF1632_ELF_KLUDGE)+4 - movl $L4, %eax - andl $0x0000ffff, %eax - movl %eax,A(IF1632_ELF_KLUDGE) - ljmp A(IF1632_ELF_KLUDGE) -L4: -#endif - /* - * Get target address. - */ - movl 8(%ebp),%eax - movl %eax,jump_target - lea jump_target,%edx - - /* - * Put stack registers where we can get them after stack switch. - */ - movw %ss,A(IF1632_Saved32_ss) - movl %esp,A(IF1632_Saved32_esp) - movl %ebp,A(IF1632_Saved32_ebp) - - /* - * Load initial registers - */ - movw A(WIN_StackSize),%bx - movw A(WIN_HeapSize),%cx - movl $0,%esi - xorl %eax,%eax - movw A(PSPSelector),%ax - movw %ax,%es - movw 16(%ebp),%ax - movw %ax,%ds - movl %eax,%edi - xorl %eax,%eax - movw 12(%ebp),%ax - movl %eax,%esp - movw 14(%ebp),%ax - movw %ax,%ss - movl %esp,%eax - movl %eax,%ebp - movw $UDATASEL,%ax - movw %ax,%fs - movw %ax,%gs - movw %ds,%ax - - /* - * Call entry point - */ - .byte 0x66 - lcall %fs:(%edx) - - /* - * Restore old stack and segment registers. - * - * Two choices here: - * 1. Trust that fs or gs hasn't changed. - * 2. Rely on knowledge of Linux use of segments. - * - * I'll opt for choice 2 because who knows what programs we - * going to run. Linux should be fairly stable in terms of - * GDT usage. - */ - pushl %eax - movw $UDATASEL,%ax - movw %ax,%ds - movw %ax,%es - movw %ax,%fs - movw %ax,%gs - popl %eax - movw A(IF1632_Saved32_ss),%ss - movl A(IF1632_Saved32_esp),%esp - movl A(IF1632_Saved32_ebp),%ebp - - /* - * Restore registers, but do not destroy return value. - */ - popw A(IF1632_Saved32_ss) - popl A(IF1632_Saved32_ebp) - popl A(IF1632_Saved32_esp) - movl %eax,return_value -#ifdef __ELF__ - /* change back */ - movw $0x23, %ax - movw %ax, A(IF1632_ELF_KLUDGE)+4 - movl $L5, %eax - movl %eax,A(IF1632_ELF_KLUDGE) - ljmp A(IF1632_ELF_KLUDGE) -L5: -#endif - popal - movl return_value,%eax - .align 2,0x90 - leave - ret - -/********************************************************************** - * int CallTo16 (unsigned long csip, unsigned short ds) - * int CallTo16cx(unsigned long csip, unsigned long dscx); - * - * Stack: 0 ebp - * 4 eip - * 8 target ip - * 10 target cs - * 12 target ds - * 14 target cx (only CallTo16cx) - * 16 target di - */ - .align 4 - .globl A(CallTo16), A(CallTo16cx), A(CallToLibMain) -A(CallToLibMain:) - pushl %ebp - movl %esp,%ebp - movw 16(%ebp),%di - movw 0,%si - movw 0,%es - jmp L1 -A(CallTo16:) -A(CallTo16cx:) - pushl %ebp - movl %esp,%ebp - - /* - * Get target address and new ds - */ -L1: -#ifdef __ELF__ - /* change code segments */ - movw $0x0f, %ax - movw %ax, A(IF1632_ELF_KLUDGE)+4 - movl $L2, %eax - andl $0x0000ffff, %eax - movl %eax,A(IF1632_ELF_KLUDGE) - ljmp A(IF1632_ELF_KLUDGE) -L2: -#endif - /* At this point we have changed segments. */ - movl 8(%ebp),%eax - movl %eax,jump_target - lea jump_target,%edx - movw 12(%ebp),%ax - movw 14(%ebp),%cx - - /* - * Switch to 16-bit stack - */ - pushl A(IF1632_Saved32_esp) - pushl A(IF1632_Saved32_ebp) - pushw A(IF1632_Saved32_ss) - - movw %ss,A(IF1632_Saved32_ss) - movl %esp,A(IF1632_Saved32_esp) - movl %ebp,A(IF1632_Saved32_ebp) - - movw A(IF1632_Saved16_ss),%ss - movw A(IF1632_Saved16_sp),%sp - movw A(IF1632_Saved16_bp),%bp - - /* - * Call entry point - */ - movw %ax,%ds - movw %ax,%di - .byte 0x66 - lcall %fs:(%edx) - - /* - * Restore old stack and segment registers. - * - * Two choices here: - * 1. Trust that fs or gs hasn't changed. - * 2. Rely on knowledge of Linux use of segments. - * - * I'll opt for choice 2 because who knows what programs we - * going to run. Linux should be fairly stable in terms of - * GDT usage. - */ - pushl %eax - movw $UDATASEL,%ax - movw %ax,%ds - movw %ax,%es - movw %ax,%fs - movw %ax,%gs - popl %eax - - movw %ss,A(IF1632_Saved16_ss) - movw %esp,A(IF1632_Saved16_sp) - movw %ebp,A(IF1632_Saved16_bp) - - movw A(IF1632_Saved32_ss),%ss - movl A(IF1632_Saved32_esp),%esp - movl A(IF1632_Saved32_ebp),%ebp - - popw A(IF1632_Saved32_ss) - popl A(IF1632_Saved32_ebp) - popl A(IF1632_Saved32_esp) - - movl %eax,return_value - movw return_value+2,%dx - /* switch segments */ -#ifdef __ELF__ - movw $0x23, %ax - movw %ax, A(IF1632_ELF_KLUDGE)+4 - movl $L3, %eax - movl %eax,A(IF1632_ELF_KLUDGE) - ljmp A(IF1632_ELF_KLUDGE) -L3: - /* back in the regular segment set up. */ - /* restore eax */ - movl return_value, %eax -#endif - .align 2,0x90 - leave - ret - -/********************************************************************** - * CallTo32() - * - * This function is called as a relay point to the built function - * handler. KERNEL, USER and GDI calls are dealt with by this - * handler. Calls to these DLLs will be mapped to a call handler - * which will set EAX to a number indicating which DLL and which - * function within that DLL. - * - * This function will pass to the function handler two arguments. - * The first argument will be the contents of EAX, the second - * argument will be a segment:offset pair that points to the - * 16-bit stack. - */ - .align 4 - .globl A(CallTo32) -A(CallTo32:) - andl $0x0000ffff,%esp - pushw %bp - movl %esp,%ebp - - /* - * Save registers. 286 mode does not have fs or gs. - */ - pushw %ds - - /* - * Restore segment registers. - */ - pushl %eax - movw $UDATASEL,%ax - movw %ax,%ds - movw %ax,%es - popl %eax - - /* - * Save old stack save variables, save stack registers, reload - * stack registers. - */ - pushw A(IF1632_Saved16_sp) - pushw A(IF1632_Saved16_bp) - pushw A(IF1632_Saved16_ss) - - movw %ss,A(IF1632_Saved16_ss) - movw %sp,A(IF1632_Saved16_sp) - movw %bp,A(IF1632_Saved16_bp) - - movw A(IF1632_Saved32_ss),%ss - movl A(IF1632_Saved32_esp),%esp - movl A(IF1632_Saved32_ebp),%ebp - - /* - * Call entry point - */ - pushl %edx - pushw A(IF1632_Saved16_ss) - pushw A(IF1632_Saved16_sp) - pushl %eax - call A(DLLRelay) - - popl %edx - popl %edx - popl %edx - - /* - * Restore registers, but do not destroy return value. - */ - movw A(IF1632_Saved16_ss),%ss - movw A(IF1632_Saved16_sp),%sp - movw A(IF1632_Saved16_bp),%bp - - popw A(IF1632_Saved16_ss) - popw A(IF1632_Saved16_bp) - popw A(IF1632_Saved16_sp) - - popw %ds - popw %bp - - /* - * Now we need to ditch the parameter bytes that were left on the - * stack. We do this by effectively popping the number of bytes, - * and the return address, removing the parameters and then putting - * the return address back on the stack. - * Normally this field is filled in by the relevant function in - * the emulation library, since it should know how many bytes to - * expect. - */ - popw %gs:nbytes - cmpw $0,%gs:nbytes - je noargs - popw %gs:offset - popw %gs:selector - addw %gs:nbytes,%esp - pushw %gs:selector - pushw %gs:offset -noargs: - - /* - * Last, but not least we need to move the high word from eax to dx - */ - - pushl %eax - popw %dx - popw %dx - - .byte 0x66 - lret - -/********************************************************************** - * CallTo32_16() - * - * This function is same one as CallTo32() except that the high - * word of EAX won't be moved to DX. - */ - .align 4 - .globl A(CallTo32_16) -A(CallTo32_16:) - andl $0x0000ffff,%esp - pushw %bp - movl %esp,%ebp - - /* - * Save registers. 286 mode does not have fs or gs. - */ - pushw %ds - - /* - * Restore segment registers. - */ - pushl %eax - movw $UDATASEL,%ax - movw %ax,%ds - movw %ax,%es - popl %eax - - /* - * Save old stack save variables, save stack registers, reload - * stack registers. - */ - pushw A(IF1632_Saved16_sp) - pushw A(IF1632_Saved16_bp) - pushw A(IF1632_Saved16_ss) - - movw %ss,A(IF1632_Saved16_ss) - movw %esp,A(IF1632_Saved16_sp) - movw %ebp,A(IF1632_Saved16_bp) - - movw A(IF1632_Saved32_ss),%ss - movl A(IF1632_Saved32_esp),%esp - movl A(IF1632_Saved32_ebp),%ebp - - /* - * Call entry point - */ - pushl %edx - pushw A(IF1632_Saved16_ss) - pushw A(IF1632_Saved16_sp) - pushl %eax - call A(DLLRelay) - - popl %edx - popl %edx - popl %edx - - /* - * Restore registers, but do not destroy return value. - */ - movw A(IF1632_Saved16_ss),%ss - movw A(IF1632_Saved16_sp),%sp - movw A(IF1632_Saved16_bp),%bp - - popw A(IF1632_Saved16_ss) - popw A(IF1632_Saved16_bp) - popw A(IF1632_Saved16_sp) - - popw %ds - popw %bp - - /* - * Now we need to ditch the parameter bytes that were left on the - * stack. We do this by effectively popping the number of bytes, - * and the return address, removing the parameters and then putting - * the return address back on the stack. - * Normally this field is filled in by the relevant function in - * the emulation library, since it should know how many bytes to - * expect. - */ - popw %gs:nbytes - cmpw $0,%gs:nbytes - je noargs2 - popw %gs:offset - popw %gs:selector - addw %gs:nbytes,%esp - pushw %gs:selector - pushw %gs:offset -noargs2: - .byte 0x66 - lret - -/********************************************************************** - * ReturnFromRegisterFunc() - */ - .globl A(ReturnFromRegisterFunc) -A(ReturnFromRegisterFunc:) - /* - * Restore 16-bit stack - */ - movw A(IF1632_Saved16_ss),%ss - movw A(IF1632_Saved16_sp),%sp - movw A(IF1632_Saved16_bp),%bp - - popw A(IF1632_Saved16_ss) - popw A(IF1632_Saved16_bp) - popw A(IF1632_Saved16_sp) - - popw %ds - popw %bp - - /* - * This leaves us with a stack that has number of arguments, - * the return address, the saved registers, and the return - * address again. - */ - add $6,%esp /* argument count, return address */ -#include "pop.h" /* restore context */ - - /* - * Return to original caller. - */ - .byte 0x66 - lret - diff --git a/if1632/callback.c b/if1632/callback.c index db210f2e611..a941b16045d 100644 --- a/if1632/callback.c +++ b/if1632/callback.c @@ -7,18 +7,17 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include <stdio.h> #include <stdlib.h> #include <strings.h> +#include <setjmp.h> #include "windows.h" #include "callback.h" #include "wine.h" -#include <setjmp.h> -#include "ldt.h" +#include "global.h" #include "stackframe.h" #include "dlls.h" #include "stddebug.h" #include "debug.h" #include "if1632.h" -extern unsigned short IF1632_Saved32_ss; extern unsigned long IF1632_Saved32_ebp; extern unsigned long IF1632_Saved32_esp; @@ -30,64 +29,6 @@ struct thunk_s unsigned char thunk[8]; }; -#ifdef __ELF__ -#define FIRST_SELECTOR 2 -#define IS_16_BIT_ADDRESS(addr) \ - (((unsigned int)(addr) < 0x8000000) || ((unsigned int)(addr) >= 0x8400000)) -#else -#define FIRST_SELECTOR 8 -#define IS_16_BIT_ADDRESS(addr) \ - ((unsigned int)(addr) >= (((FIRST_SELECTOR << __AHSHIFT) | 7) << 16)) -#endif - -/********************************************************************** - * PushOn16 - */ -static void -PushOn16(int size, unsigned int value) -{ - char *p = PTR_SEG_OFF_TO_LIN( IF1632_Saved16_ss, IF1632_Saved16_sp ); - if (size) - { - unsigned long *lp = (unsigned long *) p - 1; - - *lp = value; - IF1632_Saved16_sp -= 4; - } - else - { - unsigned short *sp = (unsigned short *) p - 1; - - *sp = value; - IF1632_Saved16_sp -= 2; - } -} - - -/********************************************************************** - * CallBack16 - */ -int -CallBack16(void *func, int n_args, ...) -{ - va_list ap; - int i; - int arg_type, arg_value; - WORD ds = CURRENT_DS; - - va_start(ap, n_args); - - for (i = 0; i < n_args; i++) - { - arg_type = va_arg(ap, int); - arg_value = va_arg(ap, int); - PushOn16(arg_type, arg_value); - } - - va_end(ap); - - return CallTo16((unsigned int) func, ds ); -} /********************************************************************** * MakeProcInstance @@ -100,18 +41,8 @@ FARPROC MakeProcInstance( FARPROC func, WORD instance ) if (!ThunkSelector) { - ldt_entry entry; - - /* Allocate a segment for thunks */ - ThunkSelector = AllocSelector( 0 ); - entry.base = (unsigned long) malloc( 0x10000 ); - entry.limit = 0xffff; - entry.seg_32bit = 0; - entry.limit_in_pages = 0; - entry.type = SEGMENT_CODE; - entry.read_only = 0; - memset( (char *)entry.base, 0, 0x10000 ); - LDT_SetEntry( SELECTOR_TO_ENTRY(ThunkSelector), &entry ); + HGLOBAL handle = GLOBAL_Alloc( GMEM_ZEROINIT, 0x10000, 0, TRUE, FALSE); + ThunkSelector = GlobalHandleToSel(handle); } thunks = (char *)PTR_SEG_OFF_TO_LIN( ThunkSelector, 0 ); @@ -173,110 +104,9 @@ LONG CallWindowProc( WNDPROC func, HWND hwnd, WORD message, WORD wParam, LONG lParam ) { SpyMessage(hwnd, message, wParam, lParam); - - if (HIWORD((LONG)func) == WINE_CODE_SELECTOR) - { - static struct dll_table_entry_s *user_tab = NULL; - void *address = (void *) ((LONG) func & 0xffff); - - if (user_tab == NULL) - user_tab = FindDLLTable("USER"); - - /* DefWindowProc */ - if (((LONG)user_tab[107].address &0xffff) == (LONG) address) - return DefWindowProc(hwnd, message, wParam, lParam); - - /* DefDlgProc */ - else if (((LONG)user_tab[308].address &0xffff) == (LONG)address) - return DefDlgProc(hwnd, message, wParam, lParam); - - /* DefMDIChildProc */ - else if (((LONG)user_tab[447].address &0xffff) == (LONG)address) - return DefMDIChildProc(hwnd, message, wParam, lParam); - - /* default */ - else - { - fprintf(stderr, "wine: Unknown wine callback %08x\n", - (unsigned int) func); - exit(1); - } - } - else if (IS_16_BIT_ADDRESS(func)) - { - WORD ds = CURRENT_DS; - dprintf_callback(stddeb, "CallWindowProc // 16bit func=%08x ds=%04x!\n", - (unsigned int) func, ds ); - PushOn16( CALLBACK_SIZE_WORD, hwnd ); - PushOn16( CALLBACK_SIZE_WORD, message ); - PushOn16( CALLBACK_SIZE_WORD, wParam ); - PushOn16( CALLBACK_SIZE_LONG, lParam ); - return CallTo16((unsigned int) func, ds ); - } - else - { - dprintf_callback(stddeb, "CallWindowProc // 32bit func=%08X !\n", - (unsigned int) func); - return (*func)(hwnd, message, wParam, lParam); - } + return CallWndProc( (FARPROC)func, hwnd, message, wParam, lParam ); } -/********************************************************************** - * CallLineDDAProc - */ -void CallLineDDAProc(FARPROC func, short xPos, short yPos, long lParam) -{ - WORD ds = CURRENT_DS; - if (IS_16_BIT_ADDRESS(func)) - { - PushOn16( CALLBACK_SIZE_WORD, xPos ); - PushOn16( CALLBACK_SIZE_WORD, yPos ); - PushOn16( CALLBACK_SIZE_LONG, lParam ); - CallTo16((unsigned int) func, ds ); - } - else - { - (*func)(xPos, yPos, lParam); - } -} - -/********************************************************************** - * CallHookProc - */ -DWORD CallHookProc( HOOKPROC func, short code, WPARAM wParam, LPARAM lParam ) -{ - WORD ds = CURRENT_DS; - if (IS_16_BIT_ADDRESS(func)) - { - PushOn16( CALLBACK_SIZE_WORD, code ); - PushOn16( CALLBACK_SIZE_WORD, wParam ); - PushOn16( CALLBACK_SIZE_LONG, lParam ); - return CallTo16((unsigned int) func, ds ); - } - else - { - return (*func)( code, wParam, lParam ); - } -} - -/********************************************************************** - * CallGrayStringProc - */ -BOOL CallGrayStringProc(FARPROC func, HDC hdc, LPARAM lParam, INT cch ) -{ - WORD ds = CURRENT_DS; - if (IS_16_BIT_ADDRESS(func)) - { - PushOn16( CALLBACK_SIZE_WORD, hdc ); - PushOn16( CALLBACK_SIZE_LONG, lParam ); - PushOn16( CALLBACK_SIZE_WORD, cch ); - return CallTo16((unsigned int) func, ds ); - } - else - { - return (*func)( hdc, lParam, cch ); - } -} /* ------------------------------------------------------------------------ */ /* @@ -295,7 +125,7 @@ BOOL CallGrayStringProc(FARPROC func, HDC hdc, LPARAM lParam, INT cch ) struct special_buffer { jmp_buf buffer; - long regs [6]; + long regs [5]; char stack_part [STACK_DEPTH_16]; } *sb; @@ -303,8 +133,6 @@ int Catch (LPCATCHBUF cbuf) { WORD retval; jmp_buf *tmp_jmp; - char *stack16 = (char *) (((unsigned int)IF1632_Saved16_ss << 16) + - IF1632_Saved16_sp); sb = malloc (sizeof (struct special_buffer)); @@ -313,8 +141,7 @@ int Catch (LPCATCHBUF cbuf) sb -> regs [2] = IF1632_Saved16_ss & 0xffff; sb -> regs [3] = IF1632_Saved32_esp; sb -> regs [4] = IF1632_Saved32_ebp; - sb -> regs [5] = IF1632_Saved32_ss & 0xffff; - memcpy (sb -> stack_part, stack16, STACK_DEPTH_16); + memcpy (sb -> stack_part, CURRENT_STACK16, STACK_DEPTH_16); tmp_jmp = &sb -> buffer; *((struct special_buffer **)cbuf) = sb; @@ -325,11 +152,8 @@ int Catch (LPCATCHBUF cbuf) IF1632_Saved16_ss = sb -> regs [2] & 0xffff; IF1632_Saved32_esp = sb -> regs [3]; IF1632_Saved32_ebp = sb -> regs [4]; - IF1632_Saved32_ss = sb -> regs [5] & 0xffff; - stack16 = (char *) (((unsigned int)IF1632_Saved16_ss << 16) + - IF1632_Saved16_sp); - memcpy (stack16, sb -> stack_part, STACK_DEPTH_16); + memcpy (CURRENT_STACK16, sb -> stack_part, STACK_DEPTH_16); dprintf_catch (stddeb, "Been thrown here: %d, retval = %d\n", (int) sb, (int) retval); free ((void *) sb); diff --git a/if1632/compobj.spec b/if1632/compobj.spec index a4b0993a28b..06618a80a69 100644 --- a/if1632/compobj.spec +++ b/if1632/compobj.spec @@ -16,7 +16,7 @@ length 163 #12 COFREEALLLIBRARIES #13 COCREATEINSTANCE #14 STRINGFROMIID -#15 CODISCONNECTOBJECT +15 pascal CoDisconnectObject(ptr long) CoDisconnectObject #16 CORELEASEMARSHALDATA #17 COFREEUNUSEDLIBRARIES #18 ISEQUALGUID diff --git a/if1632/gdi.spec b/if1632/gdi.spec index ea1197043ae..4389097cc8d 100644 --- a/if1632/gdi.spec +++ b/if1632/gdi.spec @@ -212,7 +212,7 @@ length 490 #310 pascal CREATESCALABLEFONTRESOURCE #311 pascal GETFONTDATA #312 pascal CONVERTOUTLINEFONTFILE -#313 pascal GETRASTERIZERCAPS +313 pascal16 GetRasterizerCaps(ptr word) GetRasterizerCaps #314 pascal ENGINEEXTTEXTOUT 330 pascal16 EnumFontFamilies(word ptr segptr long) EnumFontFamilies #332 pascal GETKERNINGPAIRS diff --git a/if1632/kernel.spec b/if1632/kernel.spec index a9eec0580cb..bdaa2ef169b 100644 --- a/if1632/kernel.spec +++ b/if1632/kernel.spec @@ -207,10 +207,10 @@ length 415 #318 FATALEXITHOOK #319 FLUSHCACHEDFILEHANDLE #320 ISTASK -323 pascal IsRomModule() IsRomModule +323 return IsRomModule 2 0 #324 LOGERROR #325 LOGPARAMERROR -#326 ISROMFILE +326 return IsRomFile 2 0 #327 K327 #328 _DEBUGOUTPUT #329 K329 @@ -237,5 +237,5 @@ length 415 #354 GETAPPCOMPATFLAGS #355 GETWINDEBUGINFO #356 SETWINDEBUGINFO -#403 K403 -#404 K404 +403 pascal16 FarSetOwner(word word) FarSetOwner +404 pascal16 FarGetOwner(word) FarGetOwner diff --git a/if1632/olecli.spec b/if1632/olecli.spec index ea211077980..97c3ded4f8d 100644 --- a/if1632/olecli.spec +++ b/if1632/olecli.spec @@ -1,8 +1,6 @@ name olecli id 20 -length 43 -## 954 is too large for now -##length 954 +length 954 #1 WEP #2 OLEDELETE diff --git a/if1632/relay.c b/if1632/relay.c index e717b5af7d3..c855e8192bd 100644 --- a/if1632/relay.c +++ b/if1632/relay.c @@ -23,16 +23,16 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include "prototypes.h" #include "dlls.h" #include "options.h" +#include "selectors.h" #include "stackframe.h" +#include "wine.h" #include "stddebug.h" /* #define DEBUG_RELAY */ -/* #define DEBUG_STACK */ #include "debug.h" #if 0 /* Make make_debug think these were really used */ dprintf_relay -dprintf_stack #endif #ifdef WINELIB @@ -43,256 +43,210 @@ dprintf_stack struct dll_name_table_entry_s dll_builtin_table[N_BUILTINS] = { - { "KERNEL", WineLibSkip(KERNEL_table), 410, 1, 1 }, - { "USER", WineLibSkip(USER_table), 540, 2, 1 }, - { "GDI", WineLibSkip(GDI_table), 490, 3, 1 }, - { "WIN87EM", WineLibSkip(WIN87EM_table), 10, 4, 1 }, - { "SHELL", WineLibSkip(SHELL_table), 103, 5, 1 }, - { "SOUND", WineLibSkip(SOUND_table), 20, 6, 1 }, - { "KEYBOARD",WineLibSkip(KEYBOARD_table),137, 7, 1 }, - { "WINSOCK", WineLibSkip(WINSOCK_table), 155, 8, 1 }, - { "STRESS", WineLibSkip(STRESS_table), 15, 9, 1}, - { "MMSYSTEM",WineLibSkip(MMSYSTEM_table),1226,10, 1}, - { "SYSTEM", WineLibSkip(SYSTEM_table), 20 ,11, 1}, - { "TOOLHELP",WineLibSkip(TOOLHELP_table), 83, 12, 1}, - { "MOUSE", WineLibSkip(MOUSE_table), 8, 13, 1}, - { "COMMDLG", WineLibSkip(COMMDLG_table), 31, 14, 1}, - { "OLE2", WineLibSkip(OLE2_table), 31, 15, 1}, - { "OLE2CONV",WineLibSkip(OLE2CONV_table), 31, 16, 1}, - { "OLE2DISP",WineLibSkip(OLE2DISP_table), 31, 17, 1}, - { "OLE2NLS", WineLibSkip(OLE2NLS_table), 31, 18, 1}, - { "OLE2PROX",WineLibSkip(OLE2PROX_table), 31, 19, 1}, - { "OLECLI", WineLibSkip(OLECLI_table), 31, 20, 1}, - { "OLESVR", WineLibSkip(OLESVR_table), 31, 21, 1}, - { "COMPOBJ", WineLibSkip(COMPOBJ_table), 31, 22, 1}, - { "STORAGE", WineLibSkip(STORAGE_table), 31, 23, 1} + { "KERNEL", WineLibSkip(&KERNEL_table), 1 }, + { "USER", WineLibSkip(&USER_table), 1 }, + { "GDI", WineLibSkip(&GDI_table), 1 }, + { "WIN87EM", WineLibSkip(&WIN87EM_table), 1 }, + { "SHELL", WineLibSkip(&SHELL_table), 1 }, + { "SOUND", WineLibSkip(&SOUND_table), 1 }, + { "KEYBOARD", WineLibSkip(&KEYBOARD_table), 1 }, + { "WINSOCK", WineLibSkip(&WINSOCK_table), 1 }, + { "STRESS", WineLibSkip(&STRESS_table), 1 }, + { "MMSYSTEM", WineLibSkip(&MMSYSTEM_table), 1 }, + { "SYSTEM", WineLibSkip(&SYSTEM_table), 1 }, + { "TOOLHELP", WineLibSkip(&TOOLHELP_table), 1 }, + { "MOUSE", WineLibSkip(&MOUSE_table), 1 }, + { "COMMDLG", WineLibSkip(&COMMDLG_table), 1 }, + { "OLE2", WineLibSkip(&OLE2_table), 1 }, + { "OLE2CONV", WineLibSkip(&OLE2CONV_table), 1 }, + { "OLE2DISP", WineLibSkip(&OLE2DISP_table), 1 }, + { "OLE2NLS", WineLibSkip(&OLE2NLS_table), 1 }, + { "OLE2PROX", WineLibSkip(&OLE2PROX_table), 1 }, + { "OLECLI", WineLibSkip(&OLECLI_table), 1 }, + { "OLESVR", WineLibSkip(&OLESVR_table), 1 }, + { "COMPOBJ", WineLibSkip(&COMPOBJ_table), 1 }, + { "STORAGE", WineLibSkip(&STORAGE_table), 1 }, + { "WINPROCS", WineLibSkip(&WINPROCS_table), 1 }, }; -/* don't forget to increase N_BUILTINS in dll.h if you add a dll */ - -/* the argument conversion tables for each dll */ -struct dll_conversions { - unsigned short *dst_args; /* Offsets to arguments on stack */ - unsigned char *src_types; /* Argument types */ -} dll_conversion_table[N_BUILTINS]= { - { KERNEL_offsets, KERNEL_types }, /* KERNEL */ - { USER_offsets, USER_types }, /* USER */ - { GDI_offsets, GDI_types }, /* GDI */ - { WIN87EM_offsets, WIN87EM_types }, /* WIN87EM */ - { SHELL_offsets, SHELL_types }, /* SHELL */ - { SOUND_offsets, SOUND_types }, /* SOUND */ - { KEYBOARD_offsets, KEYBOARD_types }, /* KEYBOARD */ - { WINSOCK_offsets, WINSOCK_types }, /* WINSOCK */ - { STRESS_offsets, STRESS_types }, /* STRESS, */ - { MMSYSTEM_offsets, MMSYSTEM_types }, /* MMSYSTEM */ - { SYSTEM_offsets, SYSTEM_types }, /* SYSTEM */ - { TOOLHELP_offsets, TOOLHELP_types }, /* TOOLHELP */ - { MOUSE_offsets, MOUSE_types }, /* MOUSE */ - { COMMDLG_offsets, COMMDLG_types }, /* EMUCOMMDLG */ - { OLE2_offsets, OLE2_types }, /* OLE2 */ - { OLE2CONV_offsets, OLE2CONV_types }, /* OLE2CONV */ - { OLE2DISP_offsets, OLE2DISP_types }, /* OLE2DISP */ - { OLE2NLS_offsets, OLE2NLS_types }, /* OLE2NLS */ - { OLE2DISP_offsets, OLE2DISP_types }, /* OLE2PROX */ - { OLECLI_offsets, OLECLI_types }, /* OLE2CLI */ - { OLESVR_offsets, OLESVR_types }, /* OLE2CLI */ - { COMPOBJ_offsets, COMPOBJ_types }, /* COMPOBJ */ - { STORAGE_offsets, STORAGE_types } /* STORAGE */ -}; - +/* don't forget to increase N_BUILTINS in dlls.h if you add a dll */ -#ifndef WINELIB + /* Saved 16-bit stack */ +WORD IF1632_Saved16_ss = 0; +WORD IF1632_Saved16_sp = 0; +WORD IF1632_Saved16_bp = 0; -extern unsigned short IF1632_Saved16_sp; -extern unsigned short IF1632_Saved16_bp; -extern unsigned short IF1632_Saved16_ss; + /* Saved 32-bit stack */ +DWORD IF1632_Saved32_esp = 0; +DWORD IF1632_Saved32_ebp = 0; -void RelayDebug( unsigned int func_num ) +/*********************************************************************** + * RELAY_Init + */ +BOOL RELAY_Init(void) { - unsigned int dll_id, ordinal; + WORD codesel, datasel; + struct dll_table_s *table; + struct dll_table_entry_s *entry; + int i, j; + + /* Allocate the code selector for CallTo16 routines */ + + extern void CALL16_Start(), CALL16_End(); + extern void CALL16_Ret_word(), CALL16_Ret_long(); + extern DWORD CALL16_RetAddr_word, CALL16_RetAddr_long; + + codesel = SELECTOR_AllocBlock( (void *)CALL16_Start, + (int)CALL16_End - (int)CALL16_Start, + SEGMENT_CODE, TRUE, FALSE ); + if (!codesel) return FALSE; + + /* Patch the return addresses for CallTo16 routines */ - if (debugging_relay) + CALL16_RetAddr_word = MAKELONG( (int)CALL16_Ret_word - (int)CALL16_Start, + codesel ); + CALL16_RetAddr_long = MAKELONG( (int)CALL16_Ret_long - (int)CALL16_Start, + codesel ); + + /* Allocate the selectors for built-in dlls */ + + for (i = 0; i < N_BUILTINS; i++) { - dll_id = ((func_num >> 16) & 0xffff) - 1; - ordinal = func_num & 0xffff; - printf( "Calling %s.%d\n", - dll_builtin_table[dll_id].dll_table[ordinal].export_name, - ordinal ); + table = dll_builtin_table[i].table; + codesel = SELECTOR_AllocBlock( table->code_start, + (int)table->code_end-(int)table->code_start, + SEGMENT_CODE, TRUE, FALSE ); + if (!codesel) return FALSE; + if (table->data_start != table->data_end) + datasel = SELECTOR_AllocBlock( table->data_start, + (int)table->data_end-(int)table->data_start, + SEGMENT_DATA, TRUE, FALSE ); + else datasel = 0; + entry = table->dll_table; + for (j = 0; j < table->dll_table_length; j++, entry++) + { + if (entry->selector == 1) /* code selector */ + entry->selector = codesel; + else if (entry->selector == 2) /* data selector */ + entry->selector = datasel; + else entry->selector = 0; /* constant selector */ + } } + + return TRUE; } -/********************************************************************** - * DLLRelay - * - * We get a stack frame pointer to data that looks like this: - * - * Hex Offset Contents - * ---------- ------- - * +00 previous saved_16ss - * +02 previous saved_16ebp - * +06 previous saved_16esp - * +0A 16-bit es - * +0C 16-bit ds - * +0E 16-bit ebp - * +12 length of 16-bit arguments - * +14 16-bit ip - * +16 16-bit cs - * +18 arguments - */ -int -DLLRelay(unsigned int func_num, unsigned int seg_off) +#ifndef WINELIB + +void RELAY_DebugCall32( char *args ) { - struct dll_table_entry_s *dll_p; - STACK16FRAME *pStack16Frame; - unsigned int offset; - unsigned int dll_id; - unsigned int ordinal; - int arg_table[DLL_MAX_ARGS]; - void *arg_ptr; - int (*func_ptr)(); + STACK16FRAME *frame; + char *args16; int i; - int ret_val; - int conv_ref; - unsigned char *type_conv; - unsigned short *offset_conv; - STACK16FRAME stackFrameCopy; - - /* - * Determine address of arguments. - */ - pStack16Frame = (STACK16FRAME *) PTR_SEG_TO_LIN(seg_off); - arg_ptr = (void *)pStack16Frame->args; - - /* - * Extract the DLL number and ordinal number. - */ - dll_id = ((func_num >> 16) & 0xffff) - 1; - ordinal = func_num & 0xffff; - dll_p = &dll_builtin_table[dll_id].dll_table[ordinal]; - - dprintf_relay( stddeb, "Call %s (%s.%d), stack=%04x:%04x ret=%04x:%04x ds=%04x bp=%04x args=%d\n", - dll_p->export_name, - dll_builtin_table[dll_id].dll_name, ordinal, - seg_off >> 16, seg_off & 0xffff, - pStack16Frame->cs, pStack16Frame->ip, - pStack16Frame->ds, pStack16Frame->bp, - pStack16Frame->arg_length ); - - if(debugging_stack) + + if (!debugging_relay) return; + + frame = CURRENT_STACK16; + printf( "Call %s.%d: %s(", + dll_builtin_table[frame->dll_id-1].dll_name, + frame->ordinal_number, + dll_builtin_table[frame->dll_id-1].table->dll_table[frame->ordinal_number].export_name ); + args16 = (char *)frame->args; + for (i = 0; i < strlen(args); i++) { - unsigned short *stack_p = (unsigned short *) pStack16Frame; - /* FIXME: Is there an end-of-stack-pointer somewhere ? */ - int n = min(24, (0x10000 - (seg_off & 0xffff)) / sizeof(*stack_p)); - for (i = 0; i < n; i++, stack_p++) + switch(args[i]) { - printf("%04x ", *stack_p); - if ((i & 7) == 7) - printf("\n"); + case 'w': + case 's': + args16 += 2; + break; + case 'l': + case 'p': + args16 += 4; + break; } - printf("\n"); } - /* - * Make sure we have a handler defined for this call. - */ - if (dll_p->handler == NULL) + while (*args) { - char buffer[100]; - - sprintf(buffer, "No handler for routine %s.%d", - dll_builtin_table[dll_id].dll_name, ordinal); - myerror(buffer); - } - func_ptr = dll_p->handler; - - /* - * OK, special case. If the handler is define as taking no arguments - * then pass the address of the arguments on the 16-bit stack to the - * handler. It will just ignore the pointer if it really takes no - * arguments. This allows us to write slightly faster library routines - * if we choose. - */ - if (dll_p->n_args == 0) - { - ret_val = (*func_ptr)(arg_ptr); - dprintf_relay( stddeb, "Returning %08x from %s (%s.%d) ds=%04x\n", - ret_val, dll_p->export_name, - dll_builtin_table[dll_id].dll_name, ordinal, - pStack16Frame->ds ); - return ret_val; + switch(*args) + { + case 'w': + case 's': + args16 -= 2; + printf( "0x%04x", *(WORD *)args16 ); + break; + case 'l': + args16 -= 4; + printf( "0x%08x", *(int *)args16 ); + break; + case 'p': + args16 -= 4; + printf( "%04x:%04x", *(WORD *)(args16+2), *(WORD *)args16 ); + break; + } + args++; + if (*args) printf( "," ); } + printf( ") ret=%04x:%04x ds=%04x\n", frame->cs, frame->ip, frame->ds ); +} - /* - * Getting this far means we need to convert the 16-bit argument stack. - */ - conv_ref= dll_p->conv_reference; - type_conv= dll_conversion_table[dll_id].src_types + conv_ref; - offset_conv= dll_conversion_table[dll_id].dst_args + conv_ref; - for (i = 0; i < dll_p->n_args; i++,type_conv++,offset_conv++) - { - short *sp; - int *ip; - - offset = *offset_conv; - - switch (*type_conv) - { - case DLL_ARGTYPE_SIGNEDWORD: - sp = (short *) ((char *) arg_ptr + offset); - arg_table[i] = *sp; - break; - - case DLL_ARGTYPE_WORD: - sp = (short *) ((char *) arg_ptr + offset); - arg_table[i] = (int) *sp & 0xffff; - break; - - case DLL_ARGTYPE_LONG: - ip = (int *) ((char *) arg_ptr + offset); - arg_table[i] = *ip; - break; - case DLL_ARGTYPE_FARPTR: - ip = (int *) ((char *) arg_ptr + offset); - arg_table[i] = (unsigned int) PTR_SEG_TO_LIN( *ip ); - break; - } - } +void RELAY_DebugReturn( int short_ret, int ret_val ) +{ + STACK16FRAME *frame; - if (debugging_relay) - memcpy( &stackFrameCopy, pStack16Frame, sizeof(stackFrameCopy) ); + if (!debugging_relay) return; - /* - * Call the handler - */ - ret_val = (*func_ptr)(arg_table[0], arg_table[1], arg_table[2], - arg_table[3], arg_table[4], arg_table[5], - arg_table[6], arg_table[7], arg_table[8], - arg_table[9], arg_table[10], arg_table[11], - arg_table[12], arg_table[13], arg_table[14], - arg_table[15]); + frame = CURRENT_STACK16; + printf( "Ret %s.%d: %s() ", + dll_builtin_table[frame->dll_id-1].dll_name, + frame->ordinal_number, + dll_builtin_table[frame->dll_id-1].table->dll_table[frame->ordinal_number].export_name ); + if (short_ret) printf( "retval=0x%04x\n", ret_val & 0xffff ); + else printf( "retval=0x%08x\n", ret_val ); +} - if (debugging_relay) - { - if (memcmp( &stackFrameCopy, pStack16Frame, sizeof(stackFrameCopy) )) - { - printf( "**** 16-bit stack corrupted!\n" ); - } - printf("Returning %08x from %s (%s.%d) ds=%04x\n", - ret_val, - dll_p->export_name, - dll_builtin_table[dll_id].dll_name, ordinal, - pStack16Frame->ds ); - } - return ret_val; +void RELAY_Unimplemented(void) +{ + STACK16FRAME *frame = CURRENT_STACK16; + + fprintf( stderr, "No handler for routine %s.%d\n", + dll_builtin_table[frame->dll_id-1].dll_name, + frame->ordinal_number ); + exit(1); } -#endif + + +/*********************************************************************** + * RELAY_DebugCall16 + * + * 'stack' points to the called function address on the 32-bit stack. + * Stack layout: + * ... ... + * (stack+12) arg2 + * (stack+8) arg1 + * (stack+4) 16-bit ds + * (stack) func to call + */ +void RELAY_DebugCall16( int* stack, int nbargs ) +{ + if (!debugging_relay) return; + + printf( "CallTo16(func=%04x:%04x,ds=%04x", + HIWORD(stack[0]), LOWORD(stack[0]), LOWORD(stack[1]) ); + stack += 2; + while (nbargs--) printf( ",0x%x", *stack++ ); + printf( ")\n" ); +} + +#endif /* WINELIB */ /********************************************************************** * FindDLLTable */ -struct dll_table_entry_s * +struct dll_table_s * FindDLLTable(char *dll_name) { int i; @@ -300,11 +254,7 @@ FindDLLTable(char *dll_name) for (i = 0; i < N_BUILTINS; i++) if (strcasecmp(dll_builtin_table[i].dll_name, dll_name) == 0 && dll_builtin_table[i].dll_is_used) -#ifdef WINELIB - return dll_builtin_table[i].dll_number; -#else - return dll_builtin_table[i].dll_table; -#endif + return dll_builtin_table[i].table; return NULL; } @@ -317,27 +267,19 @@ FindOrdinalFromName(struct dll_table_entry_s *dll_table, char *func_name) int i, limit; for (i = 0; i < N_BUILTINS; i++) - if (dll_table == dll_builtin_table[i].dll_table) + if (dll_table == dll_builtin_table[i].table->dll_table) break; if (i == N_BUILTINS) return 0; - limit = dll_builtin_table[i].dll_table_length; + limit = dll_builtin_table[i].table->dll_table_length; for (i = 0; i < limit; i++) if (strcasecmp(dll_table[i].export_name, func_name) == 0) return i; return 0; } -/********************************************************************** - * ReturnArg - */ -int -ReturnArg(int arg) -{ - return arg; -} #ifndef WINELIB #ifdef WINESTAT @@ -351,13 +293,13 @@ void winestat(){ tused = 0; timplemented = 0; for (i = 0; i < N_BUILTINS; i++) { - table = dll_builtin_table[i].dll_table; + table = dll_builtin_table[i].table->dll_table; used = 0; implemented = 0; - for(j=0; j < dll_builtin_table[i].dll_table_length; j++) { + for(j=0; j < dll_builtin_table[i].table->dll_table_length; j++) { if(table[j].used){ used++; - if (table[j].handler) implemented++; + if (table[j].export_name[0]) implemented++; else printf("%s.%d not implemented\n", dll_builtin_table[i].dll_name, diff --git a/if1632/toolhelp.spec b/if1632/toolhelp.spec index 775ee81ad16..a7d8243ead2 100644 --- a/if1632/toolhelp.spec +++ b/if1632/toolhelp.spec @@ -3,11 +3,11 @@ id 12 length 83 50 pascal16 GlobalHandleToSel(word) GlobalHandleToSel -# 51 1 0318 GLOBALFIRST exported, shared data -# 52 1 0399 GLOBALNEXT exported, shared data -# 53 1 02a2 GLOBALINFO exported, shared data -# 54 1 0417 GLOBALENTRYHANDLE exported, shared data -# 55 1 04a9 GLOBALENTRYMODULE exported, shared data +51 pascal16 GlobalFirst(ptr word) GlobalFirst +52 pascal16 GlobalNext(ptr word) GlobalNext +53 pascal16 GlobalInfo(ptr) GlobalInfo +54 pascal16 GlobalEntryHandle(ptr word) GlobalEntryHandle +55 pascal16 GlobalEntryModule(ptr word word) GlobalEntryModule 56 pascal16 LocalInfo(ptr word) LocalInfo 57 pascal16 LocalFirst(ptr word) LocalFirst 58 pascal16 LocalNext(ptr) LocalNext @@ -24,7 +24,7 @@ length 83 69 pascal16 ClassFirst(ptr) ClassFirst 70 pascal16 ClassNext(ptr) ClassNext 71 pascal16 SystemHeapInfo(ptr) SystemHeapInfo -#72 pascal16 MemManInfo(ptr) MemManInfo +72 pascal16 MemManInfo(ptr) MemManInfo # 73 1 1b72 NOTIFYREGISTER exported, shared data # 74 1 1c29 NOTIFYUNREGISTER exported, shared data # 75 1 2060 INTERRUPTREGISTER exported, shared data diff --git a/if1632/user.spec b/if1632/user.spec index 73de7b650de..58a1a79e590 100644 --- a/if1632/user.spec +++ b/if1632/user.spec @@ -392,36 +392,36 @@ length 540 482 pascal16 EnableScrollBar(word word word) EnableScrollBar 483 pascal SystemParametersInfo(word word ptr word) SystemParametersInfo #484 __GP -#499 WNETERRORTEXT -#501 WNETOPENJOB -#502 WNETCLOSEJOB -#503 WNETABORTJOB -#504 WNETHOLDJOB -#505 WNETRELEASEJOB -#506 WNETCANCELJOB -#507 WNETSETJOBCOPIES -#508 WNETWATCHQUEUE -#509 WNETUNWATCHQUEUE -#510 WNETLOCKQUEUEDATA -#511 WNETUNLOCKQUEUEDATA +499 pascal WNetErrorText(word ptr word) WNetErrorText +501 pascal WNetOpenJob(ptr ptr word ptr) WNetOpenJob +502 pascal WNetCloseJob(word ptr ptr) WNetCloseJob +503 pascal WNetAbortJob(ptr word) WNetAbortJob +504 pascal WNetHoldJob(ptr word) WNetHoldJob +505 pascal WNetReleaseJob(ptr word) WNetReleaseJob +506 pascal WNetCancelJob(ptr word) WNetCancelJob +507 pascal WNetSetJobCopies(ptr word word) WNetSetJobCopies +508 pascal WNetWatchQueue(word ptr ptr word) WNetWatchQueue +509 pascal WNetUnwatchQueue(word ptr ptr word) WNetUnwatchQueue +510 pascal WNetLockQueueData(ptr ptr ptr) WNetLockQueueData +511 pascal WNetUnlockQueueData(ptr) WNetUnlockQueueData 512 pascal16 WNetGetConnection(ptr ptr ptr) WNetGetConnection 513 pascal WNetGetCaps(word) WNetGetCaps -#514 WNETDEVICEMODE -#515 WNETBROWSEDIALOG +514 pascal WNetDeviceMode(word) WNetDeviceMode +515 pascal WNetBrowseDialog(word word ptr) WNetBrowseDialog 516 pascal WNetGetUser(ptr ptr ptr) WNetGetUser 517 pascal16 WNetAddConnection(ptr ptr ptr) WNetAddConnection 518 pascal16 WNetCancelConnection(ptr word) WNetCancelConnection -#519 WNETGETERROR -#520 WNETGETERRORTEXT +519 pascal WNetGetError(ptr) WNetGetError +520 pascal WNetGetErrorText(word ptr ptr) WNetGetErrorText #521 WNETENABLE #522 WNETDISABLE -#523 WNETRESTORECONNECTION -#524 WNETWRITEJOB -#525 WNETCONNECTDIALOG -#526 WNETDISCONNECTDIALOG -#527 WNETCONNECTIONDIALOG -#528 WNETVIEWQUEUEDIALOG -#529 WNETPROPERTYDIALOG -#530 WNETGETDIRECTORYTYPE -#531 WNETDIRECTORYNOTIFY -#532 WNETGETPROPERTYTEXT +523 pascal WNetRestoreConnection(word ptr) WNetRestoreConnection +524 pascal WNetWriteJob(word ptr ptr) WNetWriteJob +525 pascal WnetConnectDialog(word word) WNetConnectDialog +526 pascal WNetDisconnectDialog(word word) WNetDisconnectDialog +527 pascal WNetConnectionDialog(word word) WNetConnectionDialog +528 pascal WNetViewQueueDialog(word ptr) WNetViewQueueDialog +529 pascal WNetPropertyDialog(word word ptr word) WNetPropertyDialog +530 pascal WNetGetDirectoryType(ptr ptr) WNetGetDirectoryType +531 pascal WNetDirectoryNotify(word ptr word) WNetDirectoryNotify +532 pascal WNetGetPropertyText(word word word ptr word) WNetGetPropertyText diff --git a/if1632/winprocs.spec b/if1632/winprocs.spec new file mode 100644 index 00000000000..c27681700e9 --- /dev/null +++ b/if1632/winprocs.spec @@ -0,0 +1,27 @@ +name winprocs +id 24 +length 23 + +1 pascal ButtonWndProc(word word word long) ButtonWndProc +2 pascal StaticWndProc(word word word long) StaticWndProc +3 pascal ScrollBarWndProc(word word word long) ScrollBarWndProc +4 pascal ListBoxWndProc(word word word long) ListBoxWndProc +5 pascal ComboBoxWndProc(word word word long) ComboBoxWndProc +6 pascal EditWndProc(word word word long) EditWndProc +7 pascal PopupMenuWndProc(word word word long) PopupMenuWndProc +8 pascal DesktopWndProc(word word word long) DesktopWndProc +9 pascal DefDlgProc(word word word long) DefDlgProc +10 pascal MDIClientWndProc(word word word long) MDIClientWndProc +11 pascal DefWindowProc(word word word long) DefWindowProc +12 pascal DefMDIChildProc(word word word long) DefMDIChildProc +13 pascal SystemMessageBoxProc(word word word long) SystemMessageBoxProc +14 pascal FileOpenDlgProc(word word word long) FileOpenDlgProc +15 pascal FileSaveDlgProc(word word word long) FileSaveDlgProc +16 pascal ColorDlgProc(word word word long) ColorDlgProc +17 pascal FindTextDlgProc(word word word long) FindTextDlgProc +18 pascal ReplaceTextDlgProc(word word word long) ReplaceTextDlgProc +19 pascal PrintSetupDlgProc(word word word long) PrintSetupDlgProc +20 pascal PrintDlgProc(word word word long) PrintDlgProc +21 pascal AboutDlgProc(word word word long) AboutDlgProc +22 pascal AboutWine_Proc(word word word long) AboutWine_Proc +23 pascal16 CARET_Callback(word word word long) CARET_Callback diff --git a/include/callback.h b/include/callback.h index 18206c904d7..01a87d6a4d6 100644 --- a/include/callback.h +++ b/include/callback.h @@ -1,21 +1,93 @@ -/* $Id$ - */ /* - * Copyright Robert J. Amstadt, 1993 + * 16-bit mode callback functions + * + * Copyright 1995 Alexandre Julliard */ -#ifndef CALLBACK_H -#define CALLBACK_H +#ifndef WINE_CALLBACK_H +#define WINE_CALLBACK_H #include <stdlib.h> #include <stdarg.h> -#define CALLBACK_SIZE_WORD 0 -#define CALLBACK_SIZE_LONG 1 +#include "stackframe.h" + +#ifndef WINELIB + +/* List of the 16-bit callback functions. This list is used */ +/* by the build program to generate the file if1632/call16.S */ + + /* func ds parameters */ +extern WORD CallTo16_word_wl ( FARPROC, WORD, WORD, LONG ); +extern WORD CallTo16_word_ll ( FARPROC, WORD, LONG, LONG ); +extern WORD CallTo16_word_wwl ( FARPROC, WORD, WORD, WORD, LONG ); +extern WORD CallTo16_word_wlw ( FARPROC, WORD, WORD, LONG, WORD ); +extern LONG CallTo16_long_wwl ( FARPROC, WORD, WORD, WORD, LONG ); +extern WORD CallTo16_word_llwl ( FARPROC, WORD, LONG, LONG, WORD, LONG ); +extern LONG CallTo16_long_wwwl ( FARPROC, WORD, WORD, WORD, WORD, LONG ); +extern WORD CallTo16_word_wllwl( FARPROC, WORD, WORD, LONG, LONG, WORD, LONG ); +extern WORD CallTo16_word_wwlll( FARPROC, WORD, WORD, WORD, LONG, LONG, LONG ); + +extern WORD CallTo16_regs_( FARPROC func, WORD ds, WORD es, WORD ax, WORD bx, + WORD cx, WORD dx, WORD si, WORD di ); + +#define CallEnumChildProc( func, hwnd, lParam ) \ + CallTo16_word_wl( func, CURRENT_DS, hwnd, lParam ) +#define CallEnumFontFamProc( func, lpfont, lpmetric, type, lParam ) \ + CallTo16_word_llwl( func, CURRENT_DS, lpfont, lpmetric, type, lParam ) +#define CallEnumFontsProc( func, lpfont, lpmetric, type, lParam ) \ + CallTo16_word_llwl( func, CURRENT_DS, lpfont, lpmetric, type, lParam ) +#define CallEnumMetafileProc( func, hdc, lptable, lprecord, objs, lParam ) \ + CallTo16_word_wllwl(func, CURRENT_DS, hdc, lptable, lprecord, objs, lParam) +#define CallEnumObjectsProc( func, lpobj, lParam ) \ + CallTo16_word_ll( func, CURRENT_DS, lpobj, lParam ) +#define CallEnumPropProc( func, hwnd, lpstr, data ) \ + CallTo16_word_wlw( func, CURRENT_DS, hwnd, lpstr, data ) +#define CallEnumTaskWndProc( func, hwnd, lParam ) \ + CallTo16_word_wl( func, CURRENT_DS, hwnd, lParam ) +#define CallEnumWindowsProc( func, hwnd, lParam ) \ + CallTo16_word_wl( func, CURRENT_DS, hwnd, lParam ) +#define CallLineDDAProc( func, xPos, yPos, lParam ) \ + CallTo16_word_wwl( func, CURRENT_DS, xPos, yPos, lParam ) +#define CallGrayStringProc( func, hdc, lParam, cch ) \ + CallTo16_word_wlw( func, CURRENT_DS, hdc, lParam, cch ) +#define CallHookProc( func, code, wParam, lParam ) \ + CallTo16_long_wwl( func, CURRENT_DS, code, wParam, lParam ) +#define CallTimeFuncProc( func, id, msg, dwUser, dw1, dw2 ) \ + CallTo16_word_wwlll( func, CURRENT_DS, id, msg, dwUser, dw1, dw2 ) +#define CallWndProc( func, hwnd, msg, wParam, lParam ) \ + CallTo16_long_wwwl( func, CURRENT_DS, hwnd, msg, wParam, lParam ) + +#else /* WINELIB */ + +#define CallEnumChildProc( func, hwnd, lParam ) \ + (*func)( hwnd, lParam ) +#define CallEnumFontFamProc( func, lpfont, lpmetric, type, lParam ) \ + (*func)( lpfont, lpmetric, type, lParam ) +#define CallEnumFontsProc( func, lpfont, lpmetric, type, lParam ) \ + (*func)( lpfont, lpmetric, type, lParam ) +#define CallEnumMetafileProc( func, hdc, lptable, lprecord, objs, lParam ) \ + (*func)( hdc, lptable, lprecord, objs, lParam) +#define CallEnumObjectsProc( func, lpobj, lParam ) \ + (*func)( lpobj, lParam ) +#define CallEnumPropProc( func, hwnd, lpstr, data ) \ + (*func)( hwnd, lpstr, data ) +#define CallEnumTaskWndProc( func, hwnd, lParam ) \ + (*func)( hwnd, lParam ) +#define CallEnumWindowsProc( func, hwnd, lParam ) \ + (*func)( hwnd, lParam ) +#define CallLineDDAProc( func, xPos, yPos, lParam ) \ + (*func)( xPos, yPos, lParam ) +#define CallGrayStringProc( func, hdc, lParam, cch ) \ + (*func)( hdc, lParam, cch ) +#define CallHookProc( func, code, wParam, lParam ) \ + (*func)( code, wParam, lParam ) +#define CallTimeFuncProc( func, id, msg, dwUser, dw1, dw2 ) \ + (*func)( id, msg, dwUser, dw1, dw2 ) +#define CallWndProc( func, hwnd, msg, wParam, lParam ) \ + (*func)( hwnd, msg, wParam, lParam ) -extern int CallTo16(unsigned int csip, unsigned short ds); -extern int CallBack16(void *func, int n_args, ...); +#endif /* WINELIB */ -extern BOOL CallGrayStringProc(FARPROC func, HDC hdc, LPARAM lParam, INT cch); -#endif /* CALLBACK_H */ +#endif /* WINE_CALLBACK_H */ diff --git a/include/compobj.h b/include/compobj.h new file mode 100644 index 00000000000..d9482dcdcee --- /dev/null +++ b/include/compobj.h @@ -0,0 +1,5 @@ +/* + * compobj.h - Declarations for COMPOBJ + */ + +typedef LPVOID LPUNKNOWN; diff --git a/include/debug.h b/include/debug.h index 34493c85112..24c4730366c 100644 --- a/include/debug.h +++ b/include/debug.h @@ -69,7 +69,6 @@ #undef DEBUG_SCROLL #undef DEBUG_SELECTOR #undef DEBUG_SELECTORS -#undef DEBUG_STACK #undef DEBUG_STRESS #undef DEBUG_SYSCOLOR #undef DEBUG_TASK @@ -145,7 +144,6 @@ #define DEBUG_SCROLL #define DEBUG_SELECTOR #define DEBUG_SELECTORS -#define DEBUG_STACK #define DEBUG_STRESS #define DEBUG_SYSCOLOR #define DEBUG_TASK @@ -475,11 +473,6 @@ short debug_msg_enabled[]={ #else 0, #endif -#ifdef DEBUG_STACK - 1, -#else - 0, -#endif #ifdef DEBUG_STRESS 1, #else @@ -1352,21 +1345,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_stack if(!debug_msg_enabled[63]) ; else fprintf -#define debugging_stack debug_msg_enabled[63] -#else -#ifdef DEBUG_STACK -#define dprintf_stack fprintf -#define debugging_stack 1 -#else -#define dprintf_stack while(0) fprintf -#define debugging_stack 0 -#endif -#endif - -#ifdef DEBUG_RUNTIME -#define dprintf_stress if(!debug_msg_enabled[64]) ; else fprintf -#define debugging_stress debug_msg_enabled[64] +#define dprintf_stress if(!debug_msg_enabled[63]) ; else fprintf +#define debugging_stress debug_msg_enabled[63] #else #ifdef DEBUG_STRESS #define dprintf_stress fprintf @@ -1378,8 +1358,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_syscolor if(!debug_msg_enabled[65]) ; else fprintf -#define debugging_syscolor debug_msg_enabled[65] +#define dprintf_syscolor if(!debug_msg_enabled[64]) ; else fprintf +#define debugging_syscolor debug_msg_enabled[64] #else #ifdef DEBUG_SYSCOLOR #define dprintf_syscolor fprintf @@ -1391,8 +1371,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_task if(!debug_msg_enabled[66]) ; else fprintf -#define debugging_task debug_msg_enabled[66] +#define dprintf_task if(!debug_msg_enabled[65]) ; else fprintf +#define debugging_task debug_msg_enabled[65] #else #ifdef DEBUG_TASK #define dprintf_task fprintf @@ -1404,8 +1384,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_text if(!debug_msg_enabled[67]) ; else fprintf -#define debugging_text debug_msg_enabled[67] +#define dprintf_text if(!debug_msg_enabled[66]) ; else fprintf +#define debugging_text debug_msg_enabled[66] #else #ifdef DEBUG_TEXT #define dprintf_text fprintf @@ -1417,8 +1397,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_timer if(!debug_msg_enabled[68]) ; else fprintf -#define debugging_timer debug_msg_enabled[68] +#define dprintf_timer if(!debug_msg_enabled[67]) ; else fprintf +#define debugging_timer debug_msg_enabled[67] #else #ifdef DEBUG_TIMER #define dprintf_timer fprintf @@ -1430,8 +1410,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_toolhelp if(!debug_msg_enabled[69]) ; else fprintf -#define debugging_toolhelp debug_msg_enabled[69] +#define dprintf_toolhelp if(!debug_msg_enabled[68]) ; else fprintf +#define debugging_toolhelp debug_msg_enabled[68] #else #ifdef DEBUG_TOOLHELP #define dprintf_toolhelp fprintf @@ -1443,8 +1423,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_utility if(!debug_msg_enabled[70]) ; else fprintf -#define debugging_utility debug_msg_enabled[70] +#define dprintf_utility if(!debug_msg_enabled[69]) ; else fprintf +#define debugging_utility debug_msg_enabled[69] #else #ifdef DEBUG_UTILITY #define dprintf_utility fprintf @@ -1456,8 +1436,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_win if(!debug_msg_enabled[71]) ; else fprintf -#define debugging_win debug_msg_enabled[71] +#define dprintf_win if(!debug_msg_enabled[70]) ; else fprintf +#define debugging_win debug_msg_enabled[70] #else #ifdef DEBUG_WIN #define dprintf_win fprintf @@ -1469,8 +1449,8 @@ extern short debug_msg_enabled[]; #endif #ifdef DEBUG_RUNTIME -#define dprintf_winsock if(!debug_msg_enabled[72]) ; else fprintf -#define debugging_winsock debug_msg_enabled[72] +#define dprintf_winsock if(!debug_msg_enabled[71]) ; else fprintf +#define debugging_winsock debug_msg_enabled[71] #else #ifdef DEBUG_WINSOCK #define dprintf_winsock fprintf @@ -1548,7 +1528,6 @@ static char *debug_msg_name[] = { "scroll", "selector", "selectors", - "stack", "stress", "syscolor", "task", diff --git a/include/dlls.h b/include/dlls.h index cdceae540f2..10f2f08855f 100644 --- a/include/dlls.h +++ b/include/dlls.h @@ -7,6 +7,8 @@ #ifndef DLLS_H #define DLLS_H +#include "wintypes.h" + #define MAX_NAME_LENGTH 64 typedef struct resource_name_table @@ -54,119 +56,67 @@ extern struct w_files *wine_files; #define DLL 0 #define EXE 1 -#define DLL_ARGTYPE_SIGNEDWORD 0 -#define DLL_ARGTYPE_WORD 1 -#define DLL_ARGTYPE_LONG 2 -#define DLL_ARGTYPE_FARPTR 3 -#define DLL_MAX_ARGS 16 - -#define DLL_HANDLERTYPE_PASCAL 16 - struct dll_table_entry_s { /* * Relocation data */ - unsigned int selector; /* Selector to access this entry point */ - void *address; /* Offset in segment of entry point */ + WORD selector; /* Selector of entry point */ + WORD offset; /* Offset in segment of entry point */ /* * 16->32 bit interface data */ char *export_name; - void *handler; /* Address of function to process request */ - char n_args; /* Number of arguments passed to function */ - short conv_reference ; /* reference to Argument conversion data */ #ifdef WINESTAT int used; /* Number of times this function referenced */ #endif - }; -struct dll_name_table_entry_s +struct dll_table_s { - char *dll_name; struct dll_table_entry_s *dll_table; int dll_table_length; int dll_number; + void *code_start; /* 32-bit address of DLL code */ + void *code_end; + void *data_start; /* 32-bit address of DLL data */ + void *data_end; +}; + +struct dll_name_table_entry_s +{ + char *dll_name; + struct dll_table_s *table; int dll_is_used; /* use MS provided if set to zero */ }; -extern struct dll_table_entry_s KERNEL_table[]; -extern struct dll_table_entry_s USER_table[]; -extern struct dll_table_entry_s GDI_table[]; -extern struct dll_table_entry_s WIN87EM_table[]; -extern struct dll_table_entry_s MMSYSTEM_table[]; -extern struct dll_table_entry_s SHELL_table[]; -extern struct dll_table_entry_s SOUND_table[]; -extern struct dll_table_entry_s KEYBOARD_table[]; -extern struct dll_table_entry_s WINSOCK_table[]; -extern struct dll_table_entry_s STRESS_table[]; -extern struct dll_table_entry_s SYSTEM_table[]; -extern struct dll_table_entry_s TOOLHELP_table[]; -extern struct dll_table_entry_s MOUSE_table[]; -extern struct dll_table_entry_s COMMDLG_table[]; -extern struct dll_table_entry_s OLE2_table[]; -extern struct dll_table_entry_s OLE2CONV_table[]; -extern struct dll_table_entry_s OLE2DISP_table[]; -extern struct dll_table_entry_s OLE2NLS_table[]; -extern struct dll_table_entry_s OLE2PROX_table[]; -extern struct dll_table_entry_s OLECLI_table[]; -extern struct dll_table_entry_s OLESVR_table[]; -extern struct dll_table_entry_s COMPOBJ_table[]; -extern struct dll_table_entry_s STORAGE_table[]; - - -extern unsigned short KERNEL_offsets[]; -extern unsigned short USER_offsets[]; -extern unsigned short GDI_offsets[]; -extern unsigned short WIN87EM_offsets[]; -extern unsigned short MMSYSTEM_offsets[]; -extern unsigned short SHELL_offsets[]; -extern unsigned short SOUND_offsets[]; -extern unsigned short KEYBOARD_offsets[]; -extern unsigned short WINSOCK_offsets[]; -extern unsigned short STRESS_offsets[]; -extern unsigned short SYSTEM_offsets[]; -extern unsigned short TOOLHELP_offsets[]; -extern unsigned short MOUSE_offsets[]; -extern unsigned short COMMDLG_offsets[]; -extern unsigned short OLE2_offsets[]; -extern unsigned short OLE2CONV_offsets[]; -extern unsigned short OLE2DISP_offsets[]; -extern unsigned short OLE2NLS_offsets[]; -extern unsigned short OLE2PROX_offsets[]; -extern unsigned short OLECLI_offsets[]; -extern unsigned short OLESVR_offsets[]; -extern unsigned short COMPOBJ_offsets[]; -extern unsigned short STORAGE_offsets[]; - - -extern unsigned char KERNEL_types[]; -extern unsigned char USER_types[]; -extern unsigned char GDI_types[]; -extern unsigned char WIN87EM_types[]; -extern unsigned char MMSYSTEM_types[]; -extern unsigned char SHELL_types[]; -extern unsigned char SOUND_types[]; -extern unsigned char KEYBOARD_types[]; -extern unsigned char WINSOCK_types[]; -extern unsigned char STRESS_types[]; -extern unsigned char SYSTEM_types[]; -extern unsigned char TOOLHELP_types[]; -extern unsigned char MOUSE_types[]; -extern unsigned char COMMDLG_types[]; -extern unsigned char OLE2_types[]; -extern unsigned char OLE2CONV_types[]; -extern unsigned char OLE2DISP_types[]; -extern unsigned char OLE2NLS_types[]; -extern unsigned char OLE2PROX_types[]; -extern unsigned char OLECLI_types[]; -extern unsigned char OLESVR_types[]; -extern unsigned char COMPOBJ_types[]; -extern unsigned char STORAGE_types[]; - -#define N_BUILTINS 23 +extern struct dll_table_s KERNEL_table; +extern struct dll_table_s USER_table; +extern struct dll_table_s GDI_table; +extern struct dll_table_s WIN87EM_table; +extern struct dll_table_s MMSYSTEM_table; +extern struct dll_table_s SHELL_table; +extern struct dll_table_s SOUND_table; +extern struct dll_table_s KEYBOARD_table; +extern struct dll_table_s WINSOCK_table; +extern struct dll_table_s STRESS_table; +extern struct dll_table_s SYSTEM_table; +extern struct dll_table_s TOOLHELP_table; +extern struct dll_table_s MOUSE_table; +extern struct dll_table_s COMMDLG_table; +extern struct dll_table_s OLE2_table; +extern struct dll_table_s OLE2CONV_table; +extern struct dll_table_s OLE2DISP_table; +extern struct dll_table_s OLE2NLS_table; +extern struct dll_table_s OLE2PROX_table; +extern struct dll_table_s OLECLI_table; +extern struct dll_table_s OLESVR_table; +extern struct dll_table_s COMPOBJ_table; +extern struct dll_table_s STORAGE_table; +extern struct dll_table_s WINPROCS_table; + +#define N_BUILTINS 24 #endif /* DLLS_H */ diff --git a/include/global.h b/include/global.h new file mode 100644 index 00000000000..626890f8f17 --- /dev/null +++ b/include/global.h @@ -0,0 +1,16 @@ +/* + * Global heap declarations + * + * Copyright 1995 Alexandre Julliard + */ + +#ifndef __WINE_GLOBAL_H +#define __WINE_GLOBAL_H + +#include "wintypes.h" + +extern HGLOBAL GLOBAL_Alloc( WORD flags, DWORD size, HGLOBAL hOwner, + BOOL isCode, BOOL isReadOnly ); +extern WORD GlobalHandleToSel( HGLOBAL handle ); + +#endif /* __WINE_GLOBAL_H */ diff --git a/include/hook.h b/include/hook.h index 303fdd8d56c..bd918220bf6 100644 --- a/include/hook.h +++ b/include/hook.h @@ -9,6 +9,7 @@ #include "windows.h" #include "ldt.h" +#include "callback.h" /* Hook data (pointed to by a HHOOK) */ typedef struct @@ -34,9 +35,6 @@ typedef struct #define CALL_TASK_HOOK(id,code,wparam,lparam) \ INTERNAL_CALL_HOOK(TASK_HOOK(id),code,wparam,lparam) -extern DWORD CallHookProc( HOOKPROC func, short code, - WPARAM wParam, LPARAM lParam ); /* callback.c */ - extern HHOOK systemHooks[]; extern HHOOK taskHooks[]; diff --git a/include/if1632.h b/include/if1632.h index 03621a62835..96726dd0e44 100644 --- a/include/if1632.h +++ b/include/if1632.h @@ -7,12 +7,11 @@ extern int CallToInit16(unsigned long csip, unsigned long sssp, unsigned short ds); extern int CallTo16cx(unsigned long csip, unsigned long dscx); extern int CallToDllEntry(unsigned long csip, unsigned long dscx, unsigned short di); -extern int CallBack16(void *func, int n_args, ...); -extern void CallLineDDAProc(FARPROC func, short xPos, short yPos, long lParam); extern void winestat(void); -extern int DLLRelay(unsigned int func_num, unsigned int seg_off); -extern struct dll_table_entry_s *FindDLLTable(char *dll_name); +extern struct dll_table_s *FindDLLTable(char *dll_name); extern int FindOrdinalFromName(struct dll_table_entry_s *dll_table, char *func_name); extern int ReturnArg(int arg); +extern BOOL RELAY_Init(void); + #endif /* __WINE_IF1632_H */ diff --git a/include/listbox.h b/include/listbox.h index c1b2278bc7e..307a74e6070 100644 --- a/include/listbox.h +++ b/include/listbox.h @@ -8,7 +8,7 @@ typedef struct tagLISTSTRUCT { HANDLE hMem; HANDLE hData; char *itemText; - void *lpNext; + struct tagLISTSTRUCT *lpNext; } LISTSTRUCT; typedef LISTSTRUCT FAR* LPLISTSTRUCT; @@ -21,15 +21,17 @@ typedef struct tagHEADLIST { short ItemsPerColumn; short ItemFocused; short PrevFocused; - short SelCount; short StdItemHeight; short ColumnsWidth; short DrawCtlType; - void *lpFirst; + void *lpFirst; DWORD dwStyle; HWND hWndLogicParent; HFONT hFont; BOOL bRedrawFlag; + WORD iNumStops; + LPINT TabStops; + HANDLE hDrawItemStruct; /* MDESC *Heap; */ } HEADLIST; typedef HEADLIST FAR* LPHEADLIST; diff --git a/include/local.h b/include/local.h index eb813e93041..a676a137740 100644 --- a/include/local.h +++ b/include/local.h @@ -4,8 +4,8 @@ * Copyright 1995 Alexandre Julliard */ -#ifndef __WINE_HEAP_H -#define __WINE_HEAP_H +#ifndef __WINE_LOCAL_H +#define __WINE_LOCAL_H #include "wintypes.h" @@ -21,4 +21,4 @@ extern WORD LOCAL_Size( WORD ds, HLOCAL handle ); extern WORD LOCAL_Flags( WORD ds, HLOCAL handle ); extern WORD LOCAL_HeapSize( WORD ds ); -#endif /* __WINE_HEAP_H */ +#endif /* __WINE_LOCAL_H */ diff --git a/include/msdos.h b/include/msdos.h index 35b8d92f485..7b2bda78315 100644 --- a/include/msdos.h +++ b/include/msdos.h @@ -30,7 +30,7 @@ struct fcb { BYTE dummy2[9]; }; -#define DOSVERSION 0x0500; /* Might as well pretend we're DOS 5.0 */ +#define DOSVERSION 0x0005; /* Major version in low byte: DOS 5.00 */ #define MAX_DOS_DRIVES 26 extern WORD ExtendedError; diff --git a/include/neexe.h b/include/neexe.h index ad26cbec762..51e860def25 100644 --- a/include/neexe.h +++ b/include/neexe.h @@ -12,18 +12,19 @@ */ struct mz_header_s { - u_char dont_care1[0x18]; /* MZ Header stuff */ - u_char must_be_0x40; /* 0x40 for non-MZ program */ - u_char dont_care2[0x23]; /* More MZ header stuff */ - u_short ne_offset; /* Offset to extended header */ + u_short mz_magic; /* MZ Header signature */ + u_char dont_care[0x3a]; /* MZ Header stuff */ + u_short ne_offset; /* Offset to extended header */ }; +#define MZ_SIGNATURE ('M' | ('Z' << 8)) + /* * This is the Windows executable (NE) header. */ struct ne_header_s { - char header_type[2]; /* Must contain 'N' 'E' */ + u_short ne_magic; /* NE signature 'NE' */ u_char linker_version; /* Linker version number */ u_char linker_revision; /* Linker revision number */ u_short entry_tab_offset; /* Offset to entry table relative to NE */ @@ -57,6 +58,9 @@ struct ne_header_s u_short expect_version; /* Expected Windows version number */ }; +#define NE_SIGNATURE ('N' | ('E' << 8)) +#define PE_SIGNATURE ('P' | ('E' << 8)) + /* * NE Header FORMAT FLAGS */ diff --git a/include/registers.h b/include/registers.h index ce06a0fed05..0298c238d6d 100644 --- a/include/registers.h +++ b/include/registers.h @@ -5,6 +5,8 @@ #ifndef PROCEMU +#include "wine.h" + #define EAX context->sc_eax #define EBX context->sc_ebx #define ECX context->sc_ecx diff --git a/include/selectors.h b/include/selectors.h index 55715b9c7f7..13cb8365fb6 100644 --- a/include/selectors.h +++ b/include/selectors.h @@ -20,12 +20,14 @@ extern WORD SELECTOR_ReallocBlock( WORD sel, void *base, DWORD size, extern WORD *CreateSelectors( struct w_files * wpnt ); -extern unsigned int GetEntryDLLName(char *dll_name, char *function, WORD *sel, - int *addr); -extern unsigned int GetEntryDLLOrdinal(char *dll_name, int ordinal, WORD *sel, - int *addr); -extern unsigned int GetEntryPointFromOrdinal(struct w_files * wpnt, - int ordinal); +extern unsigned int GetEntryDLLName(char *dll_name, char *function, + WORD *sel, WORD *offset); +extern unsigned int GetEntryDLLOrdinal(char *dll_name, int ordinal, + WORD *sel, WORD *offset); +extern unsigned int GetEntryPointFromOrdinal(struct w_files * wpnt, + int ordinal); extern void InitSelectors(void); +extern WNDPROC GetWndProcEntry16( char *name ); + #endif /* __WINE_SELECTORS_H */ diff --git a/include/stackframe.h b/include/stackframe.h index d029ec198d5..3a1bf2de1f7 100644 --- a/include/stackframe.h +++ b/include/stackframe.h @@ -10,19 +10,29 @@ #include <windows.h> #include "ldt.h" +#ifndef WINELIB +#pragma pack(1) +#endif + typedef struct { - WORD saved_ss; + WORD saved_ss; /* saved previous 16-bit stack */ WORD saved_bp; WORD saved_sp; - WORD ds; - WORD bp; - WORD arg_length; - WORD ip; + WORD ds; /* 16-bit ds */ + DWORD entry_point WINE_PACKED; /* entry point to call */ + WORD ordinal_number; /* ordinal number of entry point */ + WORD dll_id; /* DLL id of entry point */ + WORD bp; /* 16-bit bp */ + WORD ip; /* return address */ WORD cs; - WORD args[1]; + WORD args[1]; /* arguments to API function */ } STACK16FRAME; +#ifndef WINELIB +#pragma pack(4) +#endif + extern WORD IF1632_Saved16_ss; extern WORD IF1632_Saved16_sp; extern WORD IF1632_Saved16_bp; diff --git a/include/stddebug.h b/include/stddebug.h index 4abb78e8bfa..2b4114e940e 100644 --- a/include/stddebug.h +++ b/include/stddebug.h @@ -139,7 +139,6 @@ #undef DEBUG_SCROLL #undef DEBUG_SELECTOR #undef DEBUG_SELECTORS -#undef DEBUG_STACK #undef DEBUG_STRESS #undef DEBUG_SYSCOLOR #undef DEBUG_TASK @@ -215,7 +214,6 @@ #define DEBUG_SCROLL #define DEBUG_SELECTOR #define DEBUG_SELECTORS -#define DEBUG_STACK #define DEBUG_STRESS #define DEBUG_SYSCOLOR #define DEBUG_TASK diff --git a/include/toolhelp.h b/include/toolhelp.h index 85ab7b30e97..ba1a05a8afd 100644 --- a/include/toolhelp.h +++ b/include/toolhelp.h @@ -10,8 +10,76 @@ /* Global heap */ -WORD GlobalHandleToSel( HANDLE handle ); +typedef struct +{ + DWORD dwSize; + WORD wcItems; + WORD wcItemsFree; + WORD wcItemsLRU; +} GLOBALINFO; +typedef struct +{ + DWORD dwSize; + DWORD dwAddress; + DWORD dwBlockSize; + HGLOBAL hBlock; + WORD wcLock; + WORD wcPageLock; + WORD wFlags; + BOOL wHeapPresent; + HGLOBAL hOwner; + WORD wType; + WORD wData; + DWORD dwNext; + DWORD dwNextAlt; +} GLOBALENTRY; + + /* GlobalFirst()/GlobalNext() flags */ +#define GLOBAL_ALL 0 +#define GLOBAL_LRU 1 +#define GLOBAL_FREE 2 + + /* wType values */ +#define GT_UNKNOWN 0 +#define GT_DGROUP 1 +#define GT_DATA 2 +#define GT_CODE 3 +#define GT_TASK 4 +#define GT_RESOURCE 5 +#define GT_MODULE 6 +#define GT_FREE 7 +#define GT_INTERNAL 8 +#define GT_SENTINEL 9 +#define GT_BURGERMASTER 10 + +/* wData values */ +#define GD_USERDEFINED 0 +#define GD_CURSORCOMPONENT 1 +#define GD_BITMAP 2 +#define GD_ICONCOMPONENT 3 +#define GD_MENU 4 +#define GD_DIALOG 5 +#define GD_STRING 6 +#define GD_FONTDIR 7 +#define GD_FONT 8 +#define GD_ACCELERATORS 9 +#define GD_RCDATA 10 +#define GD_ERRTABLE 11 +#define GD_CURSOR 12 +#define GD_ICON 14 +#define GD_NAMETABLE 15 +#define GD_MAX_RESOURCE 15 + +/* wFlags values */ +#define GF_PDB_OWNER 0x0100 /* Low byte is KERNEL flags */ + +BOOL GlobalInfo( GLOBALINFO *pInfo ); +BOOL GlobalFirst( GLOBALENTRY *pGlobal, WORD wFlags ); +BOOL GlobalNext( GLOBALENTRY *pGlobal, WORD wFlags) ; +BOOL GlobalEntryHandle( GLOBALENTRY *pGlobal, HGLOBAL hItem ); +BOOL GlobalEntryModule( GLOBALENTRY *pGlobal, HMODULE hModule, WORD wSeg ); +WORD GlobalHandleToSel( HGLOBAL handle ); /* Local heap */ diff --git a/include/windows.h b/include/windows.h index 5ff1c252d6c..2e639f93113 100644 --- a/include/windows.h +++ b/include/windows.h @@ -680,6 +680,17 @@ typedef struct tagTEXTMETRIC #define ETO_OPAQUE 0x02 #define ETO_CLIPPED 0x04 + /* Rasterizer status */ +typedef struct +{ + WORD nSize; + WORD wFlags; + WORD nLanguageID; +} RASTERIZER_STATUS, *LPRASTERIZER_STATUS; + +#define TT_AVAILABLE 0x0001 +#define TT_ENABLED 0x0002 + typedef struct tagPALETTEENTRY { BYTE peRed, peGreen, peBlue, peFlags; @@ -2469,8 +2480,8 @@ Fa(LPSTR,AnsiLower,LPSTR,a) Fa(SEGPTR,AnsiNext,SEGPTR,a) Fa(LPSTR,AnsiUpper,LPSTR,a) Fa(LPSTR,GlobalLock,HGLOBAL,a) -Fa(LPSTR,GlobalWire,HGLOBAL,a) Fa(LPSTR,LockResource,HANDLE,a) +Fa(SEGPTR,GlobalWire,HGLOBAL,a) Fa(SEGPTR,WIN16_GlobalLock,HGLOBAL,a) Fa(UINT,GDIRealizePalette,HDC,a) Fa(UINT,RealizePalette,HDC,a) diff --git a/include/wine.h b/include/wine.h index bd426f378e7..101f50e1df8 100644 --- a/include/wine.h +++ b/include/wine.h @@ -1,8 +1,5 @@ #ifndef WINE_H #define WINE_H -#if 0 -#define __ELF__ -#endif extern char *WineIniFileName(void); extern char *WinIniFileName(void); @@ -36,12 +33,8 @@ struct sigcontext_struct { unsigned long cr2; }; #define WINE_DATA_SELECTOR 0x2b -#ifdef __ELF__ -#define WINE_CODE_SELECTOR 0x0f -#else #define WINE_CODE_SELECTOR 0x23 -#endif -#endif +#endif /* linux */ #if defined(__NetBSD__) || defined(__FreeBSD__) #include <signal.h> diff --git a/loader/dump.c b/loader/dump.c index 77a2a063006..2011bbe14f3 100644 --- a/loader/dump.c +++ b/loader/dump.c @@ -25,8 +25,8 @@ void PrintFileHeader(struct ne_header_s *ne_header) { printf("ne_header: %c%c\n", - ne_header->header_type[0], - ne_header->header_type[1]); + ne_header->ne_magic & 0xff, + ne_header->ne_magic >> 8 ); printf("linker version: %d.%d\n", ne_header->linker_version, ne_header->linker_revision); printf("format flags: %04x\n", ne_header->format_flags); diff --git a/loader/library.c b/loader/library.c index e610d3c7d7a..8c0218108f5 100644 --- a/loader/library.c +++ b/loader/library.c @@ -381,6 +381,8 @@ HANDLE LoadLibrary(LPSTR libname) { HANDLE h; + dprintf_module(stddeb,"LoadLibrary: (%08x) %s\n",(int)libname,libname); + if ((h = LoadImage(libname, DLL, 0)) < 32) return h; @@ -435,8 +437,8 @@ FARPROC GetProcAddress(HANDLE hModule, char *proc_name) #ifdef WINELIB WINELIB_UNIMP ("GetProcAddress"); #else - int addr, ret; - WORD sel; + int ret; + WORD sel, addr; register struct w_files *w = wine_files; int ordinal, len; char * cpnt; @@ -541,9 +543,9 @@ FARPROC GetProcAddress(HANDLE hModule, char *proc_name) static void FillModStructBuiltIn(MODULEENTRY *lpModule, struct dll_name_table_entry_s *dll) { - lpModule->dwSize = dll->dll_table_length * 1024; + lpModule->dwSize = dll->table->dll_table_length * 1024; strcpy(lpModule->szModule, dll->dll_name); - lpModule->hModule = 0xff00 + dll->dll_number; + lpModule->hModule = 0xff00 + dll->table->dll_number; lpModule->wcUsage = GetModuleUsage(lpModule->hModule); GetModuleFileName(lpModule->hModule, lpModule->szExePath, MAX_PATH + 1); lpModule->wNext = 0; diff --git a/loader/ne_image.c b/loader/ne_image.c index 0c18f4d9699..d0bd13732e7 100644 --- a/loader/ne_image.c +++ b/loader/ne_image.c @@ -18,6 +18,7 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include "library.h" #include "if1632.h" #include "selectors.h" +#include "callback.h" #include "ne_image.h" #include "prototypes.h" #include "stddebug.h" @@ -146,7 +147,7 @@ int NE_FixupSegment(struct w_files *wpnt, int segment_num) ordinal = rep->target2; status = GetEntryDLLOrdinal(dll_name, ordinal, &selector, - &address); + &offset); if (status) { char s[80]; @@ -157,7 +158,7 @@ int NE_FixupSegment(struct w_files *wpnt, int segment_num) } dprintf_fixup(stddeb,"%d: %s.%d: %04x:%04x\n", i + 1, - dll_name, ordinal, selector, address); + dll_name, ordinal, selector, offset); break; case NE_RELTYPE_NAME: @@ -172,7 +173,7 @@ int NE_FixupSegment(struct w_files *wpnt, int segment_num) } status = GetEntryDLLName(dll_name, func_name, &selector, - &address); + &offset); if (status) { char s[80]; @@ -181,8 +182,8 @@ int NE_FixupSegment(struct w_files *wpnt, int segment_num) myerror(s); return -1; } -/* dprintf_fixup(stddeb,"%d: %s %s.%d: %04x:%04x\n", i + 1, - func_name, dll_name, ordinal, selector, address);*/ + dprintf_fixup(stddeb,"%d: %s %s.%d: %04x:%04x\n", i + 1, + func_name, dll_name, ordinal, selector, offset); break; case NE_RELTYPE_INTERNAL: @@ -190,16 +191,16 @@ int NE_FixupSegment(struct w_files *wpnt, int segment_num) { address = GetEntryPointFromOrdinal(wpnt, rep->target2); selector = (address >> 16) & 0xffff; - address &= 0xffff; + offset = address & 0xffff; } else { selector = selector_table[rep->target1-1]; - address = rep->target2; + offset = rep->target2; } dprintf_fixup(stddeb,"%d: %04x:%04x\n", - i + 1, selector, address); + i + 1, selector, offset); break; case NE_RELTYPE_OSFIXUP: @@ -240,7 +241,8 @@ int NE_FixupSegment(struct w_files *wpnt, int segment_num) i+1, rep->address_type, rep->relocation_type, rep->offset, rep->target1, rep->target2); - offset = rep->offset; + address = (unsigned int)offset; + offset = rep->offset; switch (rep->address_type) { @@ -290,8 +292,9 @@ int NE_FixupSegment(struct w_files *wpnt, int segment_num) sel, offset, *sp, additive ? " additive" : "" ); offset = *sp; *sp = (unsigned short) selector; - if(additive) - fprintf(stderr,"Additive selector, please report\n"); + /* Borland creates additive records with offset zero. Strange, but OK */ + if(additive && offset) + fprintf(stderr,"Additive selector to %4.4x.Please report\n",offset); } while (offset != 0xffff && !additive); break; @@ -321,20 +324,39 @@ int NE_unloadImage(struct w_files *wpnt) int NE_StartProgram(struct w_files *wpnt) { - int cs_reg, ds_reg, ss_reg, ip_reg, sp_reg; + extern WORD PSPSelector; + + int cs_reg, ds_reg, ip_reg; + + /* Registers at initialization must be: + * ax zero + * bx stack size in bytes + * cx heap size in bytes + * si previous app instance + * di current app instance + * bp zero + * es selector to the PSP + * ds dgroup of the application + * ss stack selector + * sp top of the stack + */ + /* * Fixup stack and jump to start. */ WIN_StackSize = wpnt->ne->ne_header->stack_length; WIN_HeapSize = wpnt->ne->ne_header->local_heap_length; - ds_reg = wpnt->ne->selector_table[wpnt->ne->ne_header->auto_data_seg-1]; cs_reg = wpnt->ne->selector_table[wpnt->ne->ne_header->cs-1]; ip_reg = wpnt->ne->ne_header->ip; - ss_reg = wpnt->ne->selector_table[wpnt->ne->ne_header->ss-1]; - sp_reg = wpnt->ne->ne_header->sp; + ds_reg = wpnt->ne->selector_table[wpnt->ne->ne_header->auto_data_seg-1]; - return CallToInit16(cs_reg << 16 | ip_reg, ss_reg << 16 | sp_reg, ds_reg); + IF1632_Saved16_ss = wpnt->ne->selector_table[wpnt->ne->ne_header->ss-1]; + IF1632_Saved16_sp = wpnt->ne->ne_header->sp; + IF1632_Saved16_bp = 0; + return CallTo16_regs_( (FARPROC)(cs_reg << 16 | ip_reg), ds_reg, + PSPSelector /*es*/, 0 /*ax*/, WIN_StackSize /*bx*/, + WIN_HeapSize, 0 /*dx*/, 0 /*si*/, ds_reg /*di*/ ); } void NE_InitDLL(struct w_files *wpnt) @@ -363,7 +385,9 @@ void NE_InitDLL(struct w_files *wpnt) cx_reg = wpnt->ne->ne_header->local_heap_length; } - cs_reg = wpnt->ne->selector_table[wpnt->ne->ne_header->cs-1]; + dprintf_dll(stddeb,"InitDLL: ne_header->cs = %04x\n",wpnt->ne->ne_header->cs); + if (!wpnt->ne->ne_header->cs) cs_reg = 0; + else cs_reg = wpnt->ne->selector_table[wpnt->ne->ne_header->cs-1]; ip_reg = wpnt->ne->ne_header->ip; di_reg = wpnt->hinstance; @@ -372,7 +396,9 @@ void NE_InitDLL(struct w_files *wpnt) dprintf_dll(stddeb,"Initializing %s, cs:ip %04x:%04x, ds %04x, cx %04x\n", wpnt->name, cs_reg, ip_reg, ds_reg, cx_reg); - rv = CallTo16cx(cs_reg << 16 | ip_reg, ds_reg | (cx_reg<<16)); + rv = CallTo16_regs_( (FARPROC)(cs_reg << 16 | ip_reg), ds_reg, + 0 /*es*/, 0 /*ax*/, 0 /*bx*/, cx_reg, + 0 /*dx*/, 0 /*si*/, di_reg ); dprintf_exec(stddeb,"rv = %x\n", rv); } else dprintf_exec(stddeb,"%s skipped\n", wpnt->name); diff --git a/loader/resource.c b/loader/resource.c index 0446393e9d9..0d1249bf8c6 100644 --- a/loader/resource.c +++ b/loader/resource.c @@ -623,8 +623,7 @@ int TranslateAccelerator(HWND hWnd, HANDLE hAccel, LPMSG msg) int LoadString(HANDLE instance, WORD resource_id, LPSTR buffer, int buflen) { - HANDLE hmem; - int rsc_size; + HANDLE hmem, hrsrc; unsigned char *p; int string_num; int i; @@ -632,10 +631,11 @@ LoadString(HANDLE instance, WORD resource_id, LPSTR buffer, int buflen) dprintf_resource(stddeb, "LoadString: instance = %04x, id = %d, buffer = %08x, " "length = %d\n", instance, resource_id, (int) buffer, buflen); - hmem = RSC_LoadResource(instance, (SEGPTR)((resource_id >> 4) + 1), - (SEGPTR) NE_RSCTYPE_STRING, &rsc_size ); - if (hmem == 0) - return 0; + hrsrc = FindResource( instance, (SEGPTR)((resource_id >> 4) + 1), + (SEGPTR) NE_RSCTYPE_STRING ); + if (!hrsrc) return 0; + hmem = LoadResource( instance, hrsrc ); + if (!hmem) return 0; p = GlobalLock(hmem); string_num = resource_id & 0x000f; @@ -655,7 +655,7 @@ LoadString(HANDLE instance, WORD resource_id, LPSTR buffer, int buflen) fprintf(stderr,"LoadString // I dont know why , but caller give buflen=%d *p=%d !\n", buflen, *p); fprintf(stderr,"LoadString // and try to obtain string '%s'\n", p + 1); } - GlobalFree(hmem); + FreeResource( hrsrc ); dprintf_resource(stddeb,"LoadString // '%s' copied !\n", buffer); return i; diff --git a/loader/selector.c b/loader/selector.c index a8e687175d6..142c70367d6 100644 --- a/loader/selector.c +++ b/loader/selector.c @@ -31,7 +31,7 @@ #include "windows.h" #include "ldt.h" #include "wine.h" - +#include "global.h" #include "dlls.h" #include "neexe.h" #include "if1632.h" @@ -51,8 +51,6 @@ WORD PSPSelector = 0; int max_selectors = 0; -extern void KERNEL_Ordinal_1(); /* FatalExit() */ -extern void KERNEL_Ordinal_102(); /* Dos3Call() */ extern char WindowsPath[256]; extern char **Argv; @@ -62,46 +60,6 @@ extern char **environ; unsigned int GetEntryPointFromOrdinal(struct w_files * wpnt, int ordinal); -#if 0 - - -/********************************************************************** - * InitSelectors - */ -void -InitSelectors(void) -{ - int i; - max_selectors = MAX_SELECTORS; - SelectorMap = malloc(max_selectors * sizeof(unsigned short)); - Segments = malloc(max_selectors * sizeof(SEGDESC)); - for (i = 0; i < max_selectors; i++) { - if (i < FIRST_SELECTOR) { - SelectorMap[i] = SELECTOR_IS32BIT; -#ifdef __ELF__ - /* quick hack, just reserves 4 meg for wine. */ - } else if ((i << (16 + __AHSHIFT)) >= 0x8000000 && - (i << (16 + __AHSHIFT)) <= 0x8400000) { - SelectorMap[i]= SELECTOR_IS32BIT; -#endif - } else { - SelectorMap[i]=0; - } - } -#ifdef __ELF__ - /* create an ldt. */ - if (set_ldt_entry(1, 0x8000000, 65535, 1,0x1a ,1,0)) { - perror ("set_ldt_entry"); - exit (1); - } -#endif - } - - -#endif /* 0 */ - - - /********************************************************************** * Check whether pseudo-functions like __0040H for direct memory @@ -110,8 +68,8 @@ InitSelectors(void) * (e.g. reading from the Bios data segment (esp. clock!) ) */ -unsigned int GetMemoryReference(char *dll_name, char *function, WORD *sel, - int *addr) +unsigned int GetMemoryReference( char *dll_name, char *function, + WORD *sel, WORD *offset ) { static HANDLE memory_handles[ 10 ] = { 0,0,0,0,0,0,0,0,0,0 }; static char *memory_names[ 10 ] = { "segment 0xA000", @@ -143,13 +101,11 @@ unsigned int GetMemoryReference(char *dll_name, char *function, WORD *sel, else if( !strcasecmp( function, "__C000H" ) ) nr = 8; else if( !strcasecmp( function, "__0040H" ) ) nr = 9; else if( !strcasecmp( function, "__AHIncr" ) ) { - *sel = __AHINCR; - *addr = MAKELONG(__AHINCR,__AHINCR); + *sel = *offset = __AHINCR; return 1; } else if( !strcasecmp( function, "__AHShift" ) ) { - *sel = __AHSHIFT; - *addr = MAKELONG(__AHSHIFT,__AHSHIFT); + *sel = *offset = __AHSHIFT; return 1; } else @@ -168,12 +124,10 @@ unsigned int GetMemoryReference(char *dll_name, char *function, WORD *sel, case 195: nr = 8; break; case 193: nr = 9; break; case 114: - *sel = __AHINCR; - *addr = MAKELONG(__AHINCR,__AHINCR); + *sel = *offset = __AHINCR; return 1; case 113: - *sel = __AHSHIFT; - *addr = MAKELONG(__AHSHIFT,__AHSHIFT); + *sel = *offset = __AHSHIFT; return 1; default: return 0; } @@ -183,8 +137,7 @@ unsigned int GetMemoryReference(char *dll_name, char *function, WORD *sel, fprintf( stderr, "Warning: Direct access to %s!\n", memory_names[ nr ] ); memory_handles[ nr ] = GlobalAlloc( GMEM_FIXED, 65535 ); } - *sel = memory_handles[ nr ]; - *addr = MAKELONG(*sel,*sel); + *sel = *offset = memory_handles[ nr ]; return 1; } @@ -200,32 +153,31 @@ union lookup{ char * cpnt; }; -unsigned int GetEntryDLLName(char * dll_name, char * function, WORD* sel, - int * addr) +unsigned int GetEntryDLLName( char * dll_name, char * function, + WORD* sel, WORD *offset ) { - struct dll_table_entry_s *dll_table; + struct dll_table_s *dll_table; struct w_files * wpnt; char * cpnt; int ordinal, j, len; - if( GetMemoryReference( dll_name, function, sel, addr ) ) + if( GetMemoryReference( dll_name, function, sel, offset ) ) return 0; dll_table = FindDLLTable(dll_name); if(dll_table) { - ordinal = FindOrdinalFromName(dll_table, function); + ordinal = FindOrdinalFromName(dll_table->dll_table,function); if(!ordinal){ dprintf_module(stddeb,"GetEntryDLLName: %s.%s not found\n", dll_name, function); - *sel=0; - *addr=0; + *sel = *offset = 0; return -1; } - *sel = dll_table[ordinal].selector; - *addr = (unsigned int) dll_table[ordinal].address; + *sel = dll_table->dll_table[ordinal].selector; + *offset = dll_table->dll_table[ordinal].offset; #ifdef WINESTAT - dll_table[ordinal].used++; + dll_table->dll_table[ordinal].used++; #endif return 0; }; @@ -244,31 +196,30 @@ unsigned int GetEntryDLLName(char * dll_name, char * function, WORD* sel, }; ordinal = *((unsigned short *) (cpnt + len)); j = GetEntryPointFromOrdinal(wpnt, ordinal); - *addr = j & 0xffff; - j = j >> 16; - *sel = j; + *offset = LOWORD(j); + *sel = HIWORD(j); return 0; }; return 1; } -unsigned int GetEntryDLLOrdinal(char * dll_name, int ordinal, WORD *sel, - int * addr) +unsigned int GetEntryDLLOrdinal( char * dll_name, int ordinal, + WORD *sel, WORD *offset ) { - struct dll_table_entry_s *dll_table; + struct dll_table_s *dll_table; struct w_files * wpnt; int j; - if( GetMemoryReference( dll_name, (char*)ordinal, sel, addr ) ) + if( GetMemoryReference( dll_name, (char*)ordinal, sel, offset ) ) return 0; dll_table = FindDLLTable(dll_name); if(dll_table) { - *sel = dll_table[ordinal].selector; - *addr = (unsigned int) dll_table[ordinal].address; + *sel = dll_table->dll_table[ordinal].selector; + *offset = dll_table->dll_table[ordinal].offset; #ifdef WINESTAT - dll_table[ordinal].used++; + dll_table->dll_table[ordinal].used++; #endif return 0; }; @@ -277,9 +228,8 @@ unsigned int GetEntryDLLOrdinal(char * dll_name, int ordinal, WORD *sel, for(wpnt = wine_files; wpnt; wpnt = wpnt->next){ if(strcasecmp(wpnt->name, dll_name)) continue; j = GetEntryPointFromOrdinal(wpnt, ordinal); - *addr = j & 0xffff; - j = j >> 16; - *sel = j; + *offset = LOWORD(j); + *sel = HIWORD(j); return 0; }; return 1; @@ -345,6 +295,15 @@ GetEntryPointFromOrdinal(struct w_files * wpnt, int ordinal) } +WNDPROC GetWndProcEntry16( char *name ) +{ + WORD sel, offset; + + GetEntryDLLName( "WINPROCS", name, &sel, &offset ); + return (WNDPROC) MAKELONG( offset, sel ); +} + + /*********************************************************************** * GetDOSEnvironment (KERNEL.131) */ @@ -413,9 +372,9 @@ static WORD CreatePSP(void) { HANDLE handle; struct dos_psp_s *psp; - unsigned short *usp; char *p1, *p2; int i; + WORD sel, offset; handle = GlobalAlloc( GMEM_MOVEABLE, sizeof(*psp) ); if (!handle) return 0; @@ -426,15 +385,16 @@ static WORD CreatePSP(void) */ psp->pspInt20 = 0x20cd; psp->pspDispatcher[0] = 0x9a; - usp = (unsigned short *) &psp->pspDispatcher[1]; - *usp = (unsigned short) KERNEL_Ordinal_102; - *(usp + 1) = WINE_CODE_SELECTOR; - psp->pspTerminateVector[0] = (unsigned short) KERNEL_Ordinal_1; - psp->pspTerminateVector[1] = WINE_CODE_SELECTOR; - psp->pspControlCVector[0] = (unsigned short) KERNEL_Ordinal_1; - psp->pspControlCVector[1] = WINE_CODE_SELECTOR; - psp->pspCritErrorVector[0] = (unsigned short) KERNEL_Ordinal_1; - psp->pspCritErrorVector[1] = WINE_CODE_SELECTOR; + GetEntryDLLName( "KERNEL", "DOS3Call", &sel, &offset ); + *(unsigned short *)&psp->pspDispatcher[1] = offset; + *(unsigned short *)&psp->pspDispatcher[3] = sel; + GetEntryDLLName( "KERNEL", "FatalAppExit", &sel, &offset ); + psp->pspTerminateVector[0] = offset; + psp->pspTerminateVector[1] = sel; + psp->pspControlCVector[0] = offset; + psp->pspControlCVector[1] = sel; + psp->pspCritErrorVector[0] = offset; + psp->pspCritErrorVector[1] = sel; psp->pspEnvironment = SELECTOROF( GetDOSEnvironment() ); p1 = psp->pspCommandTail; @@ -473,7 +433,7 @@ unsigned short *CreateSelectors(struct w_files * wpnt) int i, length; void *base_addr; WORD *selectors; - ldt_entry entry; + HGLOBAL handle; auto_data_sel=0; /* @@ -523,36 +483,21 @@ unsigned short *CreateSelectors(struct w_files * wpnt) dprintf_selectors(stddeb,"Auto data image length %x\n",file_image_length); } - if (!(selectors[i] = AllocSelector( 0 ))) - { - fprintf( stderr, "CreateSelectors: out of free LDT entries\n" ); - exit( 1 ); - } - if (!(base_addr = (void *) malloc( length ))) - { - fprintf( stderr, "CreateSelectors: malloc() failed\n" ); - exit( 1 ); - } - entry.base = (unsigned long) base_addr; - entry.limit = length - 1; - entry.seg_32bit = 0; - entry.limit_in_pages = 0; - /* * Is this a DATA or CODE segment? */ if (seg_table[i].seg_flags & NE_SEGFLAGS_DATA) { - entry.type = SEGMENT_DATA; - entry.read_only = seg_table[i].seg_flags & NE_SEGFLAGS_READONLY; - memset( base_addr, 0, length ); + handle = GLOBAL_Alloc( GMEM_ZEROINIT, length, 0, FALSE, + seg_table[i].seg_flags & NE_SEGFLAGS_READONLY ); } else { - entry.type = SEGMENT_CODE; - entry.read_only = seg_table[i].seg_flags & NE_SEGFLAGS_EXECUTEONLY; + handle = GLOBAL_Alloc( 0, length, 0, TRUE, + seg_table[i].seg_flags & NE_SEGFLAGS_EXECUTEONLY ); } - LDT_SetEntry( SELECTOR_TO_ENTRY(selectors[i]), &entry ); + base_addr = GlobalLock( handle ); + selectors[i] = GlobalHandleToSel( handle ); if (seg_table[i].seg_data_offset != 0) { @@ -578,14 +523,13 @@ unsigned short *CreateSelectors(struct w_files * wpnt) saved_old_length = old_length; } } - if(!auto_data_sel)dprintf_selectors(stddeb,"Warning: No auto_data_sel\n"); for (i = 0; i < ne_header->n_segment_tab; i++) { /* Segments[s->selector >> __AHSHIFT].owner = auto_data_sel; */ if (selectors[i] == auto_data_sel) LocalInit( auto_data_sel, saved_old_length, - 0x10000 - 2 - saved_old_length + 0x10000 - 2 - ne_header->stack_length ); #if 0 HEAP_LocalInit(auto_data_sel, @@ -610,7 +554,6 @@ unsigned short *CreateSelectors(struct w_files * wpnt) void FixupFunctionPrologs(struct w_files * wpnt) { - struct ne_header_s *ne_header = wpnt->ne->ne_header; union lookup entry_tab_pointer; struct entry_tab_header_s *eth; struct entry_tab_movable_s *etm; @@ -618,9 +561,9 @@ FixupFunctionPrologs(struct w_files * wpnt) unsigned char *fixup_ptr; int i; - if (!(ne_header->format_flags & 0x0001)) +/* if (!(ne_header->format_flags & NE_FFLAGS_SINGLEDATA)) return; - +*/ entry_tab_pointer.cpnt = wpnt->ne->lookup_table; /* * Let's walk through the table and fixup prologs as we go. @@ -645,26 +588,42 @@ FixupFunctionPrologs(struct w_files * wpnt) if (eth->seg_number >= 0xfe) { etm = entry_tab_pointer.etm++; + /* FIXME: Does anyone know the exact meaning of these flags? */ + /* 0x0001 seems to mean: Fix up the function prolog */ + dprintf_selector(stddeb,"ETM_Flags: %04x ",etm->flags); + if (!(etm->flags & 0x0001)) continue; fixup_ptr = (char *)GET_SEL_BASE(wpnt->ne->selector_table[etm->seg_number-1]) + etm->offset; } else { etf = entry_tab_pointer.etf++; + dprintf_selector(stddeb,"ETF_Flags: %04x ",etf->flags); + if (!(etf->flags & 0x0001)) continue; fixup_ptr = (char *)GET_SEL_BASE(wpnt->ne->selector_table[eth->seg_number-1]) + (int) etf->offset[0] + ((int) etf->offset[1] << 8); } + dprintf_selector(stddeb,"Signature: %02x %02x %02x,ff %x\n", + fixup_ptr[0],fixup_ptr[1],fixup_ptr[2], + wpnt->ne->ne_header->format_flags); /* Verify the signature */ if (((fixup_ptr[0] == 0x1e && fixup_ptr[1] == 0x58) || (fixup_ptr[0] == 0x8c && fixup_ptr[1] == 0xd8)) && fixup_ptr[2] == 0x90) { + if (wpnt->ne->ne_header->format_flags & NE_FFLAGS_SINGLEDATA) { + fixup_ptr[0] = 0xb8; /* MOV AX, */ fixup_ptr[1] = wpnt->hinstance; fixup_ptr[2] = (wpnt->hinstance >> 8); - } + } else { + fixup_ptr[0] = 0x90; /* non-library: NOPs */ + fixup_ptr[1] = 0x90; + fixup_ptr[2] = 0x90; + } + } } } } diff --git a/loader/signal.c b/loader/signal.c index 5b348392e89..c6943de5f89 100644 --- a/loader/signal.c +++ b/loader/signal.c @@ -287,38 +287,4 @@ void init_wine_signals(void) #endif } -static sigjmp_buf segv_jmpbuf; - -static void -segv_handler() -{ - siglongjmp(segv_jmpbuf, 1); -} - -int -test_memory( char *p, int write ) -{ - int ret = FALSE; - struct sigaction new_act; - struct sigaction old_act; - - memset(&new_act, 0, sizeof new_act); - new_act.sa_handler = segv_handler; - if (sigsetjmp( segv_jmpbuf, 1 ) == 0) { - char c = 100; - if (sigaction(SIGSEGV, &new_act, &old_act) < 0) - perror("sigaction"); - c = *p; - if (write) - *p = c; - ret = TRUE; - } -#ifdef linux - wine_sigaction(SIGSEGV, &old_act, NULL); -#else - sigaction(SIGSEGV, &old_act, NULL); -#endif - return ret; -} - #endif /* ifndef WINELIB */ diff --git a/loader/task.c b/loader/task.c index de42cc3ebf6..93c14a55c8c 100644 --- a/loader/task.c +++ b/loader/task.c @@ -9,7 +9,7 @@ static char Copyright[] = "Copyright Martin Ayotte, 1994"; #include <sys/types.h> #include <unistd.h> #include "windows.h" -#include "if1632.h" +#include "callback.h" #include "task.h" #include "stddebug.h" #include "debug.h" @@ -102,11 +102,7 @@ BOOL EnumTaskWindows(HANDLE hTask, FARPROC lpEnumFunc, LONG lParam) while ((hWnd = *(wptr++)) != 0) { if (++count >= MAXWIN_PER_TASK) return FALSE; dprintf_task(stddeb,"EnumTaskWindows // hWnd=%04X count=%d !\n", hWnd, count); -#ifdef WINELIB - bRet = (*lpEnumFunc)(hWnd, lParam); -#else - bRet = CallBack16(lpEnumFunc, 2, 0, (int)hWnd, 2, (int)lParam); -#endif + bRet = CallEnumTaskWndProc( lpEnumFunc, hWnd, lParam ); if (bRet == 0) break; } return TRUE; diff --git a/memory/global.c b/memory/global.c index f62f2fd0df2..2067ad0da6a 100644 --- a/memory/global.c +++ b/memory/global.c @@ -13,20 +13,62 @@ #include "stddebug.h" #include "debug.h" + /* Global arena block */ +typedef struct +{ + DWORD base; /* Base address */ + DWORD size; /* Size in bytes */ + HGLOBAL handle; /* Handle for this block */ + HGLOBAL hOwner; /* Owner of this block */ + BYTE lockCount; /* Count of GlobalFix() calls */ + BYTE pageLockCount; /* Count of GlobalPageLock() calls */ + BYTE flags; /* Allocation flags */ + BYTE selCount; /* Number of selectors allocated for this block */ +} GLOBALARENA; + + /* Flags definitions */ +#define GA_DGROUP 0x04 +#define GA_DISCARDABLE 0x08 + + /* Arena array */ +static GLOBALARENA *pGlobalArena = NULL; +static int globalArenaSize = 0; + #define GLOBAL_MAX_ALLOC_SIZE 0x00ff0000 /* Largest allocation is 16M - 64K */ -#define HGLOBAL_TO_SEL(handle) \ - ((handle == (HGLOBAL)-1) ? CURRENT_DS : GlobalHandleToSel(handle)) +#define GET_ARENA_PTR(handle) (pGlobalArena + ((handle) >> __AHSHIFT)) /*********************************************************************** - * GlobalAlloc (KERNEL.15) + * GLOBAL_GetArena + * + * Return the arena for a given selector, growing the arena array if needed. */ -HGLOBAL GlobalAlloc( WORD flags, DWORD size ) +static GLOBALARENA *GLOBAL_GetArena( WORD sel, WORD selcount ) { - WORD sel; - void *ptr; + if (((sel >> __AHSHIFT) + selcount) >= globalArenaSize) + { + GLOBALARENA *pNewArena = realloc( pGlobalArena, + (globalArenaSize + 256) * sizeof(GLOBALARENA) ); + if (!pNewArena) return 0; + pGlobalArena = pNewArena; + memset( pGlobalArena + globalArenaSize, 0, 256 * sizeof(GLOBALARENA) ); + globalArenaSize += 256; + } + return pGlobalArena + (sel >> __AHSHIFT); +} - dprintf_global( stddeb, "GlobalAlloc: %ld flags=%04x\n", size, flags ); + +/*********************************************************************** + * GLOBAL_Alloc + * + * Implementation of GlobalAlloc() + */ +HGLOBAL GLOBAL_Alloc( WORD flags, DWORD size, HGLOBAL hOwner, + BOOL isCode, BOOL isReadOnly ) +{ + WORD sel, selcount; + void *ptr; + GLOBALARENA *pArena; /* Fixup the size */ @@ -41,20 +83,50 @@ HGLOBAL GlobalAlloc( WORD flags, DWORD size ) /* Allocate the selector(s) */ - sel = SELECTOR_AllocBlock( ptr, size, SEGMENT_DATA, 0, 0 ); + sel = SELECTOR_AllocBlock( ptr, size, isCode ? SEGMENT_CODE : SEGMENT_DATA, + 0, isReadOnly ); if (!sel) { free( ptr ); return 0; } + selcount = (size + 0xffff) / 0x10000; + + if (!(pArena = GLOBAL_GetArena( sel, selcount ))) + { + free( ptr ); + FreeSelector( sel ); + return 0; + } + + /* Fill the arena block */ + + pArena->base = (DWORD)ptr; + pArena->size = GET_SEL_LIMIT(sel) + 1; + pArena->handle = (flags & GMEM_MOVEABLE) ? sel - 1 : sel; + pArena->hOwner = hOwner; + pArena->lockCount = 0; + pArena->pageLockCount = 0; + pArena->flags = flags & 0xff; + if (flags & GMEM_DISCARDABLE) pArena->flags |= GA_DISCARDABLE; + if (!isCode) pArena->flags |= GA_DGROUP; + pArena->selCount = selcount; + if (selcount > 1) /* clear the next arena blocks */ + memset( pArena + 1, 0, (selcount - 1) * sizeof(GLOBALARENA) ); if (flags & GMEM_ZEROINIT) memset( ptr, 0, size ); + return pArena->handle; +} + - /* Return the handle */ - /* If allocating a GMEM_FIXED block, the handle is the selector. */ - /* Otherwise, the handle is the selector-1 (don't ask me why :-) */ - if (flags & GMEM_MOVEABLE) return sel - 1; - else return sel; +/*********************************************************************** + * GlobalAlloc (KERNEL.15) + */ +HGLOBAL GlobalAlloc( WORD flags, DWORD size ) +{ + dprintf_global( stddeb, "GlobalAlloc: %ld flags=%04x\n", size, flags ); + + return GLOBAL_Alloc( flags, size, GetCurrentPDB(), 0, 0 ); } @@ -63,12 +135,18 @@ HGLOBAL GlobalAlloc( WORD flags, DWORD size ) */ HGLOBAL GlobalReAlloc( HGLOBAL handle, DWORD size, WORD flags ) { - WORD sel; + WORD sel, selcount; DWORD oldsize; void *ptr; + GLOBALARENA *pArena, *pNewArena; dprintf_global( stddeb, "GlobalReAlloc: %04x %ld flags=%04x\n", handle, size, flags ); + if (!handle) + { + printf( "GlobalReAlloc: handle is 0.\n" ); + return 0; + } /* Fixup the size */ @@ -78,15 +156,17 @@ HGLOBAL GlobalReAlloc( HGLOBAL handle, DWORD size, WORD flags ) /* Reallocate the linear memory */ + pArena = GET_ARENA_PTR( handle ); sel = GlobalHandleToSel( handle ); - ptr = (void *)GET_SEL_BASE( sel ); - oldsize = GlobalSize( handle ); + ptr = (void *)pArena->base; + oldsize = pArena->size; if (size == oldsize) return handle; /* Nothing to do */ ptr = realloc( ptr, size ); if (!ptr) { FreeSelector( sel ); + memset( pArena, 0, sizeof(GLOBALARENA) ); return 0; } @@ -96,17 +176,39 @@ HGLOBAL GlobalReAlloc( HGLOBAL handle, DWORD size, WORD flags ) if (!sel) { free( ptr ); + memset( pArena, 0, sizeof(GLOBALARENA) ); return 0; } + selcount = (size + 0xffff) / 0x10000; - if ((oldsize < size) && (flags & GMEM_ZEROINIT)) - memset( (char *)ptr + oldsize, 0, size - oldsize ); + if (!(pNewArena = GLOBAL_GetArena( sel, selcount ))) + { + free( ptr ); + FreeSelector( sel ); + return 0; + } + + /* Fill the new arena block */ - if (sel == GlobalHandleToSel( handle )) - return handle; /* Selector didn't change */ + if (pNewArena != pArena) memcpy( pNewArena, pArena, sizeof(GLOBALARENA) ); + pNewArena->base = (DWORD)ptr; + pNewArena->size = GET_SEL_LIMIT(sel) + 1; + pNewArena->selCount = selcount; + if (flags & GMEM_MODIFY) + { + /* Change the flags, leaving GA_DGROUP alone */ + pNewArena->flags = (pNewArena->flags & GA_DGROUP) | + (flags & ~GA_DGROUP); + if (flags & GMEM_DISCARDABLE) pNewArena->flags |= GA_DISCARDABLE; + } + pNewArena->handle = (pNewArena->flags & GMEM_MOVEABLE) ? sel - 1 : sel; + + if (selcount > 1) /* clear the next arena blocks */ + memset( pNewArena + 1, 0, (selcount - 1) * sizeof(GLOBALARENA) ); - if (flags & GMEM_MOVEABLE) return sel - 1; - else return sel; + if ((oldsize < size) && (flags & GMEM_ZEROINIT)) + memset( (char *)ptr + oldsize, 0, size - oldsize ); + return pNewArena->handle; } @@ -119,10 +221,12 @@ HGLOBAL GlobalFree( HGLOBAL handle ) void *ptr; dprintf_global( stddeb, "GlobalFree: %04x\n", handle ); + if (!handle) return 0; sel = GlobalHandleToSel( handle ); ptr = (void *)GET_SEL_BASE(sel); if (FreeSelector( sel )) return handle; /* failed */ free( ptr ); + memset( GET_ARENA_PTR(handle), 0, sizeof(GLOBALARENA) ); return 0; } @@ -136,7 +240,7 @@ SEGPTR WIN16_GlobalLock( HGLOBAL handle ) { dprintf_global( stddeb, "WIN16_GlobalLock: %04x\n", handle ); if (!handle) return 0; - return (SEGPTR)MAKELONG( 0, HGLOBAL_TO_SEL(handle) ); + return (SEGPTR)MAKELONG( 0, GlobalHandleToSel(handle) ); } @@ -149,7 +253,7 @@ LPSTR GlobalLock( HGLOBAL handle ) { dprintf_global( stddeb, "GlobalLock: %04x\n", handle ); if (!handle) return 0; - return (LPSTR)GET_SEL_BASE( HGLOBAL_TO_SEL(handle) ); + return (LPSTR)GET_ARENA_PTR(handle)->base; } @@ -170,7 +274,7 @@ DWORD GlobalSize( HGLOBAL handle ) { dprintf_global( stddeb, "GlobalSize: %04x\n", handle ); if (!handle) return 0; - return GET_SEL_LIMIT( HGLOBAL_TO_SEL(handle) ) + 1; + return GET_ARENA_PTR(handle)->size; } @@ -179,11 +283,8 @@ DWORD GlobalSize( HGLOBAL handle ) */ DWORD GlobalHandle( WORD sel ) { - /* FIXME: what about GMEM_FIXED blocks? */ - WORD handle = sel & ~1; - dprintf_global( stddeb, "GlobalHandle(%04x): returning %08lx\n", - sel, MAKELONG( handle, sel ) ); - return MAKELONG( handle, sel ); + dprintf_global( stddeb, "GlobalHandle: %04x\n", sel ); + return MAKELONG( GET_ARENA_PTR(sel)->handle, sel ); } @@ -192,8 +293,12 @@ DWORD GlobalHandle( WORD sel ) */ WORD GlobalFlags( HGLOBAL handle ) { + GLOBALARENA *pArena; + dprintf_global( stddeb, "GlobalFlags: %04x\n", handle ); - return 0; /* lock count is always 0 */ + pArena = GET_ARENA_PTR(handle); + return pArena->lockCount | + ((pArena->flags & GA_DISCARDABLE) ? GMEM_DISCARDABLE : 0); } @@ -204,6 +309,7 @@ HGLOBAL LockSegment( HGLOBAL handle ) { dprintf_global( stddeb, "LockSegment: %04x\n", handle ); if (handle == (HGLOBAL)-1) handle = CURRENT_DS; + GET_ARENA_PTR(handle)->lockCount++; return handle; } @@ -214,6 +320,8 @@ HGLOBAL LockSegment( HGLOBAL handle ) void UnlockSegment( HGLOBAL handle ) { dprintf_global( stddeb, "UnlockSegment: %04x\n", handle ); + if (handle == (HGLOBAL)-1) handle = CURRENT_DS; + GET_ARENA_PTR(handle)->lockCount--; /* FIXME: this ought to return the lock count in CX (go figure...) */ } @@ -230,9 +338,9 @@ DWORD GlobalCompact( DWORD desired ) /*********************************************************************** * GlobalWire (KERNEL.111) */ -LPSTR GlobalWire( HGLOBAL handle ) +SEGPTR GlobalWire( HGLOBAL handle ) { - return GlobalLock( handle ); + return WIN16_GlobalLock( handle ); } @@ -312,8 +420,7 @@ DWORD GetFreeSpace( UINT wFlags ) WORD GlobalPageLock( HGLOBAL handle ) { dprintf_global( stddeb, "GlobalPageLock: %04x\n", handle ); - /* Nothing to do, as we can't page-lock a block (and we don't want to) */ - return 1; /* lock count */ + return ++(GET_ARENA_PTR(handle)->pageLockCount); } @@ -323,7 +430,7 @@ WORD GlobalPageLock( HGLOBAL handle ) WORD GlobalPageUnlock( HGLOBAL handle ) { dprintf_global( stddeb, "GlobalPageUnlock: %04x\n", handle ); - return 0; /* lock count */ + return --(GET_ARENA_PTR(handle)->pageLockCount); } @@ -333,7 +440,7 @@ WORD GlobalPageUnlock( HGLOBAL handle ) void GlobalFix( HGLOBAL handle ) { dprintf_global( stddeb, "GlobalFix: %04x\n", handle ); - /* Nothing to do, as all the blocks are fixed in linear memory anyway */ + GET_ARENA_PTR(handle)->lockCount++; } @@ -343,7 +450,25 @@ void GlobalFix( HGLOBAL handle ) void GlobalUnfix( HGLOBAL handle ) { dprintf_global( stddeb, "GlobalUnfix: %04x\n", handle ); - /* This one is even more complicated that GlobalFix() :-) */ + GET_ARENA_PTR(handle)->lockCount--; +} + + +/*********************************************************************** + * FarSetOwner (KERNEL.403) + */ +void FarSetOwner( HANDLE handle, WORD hOwner ) +{ + GET_ARENA_PTR(handle)->hOwner = hOwner; +} + + +/*********************************************************************** + * FarGetOwner (KERNEL.404) + */ +WORD FarGetOwner( HANDLE handle ) +{ + return GET_ARENA_PTR(handle)->hOwner; } @@ -353,21 +478,98 @@ void GlobalUnfix( HGLOBAL handle ) WORD GlobalHandleToSel( HGLOBAL handle ) { dprintf_toolhelp( stddeb, "GlobalHandleToSel: %04x\n", handle ); + if (!handle) return 0; if (!(handle & 7)) { fprintf( stderr, "Program attempted invalid selector conversion\n" ); return handle - 1; } - return handle | 1; + return handle | 7; } -/********************************************************************** - * MemManInfo (toolhelp.72) +/*********************************************************************** + * GlobalFirst (TOOLHELP.51) */ -/* -BOOL MemManInfo(LPMEMMANINFO lpmmi) +BOOL GlobalFirst( GLOBALENTRY *pGlobal, WORD wFlags ) +{ + if (wFlags == GLOBAL_LRU) return FALSE; + pGlobal->dwNext = 0; + return GlobalNext( pGlobal, wFlags ); +} + + +/*********************************************************************** + * GlobalNext (TOOLHELP.52) + */ +BOOL GlobalNext( GLOBALENTRY *pGlobal, WORD wFlags) +{ + GLOBALARENA *pArena; + + pArena = pGlobalArena + pGlobal->dwNext; + if (wFlags == GLOBAL_FREE) /* only free blocks */ + { + int i; + for (i = pGlobal->dwNext; i < globalArenaSize; i++, pArena++) + if (pArena->size == 0) break; /* block is free */ + if (i >= globalArenaSize) return FALSE; + pGlobal->dwNext = i; + } + + pGlobal->dwAddress = pArena->base; + pGlobal->dwBlockSize = pArena->size; + pGlobal->hBlock = pArena->handle; + pGlobal->wcLock = pArena->lockCount; + pGlobal->wcPageLock = pArena->pageLockCount; + pGlobal->wFlags = (GetCurrentPDB() == pArena->hOwner); + pGlobal->wHeapPresent = FALSE; + pGlobal->hOwner = pArena->hOwner; + pGlobal->wType = GT_UNKNOWN; + pGlobal->wData = 0; + pGlobal->dwNext++; + return TRUE; +} + + +/*********************************************************************** + * GlobalInfo (TOOLHELP.53) + */ +BOOL GlobalInfo( GLOBALINFO *pInfo ) +{ + int i; + GLOBALARENA *pArena; + + pInfo->wcItems = globalArenaSize; + pInfo->wcItemsFree = 0; + pInfo->wcItemsLRU = 0; + for (i = 0, pArena = pGlobalArena; i < globalArenaSize; i++, pArena++) + if (pArena->size == 0) pInfo->wcItemsFree++; + return TRUE; +} + + +/*********************************************************************** + * GlobalEntryHandle (TOOLHELP.54) + */ +BOOL GlobalEntryHandle( GLOBALENTRY *pGlobal, HGLOBAL hItem ) +{ + return FALSE; +} + + +/*********************************************************************** + * GlobalEntryModule (TOOLHELP.55) + */ +BOOL GlobalEntryModule( GLOBALENTRY *pGlobal, HMODULE hModule, WORD wSeg ) +{ + return FALSE; +} + + +/*********************************************************************** + * MemManInfo (TOOLHELP.72) + */ +BOOL MemManInfo( MEMMANINFO *pInfo ) { - return 1; + return TRUE; } -*/ diff --git a/memory/local.c b/memory/local.c index 5adf693b6ad..8c9a82933c9 100644 --- a/memory/local.c +++ b/memory/local.c @@ -285,11 +285,19 @@ HLOCAL LocalInit( WORD selector, WORD start, WORD end ) /* - large free block (FREE) */ /* - last arena (FREE) */ - /* FIXME: What should be done if there's already */ - /* a local heap in this segment? */ dprintf_local(stddeb, "LocalInit: %04x %04x-%04x\n", selector, start, end); if (!selector) selector = CURRENT_DS; ptr = PTR_SEG_OFF_TO_LIN( selector, 0 ); + pHeapInfo = LOCAL_GetHeap(selector); + /* If there's already a local heap in this segment, */ + /* we simply return TRUE. Helps some programs, but */ + /* does not seem to be 100% correct yet (there are */ + /* still some "heap corrupted" messages in LocalAlloc */ + if (pHeapInfo) { + dprintf_local(stddeb,"LocalInit: Heap %04x initialized twice.\n",selector); + if (debugging_local) LOCAL_PrintHeap(selector); + return TRUE; + } start = LALIGN( max( start, sizeof(INSTANCEDATA) ) ); heapInfoArena = LALIGN(start + sizeof(LOCALARENA) ); freeArena = LALIGN( heapInfoArena + ARENA_HEADER_SIZE @@ -368,14 +376,20 @@ HLOCAL LOCAL_Alloc( WORD ds, WORD flags, WORD size ) /* Find a suitable free block */ - if (!(pInfo = LOCAL_GetHeap( ds ))) return 0; + if (!(pInfo = LOCAL_GetHeap( ds ))) { + LOCAL_PrintHeap(ds); + return 0; + } size += ARENA_HEADER_SIZE; size = LALIGN( max( size, sizeof(LOCALARENA) ) ); arena = pInfo->first; pArena = ARENA_PTR( ptr, arena ); for (;;) { - if (arena == pArena->free_next) return 0; /* not found */ + if (arena == pArena->free_next) { + LOCAL_PrintHeap(ds); + return 0; /* not found */ + } arena = pArena->free_next; pArena = ARENA_PTR( ptr, arena ); if (pArena->size >= size) break; @@ -635,6 +649,7 @@ WORD LocalShrink( HLOCAL handle, WORD newsize ) */ DWORD GetHeapSpaces( HMODULE module ) { + return MAKELONG( 0x7fff, 0xffff ); } diff --git a/memory/selector.c b/memory/selector.c index c9dc5ae7c2d..60556c21485 100644 --- a/memory/selector.c +++ b/memory/selector.c @@ -4,22 +4,16 @@ * Copyright 1995 Alexandre Julliard */ +#include <string.h> #include "windows.h" #include "ldt.h" +#include "selectors.h" #include "stddebug.h" #include "debug.h" ldt_copy_entry ldt_copy[LDT_SIZE] = { {0,0}, }; -#define FIRST_LDT_ENTRY_TO_ALLOC 10 - - -/*********************************************************************** - * SELECTOR_Init - */ -void SELECTOR_Init() -{ -} +#define FIRST_LDT_ENTRY_TO_ALLOC 4 /*********************************************************************** @@ -74,7 +68,7 @@ WORD FreeSelector( WORD sel ) dprintf_selector( stddeb, "FreeSelector(%04x)\n", sel ); if (IS_SELECTOR_FREE(sel)) return sel; /* error */ count = (GET_SEL_LIMIT(sel) >> 16) + 1; - entry.base = entry.limit = 0; /* clear the LDT entries */ + memset( &entry, 0, sizeof(entry) ); /* clear the LDT entries */ for (i = 0; i < count; i++) LDT_SetEntry( SELECTOR_TO_ENTRY(sel) + i, &entry ); return 0; @@ -129,7 +123,7 @@ static WORD SELECTOR_ReallocArray( WORD sel, WORD newcount ) { /* Check if the next selectors are free */ for (i = oldcount; i < newcount; i++) - if (!IS_SELECTOR_FREE(sel)) break; + if (!IS_SELECTOR_FREE(sel+i)) break; if (i < newcount) { FreeSelector( sel ); @@ -138,7 +132,7 @@ static WORD SELECTOR_ReallocArray( WORD sel, WORD newcount ) } else if (oldcount > newcount) /* We need to remove selectors */ { - entry.base = entry.limit = 0; /* clear the LDT entries */ + memset( &entry, 0, sizeof(entry) ); /* clear the LDT entries */ for (i = oldcount; i < newcount; i++) LDT_SetEntry( SELECTOR_TO_ENTRY(sel) + i, &entry ); } diff --git a/misc/Imakefile b/misc/Imakefile index a5f54d2c5cf..c2b18115a30 100644 --- a/misc/Imakefile +++ b/misc/Imakefile @@ -7,6 +7,7 @@ SRCS = \ clipboard.c \ comm.c \ commdlg.c \ + compobj.c \ dos_fs.c \ driver.c \ exec.c \ diff --git a/misc/commdlg.c b/misc/commdlg.c index 1b6cd824ecd..31ad412efeb 100644 --- a/misc/commdlg.c +++ b/misc/commdlg.c @@ -19,6 +19,7 @@ #include "library.h" #include "commdlg.h" #include "dlgs.h" +#include "selectors.h" #define OPENFILEDLG2 11 #define SAVEFILEDLG2 12 @@ -97,7 +98,8 @@ BOOL GetOpenFileName(LPOPENFILENAME lpofn) printf("GetOpenFileName // apres LoadResource hDlgTmpl=%04X!\n", hDlgTmpl); wndPtr = WIN_FindWndPtr(lpofn->hwndOwner); bRet = DialogBoxIndirectParam(wndPtr->hInstance, hDlgTmpl, - lpofn->hwndOwner, (WNDPROC)FileOpenDlgProc, (DWORD)lpofn); + lpofn->hwndOwner, GetWndProcEntry16("FileOpenDlgProc"), + (DWORD)lpofn); /* strcpy(lpofn->lpstrFile, "SETUP.TXT"); */ /* strcpy(lpofn->lpstrFileTitle, "SETUP.TXT");*/ @@ -156,7 +158,8 @@ BOOL GetSaveFileName(LPOPENFILENAME lpofn) } wndPtr = WIN_FindWndPtr(lpofn->hwndOwner); bRet = DialogBoxIndirectParam(wndPtr->hInstance, hDlgTmpl, - lpofn->hwndOwner, (WNDPROC)FileSaveDlgProc, (DWORD)lpofn); + lpofn->hwndOwner, GetWndProcEntry16("FileSaveDlgProc"), + (DWORD)lpofn); printf("GetSaveFileName // return lpstrFile='%s' !\n", PTR_SEG_TO_LIN(lpofn->lpstrFile)); return bRet; } @@ -175,7 +178,8 @@ BOOL ChooseColor(LPCHOOSECOLOR lpChCol) hDlgTmpl = LoadResource(hSysRes, hResInfo); wndPtr = WIN_FindWndPtr(lpChCol->hwndOwner); bRet = DialogBoxIndirectParam(wndPtr->hInstance, hDlgTmpl, - lpChCol->hwndOwner, (WNDPROC)ColorDlgProc, (DWORD)lpChCol); + lpChCol->hwndOwner, GetWndProcEntry16("ColorDlgProc"), + (DWORD)lpChCol); return bRet; } @@ -909,7 +913,8 @@ BOOL FindText(LPFINDREPLACE lpFind) } wndPtr = WIN_FindWndPtr(lpFind->hwndOwner); bRet = DialogBoxIndirectParam(wndPtr->hInstance, hDlgTmpl, - lpFind->hwndOwner, (WNDPROC)FindTextDlgProc, (DWORD)lpFind); + lpFind->hwndOwner, GetWndProcEntry16("FindTextDlgProc"), + (DWORD)lpFind); return bRet; } @@ -935,7 +940,8 @@ BOOL ReplaceText(LPFINDREPLACE lpFind) } wndPtr = WIN_FindWndPtr(lpFind->hwndOwner); bRet = DialogBoxIndirectParam(wndPtr->hInstance, hDlgTmpl, - lpFind->hwndOwner, (WNDPROC)ReplaceTextDlgProc, (DWORD)lpFind); + lpFind->hwndOwner, GetWndProcEntry16("ReplaceTextDlgProc"), + (DWORD)lpFind); return bRet; } @@ -1018,10 +1024,12 @@ BOOL PrintDlg(LPPRINTDLG lpPrint) wndPtr = WIN_FindWndPtr(lpPrint->hwndOwner); if (lpPrint->Flags & PD_PRINTSETUP) bRet = DialogBoxIndirectParam(wndPtr->hInstance, hDlgTmpl, - lpPrint->hwndOwner, (WNDPROC)PrintSetupDlgProc, (DWORD)lpPrint); + lpPrint->hwndOwner, GetWndProcEntry16("PrintSetupDlgProc"), + (DWORD)lpPrint); else bRet = DialogBoxIndirectParam(wndPtr->hInstance, hDlgTmpl, - lpPrint->hwndOwner, (WNDPROC)PrintDlgProc, (DWORD)lpPrint); + lpPrint->hwndOwner, GetWndProcEntry16("PrintDlgProc"), + (DWORD)lpPrint); return bRet; } diff --git a/misc/compobj.c b/misc/compobj.c new file mode 100644 index 00000000000..c527b0fc241 --- /dev/null +++ b/misc/compobj.c @@ -0,0 +1,25 @@ +/* + * COMPOBJ library + * + * Copyright 1995 Martin von Loewis + */ + +/* At the moment, these are only empty stubs. + */ + +#include "windows.h" +#include "compobj.h" +#include "ole.h" +#include "stddebug.h" +#include "debug.h" + +/*********************************************************************** + * CoDisconnectObject + */ +OLESTATUS WINAPI CoDisconnectObject( + LPUNKNOWN lpUnk, + DWORD reserved) +{ + dprintf_ole(stdnimp,"CoDisconnectObject:%x %x\n",lpUnk,reserved); + return OLE_OK; +} diff --git a/misc/dos_fs.c b/misc/dos_fs.c index f2752561afc..dfc69ddbc82 100644 --- a/misc/dos_fs.c +++ b/misc/dos_fs.c @@ -334,38 +334,24 @@ int DOS_ValidDirectory(char *name) ".."'s in names like "/usr/bin/../lib/test" */ void DOS_SimplifyPath(char *name) { - char *p = name, *q = name, *l = NULL; + char *l,*p; BOOL changed; - start: - p = name; - q = name; - while( *p ) { - *q++ = *p++; - if( ( *p == '/' ) && ( *(p-1) == '/' ) ) - p++; - } - *q = 0; - - p = name; - q = name; - changed = FALSE; - while( *p ) { - if( (!changed) &&( *p == '/' ) && ( *(p+1) == '.' ) && ( *(p+2) == '.' ) ) { - if( l ) { - q = l; - p += 3; - changed = TRUE; - continue; - } + dprintf_dosfs(stddeb,"SimplifyPath: Before %s\n",name); + do { + changed = FALSE; + while ((l = strstr(name,"//"))) { + strcpy(l,l+1); changed = TRUE; + } + while ((l = strstr(name,"/../"))) { + *l = 0; + p = strrchr(name,'/'); + if (p == NULL) p = name; + strcpy(p,l+3); + changed = TRUE; } - else if( *p == '/' ) - l = q; - *q++ = *p++; - } - *q = 0; - if( changed) - goto start; + } while (changed); + dprintf_dosfs(stddeb,"SimplifyPath: After %s\n",name); } @@ -887,14 +873,6 @@ struct dosdirent *DOS_opendir(char *dosdirname) char *unixdirname; char temp[256]; - for (x=0; x != MAX_OPEN_DIRS && DosDirs[x].inuse; x++) - ; - - if (x == MAX_OPEN_DIRS) { - fprintf( stderr, "DOS_opendir(): Too many open directories\n"); - return NULL; - } - if ((unixdirname = DOS_GetUnixFileName(dosdirname)) == NULL) return NULL; @@ -905,13 +883,23 @@ struct dosdirent *DOS_opendir(char *dosdirname) if (temp[y] == '/') { temp[y++] = '\0'; - strcpy(DosDirs[x].filemask, temp +y); - ToDos(DosDirs[x].filemask); + unixdirname += y; break; } } - dprintf_dosfs(stddeb,"DOS_opendir: %s -> %s\n", unixdirname, temp); + for (x=0; x <= MAX_OPEN_DIRS; x++) { + if (x == MAX_OPEN_DIRS) { + fprintf( stderr, "DOS_opendir(): Too many open directories\n"); + return NULL; + } + if (!DosDirs[x].inuse) break; + if (strcmp(DosDirs[x].unixpath,temp) == 0) break; + } + + strcpy(DosDirs[x].filemask, unixdirname); + ToDos(DosDirs[x].filemask); + dprintf_dosfs(stddeb,"DOS_opendir: %s / %s\n", unixdirname, temp); DosDirs[x].inuse = 1; strcpy(DosDirs[x].unixpath, temp); diff --git a/misc/exec.c b/misc/exec.c index 7d53906aa73..771fba294c1 100644 --- a/misc/exec.c +++ b/misc/exec.c @@ -85,7 +85,9 @@ void InitializeLoadedNewDLLs(HINSTANCE hInst) dprintf_exec(stddeb, "Initializing %s, cs:ip %04x:%04x, ds %04x\n", wpnt->name, cs_reg, ip_reg, ds_reg); - rv = CallTo16(cs_reg << 16 | ip_reg, ds_reg); + rv = CallTo16_regs_( (FARPROC)(cs_reg << 16 | ip_reg), ds_reg, + 0 /*es*/, 0 /*ax*/, 0 /*bx*/, 0 /*cx*/, + 0 /*dx*/, 0 /*si*/, wpnt->hinstance /*di*/ ); dprintf_exec(stddeb,"rv = %x\n", rv); } } @@ -123,7 +125,9 @@ void StartNewTask(HINSTANCE hInst) sp_reg = wpnt->ne->ne_header->sp; dprintf_exec(stddeb,"StartNewTask() before CallToInit16() !\n"); +/* rv = CallToInit16(cs_reg << 16 | ip_reg, ss_reg << 16 | sp_reg, ds_reg); +*/ dprintf_exec(stddeb,"rv = %x\n", rv); } diff --git a/misc/file.c b/misc/file.c index 2f3aa2f4f05..c71673a409e 100644 --- a/misc/file.c +++ b/misc/file.c @@ -23,11 +23,8 @@ #include <sys/stat.h> #include <string.h> #include "dos_fs.h" -#include "regfunc.h" #include "windows.h" -#include "wine.h" #include "msdos.h" -#include "registers.h" #include "options.h" #include "stddebug.h" #include "debug.h" @@ -118,11 +115,6 @@ INT OpenFile (LPSTR lpFileName, LPOFSTRUCT ofs, WORD wStyle) #ifdef WINELIB dprintf_file(stdnimp, "OpenFile: not implemented\n"); #else -#ifndef PROCEMU - struct sigcontext_struct ccontext; - /* To make macros like EAX happy */ - struct sigcontext_struct *context=&ccontext; -#endif char filename[MAX_PATH+1]; int action; struct stat s; diff --git a/misc/main.c b/misc/main.c index b672f44d491..4da1c087bb4 100644 --- a/misc/main.c +++ b/misc/main.c @@ -28,8 +28,9 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1994"; #include "desktop.h" #include "prototypes.h" #include "texts.h" -#include "dlls.h" #include "library.h" +#include "dlls.h" +#include "if1632.h" #define DEBUG_DEFINE_VARIABLES #include "stddebug.h" #include "debug.h" @@ -573,6 +574,7 @@ int main( int argc, char *argv[] ) if (Options.desktopGeometry) MAIN_CreateDesktop( argc, argv ); else rootWindow = DefaultRootWindow( display ); + RELAY_Init(); MAIN_SaveSetup(); DOS_InitFS(); Comm_Init(); @@ -862,17 +864,6 @@ BOOL SwapMouseButton(BOOL fSwap) return 0; /* don't swap */ } -/*********************************************************************** -* ISROMMODULE (KERNEL.323) -*/ -BOOL IsRomModule(HANDLE x) -{ - /* I don't know the prototype, I assume that it returns true - if the dll is located in rom */ - - return FALSE; -} - /*********************************************************************** * FileCDR (KERNEL.130) */ diff --git a/misc/message.c b/misc/message.c index 6daf380ce05..7d23f7e5eba 100644 --- a/misc/message.c +++ b/misc/message.c @@ -19,6 +19,7 @@ static char Copyright[] = "Copyright Martin Ayotte, 1993"; #include "win.h" #include "texts.h" #include "user.h" +#include "selectors.h" #include "stddebug.h" /* #define DEBUG_MSGBOX */ #include "debug.h" @@ -83,7 +84,7 @@ int MessageBox(HWND hWnd, LPSTR str, LPSTR title, WORD type) HINSTANCE hInst; int nRet; - if (title == NULL) + if (title == NULL) title = "Error"; wndPtr = WIN_FindWndPtr(hWnd); if (wndPtr == NULL) { @@ -115,7 +116,7 @@ int MessageBox(HWND hWnd, LPSTR str, LPSTR title, WORD type) lpmb->wType = type; lpmb->ActiveFlg = TRUE; wndClass.style = CS_HREDRAW | CS_VREDRAW ; - wndClass.lpfnWndProc = (WNDPROC)SystemMessageBoxProc; + wndClass.lpfnWndProc = GetWndProcEntry16("SystemMessageBoxProc"); wndClass.cbClsExtra = 0; wndClass.cbWndExtra = 4; wndClass.hInstance = hInst; diff --git a/misc/network.c b/misc/network.c index b662d996801..5c7ab4f60d9 100644 --- a/misc/network.c +++ b/misc/network.c @@ -30,6 +30,124 @@ typedef LPSTR LPNETRESOURCE; +/************************************************************************** + * WNetErrorText [USER.499] + */ +int WNetErrorText(WORD nError,LPSTR lpszText,WORD cbText) +{ + printf("EMPTY STUB !!! WNetErrorText(%x,%p,%x)\n", + nError,lpszText,cbText); + return FALSE; +} + +/************************************************************************** + * WNetOpenJob [USER.501] + */ +int WNetOpenJob(LPSTR szQueue,LPSTR szJobTitle,WORD nCopies,LPWORD pfh) +{ + printf("EMPTY STUB !!! WNetOpenJob('%s','%s',%x,%p)\n", + szQueue,szJobTitle,nCopies,pfh); + return WN_NET_ERROR; +} + +/************************************************************************** + * WNetCloseJob [USER.502] + */ +int WNetCloseJob(WORD fh,LPWORD pidJob,LPSTR szQueue) +{ + printf("EMPTY STUB !!! WNetCloseJob(%x,%p,'%s')\n", + fh,pidJob,szQueue); + return WN_NET_ERROR; +} + +/************************************************************************** + * WNetAbortJob [USER.503] + */ +int WNetAbortJob(LPSTR szQueue,WORD wJobId) +{ + printf("EMPTY STUB !!! WNetAbortJob('%s',%x)\n", + szQueue,wJobId); + return WN_NET_ERROR; +} + +/************************************************************************** + * WNetHoldJob [USER.504] + */ +int WNetHoldJob(LPSTR szQueue,WORD wJobId) +{ + printf("EMPTY STUB !!! WNetHoldJob('%s',%x)\n", + szQueue,wJobId); + return WN_NET_ERROR; +} + +/************************************************************************** + * WNetReleaseJob [USER.505] + */ +int WNetReleaseJob(LPSTR szQueue,WORD wJobId) +{ + printf("EMPTY STUB !!! WNetReleaseJob('%s',%x)\n", + szQueue,wJobId); + return WN_NET_ERROR; +} + +/************************************************************************** + * WNetCancelJob [USER.506] + */ +int WNetCancelJob(LPSTR szQueue,WORD wJobId) +{ + printf("EMPTY STUB !!! WNetCancelJob('%s',%x)\n", + szQueue,wJobId); + return WN_NET_ERROR; +} + +/************************************************************************** + * WNetSetJobCopies [USER.507] + */ +int WNetSetJobCopies(LPSTR szQueue,WORD wJobId,WORD nCopies) +{ + printf("EMPTY STUB !!! WNetSetJobCopies('%s',%x,%x)\n", + szQueue,wJobId,nCopies); + return WN_NET_ERROR; +} + +/************************************************************************** + * WNetWatchQueue [USER.508] + */ +int WNetWatchQueue(HWND hWnd,LPSTR szLocal,LPSTR szUser,WORD nQueue) +{ + printf("EMPTY STUB !!! WNetWatchQueue(%x,'%s','%s',%x)\n", + hWnd,szLocal,szUser,nQueue); + return WN_NET_ERROR; +} + +/************************************************************************** + * WNetUnwatchQueue [USER.509] + */ +int WNetUnwatchQueue(LPSTR szQueue) +{ + printf("EMPTY STUB !!! WNetUnwatchQueue('%s')\n", szQueue); + return WN_NET_ERROR; +} + +/************************************************************************** + * WNetLockQueueData [USER.510] + */ +int WNetLockQueueData(LPSTR szQueue,LPSTR szUser,void *lplpQueueStruct) +{ + printf("EMPTY STUB !!! WNetLockQueueData('%s','%s',%p)\n", + szQueue,szUser,lplpQueueStruct); + return WN_NET_ERROR; +} + +/************************************************************************** + * WNetUnlockQueueData [USER.511] + */ +int WNetUnlockQueueData(LPSTR szQueue) +{ + printf("EMPTY STUB !!! WNetUnlockQueueData('%s')\n",szQueue); + return WN_NET_ERROR; +} + /************************************************************************** * WNetGetConnection [USER.512] */ @@ -49,6 +167,25 @@ int WNetGetCaps(WORD capability) return 0; } +/************************************************************************** + * WNetDeviceMode [USER.514] + */ +int WNetDeviceMode(HWND hWndOwner) +{ + printf("EMPTY STUB !!! WNetDeviceMode(%x)\n",hWndOwner); + return WN_NET_ERROR; +} + +/************************************************************************** + * WNetBrowseDialog [USER.515] + */ +int WNetBrowseDialog(HWND hParent,WORD nType,LPSTR szPath) +{ + printf("EMPTY STUB !!! WNetBrowseDialog(%x,%x,'%s')\n", + hParent,nType,szPath); + return WN_NET_ERROR; +} + /************************************************************************** * WNetGetUser [USER.516] */ @@ -80,6 +217,126 @@ UINT WNetCancelConnection(LPSTR lpName, BOOL bForce) return WN_NET_ERROR; } +/************************************************************************** + * WNetGetError [USER.519] + */ +int WNetGetError(LPWORD nError) +{ + printf("EMPTY STUB !!! WNetGetError(%p)\n",nError); + return WN_NET_ERROR; +} + +/************************************************************************** + * WNetGetErrorText [USER.520] + */ +int WNetGetErrorText(WORD nError, LPSTR lpBuffer, LPWORD nBufferSize) +{ + printf("EMPTY STUB !!! WNetGetErrorText(%x,%p,%p)\n", + nError,lpBuffer,nBufferSize); + return WN_NET_ERROR; +} + +/************************************************************************** + * WNetRestoreConnection [USER.523] + */ +int WNetRestoreConnection(HWND hwndOwner,LPSTR lpszDevice) +{ + printf("EMPTY STUB !!! WNetRestoreConnection(%x,'%s')\n", + hwndOwner,lpszDevice); + return WN_NET_ERROR; +} + +/************************************************************************** + * WNetWriteJob [USER.524] + */ +int WNetWriteJob(WORD hJob,void *lpData,LPWORD lpcbData) +{ + printf("EMPTY STUB !!! WNetWriteJob(%x,%p,%p)\n", + hJob,lpData,lpcbData); + return WN_NET_ERROR; +} + +/************************************************************************** + * WnetConnectDialog [USER.525] + */ +UINT WNetConnectDialog(HWND hWndParent, WORD iType) +{ + printf("EMPTY STUB !!! WNetConnectDialog(%4X, %4X)\n", hWndParent, iType); + return WN_SUCCESS; +} + +/************************************************************************** + * WNetDisconnectDialog [USER.526] + */ +int WNetDisconnectDialog(HWND hwndOwner, WORD iType) +{ + printf("EMPTY STUB !!! WNetDisconnectDialog(%x,%x)\n", + hwndOwner,iType); + return WN_NET_ERROR; +} + +/************************************************************************** + * WnetConnectionDialog [USER.527] + */ +UINT WNetConnectionDialog(HWND hWndParent, WORD iType) +{ + printf("EMPTY STUB !!! WNetConnectionDialog(%4X, %4X)\n", + hWndParent, iType); + return WN_SUCCESS; +} + +/************************************************************************** + * WNetViewQueueDialog [USER.528] + */ +int WNetViewQueueDialog(HWND hwndOwner,LPSTR lpszQueue) +{ + printf("EMPTY STUB !!! WNetViewQueueDialog(%x,'%s')\n", + hwndOwner,lpszQueue); + return WN_NET_ERROR; +} + +/************************************************************************** + * WNetPropertyDialog [USER.529] + */ +int WNetPropertyDialog(HWND hwndParent,WORD iButton, + WORD nPropSel,LPSTR lpszName,WORD nType) +{ + printf("EMPTY STUB !!! WNetPropertyDialog(%x,%x,%x,'%s',%x)\n", + hwndParent,iButton,nPropSel,lpszName,nType); + return WN_NET_ERROR; +} + +/************************************************************************** + * WNetGetDirectoryType [USER.530] + */ +int WNetGetDirectoryType(LPSTR lpName,void *lpType) +{ + printf("EMPTY STUB !!! WNetGetDirectoryType('%s',%p)\n", + lpName,lpType); + return WN_NET_ERROR; +} + +/************************************************************************** + * WNetDirectoryNotify [USER.531] + */ +int WNetDirectoryNotify(HWND hwndOwner,void *lpDir,WORD wOper) +{ + printf("EMPTY STUB !!! WNetDirectoryNotify(%x,%p,%x)\n", + hwndOwner,lpDir,wOper); + return WN_NET_ERROR; +} + +/************************************************************************** + * WNetGetPropertyText [USER.532] + */ +int WNetGetPropertyText(HWND hwndParent,WORD iButton,WORD nPropSel, + LPSTR lpszName,WORD nType) +{ + printf("EMPTY STUB !!! WNetGetPropertyText(%x,%x,%x,'%s',%x)\n", + hwndParent,iButton,nPropSel,lpszName,nType); + return WN_NET_ERROR; +} + /************************************************************************** * WNetAddConnection2 [USER.???] */ diff --git a/misc/property.c b/misc/property.c index e97c3ea7726..75f442f8261 100644 --- a/misc/property.c +++ b/misc/property.c @@ -218,15 +218,8 @@ int EnumProps(HWND hWnd, FARPROC lpEnumFunc) printf("EnumProps // lpProp->PropName='%s' !\n", lpProp->PropName); str = lpProp->PropName; } -#ifdef WINELIB - nRet = (*lpEnumFunc)((HWND)hWnd, (WORD)0, - (LPSTR)str, (HANDLE)lpProp->hData); -#else - nRet = CallBack16(lpEnumFunc, 3, - CALLBACK_SIZE_WORD, (HWND)hWnd, - CALLBACK_SIZE_LONG, (LPSTR)str, - CALLBACK_SIZE_WORD, (HANDLE)lpProp->hData); -#endif + nRet = CallEnumPropProc( lpEnumFunc, hWnd, + (LONG)str, lpProp->hData); if (nRet == 0) break; if (lpProp->lpNextProp == NULL) break; lpProp = lpProp->lpNextProp; diff --git a/misc/shell.c b/misc/shell.c index e5c804331bd..f412887e1f0 100644 --- a/misc/shell.c +++ b/misc/shell.c @@ -9,6 +9,7 @@ #include "library.h" #include "shell.h" #include "neexe.h" +#include "selectors.h" #include "../rc/sysres.h" #include "stddebug.h" /* #define DEBUG_REG */ @@ -81,6 +82,7 @@ LONG RegOpenKey(HKEY hKey, LPCSTR lpSubKey, HKEY FAR *lphKey) dprintf_reg(stddeb,"RegOpenKey // specific key = %08lX !\n", hKey); lpKey = (LPKEYSTRUCT)GlobalLock(hKey); } + if (!*lpSubKey) { *lphKey = hKey; return ERROR_SUCCESS; } while(*lpSubKey) { ptr = strchr(lpSubKey,'\\'); if (!ptr) ptr = lpSubKey + strlen(lpSubKey); @@ -128,6 +130,7 @@ LONG RegCreateKey(HKEY hKey, LPCSTR lpSubKey, HKEY FAR *lphKey) dprintf_reg(stddeb,"RegCreateKey // specific key = %08lX !\n", hKey); lpKey = (LPKEYSTRUCT)GlobalLock(hKey); } + if (!*lpSubKey) { *lphKey = hKey; return ERROR_SUCCESS; } while (*lpSubKey) { dprintf_reg(stddeb, "RegCreateKey: Looking for subkey %s\n", lpSubKey); ptr = strchr(lpSubKey,'\\'); @@ -389,7 +392,7 @@ INT ShellAbout(HWND hWnd, LPCSTR szApp, LPCSTR szOtherStuff, HICON hIcon) return DialogBoxIndirectPtr( GetWindowWord(hWnd, GWW_HINSTANCE), sysres_DIALOG_SHELL_ABOUT_MSGBOX, - hWnd, (WNDPROC)AboutDlgProc); + hWnd, GetWndProcEntry16("AboutDlgProc")); } diff --git a/miscemu/emulate.c b/miscemu/emulate.c index 31c96344936..70d8153a332 100644 --- a/miscemu/emulate.c +++ b/miscemu/emulate.c @@ -1,6 +1,6 @@ #include <stdlib.h> #include <stdio.h> -#include "regfunc.h" +#include "wine.h" #include "stddebug.h" /* #define DEBUG_INT */ #include "debug.h" @@ -14,20 +14,21 @@ struct Win87EmInfoStruct { unsigned short Unused; }; -int -WIN87_fpmath() +void +WIN87_fpmath( struct sigcontext_struct context ) { - dprintf_int(stddeb, "_fpmath: (%x:%lx %x %x)\n",_CONTEXT->sc_cs, - _CONTEXT->sc_eip, _CONTEXT->sc_es, (unsigned int)_BX & 0xffff); + dprintf_int(stddeb, "_fpmath: (%x:%lx %x %x)\n",context.sc_cs, + context.sc_eip, context.sc_es, (int)context.sc_ebx & 0xffff ); - switch(_BX & 0xffff) + switch(context.sc_ebx & 0xffff) { case 11: - return 1; + context.sc_eax = 1; + break; default: - return 0; + context.sc_eax = 0; + break; } - } void diff --git a/miscemu/int21.c b/miscemu/int21.c index 03afeef18e2..28d4dca1459 100644 --- a/miscemu/int21.c +++ b/miscemu/int21.c @@ -16,7 +16,6 @@ #include <utime.h> #include <ctype.h> #include "dos_fs.h" -#include "regfunc.h" #include "windows.h" #include "msdos.h" #include "registers.h" @@ -1669,10 +1668,9 @@ int do_int21(struct sigcontext_struct * context) /********************************************************************** * DOS3Call */ -void DOS3Call(void) +void DOS3Call( struct sigcontext_struct context ) { - do_int21((struct sigcontext_struct *) _CONTEXT); - ReturnFromRegisterFunc(); + do_int21( &context ); } void INT21_Init(void) diff --git a/miscemu/kernel.c b/miscemu/kernel.c index 8f24c724d67..f81410b8c78 100644 --- a/miscemu/kernel.c +++ b/miscemu/kernel.c @@ -6,8 +6,8 @@ static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; #include <stdio.h> #include <stdlib.h> #include "prototypes.h" -#include "regfunc.h" #include "options.h" +#include "wine.h" #include "stddebug.h" #include "debug.h" @@ -16,20 +16,14 @@ extern unsigned short WIN_StackSize; /********************************************************************** * KERNEL_InitTask */ -void KERNEL_InitTask(void) +void KERNEL_InitTask( struct sigcontext_struct context ) { - _BX = 0x81; - _AX = 1; - _CX = WIN_StackSize; - _DX = Options.cmdShow; - _DI = _DS; - -/* FIXME: DI should contain the instance handle of the caller, _DS doesn't - always work as the caller might have changed it. */ - - _SI = 0; - ReturnFromRegisterFunc(); - /* Function does not return */ + context.sc_eax = 1; + context.sc_ebx = 0x81; + context.sc_ecx = WIN_StackSize; + context.sc_edx = Options.cmdShow; + context.sc_edi = 0; + context.sc_edi = context.sc_ds; } /********************************************************************** diff --git a/multimedia/mmsystem.c b/multimedia/mmsystem.c index 27a2b3c004c..e2af222e62a 100644 --- a/multimedia/mmsystem.c +++ b/multimedia/mmsystem.c @@ -1833,14 +1833,9 @@ WORD FAR PASCAL MMSysTimeCallback(HWND hWnd, WORD wMsg, int nID, DWORD dwTime) lpTimer->wCurTime = lpTimer->wDelay; if (lpTimer->lpFunc != NULL) { dprintf_mmtime(stddeb,"MMSysTimeCallback // before CallBack16 !\n"); -#ifdef WINELIB - (*lpTimer->lpFunc)(lpTimer->wTimerID, (WORD)0, - lpTimer->dwUser, (DWORD)0, (DWORD)0); -#else - CallBack16(lpTimer->lpFunc, 5, - 0, (int)lpTimer->wTimerID, 0, (int)0, - 2, lpTimer->dwUser, 2, 0, 2, 0); -#endif + CallTimeFuncProc( lpTimer->lpFunc, + lpTimer->wTimerID, 0, + lpTimer->dwUser, 0, 0 ); dprintf_mmtime(stddeb, "MMSysTimeCallback // after CallBack16 !\n"); fflush(stdout); } diff --git a/objects/font.c b/objects/font.c index 15d1785b1ee..5272b4f3ff0 100644 --- a/objects/font.c +++ b/objects/font.c @@ -736,14 +736,10 @@ int EnumFonts(HDC hDC, LPSTR lpFaceName, FARPROC lpEnumFunc, LPSTR lpData) SelectObject(hDC, hOldFont); DeleteObject(hFont); dprintf_font(stddeb,"EnumFonts // i=%d lpLogFont=%p lptm=%p\n", i, lpLogFont, lptm); - -#ifdef WINELIB - nRet = (*lpEnumFunc)(lpLogFont, lptm, 0, lpData); -#else - nRet = CallBack16(lpEnumFunc, 4, 2, GDI_HEAP_SEG_ADDR(hLog), - 2, GDI_HEAP_SEG_ADDR(hMet), - 0, (int)0, 2, (int)lpData); -#endif + nRet = CallEnumFontsProc( lpEnumFunc, + GDI_HEAP_SEG_ADDR(hLog), + GDI_HEAP_SEG_ADDR(hMet), + 0, (LONG)lpData ); if (nRet == 0) { dprintf_font(stddeb,"EnumFonts // EnumEnd requested by application !\n"); break; @@ -823,13 +819,10 @@ int EnumFontFamilies(HDC hDC, LPSTR lpszFamily, FARPROC lpEnumFunc, LPSTR lpData DeleteObject(hFont); dprintf_font(stddeb, "EnumFontFamilies // i=%d lpLogFont=%p lptm=%p\n", i, lpLogFont, lptm); -#ifdef WINELIB - nRet = (*lpEnumFunc)(lpLogFont, lptm, 0, lpData); -#else - nRet = CallBack16(lpEnumFunc, 4, 2, GDI_HEAP_SEG_ADDR(hLog), - 2, GDI_HEAP_SEG_ADDR(hMet), - 0, (int)0, 2, (int)lpData); -#endif + nRet = CallEnumFontFamProc( lpEnumFunc, + GDI_HEAP_SEG_ADDR(hLog), + GDI_HEAP_SEG_ADDR(hMet), + 0, (LONG)lpData ); if (nRet == 0) { dprintf_font(stddeb,"EnumFontFamilies // EnumEnd requested by application !\n"); break; @@ -840,5 +833,17 @@ int EnumFontFamilies(HDC hDC, LPSTR lpszFamily, FARPROC lpEnumFunc, LPSTR lpData return 0; } +/************************************************************************* + * GetRasterizerCaps [GDI.313] + */ - +BOOL GetRasterizerCaps(LPRASTERIZER_STATUS lprs, WORD cbNumBytes) +{ + /* This is not much more than a dummy */ + RASTERIZER_STATUS rs; + + rs.nSize = sizeof(rs); + rs.wFlags = 0; + rs.nLanguageID = 0; + return True; +} diff --git a/objects/gdiobj.c b/objects/gdiobj.c index fff10ce6d84..ed865822b03 100644 --- a/objects/gdiobj.c +++ b/objects/gdiobj.c @@ -16,6 +16,7 @@ static char Copyright[] = "Copyright Alexandre Julliard, 1993"; #include "palette.h" #include "pen.h" #include "region.h" +#include "callback.h" #include "stddebug.h" /* #define DEBUG_GDI */ #include "debug.h" @@ -486,16 +487,10 @@ int EnumObjects(HDC hDC, int nObjType, FARPROC lpEnumFunc, LPSTR lpData) dprintf_gdi(stddeb,"EnumObjects // StockPen lopnWidth=%d\n", ((LPLOGPEN)lpLog)->lopnWidth.x); dprintf_gdi(stddeb,"EnumObjects // StockPen lopnColor=%08lX\n", ((LPLOGPEN)lpLog)->lopnColor); } - nRet = 1; -/* -#ifdef WINELIB - nRet = (*lpEnumFunc)(lpLog, lpData); -#else - nRet = CallBack16(lpEnumFunc, 4, 2, - GDI_HEAP_SEG_ADDR(hLog), 2, (int)lpData); -#endif -*/ - dprintf_gdi(stddeb,"EnumObjects // after CallBack16 !\n"); + nRet = CallEnumObjectsProc( lpEnumFunc, + GDI_HEAP_SEG_ADDR(hLog), + (int)lpData ); + dprintf_gdi(stddeb,"EnumObjects // after Callback!\n"); if (nRet == 0) { GDI_HEAP_FREE(hLog); dprintf_gdi(stddeb,"EnumObjects // EnumEnd requested by application !\n"); @@ -524,16 +519,10 @@ int EnumObjects(HDC hDC, int nObjType, FARPROC lpEnumFunc, LPSTR lpData) dprintf_gdi(stddeb,"EnumObjects // DC_Pen lopnWidth=%d\n", ((LPLOGPEN)lpLog)->lopnWidth.x); dprintf_gdi(stddeb,"EnumObjects // DC_Pen lopnColor=%08lX\n", ((LPLOGPEN)lpLog)->lopnColor); } -/* -#ifdef WINELIB - nRet = (*lpEnumFunc)(lpLog, lpData); -#else - nRet = CallBack16(lpEnumFunc, 4, 2, - GDI_HEAP_SEG_ADDR(hLog), 2, (int)lpData); -#endif -*/ - nRet = 1; - dprintf_gdi(stddeb,"EnumObjects // after CallBack16 !\n"); + nRet = CallEnumObjectsProc( lpEnumFunc, + GDI_HEAP_SEG_ADDR(hLog), + (int)lpData ); + dprintf_gdi(stddeb,"EnumObjects // after Callback!\n"); if (nRet == 0) { GDI_HEAP_FREE(hLog); dprintf_gdi(stddeb,"EnumObjects // EnumEnd requested by application !\n"); diff --git a/objects/linedda.c b/objects/linedda.c index 729f9ec26a8..d53e1336e02 100644 --- a/objects/linedda.c +++ b/objects/linedda.c @@ -8,7 +8,7 @@ static char Copyright[] = "Copyright Bob Amstadt, 1993"; #include <stdlib.h> #include "windows.h" -#include "if1632.h" +#include "callback.h" /********************************************************************** * LineDDA (GDI.100) @@ -16,32 +16,41 @@ static char Copyright[] = "Copyright Bob Amstadt, 1993"; void LineDDA(short nXStart, short nYStart, short nXEnd, short nYEnd, FARPROC callback, long lParam) { - int x, y; - int b; - int x_diff = nXEnd - nXStart; - int y_diff = nYEnd - nYStart; + int xadd = 1, yadd = 1; + int err,erradd; + int cnt; + int dx = nXEnd - nXStart; + int dy = nYEnd - nYStart; - if (x_diff == 0 && y_diff == 0) - return; - - if ((abs(x_diff) < abs(y_diff) && x_diff != 0) || y_diff == 0) - { - b = (nXStart * y_diff) / x_diff - nYStart; - - for (x = nXStart; x <= nXEnd; x++) - { - y = (x * y_diff) / x_diff + b; - CallLineDDAProc(callback, x, y, lParam); - } + if (dx < 0) { + dx = -dx; xadd = -1; } - else - { - b = (nYStart * x_diff) / y_diff - nXStart; - - for (y = nYStart; y <= nYEnd; y++) - { - x = (y * x_diff) / y_diff + b; - CallLineDDAProc(callback, x, y, lParam); + if (dy < 0) { + dy = -dy; yadd = -1; + } + if (dx > dy) { /* line is "more horizontal" */ + err = 2*dy - dx; erradd = 2*dy - 2*dx; + for(cnt = 0;cnt <= dx; cnt++) { + CallLineDDAProc(callback,nXStart,nYStart,lParam); + if (err > 0) { + nYStart += yadd; + err += erradd; + } else { + err += 2*dy; + } + nXStart += xadd; + } + } else { /* line is "more vertical" */ + err = 2*dx - dy; erradd = 2*dx - 2*dy; + for(cnt = 0;cnt <= dy; cnt++) { + CallLineDDAProc(callback,nXStart,nYStart,lParam); + if (err > 0) { + nXStart += xadd; + err += erradd; + } else { + err += 2*dx; } + nYStart += yadd; + } } } diff --git a/toolkit/sup.c b/toolkit/sup.c index 3d1be0c4987..f22343c6b89 100644 --- a/toolkit/sup.c +++ b/toolkit/sup.c @@ -13,21 +13,6 @@ LONG CallWindowProc (WNDPROC func, HWND hwnd, WORD message, return (*func)(hwnd, message, wParam, lParam); } -CallLineDDAProc (FARPROC back, int x, int y, long lParam) -{ - return (*back)(x, y, lParam); -} - -DWORD CallHookProc (HOOKPROC func, short code, WPARAM wParam, LPARAM lParam) -{ - return (*func)(code, wParam, lParam); -} - -BOOL CallGrayStringProc (FARPROC func, HDC hdc, LPARAM lParam, INT cch) -{ - return (*func) (hdc, lParam, cch); -} - /* * Header loading routines for WineLib. */ diff --git a/tools/Imakefile b/tools/Imakefile index 2c6613b0f40..e5abd7b3243 100644 --- a/tools/Imakefile +++ b/tools/Imakefile @@ -6,11 +6,7 @@ OBJS = $(SRCS:.c=.o) AllTarget(build) -#ifndef NewBuild NormalProgramTarget(build,build.o,$(DEPLIBS),,) -#else -NormalProgramTarget(newbuild,$(OBJS),$(DEPLIBS),,) -#endif DependTarget() diff --git a/tools/build-spec.txt b/tools/build-spec.txt index 25dfed69e6f..af4c7fac292 100644 --- a/tools/build-spec.txt +++ b/tools/build-spec.txt @@ -4,8 +4,7 @@ length NUMBER_OF_ORDINALS ORDINAL VARTYPE EXPORTNAME (DATA [DATA [DATA [...]]]) -ORDINAL FUNCTYPE EXPORTNAME([ARGTYPE [ARGTYPE [...]]]) - HANDLERNAME([ARGNUM [ARGNUM [...]]]) +ORDINAL FUNCTYPE EXPORTNAME([ARGTYPE [ARGTYPE [...]]]) HANDLERNAME ORDINAL equate EXPORTNAME DATA @@ -36,34 +35,22 @@ ordinal 2 and containing 4 bytes: Function ordinals: - This type defines a function entry point. The prototype defined -by "EXPORTNAME ([ARGTYPE [ARGTYPE [...]]])" specifies the name available -for dynamic linking and the format of the 16-bit stack. By specifying -"FUNCTYPE", the loader can automatically determine which order the -parameters were pushed by the calling routine. The prototype -specified by "HANDLERNAME([ARGNUM [ARGNUM [...]]])" specifies to -the loader how to call the 32-bit library routine which will handle this -call. Note that specifying "ARGNUM" as 1 means the leftmost argument -given to the function call, and not the first argument on the stack. -For "pascal" functions, "ARGNUM" equal to 1 specifies the last -argument on the stack. If you do not specify any arguments to the -handler function, then address of the 16-bit argument stack is -passed to the handler function. - "ORDINAL" is replaced by the ordinal number corresponding to the -function. "FUNCTYPE" should be "c" or "pascal" ("pascal" may be -shortened to "p"). "EXPORTNAME" will be the name available for -dynamic linking. "ARGTYPE" should be "byte", "word", "long", "ptr", -"s_byte" (signed byte), "s_word" (signed word) or "s_long" -(signed long). "HANDLERNAME" is the name of the actual function -that will process the request in 32-bit mode. "ARGNUM" is the -original argument number. The first argument is numbered "1". + This type defines a function entry point. The prototype defined by +"EXPORTNAME ([ARGTYPE [ARGTYPE [...]]])" specifies the name available for +dynamic linking and the format of the 16-bit stack. "ORDINAL" is replaced +by the ordinal number corresponding to the function. "FUNCTYPE" should be +"pascal16" or "pascal" for 16-bit or 32-bit return values. "ARGTYPE" +should be "byte", "word", "long", "ptr" (linear pointer), "s_byte" (signed +byte), "s_word" (signed word), "s_long" (signed long), or "segptr" +(segmented pointer). "HANDLERNAME" is the name of the actual function that +will process the request in 32-bit mode. This first example defines an entry point for the CreateWindow() call (the ordinal 100 is just an example): 100 pascal CreateWindow(ptr ptr long s_word s_word s_word s_word word word word ptr) - WIN_CreateWindow(1 2 3 4 5 6 7 8 9 10 11) + WIN_CreateWindow This second example defines an entry point for the GetFocus() call (the ordinal 100 is just an example): diff --git a/tools/build.c b/tools/build.c index c4e8125dc09..6c1d179dbee 100644 --- a/tools/build.c +++ b/tools/build.c @@ -1,4 +1,7 @@ -/* static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; */ +/* + * Copyright 1993 Robert J. Amstadt + * Copyright 1995 Alexandre Julliard + */ #include <stdio.h> #include <stdlib.h> @@ -6,17 +9,6 @@ #include <ctype.h> #include "wine.h" -#ifdef linux -#ifdef __ELF__ -#define UTEXTSEL 0x0f -#else -#define UTEXTSEL 0x23 -#endif -#endif -#if defined(__NetBSD__) || defined(__FreeBSD__) -#define UTEXTSEL 0x1f -#endif - /* ELF symbols do not have an underscore in front */ #ifdef __ELF__ #define PREFIX @@ -24,66 +16,22 @@ #define PREFIX "_" #endif -#define VARTYPE_BYTE 0 -#define VARTYPE_SIGNEDWORD 0 -#define VARTYPE_WORD 1 -#define VARTYPE_LONG 2 -#define VARTYPE_FARPTR 3 - -#define FUNCTYPE_PASCAL_16 16 -#define FUNCTYPE_PASCAL 17 -#define FUNCTYPE_REG 18 - -#define EQUATETYPE_ABS 19 -#define TYPE_RETURN 20 +#define TYPE_INVALID 0 +#define TYPE_BYTE 1 +#define TYPE_WORD 2 +#define TYPE_LONG 3 +#define TYPE_PASCAL_16 4 +#define TYPE_PASCAL 5 +#define TYPE_REGISTER 6 +#define TYPE_ABS 7 +#define TYPE_RETURN 8 -/*#define MAX_ORDINALS 1024*/ #define MAX_ORDINALS 1299 -#define PUSH_0 "\tpushl\t$0\n" -#define PUSH_SS "\tpushw\t$0\n\tpushw\t%%ss\n" -#define PUSH_ESP "\tpushl\t%%esp\n" -#define PUSH_EFL "\tpushfl\n" -#define PUSH_CS "\tpushw\t$0\n\tpushw\t%%cs\n" -#define PUSH_EIP "\tpushl\t$0\n" -#define PUSH_DS "\tpushw\t$0\n\tpushw\t%%ds\n" -#define PUSH_ES "\tpushw\t$0\n\tpushw\t%%es\n" -#define PUSH_FS "\tpushw\t$0\n\tpushw\t%%fs\n" -#define PUSH_GS "\tpushw\t$0\n\tpushw\t%%gs\n" -#define PUSH_EAX "\tpushl\t%%eax\n" -#define PUSH_ECX "\tpushl\t%%ecx\n" -#define PUSH_EDX "\tpushl\t%%edx\n" -#define PUSH_EBX "\tpushl\t%%ebx\n" -#define PUSH_EBP "\tpushl\t%%ebp\n" -#define PUSH_ESI "\tpushl\t%%esi\n" -#define PUSH_EDI "\tpushl\t%%edi\n" - -#define POP_0 "\tadd\t$4,%%esp\n" -#define POP_SS "\tpopw\t%%ss\n\tadd\t$2,%%esp\n" -#define POP_ESP "\tpopl\t%%esp\n" -#define POP_EFL "\tpopl\t%%gs:return_value\n" -#define POP_CS "\tpopw\t%%cs\n\tadd\t$2,%%esp\n" -#define POP_EIP "\tpopl\t$0\n" -#define POP_DS "\tpopw\t%%ds\n\tadd\t$2,%%esp\n" -#define POP_ES "\tpopw\t%%es\n\tadd\t$2,%%esp\n" -#define POP_FS "\tpopw\t%%fs\n\tadd\t$2,%%esp\n" -#define POP_GS "\tpopw\t%%gs\n\tadd\t$2,%%esp\n" -#define POP_EAX "\tpopl\t%%eax\n" -#define POP_ECX "\tpopl\t%%ecx\n" -#define POP_EDX "\tpopl\t%%edx\n" -#define POP_EBX "\tpopl\t%%ebx\n" -#define POP_EBP "\tpopl\t%%ebp\n" -#define POP_ESI "\tpopl\t%%esi\n" -#define POP_EDI "\tpopl\t%%edi\n" - -char **context_strings; -char **pop_strings; -int n_context_strings; - typedef struct ordinal_definition_s { - int valid; int type; + int offset; char export_name[80]; void *additional_data; } ORDDEF; @@ -96,10 +44,8 @@ typedef struct ordinal_variable_definition_s typedef struct ordinal_function_definition_s { - int n_args_16; - int arg_types_16[16]; - int arg_16_offsets[16]; - int arg_16_size; + int n_args; + char arg_types[32]; char internal_name[80]; } ORDFUNCDEF; @@ -109,7 +55,7 @@ typedef struct ordinal_return_definition_s int ret_value; } ORDRETDEF; -ORDDEF OrdinalDefinitions[MAX_ORDINALS]; +static ORDDEF OrdinalDefinitions[MAX_ORDINALS]; char LowerDLLName[80]; char UpperDLLName[80]; @@ -122,7 +68,14 @@ char *ParseNext; char ParseSaveChar; int Line; -int IsNumberString(char *s) +static int debugging = 1; + + /* Offset of register relative to the end of the context struct */ +#define CONTEXTOFFSET(reg) \ + ((int)&(((struct sigcontext_struct *)1)->reg) - 1 \ + - sizeof(struct sigcontext_struct)) + +static int IsNumberString(char *s) { while (*s != '\0') if (!isdigit(*s++)) @@ -131,7 +84,7 @@ int IsNumberString(char *s) return 1; } -char *strlower(char *s) +static char *strlower(char *s) { char *p; @@ -141,7 +94,7 @@ char *strlower(char *s) return s; } -char *strupper(char *s) +static char *strupper(char *s) { char *p; @@ -151,20 +104,7 @@ char *strupper(char *s) return s; } -int stricmp(char *s1, char *s2) -{ - if (strlen(s1) != strlen(s2)) - return -1; - - while (*s1 != '\0') - if (*s1++ != *s2++) - return -1; - - return 0; -} - -char * -GetTokenInLine(void) +static char * GetTokenInLine(void) { char *p; char *token; @@ -200,8 +140,7 @@ GetTokenInLine(void) return token; } -char * -GetToken(void) +static char * GetToken(void) { char *token; @@ -235,8 +174,7 @@ GetToken(void) return token; } -int -ParseVariable(int ordinal, int type) +static int ParseVariable(int ordinal, int type) { ORDDEF *odp; ORDVARDEF *vdp; @@ -294,7 +232,6 @@ ParseVariable(int ordinal, int type) } odp = &OrdinalDefinitions[ordinal]; - odp->valid = 1; odp->type = type; strcpy(odp->export_name, export_name); @@ -307,16 +244,12 @@ ParseVariable(int ordinal, int type) return 0; } -int -ParseExportFunction(int ordinal, int type) +static int ParseExportFunction(int ordinal, int type) { char *token; ORDDEF *odp; ORDFUNCDEF *fdp; int i; - int current_offset; - int arg_size; - if (ordinal >= MAX_ORDINALS) { @@ -326,7 +259,6 @@ ParseExportFunction(int ordinal, int type) odp = &OrdinalDefinitions[ordinal]; strcpy(odp->export_name, GetToken()); - odp->valid = 1; odp->type = type; fdp = malloc(sizeof(*fdp)); odp->additional_data = fdp; @@ -338,60 +270,39 @@ ParseExportFunction(int ordinal, int type) exit(1); } - fdp->arg_16_size = 0; for (i = 0; i < 16; i++) { token = GetToken(); if (*token == ')') break; - if (stricmp(token, "byte") == 0 || stricmp(token, "word") == 0) - { - fdp->arg_types_16[i] = VARTYPE_WORD; - fdp->arg_16_size += 2; - fdp->arg_16_offsets[i] = 2; - } - else if (stricmp(token, "s_byte") == 0 || - stricmp(token, "s_word") == 0) - { - fdp->arg_types_16[i] = VARTYPE_SIGNEDWORD; - fdp->arg_16_size += 2; - fdp->arg_16_offsets[i] = 2; - } - else if (stricmp(token, "long") == 0 || stricmp(token, "segptr") == 0) - { - fdp->arg_types_16[i] = VARTYPE_LONG; - fdp->arg_16_size += 4; - fdp->arg_16_offsets[i] = 4; - } - else if (stricmp(token, "ptr") == 0) - { - fdp->arg_types_16[i] = VARTYPE_FARPTR; - fdp->arg_16_size += 4; - fdp->arg_16_offsets[i] = 4; - } + if (!strcmp(token, "byte") || !strcmp(token, "word")) + fdp->arg_types[i] = 'w'; + else if (!strcmp(token, "s_byte") || !strcmp(token, "s_word")) + fdp->arg_types[i] = 's'; + else if (!strcmp(token, "long") || !strcmp(token, "segptr")) + fdp->arg_types[i] = 'l'; + else if (!strcmp(token, "ptr")) + fdp->arg_types[i] = 'p'; else { fprintf(stderr, "%d: Unknown variable type '%s'\n", Line, token); exit(1); } } - fdp->n_args_16 = i; + fdp->arg_types[i] = '\0'; - current_offset = 0; - for (i--; i >= 0; i--) + if ((type == TYPE_REGISTER) && (i > 0)) { - arg_size = fdp->arg_16_offsets[i]; - fdp->arg_16_offsets[i] = current_offset; - current_offset += arg_size; + fprintf( stderr, "%d: Register function can't have arguments\n", Line); + exit(1); } strcpy(fdp->internal_name, GetToken()); return 0; } -int -ParseEquate(int ordinal) +static int ParseEquate(int ordinal) { ORDDEF *odp; char *token; @@ -416,15 +327,13 @@ ParseEquate(int ordinal) exit(1); } - odp->valid = 1; - odp->type = EQUATETYPE_ABS; + odp->type = TYPE_ABS; odp->additional_data = (void *) value; return 0; } -int -ParseReturn(int ordinal) +static int ParseReturn(int ordinal) { ORDDEF *odp; ORDRETDEF *rdp; @@ -441,7 +350,6 @@ ParseReturn(int ordinal) odp = &OrdinalDefinitions[ordinal]; strcpy(odp->export_name, GetToken()); - odp->valid = 1; odp->type = TYPE_RETURN; odp->additional_data = rdp; @@ -466,8 +374,7 @@ ParseReturn(int ordinal) return 0; } -int -ParseOrdinal(int ordinal) +static int ParseOrdinal(int ordinal) { char *token; @@ -478,23 +385,23 @@ ParseOrdinal(int ordinal) exit(1); } - if (stricmp(token, "byte") == 0) - return ParseVariable(ordinal, VARTYPE_BYTE); - else if (stricmp(token, "word") == 0) - return ParseVariable(ordinal, VARTYPE_WORD); - else if (stricmp(token, "long") == 0) - return ParseVariable(ordinal, VARTYPE_LONG); - else if (stricmp(token, "p") == 0) - return ParseExportFunction(ordinal, FUNCTYPE_PASCAL); - else if (stricmp(token, "pascal") == 0) - return ParseExportFunction(ordinal, FUNCTYPE_PASCAL); - else if (stricmp(token, "pascal16") == 0) - return ParseExportFunction(ordinal, FUNCTYPE_PASCAL_16); - else if (stricmp(token, "register") == 0) - return ParseExportFunction(ordinal, FUNCTYPE_REG); - else if (stricmp(token, "equate") == 0) + if (strcmp(token, "byte") == 0) + return ParseVariable(ordinal, TYPE_BYTE); + else if (strcmp(token, "word") == 0) + return ParseVariable(ordinal, TYPE_WORD); + else if (strcmp(token, "long") == 0) + return ParseVariable(ordinal, TYPE_LONG); + else if (strcmp(token, "p") == 0) + return ParseExportFunction(ordinal, TYPE_PASCAL); + else if (strcmp(token, "pascal") == 0) + return ParseExportFunction(ordinal, TYPE_PASCAL); + else if (strcmp(token, "pascal16") == 0) + return ParseExportFunction(ordinal, TYPE_PASCAL_16); + else if (strcmp(token, "register") == 0) + return ParseExportFunction(ordinal, TYPE_REGISTER); + else if (strcmp(token, "equate") == 0) return ParseEquate(ordinal); - else if (stricmp(token, "return") == 0) + else if (strcmp(token, "return") == 0) return ParseReturn(ordinal); else { @@ -505,14 +412,13 @@ ParseOrdinal(int ordinal) } } -int -ParseTopLevel(void) +static int ParseTopLevel(void) { char *token; while ((token = GetToken()) != NULL) { - if (stricmp(token, "name") == 0) + if (strcmp(token, "name") == 0) { strcpy(LowerDLLName, GetToken()); strlower(LowerDLLName); @@ -520,7 +426,7 @@ ParseTopLevel(void) strcpy(UpperDLLName, LowerDLLName); strupper(UpperDLLName); } - else if (stricmp(token, "id") == 0) + else if (strcmp(token, "id") == 0) { token = GetToken(); if (!IsNumberString(token)) @@ -531,7 +437,7 @@ ParseTopLevel(void) DLLId = atoi(token); } - else if (stricmp(token, "length") == 0) + else if (strcmp(token, "length") == 0) { token = GetToken(); if (!IsNumberString(token)) @@ -562,85 +468,14 @@ ParseTopLevel(void) return 0; } -void -InitContext(void) -{ - struct sigcontext_struct context; - int i; - - n_context_strings = sizeof(context) / 4; - context_strings = (char **) malloc(n_context_strings * sizeof(char **)); - pop_strings = (char **) malloc(n_context_strings * sizeof(char **)); - for (i = 0; i < n_context_strings; i++) - { - context_strings[i] = PUSH_0; - pop_strings[i] = POP_0; - } - - i = n_context_strings - 1 + ((int) &context - (int) &context.sc_esp) / 4; - context_strings[i] = PUSH_ESP; - - i = n_context_strings - 1 + ((int) &context - (int) &context.sc_ebp) / 4; - context_strings[i] = PUSH_EBP; - pop_strings[n_context_strings - 1 - i] = POP_EBP; - - i = n_context_strings - 1 + ((int) &context - (int) &context.sc_eip) / 4; - context_strings[i] = PUSH_EIP; - -#ifndef __FreeBSD__ - i = n_context_strings - 1 + ((int) &context - (int)&context.sc_eflags) / 4; -#else - i = n_context_strings - 1 + ((int) &context - (int)&context.sc_efl) / 4; -#endif - context_strings[i] = PUSH_EFL; - pop_strings[n_context_strings - 1 - i] = POP_EFL; - - i = n_context_strings - 1 + ((int) &context - (int) &context.sc_es) / 4; - context_strings[i] = PUSH_ES; - pop_strings[n_context_strings - 1 - i] = POP_ES; - - i = n_context_strings - 1 + ((int) &context - (int) &context.sc_ds) / 4; - context_strings[i] = PUSH_DS; - pop_strings[n_context_strings - 1 - i] = POP_DS; - - i = n_context_strings - 1 + ((int) &context - (int) &context.sc_cs) / 4; - context_strings[i] = PUSH_CS; - - i = n_context_strings - 1 + ((int) &context - (int) &context.sc_ss) / 4; - context_strings[i] = PUSH_SS; - - i = n_context_strings - 1 + ((int) &context - (int) &context.sc_edi) / 4; - context_strings[i] = PUSH_EDI; - pop_strings[n_context_strings - 1 - i] = POP_EDI; - - i = n_context_strings - 1 + ((int) &context - (int) &context.sc_esi) / 4; - context_strings[i] = PUSH_ESI; - pop_strings[n_context_strings - 1 - i] = POP_ESI; - - i = n_context_strings - 1 + ((int) &context - (int) &context.sc_ebx) / 4; - context_strings[i] = PUSH_EBX; - pop_strings[n_context_strings - 1 - i] = POP_EBX; - - i = n_context_strings - 1 + ((int) &context - (int) &context.sc_edx) / 4; - context_strings[i] = PUSH_EDX; - pop_strings[n_context_strings - 1 - i] = POP_EDX; - - i = n_context_strings - 1 + ((int) &context - (int) &context.sc_ecx) / 4; - context_strings[i] = PUSH_ECX; - pop_strings[n_context_strings - 1 - i] = POP_ECX; - - i = n_context_strings - 1 + ((int) &context - (int) &context.sc_eax) / 4; - context_strings[i] = PUSH_EAX; - pop_strings[n_context_strings - 1 - i] = POP_EAX; -} -void -OutputVariableCode(FILE *fp, char *storage, ORDDEF *odp) +static int OutputVariableCode(FILE *fp, char *storage, ORDDEF *odp) { ORDVARDEF *vdp; int i; vdp = odp->additional_data; + fprintf( fp, "\t.data\n" ); for (i = 0; i < vdp->n_values; i++) { if ((i & 7) == 0) @@ -654,320 +489,770 @@ OutputVariableCode(FILE *fp, char *storage, ORDDEF *odp) fprintf(fp, ", "); } fprintf(fp, "\n"); + fprintf( fp, "\t.text\n" ); + return vdp->n_values; } -int main(int argc, char **argv) +static void BuildSpecFiles( char *specname) { ORDDEF *odp; ORDFUNCDEF *fdp; ORDRETDEF *rdp; FILE *fp; char filename[80]; - int i, ci, add_count, argnum; - int prev_index; /* Index to previous #define (-1 if none) */ + int i; + int code_offset, data_offset; - /* the difference between last #define and the current */ - int prev_n_args; - - if (argc < 2) + SpecFp = fopen( specname, "r"); + if (SpecFp == NULL) { - fprintf(stderr, "usage: build SPECNAME\n build -p\n"); + fprintf(stderr, "Could not open specification file, '%s'\n", specname); exit(1); } - InitContext(); + ParseTopLevel(); - if (strcmp("-p", argv[1]) == 0) + sprintf(filename, "dll_%s.S", LowerDLLName); + fp = fopen(filename, "w"); + fprintf( fp, "/* File generated automatically; do not edit! */\n" ); + fprintf( fp, "\t.data\n" ); + fprintf( fp, "\t.globl " PREFIX "%s_Data_Start\n", UpperDLLName ); + fprintf( fp, PREFIX "%s_Data_Start:\n", UpperDLLName ); + fprintf( fp, "\t.text\n" ); + fprintf( fp, "\t.globl " PREFIX "%s_Code_Start\n", UpperDLLName ); + fprintf( fp, PREFIX "%s_Code_Start:\n", UpperDLLName ); + code_offset = data_offset = 0; + + odp = OrdinalDefinitions; + for (i = 0; i <= Limit; i++, odp++) { - fp = fopen("pop.h", "w"); - add_count = 0; - for (i = 0; i < n_context_strings; i++) - { - if (strncmp(pop_strings[i], "\tadd\t", 5) == 0) - { - add_count += atoi(pop_strings[i] + 6); - } - else - { - if (add_count > 0) - { - fprintf(fp, "\tadd\t$%d,%%esp\n", add_count); - add_count = 0; - } + fdp = odp->additional_data; + rdp = odp->additional_data; + + switch (odp->type) + { + case TYPE_INVALID: + fprintf( fp, "/* %s.%d */\n", UpperDLLName, i); + fprintf( fp, "\tpushw %%bp\n" ); + fprintf( fp, "\tpushl $0x%08x\n", (DLLId << 16) | i); + fprintf( fp, "\tpushl $" PREFIX "RELAY_Unimplemented\n" ); + fprintf( fp, "\tljmp $0x%04x, $" PREFIX "CallTo32_word_\n", + WINE_CODE_SELECTOR ); + odp->offset = code_offset; + code_offset += 19; /* Assembly code is 19 bytes long */ + break; + + case TYPE_ABS: + odp->offset = (int)odp->additional_data & 0xffff; + break; + + case TYPE_BYTE: + fprintf( fp, "/* %s.%d */\n", UpperDLLName, i); + odp->offset = data_offset; + data_offset += OutputVariableCode(fp, ".byte", odp); + break; + + case TYPE_WORD: + fprintf( fp, "/* %s.%d */\n", UpperDLLName, i); + odp->offset = data_offset; + data_offset += 2 * OutputVariableCode(fp, ".word", odp); + break; + + case TYPE_LONG: + fprintf( fp, "/* %s.%d */\n", UpperDLLName, i); + odp->offset = data_offset; + data_offset += 4 * OutputVariableCode(fp, ".long", odp); + break; + + case TYPE_RETURN: + fprintf( fp, "/* %s.%d */\n", UpperDLLName, i); + fprintf( fp, "\tmovw $%d,%%ax\n", rdp->ret_value & 0xffff ); + fprintf( fp, "\tmovw $%d,%%dx\n", (rdp->ret_value >> 16) & 0xffff); + fprintf(fp, "\t.byte 0x66\n"); + if (rdp->arg_size != 0) + fprintf(fp, "\tlret $%d\n", rdp->arg_size); + else + fprintf(fp, "\tlret\n"); + odp->offset = code_offset; + code_offset += 10; /* Assembly code is 10 bytes long */ + if (rdp->arg_size != 0) code_offset += 2; + break; + + case TYPE_REGISTER: + case TYPE_PASCAL: + case TYPE_PASCAL_16: + fprintf( fp, "/* %s.%d */\n", UpperDLLName, i); + fprintf(fp, "\tpushw %%bp\n" ); + fprintf(fp, "\tpushl $0x%08x\n", (DLLId << 16) | i); + fprintf(fp, "\tpushl $" PREFIX "%s\n", fdp->internal_name ); + fprintf(fp, "\tljmp $0x%04x, $" PREFIX "CallTo32_%s_%s\n\n", + WINE_CODE_SELECTOR, + (odp->type == TYPE_REGISTER) ? "regs" : + (odp->type == TYPE_PASCAL) ? "long" : "word", + fdp->arg_types ); + odp->offset = code_offset; + code_offset += 19; /* Assembly code is 19 bytes long */ + break; - fprintf(fp, pop_strings[i]); - } + default: + fprintf( stderr, "build: Unknown function type; please report.\n"); + break; } - - if (add_count > 0) - fprintf(fp, "\tadd\t$%d,%%esp\n", add_count); - - fprintf(fp, "\tpushl\t%%gs:return_value\n\tpopfl\n"); - - fclose(fp); - exit(0); } - SpecFp = fopen(argv[1], "r"); - if (SpecFp == NULL) - { - fprintf(stderr, "Could not open specification file, '%s'\n", argv[1]); - exit(1); - } + fprintf( fp, "\t.data\n" ); + fprintf( fp, "\t.globl " PREFIX "%s_Data_End\n", UpperDLLName ); + fprintf( fp, PREFIX "%s_Data_End:\n", UpperDLLName ); + fprintf( fp, "\t.text\n" ); + fprintf( fp, "\t.globl " PREFIX "%s_Code_End\n", UpperDLLName ); + fprintf( fp, PREFIX "%s_Code_End:\n", UpperDLLName ); - ParseTopLevel(); + fclose(fp); - sprintf(filename, "dll_%s.S", LowerDLLName); + sprintf(filename, "tab_%s.c", LowerDLLName); fp = fopen(filename, "w"); -#ifdef __ELF__ - fprintf (fp, "#define __ASSEMBLY__\n"); - fprintf (fp, "#include <asm/segment.h>\n"); -#endif + fprintf( fp, "/* File generated automatically; do not edit! */\n\n" ); + fprintf( fp, "#include \"dlls.h\"\n\n" ); + fprintf( fp, "static struct dll_table_entry_s %s_table_entries[%d] =\n{\n", + UpperDLLName, Limit + 1); odp = OrdinalDefinitions; for (i = 0; i <= Limit; i++, odp++) { - fprintf(fp, "\t.globl " PREFIX "%s_Ordinal_%d\n", UpperDLLName, i); + int selector; - if (!odp->valid) - { - fprintf(fp, PREFIX "%s_Ordinal_%d:\n", UpperDLLName, i); - fprintf(fp, "\tmovl\t$0x%08x,%%eax\n", (DLLId << 16) | i); - fprintf(fp, "\tpushw\t$0\n"); -#ifdef __ELF__ - fprintf(fp, "\tljmp\t$USER_CS, $" PREFIX "CallTo32\n\n"); -#else - fprintf(fp, "\tjmp\t_CallTo32\n\n"); -#endif - } - else + fdp = odp->additional_data; + + switch (odp->type) { - fdp = odp->additional_data; - rdp = odp->additional_data; - - switch (odp->type) - { - case EQUATETYPE_ABS: - fprintf(fp, PREFIX "%s_Ordinal_%d = %d\n\n", - UpperDLLName, i, (int) odp->additional_data); - break; + case TYPE_INVALID: + case TYPE_PASCAL: + case TYPE_PASCAL_16: + case TYPE_REGISTER: + selector = 1; /* Code selector */ + break; + + case TYPE_BYTE: + case TYPE_WORD: + case TYPE_LONG: + selector = 2; /* Data selector */ + break; + + case TYPE_ABS: + selector = 0xff; /* Constant selector */ + break; + } - case VARTYPE_BYTE: - fprintf(fp, PREFIX "%s_Ordinal_%d:\n", UpperDLLName, i); - OutputVariableCode(fp, ".byte", odp); - break; + fprintf(fp, " { %d, %d, ", selector, odp->offset ); + fprintf(fp, "\"%s\" ", odp->export_name); +#ifdef WINESTAT + fprintf(fp, ",0 "); +#endif + fprintf(fp, "}, \n"); + } - case VARTYPE_WORD: - fprintf(fp, PREFIX "%s_Ordinal_%d:\n", UpperDLLName, i); - OutputVariableCode(fp, ".word", odp); - break; + fprintf(fp, "};\n\n"); + + fprintf( fp, "extern void %s_Code_Start();\n", UpperDLLName ); + fprintf( fp, "extern void %s_Code_End();\n", UpperDLLName ); + fprintf( fp, "extern void %s_Data_Start();\n", UpperDLLName ); + fprintf( fp, "extern void %s_Data_End();\n\n", UpperDLLName ); + fprintf( fp, "struct dll_table_s %s_table =\n{\n", UpperDLLName ); + fprintf( fp, " %s_table_entries, %d, %d,\n", + UpperDLLName, Limit + 1, DLLId ); + fprintf( fp, " (void *)%s_Code_Start, (void *)%s_Code_End,\n", + UpperDLLName, UpperDLLName ); + fprintf( fp, " (void *)%s_Data_Start, (void *)%s_Data_End\n};\n", + UpperDLLName, UpperDLLName ); + fclose(fp); +} - case VARTYPE_LONG: - fprintf(fp, PREFIX "%s_Ordinal_%d:\n", UpperDLLName, i); - OutputVariableCode(fp, ".long", odp); - break; - case TYPE_RETURN: - fprintf(fp, PREFIX "%s_Ordinal_%d:\n", UpperDLLName, i); - fprintf(fp, "\tmovw\t$%d,%%ax\n", rdp->ret_value & 0xffff); - fprintf(fp, "\tmovw\t$%d,%%dx\n", - (rdp->ret_value >> 16) & 0xffff); - fprintf(fp, "\t.byte\t0x66\n"); - if (rdp->arg_size != 0) - fprintf(fp, "\tlret\t$%d\n", rdp->arg_size); - else - fprintf(fp, "\tlret\n"); - break; +/******************************************************************* + * TransferArgs16To32 + * + * Get the arguments from the 16-bit stack and push them on the 32-bit stack. + * The 16-bit stack layout is: + * ... ... + * (bp+8) arg2 + * (bp+6) arg1 + * (bp+4) cs + * (bp+2) ip + * (bp) bp + */ +static int TransferArgs16To32( char *args ) +{ + int i, pos16, pos32; - case FUNCTYPE_REG: - fprintf(fp, PREFIX "%s_Ordinal_%d:\n", UpperDLLName, i); - fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n"); - fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n"); - - for (ci = 0; ci < n_context_strings; ci++) - fprintf(fp, context_strings[ci]); - - fprintf(fp, "\tmovl\t%%ebp,%%eax\n"); - fprintf(fp, "\tmovw\t%%esp,%%ebp\n"); - fprintf(fp, "\tpushl\t%d(%%ebp)\n", - sizeof(struct sigcontext_struct)); - fprintf(fp, "\tmovl\t%%eax,%%ebp\n"); - fprintf(fp, "\tmovl\t$0x%08x,%%eax\n", (DLLId << 16) | i); - fprintf(fp, "\tpushw\t$%d\n", - sizeof(struct sigcontext_struct) + 4); -#ifdef __ELF__ - fprintf(fp, "\tljmp\t$USER_CS, $" PREFIX "CallTo32\n\n"); -#else - fprintf(fp, "\tjmp\t_CallTo32\n\n"); -#endif - break; + /* Save ebx first */ - case FUNCTYPE_PASCAL: - fprintf(fp, PREFIX "%s_Ordinal_%d:\n", UpperDLLName, i); - fprintf(fp, "\tmovl\t$0x%08x,%%eax\n", (DLLId << 16) | i); - fprintf(fp, "\tpushw\t$%d\n", fdp->arg_16_size); -#ifdef __ELF__ - fprintf(fp, "\tljmp\t$USER_CS, $" PREFIX "CallTo32\n\n"); -#else - fprintf(fp, "\tjmp\t_CallTo32\n\n"); -#endif - break; - - case FUNCTYPE_PASCAL_16: - fprintf(fp, PREFIX "%s_Ordinal_%d:\n", UpperDLLName, i); - fprintf(fp, "\tmovl\t$0x%08x,%%eax\n", (DLLId << 16) | i); - fprintf(fp, "\tpushw\t$%d\n", fdp->arg_16_size); -#ifdef __ELF__ - fprintf(fp, "\tljmp\t$USER_CS, $" PREFIX "CallTo32_16\n\n"); -#else - fprintf(fp, "\tjmp\t_CallTo32_16\n\n"); -#endif - break; - - default: - fprintf(fp, PREFIX "%s_Ordinal_%d:\n", UpperDLLName, i); - fprintf(fp, "\tmovl\t$0x%08x,%%eax\n", (DLLId << 16) | i); - fprintf(fp, "\tpushw\t$0\n"); -#ifdef __ELF__ - fprintf(fp, "\tljmp\t$USER_CS, $" PREFIX "CallTo32\n\n"); -#else - fprintf(fp, "\tjmp\t_CallTo32\n\n"); -#endif - break; - } - } + printf( "\tpushl %%ebx\n" ); + + /* Get the 32-bit stack pointer */ + + printf( "\tmovl " PREFIX "IF1632_Saved32_esp,%%ebx\n" ); + + /* Copy the arguments */ + + pos16 = 6; /* skip bp and return address */ + pos32 = 0; + + for (i = strlen(args); i > 0; i--) + { + pos32 -= 4; + switch(args[i-1]) + { + case 'w': /* word */ + printf( "\tmovzwl %d(%%ebp),%%eax\n", pos16 ); + printf( "\tmovl %%eax,%d(%%ebx)\n", pos32 ); + pos16 += 2; + break; + + case 's': /* s_word */ + printf( "\tmovswl %d(%%ebp),%%eax\n", pos16 ); + printf( "\tmovl %%eax,%d(%%ebx)\n", pos32 ); + pos16 += 2; + break; + + case 'l': /* long */ + printf( "\tmovl %d(%%ebp),%%eax\n", pos16 ); + printf( "\tmovl %%eax,%d(%%ebx)\n", pos32 ); + pos16 += 4; + break; + + case 'p': /* ptr */ + /* Get the selector */ + printf( "\tmovw %d(%%ebp),%%ax\n", pos16 + 2 ); + /* Get the selector base */ + printf( "\tandl $0xfff8,%%eax\n" ); + printf( "\tmovl " PREFIX "ldt_copy(%%eax),%%eax\n" ); + printf( "\tmovl %%eax,%d(%%ebx)\n", pos32 ); + /* Add the offset */ + printf( "\tmovzwl %d(%%ebp),%%eax\n", pos16 ); + printf( "\taddl %%eax,%d(%%ebx)\n", pos32 ); + pos16 += 4; + break; + + default: + fprintf( stderr, "Unknown arg type '%c'\n", args[i-1] ); + } } - fclose(fp); + /* Restore ebx */ + + printf( "\tpopl %%ebx\n" ); -#ifndef SHORTNAMES - sprintf(filename, "dll_%s_tab.c", LowerDLLName); -#else - sprintf(filename, "dtb_%s.c", LowerDLLName); + return pos16 - 6; /* Return the size of the 16-bit args */ +} + + +/******************************************************************* + * BuildContext + * + * Build the context structure on the 32-bit stack. + * The only valid registers in the context structure are: + * eax, ebx, ecx, edx, esi, edi, ds, es, (some of the) flags + */ +static void BuildContext(void) +{ + /* Save ebx first */ + + printf( "\tpushl %%ebx\n" ); + + /* Get the 32-bit stack pointer */ + + printf( "\tmovl " PREFIX "IF1632_Saved32_esp,%%ebx\n" ); + + /* Store the registers */ + + printf( "\tpopl %d(%%ebx)\n", CONTEXTOFFSET(sc_ebx) ); /* Get ebx from stack */ + printf( "\tmovl %%eax,%d(%%ebx)\n", CONTEXTOFFSET(sc_eax) ); + printf( "\tmovl %%ecx,%d(%%ebx)\n", CONTEXTOFFSET(sc_ecx) ); + printf( "\tmovl %%edx,%d(%%ebx)\n", CONTEXTOFFSET(sc_edx) ); + printf( "\tmovl %%esi,%d(%%ebx)\n", CONTEXTOFFSET(sc_esi) ); + printf( "\tmovl %%edi,%d(%%ebx)\n", CONTEXTOFFSET(sc_edi) ); + printf( "\tmovw %%es,%d(%%ebx)\n", CONTEXTOFFSET(sc_es) ); + printf( "\tmovw -10(%%ebp),%%ax\n" ); /* Get saved ds from stack */ + printf( "\tmovw %%ax,%d(%%ebx)\n", CONTEXTOFFSET(sc_ds) ); + printf( "\tpushfl\n" ); +#ifndef __FreeBSD__ + printf( "\tpopl %d(%%ebx)\n", CONTEXTOFFSET(sc_eflags) ); +#else + printf( "\tpopl %d(%%ebx)\n", CONTEXTOFFSET(sc_efl) ); #endif - fp = fopen(filename, "w"); +} - fprintf(fp, "#include <stdio.h>\n"); - fprintf(fp, "#include <stdlib.h>\n"); - fprintf(fp, "#include \042dlls.h\042\n\n"); - for (i = 0; i <= Limit; i++) +/******************************************************************* + * RestoreContext + * + * Restore the registers from the context structure + */ +static void RestoreContext(void) +{ + /* Get the 32-bit stack pointer */ + + printf( "\tmovl " PREFIX "IF1632_Saved32_esp,%%ebx\n" ); + + /* Restore the registers */ + + printf( "\tmovl %d(%%ebx),%%ecx\n", CONTEXTOFFSET(sc_ecx) ); + printf( "\tmovl %d(%%ebx),%%edx\n", CONTEXTOFFSET(sc_edx) ); + printf( "\tmovl %d(%%ebx),%%esi\n", CONTEXTOFFSET(sc_esi) ); + printf( "\tmovl %d(%%ebx),%%edi\n", CONTEXTOFFSET(sc_edi) ); + printf( "\tmovw %d(%%ebx),%%es\n", CONTEXTOFFSET(sc_es) ); + printf( "\tpopw %%ax\n" ); /* Remove old ds from the stack */ + printf( "\tpushw %d(%%ebx)\n", CONTEXTOFFSET(sc_ds) ); /* Push new ds */ +#ifndef __FreeBSD__ + printf( "\tpushl %d(%%ebx)\n", CONTEXTOFFSET(sc_eflags) ); +#else + printf( "\tpushl %d(%%ebx)\n", CONTEXTOFFSET(sc_efl) ); +#endif + printf( "\tpopfl\n" ); + printf( "\tmovl %d(%%ebx),%%eax\n", CONTEXTOFFSET(sc_eax) ); + printf( "\tmovl %d(%%ebx),%%ebx\n", CONTEXTOFFSET(sc_ebx) ); +} + + +/******************************************************************* + * BuildCall32Func + * + * Build a 32-bit callback function. The syntax of the function + * profile is: type_xxxxx, where 'type' is one of 'regs', 'word' or + * 'long' and each 'x' is an argument ('w'=word, 's'=signed word, + * 'l'=long, 'p'=pointer). + * + * Stack layout upon entry to the callback function: + * ... ... + * (sp+14) first 16-bit arg + * (sp+12) cs (word) + * (sp+10) ip (word) + * (sp+8) bp (word) + * (sp+4) dll_id+ordinal (long) + * (sp) entrypoint (long) + * + */ +static void BuildCall32Func( char *profile ) +{ + int argsize = 0; + int short_ret = 0; + int reg_func = 0; + char *args = profile + 5; + + /* Parse function type */ + + if (!strncmp( "word_", profile, 5 )) short_ret = 1; + else if (!strncmp( "regs_", profile, 5 )) reg_func = 1; + else if (strncmp( "long_", profile, 5 )) { - fprintf(fp, "extern void %s_Ordinal_%d();\n", UpperDLLName, i); + fprintf( stderr, "Invalid function name '%s', ignored\n", profile ); + return; } - - odp = OrdinalDefinitions; - for (i = 0; i <= Limit; i++, odp++) + + /* Function header */ + + printf( "/**********\n" ); + printf( " * " PREFIX "CallTo32_%s\n", profile ); + printf( " **********/\n" ); + printf( "\t.align 4\n" ); + printf( "\t.global " PREFIX "CallTo32_%s\n\n", profile ); + printf( PREFIX "CallTo32_%s:\n", profile ); + + /* Setup bp to point to its copy on the stack */ + + printf( "\tmovzwl %%sp,%%ebp\n" ); + printf( "\taddw $8,%%bp\n" ); + + /* Save 16-bit ds */ + + printf( "\tpushw %%ds\n" ); + + /* Restore 32-bit ds */ + + printf( "\tpushw $0x%04x\n", WINE_DATA_SELECTOR ); + printf( "\tpopw %%ds\n" ); + + /* Save the 16-bit stack */ + + printf( "\tpushw " PREFIX "IF1632_Saved16_bp\n" ); + printf( "\tpushw " PREFIX "IF1632_Saved16_sp\n" ); + printf( "\tpushw " PREFIX "IF1632_Saved16_ss\n" ); + printf( "\tmovw %%ss," PREFIX "IF1632_Saved16_ss\n" ); + printf( "\tmovw %%sp," PREFIX "IF1632_Saved16_sp\n" ); + printf( "\tmovw %%bp," PREFIX "IF1632_Saved16_bp\n" ); + + /* Transfer the arguments */ + + if (reg_func) BuildContext(); + else if (*args) argsize = TransferArgs16To32( args ); + + /* Get the address of the API function */ + + printf( "\tmovl -8(%%ebp),%%eax\n" ); + + /* Setup es */ + + printf( "\tpushw %%ds\n" ); + printf( "\tpopw %%es\n" ); + + /* Switch to the 32-bit stack */ + + printf( "\tpushw %%ds\n" ); + printf( "\tpopw %%ss\n" ); + printf( "\tmovl " PREFIX "IF1632_Saved32_esp,%%esp\n" ); + printf( "\tmovl " PREFIX "IF1632_Saved32_ebp,%%ebp\n" ); + if (reg_func) + printf( "\tsubl $%d,%%esp\n", sizeof(struct sigcontext_struct) ); + else if (*args) + printf( "\tsubl $%d,%%esp\n", 4 * strlen(args) ); + + /* Call the entry point */ + + if (debugging) { - if (odp->valid && - (odp->type == FUNCTYPE_PASCAL || odp->type == FUNCTYPE_PASCAL_16 || - odp->type == FUNCTYPE_REG)) - { - fdp = odp->additional_data; - fprintf(fp, "extern int %s();\n", fdp->internal_name); - } + printf( "\tpushl %%eax\n" ); + printf( "\tpushl $CALL32_Str_%s\n", profile ); + printf( "\tcall " PREFIX "RELAY_DebugCall32\n" ); + printf( "\tpopl %%eax\n" ); + printf( "\tpopl %%eax\n" ); } - /******* Michael Veksler 95-2-3 (pointers instead of fixed data) ****/ - fprintf(fp,"unsigned short %s_offsets[]={\n" , UpperDLLName); - prev_index=-1; /* Index to previous #define (-1 if none) */ - /* the difference between last #define and the current */ - prev_n_args= 0; - - odp = OrdinalDefinitions; - for (i = 0; i <= Limit; i++, odp++) + printf( "\tcall %%eax\n" ); + + if (debugging) { - fdp = odp->additional_data; + printf( "\tpushl %%eax\n" ); + printf( "\tpushl $%d\n", short_ret ); + printf( "\tcall " PREFIX "RELAY_DebugReturn\n" ); + printf( "\tpopl %%eax\n" ); + printf( "\tpopl %%eax\n" ); + } - switch (odp->type) - { - case FUNCTYPE_PASCAL: - case FUNCTYPE_PASCAL_16: - case FUNCTYPE_REG: - if (!odp->valid || fdp->n_args_16 <= 0) continue; - if (prev_index<0) - fprintf(fp,"#\tdefine %s_ref_%d 0\n\t", UpperDLLName, i); - else - fprintf(fp,"#\tdefine %s_ref_%d %s_ref_%d+%d\n\t", - UpperDLLName,i, UpperDLLName,prev_index ,prev_n_args); - for (argnum = 0; argnum < fdp->n_args_16; argnum++) - fprintf(fp, "%d, ", fdp->arg_16_offsets[argnum]); - fprintf(fp,"\n"); - - prev_n_args=fdp->n_args_16; - prev_index=i; + if (reg_func) + printf( "\taddl $%d,%%esp\n", sizeof(struct sigcontext_struct) ); + else if (*args) + printf( "\taddl $%d,%%esp\n", 4 * strlen(args) ); + + /* Restore the 16-bit stack */ + + printf( "\tmovw " PREFIX "IF1632_Saved16_ss,%%ss\n" ); + printf( "\tmovw " PREFIX "IF1632_Saved16_sp,%%sp\n" ); + printf( "\tmovw " PREFIX "IF1632_Saved16_bp,%%bp\n" ); + printf( "\tpopw " PREFIX "IF1632_Saved16_ss\n" ); + printf( "\tpopw " PREFIX "IF1632_Saved16_sp\n" ); + printf( "\tpopw " PREFIX "IF1632_Saved16_bp\n" ); + + /* Restore registers from the context structure */ + + if (reg_func) + { + printf( "\tandl $0xffff,%%ebp\n" ); + RestoreContext(); + } + else /* Store the return value in dx:ax if needed */ + { + if (!short_ret) + { + printf( "\tpushl %%eax\n" ); + printf( "\tpopw %%dx\n" ); + printf( "\tpopw %%dx\n" ); } - } - fprintf(fp,"};\n"); + } + /* Restore ds and bp */ - fprintf(fp,"unsigned char %s_types[]={\n" , UpperDLLName); + printf( "\tpopw %%ds\n" ); + printf( "\tmovw %%bp,%%sp\n" ); + printf( "\tpopw %%bp\n" ); - odp = OrdinalDefinitions; - for (i = 0; i <= Limit; i++, odp++) + /* Remove the arguments and return */ + + if (argsize) { - int argnum; + printf( "\t.byte 0x66\n" ); + printf( "\tlret $%d\n", argsize ); + } + else + { + printf( "\t.byte 0x66\n" ); + printf( "\tlret\n" ); + } +} - fdp = odp->additional_data; - switch (odp->type) - { - case FUNCTYPE_PASCAL: - case FUNCTYPE_PASCAL_16: - case FUNCTYPE_REG: - if (!odp->valid || fdp->n_args_16 <= 0) continue; - - fprintf(fp,"/* %s_%d */\n\t", UpperDLLName, i); - - for (argnum = 0; argnum < fdp->n_args_16; argnum++) - fprintf(fp, "%d, ", fdp->arg_types_16[argnum]); - fprintf(fp,"\n"); +/******************************************************************* + * BuildCall16Func + * + * Build a 16-bit callback function. + * + * Stack frame of the callback function: + * ... ... + * (ebp+22) arg2 + * (ebp+18) arg1 + * (ebp+14) 16-bit ds + * (ebp+10) func to call + * (ebp+8) code selector + * (ebp+4) return address + * (ebp) previous ebp + * + * Prototypes for the CallTo16 functions: + * extern WORD CallTo16_word_xxx( FARPROC func, WORD ds, args... ); + * extern LONG CallTo16_long_xxx( FARPROC func, WORD ds, args... ); + * extern void CallTo16_regs_( FARPROC func, WORD ds, WORD es, WORD ax, + * WORD bx, WORD cx, WORD dx, WORD si, WORD di ); + */ +static void BuildCall16Func( char *profile ) +{ + int short_ret = 0; + int reg_func = 0; + char *args = profile + 5; + + if (!strncmp( "word_", profile, 5 )) short_ret = 1; + else if (!strncmp( "regs_", profile, 5 )) reg_func = short_ret = 1; + else if (strncmp( "long_", profile, 5 )) + { + fprintf( stderr, "Invalid function name '%s', ignored\n", profile ); + return; + } + + /* Function header */ + + printf( "/**********\n" ); + printf( " * " PREFIX "CallTo16_%s\n", profile ); + printf( " **********/\n" ); + printf( "\t.align 4\n" ); + printf( "\t.global " PREFIX "CallTo16_%s\n\n", profile ); + printf( PREFIX "CallTo16_%s:\n", profile ); + + /* Push code selector before return address to simulate a lcall */ + + printf( "\tpopl %%eax\n" ); + printf( "\tpushw $0x%04x\n", WINE_CODE_SELECTOR ); + printf( "\tpushl %%eax\n" ); + + /* Entry code */ + + printf( "\tpushl %%ebp\n" ); + printf( "\tmovl %%esp,%%ebp\n" ); + + /* Save the 32-bit registers */ + + printf( "\tpushl %%ebx\n" ); + printf( "\tpushl %%ecx\n" ); + printf( "\tpushl %%edx\n" ); + printf( "\tpushl %%esi\n" ); + printf( "\tpushl %%edi\n" ); + + /* Save the 32-bit stack */ + + printf( "\tpushl " PREFIX "IF1632_Saved32_esp\n" ); + printf( "\tpushl " PREFIX "IF1632_Saved32_ebp\n" ); + printf( "\tmovl %%esp," PREFIX "IF1632_Saved32_esp\n" ); + printf( "\tmovl %%ebp," PREFIX "IF1632_Saved32_ebp\n" ); + printf( "\tmovl %%ebp,%%ebx\n" ); + + /* Print debugging info */ + + if (debugging) + { + /* Push the address of the first argument */ + printf( "\tmovl %%ebx,%%eax\n" ); + printf( "\taddl $10,%%eax\n" ); + printf( "\tpushl $%d\n", reg_func ? 7 : strlen(args) ); + printf( "\tpushl %%eax\n" ); + printf( "\tcall " PREFIX "RELAY_DebugCall16\n" ); + printf( "\tpopl %%eax\n" ); + printf( "\tpopl %%eax\n" ); + } + + /* Switch to the 16-bit stack */ + + printf( "\tmovw " PREFIX "IF1632_Saved16_ss,%%ss\n" ); + printf( "\tmovw " PREFIX "IF1632_Saved16_sp,%%sp\n" ); + printf( "\tmovzwl " PREFIX "IF1632_Saved16_bp,%%ebp\n" ); + + /* Transfer the arguments */ + + if (reg_func) + { + /* Get the registers. ebx is handled later on. */ + printf( "\tmovl 18(%%ebx),%%es\n" ); + printf( "\tmovl 22(%%ebx),%%eax\n" ); + printf( "\tmovl 30(%%ebx),%%ecx\n" ); + printf( "\tmovl 34(%%ebx),%%edx\n" ); + printf( "\tmovl 38(%%ebx),%%esi\n" ); + printf( "\tmovl 42(%%ebx),%%edi\n" ); + } + else /* not a register function */ + { + int pos = 18; /* first argument position */ + while (*args) + { + switch(*args++) + { + case 'w': /* word */ + printf( "\tpushw %d(%%ebx)\n", pos ); + break; + case 'l': /* long */ + printf( "\tpushl %d(%%ebx)\n", pos ); + break; + } + pos += 4; } - } - fprintf(fp,"};\n"); + } + /* Push the return address */ - /**************************************************/ - fprintf(fp, "\nstruct dll_table_entry_s %s_table[%d] =\n", - UpperDLLName, Limit + 1); - fprintf(fp, "{\n"); - odp = OrdinalDefinitions; - for (i = 0; i <= Limit; i++, odp++) + printf( "\tpushl " PREFIX "CALL16_RetAddr_%s\n", + short_ret ? "word" : "long" ); + + /* Push the called routine address */ + + printf( "\tpushl 10(%%ebx)\n" ); + + /* Get the 16-bit ds */ + /* FIXME: this shouldn't be necessary if function prologs fixup worked. */ + + printf( "\tmovw 14(%%ebx),%%ds\n" ); + + if (reg_func) { - fdp = odp->additional_data; + /* Retrieve ebx from the 32-bit stack */ + printf( "\tmovl %%fs:26(%%ebx),%%ebx\n" ); + } + else + { + /* Set ax equal to ds for window procedures */ + printf( "\tmovw %%ds,%%ax\n" ); + } - if (!odp->valid) - odp->type = -1; - - switch (odp->type) - { - case FUNCTYPE_PASCAL: - case FUNCTYPE_PASCAL_16: - case FUNCTYPE_REG: - fprintf(fp, " { 0x%x, %s_Ordinal_%d, ", UTEXTSEL, UpperDLLName, i); - fprintf(fp, "\042%s\042, ", odp->export_name); - fprintf(fp, "%s, ", fdp->internal_name); - fprintf(fp, "%d, ", fdp->n_args_16); - if (fdp->n_args_16 > 0) - fprintf(fp,"%s_ref_%d", UpperDLLName, i); - else - fprintf(fp," 0 "); - -#ifdef WINESTAT - fprintf(fp, ",0 "); -#endif - fprintf(fp, "}, \n"); - break; - - default: - fprintf(fp, " { 0x%x, %s_Ordinal_%d, \042\042, NULL },\n", - UTEXTSEL, UpperDLLName, i); - break; - } + /* Jump to the called routine */ + + printf( "\t.byte 0x66\n" ); + printf( "\tlret\n" ); +} + + +/******************************************************************* + * BuildRet16Func + * + * Build the return code for 16-bit callbacks + */ +static void BuildRet16Func() +{ + printf( "\t.globl " PREFIX "CALL16_Ret_word\n" ); + printf( "\t.globl " PREFIX "CALL16_Ret_long\n" ); + + /* Put return value into eax */ + + printf( PREFIX "CALL16_Ret_long:\n" ); + printf( "\tpushw %%dx\n" ); + printf( "\tpushw %%ax\n" ); + printf( "\tpopl %%eax\n" ); + printf( PREFIX "CALL16_Ret_word:\n" ); + + /* Restore 32-bit segment registers */ + + printf( "\tmovw $0x%04x,%%bx\n", WINE_DATA_SELECTOR ); + printf( "\tmovw %%bx,%%ds\n" ); + printf( "\tmovw %%bx,%%es\n" ); + printf( "\tmovw %%bx,%%ss\n" ); + + /* Restore the 32-bit stack */ + + printf( "\tmovl " PREFIX "IF1632_Saved32_esp,%%esp\n" ); + printf( "\tmovl " PREFIX "IF1632_Saved32_ebp,%%ebp\n" ); + printf( "\tpopl " PREFIX "IF1632_Saved32_ebp\n" ); + printf( "\tpopl " PREFIX "IF1632_Saved32_esp\n" ); + + /* Restore the 32-bit registers */ + + printf( "\tpopl %%edi\n" ); + printf( "\tpopl %%esi\n" ); + printf( "\tpopl %%edx\n" ); + printf( "\tpopl %%ecx\n" ); + printf( "\tpopl %%ebx\n" ); + + /* Return to caller */ + + printf( "\tmovl %%ebp,%%esp\n" ); + printf( "\tpopl %%ebp\n" ); + printf( "\tlret\n" ); + + /* Declare the return address variables */ + + printf( "\t.data\n" ); + printf( "\t.globl " PREFIX "CALL16_RetAddr_word\n" ); + printf( "\t.globl " PREFIX "CALL16_RetAddr_long\n" ); + printf( PREFIX "CALL16_RetAddr_word:\t.long 0\n" ); + printf( PREFIX "CALL16_RetAddr_long:\t.long 0\n" ); + printf( "\t.text\n" ); +} + + +static void usage(void) +{ + fprintf(stderr, "usage: build -spec SPECNAMES\n" + " build -call32 FUNCTION_PROFILES\n" + " build -call16 FUNCTION_PROFILES\n" ); + exit(1); +} + + +int main(int argc, char **argv) +{ + int i; + + if (argc <= 2) usage(); + + if (!strcmp( argv[1], "-spec" )) + { + for (i = 2; i < argc; i++) BuildSpecFiles( argv[i] ); } - fprintf(fp, "};\n"); + else if (!strcmp( argv[1], "-call32" )) /* 32-bit callbacks */ + { + /* File header */ + + printf( "/* File generated automatically. Do no edit! */\n\n" ); + printf( "\t.text\n" ); + + /* Build the callback functions */ + + for (i = 2; i < argc; i++) BuildCall32Func( argv[i] ); + + /* Output the argument debugging strings */ + + if (debugging) + { + printf( "/* Argument strings */\n" ); + for (i = 2; i < argc; i++) + { + printf( "CALL32_Str_%s:\n", argv[i] ); + printf( "\t.ascii \"%s\\0\"\n", argv[i] + 5 ); + } + } + } + else if (!strcmp( argv[1], "-call16" )) /* 16-bit callbacks */ + { + /* File header */ + + printf( "/* File generated automatically. Do no edit! */\n\n" ); + printf( "\t.text\n" ); + printf( "\t.globl " PREFIX "CALL16_Start\n" ); + printf( PREFIX "CALL16_Start:\n" ); + + /* Build the callback functions */ + + for (i = 2; i < argc; i++) BuildCall16Func( argv[i] ); + + /* Output the 16-bit return code */ + + BuildRet16Func(); + + printf( "\t.globl " PREFIX "CALL16_End\n" ); + printf( PREFIX "CALL16_End:\n" ); + } + else usage(); - fclose(fp); return 0; } - diff --git a/tools/newbuild.c b/tools/newbuild.c deleted file mode 100644 index f9f8e42cf54..00000000000 --- a/tools/newbuild.c +++ /dev/null @@ -1,958 +0,0 @@ -static char RCSId[] = "$Id: build.c,v 1.3 1993/07/04 04:04:21 root Exp root $"; -static char Copyright[] = "Copyright Robert J. Amstadt, 1993"; - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> - -#ifdef linux -#ifdef __ELF__ -#define UTEXTSEL 0x0f -#else -#define UTEXTSEL 0x23 -#endif -#define UDATASEL 0x2b -#endif -#if defined(__NetBSD__) || defined(__FreeBSD__) -#define UTEXTSEL 0x1f -#define UDATASEL 0x27 -#endif - -#define VARTYPE_BYTE 0 -#define VARTYPE_SIGNEDWORD 0 -#define VARTYPE_WORD 1 -#define VARTYPE_LONG 2 -#define VARTYPE_FARPTR 3 - -#define FUNCTYPE_PASCAL 16 -#define FUNCTYPE_C 17 -#define FUNCTYPE_REG 19 - -#define EQUATETYPE_ABS 18 -#define TYPE_RETURN 20 - -#define MAX_ORDINALS 1024 - -typedef struct ordinal_definition_s -{ - int valid; - int type; - char export_name[80]; - void *additional_data; -} ORDDEF; - -typedef struct ordinal_variable_definition_s -{ - int n_values; - int *values; -} ORDVARDEF; - -typedef struct ordinal_function_definition_s -{ - int n_args_16; - int arg_types_16[16]; - int arg_16_offsets[16]; - int arg_16_size; - char internal_name[80]; - int n_args_32; - int arg_indices_32[16]; -} ORDFUNCDEF; - -typedef struct ordinal_return_definition_s -{ - int arg_size; - int ret_value; -} ORDRETDEF; - -ORDDEF OrdinalDefinitions[MAX_ORDINALS]; - -char LowerDLLName[80]; -char UpperDLLName[80]; -int Limit; -int DLLId; -FILE *SpecFp; - -char *ParseBuffer = NULL; -char *ParseNext; -char ParseSaveChar; -int Line; - -int IsNumberString(char *s) -{ - while (*s != '\0') - if (!isdigit(*s++)) - return 0; - - return 1; -} - -char *strlower(char *s) -{ - char *p; - - for(p = s; *p != '\0'; p++) - *p = tolower(*p); - - return s; -} - -char *strupper(char *s) -{ - char *p; - - for(p = s; *p != '\0'; p++) - *p = toupper(*p); - - return s; -} - -int stricmp(char *s1, char *s2) -{ - if (strlen(s1) != strlen(s2)) - return -1; - - while (*s1 != '\0') - if (*s1++ != *s2++) - return -1; - - return 0; -} - -char * -GetTokenInLine(void) -{ - char *p; - char *token; - - if (ParseNext != ParseBuffer) - { - if (ParseSaveChar == '\0') - return NULL; - *ParseNext = ParseSaveChar; - } - - /* - * Remove initial white space. - */ - for (p = ParseNext; isspace(*p); p++) - ; - - if (*p == '\0') - return NULL; - - /* - * Find end of token. - */ - token = p++; - if (*token != '(' && *token != ')') - while (*p != '\0' && *p != '(' && *p != ')' && !isspace(*p)) - p++; - - ParseSaveChar = *p; - ParseNext = p; - *p = '\0'; - - return token; -} - -char * -GetToken(void) -{ - char *token; - - if (ParseBuffer == NULL) - { - ParseBuffer = malloc(512); - ParseNext = ParseBuffer; - Line++; - while (1) - { - if (fgets(ParseBuffer, 511, SpecFp) == NULL) - return NULL; - if (ParseBuffer[0] != '#') - break; - } - } - - while ((token = GetTokenInLine()) == NULL) - { - ParseNext = ParseBuffer; - Line++; - while (1) - { - if (fgets(ParseBuffer, 511, SpecFp) == NULL) - return NULL; - if (ParseBuffer[0] != '#') - break; - } - } - - return token; -} - -int -ParseVariable(int ordinal, int type) -{ - ORDDEF *odp; - ORDVARDEF *vdp; - char export_name[80]; - char *token; - char *endptr; - int *value_array; - int n_values; - int value_array_size; - - strcpy(export_name, GetToken()); - - token = GetToken(); - if (*token != '(') - { - fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token); - exit(1); - } - - n_values = 0; - value_array_size = 25; - value_array = malloc(sizeof(*value_array) * value_array_size); - - while ((token = GetToken()) != NULL) - { - if (*token == ')') - break; - - value_array[n_values++] = strtol(token, &endptr, 0); - if (n_values == value_array_size) - { - value_array_size += 25; - value_array = realloc(value_array, - sizeof(*value_array) * value_array_size); - } - - if (endptr == NULL || *endptr != '\0') - { - fprintf(stderr, "%d: Expected number value, got '%s'\n", Line, - token); - exit(1); - } - } - - if (token == NULL) - { - fprintf(stderr, "%d: End of file in variable declaration\n", Line); - exit(1); - } - - if (ordinal >= MAX_ORDINALS) - { - fprintf(stderr, "%d: Ordinal number too large\n", Line); - exit(1); - } - - odp = &OrdinalDefinitions[ordinal]; - odp->valid = 1; - odp->type = type; - strcpy(odp->export_name, export_name); - - vdp = malloc(sizeof(*vdp)); - odp->additional_data = vdp; - - vdp->n_values = n_values; - vdp->values = realloc(value_array, sizeof(*value_array) * n_values); - - return 0; -} - -int -ParseExportFunction(int ordinal, int type) -{ - char *token; - ORDDEF *odp; - ORDFUNCDEF *fdp; - int arg_types[16]; - int i; - int arg_num; - int current_offset; - int arg_size; - - - if (ordinal >= MAX_ORDINALS) - { - fprintf(stderr, "%d: Ordinal number too large\n", Line); - exit(1); - } - - odp = &OrdinalDefinitions[ordinal]; - strcpy(odp->export_name, GetToken()); - odp->valid = 1; - odp->type = type; - fdp = malloc(sizeof(*fdp)); - odp->additional_data = fdp; - - token = GetToken(); - if (*token != '(') - { - fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token); - exit(1); - } - - fdp->arg_16_size = 0; - for (i = 0; i < 16; i++) - { - token = GetToken(); - if (*token == ')') - break; - - if (stricmp(token, "byte") == 0 || stricmp(token, "word") == 0) - { - fdp->arg_types_16[i] = VARTYPE_WORD; - fdp->arg_16_size += 2; - fdp->arg_16_offsets[i] = 2; - } - else if (stricmp(token, "s_byte") == 0 || - stricmp(token, "s_word") == 0) - { - fdp->arg_types_16[i] = VARTYPE_SIGNEDWORD; - fdp->arg_16_size += 2; - fdp->arg_16_offsets[i] = 2; - } - else if (stricmp(token, "long") == 0 || stricmp(token, "s_long") == 0) - { - fdp->arg_types_16[i] = VARTYPE_LONG; - fdp->arg_16_size += 4; - fdp->arg_16_offsets[i] = 4; - } - else if (stricmp(token, "ptr") == 0) - { - fdp->arg_types_16[i] = VARTYPE_FARPTR; - fdp->arg_16_size += 4; - fdp->arg_16_offsets[i] = 4; - } - else - { - fprintf(stderr, "%d: Unknown variable type '%s'\n", Line, token); - exit(1); - } - } - fdp->n_args_16 = i; - - if (type == FUNCTYPE_PASCAL || type == FUNCTYPE_REG) - { - current_offset = 0; - for (i--; i >= 0; i--) - { - arg_size = fdp->arg_16_offsets[i]; - fdp->arg_16_offsets[i] = current_offset; - current_offset += arg_size; - } - } - else - { - current_offset = 0; - for (i = 0; i < fdp->n_args_16; i++) - { - arg_size = fdp->arg_16_offsets[i]; - fdp->arg_16_offsets[i] = current_offset; - current_offset += arg_size; - } - } - - strcpy(fdp->internal_name, GetToken()); - token = GetToken(); - if (*token != '(') - { - fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token); - exit(1); - } - for (i = 0; i < 16; i++) - { - token = GetToken(); - if (*token == ')') - break; - - fdp->arg_indices_32[i] = atoi(token); - if (fdp->arg_indices_32[i] < 1 || - fdp->arg_indices_32[i] > fdp->n_args_16) - { - fprintf(stderr, "%d: Bad argument index %d\n", Line, - fdp->arg_indices_32[i]); - exit(1); - } - } - fdp->n_args_32 = i; - - return 0; -} - -int -ParseEquate(int ordinal) -{ - ORDDEF *odp; - char *token; - char *endptr; - int value; - - if (ordinal >= MAX_ORDINALS) - { - fprintf(stderr, "%d: Ordinal number too large\n", Line); - exit(1); - } - - odp = &OrdinalDefinitions[ordinal]; - strcpy(odp->export_name, GetToken()); - - token = GetToken(); - value = strtol(token, &endptr, 0); - if (endptr == NULL || *endptr != '\0') - { - fprintf(stderr, "%d: Expected number value, got '%s'\n", Line, - token); - exit(1); - } - - odp->valid = 1; - odp->type = EQUATETYPE_ABS; - odp->additional_data = (void *) value; - - return 0; -} - -int -ParseReturn(int ordinal) -{ - ORDDEF *odp; - ORDRETDEF *rdp; - char *token; - char *endptr; - int value; - - if (ordinal >= MAX_ORDINALS) - { - fprintf(stderr, "%d: Ordinal number too large\n", Line); - exit(1); - } - - rdp = malloc(sizeof(*rdp)); - - odp = &OrdinalDefinitions[ordinal]; - strcpy(odp->export_name, GetToken()); - odp->valid = 1; - odp->type = TYPE_RETURN; - odp->additional_data = rdp; - - token = GetToken(); - rdp->arg_size = strtol(token, &endptr, 0); - if (endptr == NULL || *endptr != '\0') - { - fprintf(stderr, "%d: Expected number value, got '%s'\n", Line, - token); - exit(1); - } - - token = GetToken(); - rdp->ret_value = strtol(token, &endptr, 0); - if (endptr == NULL || *endptr != '\0') - { - fprintf(stderr, "%d: Expected number value, got '%s'\n", Line, - token); - exit(1); - } - - return 0; -} - -int -ParseOrdinal(int ordinal) -{ - char *token; - - token = GetToken(); - if (token == NULL) - { - fprintf(stderr, "%d: Expected type after ordinal\n", Line); - exit(1); - } - - if (stricmp(token, "byte") == 0) - return ParseVariable(ordinal, VARTYPE_BYTE); - else if (stricmp(token, "word") == 0) - return ParseVariable(ordinal, VARTYPE_WORD); - else if (stricmp(token, "long") == 0) - return ParseVariable(ordinal, VARTYPE_LONG); - else if (stricmp(token, "c") == 0) - return ParseExportFunction(ordinal, FUNCTYPE_C); - else if (stricmp(token, "p") == 0) - return ParseExportFunction(ordinal, FUNCTYPE_PASCAL); - else if (stricmp(token, "pascal") == 0) - return ParseExportFunction(ordinal, FUNCTYPE_PASCAL); - else if (stricmp(token, "register") == 0) - return ParseExportFunction(ordinal, FUNCTYPE_REG); - else if (stricmp(token, "equate") == 0) - return ParseEquate(ordinal); - else if (stricmp(token, "return") == 0) - return ParseReturn(ordinal); - else - { - fprintf(stderr, - "%d: Expected type after ordinal, found '%s' instead\n", - Line, token); - exit(1); - } -} - -int -ParseTopLevel(void) -{ - char *token; - - while ((token = GetToken()) != NULL) - { - if (stricmp(token, "name") == 0) - { - strcpy(LowerDLLName, GetToken()); - strlower(LowerDLLName); - - strcpy(UpperDLLName, LowerDLLName); - strupper(UpperDLLName); - } - else if (stricmp(token, "id") == 0) - { - token = GetToken(); - if (!IsNumberString(token)) - { - fprintf(stderr, "%d: Expected number after id\n", Line); - exit(1); - } - - DLLId = atoi(token); - } - else if (stricmp(token, "length") == 0) - { - token = GetToken(); - if (!IsNumberString(token)) - { - fprintf(stderr, "%d: Expected number after length\n", Line); - exit(1); - } - - Limit = atoi(token); - } - else if (IsNumberString(token)) - { - int ordinal; - int rv; - - ordinal = atoi(token); - if ((rv = ParseOrdinal(ordinal)) < 0) - return rv; - } - else - { - fprintf(stderr, - "%d: Expected name, id, length or ordinal\n", Line); - exit(1); - } - } - - return 0; -} - -void -OutputVariableCode(FILE *fp, char *storage, ORDDEF *odp) -{ - ORDVARDEF *vdp; - int i; - - fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i); - - vdp = odp->additional_data; - for (i = 0; i < vdp->n_values; i++) - { - if ((i & 7) == 0) - fprintf(fp, "\t%s\t", storage); - - fprintf(fp, "%d", vdp->values[i]); - - if ((i & 7) == 7 || i == vdp->n_values - 1) - fprintf(fp, "\n"); - else - fprintf(fp, ", "); - } - fprintf(fp, "\n"); -} - -main(int argc, char **argv) -{ - ORDDEF *odp; - ORDFUNCDEF *fdp; - ORDRETDEF *rdp; - FILE *fp; - char filename[80]; - char buffer[80]; - char *p; - int i; - - if (argc < 2) - { - fprintf(stderr, "usage: build SPECNAME\n"); - exit(1); - } - - SpecFp = fopen(argv[1], "r"); - if (SpecFp == NULL) - { - fprintf(stderr, "Could not open specification file, '%s'\n", argv[1]); - exit(1); - } - - ParseTopLevel(); - - /********************************************************************** - * DLL ENTRY POINTS - */ - sprintf(filename, "dll_%s.S", LowerDLLName); - fp = fopen(filename, "w"); - - fprintf(fp, "\t.globl _%s_Dispatch\n", UpperDLLName); - fprintf(fp, "_%s_Dispatch:\n", UpperDLLName); - fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n"); - fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n"); - fprintf(fp, "\torl\t$0x%08x,%%eax\n", DLLId << 16); - fprintf(fp, "\tjmp\t_CallTo32\n\n"); - - odp = OrdinalDefinitions; - for (i = 0; i <= Limit; i++, odp++) - { - fprintf(fp, "\t.globl _%s_Ordinal_%d\n", UpperDLLName, i); - - if (!odp->valid) - { - fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i); -#ifdef BOB_SAYS_NO - fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n"); - fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n"); -#endif - fprintf(fp, "\tmovl\t$%d,%%eax\n", i); - fprintf(fp, "\tpushw\t$0\n"); - fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName); - } - else - { - fdp = odp->additional_data; - rdp = odp->additional_data; - - switch (odp->type) - { - case EQUATETYPE_ABS: - fprintf(fp, "_%s_Ordinal_%d = %d\n\n", - UpperDLLName, i, (int) odp->additional_data); - break; - - case VARTYPE_BYTE: - OutputVariableCode(fp, ".byte", odp); - break; - - case VARTYPE_WORD: - OutputVariableCode(fp, ".word", odp); - break; - - case VARTYPE_LONG: - OutputVariableCode(fp, ".long", odp); - break; - - case TYPE_RETURN: - fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i); - fprintf(fp, "\tmovw\t$%d,%%ax\n", rdp->ret_value & 0xffff); - fprintf(fp, "\tmovw\t$%d,%%dx\n", - (rdp->ret_value >> 16) & 0xffff); - fprintf(fp, "\t.byte\t0x66\n"); - if (rdp->arg_size != 0) - fprintf(fp, "\tlret\t$%d\n", rdp->arg_size); - else - fprintf(fp, "\tlret\n"); - break; - - case FUNCTYPE_REG: - fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i); - fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n"); - fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n"); - fprintf(fp, "\tpushl\t$0\n"); /* cr2 */ - fprintf(fp, "\tpushl\t$0\n"); /* oldmask */ - fprintf(fp, "\tpushl\t$0\n"); /* i387 */ - fprintf(fp, "\tpushw\t$0\n"); /* __ssh */ - fprintf(fp, "\tpushw\t%%ss\n"); /* ss */ - fprintf(fp, "\tpushl\t%%esp\n"); /* esp */ - fprintf(fp, "\tpushfl\n"); /* eflags */ - fprintf(fp, "\tpushw\t$0\n"); /* __csh */ - fprintf(fp, "\tpushw\t%%cs\n"); /* cs */ - fprintf(fp, "\tpushl\t$0\n"); /* eip */ - fprintf(fp, "\tpushl\t$0\n"); /* err */ - fprintf(fp, "\tpushl\t$0\n"); /* trapno */ - fprintf(fp, "\tpushal\n"); /* AX, ... */ - fprintf(fp, "\tpushw\t$0\n"); /* __dsh */ - fprintf(fp, "\tpushw\t%%ds\n"); /* ds */ - fprintf(fp, "\tpushw\t$0\n"); /* __esh */ - fprintf(fp, "\tpushw\t%%es\n"); /* es */ - fprintf(fp, "\tpushw\t$0\n"); /* __fsh */ - fprintf(fp, "\tpushw\t%%fs\n"); /* fs */ - fprintf(fp, "\tpushw\t$0\n"); /* __gsh */ - fprintf(fp, "\tpushw\t%%gs\n"); /* gs */ - fprintf(fp, "\tmovl\t%%ebp,%%eax\n"); - fprintf(fp, "\tmovw\t%%esp,%%ebp\n"); - fprintf(fp, "\tpushl\t88(%%ebp)\n"); - fprintf(fp, "\tmovl\t%%eax,%%ebp\n"); - fprintf(fp, "\tmovl\t$%d,%%eax\n", i); - fprintf(fp, "\tpushw\t$92\n"); - fprintf(fp, "\tjmp\t_%s_Relay_%d:\n", UpperDLLName, i); - break; - - case FUNCTYPE_PASCAL: - fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i); -#ifdef BOB_SAYS_NO - fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n"); - fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n"); -#endif - fprintf(fp, "\tmovl\t$%d,%%eax\n", i); - fprintf(fp, "\tpushw\t$%d\n", fdp->arg_16_size); - fprintf(fp, "\tjmp\t_%s_Relay_%d:\n", UpperDLLName, i); - break; - - case FUNCTYPE_C: - default: - fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i); -#ifdef BOB_SAYS_NO - fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n"); - fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n"); -#endif - fprintf(fp, "\tmovl\t$%d,%%eax\n", i); - fprintf(fp, "\tpushw\t$0\n"); - fprintf(fp, "\tjmp\t_%s_Relay_%d:\n", UpperDLLName, i); - break; - } - } - } - - fclose(fp); - - /********************************************************************** - * RELAY CODE - */ - sprintf(filename, "rly_%s.S", LowerDLLName); - fp = fopen(filename, "w"); - - odp = OrdinalDefinitions; - for (i = 0; i <= Limit; i++, odp++) - { - if (!odp->valid) - continue; - - fdp = odp->additional_data; - - fprintf(fp, "\t.globl _%s_Relay_%d\n", UpperDLLName, i); - fprintf(fp, "_%s_Relay_%d:\n", UpperDLLName, i); - fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n"); - fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n"); - - fprintf(fp, "\tpushl\t%%ebp\n"); - fprintf(fp, "\tmovl\t%%esp,%%ebp\n"); - - /* - * Save registers. 286 mode does not have fs or gs. - */ - fprintf(fp, "\tpushw\t%%ds\n"); - fprintf(fp, "\tpushw\t%%es\n"); - - /* - * Restore segment registers. - */ - fprintf(fp, "\tmovw\t%d,%%ax\n", UDATASEL); - fprintf(fp, "\tmovw\t%%ax,%%ds\n"); - fprintf(fp, "\tmovw\t%%ax,%%es\n"); - - /* - * Save old stack save variables, save stack registers, reload - * stack registers. - */ - fprintf(fp, "\tpushl\t_IF1632_Saved16_esp\n"); - fprintf(fp, "\tpushl\t_IF1632_Saved16_ebp\n"); - fprintf(fp, "\tpushw\t_IF1632_Saved16_ss\n"); - - fprintf(fp, "\tmovw\t%%ss,_IF1632_Saved16_ss\n"); - fprintf(fp, "\tmovl\t%%esp,_IF1632_Saved16_esp\n"); - fprintf(fp, "\tmovl\t%%ebp,_IF1632_Saved16_ebp\n"); - - fprintf(fp, "\tmovw\t%%ss,%%ax\n"); - fprintf(fp, "\tshll\t16,%%eax\n"); - fprintf(fp, "\torl\t%%esp,%%eax\n"); - - fprintf(fp, "\tmovw\t_IF1632_Saved32_ss,%%ss\n"); - fprintf(fp, "\tmovl\t_IF1632_Saved32_esp,%%esp\n"); - fprintf(fp, "\tmovl\t_IF1632_Saved32_ebp,%%ebp\n"); - - fprintf(fp, "\tpushl\t_Stack16Frame\n"); - fprintf(fp, "\tmovl\t%%eax,_Stack16Frame\n"); - - /* - * Move arguments. - */ - - - /* - * Call entry point - */ - fprintf(fp, "\tcall\t%s\n", fdp->internal_name); - - /* - * Restore registers, but do not destroy return value. - */ - fprintf(fp, "\tmovw\t_IF1632_Saved16_ss,%%ss\n"); - fprintf(fp, "\tmovl\t_IF1632_Saved16_esp,%%esp\n"); - fprintf(fp, "\tmovl\t_IF1632_Saved16_ebp,%%ebp\n"); - - fprintf(fp, "\tpopw\t_IF1632_Saved16_ss\n"); - fprintf(fp, "\tpopl\t_IF1632_Saved16_ebp\n"); - fprintf(fp, "\tpopl\t_IF1632_Saved16_esp\n"); - - fprintf(fp, "\tpopw\t%%es\n"); - fprintf(fp, "\tpopw\t%%ds\n"); - - fprintf(fp, "\t.align\t2,0x90\n"); - fprintf(fp, "\tleave\n"); - - /* - * Now we need to ditch the parameter bytes that were left on the - * stack. We do this by effectively popping the number of bytes, - * and the return address, removing the parameters and then putting - * the return address back on the stack. - * Normally this field is filled in by the relevant function in - * the emulation library, since it should know how many bytes to - * expect. - */ - fprintf(fp, "\tpopw\t%%gs:nbytes\n"); - fprintf(fp, "\tcmpw\t$0,%%gs:nbytes\n"); - fprintf(fp, "\tje\tnoargs\n"); - fprintf(fp, "\tpopw\t%%gs:offset\n"); - fprintf(fp, "\tpopw\t%%gs:selector\n"); - fprintf(fp, "\taddw\t%%gs:nbytes,%%esp\n"); - fprintf(fp, "\tpushw\t%%gs:selector\n"); - fprintf(fp, "\tpushw\t%%gs:offset\n"); - fprintf(fp, "noargs:\n"); - - /* - * Last, but not least we need to move the high word from eax to dx - */ - fprintf(fp, "\t pushl\t%%eax\n"); - fprintf(fp, "\tpopw\t%%dx\n"); - fprintf(fp, "\tpopw\t%%dx\n"); - - fprintf(fp, "\t.byte\t0x66\n"); - fprintf(fp, "\tlret\n"); - - } - - fclose(fp); - - /********************************************************************** - * DLL ENTRY TABLE - */ -#ifndef SHORTNAMES - sprintf(filename, "dll_%s_tab.c", LowerDLLName); -#else - sprintf(filename, "dtb_%s.c", LowerDLLName); -#endif - fp = fopen(filename, "w"); - - fprintf(fp, "#include <stdio.h>\n"); - fprintf(fp, "#include <stdlib.h>\n"); - fprintf(fp, "#include \042dlls.h\042\n\n"); - - for (i = 0; i <= Limit; i++) - { - fprintf(fp, "extern void %s_Ordinal_%d();\n", UpperDLLName, i); - } - - odp = OrdinalDefinitions; - for (i = 0; i <= Limit; i++, odp++) - { - if (odp->valid && - (odp->type == FUNCTYPE_PASCAL || odp->type == FUNCTYPE_C || - odp->type == FUNCTYPE_REG)) - { - fdp = odp->additional_data; - fprintf(fp, "extern int %s();\n", fdp->internal_name); - } - } - - fprintf(fp, "\nstruct dll_table_entry_s %s_table[%d] =\n", - UpperDLLName, Limit + 1); - fprintf(fp, "{\n"); - odp = OrdinalDefinitions; - for (i = 0; i <= Limit; i++, odp++) - { - fdp = odp->additional_data; - - if (!odp->valid) - odp->type = -1; - - switch (odp->type) - { - case FUNCTYPE_PASCAL: - case FUNCTYPE_REG: - fprintf(fp, " { 0x%x, %s_Ordinal_%d, ", UTEXTSEL, UpperDLLName, i); - fprintf(fp, "\042%s\042, ", odp->export_name); - fprintf(fp, "%s, DLL_HANDLERTYPE_PASCAL, ", fdp->internal_name); -#ifdef WINESTAT - fprintf(fp, "0, "); -#endif - fprintf(fp, "%d, ", fdp->n_args_32); - if (fdp->n_args_32 > 0) - { - int argnum; - - fprintf(fp, "\n {\n"); - for (argnum = 0; argnum < fdp->n_args_32; argnum++) - { - fprintf(fp, " { %d, %d },\n", - fdp->arg_16_offsets[fdp->arg_indices_32[argnum]-1], - fdp->arg_types_16[argnum]); - } - fprintf(fp, " }\n "); - } - fprintf(fp, "}, \n"); - break; - - case FUNCTYPE_C: - fprintf(fp, " { 0x%x, %s_Ordinal_%d, ", UTEXTSEL, UpperDLLName, i); - fprintf(fp, "\042%s\042, ", odp->export_name); - fprintf(fp, "%s, DLL_HANDLERTYPE_C, ", fdp->internal_name); -#ifdef WINESTAT - fprintf(fp, "0, "); -#endif - fprintf(fp, "%d, ", fdp->n_args_32); - if (fdp->n_args_32 > 0) - { - int argnum; - - fprintf(fp, "\n {\n"); - for (argnum = 0; argnum < fdp->n_args_32; argnum++) - { - fprintf(fp, " { %d, %d },\n", - fdp->arg_16_offsets[fdp->arg_indices_32[argnum]-1], - fdp->arg_types_16[argnum]); - } - fprintf(fp, " }\n "); - } - fprintf(fp, "}, \n"); - break; - - default: - fprintf(fp, " { 0x%x, %s_Ordinal_%d, \042\042, NULL },\n", - UTEXTSEL, UpperDLLName, i); - break; - } - } - fprintf(fp, "};\n"); - - fclose(fp); -} - diff --git a/windows/caret.c b/windows/caret.c index 5c31d192afd..8f329902cfe 100644 --- a/windows/caret.c +++ b/windows/caret.c @@ -7,6 +7,7 @@ static char Copyright[] = "Copyright David Metcalfe, 1993"; */ #include "windows.h" +#include "selectors.h" #include "stddebug.h" /* #define DEBUG_CARET */ #include "debug.h" @@ -30,15 +31,13 @@ typedef struct static CARET Caret; static BOOL LockCaret; -static WORD CARET_Callback(HWND hwnd, WORD msg, WORD timerid, LONG ctime); static void CARET_HideCaret(); /***************************************************************** * CARET_Callback */ - -static WORD CARET_Callback(HWND hwnd, WORD msg, WORD timerid, LONG ctime) +WORD CARET_Callback(HWND hwnd, WORD msg, WORD timerid, LONG ctime) { HDC hdc; HBRUSH hBrush; @@ -134,7 +133,8 @@ void CreateCaret(HWND hwnd, HBITMAP bitmap, short width, short height) Caret.timeout = 750; LockCaret = FALSE; - Caret.timerid = SetSystemTimer((HWND)0, 0, Caret.timeout, (FARPROC)CARET_Callback); + Caret.timerid = SetSystemTimer( (HWND)0, 0, Caret.timeout, + (FARPROC)GetWndProcEntry16("CARET_Callback")); dprintf_caret(stddeb,"CreateCaret: hwnd=%d, timerid=%d\n", hwnd, Caret.timerid); @@ -222,7 +222,8 @@ void SetCaretBlinkTime(WORD msecs) KillSystemTimer( (HWND)0, Caret.timerid); Caret.timeout = msecs; - Caret.timerid = SetSystemTimer((HWND)0, 0, Caret.timeout, (FARPROC)CARET_Callback); + Caret.timerid = SetSystemTimer( (HWND)0, 0, Caret.timeout, + (FARPROC)GetWndProcEntry16("CARET_Callback")); } diff --git a/windows/cursor.c b/windows/cursor.c index 369506d471d..fb13b6d3761 100644 --- a/windows/cursor.c +++ b/windows/cursor.c @@ -23,6 +23,7 @@ static char Copyright[] = "Copyright Martin Ayotte, 1993"; /* #define DEBUG_CURSOR */ /* #define DEBUG_RESOURCE */ #include "debug.h" +#include "arch.h" static int ShowCursCount = 0; static HCURSOR hActiveCursor; @@ -52,16 +53,15 @@ static struct { SEGPTR name; HCURSOR cursor; } system_cursor[] = */ HCURSOR LoadCursor(HANDLE instance, SEGPTR cursor_name) { - XColor bkcolor; - XColor fgcolor; HCURSOR hCursor; HANDLE rsc_mem; WORD *lp; + LONG *lpl,size; CURSORDESCRIP *lpcurdesc; CURSORALLOC *lpcur; HDC hdc; - int i, j, image_size; - + int i, image_size; + unsigned char *cp1,*cp2; dprintf_resource(stddeb,"LoadCursor: instance = %04x, name = %08lx\n", instance, cursor_name); if (!instance) @@ -117,27 +117,29 @@ HCURSOR LoadCursor(HANDLE instance, SEGPTR cursor_name) } } -#if 1 +#if 0 + /* this code replaces all bitmap cursors with the default cursor */ lpcur->xcursor = XCreateFontCursor(display, XC_top_left_arrow); GlobalUnlock(hCursor); return hCursor; #endif - if (!(hdc = GetDC(GetDesktopWindow()))) return 0; + if (!(hdc = GetDC(0))) return 0; rsc_mem = RSC_LoadResource(instance, cursor_name, NE_RSCTYPE_GROUP_CURSOR, &image_size); if (rsc_mem == (HANDLE)NULL) { fprintf(stderr,"LoadCursor / Cursor %08lx not Found !\n", cursor_name); - ReleaseDC(GetDesktopWindow(), hdc); + ReleaseDC(0, hdc); return 0; } lp = (WORD *)GlobalLock(rsc_mem); if (lp == NULL) { GlobalFree(rsc_mem); - ReleaseDC(GetDesktopWindow(), hdc); + ReleaseDC(0, hdc); return 0; } lpcurdesc = (CURSORDESCRIP *)(lp + 3); +#if 0 dprintf_cursor(stddeb,"LoadCursor / image_size=%d\n", image_size); dprintf_cursor(stddeb,"LoadCursor / curReserved=%X\n", *lp); dprintf_cursor(stddeb,"LoadCursor / curResourceType=%X\n", *(lp + 1)); @@ -154,6 +156,7 @@ HCURSOR LoadCursor(HANDLE instance, SEGPTR cursor_name) (DWORD)lpcurdesc->curDIBSize); dprintf_cursor(stddeb,"LoadCursor / cursor curDIBOffset=%lX\n", (DWORD)lpcurdesc->curDIBOffset); +#endif lpcur->descriptor = *lpcurdesc; GlobalUnlock(rsc_mem); GlobalFree(rsc_mem); @@ -163,63 +166,64 @@ HCURSOR LoadCursor(HANDLE instance, SEGPTR cursor_name) if (rsc_mem == (HANDLE)NULL) { fprintf(stderr, "LoadCursor / Cursor %08lx Bitmap not Found !\n", cursor_name); - ReleaseDC(GetDesktopWindow(), hdc); + ReleaseDC(0, hdc); return 0; } - lp = (WORD *)GlobalLock(rsc_mem); + lpl = (LONG *)GlobalLock(rsc_mem); if (lp == NULL) { GlobalFree(rsc_mem); - ReleaseDC(GetDesktopWindow(), hdc); + ReleaseDC(0, hdc); return 0; - } - lp++; - for (j = 0; j < 16; j++) - dprintf_cursor(stddeb,"%04X ", *(lp + j)); -/* - if (*lp == sizeof(BITMAPINFOHEADER)) - lpcur->hBitmap = ConvertInfoBitmap(hdc, (BITMAPINFO *)lp); - else -*/ - lpcur->hBitmap = 0; -/* lp += sizeof(BITMAP); */ - for (i = 0; i < 81; i++) { - char temp = *((char *)lp + 162 + i); - *((char *)lp + 162 + i) = *((char *)lp + 324 - i); - *((char *)lp + 324 - i) = temp; - } - lpcur->pixshape = XCreatePixmapFromBitmapData( - display, DefaultRootWindow(display), - ((char *)lp + 211), 32, 32, -/* - lpcurdesc->Width / 2, lpcurdesc->Height / 4, -*/ - WhitePixel(display, DefaultScreen(display)), - BlackPixel(display, DefaultScreen(display)), 1); - lpcur->pixmask = XCreatePixmapFromBitmapData( - display, DefaultRootWindow(display), - ((char *)lp + 211), 32, 32, - WhitePixel(display, DefaultScreen(display)), - BlackPixel(display, DefaultScreen(display)), 1); - memset(&bkcolor, 0, sizeof(XColor)); - memset(&fgcolor, 0, sizeof(XColor)); - bkcolor.pixel = WhitePixel(display, DefaultScreen(display)); - fgcolor.pixel = BlackPixel(display, DefaultScreen(display)); - dprintf_cursor(stddeb,"LoadCursor / before XCreatePixmapCursor !\n"); - lpcur->xcursor = XCreatePixmapCursor(display, - lpcur->pixshape, lpcur->pixmask, - &fgcolor, &bkcolor, lpcur->descriptor.curXHotspot, - lpcur->descriptor.curYHotspot); + } + lpl++; + size = CONV_LONG (*lpl); + if (size == sizeof(BITMAPCOREHEADER)){ + CONV_BITMAPCOREHEADER (lpl); + ((BITMAPINFOHEADER *)lpl)->biHeight /= 2; + lpcur->hBitmap = ConvertCoreBitmap( hdc, (BITMAPCOREHEADER *) lpl ); + } else if (size == sizeof(BITMAPINFOHEADER)){ + CONV_BITMAPINFO (lpl); + ((BITMAPINFOHEADER *)lpl)->biHeight /= 2; + lpcur->hBitmap = ConvertInfoBitmap( hdc, (BITMAPINFO *) lpl ); + } else { + fprintf(stderr,"No bitmap for cursor?\n"); + lpcur->hBitmap = 0; + } + lpl = (char *)lpl + size + 8; + /* This is rather strange! The data is stored *BACKWARDS* and */ + /* mirrored! But why?? FIXME: the image must be flipped at the Y */ + /* axis, either here or in CreateCusor(); */ + size = lpcur->descriptor.Height/2 * ((lpcur->descriptor.Width+7)/8); +#if 0 + dprintf_cursor(stddeb,"Before:\n"); + for(i=0;i<2*size;i++) { + dprintf_cursor(stddeb,"%02x ",((unsigned char *)lpl)[i]); + if ((i & 7) == 7) dprintf_cursor(stddeb,"\n"); + } +#endif + cp1 = (char *)lpl; + cp2 = cp1+2*size; + for(i = 0; i < size; i++) { + char tmp=*--cp2; + *cp2 = *cp1; + *cp1++ = tmp; + } +#if 0 + dprintf_cursor(stddeb,"After:\n"); + for(i=0;i<2*size;i++) { + dprintf_cursor(stddeb,"%02x ",((unsigned char *)lpl)[i]); + if ((i & 7) == 7) dprintf_cursor(stddeb,"\n"); + } +#endif + hCursor = CreateCursor(instance, lpcur->descriptor.curXHotspot, + lpcur->descriptor.curYHotspot, lpcur->descriptor.Width, + lpcur->descriptor.Height/2, + (LPSTR)lpl, ((LPSTR)lpl)+size); + GlobalUnlock(rsc_mem); GlobalFree(rsc_mem); -/* - hCursor = CreateCursor(instance, lpcur->descriptor.curXHotspot, - lpcur->descriptor.curYHotspot, 32, 32, - (LPSTR)lp + 211, , (LPSTR)lp + 211); -*/ - XFreePixmap(display, lpcur->pixshape); - XFreePixmap(display, lpcur->pixmask); - ReleaseDC(GetDesktopWindow(), hdc); GlobalUnlock(hCursor); + ReleaseDC(0,hdc); return hCursor; } @@ -231,12 +235,16 @@ HCURSOR LoadCursor(HANDLE instance, SEGPTR cursor_name) HCURSOR CreateCursor(HANDLE instance, short nXhotspot, short nYhotspot, short nWidth, short nHeight, LPSTR lpANDbitPlane, LPSTR lpXORbitPlane) { - XColor bkcolor; - XColor fgcolor; HCURSOR hCursor; CURSORALLOC *lpcur; HDC hdc; - + int bpllen = (nWidth + 7)/8 * nHeight; + char *tmpbpl = malloc(bpllen); + int i; + + XColor bkcolor,fgcolor; + Colormap cmap = XDefaultColormap(display,XDefaultScreen(display)); + dprintf_resource(stddeb,"CreateCursor: inst=%04x nXhotspot=%d nYhotspot=%d nWidth=%d nHeight=%d\n", instance, nXhotspot, nYhotspot, nWidth, nHeight); dprintf_resource(stddeb,"CreateCursor: inst=%04x lpANDbitPlane=%p lpXORbitPlane=%p\n", @@ -253,24 +261,21 @@ HCURSOR CreateCursor(HANDLE instance, short nXhotspot, short nYhotspot, memset(lpcur, 0, sizeof(CURSORALLOC)); lpcur->descriptor.curXHotspot = nXhotspot; lpcur->descriptor.curYHotspot = nYhotspot; - lpcur->pixshape = XCreatePixmapFromBitmapData( - display, DefaultRootWindow(display), - lpXORbitPlane, nWidth, nHeight, - WhitePixel(display, DefaultScreen(display)), - BlackPixel(display, DefaultScreen(display)), 1); + for(i=0; i<bpllen; i++) tmpbpl[i] = ~lpANDbitPlane[i]; lpcur->pixmask = XCreatePixmapFromBitmapData( display, DefaultRootWindow(display), - lpANDbitPlane, nWidth, nHeight, - WhitePixel(display, DefaultScreen(display)), - BlackPixel(display, DefaultScreen(display)), 1); - memset(&bkcolor, 0, sizeof(XColor)); - memset(&fgcolor, 0, sizeof(XColor)); - bkcolor.pixel = WhitePixel(display, DefaultScreen(display)); - fgcolor.pixel = BlackPixel(display, DefaultScreen(display)); + tmpbpl, nWidth, nHeight, 1, 0, 1); + for(i=0; i<bpllen; i++) tmpbpl[i] ^= lpXORbitPlane[i]; + lpcur->pixshape = XCreatePixmapFromBitmapData( + display, DefaultRootWindow(display), + tmpbpl, nWidth, nHeight, 1, 0, 1); + XParseColor(display,cmap,"#000000",&fgcolor); + XParseColor(display,cmap,"#ffffff",&bkcolor); lpcur->xcursor = XCreatePixmapCursor(display, lpcur->pixshape, lpcur->pixmask, &fgcolor, &bkcolor, lpcur->descriptor.curXHotspot, lpcur->descriptor.curYHotspot); + free(tmpbpl); XFreePixmap(display, lpcur->pixshape); XFreePixmap(display, lpcur->pixmask); ReleaseDC(GetDesktopWindow(), hdc); diff --git a/windows/message.c b/windows/message.c index cf1d2cdc77c..279b32089d5 100644 --- a/windows/message.c +++ b/windows/message.c @@ -882,10 +882,14 @@ BOOL PostMessage( HWND hwnd, WORD message, WORD wParam, LONG lParam ) LONG SendMessage( HWND hwnd, WORD msg, WORD wParam, LONG lParam ) { WND * wndPtr; + LONG ret; wndPtr = WIN_FindWndPtr( hwnd ); if (!wndPtr) return 0; - return CallWindowProc( wndPtr->lpfnWndProc, hwnd, msg, wParam, lParam ); + ret = CallWindowProc( wndPtr->lpfnWndProc, hwnd, msg, wParam, lParam ); + dprintf_msg( stddeb,"SendMessage(%4.4x,%x,%x,%lx) -> %lx\n", + hwnd, msg, wParam, lParam, ret ); + return ret; } diff --git a/windows/nonclient.c b/windows/nonclient.c index 8e437522a91..9604d35ff09 100644 --- a/windows/nonclient.c +++ b/windows/nonclient.c @@ -18,6 +18,7 @@ #include "scroll.h" #include "nonclient.h" #include "graphics.h" +#include "selectors.h" #include "stddebug.h" /* #define DEBUG_NONCLIENT */ #include "debug.h" @@ -1321,7 +1322,7 @@ LONG NC_HandleSysCommand( HWND hwnd, WORD wParam, POINT pt ) if (wParam == SC_ABOUTWINE) { extern char sysres_DIALOG_2[]; DialogBoxIndirectPtr( wndPtr->hInstance, sysres_DIALOG_2, - hwnd, (WNDPROC)AboutWine_Proc ); + hwnd, GetWndProcEntry16("AboutWine_Proc") ); } break; } diff --git a/windows/utility.c b/windows/utility.c index 385848735f2..6bc0ef47828 100644 --- a/windows/utility.c +++ b/windows/utility.c @@ -14,6 +14,7 @@ #include <stdlib.h> #include "windows.h" #include "ldt.h" +#include "stackframe.h" #include "stddebug.h" /* #define DEBUG_UTILITY */ #include "debug.h" @@ -56,7 +57,7 @@ void UTILITY_strip015(char *dest) { int DebugPrintString(char *str) { - fprintf(stderr, "%s", str); + fprintf(stderr, "%s\n", str); return 0; } @@ -268,12 +269,14 @@ char *UTILITY_convertArgs(char *format, char *winarg) }; #ifndef WINELIB -INT windows_wsprintf(BYTE *win_stack) +INT windows_wsprintf(void) { LPSTR lpOutput, lpFormat, ptr; BYTE new_stack[1024], *stack_ptr; BOOL fLarge; + BYTE *win_stack = (BYTE *)CURRENT_STACK16->args; + lpOutput = (LPSTR) PTR_SEG_TO_LIN(*(DWORD*)win_stack); win_stack += sizeof(DWORD); lpFormat = (LPSTR) PTR_SEG_TO_LIN(*(DWORD*)win_stack); diff --git a/windows/win.c b/windows/win.c index 6ed50d87a46..f17a885ccc7 100644 --- a/windows/win.c +++ b/windows/win.c @@ -21,8 +21,8 @@ #include "nonclient.h" #include "winpos.h" #include "color.h" -#include "stddebug.h" #include "callback.h" +#include "stddebug.h" /* #define DEBUG_WIN */ /* #define DEBUG_MENU */ #include "debug.h" @@ -318,9 +318,15 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, if (parent) { /* Make sure parent is valid */ - if (!IsWindow( parent )) return 0; + if (!IsWindow( parent )) { + dprintf_win(stddeb,"CreateWindowEx: Parent %x is not a windows\n", parent); + return 0; + } } - else if (style & WS_CHILD) return 0; /* WS_CHILD needs a parent */ + else if (style & WS_CHILD) { + dprintf_win(stddeb,"CreateWindowEx: no parent\n"); + return 0; /* WS_CHILD needs a parent */ + } if (!(class = CLASS_FindClassByName( className, instance, &classPtr ))) { fprintf(stderr,"CreateWindow BAD CLASSNAME '%s' !\n", className); @@ -336,7 +342,10 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, /* Create the window structure */ hwnd = USER_HEAP_ALLOC( sizeof(WND)+classPtr->wc.cbWndExtra ); - if (!hwnd) return 0; + if (!hwnd) { + dprintf_win(stddeb,"CreateWindowEx: Out of memory\n"); + return 0; + } /* Fill the structure */ @@ -480,7 +489,10 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, wmcreate = SendMessage( hwnd, WM_NCCREATE, 0, USER_HEAP_SEG_ADDR(hcreateStruct) ); - if (!wmcreate) wmcreate = -1; + if (!wmcreate) { + dprintf_win(stddeb,"CreateWindowEx: WM_NCCREATE return 0\n"); + wmcreate = -1; + } else { WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow, @@ -496,6 +508,7 @@ HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName, if (wmcreate == -1) { /* Abort window creation */ + dprintf_win(stddeb,"CreateWindowEx: wmcreate==-1, aborting\n"); WIN_DestroyWindow( hwnd ); return 0; } @@ -991,8 +1004,6 @@ HWND GetLastActivePopup(HWND hwnd) * pointers * * o call wndenumprc for every child window the desktop has - * (parameters to Callback16 passed backwards so they are - * put in in pascal calling order) * * o if wndenumprc returns 0 exit * @@ -1009,13 +1020,7 @@ BOOL EnumWindows(FARPROC wndenumprc, LPARAM lParam) if ( !(wndPtr=WIN_FindWndPtr(hwnd)) ) { return 0; } -#ifdef WINELIB - (*wndenumprc)(hwnd, lParam); -#else - result = CallBack16(wndenumprc, 2, - CALLBACK_SIZE_WORD, (int) hwnd, - CALLBACK_SIZE_LONG, lParam); -#endif + result = CallEnumWindowsProc( wndenumprc, hwnd, lParam ); if ( ! result ) { return 0; } @@ -1030,7 +1035,7 @@ BOOL EnumWindows(FARPROC wndenumprc, LPARAM lParam) * o hwnd is the first child to use, loop until all next windows * are processed * - * o call wdnenumprc with parameters in inverse order (pascal) + * o call wdnenumprc * * o call ourselves with the next child window * @@ -1039,22 +1044,11 @@ static BOOL WIN_EnumChildWin(HWND hwnd, FARPROC wndenumprc, LPARAM lParam) { WND *wndPtr; - while (hwnd) { - if ( !(wndPtr=WIN_FindWndPtr(hwnd)) ) { - return 0; - } -#ifdef WINELIB - if (!(*wndenumprc)( 2, lParam, (int) hwnd)) { -#else - if (!CallBack16(wndenumprc, 2, - CALLBACK_SIZE_WORD, (int) hwnd, - CALLBACK_SIZE_LONG, lParam)) { -#endif - return 0; - } - if (!WIN_EnumChildWin(wndPtr->hwndChild, wndenumprc, lParam)) { - return 0; - } + while (hwnd) + { + if (!(wndPtr=WIN_FindWndPtr(hwnd))) return 0; + if (!CallEnumWindowsProc( wndenumprc, hwnd, lParam )) return 0; + if (!WIN_EnumChildWin(wndPtr->hwndChild, wndenumprc, lParam)) return 0; hwnd=wndPtr->hwndNext; } return 1; -- GitLab