Release 960421 Sat Apr 20 23:23:16 1996 Robert Pouliot <krynos@qbc.clic.net> * [resources/sysres_Fr.rc] [resources/TODO] Made changes for Choose_Color dialog. Sat Apr 20 15:43:49 1996 Alexandre Julliard <julliard@lrc.epfl.ch> * [controls/button.c] Fixed test that got miscompiled by some old gcc versions. * [memory/local.c] Fixed the layout of handle tables so that moveable handle entries can be freed on LocalFree(). Implemented LocalFlags(), LocalCountFree(), LocalHandleDelta() and GetHeapSpaces(). * [misc/main.c] [ANNOUNCE] Update the list of contributors. Please let me know if I forgot someone. Fri Apr 19 20:07:20 1996 Frans van Dorsselaer <dorssel@rulhm1.leidenuniv.nl> * [controls/edit.c] [controls/EDIT.TODO] Fixed EM_SETHANDLE / WM_CREATE / EDIT_MakeFir() buffer allocation. Fixed ES_NOHIDESEL / WM_MOUSEMOVE / WM_LBUTTONDOWN implementation. Added WM_ENABLE implementation (gray text). Fixed buffer > 32767 bug. Fixed argument types / typecasting. Faster selection (re)drawing. Thu Apr 18 13:38:26 1996 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de> * [misc/registry.c] [include/winreg.h] Changed savefile format again to human readable/editable (UNICODE chars >0xff are specified by \uXXXX, data by XX). Has now global / local registry databases (including merging them). HKEY_CLASSES_ROOT == HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes. HKEY_CURRENT_USER == HKEY_USERS\\<loginname>. * [misc/comm.c] Allow " " as COMx: ... spec delimiter too. (AOL-CD setup.exe tries to initialize modem2 as "9600,x,x x" (can't remember the x). Thu Apr 18 09:00:00 1996 Alex Korobka <alex@phm30.pharm.sunysb.edu> * [windows/mdi.c] Miscellaneous changes. * [windows/winpos.c] Use BitBlt whenever possible in SetWindowPos. * [windows/painting.c] Fix incompatibilities with hrgnUpdate being 1. Wed Apr 17 19:19:22 1996 Albrecht Kleine <kleine@ak.sax.de> * [misc/commdlg.c] Many bugfixes in ChooseColor dialog. Added a user defined dialog title in FileOpen-/FileSave- dialog. * [misc/commdlg.c][include/commdlg.h] [if1632/commdlg.spec][if1632/winprocs.spec] Introduced dialog-, callback- and enum- stub functions for ChooseFont dialog Wed Apr 17 19:08:38 1996 Niels de Carpentier <niels@cindy.et.tudelft.nl> * [objects/metafile.c] [include/metafile.h] [if1632/gdi.spec] Implemented EnumMetaFile and CopyMetaFile. Removed METAFILE struct. Implemented META_STRETCHDIB in PlayMetaFileRecord, several bug fixes. * [windows/winpos.c] Don't try to hide the window if it's already hidden. * [windows/message.c] Let MSG_PeekHardwareMsg fill the message queue with events if it's empty. Wed Apr 17 17:54:04 1996 Tristan Tarrant <tst@sthinc.demon.co.uk> * [resources/sysres_It.rc] Updated to support the new CHOOSE_COLOR_DIALOG. Tue Apr 16 11:50:00 1996 Anand Kumria <akumria@ozemail.com.au> * [if1632/Makefile] [if1632/relay.c] [if1631/w32sys.spec] [include/w32sys.h] [include/dlls.h] [misc/Makefile] [misc/w32sys.c] W32SYS.DLL partially implemented.
diff --git a/ANNOUNCE b/ANNOUNCE index 7f3bb2f..23bded41 100644 --- a/ANNOUNCE +++ b/ANNOUNCE
@@ -1,14 +1,15 @@ -This is release 960414 of Wine the MS Windows emulator. This is still a +This is release 960421 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 "julliard@lrc.epfl.ch". Please don't forget to include a ChangeLog entry. -WHAT'S NEW with Wine-960414: (see ChangeLog for details) - - Complete rewrite of the edit control. - - Better color selection dialog. - - Win32 heap management. +WHAT'S NEW with Wine-960421: (see ChangeLog for details) + - Preliminary support for W32SYS.DLL. + - Built-in COMMDLG improvements. + - New format and location for registry files. + - Window refresh optimized. - Lots of bug fixes. See the README file in the distribution for installation instructions. @@ -17,10 +18,10 @@ the release is available at the ftp sites. The sources will be available from the following locations: - sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960414.tar.gz - tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960414.tar.gz - ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960414.tar.gz - aris.com:/pub/linux/ALPHA/Wine/development/Wine-960414.tar.gz + sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960421.tar.gz + tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960421.tar.gz + ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960421.tar.gz + aris.com:/pub/linux/ALPHA/Wine/development/Wine-960421.tar.gz It should also be available from any site that mirrors tsx-11 or sunsite. @@ -34,19 +35,25 @@ really intend to test the new releases as soon as they're out. Wine is available thanks to the work of Bob Amstadt, Dag Asheim, -Martin Ayotte, Ross Biro, Erik Bos, Fons Botman, John Brezak, -Andrew Bulhak, John Burton, Paul Falstad, Olaf Flebbe, Peter Galbavy, -Ramon Garcia, Hans de Graaff, Charles M. Hannum, Cameron Heide, -Jochen Hoenicke, Jeffrey Hsu, Miguel de Icaza, Alexandre Julliard, -Jon Konrath, Scott A. Laird, Martin von Loewis, Kenneth MacDonald, -Peter MacDonald, William Magro, Marcus Meissner, Graham Menhennitt, -David Metcalfe, Michael Patra, John Richardson, Johannes Ruscheinski, -Thomas Sandford, Constantine Sapuntzakis, Daniel Schepler, +Martin Ayotte, Ross Biro, Uwe Bonnes, Erik Bos, Fons Botman, John Brezak, +Andrew Bulhak, John Burton, Niels de Carpentier, Roman Dolejsi, +Frans van Dorsselaer, Paul Falstad, Olaf Flebbe, Peter Galbavy, +Ramon Garcia, Hans de Graaff, Charles M. Hannum, John Harvey, +Cameron Heide, Jochen Hoenicke, Onno Hovers, Jeffrey Hsu, +Miguel de Icaza, Jukka Iivonen, Alexandre Julliard, Jochen Karrer, +Andreas Kirschbaum, Albrecht Kleine, Jon Konrath, Alex Korobka, +Greg Kreider, Anand Kumria, Scott A. Laird, Martin von Loewis, +Kenneth MacDonald, Peter MacDonald, William Magro, Juergen Marquardt, +Marcus Meissner, Graham Menhennitt, David Metcalfe, Steffen Moeller, +Philippe De Muyter, Itai Nahshon, Michael Patra, Jim Peterson, +Robert Pouliot, Keith Reynolds, John Richardson, Johannes Ruscheinski, +Thomas Sandford, Constantine Sapuntzakis, Daniel Schepler, Ulrich Schmid, Bernd Schmidt, Yngvi Sigurjonsson, Rick Sladkey, William Smith, -Erik Svendsen, Goran Thyni, Jimmy Tirtawangsa, Jon Tombs, -Linus Torvalds, Gregory Trubetskoy, Michael Veksler, Morten Welinder, -Jan Willamowius, Carl Williams, Karl Guenter Wuensch, Eric Youngdale, -and James Youngman. +Erik Svendsen, Tristan Tarrant, Andrew Taylor, Duncan C Thomson, +Goran Thyni, Jimmy Tirtawangsa, Jon Tombs, Linus Torvalds, +Gregory Trubetskoy, Michael Veksler, Sven Verdoolaege, Eric Warnke, +Manfred Weichel, Morten Welinder, Jan Willamowius, Carl Williams, +Karl Guenter Wuensch, Eric Youngdale, and James Youngman. -- Alexandre Julliard
diff --git a/ChangeLog b/ChangeLog index 46b0a5b..f8d4c3d 100644 --- a/ChangeLog +++ b/ChangeLog
@@ -1,4 +1,97 @@ ---------------------------------------------------------------------- +Sat Apr 20 23:23:16 1996 Robert Pouliot <krynos@qbc.clic.net> + + * [resources/sysres_Fr.rc] [resources/TODO] + Made changes for Choose_Color dialog. + +Sat Apr 20 15:43:49 1996 Alexandre Julliard <julliard@lrc.epfl.ch> + + * [controls/button.c] + Fixed test that got miscompiled by some old gcc versions. + + * [memory/local.c] + Fixed the layout of handle tables so that moveable handle entries + can be freed on LocalFree(). + Implemented LocalFlags(), LocalCountFree(), LocalHandleDelta() and + GetHeapSpaces(). + + * [misc/main.c] [ANNOUNCE] + Update the list of contributors. Please let me know if I forgot + someone. + +Fri Apr 19 20:07:20 1996 Frans van Dorsselaer <dorssel@rulhm1.leidenuniv.nl> + + * [controls/edit.c] [controls/EDIT.TODO] + Fixed EM_SETHANDLE / WM_CREATE / EDIT_MakeFir() buffer allocation. + Fixed ES_NOHIDESEL / WM_MOUSEMOVE / WM_LBUTTONDOWN implementation. + Added WM_ENABLE implementation (gray text). + Fixed buffer > 32767 bug. + Fixed argument types / typecasting. + Faster selection (re)drawing. + +Thu Apr 18 13:38:26 1996 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de> + + * [misc/registry.c] [include/winreg.h] + Changed savefile format again to human readable/editable + (UNICODE chars >0xff are specified by \uXXXX, data by XX). + Has now global / local registry databases (including merging them). + HKEY_CLASSES_ROOT == HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes. + HKEY_CURRENT_USER == HKEY_USERS\\<loginname>. + + * [misc/comm.c] + Allow " " as COMx: ... spec delimiter too. + (AOL-CD setup.exe tries to initialize modem2 as "9600,x,x x" (can't + remember the x). + +Thu Apr 18 09:00:00 1996 Alex Korobka <alex@phm30.pharm.sunysb.edu> + + * [windows/mdi.c] + Miscellaneous changes. + + * [windows/winpos.c] + Use BitBlt whenever possible in SetWindowPos. + + * [windows/painting.c] + Fix incompatibilities with hrgnUpdate being 1. + +Wed Apr 17 19:19:22 1996 Albrecht Kleine <kleine@ak.sax.de> + + * [misc/commdlg.c] + Many bugfixes in ChooseColor dialog. + Added a user defined dialog title in FileOpen-/FileSave- dialog. + + * [misc/commdlg.c][include/commdlg.h] + [if1632/commdlg.spec][if1632/winprocs.spec] + Introduced dialog-, callback- and enum- stub functions + for ChooseFont dialog + +Wed Apr 17 19:08:38 1996 Niels de Carpentier <niels@cindy.et.tudelft.nl> + + * [objects/metafile.c] [include/metafile.h] [if1632/gdi.spec] + Implemented EnumMetaFile and CopyMetaFile. Removed METAFILE struct. + Implemented META_STRETCHDIB in PlayMetaFileRecord, several bug + fixes. + + * [windows/winpos.c] + Don't try to hide the window if it's already hidden. + + * [windows/message.c] + Let MSG_PeekHardwareMsg fill the message queue with events if + it's empty. + +Wed Apr 17 17:54:04 1996 Tristan Tarrant <tst@sthinc.demon.co.uk> + + * [resources/sysres_It.rc] + Updated to support the new CHOOSE_COLOR_DIALOG. + +Tue Apr 16 11:50:00 1996 Anand Kumria <akumria@ozemail.com.au> + + * [if1632/Makefile] [if1632/relay.c] [if1631/w32sys.spec] + [include/w32sys.h] [include/dlls.h] + [misc/Makefile] [misc/w32sys.c] + W32SYS.DLL partially implemented. + +---------------------------------------------------------------------- Sun Apr 14 12:51:27 1996 Alexandre Julliard <julliard@lrc.epfl.ch> * [controls/menu.c] [include/dialog.h] [windows/dialog.c]
diff --git a/controls/EDIT.TODO b/controls/EDIT.TODO index a190874..99b4270 100644 --- a/controls/EDIT.TODO +++ b/controls/EDIT.TODO
@@ -98,9 +98,6 @@ - The clipboard is broken. Whenever things go wrong with cut/copy/paste, it is probably the clipboard that messes up things, not edit.c. -- With Notepad, if you select New File a couple of times and enter - text, the buffer is sometimes corrupted. -- Switching on/off WordWrap with Notepad sometimes corrupts the buffer. I am still very actively changing things. Especially I am working
diff --git a/controls/button.c b/controls/button.c index 68515db..f5e7eff 100644 --- a/controls/button.c +++ b/controls/button.c
@@ -253,12 +253,17 @@ break; case BM_SETSTATE: - if (!wParam != !(infoPtr->state & BUTTON_HIGHLIGHTED)) + if (wParam) { - if (wParam) infoPtr->state |= BUTTON_HIGHLIGHTED; - else infoPtr->state &= ~BUTTON_HIGHLIGHTED; - PAINT_BUTTON( wndPtr, style, ODA_SELECT ); + if (infoPtr->state & BUTTON_HIGHLIGHTED) break; + infoPtr->state |= BUTTON_HIGHLIGHTED; } + else + { + if (!(infoPtr->state & BUTTON_HIGHLIGHTED)) break; + infoPtr->state &= ~BUTTON_HIGHLIGHTED; + } + PAINT_BUTTON( wndPtr, style, ODA_SELECT ); break; default:
diff --git a/controls/edit.c b/controls/edit.c index d49bd04..296365c 100644 --- a/controls/edit.c +++ b/controls/edit.c
@@ -23,8 +23,8 @@ #include "xmalloc.h" #include "callback.h" -#define BUFLIMIT_MULTI 65535 /* maximum text buffer length */ -#define BUFLIMIT_SINGLE 32767 /* maximum text buffer length */ +#define BUFLIMIT_MULTI 65534 /* maximum text buffer length (not including '\0') */ +#define BUFLIMIT_SINGLE 32766 #define BUFSTART_MULTI 1024 /* starting length for multi-line control */ #define BUFSTART_SINGLE 256 /* starting length for single line control */ #define GROWLENGTH 64 /* buffers grow by this much */ @@ -40,38 +40,38 @@ } LINE_END; typedef struct { - int offset; - int length; + UINT offset; + UINT length; LINE_END ending; } LINEDEF; typedef struct { - int TextWidth; /* width of the widest line in pixels */ + UINT TextWidth; /* width of the widest line in pixels */ HLOCAL hBuf; char *text; HFONT hFont; LINEDEF *LineDefs; - int XOffset; /* possitive offset of the viewport in pixels */ - int FirstVisibleLine; - int LineCount; - int LineHeight; /* height of a screen line in pixels */ - int AveCharWidth; /* average character width in pixels */ - unsigned int BufLimit; - unsigned int BufSize; + UINT XOffset; /* offset of the viewport in pixels */ + UINT FirstVisibleLine; + UINT LineCount; + UINT LineHeight; /* height of a screen line in pixels */ + UINT AveCharWidth; /* average character width in pixels */ + UINT BufLimit; + UINT BufSize; BOOL TextChanged; BOOL Redraw; - int SelStart; /* offset of selection start, == SelEnd if no selection */ - int SelEnd; /* offset of selection end == current caret position */ - int NumTabStops; + UINT SelStart; /* offset of selection start, == SelEnd if no selection */ + UINT SelEnd; /* offset of selection end == current caret position */ + UINT NumTabStops; LPINT TabStops; EDITWORDBREAKPROC WordBreakProc; char PasswordChar; } EDITSTATE; -#define SWAP_INT(x,y) do { int temp = (x); (x) = (y); (y) = temp; } while(0) -#define ORDER_INT(x,y) do { if ((y) < (x)) SWAP_INT((x),(y)); } while(0) +#define SWAP_UINT(x,y) do { UINT temp = (UINT)(x); (x) = (UINT)(y); (y) = temp; } while(0) +#define ORDER_UINT(x,y) do { if ((UINT)(y) < (UINT)(x)) SWAP_UINT((x),(y)); } while(0) /* macros to access window styles */ #define IsMultiLine(wndPtr) ((wndPtr)->dwStyle & ES_MULTILINE) @@ -118,23 +118,24 @@ LRESULT EditWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); static void EDIT_BuildLineDefs(WND *wndPtr); -static int EDIT_CallWordBreakProc(WND *wndPtr, char *s, int index, int count, int action); -static int EDIT_ColFromWndX(WND *wndPtr, int line, int x); +static INT EDIT_CallWordBreakProc(WND *wndPtr, char *s, INT index, INT count, INT action); +static UINT EDIT_ColFromWndX(WND *wndPtr, UINT line, INT x); static void EDIT_DelEnd(WND *wndPtr); static void EDIT_DelLeft(WND *wndPtr); static void EDIT_DelRight(WND *wndPtr); -static int EDIT_GetAveCharWidth(WND *wndPtr); -static int EDIT_GetLineHeight(WND *wndPtr); -static void EDIT_GetLineRect(WND *wndPtr, int line, int scol, int ecol, LPRECT rc); +static UINT EDIT_GetAveCharWidth(WND *wndPtr); +static UINT EDIT_GetLineHeight(WND *wndPtr); +static void EDIT_GetLineRect(WND *wndPtr, UINT line, UINT scol, UINT ecol, LPRECT rc); static char * EDIT_GetPointer(WND *wndPtr); static LRESULT EDIT_GetRect(WND *wndPtr, WPARAM wParam, LPARAM lParam); static BOOL EDIT_GetRedraw(WND *wndPtr); -static int EDIT_GetTextWidth(WND *wndPtr); -static int EDIT_GetVisibleLineCount(WND *wndPtr); -static int EDIT_GetWndWidth(WND *wndPtr); -static int EDIT_GetXOffset(WND *wndPtr); -static int EDIT_LineFromWndY(WND *wndPtr, int y); -static BOOL EDIT_MakeFit(WND *wndPtr, int size); +static UINT EDIT_GetTextWidth(WND *wndPtr); +static UINT EDIT_GetVisibleLineCount(WND *wndPtr); +static UINT EDIT_GetWndWidth(WND *wndPtr); +static UINT EDIT_GetXOffset(WND *wndPtr); +static void EDIT_InvalidateText(WND *wndPtr, UINT start, UINT end); +static UINT EDIT_LineFromWndY(WND *wndPtr, INT y); +static BOOL EDIT_MakeFit(WND *wndPtr, UINT size); static void EDIT_MoveBackward(WND *wndPtr, BOOL extend); static void EDIT_MoveDownward(WND *wndPtr, BOOL extend); static void EDIT_MoveEnd(WND *wndPtr, BOOL extend); @@ -145,14 +146,14 @@ static void EDIT_MoveUpward(WND *wndPtr, BOOL extend); static void EDIT_MoveWordBackward(WND *wndPtr, BOOL extend); static void EDIT_MoveWordForward(WND *wndPtr, BOOL extend); -static void EDIT_PaintLine(WND *wndPtr, HDC hdc, int line); -static int EDIT_PaintText(WND *wndPtr, HDC hdc, int x, int y, int line, int col, int count, BOOL rev); +static void EDIT_PaintLine(WND *wndPtr, HDC hdc, UINT line, BOOL rev); +static UINT EDIT_PaintText(WND *wndPtr, HDC hdc, INT x, INT y, UINT line, UINT col, UINT count, BOOL rev); static void EDIT_ReleasePointer(WND *wndPtr); static LRESULT EDIT_ReplaceSel(WND *wndPtr, WPARAM wParam, LPARAM lParam); static void EDIT_ScrollIntoView(WND *wndPtr); -static int EDIT_WndXFromCol(WND *wndPtr, int line, int col); -static int EDIT_WndYFromLine(WND *wndPtr, int line); -static int EDIT_WordBreakProc(char *s, int index, int count, int action); +static INT EDIT_WndXFromCol(WND *wndPtr, UINT line, UINT col); +static INT EDIT_WndYFromLine(WND *wndPtr, UINT line); +static INT EDIT_WordBreakProc(char *s, INT index, INT count, INT action); static LRESULT EDIT_EM_CanUndo(WND *wndPtr, WPARAM wParam, LPARAM lParam); static LRESULT EDIT_EM_EmptyUndoBuffer(WND *wndPtr, WPARAM wParam, LPARAM lParam); @@ -217,6 +218,30 @@ /********************************************************************* * + * General shortcuts for variable names: + * + * UINT l; line + * UINT c; column + * UINT s; offset of selection start + * UINT e; offset of selection end + * UINT sl; line on which the selection starts + * UINT el; line on which the selection ends + * UINT sc; column on which the selection starts + * UINT ec; column on which the selection ends + * UINT li; line index (offset) + * UINT fv; first visible line + * UINT vlc; vissible line count + * UINT lc; line count + * UINT lh; line height (in pixels) + * UINT tw; text width (in pixels) + * UINT ww; window width (in pixels) + * UINT cw; character width (average, in pixels) + * + */ + + +/********************************************************************* + * * EditWndProc() * */ @@ -587,7 +612,7 @@ * Call appropriate WordBreakProc (internal or external). * */ -static int EDIT_CallWordBreakProc(WND *wndPtr, char *s, int index, int count, int action) +static INT EDIT_CallWordBreakProc(WND *wndPtr, char *s, INT index, INT count, INT action) { EDITWORDBREAKPROC wbp = (EDITWORDBREAKPROC)EDIT_EM_GetWordBreakProc(wndPtr, 0, 0L); @@ -606,15 +631,15 @@ * Calculates, for a given line and X-coordinate on the screen, the column. * */ -static int EDIT_ColFromWndX(WND *wndPtr, int line, int x) +static UINT EDIT_ColFromWndX(WND *wndPtr, UINT line, INT x) { - int linecount = EDIT_EM_GetLineCount(wndPtr, 0, 0L); - int lineindex = EDIT_EM_LineIndex(wndPtr, line, 0L); - int linelength = EDIT_EM_LineLength(wndPtr, lineindex, 0L); - int i; + UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, 0, 0L); + UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, line, 0L); + UINT ll = (UINT)EDIT_EM_LineLength(wndPtr, li, 0L); + UINT i; - line = MAX(0, MIN(line, linecount - 1)); - for (i = 0 ; i < linelength ; i++) + line = MAX(0, MIN(line, lc - 1)); + for (i = 0 ; i < ll ; i++) if (EDIT_WndXFromCol(wndPtr, line, i) >= x) break; return i; @@ -630,7 +655,7 @@ */ static void EDIT_DelEnd(WND *wndPtr) { - EDIT_EM_SetSel(wndPtr, FALSE, MAKELPARAM(-1, 0)); + EDIT_EM_SetSel(wndPtr, 1, MAKELPARAM(-1, 0)); EDIT_MoveEnd(wndPtr, TRUE); EDIT_WM_Clear(wndPtr, 0, 0L); } @@ -645,7 +670,7 @@ */ static void EDIT_DelLeft(WND *wndPtr) { - EDIT_EM_SetSel(wndPtr, FALSE, MAKELPARAM(-1, 0)); + EDIT_EM_SetSel(wndPtr, 1, MAKELPARAM(-1, 0)); EDIT_MoveBackward(wndPtr, TRUE); EDIT_WM_Clear(wndPtr, 0, 0L); } @@ -660,7 +685,7 @@ */ static void EDIT_DelRight(WND *wndPtr) { - EDIT_EM_SetSel(wndPtr, FALSE, MAKELPARAM(-1, 0)); + EDIT_EM_SetSel(wndPtr, 1, MAKELPARAM(-1, 0)); EDIT_MoveForward(wndPtr, TRUE); EDIT_WM_Clear(wndPtr, 0, 0L); } @@ -671,7 +696,7 @@ * EDIT_GetAveCharWidth * */ -static int EDIT_GetAveCharWidth(WND *wndPtr) +static UINT EDIT_GetAveCharWidth(WND *wndPtr) { EDITSTATE *es = EDITSTATEPTR(wndPtr); @@ -684,7 +709,7 @@ * EDIT_GetLineHeight * */ -static int EDIT_GetLineHeight(WND *wndPtr) +static UINT EDIT_GetLineHeight(WND *wndPtr) { EDITSTATE *es = EDITSTATEPTR(wndPtr); @@ -700,12 +725,13 @@ * column to an ending column. * */ -static void EDIT_GetLineRect(WND *wndPtr, int line, int scol, int ecol, LPRECT rc) +static void EDIT_GetLineRect(WND *wndPtr, UINT line, UINT scol, UINT ecol, LPRECT rc) { rc->top = EDIT_WndYFromLine(wndPtr, line); rc->bottom = rc->top + EDIT_GetLineHeight(wndPtr); rc->left = EDIT_WndXFromCol(wndPtr, line, scol); - rc->right = (ecol < 0) ? EDIT_GetWndWidth(wndPtr) : EDIT_WndXFromCol(wndPtr, line, ecol); + rc->right = ((INT)ecol == -1) ? EDIT_GetWndWidth(wndPtr) : + EDIT_WndXFromCol(wndPtr, line, ecol); } @@ -761,7 +787,7 @@ * EDIT_GetTextWidth * */ -static int EDIT_GetTextWidth(WND *wndPtr) +static UINT EDIT_GetTextWidth(WND *wndPtr) { EDITSTATE *es = EDITSTATEPTR(wndPtr); @@ -774,7 +800,7 @@ * EDIT_GetVisibleLineCount * */ -static int EDIT_GetVisibleLineCount(WND *wndPtr) +static UINT EDIT_GetVisibleLineCount(WND *wndPtr) { RECT rc; @@ -788,7 +814,7 @@ * EDIT_GetWndWidth * */ -static int EDIT_GetWndWidth(WND *wndPtr) +static UINT EDIT_GetWndWidth(WND *wndPtr) { RECT rc; @@ -802,7 +828,7 @@ * EDIT_GetXOffset * */ -static int EDIT_GetXOffset(WND *wndPtr) +static UINT EDIT_GetXOffset(WND *wndPtr) { EDITSTATE *es = EDITSTATEPTR(wndPtr); @@ -812,18 +838,91 @@ /********************************************************************* * + * EDIT_InvalidateText + * + * Invalidate the text from offset start upto, but not including, + * offset end. Useful for (re)painting the selection. + * Regions outside the linewidth are not invalidated. + * end == -1 means end == TextLength. + * start and end need not be ordered. + * + */ +static void EDIT_InvalidateText(WND *wndPtr, UINT start, UINT end) +{ + UINT fv = (UINT)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L); + UINT vlc = EDIT_GetVisibleLineCount(wndPtr); + UINT sl; + UINT el; + UINT sc; + UINT ec; + RECT rcWnd; + RECT rcLine; + RECT rcUpdate; + UINT line; + + if (end == start ) + return; + + if ((INT)end == -1) + end = (UINT)EDIT_WM_GetTextLength(wndPtr, 0, 0L); + ORDER_UINT(start, end); + sl = (UINT)EDIT_EM_LineFromChar(wndPtr, start, 0L); + el = (UINT)EDIT_EM_LineFromChar(wndPtr, end, 0L); + if ((el < fv) || (sl > fv + vlc)) + return; + + sc = start - (UINT)EDIT_EM_LineIndex(wndPtr, sl, 0L); + ec = end - (UINT)EDIT_EM_LineIndex(wndPtr, el, 0L); + if (sl < fv) { + sl = fv; + sc = 0; + } + if (el > fv + vlc) { + el = fv + vlc; + ec = (UINT)EDIT_EM_LineLength(wndPtr, + (UINT)EDIT_EM_LineIndex(wndPtr, el, 0L), 0L); + } + EDIT_GetRect(wndPtr, 0, (LPARAM)&rcWnd); + if (sl == el) { + EDIT_GetLineRect(wndPtr, sl, sc, ec, &rcLine); + if (IntersectRect(&rcUpdate, &rcWnd, &rcLine)) + InvalidateRect(wndPtr->hwndSelf, &rcUpdate, FALSE); + } else { + EDIT_GetLineRect(wndPtr, sl, sc, + (UINT)EDIT_EM_LineLength(wndPtr, + (UINT)EDIT_EM_LineIndex(wndPtr, sl, 0L), 0L), + &rcLine); + if (IntersectRect(&rcUpdate, &rcWnd, &rcLine)) + InvalidateRect(wndPtr->hwndSelf, &rcUpdate, FALSE); + for (line = sl + 1 ; line < el ; line++) { + EDIT_GetLineRect(wndPtr, line, 0, + (UINT)EDIT_EM_LineLength(wndPtr, + (UINT)EDIT_EM_LineIndex(wndPtr, line, 0L), 0L), + &rcLine); + if (IntersectRect(&rcUpdate, &rcWnd, &rcLine)) + InvalidateRect(wndPtr->hwndSelf, &rcUpdate, FALSE); + } + EDIT_GetLineRect(wndPtr, el, 0, ec, &rcLine); + if (IntersectRect(&rcUpdate, &rcWnd, &rcLine)) + InvalidateRect(wndPtr->hwndSelf, &rcUpdate, FALSE); + } +} + + +/********************************************************************* + * * EDIT_LineFromWndY * * Calculates, for a given Y-coordinate on the screen, the line. * */ -static int EDIT_LineFromWndY(WND *wndPtr, int y) +static UINT EDIT_LineFromWndY(WND *wndPtr, INT y) { - int firstvis = EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L); - int lineheight = EDIT_GetLineHeight(wndPtr); - int linecount = EDIT_EM_GetLineCount(wndPtr, 0, 0L); + UINT fv = (UINT)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L); + UINT lh = EDIT_GetLineHeight(wndPtr); + UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, 0, 0L); - return MAX(0, MIN(linecount - 1, y / lineheight + firstvis)); + return MAX(0, MIN(lc - 1, y / lh + fv)); } @@ -831,10 +930,10 @@ * * EDIT_MakeFit * - * Try to fit size + 1 bytes in the buffer. Contrain to limits. + * Try to fit size + 1 bytes in the buffer. Constrain to limits. * */ -static BOOL EDIT_MakeFit(WND *wndPtr, int size) +static BOOL EDIT_MakeFit(WND *wndPtr, UINT size) { EDITSTATE *es = EDITSTATEPTR(wndPtr); @@ -842,13 +941,17 @@ return TRUE; if (size > es->BufLimit) return FALSE; - es->BufSize = ((size / GROWLENGTH) + 1) * GROWLENGTH; - if (es->BufSize > es->BufLimit) - es->BufSize = es->BufLimit; + size = ((size / GROWLENGTH) + 1) * GROWLENGTH; + if (size > es->BufLimit) + size = es->BufLimit; - dprintf_edit(stddeb, "edit: EDIT_MakeFit: ReAlloc to %d+1\n", es->BufSize); + dprintf_edit(stddeb, "edit: EDIT_MakeFit: trying to ReAlloc to %d+1\n", size); - return LOCAL_ReAlloc(wndPtr->hInstance, es->hBuf, es->BufSize + 1, LMEM_MOVEABLE); + if (LOCAL_ReAlloc(wndPtr->hInstance, es->hBuf, size + 1, LMEM_MOVEABLE)) { + es->BufSize = MIN(LOCAL_Size(wndPtr->hInstance, es->hBuf) - 1, es->BufLimit); + return TRUE; + } else + return FALSE; } @@ -859,21 +962,21 @@ */ static void EDIT_MoveBackward(WND *wndPtr, BOOL extend) { - int s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - int e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - int l = EDIT_EM_LineFromChar(wndPtr, e, 0L); - int lineindex = EDIT_EM_LineIndex(wndPtr, l, 0L); + UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L); + UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L); - if (e - lineindex == 0) { + if (e - li == 0) { if (l) { - lineindex = EDIT_EM_LineIndex(wndPtr, l - 1, 0L); - e = lineindex + EDIT_EM_LineLength(wndPtr, lineindex, 0L); + li = (UINT)EDIT_EM_LineIndex(wndPtr, l - 1, 0L); + e = li + (UINT)EDIT_EM_LineLength(wndPtr, li, 0L); } } else e--; if (!extend) s = e; - EDIT_EM_SetSel(wndPtr, TRUE, MAKELPARAM(s, e)); + EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e)); } @@ -884,22 +987,22 @@ */ static void EDIT_MoveDownward(WND *wndPtr, BOOL extend) { - int s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - int e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - int l = EDIT_EM_LineFromChar(wndPtr, e, 0L); - int linecount = EDIT_EM_GetLineCount(wndPtr, e, 0L); - int lineindex = EDIT_EM_LineIndex(wndPtr, l, 0L); - int x; + UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L); + UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, e, 0L); + UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L); + INT x; - if (l < linecount - 1) { - x = EDIT_WndXFromCol(wndPtr, l, e - lineindex); + if (l < lc - 1) { + x = EDIT_WndXFromCol(wndPtr, l, e - li); l++; - e = EDIT_EM_LineIndex(wndPtr, l, 0L) + + e = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L) + EDIT_ColFromWndX(wndPtr, l, x); } if (!extend) s = e; - EDIT_EM_SetSel(wndPtr, TRUE, MAKELPARAM(s, e)); + EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e)); } @@ -910,16 +1013,16 @@ */ static void EDIT_MoveEnd(WND *wndPtr, BOOL extend) { - int s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - int e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - int l = EDIT_EM_LineFromChar(wndPtr, e, 0L); - int linelength = EDIT_EM_LineLength(wndPtr, e, 0L); - int lineindex = EDIT_EM_LineIndex(wndPtr, l, 0L); + UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L); + UINT ll = (UINT)EDIT_EM_LineLength(wndPtr, e, 0L); + UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L); - e = lineindex + linelength; + e = li + ll; if (!extend) s = e; - EDIT_EM_SetSel(wndPtr, TRUE, MAKELPARAM(s, e)); + EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e)); } @@ -930,21 +1033,21 @@ */ static void EDIT_MoveForward(WND *wndPtr, BOOL extend) { - int s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - int e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - int l = EDIT_EM_LineFromChar(wndPtr, e, 0L); - int linecount = EDIT_EM_GetLineCount(wndPtr, e, 0L); - int linelength = EDIT_EM_LineLength(wndPtr, e, 0L); - int lineindex = EDIT_EM_LineIndex(wndPtr, l, 0L); + UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L); + UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, e, 0L); + UINT ll = (UINT)EDIT_EM_LineLength(wndPtr, e, 0L); + UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L); - if (e - lineindex == linelength) { - if (l != linecount - 1) - e = EDIT_EM_LineIndex(wndPtr, l + 1, 0L); + if (e - li == ll) { + if (l != lc - 1) + e = (UINT)EDIT_EM_LineIndex(wndPtr, l + 1, 0L); } else e++; if (!extend) s = e; - EDIT_EM_SetSel(wndPtr, TRUE, MAKELPARAM(s, e)); + EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e)); } @@ -957,15 +1060,15 @@ */ static void EDIT_MoveHome(WND *wndPtr, BOOL extend) { - int s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - int e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - int l = EDIT_EM_LineFromChar(wndPtr, e, 0L); - int lineindex = EDIT_EM_LineIndex(wndPtr, l, 0L); + UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L); + UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L); - e = lineindex; + e = li; if (!extend) s = e; - EDIT_EM_SetSel(wndPtr, TRUE, MAKELPARAM(s, e)); + EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e)); } @@ -976,22 +1079,22 @@ */ static void EDIT_MovePageDown(WND *wndPtr, BOOL extend) { - int s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - int e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - int l = EDIT_EM_LineFromChar(wndPtr, e, 0L); - int linecount = EDIT_EM_GetLineCount(wndPtr, e, 0L); - int lineindex = EDIT_EM_LineIndex(wndPtr, l, 0L); - int x; + UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L); + UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, e, 0L); + UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L); + INT x; - if (l < linecount - 1) { - x = EDIT_WndXFromCol(wndPtr, l, e - lineindex); - l = MIN(linecount - 1, l + EDIT_GetVisibleLineCount(wndPtr)); - e = EDIT_EM_LineIndex(wndPtr, l, 0L) + + if (l < lc - 1) { + x = EDIT_WndXFromCol(wndPtr, l, e - li); + l = MIN(lc - 1, l + EDIT_GetVisibleLineCount(wndPtr)); + e = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L) + EDIT_ColFromWndX(wndPtr, l, x); } if (!extend) s = e; - EDIT_EM_SetSel(wndPtr, TRUE, MAKELPARAM(s, e)); + EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e)); } @@ -1002,21 +1105,21 @@ */ static void EDIT_MovePageUp(WND *wndPtr, BOOL extend) { - int s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - int e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - int l = EDIT_EM_LineFromChar(wndPtr, e, 0L); - int lineindex = EDIT_EM_LineIndex(wndPtr, l, 0L); - int x; + UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L); + UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L); + INT x; if (l) { - x = EDIT_WndXFromCol(wndPtr, l, e - lineindex); + x = EDIT_WndXFromCol(wndPtr, l, e - li); l = MAX(0, l - EDIT_GetVisibleLineCount(wndPtr)); - e = EDIT_EM_LineIndex(wndPtr, l, 0L) + + e = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L) + EDIT_ColFromWndX(wndPtr, l, x); } if (!extend) s = e; - EDIT_EM_SetSel(wndPtr, TRUE, MAKELPARAM(s, e)); + EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e)); } @@ -1027,21 +1130,21 @@ */ static void EDIT_MoveUpward(WND *wndPtr, BOOL extend) { - int s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - int e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - int l = EDIT_EM_LineFromChar(wndPtr, e, 0L); - int lineindex = EDIT_EM_LineIndex(wndPtr, l, 0L); - int x; + UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L); + UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L); + INT x; if (l) { - x = EDIT_WndXFromCol(wndPtr, l, e - lineindex); + x = EDIT_WndXFromCol(wndPtr, l, e - li); l--; - e = EDIT_EM_LineIndex(wndPtr, l, 0L) + + e = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L) + EDIT_ColFromWndX(wndPtr, l, x); } if (!extend) s = e; - EDIT_EM_SetSel(wndPtr, TRUE, MAKELPARAM(s, e)); + EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e)); } @@ -1052,26 +1155,26 @@ */ static void EDIT_MoveWordBackward(WND *wndPtr, BOOL extend) { - int s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - int e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - int l = EDIT_EM_LineFromChar(wndPtr, e, 0L); - int linelength = EDIT_EM_LineLength(wndPtr, e, 0L); - int lineindex = EDIT_EM_LineIndex(wndPtr, l, 0L); + UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L); + UINT ll = (UINT)EDIT_EM_LineLength(wndPtr, e, 0L); + UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L); char *text; - if (e - lineindex == 0) { + if (e - li == 0) { if (l) { - lineindex = EDIT_EM_LineIndex(wndPtr, l - 1, 0L); - e = lineindex + EDIT_EM_LineLength(wndPtr, lineindex, 0L); + li = (UINT)EDIT_EM_LineIndex(wndPtr, l - 1, 0L); + e = li + (UINT)EDIT_EM_LineLength(wndPtr, li, 0L); } } else { text = EDIT_GetPointer(wndPtr); - e = lineindex + EDIT_CallWordBreakProc(wndPtr, text + lineindex, - e - lineindex, linelength, WB_LEFT); + e = li + (UINT)EDIT_CallWordBreakProc(wndPtr, + text + li, e - li, ll, WB_LEFT); } if (!extend) s = e; - EDIT_EM_SetSel(wndPtr, TRUE, MAKELPARAM(s, e)); + EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e)); } @@ -1082,25 +1185,25 @@ */ static void EDIT_MoveWordForward(WND *wndPtr, BOOL extend) { - int s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - int e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - int l = EDIT_EM_LineFromChar(wndPtr, e, 0L); - int linecount = EDIT_EM_GetLineCount(wndPtr, e, 0L); - int linelength = EDIT_EM_LineLength(wndPtr, e, 0L); - int lineindex = EDIT_EM_LineIndex(wndPtr, l, 0L); + UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT l = (UINT)EDIT_EM_LineFromChar(wndPtr, e, 0L); + UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, e, 0L); + UINT ll = (UINT)EDIT_EM_LineLength(wndPtr, e, 0L); + UINT li = (UINT)EDIT_EM_LineIndex(wndPtr, l, 0L); char *text; - if (e - lineindex == linelength) { - if (l != linecount - 1) - e = EDIT_EM_LineIndex(wndPtr, l + 1, 0L); + if (e - li == ll) { + if (l != lc - 1) + e = (UINT)EDIT_EM_LineIndex(wndPtr, l + 1, 0L); } else { text = EDIT_GetPointer(wndPtr); - e = lineindex + EDIT_CallWordBreakProc(wndPtr, text + lineindex, - e - lineindex + 1, linelength, WB_RIGHT); + e = li + (UINT)EDIT_CallWordBreakProc(wndPtr, + text + li, e - li + 1, ll, WB_RIGHT); } if (!extend) s = e; - EDIT_EM_SetSel(wndPtr, TRUE, MAKELPARAM(s, e)); + EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e)); } @@ -1109,44 +1212,40 @@ * EDIT_PaintLine * */ -static void EDIT_PaintLine(WND *wndPtr, HDC hdc, int line) +static void EDIT_PaintLine(WND *wndPtr, HDC hdc, UINT line, BOOL rev) { - EDITSTATE *es = EDITSTATEPTR(wndPtr); - int firstvis = EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L); - int viscount = EDIT_GetVisibleLineCount(wndPtr); - int linecount = EDIT_EM_GetLineCount(wndPtr, 0, 0L); - int LineStart; - int LineEnd; - int ReverseStart; - int ReverseEnd; - int x; - int y; + UINT fv = (UINT)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L); + UINT vlc = EDIT_GetVisibleLineCount(wndPtr); + UINT lc = (UINT)EDIT_EM_GetLineCount(wndPtr, 0, 0L); + UINT li; + UINT ll; + UINT s; + UINT e; + INT x; + INT y; - if ((line < firstvis) || (line > firstvis + viscount) || (line >= linecount)) + if ((line < fv) || (line > fv + vlc) || (line >= lc)) return; dprintf_edit(stddeb, "edit: EDIT_PaintLine: line=%d\n", line); x = EDIT_WndXFromCol(wndPtr, line, 0); y = EDIT_WndYFromLine(wndPtr, line); - LineStart = EDIT_EM_LineIndex(wndPtr, line, 0L); - LineEnd = LineStart + EDIT_EM_LineLength(wndPtr, LineStart, 0L); - ReverseStart = MIN(es->SelStart, es->SelEnd); - ReverseEnd = MAX(es->SelStart, es->SelEnd); - ReverseStart = MIN(LineEnd, MAX(LineStart, ReverseStart)); - ReverseEnd = MIN(LineEnd, MAX(LineStart, ReverseEnd)); - if (ReverseStart != ReverseEnd) { - x += EDIT_PaintText(wndPtr, hdc, x, y, line, - 0, ReverseStart - LineStart, FALSE); - x += EDIT_PaintText(wndPtr, hdc, x, y, line, - ReverseStart - LineStart, - ReverseEnd - ReverseStart, TRUE); - x += EDIT_PaintText(wndPtr, hdc, x, y, line, - ReverseEnd - LineStart, - LineEnd - ReverseEnd, FALSE); + li = (UINT)EDIT_EM_LineIndex(wndPtr, line, 0L); + ll = (UINT)EDIT_EM_LineLength(wndPtr, li, 0L); + s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + ORDER_UINT(s, e); + s = MIN(li + ll, MAX(li, s)); + e = MIN(li + ll, MAX(li, e)); + if (rev && (s != e) && + ((GetFocus() == wndPtr->hwndSelf) || + (wndPtr->dwStyle & ES_NOHIDESEL))) { + x += EDIT_PaintText(wndPtr, hdc, x, y, line, 0, s - li, FALSE); + x += EDIT_PaintText(wndPtr, hdc, x, y, line, s - li, e - s, TRUE); + x += EDIT_PaintText(wndPtr, hdc, x, y, line, e - li, li + ll - e, FALSE); } else - x += EDIT_PaintText(wndPtr, hdc, x, y, line, - 0, LineEnd - LineStart, FALSE); + x += EDIT_PaintText(wndPtr, hdc, x, y, line, 0, ll, FALSE); } @@ -1155,19 +1254,18 @@ * EDIT_PaintText * */ -static int EDIT_PaintText(WND *wndPtr, HDC hdc, int x, int y, int line, int col, int count, BOOL rev) +static UINT EDIT_PaintText(WND *wndPtr, HDC hdc, INT x, INT y, UINT line, UINT col, UINT count, BOOL rev) { EDITSTATE *es = EDITSTATEPTR(wndPtr); COLORREF BkColor; COLORREF TextColor; - int ret; + UINT ret; char *text; - int lineindex = EDIT_EM_LineIndex(wndPtr, line, 0L); - int xoffset = EDIT_GetXOffset(wndPtr); + UINT li; + INT xoff; - if (count < 1) + if (!count) return 0; - BkColor = GetBkColor(hdc); TextColor = GetTextColor(hdc); if (rev) { @@ -1175,8 +1273,10 @@ SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT)); } text = EDIT_GetPointer(wndPtr); - ret = LOWORD(TabbedTextOut(hdc, x, y, text + lineindex + col, count, - es->NumTabStops, es->TabStops, -xoffset)); + li = (UINT)EDIT_EM_LineIndex(wndPtr, line, 0L); + xoff = EDIT_GetXOffset(wndPtr); + ret = LOWORD(TabbedTextOut(hdc, x, y, text + li + col, count, + es->NumTabStops, es->TabStops, -xoff)); if (rev) { SetBkColor(hdc, BkColor); SetTextColor(hdc, TextColor); @@ -1219,14 +1319,14 @@ const char *str = (char *)lParam; int strl = strlen(str); int tl = EDIT_WM_GetTextLength(wndPtr, 0, 0L); - int s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - int e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); int i; char *p; char *text; BOOL redraw; - ORDER_INT(s,e); + ORDER_UINT(s,e); if (!EDIT_MakeFit(wndPtr, tl - (e - s) + strl)) { EDIT_NOTIFY_PARENT(wndPtr, EN_MAXTEXT); return 0L; @@ -1243,7 +1343,7 @@ p[i] = str[i]; EDIT_BuildLineDefs(wndPtr); e += strl; - EDIT_EM_SetSel(wndPtr, TRUE, MAKELPARAM(e, e)); + EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(e, e)); EDIT_EM_SetModify(wndPtr, TRUE, 0L); EDIT_NOTIFY_PARENT(wndPtr, EN_UPDATE); EDIT_WM_SetRedraw(wndPtr, redraw, 0L); @@ -1264,10 +1364,10 @@ */ static void EDIT_ScrollIntoView(WND *wndPtr) { - int e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); int l = EDIT_EM_LineFromChar(wndPtr, e, 0L); int lineindex = EDIT_EM_LineIndex(wndPtr, l, 0L); - int firstvis = EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L); + int firstvis = (int)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L); int vislinecount = EDIT_GetVisibleLineCount(wndPtr); int wndwidth = EDIT_GetWndWidth(wndPtr); int charwidth = EDIT_GetAveCharWidth(wndPtr); @@ -1300,7 +1400,7 @@ * Calculates, for a given line and column, the X-coordinate on the screen. * */ -static int EDIT_WndXFromCol(WND *wndPtr, int line, int col) +static INT EDIT_WndXFromCol(WND *wndPtr, UINT line, UINT col) { EDITSTATE *es = EDITSTATEPTR(wndPtr); char *text = EDIT_GetPointer(wndPtr); @@ -1308,7 +1408,7 @@ HDC hdc; HFONT hFont; HFONT oldFont = 0; - int linecount = EDIT_EM_GetLineCount(wndPtr, 0, 0L); + int linecount = (int)EDIT_EM_GetLineCount(wndPtr, 0, 0L); int lineindex = EDIT_EM_LineIndex(wndPtr, line, 0L); int linelength = EDIT_EM_LineLength(wndPtr, lineindex, 0L); int xoffset = EDIT_GetXOffset(wndPtr); @@ -1336,9 +1436,9 @@ * Calculates, for a given line, the Y-coordinate on the screen. * */ -static int EDIT_WndYFromLine(WND *wndPtr, int line) +static INT EDIT_WndYFromLine(WND *wndPtr, UINT line) { - int firstvis = EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L); + int firstvis = (int)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L); int lineheight = EDIT_GetLineHeight(wndPtr); return (line - firstvis) * lineheight; @@ -1356,7 +1456,7 @@ * internally, so we can decide this for ourselves. * */ -static int EDIT_WordBreakProc(char *s, int index, int count, int action) +static INT EDIT_WordBreakProc(char *s, INT index, INT count, INT action) { int ret = 0; @@ -1481,9 +1581,9 @@ char *text; char *src; char *dst; - int len; + UINT len; int i; - int linecount = EDIT_EM_GetLineCount(wndPtr, 0, 0L); + int linecount = (int)EDIT_EM_GetLineCount(wndPtr, 0, 0L); if (!IsMultiLine(wndPtr)) wParam = 0; @@ -1629,7 +1729,7 @@ return 0L; if ((INT)wParam == -1) wParam = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - l = EDIT_EM_GetLineCount(wndPtr, 0, 0L) - 1; + l = (int)EDIT_EM_GetLineCount(wndPtr, 0, 0L) - 1; while (EDIT_EM_LineIndex(wndPtr, l, 0L) > (UINT)wParam) l--; return (LRESULT)l; @@ -1644,19 +1744,19 @@ static LRESULT EDIT_EM_LineIndex(WND *wndPtr, WPARAM wParam, LPARAM lParam) { EDITSTATE *es = EDITSTATEPTR(wndPtr); - int e; + UINT e; int l; - if ((INT)wParam < 0) { + if ((INT)wParam == -1) { e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - l = EDIT_EM_GetLineCount(wndPtr, 0, 0L) - 1; - while (es->LineDefs[l].offset > (UINT)wParam) + l = (int)EDIT_EM_GetLineCount(wndPtr, 0, 0L) - 1; + while (es->LineDefs[l].offset > e) l--; return (LRESULT)es->LineDefs[l].offset; } - if (wParam >= es->LineCount) + if ((UINT)wParam >= es->LineCount) return -1L; - return (LRESULT)es->LineDefs[wParam].offset; + return (LRESULT)es->LineDefs[(UINT)wParam].offset; } @@ -1668,18 +1768,23 @@ static LRESULT EDIT_EM_LineLength(WND *wndPtr, WPARAM wParam, LPARAM lParam) { EDITSTATE *es = EDITSTATEPTR(wndPtr); - int SelStartLine; - int SelEndLine; + UINT selstart; + UINT selend; + int startline; + int endline; if (!IsMultiLine(wndPtr)) return (LRESULT)es->LineDefs[0].length; - if ((INT)wParam >= 0) - return (LRESULT)es->LineDefs[EDIT_EM_LineFromChar(wndPtr, wParam, 0L)].length; - SelStartLine = EDIT_EM_LineFromChar(wndPtr, es->SelStart, 0L); - SelEndLine = EDIT_EM_LineFromChar(wndPtr, es->SelEnd, 0L); - return (LRESULT)(es->SelStart - es->LineDefs[SelStartLine].offset + - es->LineDefs[SelEndLine].offset + - es->LineDefs[SelEndLine].length - es->SelEnd); + if ((INT)wParam == -1) { + selstart = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + selend = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + startline = EDIT_EM_LineFromChar(wndPtr, selstart, 0L); + endline = EDIT_EM_LineFromChar(wndPtr, selend, 0L); + return (LRESULT)(selstart - es->LineDefs[startline].offset + + es->LineDefs[endline].offset + + es->LineDefs[endline].length - selend); + } + return (LRESULT)es->LineDefs[(UINT)EDIT_EM_LineFromChar(wndPtr, wParam, 0L)].length; } @@ -1691,8 +1796,8 @@ static LRESULT EDIT_EM_LineScroll(WND *wndPtr, WPARAM wParam, LPARAM lParam) { EDITSTATE *es = EDITSTATEPTR(wndPtr); - int linecount = EDIT_EM_GetLineCount(wndPtr, 0, 0L); - int firstvis = EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L); + int linecount = (int)EDIT_EM_GetLineCount(wndPtr, 0, 0L); + int firstvis = (int)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L); int newfirstvis = firstvis + (INT)LOWORD(lParam); int xoffset = EDIT_GetXOffset(wndPtr); int newxoffset = xoffset + (INT)HIWORD(lParam); @@ -1760,6 +1865,7 @@ * EM_SCROLL * * FIXME: undocumented message. + * */ static LRESULT EDIT_EM_Scroll(WND *wndPtr, WPARAM wParam, LPARAM lParam) { @@ -1780,14 +1886,10 @@ if (IsMultiLine(wndPtr)) { EDIT_ReleasePointer(wndPtr); /* - * FIXME: specs say: old buffer should be freed - * by the aplication, but e.g. Notepad doesn't. - * Should we LOCAL_Free() the old hBuf ? + * old buffer is freed by caller */ - LOCAL_Free(wndPtr->hInstance, es->hBuf); es->hBuf = (HLOCAL)wParam; - es->BufSize = MIN(1, LOCAL_Size(wndPtr->hInstance, es->hBuf)) - 1; - es->hBuf = LOCAL_ReAlloc(wndPtr->hInstance, es->hBuf, es->BufSize + 1, LMEM_MOVEABLE); + es->BufSize = LOCAL_Size(wndPtr->hInstance, es->hBuf) - 1; es->LineCount = 0; es->FirstVisibleLine = 0; es->SelStart = es->SelEnd = 0; @@ -1810,7 +1912,7 @@ { EDITSTATE *es = EDITSTATEPTR(wndPtr); - es->TextChanged = wParam; + es->TextChanged = (BOOL)wParam; return 0L; } @@ -1876,27 +1978,20 @@ static LRESULT EDIT_EM_SetSel(WND *wndPtr, WPARAM wParam, LPARAM lParam) { EDITSTATE *es = EDITSTATEPTR(wndPtr); - int ns = (INT)LOWORD(lParam); - int ne = (INT)HIWORD(lParam); - int s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - int e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - int sl; + UINT ns = LOWORD(lParam); + UINT ne = HIWORD(lParam); + UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); int el; - int sc; - int ec; int elineindex; int tl = EDIT_WM_GetTextLength(wndPtr, 0, 0L); - RECT rc; - HRGN hRgn1, hRgn2; - HRGN oldRgn, newRgn; - if (ns < 0) { - ne = e; + if ((INT)ns == -1) { ns = e; - } else { + ne = e; + } + else { ns = MIN(ns, tl); - if (ne < 0) - ne = tl; ne = MIN(ne, tl); } es->SelStart = ns; @@ -1907,75 +2002,20 @@ SetCaretPos(EDIT_WndXFromCol(wndPtr, el, ne - elineindex), EDIT_WndYFromLine(wndPtr, el)); } - if (wParam) + if (!wParam) EDIT_ScrollIntoView(wndPtr); - - /* - * Let's do some repainting - */ - ORDER_INT(s, e); - ORDER_INT(ns, ne); - if (EDIT_GetRedraw(wndPtr) && - !(((s == e) && (ns == ne)) || - ((ns == s) && (ne == e)))) { - /* Yes, there is something to paint */ - hRgn1 = CreateRectRgn(0, 0, 0, 0); - hRgn2 = CreateRectRgn(0, 0, 0, 0); - oldRgn = CreateRectRgn(0, 0, 0, 0); - newRgn = CreateRectRgn(0, 0, 0, 0); - /* Build the old selection region */ - sl = EDIT_EM_LineFromChar(wndPtr, s, 0L); - el = EDIT_EM_LineFromChar(wndPtr, e, 0L); - sc = s - EDIT_EM_LineIndex(wndPtr, sl, 0L); - ec = e - EDIT_EM_LineIndex(wndPtr, el, 0L); - if (sl == el) { - EDIT_GetLineRect(wndPtr, sl, sc, ec, &rc); - SetRectRgn(oldRgn, rc.left, rc.top, rc.right, rc.bottom); - } else { - EDIT_GetLineRect(wndPtr, sl, sc, -1, &rc); - SetRectRgn(hRgn1, rc.left, rc.top, rc.right, rc.bottom); - EDIT_GetLineRect(wndPtr, el, 0, ec, &rc); - SetRectRgn(hRgn2, rc.left, rc.top, rc.right, rc.bottom); - CombineRgn(oldRgn, hRgn1, hRgn2, RGN_OR); - if (el > sl + 1) { - EDIT_GetLineRect(wndPtr, sl + 1, 0, -1, &rc); - rc.bottom = rc.top + (rc.bottom - rc.top) * (el - sl - 1); - CombineRgn(hRgn1, oldRgn, 0, RGN_COPY); - SetRectRgn(hRgn2, rc.left, rc.top, rc.right, rc.bottom); - CombineRgn(oldRgn, hRgn1, hRgn2, RGN_OR); - } - } - /* Build the new selection region */ - sl = EDIT_EM_LineFromChar(wndPtr, ns, 0L); - el = EDIT_EM_LineFromChar(wndPtr, ne, 0L); - sc = ns - EDIT_EM_LineIndex(wndPtr, sl, 0L); - ec = ne - EDIT_EM_LineIndex(wndPtr, el, 0L); - if (sl == el) { - EDIT_GetLineRect(wndPtr, sl, sc, ec, &rc); - SetRectRgn(newRgn, rc.left, rc.top, rc.right, rc.bottom); - } else { - EDIT_GetLineRect(wndPtr, sl, sc, -1, &rc); - SetRectRgn(hRgn1, rc.left, rc.top, rc.right, rc.bottom); - EDIT_GetLineRect(wndPtr, el, 0, ec, &rc); - SetRectRgn(hRgn2, rc.left, rc.top, rc.right, rc.bottom); - CombineRgn(newRgn, hRgn1, hRgn2, RGN_OR); - if (el > sl + 1) { - EDIT_GetLineRect(wndPtr, sl + 1, 0, -1, &rc); - rc.bottom = rc.top + (rc.bottom - rc.top) * (el - sl - 1); - CombineRgn(hRgn1, newRgn, 0, RGN_COPY); - SetRectRgn(hRgn2, rc.left, rc.top, rc.right, rc.bottom); - CombineRgn(newRgn, hRgn1, hRgn2, RGN_OR); - } - } - /* Only difference needs painting */ - CombineRgn(hRgn1, oldRgn, newRgn, RGN_XOR); - /* Only part in formatting RECT needs painting */ - - InvalidateRgn(wndPtr->hwndSelf, hRgn1, FALSE); - DeleteObject(hRgn1); - DeleteObject(hRgn2); - DeleteObject(oldRgn); - DeleteObject(newRgn); + if (EDIT_GetRedraw(wndPtr)) { + ORDER_UINT(s, e); + ORDER_UINT(s, ns); + ORDER_UINT(s, ne); + ORDER_UINT(e, ns); + ORDER_UINT(e, ne); + ORDER_UINT(ns, ne); + if (e != ns) { + EDIT_InvalidateText(wndPtr, s, e); + EDIT_InvalidateText(wndPtr, ns, ne); + } else + EDIT_InvalidateText(wndPtr, s, ne); } return -1L; } @@ -1994,13 +2034,13 @@ return 0L; if (es->TabStops) free(es->TabStops); - es->NumTabStops = wParam; - if (wParam == 0) + es->NumTabStops = (UINT)wParam; + if (!wParam) es->TabStops = NULL; else { - es->TabStops = (unsigned short *)xmalloc(wParam * sizeof(unsigned short)); - memcpy(es->TabStops, (unsigned short *)PTR_SEG_TO_LIN(lParam), - wParam * sizeof(unsigned short)); + es->TabStops = (LPINT)xmalloc(wParam * sizeof(unsigned short)); + memcpy(es->TabStops, (LPINT)PTR_SEG_TO_LIN(lParam), + (UINT)wParam * sizeof(INT)); } return 1L; } @@ -2075,19 +2115,19 @@ */ static LRESULT EDIT_WM_Clear(WND *wndPtr, WPARAM wParam, LPARAM lParam) { - int s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - int e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); char *text; BOOL redraw; if (s != e) { redraw = EDIT_GetRedraw(wndPtr); EDIT_WM_SetRedraw(wndPtr, FALSE, 0L); - ORDER_INT(s, e); + ORDER_UINT(s, e); text = EDIT_GetPointer(wndPtr); strcpy(text + s, text + e); EDIT_BuildLineDefs(wndPtr); - EDIT_EM_SetSel(wndPtr, TRUE, MAKELPARAM(s, s)); + EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, s)); EDIT_EM_SetModify(wndPtr, TRUE, 0L); EDIT_NOTIFY_PARENT(wndPtr, EN_UPDATE); EDIT_WM_SetRedraw(wndPtr, redraw, 0L); @@ -2107,8 +2147,8 @@ */ static LRESULT EDIT_WM_Copy(WND *wndPtr, WPARAM wParam, LPARAM lParam) { - int s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - int e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); HGLOBAL hdst; char *text; char *dst; @@ -2117,7 +2157,7 @@ if (e == s) return -1L; - ORDER_INT(s, e); + ORDER_UINT(s, e); hdst = GlobalAlloc(GMEM_MOVEABLE, (DWORD)(e - s + 1)); dst = GlobalLock(hdst); text = EDIT_GetPointer(wndPtr); @@ -2143,37 +2183,12 @@ { CREATESTRUCT *cs = (CREATESTRUCT *)PTR_SEG_TO_LIN(lParam); EDITSTATE *es; - char *windowName = NULL; char *text; es = xmalloc(sizeof(EDITSTATE)); memset(es, 0, sizeof(EDITSTATE)); *(EDITSTATE **)wndPtr->wExtra = es; - if (IsMultiLine(wndPtr)) { - es->BufLimit = BUFLIMIT_MULTI; - es->PasswordChar = '\0'; - } else { - es->BufLimit = BUFLIMIT_SINGLE; - es->PasswordChar = (cs->style & ES_PASSWORD) ? '*' : '\0'; - } - - es->BufSize = IsMultiLine(wndPtr) ? BUFSTART_MULTI : BUFSTART_SINGLE; - if (cs->lpszName) - windowName = (char *)PTR_SEG_TO_LIN(cs->lpszName); - if (windowName) - es->BufSize = MAX(es->BufSize, strlen(windowName)); - es->hBuf = LOCAL_Alloc(wndPtr->hInstance, LMEM_MOVEABLE, es->BufSize + 1); - text = EDIT_GetPointer(wndPtr); - if (!text) { - fprintf(stderr, "edit: WM_CREATE: unable to heap buffer, please report !\n"); - return -1L; - } - if (windowName) - strcpy(text, windowName); - else - text[0] = '\0'; - if (cs->style & WS_VSCROLL) cs->style |= ES_AUTOVSCROLL; if (cs->style & WS_HSCROLL) @@ -2184,7 +2199,26 @@ if ((cs->style & WS_BORDER) && (cs->style & WS_DLGFRAME)) cs->style ^= WS_DLGFRAME; + if (IsMultiLine(wndPtr)) { + es->BufSize = BUFSTART_MULTI; + es->BufLimit = BUFLIMIT_MULTI; + es->PasswordChar = '\0'; + } else { + es->BufSize = BUFSTART_SINGLE; + es->BufLimit = BUFLIMIT_SINGLE; + es->PasswordChar = (cs->style & ES_PASSWORD) ? '*' : '\0'; + } + if (!(es->hBuf = LOCAL_Alloc(wndPtr->hInstance, LMEM_MOVEABLE, es->BufSize + 1))) { + fprintf(stderr, "edit: WM_CREATE: unable to heap buffer, please report !\n"); + return -1L; + } + es->BufSize = LOCAL_Size(wndPtr->hInstance, es->hBuf) - 1; + text = EDIT_GetPointer(wndPtr); + *text = '\0'; + EDIT_BuildLineDefs(wndPtr); EDIT_WM_SetFont(wndPtr, 0, 0L); + if (cs->lpszName) + EDIT_EM_ReplaceSel(wndPtr, FALSE, (LPARAM)cs->lpszName); EDIT_WM_SetRedraw(wndPtr, TRUE, 0L); return 0L; } @@ -2230,6 +2264,7 @@ */ static LRESULT EDIT_WM_Enable(WND *wndPtr, WPARAM wParam, LPARAM lParam) { + EDIT_InvalidateText(wndPtr, 0, -1); return 0L; } @@ -2245,6 +2280,8 @@ RECT rc; hBrush = (HBRUSH)EDIT_SEND_CTLCOLOR(wndPtr, wParam); + if (!hBrush) + hBrush = (HBRUSH)GetStockObject(WHITE_BRUSH); GetClientRect(wndPtr->hwndSelf, &rc); IntersectClipRect((HDC)wParam, rc.left, rc.top, rc.right, rc.bottom); @@ -2296,7 +2333,7 @@ LRESULT lResult = 0L; len = strlen(text); - if ((int)wParam > len) { + if ((UINT)wParam > len) { strcpy((char *)PTR_SEG_TO_LIN(lParam), text); lResult = (LRESULT)len ; } @@ -2392,8 +2429,8 @@ */ static LRESULT EDIT_WM_KeyDown(WND *wndPtr, WPARAM wParam, LPARAM lParam) { - int s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - int e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); BOOL shift; BOOL control; @@ -2479,9 +2516,15 @@ */ static LRESULT EDIT_WM_KillFocus(WND *wndPtr, WPARAM wParam, LPARAM lParam) { + UINT s; + UINT e; + DestroyCaret(); - if(!(wndPtr->dwStyle & ES_NOHIDESEL)) - EDIT_EM_SetSel(wndPtr, FALSE, MAKELPARAM(-1, 0)); + if(!(wndPtr->dwStyle & ES_NOHIDESEL)) { + s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + EDIT_InvalidateText(wndPtr, s, e); + } EDIT_NOTIFY_PARENT(wndPtr, EN_KILLFOCUS); return 0L; } @@ -2491,19 +2534,21 @@ * * WM_LBUTTONDBLCLK * + * The caret position has been set on the WM_LBUTTONDOWN message + * */ static LRESULT EDIT_WM_LButtonDblClk(WND *wndPtr, WPARAM wParam, LPARAM lParam) { int s; - int e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); - int l = EDIT_EM_LineFromChar(wndPtr, e, 0L); - int lineindex = EDIT_EM_LineIndex(wndPtr, l, 0L); - int linelength = EDIT_EM_LineLength(wndPtr, e, 0L); + UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT l = EDIT_EM_LineFromChar(wndPtr, e, 0L); + int li = EDIT_EM_LineIndex(wndPtr, l, 0L); + int ll = EDIT_EM_LineLength(wndPtr, e, 0L); char *text = EDIT_GetPointer(wndPtr); - s = lineindex + EDIT_CallWordBreakProc(wndPtr, text + lineindex, e - lineindex, linelength, WB_LEFT); - e = lineindex + EDIT_CallWordBreakProc(wndPtr, text + lineindex, e - lineindex, linelength, WB_RIGHT); - EDIT_EM_SetSel(wndPtr, TRUE, MAKELPARAM(s, e)); + s = li + EDIT_CallWordBreakProc(wndPtr, text + li, e - li, ll, WB_LEFT); + e = li + EDIT_CallWordBreakProc(wndPtr, text + li, e - li, ll, WB_RIGHT); + EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e)); return 0L; } @@ -2515,20 +2560,28 @@ */ static LRESULT EDIT_WM_LButtonDown(WND *wndPtr, WPARAM wParam, LPARAM lParam) { - int l; - int s; - int e; + INT x = (INT)LOWORD(lParam); + INT y = (INT)HIWORD(lParam); + UINT l = EDIT_LineFromWndY(wndPtr, y); + UINT c; + UINT s; + UINT e; + UINT fv = (UINT)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L); + UINT vlc = EDIT_GetVisibleLineCount(wndPtr); + UINT li; SetFocus(wndPtr->hwndSelf); SetCapture(wndPtr->hwndSelf); - l = EDIT_LineFromWndY(wndPtr, (INT)HIWORD(lParam)); - e = EDIT_EM_LineIndex(wndPtr, l ,0L) + - EDIT_ColFromWndX(wndPtr, l, (INT)LOWORD(lParam)); + l = MIN(fv + vlc - 1, MAX(fv, l)); + x = MIN(EDIT_GetWndWidth(wndPtr), MAX(0, x)); + c = EDIT_ColFromWndX(wndPtr, l, x); + li = EDIT_EM_LineIndex(wndPtr, l, 0L); + e = li + c; if (GetKeyState(VK_SHIFT) & 0x8000) s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); else s = e; - EDIT_EM_SetSel(wndPtr, TRUE, MAKELPARAM(s, e)); + EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e)); return 0L; } @@ -2553,19 +2606,27 @@ */ static LRESULT EDIT_WM_MouseMove(WND *wndPtr, WPARAM wParam, LPARAM lParam) { - EDITSTATE *es = EDITSTATEPTR(wndPtr); - int Line; - int Col; - int x = (INT)LOWORD(lParam); + INT x; + INT y; + UINT l; + UINT c; + UINT s; + UINT fv; + UINT vlc; + UINT li; if (GetCapture() == wndPtr->hwndSelf) { - Line = EDIT_LineFromWndY(wndPtr, (INT)HIWORD(lParam)); - Line = MAX(Line, EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L)); - Line = MIN(Line, EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L) + EDIT_GetVisibleLineCount(wndPtr) - 1); + x = (INT)LOWORD(lParam); + y = (INT)HIWORD(lParam); + fv = (UINT)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L); + vlc = EDIT_GetVisibleLineCount(wndPtr); + l = EDIT_LineFromWndY(wndPtr, y); + l = MIN(fv + vlc - 1, MAX(fv, l)); x = MIN(EDIT_GetWndWidth(wndPtr), MAX(0, x)); - Col = EDIT_ColFromWndX(wndPtr, Line, x); - EDIT_EM_SetSel(wndPtr, FALSE, MAKELPARAM(es->SelStart, - EDIT_EM_LineIndex(wndPtr, Line, 0L) + Col)); + c = EDIT_ColFromWndX(wndPtr, l, x); + s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + li = EDIT_EM_LineIndex(wndPtr, l, 0L); + EDIT_EM_SetSel(wndPtr, 1, MAKELPARAM(s, li + c)); } return 0L; } @@ -2581,13 +2642,16 @@ EDITSTATE *es = EDITSTATEPTR(wndPtr); PAINTSTRUCT ps; int i; - int firstvis = EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L); + int firstvis = (int)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L); HDC hdc; HFONT hFont; HFONT oldFont = 0; RECT rc; RECT rcLine; RECT rcRgn; + BOOL rev = IsWindowEnabled(wndPtr->hwndSelf) && + ((GetFocus() == wndPtr->hwndSelf) || + (wndPtr->dwStyle & ES_NOHIDESEL)); hdc = BeginPaint(wndPtr->hwndSelf, &ps); GetClientRect(wndPtr->hwndSelf, &rc); @@ -2596,11 +2660,13 @@ if (hFont) oldFont = SelectObject(hdc, hFont); EDIT_SEND_CTLCOLOR(wndPtr, hdc); + if (!IsWindowEnabled(wndPtr->hwndSelf)) + SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT)); GetClipBox(hdc, &rcRgn); for (i = firstvis ; i <= MIN(firstvis + EDIT_GetVisibleLineCount(wndPtr), firstvis + es->LineCount - 1) ; i++ ) { EDIT_GetLineRect(wndPtr, i, 0, -1, &rcLine); if (IntersectRect(&rc, &rcRgn, &rcLine)) - EDIT_PaintLine(wndPtr, hdc, i); + EDIT_PaintLine(wndPtr, hdc, i, rev); } if (hFont) SelectObject(hdc, oldFont); @@ -2652,10 +2718,13 @@ */ static LRESULT EDIT_WM_SetFocus(WND *wndPtr, WPARAM wParam, LPARAM lParam) { - LPARAM sel = EDIT_EM_GetSel(wndPtr, 0, 0L); + UINT s = LOWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); + UINT e = HIWORD(EDIT_EM_GetSel(wndPtr, 0, 0L)); CreateCaret(wndPtr->hwndSelf, 0, 2, EDIT_GetLineHeight(wndPtr)); - EDIT_EM_SetSel(wndPtr, FALSE, sel); + EDIT_EM_SetSel(wndPtr, 1, MAKELPARAM(s, e)); + if(!(wndPtr->dwStyle & ES_NOHIDESEL)) + EDIT_InvalidateText(wndPtr, s, e); ShowCaret(wndPtr->hwndSelf); EDIT_NOTIFY_PARENT(wndPtr, EN_SETFOCUS); return 0L; @@ -2686,12 +2755,12 @@ SelectObject(hdc, oldFont); ReleaseDC(wndPtr->hwndSelf, hdc); EDIT_BuildLineDefs(wndPtr); - if (lParam && EDIT_GetRedraw(wndPtr)) + if ((BOOL)lParam && EDIT_GetRedraw(wndPtr)) InvalidateRect(wndPtr->hwndSelf, NULL, TRUE); if (wndPtr->hwndSelf == GetFocus()) { DestroyCaret(); CreateCaret(wndPtr->hwndSelf, 0, 2, EDIT_GetLineHeight(wndPtr)); - EDIT_EM_SetSel(wndPtr, FALSE, sel); + EDIT_EM_SetSel(wndPtr, 1, sel); ShowCaret(wndPtr->hwndSelf); } return 0L; @@ -2707,7 +2776,7 @@ { EDITSTATE *es = EDITSTATEPTR(wndPtr); - es->Redraw = wParam ? TRUE : FALSE; + es->Redraw = (BOOL)wParam; return 0L; } @@ -2719,7 +2788,7 @@ */ static LRESULT EDIT_WM_SetText(WND *wndPtr, WPARAM wParam, LPARAM lParam) { - EDIT_EM_SetSel(wndPtr, FALSE, MAKELPARAM(0, -1)); + EDIT_EM_SetSel(wndPtr, 1, MAKELPARAM(0, -1)); EDIT_WM_Clear(wndPtr, 0, 0L); if (lParam) EDIT_EM_ReplaceSel(wndPtr, 0, lParam); @@ -2738,8 +2807,11 @@ { if (EDIT_GetRedraw(wndPtr) && ((wParam == SIZE_MAXIMIZED) || - (wParam == SIZE_RESTORED))) + (wParam == SIZE_RESTORED))) { + if (IsMultiLine(wndPtr) && IsWordWrap(wndPtr)) + EDIT_BuildLineDefs(wndPtr); InvalidateRect(wndPtr->hwndSelf, NULL, TRUE); + } return 0L; } @@ -2753,8 +2825,8 @@ */ static LRESULT EDIT_WM_VScroll(WND *wndPtr, WPARAM wParam, LPARAM lParam) { - int linecount = EDIT_EM_GetLineCount(wndPtr, 0, 0L); - int firstvis = EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L); + int linecount = (int)EDIT_EM_GetLineCount(wndPtr, 0, 0L); + int firstvis = (int)EDIT_EM_GetFirstVisibleLine(wndPtr, 0, 0L); int vislinecount = EDIT_GetVisibleLineCount(wndPtr); int dy = 0; BOOL not = TRUE;
diff --git a/controls/menu.c b/controls/menu.c index 7f09a8ea..78e991d 100644 --- a/controls/menu.c +++ b/controls/menu.c
@@ -2227,8 +2227,9 @@ lpmenu->wFlags &= ~MF_POPUP; /* Can't be a popup */ lpmenu->Height = 0; /* Make sure we recalculate the size */ } - SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | - SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED ); + if (IsWindowVisible(hWnd)) + SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | + SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED ); return TRUE; }
diff --git a/controls/scroll.c b/controls/scroll.c index 9824b3b..27323a6 100644 --- a/controls/scroll.c +++ b/controls/scroll.c
@@ -94,14 +94,12 @@ hRgArrowI = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_RGARROWI)); } - /*********************************************************************** - * SCROLL_GetScrollInfo + * SCROLL_GetPtrScrollInfo */ -static SCROLLINFO *SCROLL_GetScrollInfo( HWND hwnd, int nBar ) +static SCROLLINFO *SCROLL_GetPtrScrollInfo( WND* wndPtr, int nBar ) { HANDLE handle; - WND *wndPtr = WIN_FindWndPtr( hwnd ); if (!wndPtr) return NULL; switch(nBar) @@ -128,6 +126,15 @@ return (SCROLLINFO *) USER_HEAP_LIN_ADDR( handle ); } +/*********************************************************************** + * SCROLL_GetScrollInfo + */ +static SCROLLINFO *SCROLL_GetScrollInfo( HWND hwnd, int nBar ) +{ + WND *wndPtr = WIN_FindWndPtr( hwnd ); + return SCROLL_GetPtrScrollInfo( wndPtr, nBar ); +} + /*********************************************************************** * SCROLL_GetScrollBarRect @@ -188,7 +195,7 @@ if ((pixels -= 3*SYSMETRICS_CXVSCROLL+1) > 0) { - SCROLLINFO *info = SCROLL_GetScrollInfo( hwnd, nBar ); + SCROLLINFO *info = SCROLL_GetPtrScrollInfo( wndPtr, nBar ); if ((info->flags & ESB_DISABLE_BOTH) == ESB_DISABLE_BOTH) *thumbPos = 0; else if (info->MinVal == info->MaxVal) @@ -449,7 +456,7 @@ RECT rect; BOOL vertical; WND *wndPtr = WIN_FindWndPtr( hwnd ); - SCROLLINFO *infoPtr = SCROLL_GetScrollInfo( hwnd, nBar ); + SCROLLINFO *infoPtr = SCROLL_GetPtrScrollInfo( wndPtr, nBar ); if (!wndPtr || !infoPtr || ((nBar == SB_VERT) && !(wndPtr->dwStyle & WS_VSCROLL)) || @@ -480,7 +487,7 @@ BOOL vertical; HDC hdc; WND *wndPtr = WIN_FindWndPtr( hwnd ); - SCROLLINFO *infoPtr = SCROLL_GetScrollInfo( hwnd, nBar ); + SCROLLINFO *infoPtr = SCROLL_GetPtrScrollInfo( wndPtr, nBar ); if (!wndPtr || !infoPtr || ((nBar == SB_VERT) && !(wndPtr->dwStyle & WS_VSCROLL)) || @@ -913,6 +920,38 @@ if (bRedraw) SCROLL_RefreshScrollBar( hwnd, nBar ); } +/************************************************************************* + * SCROLL_SetNCSbState + * + * This is for CalcChildScroll in windows/mdi.c + */ +DWORD SCROLL_SetNCSbState(WND* wndPtr, int vMin, int vMax, int vPos, + int hMin, int hMax, int hPos) +{ + SCROLLINFO *infoPtr = SCROLL_GetPtrScrollInfo(wndPtr, SB_VERT); + + wndPtr->dwStyle |= (WS_VSCROLL | WS_HSCROLL); + + if( vMin >= vMax ) + { vMin = vMax; + wndPtr->dwStyle &= ~WS_VSCROLL; } + if( vPos > vMax ) vPos = vMax; else if( vPos < vMin ) vPos = vMin; + infoPtr->MinVal = vMin; + infoPtr->MaxVal = vMax; + infoPtr->CurVal = vPos; + + infoPtr = SCROLL_GetPtrScrollInfo(wndPtr, SB_HORZ); + + if( hMin >= hMax ) + { hMin = hMax; + wndPtr->dwStyle &= ~WS_HSCROLL; } + if( hPos > hMax ) hPos = hMax; else if( hPos < hMin ) hPos = hMin; + infoPtr->MinVal = hMin; + infoPtr->MaxVal = hMax; + infoPtr->CurVal = hPos; + + return wndPtr->dwStyle & (WS_VSCROLL | WS_HSCROLL); +} /************************************************************************* * GetScrollRange (USER.65)
diff --git a/if1632/Makefile.in b/if1632/Makefile.in index d55fe40..288e84a 100644 --- a/if1632/Makefile.in +++ b/if1632/Makefile.in
@@ -34,6 +34,7 @@ toolhelp.spec \ user.spec \ user32.spec \ + w32sys.spec \ win87em.spec \ winprocs.spec \ winprocs32.spec \
diff --git a/if1632/commdlg.spec b/if1632/commdlg.spec index c579065..0f5dc75 100644 --- a/if1632/commdlg.spec +++ b/if1632/commdlg.spec
@@ -13,10 +13,10 @@ 12 pascal16 ReplaceText(ptr) ReplaceText 13 pascal FindTextDlgProc(word word word long) FindTextDlgProc 14 pascal ReplaceTextDlgProc(word word word long) ReplaceTextDlgProc -15 stub ChooseFont -#16 pascal FORMATCHARDLGPROC exported, shared data -#18 pascal FONTSTYLEENUMPROC exported, shared data -#19 pascal FONTFAMILYENUMPROC exported, shared data +15 pascal16 ChooseFont(ptr) ChooseFont +16 pascal16 FormatCharDlgProc(word word word long) FormatCharDlgProc +18 pascal16 FontStyleEnumProc(ptr ptr word long) FontStyleEnumProc +19 pascal16 FontFamilyEnumProc(ptr ptr word long) FontFamilyEnumProc 20 pascal16 PrintDlg(ptr) PrintDlg 21 pascal PrintDlgProc(word word word long) PrintDlgProc 22 pascal PrintSetupDlgProc(word word word long) PrintSetupDlgProc
diff --git a/if1632/gdi.spec b/if1632/gdi.spec index 08d7d6a..cbd75d0 100644 --- a/if1632/gdi.spec +++ b/if1632/gdi.spec
@@ -136,7 +136,7 @@ 148 pascal SetBrushOrg(word s_word s_word) SetBrushOrg 149 pascal GetBrushOrg(word) GetBrushOrg 150 pascal16 UnrealizeObject(word) UnrealizeObject -151 stub CopyMetaFile +151 pascal16 CopyMetaFile(word ptr) CopyMetaFile 153 pascal16 CreateIC(ptr ptr ptr ptr) CreateIC 154 pascal GetNearestColor(word long) GetNearestColor 155 stub QueryAbort @@ -150,7 +150,7 @@ 170 stub SetDCStatus 172 pascal16 SetRectRgn(word s_word s_word s_word s_word) SetRectRgn 173 pascal16 GetClipRgn(word) GetClipRgn -175 stub EnumMetaFile +175 pascal16 EnumMetaFile(word word segptr long) EnumMetaFile 176 pascal16 PlayMetaFileRecord(word ptr ptr word) PlayMetaFileRecord 179 pascal16 GetDCState(word) GetDCState 180 pascal16 SetDCState(word word) SetDCState
diff --git a/if1632/relay.c b/if1632/relay.c index 9daacc1..1197af7 100644 --- a/if1632/relay.c +++ b/if1632/relay.c
@@ -52,6 +52,7 @@ DLL_ENTRY( WINPROCS, DLL_FLAG_ALWAYS_USED), DLL_ENTRY( DDEML, DLL_FLAG_NOT_USED), DLL_ENTRY( LZEXPAND, 0), + DLL_ENTRY( W32SYS, 0), /* Win32 DLLs */ DLL_ENTRY( ADVAPI32, 0), DLL_ENTRY( COMCTL32, 0),
diff --git a/if1632/w32sys.spec b/if1632/w32sys.spec new file mode 100644 index 0000000..04dd968 --- /dev/null +++ b/if1632/w32sys.spec
@@ -0,0 +1,16 @@ +name w32sys +type win16 +id 27 + +#1 WEP +2 stub ISPEFORMAT +3 stub EXECPE +4 stub GETPEEXEINFO +5 stub GETW32SYSVERSION +6 stub LOADPERESOURCE +7 stub GETPERESOURCETABLE +8 stub EXECPEEX +9 stub ITSME +10 stub W32SERROR +11 stub EXP1 +12 pascal16 GetWin32sInfo(ptr) GetWin32sInfo
diff --git a/if1632/winprocs.spec b/if1632/winprocs.spec index 62274e8..056c9f6 100644 --- a/if1632/winprocs.spec +++ b/if1632/winprocs.spec
@@ -31,7 +31,10 @@ 27 pascal EntryAddrProc(word word) MODULE_GetEntryPoint 28 pascal MyAlloc(word word word) MODULE_AllocateSegment 29 pascal16 ActivateAppProc(word long) ACTIVATEAPP_callback - +30 pascal FormatCharDlgProc(word word word long) FormatCharDlgProc +31 pascal16 FontStyleEnumProc(ptr ptr word long) FontStyleEnumProc +32 pascal16 FontFamilyEnumProc(ptr ptr word long) FontFamilyEnumProc + # Interrupt vectors 0-255 are ordinals 100-355 # The 'word' parameter are the flags pushed on the stack by the interrupt 100 register INT_Int00Handler(word) INT_DummyHandler
diff --git a/include/commdlg.h b/include/commdlg.h index f51e4b6..384b0b4 100644 --- a/include/commdlg.h +++ b/include/commdlg.h
@@ -298,6 +298,7 @@ BOOL GetSaveFileName(LPOPENFILENAME lpofn); BOOL PrintDlg(LPPRINTDLG lpPrint); BOOL ReplaceText(LPFINDREPLACE lpFind); +BOOL ChooseFont(LPCHOOSEFONT lpChFont); LRESULT FileOpenDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam); LRESULT FileSaveDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam); @@ -306,6 +307,7 @@ LRESULT ReplaceTextDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam); LRESULT PrintDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam); LRESULT PrintSetupDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam); +LRESULT FormatCharDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam); #endif /* #ifdef COMMDLG_H */
diff --git a/include/dlls.h b/include/dlls.h index 304b142..70d34cc 100644 --- a/include/dlls.h +++ b/include/dlls.h
@@ -57,6 +57,7 @@ DECLARE_DLL(WINPROCS) DECLARE_DLL(DDEML) DECLARE_DLL(LZEXPAND) +DECLARE_DLL(W32SYS) /* 32-bit DLLs */
diff --git a/include/local.h b/include/local.h index d3f12f7..bfc6f12 100644 --- a/include/local.h +++ b/include/local.h
@@ -20,6 +20,7 @@ extern WORD LOCAL_Size( HANDLE ds, HLOCAL handle ); extern WORD LOCAL_Flags( HANDLE ds, HLOCAL handle ); extern WORD LOCAL_HeapSize( HANDLE ds ); +extern WORD LOCAL_CountFree( WORD ds ); extern LPSTR LOCAL_Lock( HANDLE ds, HLOCAL handle ); extern BOOL LOCAL_Unlock( HANDLE ds, HLOCAL handle );
diff --git a/include/mdi.h b/include/mdi.h index a34c1d0..99d7974 100644 --- a/include/mdi.h +++ b/include/mdi.h
@@ -37,7 +37,7 @@ HMENU hWindowMenu; WORD idFirstChild; /* order is 3.1-like up to this point */ HANDLE hFrameTitle; - WORD sbStop; + WORD sbNeedUpdate; WORD sbRecalc; HBITMAP obmClose; HBITMAP obmRestore;
diff --git a/include/metafile.h b/include/metafile.h index 2c56e34..c83afcb 100644 --- a/include/metafile.h +++ b/include/metafile.h
@@ -13,19 +13,7 @@ #define MFVERSION 0x300 #define META_EOF 0x0000 -typedef struct tagMETAFILE -{ - WORD wMagic; /* `PO' */ - char Filename[80]; /* metafile name, if disk based */ - int hFile; /* MSDOS file handle for metafile */ - HANDLE hMetaHdr; /* handle of metafile header */ - int MetaOffset; /* offset of current record in metafile */ - HANDLE hBuffer; /* handle of buffer for disk based metafiles */ -} METAFILE; -typedef METAFILE *LPMETAFILE; - - -BOOL MF_WriteRecord(HMETAFILE hmf, METARECORD *mr, WORD rlen); +HMETAFILE MF_WriteRecord(HMETAFILE hmf, METARECORD *mr, WORD rlen); int MF_AddHandle(HANDLETABLE *ht, WORD htlen, HANDLE hobj); int MF_AddHandleInternal(HANDLE hobj); BOOL MF_MetaParam0(DC *dc, short func);
diff --git a/include/options.h b/include/options.h index c1b6f0e..9f6a1db 100644 --- a/include/options.h +++ b/include/options.h
@@ -22,6 +22,8 @@ LANG_It /* Italian */ } WINE_LANGUAGE; +extern const char *langNames[]; + /* Supported modes */ typedef enum {
diff --git a/include/w32sys.h b/include/w32sys.h new file mode 100644 index 0000000..6388b6c --- /dev/null +++ b/include/w32sys.h
@@ -0,0 +1,17 @@ +/* + * W32SYS + * + * Copyright (c) 1996 Anand Kumria + */ + +#ifndef __WINE__W32SYS_H +#define __WINE__W32SYS_H + +typedef struct _WIN32SINFO { + BYTE bMajor; + BYTE bMinor; + WORD wBuildNumber; + BOOL fDebug; +} WIN32SINFO, *LPWIN32SINFO; + +#endif /* __WINE_W32SYS_H */
diff --git a/include/windows.h b/include/windows.h index c25d916..5ad16fb 100644 --- a/include/windows.h +++ b/include/windows.h
@@ -2322,6 +2322,8 @@ #define LMEM_ZEROINIT 0x0040 #define LMEM_MODIFY 0x0080 #define LMEM_DISCARDABLE 0x0F00 +#define LMEM_DISCARDED 0x4000 +#define LMEM_LOCKCOUNT 0x00FF #define GMEM_FIXED 0x0000 #define GMEM_MOVEABLE 0x0002
diff --git a/include/winpos.h b/include/winpos.h index 455cce8..4ec7319 100644 --- a/include/winpos.h +++ b/include/winpos.h
@@ -11,6 +11,10 @@ #define DWP_MAGIC 0x5057 /* 'WP' */ +/* undocumented SWP flags - from SDK 3.1 */ +#define SWP_NOCLIENTSIZE 0x0800 +#define SWP_NOCLIENTMOVE 0x1000 + typedef struct { WORD actualCount;
diff --git a/include/winreg.h b/include/winreg.h index 01c60a0..d8e23b0 100644 --- a/include/winreg.h +++ b/include/winreg.h
@@ -89,6 +89,7 @@ LPWSTR name; /* name of value (UNICODE) or NULL for win31 */ DWORD type; /* type of value */ DWORD len; /* length of data */ + DWORD lastmodified; /* time of seconds since 1.1.1970 */ LPBYTE data; /* content, may be strings, binaries, etc. */ } KEYVALUE,*LPKEYVALUE;
diff --git a/memory/local.c b/memory/local.c index 96fa999..b4aba40 100644 --- a/memory/local.c +++ b/memory/local.c
@@ -47,6 +47,12 @@ #define LOCAL_ARENA_FIXED 1 #define LOCAL_ARENA_MOVEABLE 3 +/* Layout of a handle entry table + * + * WORD count of entries + * LOCALHANDLEENTRY[count] entries + * WORD near ptr to next table + */ typedef struct { WORD addr; /* Address of the MOVEABLE block */ @@ -56,26 +62,26 @@ typedef struct { - WORD check; /* Heap checking flag */ - WORD freeze; /* Heap frozen flag */ - WORD items; /* Count of items on the heap */ - WORD first; /* First item of the heap */ - WORD pad1; /* Always 0 */ - WORD last; /* Last item of the heap */ - WORD pad2; /* Always 0 */ - BYTE ncompact; /* Compactions counter */ - BYTE dislevel; /* Discard level */ - DWORD distotal; /* Total bytes discarded */ - WORD htable; /* Pointer to handle table */ - WORD hfree; /* Pointer to free handle table */ - WORD hdelta; /* Delta to expand the handle table */ - WORD expand; /* Pointer to expand function (unused) */ - WORD pstat; /* Pointer to status structure (unused) */ - DWORD notify WINE_PACKED; /* Pointer to LocalNotify() function */ - WORD lock; /* Lock count for the heap */ - WORD extra; /* Extra bytes to allocate when expanding */ - WORD minsize; /* Minimum size of the heap */ - WORD magic; /* Magic number */ + WORD check; /* 00 Heap checking flag */ + WORD freeze; /* 02 Heap frozen flag */ + WORD items; /* 04 Count of items on the heap */ + WORD first; /* 06 First item of the heap */ + WORD pad1; /* 08 Always 0 */ + WORD last; /* 0a Last item of the heap */ + WORD pad2; /* 0c Always 0 */ + BYTE ncompact; /* 0e Compactions counter */ + BYTE dislevel; /* 0f Discard level */ + DWORD distotal; /* 10 Total bytes discarded */ + WORD htable; /* 14 Pointer to handle table */ + WORD hfree; /* 16 Pointer to free handle table */ + WORD hdelta; /* 18 Delta to expand the handle table */ + WORD expand; /* 1a Pointer to expand function (unused) */ + WORD pstat; /* 1c Pointer to status structure (unused) */ + FARPROC notify WINE_PACKED; /* 1e Pointer to LocalNotify() function */ + WORD lock; /* 22 Lock count for the heap */ + WORD extra; /* 24 Extra bytes to allocate when expanding */ + WORD minsize; /* 26 Minimum size of the heap */ + WORD magic; /* 28 Magic number */ } LOCALHEAPINFO; #ifndef WINELIB @@ -455,8 +461,9 @@ WORD arena; WORD freespace = 0; - if (!(pInfo = LOCAL_GetHeap( ds ))) { - dprintf_local( stddeb, "Local_FindFreeBlock: Local heap not found\n" ); + if (!(pInfo = LOCAL_GetHeap( ds ))) + { + fprintf( stderr, "Local_FindFreeBlock: Local heap not found\n" ); LOCAL_PrintHeap(ds); return 0; } @@ -468,6 +475,11 @@ pArena = ARENA_PTR( ptr, arena ); if (pArena->size >= freespace) freespace = pArena->size; } + + if(freespace < ARENA_HEADER_SIZE) + freespace = 0; + else + freespace -= ARENA_HEADER_SIZE; if (flags & LMEM_NOCOMPACT) return freespace; @@ -485,8 +497,9 @@ LOCALARENA *pArena; WORD arena; - if (!(pInfo = LOCAL_GetHeap( ds ))) { - dprintf_local( stddeb, "Local_FindFreeBlock: Local heap not found\n" ); + if (!(pInfo = LOCAL_GetHeap( ds ))) + { + fprintf( stderr, "Local_FindFreeBlock: Local heap not found\n" ); LOCAL_PrintHeap(ds); return 0; } @@ -516,8 +529,9 @@ LOCALARENA *pArena; WORD arena; - if (!(pInfo = LOCAL_GetHeap( ds ))) { - dprintf_local( stddeb, "Local_GetBlock: Local heap not found\n"); + if (!(pInfo = LOCAL_GetHeap( ds ))) + { + fprintf( stderr, "Local_GetBlock: Local heap not found\n"); LOCAL_PrintHeap(ds); return 0; } @@ -540,7 +554,8 @@ arena = LOCAL_FindFreeBlock( ds, size ); } if (arena == 0) { - fprintf( stderr, "Local_GetBlock: not enough space!\n" ); + fprintf( stderr, "Local_GetBlock: not enough space in heap %04x for %d bytes\n", + ds, size ); return 0; } @@ -564,6 +579,7 @@ return arena + ARENA_HEADER_SIZE; } + /*********************************************************************** * LOCAL_NewHTable */ @@ -571,56 +587,82 @@ { char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 ); LOCALHEAPINFO *pInfo; + LOCALHANDLEENTRY *pEntry; HLOCAL handle; + int i; dprintf_local( stddeb, "Local_NewHTable\n" ); - if (!(pInfo = LOCAL_GetHeap( ds ))) { - dprintf_local( stddeb, "Local heap not found\n"); - LOCAL_PrintHeap(ds); - return FALSE; + if (!(pInfo = LOCAL_GetHeap( ds ))) + { + fprintf( stderr, "Local heap not found\n"); + LOCAL_PrintHeap(ds); + return FALSE; } - handle = LOCAL_GetBlock( ds, pInfo->hdelta*4 + 2, LMEM_FIXED ); + handle = LOCAL_GetBlock( ds, pInfo->hdelta * sizeof(LOCALHANDLEENTRY) + + 2 * sizeof(WORD), LMEM_FIXED ); ptr = PTR_SEG_OFF_TO_LIN( ds, 0 ); pInfo = LOCAL_GetHeap( ds ); if (handle == 0) return FALSE; - *(WORD *)(ptr + handle) = 0; /* no handles in this block yet */ + + /* Fill the entry table */ + + *(WORD *)(ptr + handle) = pInfo->hdelta; + pEntry = (LOCALHANDLEENTRY *)(ptr + handle + sizeof(WORD)); + for (i = pInfo->hdelta; i > 0; i--) (pEntry++)->lock = 0xff; + *(WORD *)pEntry = pInfo->htable; pInfo->htable = handle; return TRUE; } + /*********************************************************************** - * LOCAL_GetNewHandle + * LOCAL_GetNewHandleEntry */ -static HLOCAL LOCAL_GetNewHandle( WORD ds ) +static HLOCAL LOCAL_GetNewHandleEntry( WORD ds ) { char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 ); LOCALHEAPINFO *pInfo; - WORD count; - - if (!(pInfo = LOCAL_GetHeap( ds ))) { - dprintf_local( stddeb, "LOCAL_GetNewHandle: Local heap not found\n"); + LOCALHANDLEENTRY *pEntry = NULL; + WORD table; + + if (!(pInfo = LOCAL_GetHeap( ds ))) + { + fprintf( stderr, "LOCAL_GetNewHandleEntry: Local heap not found\n"); LOCAL_PrintHeap(ds); return 0; } - /* Check if we need a new handle table */ - if (pInfo->htable == 0) { - if (!LOCAL_NewHTable( ds )) return 0; - ptr = PTR_SEG_OFF_TO_LIN( ds, 0 ); - pInfo = LOCAL_GetHeap( ds ); - } - if (*(WORD *)(ptr + pInfo->htable) == pInfo->hdelta) { - if (!LOCAL_NewHTable( ds )) return 0; - ptr = PTR_SEG_OFF_TO_LIN( ds, 0 ); - pInfo = LOCAL_GetHeap( ds ); + + /* Find a free slot in existing tables */ + + table = pInfo->htable; + while (table) + { + WORD count = *(WORD *)(ptr + table); + pEntry = (LOCALHANDLEENTRY *)(ptr + table + sizeof(WORD)); + for (; count > 0; count--, pEntry++) + if (pEntry->lock == 0xff) break; + if (count) break; + table = *(WORD *)pEntry; } - /* increase count */ - count = (*(WORD *)(ptr + pInfo->htable))++; - dprintf_local( stddeb, "Local_GetNewHandle: %04x\n", pInfo->htable + 2 + 4*count ); - return pInfo->htable + 2 + 4*count; + if (!table) /* We need to create a new table */ + { + if (!LOCAL_NewHTable( ds )) return 0; + ptr = PTR_SEG_OFF_TO_LIN( ds, 0 ); + pInfo = LOCAL_GetHeap( ds ); + pEntry = (LOCALHANDLEENTRY *)(ptr + pInfo->htable + sizeof(WORD)); + } + + /* Now allocate this entry */ + + pEntry->lock = 0; + dprintf_local( stddeb, "LOCAL_GetNewHandleEntry(%04x): %04x\n", + ds, ((char *)pEntry - ptr) ); + return (HLOCAL)((char *)pEntry - ptr); } + /*********************************************************************** * LOCAL_FreeArena */ @@ -634,9 +676,11 @@ if (!(pInfo = LOCAL_GetHeap( ds ))) return arena; pArena = ARENA_PTR( ptr, arena ); - if ((pArena->prev & 3) == LOCAL_ARENA_FREE) { + if ((pArena->prev & 3) == LOCAL_ARENA_FREE) + { /* shouldn't happen */ - fprintf( stderr, "LocalFreeArena: Trying to free a block twice!\n" ); + fprintf( stderr, "LocalFreeArena: Trying to free block %04x twice!\n", + arena ); LOCAL_PrintHeap( ds ); return arena; } @@ -670,6 +714,59 @@ /*********************************************************************** + * LOCAL_FreeHandleEntry + * + * Free a handle table entry. + */ +static void LOCAL_FreeHandleEntry( WORD ds, HLOCAL handle ) +{ + char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 ); + LOCALHANDLEENTRY *pEntry = (LOCALHANDLEENTRY *)(ptr + handle); + LOCALHEAPINFO *pInfo; + WORD *pTable; + WORD table, count, i; + + if (!(pInfo = LOCAL_GetHeap( ds ))) return; + + /* Find the table where this handle comes from */ + + pTable = &pInfo->htable; + while (*pTable) + { + WORD size = (*(WORD *)(ptr + *pTable)) * sizeof(LOCALHANDLEENTRY); + if ((handle >= *pTable + sizeof(WORD)) && + (handle < *pTable + sizeof(WORD) + size)) break; /* Found it */ + pTable = (WORD *)(ptr + *pTable + sizeof(WORD) + size); + } + if (!*pTable) + { + fprintf(stderr, "LOCAL_FreeHandleEntry: invalid entry %04x\n", handle); + LOCAL_PrintHeap( ds ); + return; + } + + /* Make the entry free */ + + pEntry->addr = 0; /* just in case */ + pEntry->lock = 0xff; + + /* Now check if all entries in this table are free */ + + pEntry = (LOCALHANDLEENTRY *)(ptr + *pTable + sizeof(WORD)); + count = *(WORD *)(ptr + *pTable); + for (i = count; i > 0; i--, pEntry++) if (pEntry->lock != 0xff) return; + + /* Remove the table from the linked list and free it */ + + table = *pTable; + dprintf_local( stddeb, "LOCAL_FreeHandleEntry(%04x): freeing table %04x\n", + ds, table); + *pTable = *((WORD *)(ptr + count * sizeof(*pEntry)) + 1); + LOCAL_FreeArena( ds, ARENA_HEADER( table ) ); +} + + +/*********************************************************************** * LOCAL_Free * * Implementation of LocalFree(). @@ -677,20 +774,23 @@ HLOCAL LOCAL_Free( HANDLE ds, HLOCAL handle ) { char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 ); - WORD arena; dprintf_local( stddeb, "LocalFree: %04x ds=%04x\n", handle, ds ); if (!handle) { fprintf( stderr, "LOCAL_Free: handle is 0.\n" ); return 0; } - if (HANDLE_FIXED( handle )) { - arena = ARENA_HEADER( handle ); - } else { - arena = ARENA_HEADER( *(WORD *)(ptr + handle) ); - dprintf_local( stddeb, "LocalFree: real block at %04x\n", arena); + if (HANDLE_FIXED( handle )) + { + if (!LOCAL_FreeArena( ds, ARENA_HEADER( handle ) )) return 0; /* OK */ + else return handle; /* couldn't free it */ } - arena = LOCAL_FreeArena( ds, arena ); - if (arena != 0) return handle; /* couldn't free it */ - return 0; + else + { + WORD arena = ARENA_HEADER( *(WORD *)(ptr + handle) ); + dprintf_local( stddeb, "LocalFree: real block at %04x\n", arena ); + if (LOCAL_FreeArena( ds, arena )) return handle; /* couldn't free it */ + LOCAL_FreeHandleEntry( ds, handle ); + return 0; /* OK */ + } } @@ -706,26 +806,26 @@ dprintf_local( stddeb, "LocalAlloc: %04x %d ds=%04x\n", flags, size, ds ); - if (flags & LMEM_MOVEABLE) { + if (flags & LMEM_MOVEABLE) + { LOCALHANDLEENTRY *plhe; HLOCAL hmem; - hmem = LOCAL_GetBlock( ds, size + 2, flags ); - if (hmem == 0) return 0; - handle = LOCAL_GetNewHandle( ds ); - if (handle == 0) { + if (!(hmem = LOCAL_GetBlock( ds, size, flags ))) return 0; + if (!(handle = LOCAL_GetNewHandleEntry( ds ))) + { fprintf( stderr, "LocalAlloc: couldn't get handle\n"); LOCAL_FreeArena( ds, ARENA_HEADER(hmem) ); return 0; } ptr = PTR_SEG_OFF_TO_LIN( ds, 0 ); - *(WORD *)(ptr + hmem) = handle; plhe = (LOCALHANDLEENTRY *)(ptr + handle); - plhe->addr = hmem + 2; + plhe->addr = hmem; + plhe->flags = (BYTE)(flags >> 8); plhe->lock = 0; - } else { - handle = LOCAL_GetBlock( ds, size, flags ); } + else handle = LOCAL_GetBlock( ds, size, flags ); + return handle; } @@ -749,14 +849,9 @@ handle, size, flags, ds ); if (!(pInfo = LOCAL_GetHeap( ds ))) return 0; - if (HANDLE_FIXED( handle )) { - blockhandle = handle; - } else { - size += 2; - blockhandle = *(WORD *)(ptr + handle); - dprintf_local( stddeb, " blockhandle %04x (%04x)\n", blockhandle, - *(WORD *)(ptr + blockhandle - 2)); - } + if (HANDLE_FIXED( handle )) blockhandle = handle; + else blockhandle = *(WORD *)(ptr + handle); + arena = ARENA_HEADER( blockhandle ); dprintf_local( stddeb, "LocalReAlloc: arena is %04x\n", arena ); pArena = ARENA_PTR( ptr, arena ); @@ -811,8 +906,8 @@ ptr = PTR_SEG_OFF_TO_LIN( ds, 0 ); memcpy( ptr + newhandle, ptr + (arena + ARENA_HEADER_SIZE), size ); LOCAL_FreeArena( ds, arena ); - if (HANDLE_MOVEABLE( handle )) { - newhandle += 2; + if (HANDLE_MOVEABLE( handle )) + { dprintf_local( stddeb, "LocalReAlloc: fixing handle\n"); *(WORD *)(ptr + handle) = newhandle; newhandle = handle; @@ -831,7 +926,7 @@ if (HANDLE_MOVEABLE(handle)) { LOCALHANDLEENTRY *pEntry = (LOCALHANDLEENTRY *)(heap + handle); - if (pEntry->lock < 255) pEntry->lock++; + if (pEntry->lock < 0xfe) pEntry->lock++; handle = pEntry->addr; } dprintf_local( stddeb, "returning %04x\n", handle ); @@ -860,7 +955,7 @@ if (HANDLE_MOVEABLE(handle)) { LOCALHANDLEENTRY *pEntry = (LOCALHANDLEENTRY *)(ptr + handle); - if (!pEntry->lock || (pEntry->lock == 255)) return FALSE; + if (!pEntry->lock || (pEntry->lock == 0xff)) return FALSE; /* For moveable block, return the new lock count */ /* (see _Windows_Internals_ p. 197) */ return --pEntry->lock; @@ -878,21 +973,41 @@ { char *ptr = PTR_SEG_OFF_TO_LIN( CURRENT_DS, 0 ); LOCALARENA *pArena; - WORD arena; dprintf_local( stddeb, "LocalSize: %04x ds=%04x\n", handle, ds ); - - if (HANDLE_FIXED( handle )) { - arena = ARENA_HEADER( handle ); - } else { - arena = ARENA_HEADER( handle = *(WORD *)(ptr + handle) ); - } - pArena = ARENA_PTR( ptr, arena ); + + if (HANDLE_MOVEABLE( handle )) handle = *(WORD *)(ptr + handle); + pArena = ARENA_PTR( ptr, ARENA_HEADER(handle) ); return pArena->next - handle; } /*********************************************************************** + * LOCAL_Flags + * + * Implementation of LocalFlags(). + */ +WORD LOCAL_Flags( WORD ds, HLOCAL handle ) +{ + char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 ); + + if (HANDLE_MOVEABLE(handle)) + { + LOCALHANDLEENTRY *pEntry = (LOCALHANDLEENTRY *)(ptr + handle); + dprintf_local( stddeb, "LOCAL_Flags(%04x,%04x): returning %04x\n", + ds, handle, pEntry->lock | (pEntry->flags << 8) ); + return pEntry->lock | (pEntry->flags << 8); + } + else + { + dprintf_local( stddeb, "LOCAL_Flags(%04x,%04x): returning 0\n", + ds, handle ); + return 0; + } +} + + +/*********************************************************************** * LOCAL_HeapSize * * Implementation of LocalHeapSize(). @@ -906,6 +1021,67 @@ /*********************************************************************** + * LOCAL_CountFree + * + * Implementation of LocalCountFree(). + */ +WORD LOCAL_CountFree( WORD ds ) +{ + WORD arena, total; + LOCALARENA *pArena; + char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 ); + LOCALHEAPINFO *pInfo = LOCAL_GetHeap( ds ); + + total = 0; + arena = pInfo->first; + pArena = ARENA_PTR( ptr, arena ); + for (;;) + { + arena = pArena->free_next; + pArena = ARENA_PTR( ptr, arena ); + if (arena == pArena->free_next) break; + total += pArena->size; + } + dprintf_local( stddeb, "LOCAL_CountFree(%04x): returning %d\n", ds, total); + return total; +} + + +/*********************************************************************** + * LOCAL_Handle + * + * Implementation of LocalHandle(). + */ +HLOCAL LOCAL_Handle( WORD ds, WORD addr ) +{ + char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 ); + LOCALHEAPINFO *pInfo; + WORD table; + + if (!(pInfo = LOCAL_GetHeap( ds ))) + { + fprintf( stderr, "LOCAL_Handle(%04x): Local heap not found\n", ds ); + LOCAL_PrintHeap( ds ); + return 0; + } + + /* Find the address in the entry tables */ + + table = pInfo->htable; + while (table) + { + WORD count = *(WORD *)(ptr + table); + LOCALHANDLEENTRY *pEntry = (LOCALHANDLEENTRY*)(ptr+table+sizeof(WORD)); + for (; count > 0; count--, pEntry++) + if (pEntry->addr == addr) return (HLOCAL)((char *)pEntry - ptr); + table = *(WORD *)pEntry; + } + + return (HLOCAL)addr; /* Fixed block handle is addr */ +} + + +/*********************************************************************** * LocalAlloc (KERNEL.5) */ HLOCAL LocalAlloc( WORD flags, WORD size ) @@ -964,14 +1140,8 @@ * LocalHandle (KERNEL.11) */ HLOCAL LocalHandle( WORD addr ) -{ - char *ptr = PTR_SEG_OFF_TO_LIN( CURRENT_DS, 0 ); - - dprintf_local( stddeb, "LocalHandle: %04x\n", addr ); - if (HANDLE_MOVEABLE( addr )) { - addr = *(WORD *)(ptr + addr - 2); - } - return addr; +{ + return LOCAL_Handle( CURRENT_DS, addr ); } @@ -980,8 +1150,7 @@ */ WORD LocalFlags( HLOCAL handle ) { - dprintf_local( stddeb, "LocalFlags: %04x\n", handle ); - return 0; + return LOCAL_Flags( CURRENT_DS, handle ); } @@ -1000,8 +1169,20 @@ */ FARPROC LocalNotify( FARPROC func ) { - dprintf_local( stddeb, "LocalNotify: %08lx\n", func ); - return 0; + LOCALHEAPINFO *pInfo; + FARPROC oldNotify; + WORD ds = CURRENT_DS; + + if (!(pInfo = LOCAL_GetHeap( ds ))) + { + fprintf( stderr, "LOCAL_Notify(%04x): Local heap not found\n", ds ); + LOCAL_PrintHeap( ds ); + return 0; + } + dprintf_local( stddeb, "LocalNotify(%04x): %08lx\n", ds, func ); + oldNotify = pInfo->notify; + pInfo->notify = func; + return oldNotify; } @@ -1020,16 +1201,22 @@ */ DWORD GetHeapSpaces( HMODULE module ) { - return MAKELONG( 0x7fff, 0xffff ); + NE_MODULE *pModule; + WORD ds; + + module = GetExePtr( module ); + if (!(pModule = MODULE_GetPtr( module ))) return 0; + ds = (NE_SEG_TABLE( pModule ) + pModule->dgroup - 1)->selector; + return MAKELONG( LOCAL_CountFree( ds ), LOCAL_HeapSize( ds ) ); } /*********************************************************************** * LocalCountFree (KERNEL.161) */ -void LocalCountFree() +WORD LocalCountFree(void) { - dprintf_local( stddeb, "LocalCountFree:\n" ); + return LOCAL_CountFree( CURRENT_DS ); } @@ -1048,8 +1235,17 @@ */ WORD LocalHandleDelta( WORD delta ) { - dprintf_local( stddeb, "LocalHandleDelta: %04x\n", delta ); - return 0; + LOCALHEAPINFO *pInfo; + + if (!(pInfo = LOCAL_GetHeap( CURRENT_DS ))) + { + fprintf( stderr, "LocalHandleDelta: Local heap not found\n"); + LOCAL_PrintHeap( CURRENT_DS ); + return 0; + } + if (delta) pInfo->hdelta = delta; + dprintf_local(stddeb, "LocalHandleDelta: returning %04x\n", pInfo->hdelta); + return pInfo->hdelta; }
diff --git a/misc/Makefile.in b/misc/Makefile.in index 1266b05..5e7701f 100644 --- a/misc/Makefile.in +++ b/misc/Makefile.in
@@ -28,6 +28,7 @@ stress.c \ toolhelp.c \ user.c \ + w32sys.c \ winsocket.c \ xmalloc.c
diff --git a/misc/comm.c b/misc/comm.c index d0dfef3..d863ec5 100644 --- a/misc/comm.c +++ b/misc/comm.c
@@ -164,7 +164,7 @@ return -1; strcpy(temp,device+5); - ptr = strtok(temp, ","); + ptr = strtok(temp, ", "); if (COM[port].baudrate > 0) lpdcb->BaudRate = COM[port].baudrate; @@ -172,7 +172,7 @@ lpdcb->BaudRate = atoi(ptr); dprintf_comm(stddeb,"BuildCommDCB: baudrate (%d)\n", lpdcb->BaudRate); - ptr = strtok(NULL, ","); + ptr = strtok(NULL, ", "); if (islower(*ptr)) *ptr = toupper(*ptr); @@ -199,11 +199,11 @@ return -1; } - ptr = strtok(NULL, ","); + ptr = strtok(NULL, ", "); dprintf_comm(stddeb, "BuildCommDCB: charsize (%c)\n", *ptr); lpdcb->ByteSize = *ptr - '0'; - ptr = strtok(NULL, ","); + ptr = strtok(NULL, ", "); dprintf_comm(stddeb, "BuildCommDCB: stopbits (%c)\n", *ptr); switch (*ptr) { case '1':
diff --git a/misc/commdlg.c b/misc/commdlg.c index 089019b..a749ba2 100644 --- a/misc/commdlg.c +++ b/misc/commdlg.c
@@ -320,6 +320,8 @@ LPSTR pstr; SetWindowLong(hWnd, DWL_USER, lParam); lpofn = (LPOPENFILENAME)lParam; + if (lpofn->lpstrTitle) + SendMessage( hWnd, WM_SETTEXT, 0, (LPARAM)lpofn->lpstrTitle ); /* read custom filter information */ if (lpofn->lpstrCustomFilter) { @@ -1120,10 +1122,12 @@ LPCHOOSECOLOR lpcc; /* points to public known data structure */ int nextuserdef; /* next free place in user defined color array */ HDC hdcMem; /* color graph used for BitBlt() */ + HBITMAP hbmMem; /* color graph bitmap */ RECT fullsize; /* original dialog window size */ UINT msetrgb; /* # of SETRGBSTRING message (today not used) */ RECT old3angle; /* last position of l-marker */ RECT oldcross; /* last position of color/satuation marker */ + BOOL updating; /* to prevent recursive WM_COMMAND/EN_UPDATE procesing */ int h; int s; int l; /* for temporary storing of hue,sat,lum */ @@ -1501,7 +1505,6 @@ static void CC_PaintCross(HWND hDlg,int x,int y) { HDC hDC; - long temp; int w=GetDialogBaseUnits(); HWND hwnd=GetDlgItem(hDlg,0x2c6); struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong(hDlg, DWL_USER); @@ -1512,56 +1515,34 @@ if (IsWindowVisible(GetDlgItem(hDlg,0x2c6))) /* if full size */ { GetClientRect(hwnd,&rect); - hDC=GetDC(hwnd); + SelectClipRgn(hDC,CreateRectRgnIndirect(&rect)); hPen=CreatePen(PS_SOLID,2,0); hPen=SelectObject(hDC,hPen); - - temp=(long)rect.right*(long)x; - point.x=temp/(long)MAXHORI; - temp=(long)rect.bottom*(long)y; - point.y=rect.bottom-temp/(long)MAXVERT; - + point.x=((long)rect.right*(long)x)/(long)MAXHORI; + point.y=rect.bottom-((long)rect.bottom*(long)y)/(long)MAXVERT; if (lpp->oldcross.left!=lpp->oldcross.right) BitBlt(hDC,lpp->oldcross.left,lpp->oldcross.top, lpp->oldcross.right-lpp->oldcross.left, lpp->oldcross.bottom-lpp->oldcross.top, lpp->hdcMem,lpp->oldcross.left,lpp->oldcross.top,SRCCOPY); - lpp->oldcross.left =point.x-w-1; lpp->oldcross.right =point.x+w+1; lpp->oldcross.top =point.y-w-1; - lpp->oldcross.bottom=point.y+w+1; + lpp->oldcross.bottom=point.y+w+1; - if (point.y+w/2<rect.bottom-3) /* perhaps better via SelectClipRgn() */ - { - MoveTo(hDC,point.x,MIN(point.y+w/2,rect.bottom)); - LineTo(hDC,point.x,MIN(point.y+w,rect.bottom-2)); - } - if (point.y-w/2>3) - { - MoveTo(hDC,point.x,point.y-w/2); - LineTo(hDC,point.x,MAX(2,point.y-w )); - } - if (point.x+w/2<rect.right-3) - { - MoveTo(hDC,point.x+w/2,point.y); - LineTo(hDC,MIN(rect.right,point.x+w), point.y); - } - if ((point.x-w/2)>3) - { - MoveTo(hDC,point.x-w/2,point.y); - LineTo(hDC,MAX(2,point.x-w), point.y); - } - + MoveTo(hDC,point.x-w,point.y); + LineTo(hDC,point.x+w,point.y); + MoveTo(hDC,point.x,point.y-w); + LineTo(hDC,point.x,point.y+w); DeleteObject(SelectObject(hDC,hPen)); ReleaseDC(hwnd,hDC); } } -#define XSTEPS 36 -#define YSTEPS 48 +#define XSTEPS 48 +#define YSTEPS 24 /*********************************************************************** @@ -1575,14 +1556,13 @@ HBRUSH hbrush; HDC hdc ; RECT rect,client; - HBITMAP hbmMem; HCURSOR hcursor=SetCursor(LoadCursor(0,IDC_WAIT)); GetClientRect(hwnd,&client); hdc=GetDC(hwnd); lpp->hdcMem = CreateCompatibleDC(hdc); - hbmMem = CreateCompatibleBitmap(hdc,client.right,client.bottom); - SelectObject(lpp->hdcMem,hbmMem); + lpp->hbmMem = CreateCompatibleBitmap(hdc,client.right,client.bottom); + SelectObject(lpp->hdcMem,lpp->hbmMem); xdif=client.right /XSTEPS; ydif=client.bottom/YSTEPS+1; @@ -1607,7 +1587,6 @@ } ReleaseDC(hwnd,hdc); SetCursor(hcursor); - /* FIXME perhaps we should do it only ONCE for all, like hCDRom,.... ? */ } /*********************************************************************** @@ -1675,17 +1654,20 @@ static void CC_EditSetRGB(HWND hDlg,COLORREF cr) { char buffer[10]; + struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong(hDlg, DWL_USER); int r=GetRValue(cr); int g=GetGValue(cr); int b=GetBValue(cr); if (IsWindowVisible(GetDlgItem(hDlg,0x2c6))) /* if full size */ { + lpp->updating=TRUE; sprintf(buffer,"%d",r); SetWindowText(GetDlgItem(hDlg,0x2c2),buffer); sprintf(buffer,"%d",g); SetWindowText(GetDlgItem(hDlg,0x2c3),buffer); sprintf(buffer,"%d",b); SetWindowText(GetDlgItem(hDlg,0x2c4),buffer); + lpp->updating=FALSE; } } @@ -1695,14 +1677,18 @@ static void CC_EditSetHSL(HWND hDlg,int h,int s,int l) { char buffer[10]; + struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong(hDlg, DWL_USER); + lpp->updating=TRUE; if (IsWindowVisible(GetDlgItem(hDlg,0x2c6))) /* if full size */ { + lpp->updating=TRUE; sprintf(buffer,"%d",h); SetWindowText(GetDlgItem(hDlg,0x2bf),buffer); sprintf(buffer,"%d",s); SetWindowText(GetDlgItem(hDlg,0x2c0),buffer); sprintf(buffer,"%d",l); SetWindowText(GetDlgItem(hDlg,0x2c1),buffer); + lpp->updating=FALSE; } CC_PaintLumBar(hDlg,h,s); } @@ -1911,12 +1897,13 @@ HDC hdc; COLORREF *cr; struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong(hDlg, DWL_USER); + dprintf_commdlg(stddeb,"CC_WMCommand wParam=%x lParam=%lx\n",wParam,lParam); switch (wParam) { case 0x2c2: /* edit notify RGB */ case 0x2c3: case 0x2c4: - if (HIWORD(lParam)==EN_UPDATE) + if (HIWORD(lParam)==EN_UPDATE && !lpp->updating) { i=CC_CheckDigitsInEdit(LOWORD(lParam),255); r=GetRValue(lpp->lpcc->rgbResult); @@ -1946,7 +1933,7 @@ case 0x2bf: /* edit notify HSL */ case 0x2c0: case 0x2c1: - if (HIWORD(lParam)==EN_UPDATE) + if (HIWORD(lParam)==EN_UPDATE && !lpp->updating) { i=CC_CheckDigitsInEdit(LOWORD(lParam),wParam==0x2bf?239:240); xx=0; @@ -2131,7 +2118,8 @@ case WM_INITDIALOG: return CC_WMInitDialog(hDlg,wParam,lParam); case WM_NCDESTROY: - /* FIXME: what about lpp->hdcMem ? */ + DeleteDC(lpp->hdcMem); + DeleteObject(lpp->hbmMem); free(lpp); SetWindowLong(hDlg, DWL_USER, 0L); /* we don't need it anymore */ break; @@ -2158,3 +2146,84 @@ return FALSE ; } + + +/*********************************************************************** + * ChooseFont (COMMDLG.15) + --April 1996-- + please note: ChooseFont etc. are still under construction + */ +BOOL ChooseFont(LPCHOOSEFONT lpChFont) +{ + HANDLE hInst, hDlgTmpl; + BOOL bRet; + dprintf_commdlg(stddeb,"ChoseFont\n"); + hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_CHOOSE_FONT ); + hInst = WIN_GetWindowInstance( lpChFont->hwndOwner ); + bRet = DialogBoxIndirectParam( hInst, hDlgTmpl, lpChFont->hwndOwner, + MODULE_GetWndProcEntry16("FormatCharDlgProc"), + (DWORD)lpChFont ); + SYSRES_FreeResource( hDlgTmpl ); + return bRet; +} + +/*********************************************************************** + * FontStyleEnumProc (COMMDLG.18) + */ +int FontStyleEnumProc(LOGFONT *lf ,TEXTMETRIC *tm, int fonttype, LPARAM lParam) +{ + dprintf_commdlg(stddeb,"FontStyleEnumProc: font=%s (height=%d)\n",lf->lfFaceName,lf->lfHeight); + return 1; +} + +/*********************************************************************** + * FontFamilyEnumProc (COMMDLG.19) + */ +int FontFamilyEnumProc(LOGFONT *lf ,TEXTMETRIC *tm, int fonttype, LPARAM lParam) +{ + dprintf_commdlg(stddeb,"FontFamilyEnumProc: font=%s\n",lf->lfFaceName); + return 1; +} + +/*********************************************************************** + * ColorDlgProc (COMMDLG.16) + */ +LRESULT FormatCharDlgProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam) +{ + HDC hdc; + FARPROC enumCallback; + + switch (wMsg) + { + case WM_INITDIALOG: + dprintf_commdlg(stddeb,"FormatCharDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam); + ShowWindow(hDlg, SW_SHOWNORMAL); + hdc = GetDC(hDlg); + if (hdc) + { + HCURSOR hcursor=SetCursor(LoadCursor(0,IDC_WAIT)); + /* + currently only called for testing of 2 necessary EnumProcs + */ + enumCallback = MODULE_GetWndProcEntry16("FontFamilyEnumProc"); + EnumFontFamilies (hdc, NULL,enumCallback ,NULL); + enumCallback = MODULE_GetWndProcEntry16("FontStyleEnumProc"); + EnumFontFamilies(hdc, /* for example : */ "COURIER",enumCallback,NULL); + ReleaseDC(hDlg,hdc); + SetCursor(hcursor); + } + return (TRUE); + case WM_COMMAND: + switch (wParam) + { + case IDOK: + EndDialog(hDlg, TRUE); + return(TRUE); + case IDCANCEL: + EndDialog(hDlg, FALSE); + return(TRUE); + } + return(FALSE); + } + return FALSE; +}
diff --git a/misc/main.c b/misc/main.c index e7bfdda..3dcd171 100644 --- a/misc/main.c +++ b/misc/main.c
@@ -32,21 +32,28 @@ #include "xmalloc.h" const char people[] = "Wine is available thanks to the work of " -"Bob Amstadt, Dag Asheim, Martin Ayotte, Ross Biro, Erik Bos, " -"Fons Botman, John Brezak, Andrew Bulhak, John Burton, Paul Falstad, " +"Bob Amstadt, Dag Asheim, Martin Ayotte, Ross Biro, Uwe Bonnes, Erik Bos, " +"Fons Botman, John Brezak, Andrew Bulhak, John Burton, " +"Niels de Carpentier, Roman Dolejsi, Frans van Dorsselaer, Paul Falstad, " "Olaf Flebbe, Peter Galbavy, Ramon Garcia, Hans de Graaff, " -"Charles M. Hannum, Cameron Heide, Jochen Hoenicke, Jeffrey Hsu, " -"Miguel de Icaza, Alexandre Julliard, Jon Konrath, Scott A. Laird, " +"Charles M. Hannum, John Harvey, Cameron Heide, Jochen Hoenicke, " +"Onno Hovers, Jeffrey Hsu, Miguel de Icaza, Jukka Iivonen, " +"Alexandre Julliard, Jochen Karrer, Andreas Kirschbaum, Albrecht Kleine, " +"Jon Konrath, Alex Korobka, Greg Kreider, Anand Kumria, Scott A. Laird, " "Martin von Loewis, Kenneth MacDonald, Peter MacDonald, William Magro, " -"Marcus Meissner, Graham Menhennitt, David Metcalfe, Michael Patra, " -"John Richardson, Johannes Ruscheinski, Thomas Sandford, " -"Constantine Sapuntzakis, Daniel Schepler, Bernd Schmidt, " -"Yngvi Sigurjonsson, Rick Sladkey, William Smith, Erik Svendsen, " -"Goran Thyni, Jimmy Tirtawangsa, Jon Tombs, Linus Torvalds, " -"Gregory Trubetskoy, Michael Veksler, Morten Welinder, Jan Willamowius, " -"Carl Williams, Karl Guenter Wuensch, Eric Youngdale, and James Youngman."; +"Juergen Marquardt, Marcus Meissner, Graham Menhennitt, David Metcalfe, " +"Steffen Moeller, Philippe De Muyter, Itai Nahshon, Michael Patra, " +"Jim Peterson, Robert Pouliot, Keith Reynolds, John Richardson, " +"Johannes Ruscheinski, Thomas Sandford, Constantine Sapuntzakis, " +"Daniel Schepler, Ulrich Schmid, Bernd Schmidt, Yngvi Sigurjonsson, " +"Rick Sladkey, William Smith, Erik Svendsen, Tristan Tarrant, " +"Andrew Taylor, Duncan C Thomson, Goran Thyni, Jimmy Tirtawangsa, " +"Jon Tombs, Linus Torvalds, Gregory Trubetskoy, Michael Veksler, " +"Sven Verdoolaege, Eric Warnke, Manfred Weichel, Morten Welinder, " +"Jan Willamowius, Carl Williams, Karl Guenter Wuensch, Eric Youngdale, " +"and James Youngman. "; -static const char *langNames[] = +const char *langNames[] = { "En", /* LANG_En */ "Es", /* LANG_Es */
diff --git a/misc/registry.c b/misc/registry.c index 6483078..7e72b71 100644 --- a/misc/registry.c +++ b/misc/registry.c
@@ -10,22 +10,32 @@ #include <unistd.h> #include <ctype.h> #include <errno.h> +#include <sys/types.h> +#include <sys/fcntl.h> +#include <sys/stat.h> +#include <pwd.h> +#include <time.h> #include "windows.h" #include "win.h" #include "winerror.h" #include "string32.h" -#include "kernel32.h" /* LPSECURITY_ATTRIBUTES */ #include "stddebug.h" #include "debug.h" #include "xmalloc.h" #include "winreg.h" -#define SAVE_CLASSES_ROOT "/tmp/reg.classes_root" -#define SAVE_CURRENT_USER "/tmp/reg.current_user" -#define SAVE_LOCAL_MACHINE "/tmp/reg.local_machine" -#define SAVE_USERS "/tmp/reg.users" +/* FIXME: following defines should be configured global ... */ -static KEYSTRUCT *key_classes_root=NULL; /* windows global values */ +/* NOTE: do not append a /. linux' mkdir() WILL FAIL if you do that */ +#define WINE_PREFIX "/.wine" +#define SAVE_CURRENT_USER_DEFAULT "/usr/local/etc/wine.userreg" + /* relative in ~user/.wine/ */ +#define SAVE_CURRENT_USER "user.reg" +#define SAVE_LOCAL_MACHINE_DEFAULT "/usr/local/etc/wine.systemreg" + /* relative in ~user/.wine/ */ +#define SAVE_LOCAL_MACHINE "system.reg" + +static KEYSTRUCT *key_classes_root=NULL; /* windows 3.1 global values */ static KEYSTRUCT *key_current_user=NULL; /* user specific values */ static KEYSTRUCT *key_local_machine=NULL;/* machine specific values */ static KEYSTRUCT *key_users=NULL; /* all users? */ @@ -181,21 +191,46 @@ } #define FREE_KEY_PATH free(wps[0]);free(wps); -/** +/* * Shell initialisation, allocates keys. - * FIXME:should set default values too */ void SHELL_Init() { + struct passwd *pwd; + + HKEY cl_r_hkey,c_u_hkey; #define ADD_ROOT_KEY(xx) \ xx = (LPKEYSTRUCT)xmalloc(sizeof(KEYSTRUCT));\ memset(xx,'\0',sizeof(KEYSTRUCT));\ xx->keyname= strdupA2W("<should_not_appear_anywhere>"); - ADD_ROOT_KEY(key_classes_root); - ADD_ROOT_KEY(key_current_user); ADD_ROOT_KEY(key_local_machine); + if (RegCreateKey(HKEY_LOCAL_MACHINE,"\\SOFTWARE\\Classes",&cl_r_hkey)!=ERROR_SUCCESS) { + fprintf(stderr,"couldn't create HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes. This is impossible.\n"); + exit(1); + } + key_classes_root = lookup_hkey(cl_r_hkey); + ADD_ROOT_KEY(key_users); + +#if 0 + /* FIXME: load all users and their resp. pwd->pw_dir/.wine/user.reg + * (later, when a win32 registry editing tool becomes avail.) + */ + while (pwd=getpwent()) { + if (pwd->pw_name == NULL) + continue; + RegCreateKey(HKEY_USERS,pwd->pw_name,&c_u_hkey); + RegCloseKey(c_u_hkey); + } +#endif + pwd=getpwuid(getuid()); + if (pwd && pwd->pw_name) { + RegCreateKey(HKEY_USERS,pwd->pw_name,&c_u_hkey); + key_current_user = lookup_hkey(c_u_hkey); + } else { + ADD_ROOT_KEY(key_current_user); + } ADD_ROOT_KEY(key_performance_data); ADD_ROOT_KEY(key_current_config); ADD_ROOT_KEY(key_dyn_data); @@ -211,96 +246,83 @@ * old registry database files. * * Global: - * DWORD version - * DWORD nrofkeys - * KEY keys[nrofkeys] - * - * KEY: - * USTRING name - * USTRING class - * DWORD nrofvalues - * VALUE vals[nrofvalues] - * DWORD nrofsubkeys - * KEY keys[nrofsubkeys] - * - * Value: - * USTRING name - * DWORD type - * DWORD len - * BYTE data[len] - * - * USTRING: - * DWORD len (len==0 means data=NULL) - * BYTE data[len] + * "WINE REGISTRY Version %d" + * subkeys.... + * Subkeys: + * keyname + * valuename=lastmodified,type,data + * ... + * subkeys + * ... + * keyname,valuename,stringdata: + * the usual ascii characters from 0x00-0xff (well, not 0x00) + * and \uXXXX as UNICODE value XXXX with XXXX>0xff + * ( "=\\\t" escaped in \uXXXX form.) + * type,lastmodified: + * int * - * - * All _write_XXX and _read_XXX functions return !0 on sucess. + * FIXME: doesn't save 'class' (what does it mean anyway?), nor flags. */ +static void +_write_USTRING(FILE *F,LPWSTR wstr,int escapeeq) { + LPWSTR s; + int doescape; -static int -_write_DWORD(FILE *F,DWORD dw) { - return fwrite(&dw,sizeof(dw),1,F); -} - -static int -_write_USTRING(FILE *F,LPWSTR str) { - int len; - - if (str==NULL) { - if (!_write_DWORD(F,0)) - return 0; - } else { - len=strlenW(str)*2+2; - - if (!_write_DWORD(F,len)) - return 0; - if (!fwrite(str,len,1,F)) - return 0; + if (wstr==NULL) { + /* FIXME: NULL equals empty string... I hope + * the empty string isn't a valid valuename + */ + return; } - return 1; + s=wstr; + while (*s) { + doescape=0; + if (*s>0xff) + doescape = 1; + if (*s=='\n') + doescape = 1; + if (escapeeq && *s=='=') + doescape = 1; + if (*s=='\\') + fputc(*s,F); /* if \\ than put it twice. */ + if (doescape) + fprintf(F,"\\u%04x",*((unsigned short*)s)); + else + fputc(*s,F); + s++; + } } - static int -_do_save_subkey(FILE *F,LPKEYSTRUCT lpkey) { +_do_save_subkey(FILE *F,LPKEYSTRUCT lpkey,int level) { LPKEYSTRUCT lpxkey; - int nrofkeys; - int i; - - nrofkeys= 0; - lpxkey = lpkey; - while (lpxkey) { - if (!(lpxkey->flags & REG_OPTION_VOLATILE)) - nrofkeys++; - lpxkey = lpxkey->next; - } - if (!_write_DWORD(F,nrofkeys)) - return 0; + int i,tabs,j; lpxkey = lpkey; while (lpxkey) { if (!(lpxkey->flags & REG_OPTION_VOLATILE)) { - if (!_write_USTRING(F,lpxkey->keyname)) - return 0; - if (!_write_USTRING(F,lpxkey->class)) - return 0; - if (!_write_DWORD(F,lpxkey->nrofvalues)) - return 0; + for (tabs=level;tabs--;) + fputc('\t',F); + _write_USTRING(F,lpxkey->keyname,1); + fputs("\n",F); for (i=0;i<lpxkey->nrofvalues;i++) { LPKEYVALUE val=lpxkey->values+i; - if (!_write_USTRING(F,val->name)) - return 0; - if (!_write_DWORD(F,val->type)) - return 0; - if (!_write_DWORD(F,val->len)) - return 0; - if (!fwrite(val->data,val->len,1,F)) - return 0; + for (tabs=level+1;tabs--;) + fputc('\t',F); + _write_USTRING(F,val->name,0); + fputc('=',F); + fprintf(F,"%ld,%ld,",val->type,val->lastmodified); + if ((1<<val->type) & UNICONVMASK) + _write_USTRING(F,(LPWSTR)val->data,0); + else + for (j=0;j<val->len;j++) + fprintf(F,"%02x",*((unsigned char*)val->data+j)); + fputs("\n",F); } /* descend recursively */ - if (!_do_save_subkey(F,lpxkey->nextsub)) + if (!_do_save_subkey(F,lpxkey->nextsub,level+1)) return 0; } lpxkey=lpxkey->next; @@ -310,16 +332,15 @@ static int _do_savesubreg(FILE *F,LPKEYSTRUCT lpkey) { - if (!_write_DWORD(F,REGISTRY_SAVE_VERSION)) - return 0; - return _do_save_subkey(F,lpkey->nextsub); + fprintf(F,"WINE REGISTRY Version %d\n",REGISTRY_SAVE_VERSION); + return _do_save_subkey(F,lpkey->nextsub,0); } static void _SaveSubReg(LPKEYSTRUCT lpkey,char *fn) { FILE *F; - F=fopen(fn,"wb"); + F=fopen(fn,"w"); if (F==NULL) { fprintf(stddeb,__FILE__":_SaveSubReg:Couldn't open %s for writing: %s\n", fn,strerror(errno) @@ -337,105 +358,307 @@ void SHELL_SaveRegistry() { - _SaveSubReg(key_classes_root,SAVE_CLASSES_ROOT); - _SaveSubReg(key_current_user,SAVE_CURRENT_USER); - _SaveSubReg(key_local_machine,SAVE_LOCAL_MACHINE); - _SaveSubReg(key_users,SAVE_USERS); + char *fn; + struct passwd *pwd; + + pwd=getpwuid(getuid()); + if (pwd!=NULL && pwd->pw_dir!=NULL) { + fn=(char*)xmalloc(strlen(pwd->pw_dir)+strlen(WINE_PREFIX)+strlen(SAVE_CURRENT_USER)+2); + strcpy(fn,pwd->pw_dir); + strcat(fn,WINE_PREFIX); + /* create the directory. don't care about errorcodes. */ + mkdir(fn,0755); /* drwxr-xr-x */ + strcat(fn,"/"); + strcat(fn,SAVE_CURRENT_USER); + _SaveSubReg(key_current_user,fn); + free(fn); + fn=(char*)xmalloc(strlen(pwd->pw_dir)+strlen(WINE_PREFIX)+strlen(SAVE_LOCAL_MACHINE)+1); + strcpy(fn,pwd->pw_dir); + strcat(fn,WINE_PREFIX"/"SAVE_LOCAL_MACHINE); + _SaveSubReg(key_local_machine,fn); + free(fn); + } else { + fprintf(stderr,"SHELL_SaveRegistry:failed to get homedirectory of UID %d.\n",getuid()); + } } /************************ LOAD Registry Function ****************************/ -/* FIXME: - * Currently overwrites any old registry data (leaks it away) - * should better be a merge, or ? +/* reads a line including dynamically enlarging the readbuffer and throwing + * away comments */ +static int +_read_line(FILE *F,char **buf,int *len) { + char *s,*curread; + int mylen,curoff; -static int -_read_DWORD(FILE *F,DWORD *dw) { - return fread(dw,sizeof(DWORD),1,F); -} - -static int -_read_USTRING(FILE *F,LPWSTR *str) { - DWORD len; - - if (!_read_DWORD(F,&len)) - return 0; - if (len==0) { - *str=NULL; - return 1; - } - *str=xmalloc(len); - return fread(*str,len,1,F); -} - -static int -_do_load_subkey(FILE *F,LPKEYSTRUCT lpkey) { - DWORD howmuch; - LPKEYSTRUCT *lplpkey,lpxkey; - int i; - - if (!_read_DWORD(F,&howmuch)) - return 0; - - /* no subkeys? */ - if (howmuch==0) - return 1; - - lplpkey = &(lpkey->nextsub); - while (howmuch--) { - *lplpkey= (LPKEYSTRUCT)xmalloc(sizeof(KEYSTRUCT)); - memset(*lplpkey,'\0',sizeof(KEYSTRUCT)); - lpxkey = *lplpkey; - if (!_read_USTRING(F,&(lpxkey->keyname))) - return 0; - if (!_read_USTRING(F,&(lpxkey->class))) - return 0; - if (!_read_DWORD(F,&(lpxkey->nrofvalues))) - return 0; - if (lpxkey->nrofvalues) { - lpxkey->values = (LPKEYVALUE)xmalloc( - lpxkey->nrofvalues*sizeof(KEYVALUE) - ); - for (i=0;i<lpxkey->nrofvalues;i++) { - LPKEYVALUE val=lpxkey->values+i; - - memset(val,'\0',sizeof(KEYVALUE)); - if (!_read_USTRING(F,&(val->name))) - return 0; - if (!_read_DWORD(F,&(val->type))) - return 0; - if (!_read_DWORD(F,&(val->len))) - return 0; - val->data = (LPBYTE)xmalloc(val->len); - if (!fread(val->data,val->len,1,F)) - return 0; + curread = *buf; + mylen = *len; + **buf = '\0'; + while (1) { + while (1) { + s=fgets(curread,mylen,F); + if (s==NULL) + return 0; /* EOF */ + if (NULL==(s=strchr(curread,'\n'))) { + /* buffer wasn't large enough */ + curoff = strlen(*buf); + *buf = xrealloc(*buf,*len*2); + curread = *buf + curoff; + mylen = *len; /* we filled up the buffer and + * got new '*len' bytes to fill + */ + *len = *len * 2; + } else { + *s='\0'; + break; } } - if (!_do_load_subkey(F,*lplpkey)) - return 0; - lplpkey = &(lpxkey->next); + /* throw away comments */ + if (**buf=='#' || **buf==';') { + curread = *buf; + mylen = *len; + continue; + } + if (s) /* got end of line */ + break; + } + return 1; +} + +/* converts a char* into a UNICODE string (up to a special char) + * and returns the position exactly after that string + */ +static char* +_read_USTRING(char *buf,LPWSTR *str) { + char *s; + LPWSTR ws; + + /* read up to "=" or "\0" or "\n" */ + s = buf; + if (*s == '=') { + /* empty string is the win3.1 default value(NULL)*/ + *str = NULL; + return s; + } + *str = (LPWSTR)xmalloc(2*strlen(buf)+2); + ws = *str; + while (*s && (*s!='\n') && (*s!='=')) { + if (*s!='\\') + *ws++=*((unsigned char*)s++); + else { + s++; + if (*s=='\\') { + *ws+='\\'; + s++; + continue; + } + if (*s!='u') { + fprintf(stderr,"_read_USTRING:Non unicode escape sequence \\%c found in |%s|\n",*s,buf); + *ws++='\\'; + *ws++=*s++; + } else { + char xbuf[5]; + int wc; + + s++; + memcpy(xbuf,s,4);xbuf[4]='\0'; + if (!sscanf(xbuf,"%x",&wc)) + fprintf(stderr,"_read_USTRING:strange escape sequence %s found in |%s|\n",xbuf,buf); + s+=4; + *ws++ =(unsigned short)wc; + } + } + } + *ws = 0; + ws = *str; + *str = strdupW(*str); + free(ws); + return s; +} + +static int +_do_load_subkey(FILE *F,LPKEYSTRUCT lpkey,int level,char **buf,int *buflen) { + LPKEYSTRUCT lpxkey,*lplpkey; + int i; + char *s; + LPWSTR name; + + /* good. we already got a line here ... so parse it */ + lpxkey = NULL; + while (1) { + i=0;s=*buf; + while (*s=='\t') { + s++; + i++; + } + if (i>level) { + if (lpxkey==NULL) { + fprintf(stderr,"_do_load_subkey:Got a subhierarchy without resp. key?\n"); + return 0; + } + _do_load_subkey(F,lpxkey,level+1,buf,buflen); + continue; + } + /* let the caller handle this line */ + if (i<level || **buf=='\0') + return 1; + /* good. this is one line for us. + * it can be: a value or a keyname. Parse the name first + */ + s=_read_USTRING(s,&name); + + /* switch() default: hack to avoid gotos */ + switch (0) { + default: + if (*s=='\0') { + /* this is a new key + * look for the name in the already existing keys + * on this level. + */ + lplpkey= &(lpkey->nextsub); + lpxkey = *lplpkey; + while (lpxkey) { + if (!strcmpW(lpxkey->keyname,name)) + break; + lplpkey = &(lpxkey->next); + lpxkey = *lplpkey; + } + if (lpxkey==NULL) { + /* we have no key with that name yet. allocate + * it. + */ + *lplpkey = (LPKEYSTRUCT)xmalloc(sizeof(KEYSTRUCT)); + lpxkey = *lplpkey; + memset(lpxkey,'\0',sizeof(KEYSTRUCT)); + lpxkey->keyname = name; + } else { + /* already got it. we just remember it in + * 'lpxkey' + */ + free(name); + } + } else { + LPKEYVALUE val=NULL; + LPBYTE data; + int len,lastmodified,type; + + if (*s!='=') { + fprintf(stderr,"_do_load_subkey:unexpected character: %c\n",*s); + break; + } + /* good. this looks like a value to me */ + s++; + for (i=0;i<lpkey->nrofvalues;i++) { + val=lpkey->values+i; + if (name==NULL) { + if (val->name==NULL) + break; + } else { + if ( val->name!=NULL && + !strcmpW(val->name,name) + ) + break; + } + } + if (i==lpkey->nrofvalues) { + lpkey->values = xrealloc( + lpkey->values, + (++lpkey->nrofvalues)*sizeof(KEYVALUE) + ); + val=lpkey->values+i; + memset(val,'\0',sizeof(KEYVALUE)); + val->name = name; + } else { + /* value already exists, free name */ + free(name); + } + if (2!=sscanf(s,"%d,%d,",&type,&lastmodified)) { + fprintf(stderr,"_do_load_subkey: haven't understood possible value in |%s|, skipping.\n",*buf); + break; + } + /* skip the 2 , */ + s=strchr(s,',');s++; + s=strchr(s,',');s++; + if ((1<<type) & UNICONVMASK) { + s=_read_USTRING(s,(LPWSTR*)&data); + if (data) + len = strlenW((LPWSTR)data)*2+2; + else + len = 0; + } else { + len=strlen(s)/2; + data = (LPBYTE)xmalloc(len+1); + for (i=0;i<len;i++) { + data[i]=0; + if (*s>='0' && *s<='9') + data[i]=(*s-'0')<<4; + if (*s>='a' && *s<='f') + data[i]=(*s-'a')<<4; + if (*s>='A' && *s<='F') + data[i]=(*s-'A')<<4; + s++; + if (*s>='0' && *s<='9') + data[i]|=*s-'0'; + if (*s>='a' && *s<='f') + data[i]|=*s-'a'; + if (*s>='A' && *s<='F') + data[i]|=*s-'A'; + s++; + } + } + if (val->lastmodified<lastmodified) { + val->lastmodified=lastmodified; + val->type = type; + val->len = len; + if (val->data) + free(val->data); + val->data = data; + } else { + free(data); + } + } + } + /* read the next line */ + if (!_read_line(F,buf,buflen)) + return 1; } return 1; } static int _do_loadsubreg(FILE *F,LPKEYSTRUCT lpkey) { - DWORD ver; + int ver; + char *buf; + int buflen; - if (!_read_DWORD(F,&ver)) - return 0; - if (ver!=REGISTRY_SAVE_VERSION) { - dprintf_reg(stddeb,__FILE__":_do_loadsubreg:Old format (%lx) registry found, ignoring it.\n",ver); + buf=xmalloc(10);buflen=10; + if (!_read_line(F,&buf,&buflen)) { + free(buf); return 0; } - if (!_do_load_subkey(F,lpkey)) { + if (!sscanf(buf,"WINE REGISTRY Version %d",&ver)) { + free(buf); + return 0; + } + if (ver!=REGISTRY_SAVE_VERSION) { + dprintf_reg(stddeb,__FILE__":_do_loadsubreg:Old format (%d) registry found, ignoring it. (buf was %s).\n",ver,buf); + free(buf); + return 0; + } + if (!_read_line(F,&buf,&buflen)) { + free(buf); + return 0; + } + if (!_do_load_subkey(F,lpkey,0,&buf,&buflen)) { + free(buf); /* FIXME: memory leak on failure to read registry ... * But this won't happen very often. */ lpkey->nextsub=NULL; return 0; } + free(buf); return 1; } @@ -459,18 +682,40 @@ void SHELL_LoadRegistry() { + char *fn; + struct passwd *pwd; + if (key_classes_root==NULL) SHELL_Init(); - _LoadSubReg(key_classes_root,SAVE_CLASSES_ROOT); - _LoadSubReg(key_current_user,SAVE_CURRENT_USER); - _LoadSubReg(key_local_machine,SAVE_LOCAL_MACHINE); - _LoadSubReg(key_users,SAVE_USERS); + /* load the machine-wide defaults first */ + _LoadSubReg(key_current_user,SAVE_CURRENT_USER_DEFAULT); + _LoadSubReg(key_local_machine,SAVE_LOCAL_MACHINE_DEFAULT); + + /* load the user saved registry. overwriting only newer entries */ + pwd=getpwuid(getuid()); + if (pwd!=NULL && pwd->pw_dir!=NULL) { + fn=(char*)xmalloc(strlen(pwd->pw_dir)+strlen(WINE_PREFIX)+strlen(SAVE_CURRENT_USER)+1); + strcpy(fn,pwd->pw_dir); + strcat(fn,WINE_PREFIX"/"SAVE_CURRENT_USER); + _LoadSubReg(key_current_user,fn); + free(fn); + fn=(char*)xmalloc(strlen(pwd->pw_dir)+strlen(WINE_PREFIX)+strlen(SAVE_LOCAL_MACHINE)+1); + strcpy(fn,pwd->pw_dir); + strcat(fn,WINE_PREFIX"/"SAVE_LOCAL_MACHINE); + _LoadSubReg(key_local_machine,fn); + free(fn); + } else { + fprintf(stderr,"SHELL_LoadRegistry:failed to get homedirectory of UID %d.\n",getuid()); + } + /* FIXME: load all users and their resp. pwd->pw_dir/.wine/user.reg + * (later, when a win32 registry editing tool becomes avail.) + */ } /********************* API FUNCTIONS ***************************************/ /* - * Open Keys. + * Open Keys. * * All functions are stubs to RegOpenKeyExW where all the * magic happens. @@ -508,6 +753,7 @@ } split_keypath(lpszSubKey,&wps,&wpc); i = 0; + while ((i<wpc) && (wps[i][0]=='\0')) i++; lpxkey = lpNextKey; while (i<wpc) { lpxkey=lpNextKey->nextsub; @@ -647,6 +893,7 @@ } split_keypath(lpszSubKey,&wps,&wpc); i = 0; + while ((i<wpc) && (wps[i][0]=='\0')) i++; lpxkey = lpNextKey; while (i<wpc) { lpxkey=lpNextKey->nextsub; @@ -1131,6 +1378,7 @@ if (lpkey->values[i].data !=NULL) free(lpkey->values[i].data); lpkey->values[i].data = (LPBYTE)xmalloc(cbData); + lpkey->values[i].lastmodified = time(NULL); memcpy(lpkey->values[i].data,lpbData,cbData); return SHELL_ERROR_SUCCESS; }
diff --git a/misc/user.c b/misc/user.c index 0a3cd4f..194da4c 100644 --- a/misc/user.c +++ b/misc/user.c
@@ -24,30 +24,33 @@ */ WORD GetFreeSystemResources( WORD resType ) { - DWORD user, gdi; + int userPercent, gdiPercent; switch(resType) { case GFSR_USERRESOURCES: - user = GetHeapSpaces( USER_HeapSel ); - gdi = 0xffffffff; + userPercent = (int)LOCAL_CountFree( USER_HeapSel ) * 100 / + LOCAL_HeapSize( USER_HeapSel ); + gdiPercent = 100; break; case GFSR_GDIRESOURCES: - gdi = GetHeapSpaces( GDI_HeapSel ); - user = 0xffffffff; + gdiPercent = (int)LOCAL_CountFree( GDI_HeapSel ) * 100 / + LOCAL_HeapSize( GDI_HeapSel ); + userPercent = 100; break; case GFSR_SYSTEMRESOURCES: - user = GetHeapSpaces( USER_HeapSel ); - gdi = GetHeapSpaces( GDI_HeapSel ); + userPercent = (int)LOCAL_CountFree( USER_HeapSel ) * 100 / + LOCAL_HeapSize( USER_HeapSel ); + gdiPercent = (int)LOCAL_CountFree( GDI_HeapSel ) * 100 / + LOCAL_HeapSize( GDI_HeapSel ); break; default: return 0; } - if (user > gdi) return LOWORD(gdi) * 100 / HIWORD(gdi); - else return LOWORD(user) * 100 / HIWORD(user); + return (WORD)MIN( userPercent, gdiPercent ); }
diff --git a/misc/w32sys.c b/misc/w32sys.c new file mode 100644 index 0000000..8fae50d --- /dev/null +++ b/misc/w32sys.c
@@ -0,0 +1,23 @@ +/* + * W32SYS + * helper DLL for Win32s + * + * Copyright (c) 1996 Anand Kumria + */ + +#include "windows.h" +#include "w32sys.h" + + +/*********************************************************************** + * GetWin32sInfo (W32SYS.12) + */ +WORD GetWin32sInfo( LPWIN32SINFO lpInfo) +{ + lpInfo->bMajor = 1; + lpInfo->bMinor = 3; + lpInfo->wBuildNumber = 0; + lpInfo->fDebug = FALSE; + + return 0; +}
diff --git a/objects/metafile.c b/objects/metafile.c index b68373a..e831017 100644 --- a/objects/metafile.c +++ b/objects/metafile.c
@@ -2,6 +2,7 @@ * Metafile functions * * Copyright David W. Metcalfe, 1994 + * Niels de Carpentier, 1996 * */ @@ -12,7 +13,7 @@ #include "file.h" #include "metafile.h" #include "stddebug.h" -/* #define DEBUG_METAFILE */ +#include "callback.h" #include "debug.h" #define HTINCR 10 /* handle table allocation size increment */ @@ -23,52 +24,60 @@ /****************************************************************** * GetMetafile GDI.124 By Kenny MacDonald 30 Nov 94 */ + HMETAFILE GetMetaFile(LPSTR lpFilename) { HMETAFILE hmf; - METAFILE *mf; METAHEADER *mh; - + HFILE hFile; + DWORD size; + dprintf_metafile(stddeb,"GetMetaFile: %s\n", lpFilename); if (!lpFilename) return 0; - hmf = GlobalAlloc(GMEM_MOVEABLE, sizeof(METAFILE)); - mf = (METAFILE *)GlobalLock(hmf); - if (!mf) { - GlobalFree(hmf); - return 0; - } - - mf->hMetaHdr = GlobalAlloc(GMEM_MOVEABLE, MFHEADERSIZE); - mh = (METAHEADER *)GlobalLock(mf->hMetaHdr); + hmf = GlobalAlloc(GMEM_MOVEABLE, MFHEADERSIZE); + mh = (METAHEADER *)GlobalLock(hmf); + if (!mh) { - GlobalFree(mf->hMetaHdr); GlobalFree(hmf); return 0; } - strcpy(mf->Filename, lpFilename); - mf->wMagic = METAFILE_MAGIC; - if ((mf->hFile = _lopen(lpFilename, OF_READ)) == HFILE_ERROR) { - GlobalFree(mf->hMetaHdr); + + if ((hFile = _lopen(lpFilename, OF_READ)) == HFILE_ERROR) { GlobalFree(hmf); return 0; } - if (FILE_Read(mf->hFile, (char *)mh, MFHEADERSIZE) == HFILE_ERROR) { - GlobalFree(mf->hMetaHdr); + + if (FILE_Read(hFile, (char *)mh, MFHEADERSIZE) == HFILE_ERROR) { GlobalFree(hmf); return 0; } - _lclose(mf->hFile); + + size = mh->mtSize * 2; /* alloc memory for whole metafile */ + GlobalUnlock(hmf); + hmf = GlobalReAlloc(hmf,size,GMEM_MOVEABLE); + mh = (METAHEADER *)GlobalLock(hmf); + + if (!mh) { + GlobalFree(hmf); + return 0; + } + + if (FILE_Read(hFile, (char*)mh + mh->mtHeaderSize * 2, + size - mh->mtHeaderSize * 2) == HFILE_ERROR) { + GlobalFree(hmf); + return 0; + } + + _lclose(hFile); if (mh->mtType != 1) { - GlobalFree(mf->hMetaHdr); GlobalFree(hmf); return 0; } - - GlobalUnlock(mf->hMetaHdr); + GlobalUnlock(hmf); return hmf; @@ -77,34 +86,30 @@ /****************************************************************** * CreateMetafile GDI.125 */ + HANDLE CreateMetaFile(LPCTSTR lpFilename) { DC *dc; HANDLE handle; - METAFILE *mf; METAHEADER *mh; - HANDLETABLE *ht; - + int hFile; + dprintf_metafile(stddeb,"CreateMetaFile: %s\n", lpFilename); handle = GDI_AllocObject(sizeof(DC), METAFILE_DC_MAGIC); - if (!handle) return 0; + + if (!handle) + return 0; + dc = (DC *)GDI_HEAP_LIN_ADDR(handle); - if (!(dc->w.hMetaFile = GlobalAlloc(GMEM_MOVEABLE, sizeof(METAFILE)))) { + if (!(dc->w.hMetaFile = GlobalAlloc(GMEM_MOVEABLE, sizeof(METAHEADER)))) { GDI_FreeObject(handle); return 0; } - mf = (METAFILE *)GlobalLock(dc->w.hMetaFile); - if (!(mf->hMetaHdr = GlobalAlloc(GMEM_MOVEABLE, sizeof(METAHEADER)))) - { - GDI_FreeObject(handle); - GlobalFree(dc->w.hMetaFile); - return 0; - } - mh = (METAHEADER *)GlobalLock(mf->hMetaHdr); + + mh = (METAHEADER *)GlobalLock(dc->w.hMetaFile); - mf->wMagic = METAFILE_MAGIC; mh->mtHeaderSize = MFHEADERSIZE / 2; mh->mtVersion = MFVERSION; mh->mtSize = MFHEADERSIZE / 2; @@ -114,15 +119,15 @@ if (lpFilename) /* disk based metafile */ { - mh->mtType = 1; - strcpy(mf->Filename, lpFilename); - mf->hFile = _lcreat(lpFilename, 0); - if (_lwrite(mf->hFile, (char *)mh, MFHEADERSIZE) == -1) + mh->mtType = 1; /* disk */ + hFile = _lcreat(lpFilename, 0); + if (_lwrite(hFile, (char *)mh, MFHEADERSIZE) == -1) { - GlobalFree(mf->hMetaHdr); GlobalFree(dc->w.hMetaFile); return 0; } + mh->mtNoParameters = hFile; /* store file descriptor here */ + /* windows probably uses this too*/ } else /* memory based metafile */ mh->mtType = 0; @@ -131,63 +136,102 @@ HTLen = HTINCR; hHT = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(HANDLETABLE) * HTLen); - ht = (HANDLETABLE *)GlobalLock(hHT); - - GlobalUnlock(mf->hMetaHdr); + GlobalUnlock(dc->w.hMetaFile); return handle; } /****************************************************************** + * CopyMetafile GDI.151 Niels de Carpentier, April 1996 + */ + +HMETAFILE CopyMetaFile(HMETAFILE hSrcMetaFile, LPCSTR lpFilename) +{ + HMETAFILE handle = 0; + METAHEADER *mh; + METAHEADER *mh2; + int hFile; + + dprintf_metafile(stddeb,"CopyMetaFile: %s\n", lpFilename); + + mh = (METAHEADER *)GlobalLock(hSrcMetaFile); + + if (!mh) + return 0; + + if (lpFilename) /* disk based metafile */ + { + hFile = _lcreat(lpFilename, 0); + if (_lwrite(hFile, (char *)mh, mh->mtSize * 2) == -1) + { + _lclose(hFile); + return 0; + } + _lclose(hFile); + } + else /* memory based metafile */ + { + handle = GlobalAlloc(GMEM_MOVEABLE,mh->mtSize * 2); + mh2 = (METAHEADER *)GlobalLock(handle); + memcpy(mh2,mh, mh->mtSize * 2); + GlobalUnlock(handle); + } + + return handle; +} + + +/****************************************************************** * CloseMetafile GDI.126 */ + HMETAFILE CloseMetaFile(HDC hdc) { DC *dc; - METAFILE *mf; METAHEADER *mh; HMETAFILE hmf; -/* METARECORD *mr = (METARECORD *)&buffer;*/ - + HFILE hFile; + dprintf_metafile(stddeb,"CloseMetaFile\n"); dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC); - if (!dc) return 0; - mf = (METAFILE *)GlobalLock(dc->w.hMetaFile); - mh = (METAHEADER *)GlobalLock(mf->hMetaHdr); + + if (!dc) + return 0; + + mh = (METAHEADER *)GlobalLock(dc->w.hMetaFile); /* Construct the end of metafile record - this is documented * in SDK Knowledgebase Q99334. */ + if (!MF_MetaParam0(dc, META_EOF)) { - GlobalFree(mf->hMetaHdr); GlobalFree(dc->w.hMetaFile); return 0; } if (mh->mtType == 1) /* disk based metafile */ { - if (_llseek(mf->hFile, 0L, 0) == -1) - { - GlobalFree(mf->hMetaHdr); - GlobalFree(dc->w.hMetaFile); - return 0; - } - if (_lwrite(mf->hFile, (char *)mh, MFHEADERSIZE) == -1) - { - GlobalFree(mf->hMetaHdr); - GlobalFree(dc->w.hMetaFile); - return 0; - } - _lclose(mf->hFile); + hFile = mh->mtNoParameters; + mh->mtNoParameters = 0; + if (_llseek(hFile, 0L, 0) == -1) + { + GlobalFree(dc->w.hMetaFile); + return 0; + } + if (_lwrite(hFile, (char *)mh, MFHEADERSIZE) == -1) + { + GlobalFree(dc->w.hMetaFile); + return 0; + } + _lclose(hFile); } /* delete the handle table */ GlobalFree(hHT); - GlobalUnlock(mf->hMetaHdr); hmf = dc->w.hMetaFile; GlobalUnlock(hmf); GDI_FreeObject(hdc); @@ -198,14 +242,14 @@ /****************************************************************** * DeleteMetafile GDI.127 */ + BOOL DeleteMetaFile(HMETAFILE hmf) { - METAFILE *mf = (METAFILE *)GlobalLock(hmf); + METAHEADER *mh = (METAHEADER *)GlobalLock(hmf); - if (!mf || mf->wMagic != METAFILE_MAGIC) + if (!mh) return FALSE; - GlobalFree(mf->hMetaHdr); GlobalFree(hmf); return TRUE; } @@ -214,60 +258,73 @@ /****************************************************************** * PlayMetafile GDI.123 */ + BOOL PlayMetaFile(HDC hdc, HMETAFILE hmf) { - METAFILE *mf = (METAFILE *)GlobalLock(hmf); - METAHEADER *mh; + METAHEADER *mh = (METAHEADER *)GlobalLock(hmf); METARECORD *mr; HANDLETABLE *ht; - char *buffer = (char *)NULL; - - if (mf->wMagic != METAFILE_MAGIC) - return FALSE; - - mh = (METAHEADER *)GlobalLock(mf->hMetaHdr); - if (mh->mtType == 1) /* disk based metafile */ - { - mf->hFile = _lopen(mf->Filename, OF_READ); - mf->hBuffer = GlobalAlloc(GMEM_MOVEABLE, mh->mtMaxRecord * 2); - buffer = (char *)GlobalLock(mf->hBuffer); - _llseek(mf->hFile, mh->mtHeaderSize * 2, 0); - mf->MetaOffset = mh->mtHeaderSize * 2; - } - else if (mh->mtType == 0) /* memory based metafile */ - mf->MetaOffset = mh->mtHeaderSize * 2; - else /* not a valid metafile type */ - return FALSE; - + int offset = 0; + + dprintf_metafile(stddeb,"PlayMetaFile(%04x %04x)\n",hdc,hmf); + /* create the handle table */ hHT = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT, sizeof(HANDLETABLE) * mh->mtNoObjects); ht = (HANDLETABLE *)GlobalLock(hHT); /* loop through metafile playing records */ - while (mf->MetaOffset < mh->mtSize * 2) + offset = mh->mtHeaderSize * 2; + while (offset < mh->mtSize * 2) { - if (mh->mtType == 1) /* disk based metafile */ - { - FILE_Read(mf->hFile, buffer, sizeof(METARECORD)); - mr = (METARECORD *)buffer; - FILE_Read(mf->hFile, (char *)(mr->rdParam + 1), (mr->rdSize * 2) - - sizeof(METARECORD)); - mf->MetaOffset += mr->rdSize * 2; - } - else /* memory based metafile */ - { - mr = (METARECORD *)((char *)mh + mf->MetaOffset); - mf->MetaOffset += mr->rdSize * 2; - } + mr = (METARECORD *)((char *)mh + offset); + dprintf_metafile(stddeb,"offset = %04x size = %08lx function = %04x\n", + offset,mr->rdSize,mr->rdFunction); + offset += mr->rdSize * 2; PlayMetaFileRecord(hdc, ht, mr, mh->mtNoObjects); } - /* close disk based metafile and free buffer */ - if (mh->mtType == 1) + /* free handle table */ + GlobalFree(hHT); + + return TRUE; +} + + +/****************************************************************** + * EnumMetafile GDI.175 + * Niels de carpentier, april 1996 + */ + +BOOL EnumMetaFile(HDC hdc, HMETAFILE hmf, MFENUMPROC lpEnumFunc,LPARAM lpData) +{ + METAHEADER *mh = (METAHEADER *)GlobalLock(hmf); + METARECORD *mr; + HANDLETABLE *ht; + int offset = 0; + + dprintf_metafile(stddeb,"EnumMetaFile(%04x, %04x, %08lx, %08lx)\n", + hdc, hmf, (DWORD)lpEnumFunc, lpData); + + /* create the handle table */ + + hHT = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, + sizeof(HANDLETABLE) * mh->mtNoObjects); + ht = (HANDLETABLE *)GlobalLock(hHT); + + offset = mh->mtHeaderSize * 2; + + /* loop through metafile records */ + + while (offset < (mh->mtSize * 2)) { - GlobalFree(mf->hBuffer); - _lclose(mf->hFile); + mr = (METARECORD *)((char *)mh + offset); + if (!CallEnumMetafileProc(lpEnumFunc, hdc, MAKE_SEGPTR(ht), + MAKE_SEGPTR(mr), mh->mtNoObjects, + (LONG)lpData)) + break; + + offset += (mr->rdSize * 2); } /* free handle table */ @@ -280,6 +337,7 @@ /****************************************************************** * PlayMetaFileRecord GDI.176 */ + void PlayMetaFileRecord(HDC hdc, HANDLETABLE *ht, METARECORD *mr, WORD nHandles) { @@ -288,6 +346,9 @@ char *ptr; BITMAPINFOHEADER *infohdr; + dprintf_metafile(stddeb,"PlayMetaFileRecord(%04x %08lx %08lx %04x)\n", + hdc,(LONG)ht, (LONG)mr, nHandles); + switch (mr->rdFunction) { case META_EOF: @@ -552,7 +613,52 @@ } break; /* End new metafile operations. */ - + + case META_STRETCHDIB: + { + LPSTR bits; + LPBITMAPINFO info; + int offset; + info = (LPBITMAPINFO) &(mr->rdParam[11]); + if (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER)) + { + if (info->bmiHeader.biClrUsed) + { + if (info->bmiHeader.biClrUsed < (1 << info->bmiHeader.biBitCount)) + offset = info->bmiHeader.biClrUsed * 4; + else + offset = (1 << info->bmiHeader.biBitCount) * 4; + } + else + offset = (1 << info->bmiHeader.biBitCount) * 4; + } + else if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) + { + if (info->bmiHeader.biClrUsed) + { + if (info->bmiHeader.biClrUsed < (1 << info->bmiHeader.biBitCount)) + offset = info->bmiHeader.biClrUsed * 3; + else + offset = (1 << info->bmiHeader.biBitCount) * 3; + } + else + offset = (1 << info->bmiHeader.biBitCount) * 3; + } + else + { + fprintf(stderr,"Unknown size for BITMAPHEADER in PlayMetaRecord!\n"); + break; + } + + offset += info->bmiHeader.biSize; + bits = (LPSTR) info + offset; + StretchDIBits(hdc,mr->rdParam[10],mr->rdParam[9],mr->rdParam[8], + mr->rdParam[7],mr->rdParam[6],mr->rdParam[5], + mr->rdParam[4],mr->rdParam[3],bits,info, + mr->rdParam[2],(DWORD)mr->rdParam[0]); + } + break; + default: fprintf(stddeb,"PlayMetaFileRecord: Unknown record type %x\n", mr->rdFunction); @@ -564,33 +670,12 @@ * * Trade in a meta file object handle for a handle to the meta file memory */ + HANDLE GetMetaFileBits(HMETAFILE hmf) { + dprintf_metafile(stddeb,"GetMetaFileBits: hMem out: %04x\n", hmf); - /* save away the meta file bits handle */ - METAFILE *mf = (METAFILE *)GlobalLock(hmf); - HANDLE hMem = mf->hMetaHdr; - METAHEADER *mh = (METAHEADER *)GlobalLock(hMem); - - dprintf_metafile(stddeb,"GetMetaFileBits: hmf in: %04x\n", hmf); - - /* can't get bits of disk based metafile */ - /* FIXME: should the disk file be loaded in this case? */ - if(mh->mtType == 1) { - fprintf(stderr, - "GetMetaFileBits: application requested bits of disk meta file.\n"); - GlobalUnlock(hMem); - GlobalUnlock(hmf); - return FALSE; - } - - /* unlock the memory and invalidate the metafile handle */ - GlobalUnlock(hMem); - GlobalFree(hmf); - - dprintf_metafile(stddeb,"GetMetaFileBits: hMem out: %04x\n", hMem); - - return hMem; + return hmf; } /****************************************************************** @@ -598,76 +683,50 @@ * * Trade in a meta file memory handle for a handle to a meta file object */ + HMETAFILE SetMetaFileBits(HANDLE hMem) { - HMETAFILE hmf; - METAFILE *mf; - METAHEADER *mh = (METAHEADER *)GlobalLock(hMem); + dprintf_metafile(stddeb,"SetMetaFileBits: hmf out: %04x\n", hMem); - dprintf_metafile(stddeb,"SetMetaFileBits: hMem in: %04x\n", hMem); - - if (!mh) return FALSE; - - /* now it is a memory meta file */ - mh->mtType = 0; - - hmf = GlobalAlloc(GMEM_MOVEABLE, sizeof(METAFILE)); - mf = (METAFILE *)GlobalLock(hmf); - if (!mf) { - GlobalUnlock(hMem); - GlobalFree(hmf); - return FALSE; - } - - /* use the supplied memory handle */ - mf->hMetaHdr = hMem; - mf->wMagic = METAFILE_MAGIC; - mf->MetaOffset = mh->mtHeaderSize * 2; - mf->hFile = (int) (mf->hBuffer = (HANDLE) NULL); - - GlobalUnlock(hMem); - GlobalUnlock(hmf); - - dprintf_metafile(stddeb,"SetMetaFileBits: hmf out: %04x\n", hmf); - - return hmf; + return hMem; } /****************************************************************** * MF_WriteRecord */ -BOOL MF_WriteRecord(HMETAFILE hmf, METARECORD *mr, WORD rlen) + +HMETAFILE MF_WriteRecord(HMETAFILE hmf, METARECORD *mr, WORD rlen) { DWORD len; - METAFILE *mf = (METAFILE *)GlobalLock(hmf); - METAHEADER *mh = (METAHEADER *)GlobalLock(mf->hMetaHdr); - + METAHEADER *mh = (METAHEADER *)GlobalLock(hmf); + if (mh->mtType == 0) /* memory based metafile */ { len = mh->mtSize * 2 + rlen; - GlobalUnlock(mf->hMetaHdr); - mf->hMetaHdr = GlobalReAlloc(mf->hMetaHdr, len, GMEM_MOVEABLE); - mh = (METAHEADER *)GlobalLock(mf->hMetaHdr); + GlobalUnlock(hmf); + hmf = GlobalReAlloc(hmf, len, GMEM_MOVEABLE); /* hmf can change */ + mh = (METAHEADER *)GlobalLock(hmf); memcpy((WORD *)mh + mh->mtSize, mr, rlen); } else if (mh->mtType == 1) /* disk based metafile */ { - if (_lwrite(mf->hFile, (char *)mr, rlen) == -1) + dprintf_metafile(stddeb,"Writing record to disk\n"); + if (_lwrite(mh->mtNoParameters, (char *)mr, rlen) == -1) { - GlobalUnlock(mf->hMetaHdr); - return FALSE; + GlobalUnlock(hmf); + return 0; } } else { - GlobalUnlock(mf->hMetaHdr); - return FALSE; + GlobalUnlock(hmf); + return 0; } mh->mtSize += rlen / 2; mh->mtMaxRecord = MAX(mh->mtMaxRecord, rlen / 2); - GlobalUnlock(mf->hMetaHdr); - return TRUE; + GlobalUnlock(hmf); + return hmf; } @@ -676,6 +735,7 @@ * * Add a handle to an external handle table and return the index */ + int MF_AddHandle(HANDLETABLE *ht, WORD htlen, HANDLE hobj) { int i; @@ -697,6 +757,7 @@ * * Add a handle to the internal handle table and return the index */ + int MF_AddHandleInternal(HANDLE hobj) { int i; @@ -725,14 +786,19 @@ /****************************************************************** * MF_MetaParam0 */ + BOOL MF_MetaParam0(DC *dc, short func) { char buffer[8]; METARECORD *mr = (METARECORD *)&buffer; - + HMETAFILE handle; + mr->rdSize = 3; mr->rdFunction = func; - return MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2); + handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2); + dc->w.hMetaFile = handle; + + return handle; } @@ -743,11 +809,15 @@ { char buffer[8]; METARECORD *mr = (METARECORD *)&buffer; - + HMETAFILE handle; + mr->rdSize = 4; mr->rdFunction = func; *(mr->rdParam) = param1; - return MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2); + handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2); + dc->w.hMetaFile = handle; + + return handle; } @@ -758,43 +828,54 @@ { char buffer[10]; METARECORD *mr = (METARECORD *)&buffer; - + HMETAFILE handle; + mr->rdSize = 5; mr->rdFunction = func; *(mr->rdParam) = param2; *(mr->rdParam + 1) = param1; - return MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2); + handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2); + dc->w.hMetaFile = handle; + + return handle; } /****************************************************************** * MF_MetaParam4 */ + BOOL MF_MetaParam4(DC *dc, short func, short param1, short param2, short param3, short param4) { char buffer[14]; METARECORD *mr = (METARECORD *)&buffer; - + HMETAFILE handle; + mr->rdSize = 7; mr->rdFunction = func; *(mr->rdParam) = param4; *(mr->rdParam + 1) = param3; *(mr->rdParam + 2) = param2; *(mr->rdParam + 3) = param1; - return MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2); + handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2); + dc->w.hMetaFile = handle; + + return handle; } /****************************************************************** * MF_MetaParam6 */ + BOOL MF_MetaParam6(DC *dc, short func, short param1, short param2, short param3, short param4, short param5, short param6) { char buffer[18]; METARECORD *mr = (METARECORD *)&buffer; - + HMETAFILE handle; + mr->rdSize = 9; mr->rdFunction = func; *(mr->rdParam) = param6; @@ -803,7 +884,10 @@ *(mr->rdParam + 3) = param3; *(mr->rdParam + 4) = param2; *(mr->rdParam + 5) = param1; - return MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2); + handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2); + dc->w.hMetaFile = handle; + + return handle; } @@ -816,7 +900,8 @@ { char buffer[22]; METARECORD *mr = (METARECORD *)&buffer; - + HMETAFILE handle; + mr->rdSize = 11; mr->rdFunction = func; *(mr->rdParam) = param8; @@ -827,48 +912,55 @@ *(mr->rdParam + 5) = param3; *(mr->rdParam + 6) = param2; *(mr->rdParam + 7) = param1; - return MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2); + handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2); + dc->w.hMetaFile = handle; + + return handle; } /****************************************************************** * MF_CreateBrushIndirect */ + BOOL MF_CreateBrushIndirect(DC *dc, HBRUSH hBrush, LOGBRUSH *logbrush) { int index; - BOOL rc; + HMETAFILE handle; char buffer[sizeof(METARECORD) - 2 + sizeof(LOGBRUSH)]; METARECORD *mr = (METARECORD *)&buffer; - METAFILE *mf; METAHEADER *mh; mr->rdSize = (sizeof(METARECORD) + sizeof(LOGBRUSH) - 2) / 2; mr->rdFunction = META_CREATEBRUSHINDIRECT; memcpy(&(mr->rdParam), logbrush, sizeof(LOGBRUSH)); - if (!MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2)) + if (!(dc->w.hMetaFile = MF_WriteRecord(dc->w.hMetaFile, + mr, mr->rdSize * 2))) return FALSE; mr->rdSize = sizeof(METARECORD) / 2; mr->rdFunction = META_SELECTOBJECT; + if ((index = MF_AddHandleInternal(hBrush)) == -1) return FALSE; - mf = (METAFILE *)GlobalLock(dc->w.hMetaFile); - mh = (METAHEADER *)GlobalLock(mf->hMetaHdr); + mh = (METAHEADER *)GlobalLock(dc->w.hMetaFile); *(mr->rdParam) = index; if (index >= mh->mtNoObjects) mh->mtNoObjects++; - rc = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2); - GlobalUnlock(mf->hMetaHdr); + GlobalUnlock(dc->w.hMetaFile); - return rc; + handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2); + dc->w.hMetaFile = handle; + + return handle; } /****************************************************************** * MF_CreatePatternBrush */ + BOOL MF_CreatePatternBrush(DC *dc, HBRUSH hBrush, LOGBRUSH *logbrush) { DWORD len, bmSize, biSize; @@ -878,9 +970,8 @@ BITMAPINFO *info; BITMAPINFOHEADER *infohdr; int index; - BOOL rc; + HMETAFILE handle; char buffer[sizeof(METARECORD)]; - METAFILE *mf; METAHEADER *mh; switch (logbrush->lbStyle) @@ -930,98 +1021,103 @@ default: return FALSE; } - if (!MF_WriteRecord(dc->w.hMetaFile, mr, len)) + if (!(dc->w.hMetaFile = MF_WriteRecord(dc->w.hMetaFile, mr, len))) { GlobalFree(hmr); return FALSE; } GlobalFree(hmr); + mr = (METARECORD *)&buffer; mr->rdSize = sizeof(METARECORD) / 2; mr->rdFunction = META_SELECTOBJECT; if ((index = MF_AddHandleInternal(hBrush)) == -1) return FALSE; - mf = (METAFILE *)GlobalLock(dc->w.hMetaFile); - mh = (METAHEADER *)GlobalLock(mf->hMetaHdr); + mh = (METAHEADER *)GlobalLock(dc->w.hMetaFile); *(mr->rdParam) = index; if (index >= mh->mtNoObjects) mh->mtNoObjects++; - rc = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2); - GlobalUnlock(mf->hMetaHdr); GlobalUnlock(dc->w.hMetaFile); - return rc; + handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2); + dc->w.hMetaFile = handle; + + return handle; } /****************************************************************** * MF_CreatePenIndirect */ + BOOL MF_CreatePenIndirect(DC *dc, HPEN hPen, LOGPEN *logpen) { int index; - BOOL rc; + HMETAFILE handle; char buffer[sizeof(METARECORD) - 2 + sizeof(LOGPEN)]; METARECORD *mr = (METARECORD *)&buffer; - METAFILE *mf; METAHEADER *mh; mr->rdSize = (sizeof(METARECORD) + sizeof(LOGPEN) - 2) / 2; mr->rdFunction = META_CREATEPENINDIRECT; memcpy(&(mr->rdParam), logpen, sizeof(LOGPEN)); - if (!MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2)) + if (!(dc->w.hMetaFile = MF_WriteRecord(dc->w.hMetaFile, mr, + mr->rdSize * 2))) return FALSE; mr->rdSize = sizeof(METARECORD) / 2; mr->rdFunction = META_SELECTOBJECT; + if ((index = MF_AddHandleInternal(hPen)) == -1) return FALSE; - mf = (METAFILE *)GlobalLock(dc->w.hMetaFile); - mh = (METAHEADER *)GlobalLock(mf->hMetaHdr); + mh = (METAHEADER *)GlobalLock(dc->w.hMetaFile); *(mr->rdParam) = index; if (index >= mh->mtNoObjects) mh->mtNoObjects++; - rc = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2); - GlobalUnlock(mf->hMetaHdr); GlobalUnlock(dc->w.hMetaFile); - return rc; + handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2); + dc->w.hMetaFile = handle; + + return handle; } /****************************************************************** * MF_CreateFontIndirect */ + BOOL MF_CreateFontIndirect(DC *dc, HFONT hFont, LOGFONT *logfont) { int index; - BOOL rc; + HMETAFILE handle; char buffer[sizeof(METARECORD) - 2 + sizeof(LOGFONT)]; METARECORD *mr = (METARECORD *)&buffer; - METAFILE *mf; METAHEADER *mh; mr->rdSize = (sizeof(METARECORD) + sizeof(LOGFONT) - 2) / 2; mr->rdFunction = META_CREATEFONTINDIRECT; memcpy(&(mr->rdParam), logfont, sizeof(LOGFONT)); - if (!MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2)) + if (!(dc->w.hMetaFile = MF_WriteRecord(dc->w.hMetaFile, mr, + mr->rdSize * 2))) return FALSE; mr->rdSize = sizeof(METARECORD) / 2; mr->rdFunction = META_SELECTOBJECT; + if ((index = MF_AddHandleInternal(hFont)) == -1) return FALSE; - mf = (METAFILE *)GlobalLock(dc->w.hMetaFile); - mh = (METAHEADER *)GlobalLock(mf->hMetaHdr); + mh = (METAHEADER *)GlobalLock(dc->w.hMetaFile); *(mr->rdParam) = index; if (index >= mh->mtNoObjects) mh->mtNoObjects++; - rc = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2); - GlobalUnlock(mf->hMetaHdr); GlobalUnlock(dc->w.hMetaFile); - return rc; + handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2); + dc->w.hMetaFile = handle; + + return handle; } @@ -1030,7 +1126,7 @@ */ BOOL MF_TextOut(DC *dc, short x, short y, LPSTR str, short count) { - BOOL rc; + HMETAFILE handle; DWORD len; HANDLE hmr; METARECORD *mr; @@ -1047,9 +1143,10 @@ memcpy(mr->rdParam + 1, str, count); *(mr->rdParam + ((count + 1) >> 1) + 1) = y; *(mr->rdParam + ((count + 1) >> 1) + 2) = x; - rc = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2); + handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2); + dc->w.hMetaFile = handle; GlobalFree(hmr); - return rc; + return handle; } @@ -1058,7 +1155,7 @@ */ BOOL MF_MetaPoly(DC *dc, short func, LPPOINT pt, short count) { - BOOL rc; + HMETAFILE handle; DWORD len; HANDLE hmr; METARECORD *mr; @@ -1073,9 +1170,10 @@ mr->rdFunction = func; *(mr->rdParam) = count; memcpy(mr->rdParam + 1, pt, count * 4); - rc = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2); + handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2); + dc->w.hMetaFile = handle; GlobalFree(hmr); - return rc; + return handle; }
diff --git a/programs/progman/ChangeLog b/programs/progman/ChangeLog index 7688fe9..12efc7a 100644 --- a/programs/progman/ChangeLog +++ b/programs/progman/ChangeLog
@@ -1,3 +1,8 @@ +Sun Apr 14 20:09:19 1996 Pablo Saratxaga <srtxg@linux.chanae.stben.be> + + * [Fr.rc] (new) + Added French language support. + Sun Mar 24 12:28:22 1996 Ulrich Schmid <uschmid@mail.hh.provi.de> * [Strings_En.c] [Strings_De.c] (deleted)
diff --git a/programs/progman/Fr.rc b/programs/progman/Fr.rc new file mode 100644 index 0000000..251b5bd --- /dev/null +++ b/programs/progman/Fr.rc
@@ -0,0 +1,122 @@ +/* + * Program Manager + * + * Copyright 1996 Ulrich Schmid + * French Fr.rc by Pablo Saratxaga <srtxg@linux.chanae.stben.be> + */ + +#define LANGUAGE_ID Fr +#define LANGUAGE_NUMBER 4 +#define LANGUAGE_MENU_ITEM "&Français" + +/* Menu */ + +#define MENU_FILE "&Fichier" +#define MENU_FILE_NEW "&Nouveau..." +#define MENU_FILE_OPEN "O&uvrir\tEntrée" +#define MENU_FILE_MOVE "&Déplacer...\tF7" +#define MENU_FILE_COPY "&Copier...\tF8" +#define MENU_FILE_DELETE "&Supprimer\tSuppr" +#define MENU_FILE_ATTRIBUTES "&Propriétés...\tAlt+Entrée" +#define MENU_FILE_EXECUTE "E&xécuter..." +#define MENU_FILE_EXIT "&Quitter Windows..." + +#define MENU_OPTIONS "&Options" +#define MENU_OPTIONS_AUTO_ARRANGE "Réorg&anisation automatique" +#define MENU_OPTIONS_MIN_ON_RUN "&Réduire à l'utilisation" +#define MENU_OPTIONS_SAVE_SETTINGS "&Enregistrer la configuration en quittant" + +#define MENU_WINDOWS "F&enêtre" +#define MENU_WINDOWS_OVERLAP "&Cascade\tMaj+F5" +#define MENU_WINDOWS_SIDE_BY_SIDE "&Mosaïque\tMaj+F4" +#define MENU_WINDOWS_ARRANGE "&Réorganiser les icônes" + +#define MENU_LANGUAGE "&Langue" + +#define MENU_HELP "&?" +#define MENU_HELP_CONTENTS "&Index" +#define MENU_HELP_SEARCH "&Rechercher l'Aide sur..." +#define MENU_HELP_HELP_ON_HELP "&Utiliser l'Aide" +#define MENU_HELP_TUTORIAL "Didacticiel &Windows" + +#define MENU_INFO "&Info..." +#define MENU_INFO_LICENSE "&License" +#define MENU_INFO_NO_WARRANTY "&NO WARRANTY" +#define MENU_INFO_ABOUT_WINE "&A propos de WINE" + +/* Dialogs */ + +#define DIALOG_OK "OK" +#define DIALOG_CANCEL "Annuler" +#define DIALOG_BROWSE "Pa&rcourir..." +#define DIALOG_HELP "&Aide" + +#define DIALOG_NEW_CAPTION "Nouveau" +#define DIALOG_NEW_NEW "Nouveau" +#define DIALOG_NEW_GROUP "&Groupe de programmes" +#define DIALOG_NEW_PROGRAM "&Programme" + +#define DIALOG_MOVE_CAPTION "Déplacer un programme" +#define DIALOG_MOVE_PROGRAM "Déplacer le programme:" +#define DIALOG_MOVE_FROM_GROUP "A partir du groupe:" +#define DIALOG_MOVE_TO_GROUP "&Vers le groupe:" + +#define DIALOG_COPY_CAPTION "Copier un programme" +#define DIALOG_COPY_PROGRAM "Copier le programme:" +#define DIALOG_COPY_FROM_GROUP DIALOG_MOVE_FROM_GROUP +#define DIALOG_COPY_TO_GROUP DIALOG_MOVE_TO_GROUP + +#define DIALOG_GROUP_CAPTION "Propriétés de groupe" +#define DIALOG_GROUP_DESCRIPTION "&Nom:" +#define DIALOG_GROUP_FILE "&Fichier de groupe:" + +#define DIALOG_PROGRAM_CAPTION "Propriétés de programme" +#define DIALOG_PROGRAM_DESCRIPTION DIALOG_GROUP_DESCRIPTION +#define DIALOG_PROGRAM_COMMAND_LINE "&Ligne de commande:" +#define DIALOG_PROGRAM_DIRECTORY "Répertoire de tra&vail:" +#define DIALOG_PROGRAM_HOT_KEY "&Touche de raccourci:" +#define DIALOG_PROGRAM_SYMBOL "Réduire à l'&utilisation" +#define DIALOG_PROGRAM_OTHER_SYMBOL "&Changer d'icône..." + +#define DIALOG_SYMBOL_CAPTION "Changer d'icône" +#define DIALOG_SYMBOL_FILE "&Nom:" +#define DIALOG_SYMBOL_CURRENT "Icône a&ctuelle:" + +#define DIALOG_EXECUTE_CAPTION "Exécuter" +#define DIALOG_EXECUTE_COMMAND_LINE DIALOG_PROGRAM_COMMAND_LINE +#define DIALOG_EXECUTE_SYMBOL DIALOG_PROGRAM_SYMBOL + + +/* Strings */ + +#define STRING_PROGRAM_MANAGER "Gestionaire de programmes" +#define STRING_ERROR "ERREUR" +#define STRING_WARNING "WARNING" +#define STRING_INFO "Information" +#define STRING_DELETE "Supprimer" +#define STRING_DELETE_GROUP_s "Voulez-vous supprimer le groupe '%s'?" +#define STRING_DELETE_PROGRAM_s "Voulez-vous supprimer le programme '%s'?" +#define STRING_NOT_IMPLEMENTED "Non implementé" +#define STRING_FILE_READ_ERROR_s "Impossible d'ouvrir '%s'." +#define STRING_FILE_WRITE_ERROR_s "Impossible d'enregistrer '%s'." + +#define STRING_GRPFILE_READ_ERROR_s "\ +Impossible d'ouvrir le groupe '%s'.\n\ +Voulez-vous que le Gestionnaire de programmes essaie\n\ +de l'ouvrir dans les prochaines sessions?" + +#define STRING_OUT_OF_MEMORY "Mémoire insuffisante." +#define STRING_WINHELP_ERROR "Impossible d'afficher l'Aide." +#define STRING_UNKNOWN_FEATURE_s "Caracteristique inconnue dans %s" +#define STRING_FILE_NOT_OVERWRITTEN_s "Le fichier `%s' existe. Non écrasé." +#define STRING_SAVE_GROUP_AS_s "Groupe sauvé sous `%s' pour éviter l'écrasement du fichier original." + +#define STRING_NO_HOT_KEY "Aucun" + +#define STRING_ALL_FILES "Tout fichier (*.*)" +#define STRING_PROGRAMS "Programmes" +#define STRING_LIBRARIES_DLL "Bibliothèques (*.dll)" +#define STRING_SYMBOL_FILES "Icônes" +#define STRING_SYMBOLS_ICO "Icônes (*.ico)" + +#include "Xx.rc"
diff --git a/programs/progman/Makefile.in b/programs/progman/Makefile.in index ee8a900..37af394 100644 --- a/programs/progman/Makefile.in +++ b/programs/progman/Makefile.in
@@ -3,7 +3,7 @@ PROGRAMS = progman ALL_LIBS = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LDLIBS) -LANGUAGES = En De +LANGUAGES = En De Fr LICENSELANG = En MOSTOBJS = \
diff --git a/programs/progman/main.c b/programs/progman/main.c index 561fc27..1dd5e6d 100644 --- a/programs/progman/main.c +++ b/programs/progman/main.c
@@ -12,6 +12,10 @@ #include <resource.h> #include <options.h> #include <shell.h> +void LIBWINE_Register_accel(); +void LIBWINE_Register_De(); +void LIBWINE_Register_En(); +void LIBWINE_Register_Fr(); #endif GLOBALS Globals; @@ -39,6 +43,7 @@ LIBWINE_Register_accel(); LIBWINE_Register_De(); LIBWINE_Register_En(); + LIBWINE_Register_Fr(); #endif #ifndef WINELIB @@ -62,8 +67,8 @@ } #endif - /* Select Language (FIXME) */ -#ifndef WINELIB + /* Select Language */ +#ifdef WINELIB Globals.lpszLanguage = langNames[Options.language]; #else Globals.lpszLanguage = "En";
diff --git a/programs/progman/string.c b/programs/progman/string.c index cb6e160..f33941b 100644 --- a/programs/progman/string.c +++ b/programs/progman/string.c
@@ -120,8 +120,8 @@ if (Globals.hMainMenu) DestroyMenu(Globals.hMainMenu); Globals.hMainMenu = hMainMenu; -#ifndef WINELIB - /* Update system menus (FIXME) */ +#ifdef WINELIB + /* Update system menus */ for (i = 0; langNames[i] && lstrcmp(lang, langNames[i]);) i++; if (langNames[i]) Options.language = i;
diff --git a/resources/TODO b/resources/TODO index 31be6f5..eff85ce 100644 --- a/resources/TODO +++ b/resources/TODO
@@ -45,6 +45,7 @@ Today it works well for: * English * German +* French ...to be continued...... Thank you.
diff --git a/resources/sysres_Fr.rc b/resources/sysres_Fr.rc index 3a241bd..3df4265 100644 --- a/resources/sysres_Fr.rc +++ b/resources/sysres_Fr.rc
@@ -144,25 +144,37 @@ PUSHBUTTON "Annuler", 2, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP } - -CHOOSE_COLOR DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 200 +CHOOSE_COLOR DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 300, 200 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Couleurs" FONT 8, "Helv" { - LTEXT "Couleurs de &base:", 1088, 6, 6, 40, 9 - LTEXT "%Couleurs personnalisées:", 1089, 6, 126, 40, 9 - LTEXT "Couleur|&Uni", 1090, 100, 146, 40, 9 - LTEXT "&Couleur:", 1091, 150, 126, 40, 9 - LTEXT "&Sat. :", 1092, 150, 146, 40, 9 - LTEXT "&Lum. :", 1093, 150, 166, 40, 9 - LTEXT "&Rouge:", 1094, 150, 126, 40, 9 - LTEXT "&Vert:", 1095, 150, 146, 40, 9 - LTEXT "&Bleu:", 1096, 150, 166, 40, 9 - DEFPUSHBUTTON "OK", 1, 6, 182, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Ajouter la couleur", 1024, 120, 182, 100, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Supprimer la couleur", 1025, 6, 164, 56, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "Annuler", 2, 76, 182, 56, 14, WS_GROUP | WS_TABSTOP + LTEXT "Couleurs de &base:", 1088, 4, 4, 140, 10 + LTEXT "&Couleurs personnalisés:", 1089, 4, 106, 140, 10 + LTEXT "Couleur | &Uni", 1090, 150, 151, 48, 10 + LTEXT "&Rouge:", 726 /*1094*/,249,126,24,10 + EDITTEXT 706, 275,124,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP + LTEXT "&Vert:",727/*1095*/,249,140,24,10 + EDITTEXT 707, 275,138,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP + LTEXT "Bl&eu:",728 /*1096*/,249,154,24,10 + EDITTEXT 708, 275,152,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP + LTEXT "&Teinte:" ,723 /*1091*/,202,126,22,10 + EDITTEXT 703, 226,124,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP + LTEXT "&Sat.:" ,724 /*1092*/,202,140,22,10 + EDITTEXT 704, 226,138,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP + LTEXT "&Lum.:" ,725 /*1093*/,202,154,22,10 + EDITTEXT 705, 226,152,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP + CONTROL "" ,720,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP,4,14,140,86 + CONTROL "" ,721,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP,4,116,140,28 + CONTROL "" ,710,"STATIC",WS_BORDER|SS_SIMPLE|WS_TABSTOP|WS_GROUP, 152,4,118,116 CONTROL "" ,702,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP, 278,4,8,116 + CONTROL "" ,702,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP, 278,4,8,116 + CONTROL "" ,709,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP, 152,124,40,26 + DEFPUSHBUTTON "Ok", 1, 4, 166, 44, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP + PUSHBUTTON "Annuler", 2, 52, 166, 44, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Aide", 1038,100,166, 44, 14 + PUSHBUTTON "&Ajouter couleur personnalisées", 712/*1024*/, 152, 166, 142, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Definir couleurs personnalisées >>", 719/*1025*/, 4, 150, 142, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&i",713,300,200,4,14 /* just a dummy: 'i' is like &i in "sol&id" */ } FIND_TEXT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 236, 62
diff --git a/resources/sysres_It.rc b/resources/sysres_It.rc index 91ba456..5fab00a 100644 --- a/resources/sysres_It.rc +++ b/resources/sysres_It.rc
@@ -143,28 +143,39 @@ PUSHBUTTON "Annulla", 2, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP } - -CHOOSE_COLOR DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 200 +CHOOSE_COLOR DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 300, 200 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Colore" FONT 8, "Helv" { - LTEXT "Colori di &Base:", 1088, 6, 6, 40, 9 - LTEXT "Colori &Utente:", 1089, 6, 126, 40, 9 - LTEXT "Colore|Sol&ido", 1090, 100, 146, 40, 9 - LTEXT "&Tinta:", 1091, 150, 126, 40, 9 - LTEXT "&Sat:", 1092, 150, 146, 40, 9 - LTEXT "&Lum:", 1093, 150, 166, 40, 9 - LTEXT "&Rosso:", 1094, 150, 126, 40, 9 - LTEXT "&Verde:", 1095, 150, 146, 40, 9 - LTEXT "Bl&u:", 1096, 150, 166, 40, 9 - DEFPUSHBUTTON "Ok", 1, 6, 182, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Aggiungi ai Colori Utente", 1024, 120, 182, 100, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "&Cancella Colori Utente", 1025, 6, 164, 56, 14, WS_GROUP | WS_TABSTOP - PUSHBUTTON "Annulla", 2, 76, 182, 56, 14, WS_GROUP | WS_TABSTOP + LTEXT "Colori di &Base:", 1088, 4, 4, 140, 10 + LTEXT "Colori &Utente:", 1089, 4, 106, 140, 10 + LTEXT "Colore | Sol&ido", 1090, 150, 151, 48, 10 + LTEXT "&Rosso:", 726 /*1094*/,249,126,24,10 + EDITTEXT 706, 275,124,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP + LTEXT "&Verde:",727/*1095*/,249,140,24,10 + EDITTEXT 707, 275,138,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP + LTEXT "&Blu:",728 /*1096*/,249,154,24,10 + EDITTEXT 708, 275,152,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP + LTEXT "&Tinta:" ,723 /*1091*/,202,126,22,10 + EDITTEXT 703, 226,124,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP + LTEXT "&Sat:" ,724 /*1092*/,202,140,22,10 + EDITTEXT 704, 226,138,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP + LTEXT "&Lum:" ,725 /*1093*/,202,154,22,10 + EDITTEXT 705, 226,152,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP + CONTROL "" ,720,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP,4,14,140,86 + CONTROL "" ,721,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP,4,116,140,28 + CONTROL "" ,710,"STATIC",WS_BORDER|SS_SIMPLE|WS_TABSTOP|WS_GROUP, 152,4,118,116 + CONTROL "" ,702,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP, 278,4,8,116 + CONTROL "" ,709,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP, 152,124,40,26 + DEFPUSHBUTTON "Ok", 1, 4, 166, 44, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP + PUSHBUTTON "Annulla", 2, 52, 166, 44, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "Aiuto", 1038,100,166, 44, 14 + PUSHBUTTON "&Aggiungi ai Colori Utente", 712/*1024*/, 152, 166, 142, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&Definisci Colori Utente >>", 719/*1025*/, 4, 150, 142, 14, WS_GROUP | WS_TABSTOP + PUSHBUTTON "&i",713,300,200,4,14 /* just a dummy: 'i' is like &i in "sol&id" */ } - FIND_TEXT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 236, 62 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Trova"
diff --git a/windows/defwnd.c b/windows/defwnd.c index 5eccbf4..f84bdda 100644 --- a/windows/defwnd.c +++ b/windows/defwnd.c
@@ -141,18 +141,14 @@ case WM_WINDOWPOSCHANGED: { - /* Note: Windoze uses unknown SWP flags 0x1000 and 0x0800 to - * decide whether to send WM_MOVE or/and WM_SIZE respectively - */ - WINDOWPOS * winPos = (WINDOWPOS *)PTR_SEG_TO_LIN(lParam); WPARAM wp = SIZE_RESTORED; - if (!(winPos->flags & SWP_NOMOVE)) + if (!(winPos->flags & SWP_NOCLIENTMOVE)) SendMessage( hwnd, WM_MOVE, 0, MAKELONG( wndPtr->rectClient.left, wndPtr->rectClient.top )); - if (!(winPos->flags & SWP_NOSIZE)) + if (!(winPos->flags & SWP_NOCLIENTSIZE)) { if( wndPtr->dwStyle & WS_MAXIMIZE ) wp = SIZE_MAXIMIZED; else if(wndPtr->dwStyle & WS_MINIMIZE ) wp = SIZE_MINIMIZED;
diff --git a/windows/mdi.c b/windows/mdi.c index a22d1de..1a533f8 100644 --- a/windows/mdi.c +++ b/windows/mdi.c
@@ -12,8 +12,6 @@ * SetWindowPos(childHwnd,...) implicitly calls it if SWP_NOACTIVATE * is not used. * - * To fix: - * Sticky client crollbars */ #include <stdlib.h> @@ -32,6 +30,10 @@ #include "stddebug.h" #include "debug.h" + +DWORD SCROLL_SetNCSbState(WND*,int,int,int,int,int,int); + +/* ----------------- declarations ----------------- */ void MDI_UpdateFrameText(WND *, HWND, BOOL, LPCSTR); BOOL MDI_AugmentFrameMenu(MDICLIENTINFO*, WND *, HWND); BOOL MDI_RestoreFrameMenu(WND *, HWND); @@ -39,8 +41,6 @@ void ScrollChildren(HWND , UINT , WPARAM , LPARAM ); void CalcChildScroll(HWND, WORD); -/* ----------------- declarations ----------------- */ - static LONG MDI_ChildActivate(WND* ,HWND ); /* -------- Miscellaneous service functions ---------- @@ -55,6 +55,16 @@ return 0; } +static void MDI_PostUpdate(HWND hwnd, MDICLIENTINFO* ci, WORD recalc) +{ + if( !ci->sbNeedUpdate ) + { + ci->sbNeedUpdate = TRUE; + PostMessage( hwnd, WM_MDICALCCHILDSCROLL, 0, 0); + } + ci->sbRecalc = recalc; +} + /********************************************************************** * MDI_MenuAppendItem */ @@ -427,9 +437,8 @@ if (flagDestroy) { + MDI_PostUpdate(GetParent(child), ci, SB_BOTH+1); DestroyWindow(child); - PostMessage(parent,WM_MDICALCCHILDSCROLL,0,0L); - ci->sbRecalc |= (SB_BOTH+1); } } @@ -808,9 +817,8 @@ child->dwStyle &= ~WS_SYSMENU; - /* redraw frame */ - SetWindowPos(frame->hwndSelf, 0,0,0,0,0, SWP_FRAMECHANGED | SWP_NOSIZE | - SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER ); + /* redraw menu */ + DrawMenuBar(frame->hwndSelf); return 1; } @@ -837,9 +845,8 @@ RemoveMenu(frameWnd->wIDmenu,0,MF_BYPOSITION); DeleteMenu(frameWnd->wIDmenu,nItems-1,MF_BYPOSITION); - /* redraw frame */ - SetWindowPos(hChild, 0,0,0,0,0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE | - SWP_NOACTIVATE | SWP_NOZORDER ); + DrawMenuBar(frameWnd->hwndSelf); + return 1; } @@ -962,7 +969,7 @@ ci->flagChildMaximized = 0; ci->nActiveChildren = 0; ci->hFrameTitle = frameWnd->hText; - ci->sbStop = 0; + ci->sbNeedUpdate = 0; ci->self = hwnd; ci->obmClose = CreateMDIMenuBitmap(); ci->obmRestore = LoadBitmap(0, MAKEINTRESOURCE(OBM_RESTORE)); @@ -1014,11 +1021,11 @@ ((LONG) (ci->flagChildMaximized>0) << 16)); case WM_MDIICONARRANGE: - ci->sbStop = TRUE; - MDIIconArrange(hwnd); - ci->sbStop = FALSE; - SendMessage(hwnd,WM_MDICALCCHILDSCROLL,0,0L); - return 0; + ci->sbNeedUpdate = TRUE; + MDIIconArrange(hwnd); + ci->sbRecalc = SB_BOTH+1; + SendMessage(hwnd,WM_MDICALCCHILDSCROLL,0,0L); + return 0; case WM_MDIMAXIMIZE: ShowWindow((HWND)wParam, SW_MAXIMIZE); @@ -1040,17 +1047,17 @@ #endif case WM_MDITILE: - ci->sbStop = TRUE; + ci->sbNeedUpdate = TRUE; ShowScrollBar(hwnd,SB_BOTH,FALSE); MDITile(hwnd, ci,wParam); - ci->sbStop = FALSE; + ci->sbNeedUpdate = FALSE; return 0; case WM_VSCROLL: case WM_HSCROLL: - ci->sbStop = TRUE; + ci->sbNeedUpdate = TRUE; ScrollChildren(hwnd,message,wParam,lParam); - ci->sbStop = FALSE; + ci->sbNeedUpdate = FALSE; return 0; case WM_SETFOCUS: @@ -1099,18 +1106,16 @@ rect.right - rect.left, rect.bottom - rect.top, 1); } else - { - PostMessage(hwnd,WM_MDICALCCHILDSCROLL,0,0L); - ci->sbRecalc |= (SB_BOTH+1); - } + MDI_PostUpdate(hwnd, ci, SB_BOTH+1); + break; case WM_MDICALCCHILDSCROLL: - if( !ci->sbStop ) + if( ci->sbNeedUpdate ) if( ci->sbRecalc ) { CalcChildScroll(hwnd, ci->sbRecalc-1); - ci->sbRecalc = 0; + ci->sbRecalc = ci->sbNeedUpdate = 0; } return 0; } @@ -1256,11 +1261,10 @@ return 0; case WM_SETVISIBLE: - if( !ci->sbStop && !ci->flagChildMaximized) - { - PostMessage(ci->self,WM_MDICALCCHILDSCROLL,0,0L); - ci->sbRecalc |= (SB_BOTH+1); - } + if( ci->flagChildMaximized) + ci->sbNeedUpdate = 0; + else + MDI_PostUpdate(clientWnd->hwndSelf, ci, SB_BOTH+1); break; case WM_SIZE: @@ -1305,12 +1309,8 @@ if( switchTo ) SendMessage( switchTo, WM_CHILDACTIVATE, 0, 0L); } - - if( !ci->sbStop ) - { - PostMessage(ci->self,WM_MDICALCCHILDSCROLL,0,0L); - ci->sbRecalc |= (SB_BOTH+1); - } + + MDI_PostUpdate(clientWnd->hwndSelf, ci, SB_BOTH+1); break; case WM_MENUCHAR: @@ -1379,27 +1379,47 @@ void CalcChildScroll( HWND hwnd, WORD scroll ) { RECT childRect, clientRect; - WND *pWnd; + INT vmin, vmax, hmin, hmax, vpos, hpos; + BOOL noscroll = FALSE; + WND *pWnd, *Wnd; - if (!(pWnd = WIN_FindWndPtr( hwnd ))) return; + if (!(Wnd = pWnd = WIN_FindWndPtr( hwnd ))) return; GetClientRect( hwnd, &clientRect ); SetRectEmpty( &childRect ); - for (pWnd = pWnd->child; pWnd; pWnd = pWnd->next) - UnionRect( &childRect, &pWnd->rectWindow, &childRect ); + + for ( pWnd = pWnd->child; pWnd; pWnd = pWnd->next ) + { + UnionRect( &childRect, &pWnd->rectWindow, &childRect ); + if( pWnd->dwStyle & WS_MAXIMIZE ) + noscroll = TRUE; + } UnionRect( &childRect, &clientRect, &childRect ); - if ((scroll == SB_HORZ) || (scroll == SB_BOTH)) - { - SetScrollRange( hwnd, SB_HORZ, childRect.left, - childRect.right - clientRect.right, FALSE ); - SetScrollPos( hwnd, SB_HORZ, clientRect.left - childRect.left, TRUE ); - } - if ((scroll == SB_VERT) || (scroll == SB_BOTH)) - { - SetScrollRange( hwnd, SB_VERT, childRect.top, - childRect.bottom - clientRect.bottom, FALSE ); - SetScrollPos( hwnd, SB_HORZ, clientRect.top - childRect.top, TRUE ); - } + /* jump through the hoops to prevent excessive flashing + */ + + hmin = childRect.left; hmax = childRect.right - clientRect.right; + hpos = clientRect.left - childRect.left; + vmin = childRect.top; vmax = childRect.bottom - clientRect.bottom; + vpos = clientRect.top - childRect.top; + + if( noscroll ) + ShowScrollBar(hwnd, SB_BOTH, FALSE); + else + switch( scroll ) + { + case SB_HORZ: + vpos = hpos; vmin = hmin; vmax = hmax; + case SB_VERT: + SetScrollPos(hwnd, scroll, vpos, FALSE); + SetScrollRange(hwnd, scroll, vmin, vmax, TRUE); + break; + case SB_BOTH: + SCROLL_SetNCSbState( Wnd, vmin, vmax, vpos, + hmin, hmax, hpos); + SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE + | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED ); + } } /***********************************************************************
diff --git a/windows/message.c b/windows/message.c index d1ac195..78942bc 100644 --- a/windows/message.c +++ b/windows/message.c
@@ -201,6 +201,9 @@ MESSAGEQUEUE *sysMsgQueue = QUEUE_GetSysQueue(); int i, pos = sysMsgQueue->nextMessage; + /* If the queue is empty, attempt to fill it */ + if (!sysMsgQueue->msgCount && XPending(display)) MSG_WaitXEvent( 0 ); + for (i = 0; i < sysMsgQueue->msgCount; i++, pos++) { if (pos >= sysMsgQueue->queueSize) pos = 0; @@ -362,11 +365,11 @@ { #ifdef CONFIG_IPC - if (DDE_GetRemoteMessage()) + if (DDE_GetRemoteMessage()) { - while(DDE_GetRemoteMessage()) ; - return TRUE; - } + while(DDE_GetRemoteMessage()) ; + return TRUE; + } #endif /* CONFIG_IPC */ XNextEvent( display, &event );
diff --git a/windows/painting.c b/windows/painting.c index e8ce1bb..31573ff 100644 --- a/windows/painting.c +++ b/windows/painting.c
@@ -23,13 +23,13 @@ */ void WIN_UpdateNCArea(WND* wnd, BOOL bUpdate) { - RECT rect = wnd->rectClient; + POINT pt = {0, 0}; HRGN hClip = 1; dprintf_nonclient(stddeb,"NCUpdate: hwnd %04x, hrgnUpdate %04x\n", wnd->hwndSelf, wnd->hrgnUpdate ); - /* desktop windows doesn't have nonclient area */ + /* desktop window doesn't have nonclient area */ if(wnd == WIN_GetDesktop()) { wnd->flags &= ~WIN_NEEDS_NCPAINT; @@ -38,7 +38,7 @@ if( wnd->hrgnUpdate > 1 ) { - MapWindowPoints(wnd->parent->hwndSelf, 0, (POINT*)&rect, 2); + ClientToScreen(wnd->hwndSelf, &pt); hClip = CreateRectRgn( 0, 0, 0, 0 ); if (!CombineRgn(hClip, wnd->hrgnUpdate, 0, RGN_COPY) ) @@ -46,16 +46,22 @@ DeleteObject(hClip); hClip = 1; } + else + OffsetRgn(hClip, pt.x, pt.y); if (bUpdate) { - HRGN hrgn = CreateRectRgnIndirect(&rect); + /* exclude non-client area from update region */ + HRGN hrgn = CreateRectRgn(0, 0, wnd->rectClient.right - wnd->rectClient.left, + wnd->rectClient.bottom - wnd->rectClient.top); + if (hrgn && (CombineRgn(wnd->hrgnUpdate, wnd->hrgnUpdate, hrgn, RGN_AND) == NULLREGION)) { DeleteObject(wnd->hrgnUpdate); wnd->hrgnUpdate = 1; } + DeleteObject( hrgn ); } } @@ -204,19 +210,21 @@ } else { - dprintf_win( stddeb, "RedrawWindow: %04x NULL %04x flags=%04x\n", + dprintf_win(stddeb, "RedrawWindow: %04x NULL %04x flags=%04x\n", hwnd, hrgnUpdate, flags); } GetClientRect( hwnd, &rectClient ); if (flags & RDW_INVALIDATE) /* Invalidate */ { - if (wndPtr->hrgnUpdate) /* Is there already an update region? */ + int rgnNotEmpty = COMPLEXREGION; + + if (wndPtr->hrgnUpdate > 1) /* Is there already an update region? */ { if ((hrgn = hrgnUpdate) == 0) hrgn = CreateRectRgnIndirect( rectUpdate ? rectUpdate : &rectClient ); - CombineRgn( wndPtr->hrgnUpdate, wndPtr->hrgnUpdate, hrgn, RGN_OR ); + rgnNotEmpty = CombineRgn( wndPtr->hrgnUpdate, wndPtr->hrgnUpdate, hrgn, RGN_OR ); if (!hrgnUpdate) DeleteObject( hrgn ); } else /* No update region yet */ @@ -226,19 +234,31 @@ if (hrgnUpdate) { wndPtr->hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 ); - CombineRgn( wndPtr->hrgnUpdate, hrgnUpdate, 0, RGN_COPY ); + rgnNotEmpty = CombineRgn( wndPtr->hrgnUpdate, hrgnUpdate, 0, RGN_COPY ); } else wndPtr->hrgnUpdate = CreateRectRgnIndirect( rectUpdate ? rectUpdate : &rectClient ); } + if (flags & RDW_FRAME) wndPtr->flags |= WIN_NEEDS_NCPAINT; - if (flags & RDW_ERASE) wndPtr->flags |= WIN_NEEDS_ERASEBKGND; + + /* check for bogus update region */ + if ( rgnNotEmpty == NULLREGION ) + { + wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND; + DeleteObject(wndPtr->hrgnUpdate); + wndPtr->hrgnUpdate=0; + if (!(wndPtr->flags & WIN_INTERNAL_PAINT)) + QUEUE_DecPaintCount( wndPtr->hmemTaskQ ); + } + else + if (flags & RDW_ERASE) wndPtr->flags |= WIN_NEEDS_ERASEBKGND; flags |= RDW_FRAME; /* Force invalidating the frame of children */ } else if (flags & RDW_VALIDATE) /* Validate */ { /* We need an update region in order to validate anything */ - if (wndPtr->hrgnUpdate) + if (wndPtr->hrgnUpdate > 1) { if (!hrgnUpdate && !rectUpdate) { @@ -270,13 +290,13 @@ if (flags & RDW_INTERNALPAINT) { - if (!wndPtr->hrgnUpdate && !(wndPtr->flags & WIN_INTERNAL_PAINT)) + if ( wndPtr->hrgnUpdate <= 1 && !(wndPtr->flags & WIN_INTERNAL_PAINT)) QUEUE_IncPaintCount( wndPtr->hmemTaskQ ); wndPtr->flags |= WIN_INTERNAL_PAINT; } else if (flags & RDW_NOINTERNALPAINT) { - if (!wndPtr->hrgnUpdate && (wndPtr->flags & WIN_INTERNAL_PAINT)) + if ( wndPtr->hrgnUpdate <= 1 && (wndPtr->flags & WIN_INTERNAL_PAINT)) QUEUE_DecPaintCount( wndPtr->hmemTaskQ ); wndPtr->flags &= ~WIN_INTERNAL_PAINT; } @@ -401,7 +421,7 @@ if (rect) { - if (wndPtr->hrgnUpdate) + if (wndPtr->hrgnUpdate > 1) { HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 ); if (GetUpdateRgn( hwnd, hrgn, erase ) == ERROR) return FALSE; @@ -410,7 +430,7 @@ } else SetRectEmpty( rect ); } - return (wndPtr->hrgnUpdate != 0); + return (wndPtr->hrgnUpdate > 1); } @@ -423,7 +443,7 @@ WND * wndPtr = WIN_FindWndPtr( hwnd ); if (!wndPtr) return ERROR; - if (!wndPtr->hrgnUpdate) + if (wndPtr->hrgnUpdate <= 1) { SetRectRgn( hrgn, 0, 0, 0, 0 ); return NULLREGION; @@ -447,7 +467,8 @@ if ((hrgn = CreateRectRgn( 0, 0, 0, 0 )) != 0) { retval = CombineRgn( hrgn, InquireVisRgn(hdc), - wndPtr->hrgnUpdate, RGN_DIFF ); + (wndPtr->hrgnUpdate>1)?wndPtr->hrgnUpdate:0, + (wndPtr->hrgnUpdate>1)?RGN_DIFF:RGN_COPY); if (retval) SelectVisRgn( hdc, hrgn ); DeleteObject( hrgn ); }
diff --git a/windows/winpos.c b/windows/winpos.c index 524f285..09ad76a 100644 --- a/windows/winpos.c +++ b/windows/winpos.c
@@ -20,16 +20,18 @@ /* #define DEBUG_WIN */ #include "debug.h" +#define SWP_NOPOSCHANGE (SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE) + /* ----- external functions ----- */ void FOCUS_SwitchFocus( HWND , HWND ); +HRGN DCE_GetVisRgn( HWND, WORD ); /* ----- internal variables ----- */ static HWND hwndActive = 0; /* Currently active window */ static HWND hwndPrevActive = 0; /* Previously active window */ - /*********************************************************************** * WINPOS_FindIconPos * @@ -424,6 +426,7 @@ switch(cmd) { case SW_HIDE: + if (!wasVisible) return FALSE; swpflags |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER; break; @@ -1040,6 +1043,129 @@ return hwndInsertAfter; } +/*********************************************************************** + * WINPOS_SizeMoveClean + * + * Make window look nice without excessive repainting + * + * the pain: + * + * visible regions are in window coordinates + * update regions are in window client coordinates + * client and window rectangles are in parent client coordinates + */ +static void WINPOS_SizeMoveClean(WND* Wnd, HRGN oldVisRgn, LPRECT lpOldWndRect, LPRECT lpOldClientRect, BOOL bNoCopy ) +{ + /* visible regions are in window coordinates */ + + HRGN newVisRgn = DCE_GetVisRgn(Wnd->hwndSelf, DCX_WINDOW | DCX_CLIPSIBLINGS ); + HRGN dirtyRgn = CreateRectRgn(0,0,0,0); + int other, my; + + dprintf_win(stddeb,"cleaning up...new wnd=(%i %i-%i %i) old wnd=(%i %i-%i %i)\n\ +\t\tnew client=(%i %i-%i %i) old client=(%i %i-%i %i)\n", + Wnd->rectWindow.left, Wnd->rectWindow.top, Wnd->rectWindow.right, Wnd->rectWindow.bottom, + lpOldWndRect->left, lpOldWndRect->top, lpOldWndRect->right, lpOldWndRect->bottom, + Wnd->rectClient.left,Wnd->rectClient.top,Wnd->rectClient.right,Wnd->rectClient.bottom, + lpOldClientRect->left,lpOldClientRect->top,lpOldClientRect->right,lpOldClientRect->bottom); + + CombineRgn( dirtyRgn, newVisRgn, 0, RGN_COPY); + + if( !bNoCopy ) + { + HRGN hRgn = CreateRectRgn( lpOldClientRect->left - lpOldWndRect->left, lpOldClientRect->top - lpOldWndRect->top, + lpOldClientRect->right - lpOldWndRect->left, lpOldClientRect->bottom - lpOldWndRect->top); + CombineRgn( newVisRgn, newVisRgn, oldVisRgn, RGN_AND ); + CombineRgn( newVisRgn, newVisRgn, hRgn, RGN_AND ); + DeleteObject(hRgn); + } + + /* map regions to the parent client area */ + + OffsetRgn(dirtyRgn, Wnd->rectWindow.left, Wnd->rectWindow.top); + OffsetRgn(oldVisRgn, lpOldWndRect->left, lpOldWndRect->top); + + /* compute invalidated region outside Wnd - (in client coordinates of the parent window) */ + + other = CombineRgn(dirtyRgn, oldVisRgn, dirtyRgn, RGN_DIFF); + + /* map visible region to the Wnd client area */ + + OffsetRgn( newVisRgn, Wnd->rectWindow.left - Wnd->rectClient.left, + Wnd->rectWindow.top - Wnd->rectClient.top ); + + /* substract previously invalidated region from the Wnd visible region */ + + my = (Wnd->hrgnUpdate > 1)? CombineRgn( newVisRgn, newVisRgn, Wnd->hrgnUpdate, RGN_DIFF) + : COMPLEXREGION; + + if( bNoCopy ) /* invalidate Wnd visible region */ + { + if (my != NULLREGION) RedrawWindow( Wnd->hwndSelf, NULL, newVisRgn, RDW_INVALIDATE | + RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE ); + } + else /* bitblt old client area */ + { + HDC hDC; + int update; + HRGN updateRgn; + + /* client rect */ + + updateRgn = CreateRectRgn( 0,0, Wnd->rectClient.right - Wnd->rectClient.left, + Wnd->rectClient.bottom - Wnd->rectClient.top ); + + /* clip visible region with client rect */ + + my = CombineRgn( newVisRgn, newVisRgn, updateRgn, RGN_AND ); + + /* substract result from client rect to get region that won't be copied */ + + update = CombineRgn( updateRgn, updateRgn, newVisRgn, RGN_DIFF ); + + /* Blt valid bits using parent window DC */ + + if( my != NULLREGION ) + { + int xfrom = lpOldClientRect->left; + int yfrom = lpOldClientRect->top; + int xto = Wnd->rectClient.left; + int yto = Wnd->rectClient.top; + + /* check if we can skip copying */ + + if( xfrom != xto || yfrom != yto ) + { + /* compute clipping region in parent client coordinates */ + + OffsetRgn( newVisRgn, Wnd->rectClient.left, Wnd->rectClient.top); + CombineRgn( oldVisRgn, oldVisRgn, newVisRgn, RGN_OR ); + + hDC = GetDCEx( Wnd->parent->hwndSelf, oldVisRgn, DCX_INTERSECTRGN | DCX_CACHE | DCX_CLIPSIBLINGS); + + BitBlt(hDC, xto, yto, lpOldClientRect->right - lpOldClientRect->left + 1, + lpOldClientRect->bottom - lpOldClientRect->top + 1, + hDC, xfrom, yfrom, SRCCOPY ); + + ReleaseDC( Wnd->parent->hwndSelf, hDC); + } + } + + if( update != NULLREGION ) + RedrawWindow( Wnd->hwndSelf, NULL, updateRgn, RDW_INVALIDATE | + RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE ); + DeleteObject( updateRgn ); + } + + /* erase uncovered areas */ + + if( other != NULLREGION ) + RedrawWindow( Wnd->parent->hwndSelf, NULL, dirtyRgn, + RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE ); + + DeleteObject(dirtyRgn); + DeleteObject(newVisRgn); +} /*********************************************************************** * WINPOS_SetXWindowPos @@ -1088,10 +1214,13 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y, INT cx, INT cy, WORD flags ) { - WINDOWPOS winpos; - WND *wndPtr; - RECT newWindowRect, newClientRect; - int result; + WINDOWPOS winpos; + WND * wndPtr; + RECT newWindowRect, newClientRect; + HRGN visRgn = 0; + int result = 0; + + dprintf_win(stddeb,"SetWindowPos: hwnd %04x, flags %08x\n", hwnd, flags); /* Check window handle */ @@ -1130,10 +1259,19 @@ /* TOPMOST not supported yet */ if ((hwndInsertAfter == HWND_TOPMOST) || (hwndInsertAfter == HWND_NOTOPMOST)) hwndInsertAfter = HWND_TOP; + /* hwndInsertAfter must be a sibling of the window */ - if ((hwndInsertAfter != HWND_TOP) && (hwndInsertAfter != HWND_BOTTOM) && - (wndPtr->parent != WIN_FindWndPtr(hwndInsertAfter)->parent)) - return FALSE; + if ((hwndInsertAfter != HWND_TOP) && (hwndInsertAfter != HWND_BOTTOM)) + { + WND* wnd = WIN_FindWndPtr(hwndInsertAfter); + if( wnd->parent != wndPtr->parent ) return FALSE; + if( wnd->next == wndPtr ) flags |= SWP_NOZORDER; + } + else + if (hwndInsertAfter == HWND_TOP) + flags |= ( wndPtr->parent->child == wndPtr)? SWP_NOZORDER: 0; + else /* HWND_BOTTOM */ + flags |= ( wndPtr->next )? 0: SWP_NOZORDER; /* Fill the WINDOWPOS structure */ @@ -1166,8 +1304,13 @@ newWindowRect.top = winpos.y; newWindowRect.right += winpos.x - wndPtr->rectWindow.left; newWindowRect.bottom += winpos.y - wndPtr->rectWindow.top; + + OffsetRect(&newClientRect, winpos.x - wndPtr->rectWindow.left, + winpos.y - wndPtr->rectWindow.top ); } + winpos.flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE; + /* Reposition window in Z order */ if (!(winpos.flags & SWP_NOZORDER)) @@ -1186,17 +1329,42 @@ else WINPOS_MoveWindowZOrder( winpos.hwnd, hwndInsertAfter ); } - /* Send WM_NCCALCSIZE message to get new client area */ + if ( !wndPtr->window && !(flags & SWP_NOREDRAW) && + (!(flags & SWP_NOMOVE) || !(flags & SWP_NOSIZE) || (flags & SWP_FRAMECHANGED)) ) + visRgn = DCE_GetVisRgn(hwnd, DCX_WINDOW | DCX_CLIPSIBLINGS); - result = WINPOS_SendNCCalcSize( winpos.hwnd, TRUE, &newWindowRect, + + /* Send WM_NCCALCSIZE message to get new client area */ + if( (flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE ) + { + result = WINPOS_SendNCCalcSize( winpos.hwnd, TRUE, &newWindowRect, &wndPtr->rectWindow, &wndPtr->rectClient, &winpos, &newClientRect ); - /* FIXME: Should handle result here */ + + /* FIXME: WVR_ALIGNxxx */ + + if( newClientRect.left != wndPtr->rectClient.left || + newClientRect.top != wndPtr->rectClient.top ) + winpos.flags &= ~SWP_NOCLIENTMOVE; + + if( (newClientRect.right - newClientRect.left != + wndPtr->rectClient.right - wndPtr->rectClient.left) || + (newClientRect.bottom - newClientRect.top != + wndPtr->rectClient.bottom - wndPtr->rectClient.top) ) + winpos.flags &= ~SWP_NOCLIENTSIZE; + } + else + if( !(flags & SWP_NOMOVE) && (newClientRect.left != wndPtr->rectClient.left || + newClientRect.top != wndPtr->rectClient.top) ) + winpos.flags &= ~SWP_NOCLIENTMOVE; /* Perform the moving and resizing */ if (wndPtr->window) { + RECT oldWindowRect = wndPtr->rectWindow; + RECT oldClientRect = wndPtr->rectClient; + HWND bogusInsertAfter = winpos.hwndInsertAfter; winpos.hwndInsertAfter = hwndInsertAfter; @@ -1205,44 +1373,66 @@ wndPtr->rectWindow = newWindowRect; wndPtr->rectClient = newClientRect; winpos.hwndInsertAfter = bogusInsertAfter; + + /* FIXME: should do something like WINPOS_SizeMoveClean */ + + if( (oldClientRect.left - oldWindowRect.left != + newClientRect.left - newWindowRect.left) || + (oldClientRect.top - oldWindowRect.top != + newClientRect.top - newWindowRect.top) ) + + RedrawWindow(wndPtr->hwndSelf, NULL, 0, RDW_ALLCHILDREN | RDW_FRAME | RDW_ERASE); + else + if( winpos.flags & SWP_FRAMECHANGED ) + { + WORD wErase = 0; + RECT rect; + + if( oldClientRect.right > newClientRect.right ) + { + rect.left = newClientRect.right; rect.top = newClientRect.top; + rect.right = oldClientRect.right; rect.bottom = newClientRect.bottom; + wErase = 1; + RedrawWindow(wndPtr->hwndSelf, &rect, 0, RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); + } + if( oldClientRect.bottom > newClientRect.bottom ) + { + rect.left = newClientRect.left; rect.top = newClientRect.bottom; + rect.right = (wErase)?oldClientRect.right:newClientRect.right; + rect.bottom = oldClientRect.bottom; + wErase = 1; + RedrawWindow(wndPtr->hwndSelf, &rect, 0, RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); + } + + if( !wErase ) wndPtr->flags |= WIN_NEEDS_NCPAINT; + } } else { RECT oldWindowRect = wndPtr->rectWindow; + RECT oldClientRect = wndPtr->rectClient; wndPtr->rectWindow = newWindowRect; wndPtr->rectClient = newClientRect; - if (!(flags & SWP_NOREDRAW) && - (!(flags & SWP_NOSIZE) || !(flags & SWP_NOMOVE) || - (!(flags & SWP_NOZORDER) && (hwndInsertAfter != HWND_TOP)))) - { - HRGN hrgn1 = CreateRectRgnIndirect( &oldWindowRect ); - HRGN hrgn2 = CreateRectRgnIndirect( &wndPtr->rectWindow ); - HRGN hrgn3 = CreateRectRgn( 0, 0, 0, 0 ); - CombineRgn( hrgn3, hrgn1, hrgn2, RGN_DIFF ); - RedrawWindow( wndPtr->parent->hwndSelf, NULL, hrgn3, - RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE ); + if( !(flags & SWP_NOREDRAW) ) + { + BOOL bNoCopy = (flags & SWP_NOCOPYBITS) || + (result >= WVR_HREDRAW && result < WVR_VALIDRECTS); - /* DCE_GetVisRgn should be called for old coordinates - * and for new, then OffsetRgn and CombineRgn - - * voila, a nice update region to use here - AK. - */ - if ((oldWindowRect.left != wndPtr->rectWindow.left) || - (oldWindowRect.top != wndPtr->rectWindow.top)) - { - RedrawWindow( winpos.hwnd, NULL, 0, RDW_INVALIDATE | - RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE ); - } - else - if( CombineRgn( hrgn3, hrgn2, hrgn1, RGN_DIFF) != NULLREGION ) - RedrawWindow( winpos.hwnd, NULL, hrgn3, RDW_INVALIDATE | - RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE ); + if( (winpos.flags & SWP_NOPOSCHANGE) != SWP_NOPOSCHANGE ) + { + /* optimize cleanup by BitBlt'ing where possible */ - DeleteObject( hrgn1 ); - DeleteObject( hrgn2 ); - DeleteObject( hrgn3 ); - } + WINPOS_SizeMoveClean(wndPtr, visRgn, &oldWindowRect, &oldClientRect, bNoCopy); + DeleteObject(visRgn); + } + else + if( winpos.flags & SWP_FRAMECHANGED ) + RedrawWindow( winpos.hwnd, NULL, 0, RDW_NOCHILDREN | RDW_FRAME ); + + } + DeleteObject(visRgn); } if (flags & SWP_SHOWWINDOW) @@ -1271,8 +1461,7 @@ { if (!(flags & SWP_NOREDRAW)) RedrawWindow( wndPtr->parent->hwndSelf, &wndPtr->rectWindow, 0, - RDW_INVALIDATE | RDW_FRAME | - RDW_ALLCHILDREN | RDW_ERASE ); + RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE ); } if ((winpos.hwnd == GetFocus()) || IsChild(winpos.hwnd, GetFocus())) @@ -1303,18 +1492,12 @@ EVENT_DummyMotionNotify(); /* Simulate a mouse event to set the cursor */ - if ((flags & SWP_FRAMECHANGED) && !(flags & SWP_NOREDRAW)) - RedrawWindow( winpos.hwnd, NULL, 0, - RDW_ALLCHILDREN | /*FIXME: this should not be necessary*/ - RDW_INVALIDATE | RDW_FRAME | RDW_ERASE ); if (!(flags & SWP_DEFERERASE)) RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0, RDW_ALLCHILDREN | RDW_ERASENOW ); /* And last, send the WM_WINDOWPOSCHANGED message */ - winpos.flags |= SWP_NOMOVE; /* prevent looping.. window is already moved ??? (FIXME)*/ - if (!(winpos.flags & SWP_NOSENDCHANGING)) SendMessage( winpos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)MAKE_SEGPTR(&winpos) );