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 + + * [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 + + * [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 + + * [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 + + * [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,433 +72,1170 @@ 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; +LONG LBCreate( HWND hwnd, WORD message, WORD wParam, LONG lParam ) - 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; +{ + LPHEADLIST lphl; + CREATESTRUCT *createStruct; + WND *wndPtr; - 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; + CreateListBoxStruct(hwnd); + lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr); - default: - return DefWindowProc( hwnd, message, wParam, lParam ); - } -return 0; + 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) + +{ + 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; } +/*********************************************************************** + * LBDestroy + */ +LONG LBDestroy( HWND hwnd, WORD message, WORD wParam, LONG lParam ) + +{ + 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 ) + +{ + 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 ) + +{ + 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 ) + +{ + 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); + 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); + } + 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 ) + +{ + 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 ) + +{ + 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 ) + +{ + 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; @@ -515,266 +1256,240 @@ LPHEADLIST ListBoxGetStorageHeader(HWND hwnd) } -void StdDrawListBox(HWND hwnd) +void ListBoxDrawItem (HWND hwnd, HDC hdc, LPLISTSTRUCT lpls, + WORD itemAction, WORD itemState) + { - 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: + 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); -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; + hBrush = SendMessage(lphl->hWndLogicParent, WM_CTLCOLOR, (WORD)hdc, + MAKELONG(hwnd, CTLCOLOR_LISTBOX)); -/* 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; + 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; } - USER_HEAP_FREE( hDrawItemStruct ); -EndOfPaint: - EndPaint( hwnd, &ps ); + 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); + 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); } - - -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; -} - - 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); + 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); } @@ -786,6 +1501,7 @@ int ListBoxAddString(HWND hwnd, LPSTR newstr) 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; - - dprintf_listbox(stddeb,"ListBoxInsertString(%04X, %d, %p);\n", - hwnd, uIndex, newstr); - - 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; - - 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; +{ + 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); + + 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; + + 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_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 */ } - return LB_ERR; + 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 */ + } + 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 #include #include +#include #include "windows.h" #include "callback.h" #include "wine.h" -#include -#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 */ +/* don't forget to increase N_BUILTINS in dlls.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 */ -}; + /* Saved 16-bit stack */ +WORD IF1632_Saved16_ss = 0; +WORD IF1632_Saved16_sp = 0; +WORD IF1632_Saved16_bp = 0; + + /* Saved 32-bit stack */ +DWORD IF1632_Saved32_esp = 0; +DWORD IF1632_Saved32_ebp = 0; + +/*********************************************************************** + * RELAY_Init + */ +BOOL RELAY_Init(void) +{ + 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 */ + + 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++) + { + 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; +} #ifndef WINELIB -extern unsigned short IF1632_Saved16_sp; -extern unsigned short IF1632_Saved16_bp; -extern unsigned short IF1632_Saved16_ss; - -void RelayDebug( unsigned int func_num ) +void RELAY_DebugCall32( char *args ) { - unsigned int dll_id, ordinal; - - if (debugging_relay) - { - 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 ); - } -} - - -/********************************************************************** - * 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) -{ - 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; + if (!debugging_relay) return; - /* - * 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) + 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; - } - - /* - * 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; - } - } - - if (debugging_relay) - memcpy( &stackFrameCopy, pStack16Frame, sizeof(stackFrameCopy) ); - - /* - * 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]); - - if (debugging_relay) - { - if (memcmp( &stackFrameCopy, pStack16Frame, sizeof(stackFrameCopy) )) + switch(*args) { - printf( "**** 16-bit stack corrupted!\n" ); + 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; } - 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 ); + args++; + if (*args) printf( "," ); } - - return ret_val; + printf( ") ret=%04x:%04x ds=%04x\n", frame->cs, frame->ip, frame->ds ); } -#endif + + +void RELAY_DebugReturn( int short_ret, int ret_val ) +{ + STACK16FRAME *frame; + + if (!debugging_relay) return; + + 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 ); +} + + +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); +} + + +/*********************************************************************** + * 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 #include -#define CALLBACK_SIZE_WORD 0 -#define CALLBACK_SIZE_LONG 1 +#include "stackframe.h" -extern int CallTo16(unsigned int csip, unsigned short ds); -extern int CallBack16(void *func, int n_args, ...); +#ifndef WINELIB -extern BOOL CallGrayStringProc(FARPROC func, HDC hdc, LPARAM lParam, INT cch); +/* List of the 16-bit callback functions. This list is used */ +/* by the build program to generate the file if1632/call16.S */ -#endif /* CALLBACK_H */ + /* 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 ) + +#endif /* WINELIB */ + + +#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_table_s +{ + 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_entry_s *dll_table; - int dll_table_length; - int dll_number; + 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 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; - -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 +#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 #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 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 #include #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 (!(pNewArena = GLOBAL_GetArena( sel, selcount ))) + { + free( ptr ); + FreeSelector( sel ); return 0; } + /* Fill the new arena block */ + + 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 ((oldsize < size) && (flags & GMEM_ZEROINIT)) memset( (char *)ptr + oldsize, 0, size - oldsize ); - - if (sel == GlobalHandleToSel( handle )) - return handle; /* Selector didn't change */ - - if (flags & GMEM_MOVEABLE) return sel - 1; - else return sel; + 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 ) { - return 1; + 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 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 #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 #include #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 #include -#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 #include #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 #include #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 #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 #include @@ -6,17 +9,6 @@ #include #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 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 FUNCTYPE_PASCAL_16 16 -#define FUNCTYPE_PASCAL 17 -#define FUNCTYPE_REG 18 - -#define EQUATETYPE_ABS 19 -#define TYPE_RETURN 20 - -/*#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,64 +489,24 @@ 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) - { - fprintf(stderr, "usage: build SPECNAME\n build -p\n"); - exit(1); - } - - InitContext(); - - if (strcmp("-p", argv[1]) == 0) - { - 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; - } - - fprintf(fp, pop_strings[i]); - } - } - - 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"); + SpecFp = fopen( specname, "r"); if (SpecFp == NULL) { - fprintf(stderr, "Could not open specification file, '%s'\n", argv[1]); + fprintf(stderr, "Could not open specification file, '%s'\n", specname); exit(1); } @@ -719,255 +514,745 @@ int main(int argc, char **argv) sprintf(filename, "dll_%s.S", LowerDLLName); fp = fopen(filename, "w"); -#ifdef __ELF__ - fprintf (fp, "#define __ASSEMBLY__\n"); - fprintf (fp, "#include \n"); -#endif + 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++) { - fprintf(fp, "\t.globl " PREFIX "%s_Ordinal_%d\n", UpperDLLName, i); - - 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; - rdp = odp->additional_data; + 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; + 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 VARTYPE_BYTE: - fprintf(fp, PREFIX "%s_Ordinal_%d:\n", UpperDLLName, i); - OutputVariableCode(fp, ".byte", odp); - break; + case TYPE_ABS: + odp->offset = (int)odp->additional_data & 0xffff; + break; - case VARTYPE_WORD: - fprintf(fp, PREFIX "%s_Ordinal_%d:\n", UpperDLLName, i); - OutputVariableCode(fp, ".word", odp); - break; + case TYPE_BYTE: + fprintf( fp, "/* %s.%d */\n", UpperDLLName, i); + odp->offset = data_offset; + data_offset += OutputVariableCode(fp, ".byte", odp); + break; - case VARTYPE_LONG: - fprintf(fp, PREFIX "%s_Ordinal_%d:\n", UpperDLLName, i); - OutputVariableCode(fp, ".long", 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_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; + case TYPE_LONG: + fprintf( fp, "/* %s.%d */\n", UpperDLLName, i); + odp->offset = data_offset; + data_offset += 4 * OutputVariableCode(fp, ".long", odp); + break; - 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"); + 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; - 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; - - 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 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; - 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; - } + default: + fprintf( stderr, "build: Unknown function type; please report.\n"); + break; } } + 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 ); + fclose(fp); -#ifndef SHORTNAMES - sprintf(filename, "dll_%s_tab.c", LowerDLLName); -#else - sprintf(filename, "dtb_%s.c", LowerDLLName); -#endif + sprintf(filename, "tab_%s.c", LowerDLLName); fp = fopen(filename, "w"); - fprintf(fp, "#include \n"); - fprintf(fp, "#include \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); - } - + 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++) { - 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); - } - } - /******* 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) */ + int selector; - /* the difference between last #define and the current */ - prev_n_args= 0; - - odp = OrdinalDefinitions; - for (i = 0; i <= Limit; i++, odp++) - { 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; - 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; + 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; } - } - fprintf(fp,"};\n"); - - fprintf(fp,"unsigned char %s_types[]={\n" , UpperDLLName); - - odp = OrdinalDefinitions; - for (i = 0; i <= Limit; i++, odp++) - { - int argnum; - - 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"); - } - } - fprintf(fp,"};\n"); - - - /**************************************************/ - 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_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 "); - + fprintf(fp, " { %d, %d, ", selector, odp->offset ); + fprintf(fp, "\"%s\" ", odp->export_name); #ifdef WINESTAT - fprintf(fp, ",0 "); + fprintf(fp, ",0 "); #endif - fprintf(fp, "}, \n"); - break; - - default: - fprintf(fp, " { 0x%x, %s_Ordinal_%d, \042\042, NULL },\n", - UTEXTSEL, UpperDLLName, i); - break; - } + fprintf(fp, "}, \n"); } - fprintf(fp, "};\n"); + 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); - return 0; } + +/******************************************************************* + * 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; + + /* Save ebx first */ + + 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] ); + } + } + + /* Restore ebx */ + + printf( "\tpopl %%ebx\n" ); + + 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 +} + + +/******************************************************************* + * 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( stderr, "Invalid function name '%s', ignored\n", profile ); + return; + } + + /* 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) + { + 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" ); + } + + printf( "\tcall %%eax\n" ); + + if (debugging) + { + printf( "\tpushl %%eax\n" ); + printf( "\tpushl $%d\n", short_ret ); + printf( "\tcall " PREFIX "RELAY_DebugReturn\n" ); + printf( "\tpopl %%eax\n" ); + printf( "\tpopl %%eax\n" ); + } + + 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" ); + } + } + + /* Restore ds and bp */ + + printf( "\tpopw %%ds\n" ); + printf( "\tmovw %%bp,%%sp\n" ); + printf( "\tpopw %%bp\n" ); + + /* Remove the arguments and return */ + + if (argsize) + { + printf( "\t.byte 0x66\n" ); + printf( "\tlret $%d\n", argsize ); + } + else + { + printf( "\t.byte 0x66\n" ); + printf( "\tlret\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; + } + } + + /* Push the return address */ + + 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) + { + /* 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" ); + } + + /* 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] ); + } + 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(); + + 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 -#include -#include -#include - -#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 \n"); - fprintf(fp, "#include \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; ipixmask = 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; ipixshape = 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 #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;