From cdcdede2e3f1c9bc64d86d0fb7c365c0f5960bf7 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Sun, 21 Apr 1996 14:57:41 +0000 Subject: [PATCH] Release 960421 Sat Apr 20 23:23:16 1996 Robert Pouliot * [resources/sysres_Fr.rc] [resources/TODO] Made changes for Choose_Color dialog. Sat Apr 20 15:43:49 1996 Alexandre Julliard * [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 * [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 * [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\\. * [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 * [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 * [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 * [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 * [resources/sysres_It.rc] Updated to support the new CHOOSE_COLOR_DIALOG. Tue Apr 16 11:50:00 1996 Anand Kumria * [if1632/Makefile] [if1632/relay.c] [if1631/w32sys.spec] [include/w32sys.h] [include/dlls.h] [misc/Makefile] [misc/w32sys.c] W32SYS.DLL partially implemented. --- ANNOUNCE | 49 +- ChangeLog | 93 ++++ controls/EDIT.TODO | 3 - controls/button.c | 13 +- controls/edit.c | 852 +++++++++++++++++++---------------- controls/menu.c | 5 +- controls/scroll.c | 53 ++- if1632/Makefile.in | 1 + if1632/commdlg.spec | 8 +- if1632/gdi.spec | 4 +- if1632/relay.c | 1 + if1632/w32sys.spec | 16 + if1632/winprocs.spec | 5 +- include/commdlg.h | 2 + include/dlls.h | 1 + include/local.h | 1 + include/mdi.h | 2 +- include/metafile.h | 14 +- include/options.h | 2 + include/w32sys.h | 17 + include/windows.h | 2 + include/winpos.h | 4 + include/winreg.h | 1 + memory/local.c | 416 ++++++++++++----- misc/Makefile.in | 1 + misc/comm.c | 8 +- misc/commdlg.c | 149 ++++-- misc/main.c | 31 +- misc/registry.c | 582 +++++++++++++++++------- misc/user.c | 21 +- misc/w32sys.c | 23 + objects/metafile.c | 552 +++++++++++++---------- programs/progman/ChangeLog | 5 + programs/progman/Fr.rc | 122 +++++ programs/progman/Makefile.in | 2 +- programs/progman/main.c | 9 +- programs/progman/string.c | 4 +- resources/TODO | 1 + resources/sysres_Fr.rc | 42 +- resources/sysres_It.rc | 43 +- windows/defwnd.c | 8 +- windows/mdi.c | 130 +++--- windows/message.c | 11 +- windows/painting.c | 53 ++- windows/winpos.c | 277 ++++++++++-- 45 files changed, 2458 insertions(+), 1181 deletions(-) create mode 100644 if1632/w32sys.spec create mode 100644 include/w32sys.h create mode 100644 misc/w32sys.c create mode 100644 programs/progman/Fr.rc diff --git a/ANNOUNCE b/ANNOUNCE index 7f3bb2f058e..23bded410e2 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 @@ Because of lags created by using mirror, this message may reach you before the release is available at the ftp sites. The sources will be available from the following locations: - sunsite.unc.edu:/pub/Linux/ALPHA/wine/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 @@ To avoid overloading the mail host, please subscribe only if you 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 46b0a5bdd76..f8d4c3d6206 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,96 @@ +---------------------------------------------------------------------- +Sat Apr 20 23:23:16 1996 Robert Pouliot + + * [resources/sysres_Fr.rc] [resources/TODO] + Made changes for Choose_Color dialog. + +Sat Apr 20 15:43:49 1996 Alexandre Julliard + + * [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 + + * [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 + + * [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\\. + + * [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 + + * [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 + + * [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 + + * [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 + + * [resources/sysres_It.rc] + Updated to support the new CHOOSE_COLOR_DIALOG. + +Tue Apr 16 11:50:00 1996 Anand Kumria + + * [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 diff --git a/controls/EDIT.TODO b/controls/EDIT.TODO index a1908748d2c..99b42706a6c 100644 --- a/controls/EDIT.TODO +++ b/controls/EDIT.TODO @@ -98,9 +98,6 @@ D) Known bugs. - 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 68515db5bc6..f5e7eff06cb 100644 --- a/controls/button.c +++ b/controls/button.c @@ -253,12 +253,17 @@ LRESULT ButtonWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 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 d49bd0413a3..296365c69cb 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 @@ typedef enum } 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 @@ typedef struct 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_MovePageUp(WND *wndPtr, BOOL extend); 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); @@ -215,6 +216,30 @@ static LRESULT EDIT_WM_Size(WND *wndPtr, WPARAM wParam, LPARAM lParam); static LRESULT EDIT_WM_VScroll(WND *wndPtr, WPARAM wParam, LPARAM lParam); +/********************************************************************* + * + * 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 @@ static void EDIT_BuildLineDefs(WND *wndPtr) * 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 @@ static int EDIT_CallWordBreakProc(WND *wndPtr, char *s, int index, int count, in * 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 int EDIT_ColFromWndX(WND *wndPtr, int line, int x) */ 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_DelEnd(WND *wndPtr) */ 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_DelLeft(WND *wndPtr) */ 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 @@ static void EDIT_DelRight(WND *wndPtr) * EDIT_GetAveCharWidth * */ -static int EDIT_GetAveCharWidth(WND *wndPtr) +static UINT EDIT_GetAveCharWidth(WND *wndPtr) { EDITSTATE *es = EDITSTATEPTR(wndPtr); @@ -684,7 +709,7 @@ static int EDIT_GetAveCharWidth(WND *wndPtr) * EDIT_GetLineHeight * */ -static int EDIT_GetLineHeight(WND *wndPtr) +static UINT EDIT_GetLineHeight(WND *wndPtr) { EDITSTATE *es = EDITSTATEPTR(wndPtr); @@ -700,12 +725,13 @@ static int EDIT_GetLineHeight(WND *wndPtr) * 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 @@ static BOOL EDIT_GetRedraw(WND *wndPtr) * EDIT_GetTextWidth * */ -static int EDIT_GetTextWidth(WND *wndPtr) +static UINT EDIT_GetTextWidth(WND *wndPtr) { EDITSTATE *es = EDITSTATEPTR(wndPtr); @@ -774,7 +800,7 @@ static int EDIT_GetTextWidth(WND *wndPtr) * EDIT_GetVisibleLineCount * */ -static int EDIT_GetVisibleLineCount(WND *wndPtr) +static UINT EDIT_GetVisibleLineCount(WND *wndPtr) { RECT rc; @@ -788,7 +814,7 @@ static int EDIT_GetVisibleLineCount(WND *wndPtr) * EDIT_GetWndWidth * */ -static int EDIT_GetWndWidth(WND *wndPtr) +static UINT EDIT_GetWndWidth(WND *wndPtr) { RECT rc; @@ -802,7 +828,7 @@ static int EDIT_GetWndWidth(WND *wndPtr) * EDIT_GetXOffset * */ -static int EDIT_GetXOffset(WND *wndPtr) +static UINT EDIT_GetXOffset(WND *wndPtr) { EDITSTATE *es = EDITSTATEPTR(wndPtr); @@ -810,6 +836,79 @@ static int EDIT_GetXOffset(WND *wndPtr) } +/********************************************************************* + * + * 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 @@ -817,13 +916,13 @@ static int EDIT_GetXOffset(WND *wndPtr) * 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 @@ static int EDIT_LineFromWndY(WND *wndPtr, int y) * * 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 @@ static BOOL EDIT_MakeFit(WND *wndPtr, int size) 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 BOOL EDIT_MakeFit(WND *wndPtr, int size) */ 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_MoveBackward(WND *wndPtr, BOOL extend) */ 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_MoveDownward(WND *wndPtr, BOOL extend) */ 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_MoveEnd(WND *wndPtr, BOOL extend) */ 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_MoveForward(WND *wndPtr, BOOL extend) */ 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_MoveHome(WND *wndPtr, BOOL extend) */ 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_MovePageDown(WND *wndPtr, BOOL extend) */ 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_MovePageUp(WND *wndPtr, BOOL extend) */ 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_MoveUpward(WND *wndPtr, BOOL extend) */ 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_MoveWordBackward(WND *wndPtr, BOOL extend) */ 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 @@ static void EDIT_MoveWordForward(WND *wndPtr, BOOL extend) * 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 @@ static void EDIT_PaintLine(WND *wndPtr, HDC hdc, int line) * 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 @@ static int EDIT_PaintText(WND *wndPtr, HDC hdc, int x, int y, int line, int col, 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 @@ static LRESULT EDIT_ReplaceSel(WND *wndPtr, WPARAM wParam, LPARAM lParam) 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 @@ static LRESULT EDIT_ReplaceSel(WND *wndPtr, WPARAM wParam, LPARAM lParam) 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 LRESULT EDIT_ReplaceSel(WND *wndPtr, WPARAM wParam, LPARAM lParam) */ 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 @@ static void EDIT_ScrollIntoView(WND *wndPtr) * 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 @@ static int EDIT_WndXFromCol(WND *wndPtr, int line, int col) 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 @@ static int EDIT_WndXFromCol(WND *wndPtr, int line, int col) * 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 @@ static int EDIT_WndYFromLine(WND *wndPtr, int line) * 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 @@ static LRESULT EDIT_EM_GetLine(WND *wndPtr, WPARAM wParam, LPARAM lParam) 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 @@ static LRESULT EDIT_EM_LineFromChar(WND *wndPtr, WPARAM wParam, LPARAM lParam) 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_LineFromChar(WND *wndPtr, WPARAM wParam, LPARAM lParam) 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_LineIndex(WND *wndPtr, WPARAM wParam, LPARAM lParam) 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_LineLength(WND *wndPtr, WPARAM wParam, LPARAM lParam) 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 @@ static LRESULT EDIT_EM_ReplaceSel(WND *wndPtr, WPARAM wParam, LPARAM lParam) * EM_SCROLL * * FIXME: undocumented message. + * */ static LRESULT EDIT_EM_Scroll(WND *wndPtr, WPARAM wParam, LPARAM lParam) { @@ -1780,14 +1886,10 @@ static LRESULT EDIT_EM_SetHandle(WND *wndPtr, WPARAM wParam, LPARAM lParam) 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 @@ static LRESULT EDIT_EM_SetModify(WND *wndPtr, WPARAM wParam, LPARAM lParam) { EDITSTATE *es = EDITSTATEPTR(wndPtr); - es->TextChanged = wParam; + es->TextChanged = (BOOL)wParam; return 0L; } @@ -1876,27 +1978,20 @@ static LRESULT EDIT_EM_SetRectNP(WND *wndPtr, WPARAM wParam, LPARAM lParam) 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 @@ static LRESULT EDIT_EM_SetSel(WND *wndPtr, WPARAM wParam, LPARAM lParam) 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 @@ static LRESULT EDIT_EM_SetTabStops(WND *wndPtr, WPARAM wParam, LPARAM lParam) 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_Char(WND *wndPtr, WPARAM wParam, LPARAM lParam) */ 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_Clear(WND *wndPtr, WPARAM wParam, LPARAM lParam) */ 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 @@ static LRESULT EDIT_WM_Copy(WND *wndPtr, WPARAM wParam, LPARAM lParam) 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 @@ static LRESULT EDIT_WM_Create(WND *wndPtr, WPARAM wParam, LPARAM lParam) { 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 @@ static LRESULT EDIT_WM_Create(WND *wndPtr, WPARAM wParam, LPARAM lParam) 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_Destroy(WND *wndPtr, WPARAM wParam, LPARAM lParam) */ static LRESULT EDIT_WM_Enable(WND *wndPtr, WPARAM wParam, LPARAM lParam) { + EDIT_InvalidateText(wndPtr, 0, -1); return 0L; } @@ -2245,6 +2280,8 @@ static LRESULT EDIT_WM_EraseBkGnd(WND *wndPtr, WPARAM wParam, LPARAM lParam) 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 @@ static LRESULT EDIT_WM_GetText(WND *wndPtr, WPARAM wParam, LPARAM lParam) 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_HScroll(WND *wndPtr, WPARAM wParam, LPARAM lParam) */ 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_KeyDown(WND *wndPtr, WPARAM wParam, LPARAM lParam) */ 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 @@ static LRESULT EDIT_WM_KillFocus(WND *wndPtr, WPARAM wParam, LPARAM lParam) * * 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_LButtonDblClk(WND *wndPtr, WPARAM wParam, LPARAM lParam) */ 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_LButtonUp(WND *wndPtr, WPARAM wParam, LPARAM lParam) */ 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 @@ static LRESULT EDIT_WM_Paint(WND *wndPtr, WPARAM wParam, LPARAM lParam) 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 @@ static LRESULT EDIT_WM_Paint(WND *wndPtr, WPARAM wParam, LPARAM lParam) 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_SetCursor(WND *wndPtr, WPARAM wParam, LPARAM lParam) */ 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 @@ static LRESULT EDIT_WM_SetFont(WND *wndPtr, WPARAM wParam, LPARAM lParam) 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 @@ static LRESULT EDIT_WM_SetRedraw(WND *wndPtr, WPARAM wParam, LPARAM lParam) { EDITSTATE *es = EDITSTATEPTR(wndPtr); - es->Redraw = wParam ? TRUE : FALSE; + es->Redraw = (BOOL)wParam; return 0L; } @@ -2719,7 +2788,7 @@ static LRESULT EDIT_WM_SetRedraw(WND *wndPtr, WPARAM wParam, LPARAM lParam) */ 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 @@ static LRESULT EDIT_WM_Size(WND *wndPtr, WPARAM wParam, LPARAM lParam) { 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_Size(WND *wndPtr, WPARAM wParam, LPARAM lParam) */ 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 7f09a8eac6e..78e991d117c 100644 --- a/controls/menu.c +++ b/controls/menu.c @@ -2227,8 +2227,9 @@ BOOL SetMenu(HWND hWnd, HMENU hMenu) 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 9824b3b672d..27323a6507b 100644 --- a/controls/scroll.c +++ b/controls/scroll.c @@ -94,14 +94,12 @@ static void SCROLL_LoadBitmaps(void) 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 @@ static SCROLLINFO *SCROLL_GetScrollInfo( HWND hwnd, int nBar ) 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 @@ static BOOL SCROLL_GetScrollBarRect( HWND hwnd, int nBar, RECT *lprect, 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 @@ void SCROLL_DrawScrollBar( HWND hwnd, HDC hdc, int nBar ) 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 @@ static void SCROLL_RefreshScrollBar( HWND hwnd, int nBar ) 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 @@ void SetScrollRange(HWND hwnd, int nBar, int MinVal, int MaxVal, BOOL bRedraw) 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 d55fe40ba01..288e84aec23 100644 --- a/if1632/Makefile.in +++ b/if1632/Makefile.in @@ -34,6 +34,7 @@ DLLS = \ 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 c579065ffaf..0f5dc757dea 100644 --- a/if1632/commdlg.spec +++ b/if1632/commdlg.spec @@ -13,10 +13,10 @@ id 14 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 08d7d6a2f60..cbd75d07aaf 100644 --- a/if1632/gdi.spec +++ b/if1632/gdi.spec @@ -136,7 +136,7 @@ id 3 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 @@ id 3 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 9daacc173d0..1197af746b4 100644 --- a/if1632/relay.c +++ b/if1632/relay.c @@ -52,6 +52,7 @@ BUILTIN_DLL dll_builtin_table[] = 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 00000000000..04dd9688989 --- /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 62274e86b98..056c9f69fe4 100644 --- a/if1632/winprocs.spec +++ b/if1632/winprocs.spec @@ -31,7 +31,10 @@ id 24 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 f51e4b669e2..384b0b4d2a7 100644 --- a/include/commdlg.h +++ b/include/commdlg.h @@ -298,6 +298,7 @@ BOOL GetOpenFileName(LPOPENFILENAME lpofn); 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 FindTextDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam); 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 304b1420e3e..70d34ccb144 100644 --- a/include/dlls.h +++ b/include/dlls.h @@ -57,6 +57,7 @@ DECLARE_DLL(STORAGE) 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 d3f12f7c21e..bfc6f123358 100644 --- a/include/local.h +++ b/include/local.h @@ -20,6 +20,7 @@ extern HLOCAL LOCAL_Handle( HANDLE ds, WORD addr ); 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 a34c1d05b55..99d79749d82 100644 --- a/include/mdi.h +++ b/include/mdi.h @@ -37,7 +37,7 @@ typedef struct 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 2c56e3427f2..c83afcbc508 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 c1b6f0eb004..9f6a1dbf2c2 100644 --- a/include/options.h +++ b/include/options.h @@ -22,6 +22,8 @@ typedef enum 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 00000000000..6388b6c20d4 --- /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 c25d916fe3c..5ad16fbafc2 100644 --- a/include/windows.h +++ b/include/windows.h @@ -2322,6 +2322,8 @@ typedef COMPAREITEMSTRUCT FAR* LPCOMPAREITEMSTRUCT; #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 455cce8d556..4ec73192d28 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 01c60a0b4ea..d8e23b0ec92 100644 --- a/include/winreg.h +++ b/include/winreg.h @@ -89,6 +89,7 @@ typedef struct tagKEYVALUE { 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 96fa99903b8..b4aba40e181 100644 --- a/memory/local.c +++ b/memory/local.c @@ -47,6 +47,12 @@ typedef struct #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 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 @@ static WORD LOCAL_Compact( WORD ds, WORD minfree, WORD flags ) 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 @@ static WORD LOCAL_Compact( WORD ds, WORD minfree, WORD flags ) 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 @@ static HLOCAL LOCAL_FindFreeBlock( WORD ds, WORD size ) 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 @@ static HLOCAL LOCAL_GetBlock( WORD ds, WORD size, WORD flags ) 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 @@ static HLOCAL LOCAL_GetBlock( WORD ds, WORD size, WORD flags ) 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 @@ static HLOCAL LOCAL_GetBlock( WORD ds, WORD size, WORD flags ) return arena + ARENA_HEADER_SIZE; } + /*********************************************************************** * LOCAL_NewHTable */ @@ -571,56 +587,82 @@ static BOOL LOCAL_NewHTable( WORD ds ) { 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 @@ static HLOCAL LOCAL_FreeArena( WORD ds, WORD arena ) 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; } @@ -669,6 +713,59 @@ static HLOCAL LOCAL_FreeArena( WORD ds, WORD arena ) } +/*********************************************************************** + * 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 * @@ -677,20 +774,23 @@ static HLOCAL LOCAL_FreeArena( WORD ds, WORD arena ) 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 */ + } + 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 */ } - arena = LOCAL_FreeArena( ds, arena ); - if (arena != 0) return handle; /* couldn't free it */ - return 0; } @@ -706,26 +806,26 @@ HLOCAL LOCAL_Alloc( HANDLE ds, WORD flags, WORD size ) 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 @@ HLOCAL LOCAL_ReAlloc( HANDLE ds, HLOCAL handle, WORD size, WORD flags ) 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 @@ HLOCAL LOCAL_ReAlloc( HANDLE ds, HLOCAL handle, WORD size, WORD flags ) 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 @@ static HLOCAL LOCAL_InternalLock( LPSTR heap, HLOCAL handle ) 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 @@ BOOL LOCAL_Unlock( WORD ds, HLOCAL handle ) 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,20 +973,40 @@ WORD LOCAL_Size( WORD ds, HLOCAL handle ) { 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 * @@ -905,6 +1020,67 @@ WORD LOCAL_HeapSize( WORD ds ) } +/*********************************************************************** + * 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) */ @@ -964,14 +1140,8 @@ WORD LocalSize( HLOCAL handle ) * 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 @@ HLOCAL LocalHandle( WORD addr ) */ WORD LocalFlags( HLOCAL handle ) { - dprintf_local( stddeb, "LocalFlags: %04x\n", handle ); - return 0; + return LOCAL_Flags( CURRENT_DS, handle ); } @@ -1000,8 +1169,20 @@ WORD LocalCompact( WORD minfree ) */ 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 @@ WORD LocalShrink( HLOCAL handle, WORD newsize ) */ 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 LocalHeapSize() */ 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 1266b0570c6..5e7701fcd0c 100644 --- a/misc/Makefile.in +++ b/misc/Makefile.in @@ -28,6 +28,7 @@ C_SRCS = \ stress.c \ toolhelp.c \ user.c \ + w32sys.c \ winsocket.c \ xmalloc.c diff --git a/misc/comm.c b/misc/comm.c index d0dfef32829..d863ec50947 100644 --- a/misc/comm.c +++ b/misc/comm.c @@ -164,7 +164,7 @@ BOOL BuildCommDCB(LPCSTR device, LPDCB lpdcb) 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 @@ BOOL BuildCommDCB(LPCSTR device, LPDCB lpdcb) 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 @@ BOOL BuildCommDCB(LPCSTR device, LPDCB lpdcb) 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 089019b2cd1..a749ba297ac 100644 --- a/misc/commdlg.c +++ b/misc/commdlg.c @@ -320,6 +320,8 @@ static LONG FILEDLG_WMInitDialog(HWND hWnd, WPARAM wParam, LPARAM lParam) 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 @@ struct CCPRIVATE 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_PaintTriangle(HWND hDlg,int y) 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 @@ static void CC_PaintCross(HWND hDlg,int x,int y) 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; - - if (point.y+w/23) - { - MoveTo(hDC,point.x,point.y-w/2); - LineTo(hDC,point.x,MAX(2,point.y-w )); - } - if (point.x+w/23) - { - MoveTo(hDC,point.x-w/2,point.y); - LineTo(hDC,MAX(2,point.x-w), point.y); - } + lpp->oldcross.bottom=point.y+w+1; + 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 @@ static void CC_PrepareColorGraph(HWND hDlg) 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 @@ static void CC_PrepareColorGraph(HWND hDlg) } ReleaseDC(hwnd,hdc); SetCursor(hcursor); - /* FIXME perhaps we should do it only ONCE for all, like hCDRom,.... ? */ } /*********************************************************************** @@ -1675,17 +1654,20 @@ static void CC_PaintLumBar(HWND hDlg,int hue,int sat) 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_EditSetRGB(HWND hDlg,COLORREF cr) 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 @@ static LRESULT CC_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam) 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 @@ static LRESULT CC_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam) 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 @@ LRESULT ColorDlgProc(HWND hDlg, UINT message, 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 @@ LRESULT ColorDlgProc(HWND hDlg, UINT message, 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 e7bfddab84d..3dcd171ca82 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 64830784711..7e72b71a3a5 100644 --- a/misc/registry.c +++ b/misc/registry.c @@ -10,22 +10,32 @@ #include #include #include +#include +#include +#include +#include +#include #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 @@ split_keypath(LPCWSTR wp,LPWSTR **wpv,int *wpc) { } #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(""); - 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 @@ SHELL_Init() { * 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; + } + 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++; } - return 1; } - 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;inrofvalues;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<type) & UNICONVMASK) + _write_USTRING(F,(LPWSTR)val->data,0); + else + for (j=0;jlen;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 @@ _do_save_subkey(FILE *F,LPKEYSTRUCT lpkey) { 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 @@ _SaveSubReg(LPKEYSTRUCT lpkey,char *fn) { 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;inrofvalues;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 (inextsub); + 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;inrofvalues;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<='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->lastmodifiedlastmodified=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 @@ _LoadSubReg(LPKEYSTRUCT lpkey,char *fn) { 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 @@ RegOpenKeyExW( } split_keypath(lpszSubKey,&wps,&wpc); i = 0; + while ((inextsub; @@ -647,6 +893,7 @@ RegCreateKeyExW( } split_keypath(lpszSubKey,&wps,&wpc); i = 0; + while ((inextsub; @@ -1131,6 +1378,7 @@ RegSetValueExW( 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 0a3cd4fad7a..194da4c8318 100644 --- a/misc/user.c +++ b/misc/user.c @@ -24,30 +24,33 @@ WORD USER_HeapSel = 0; */ 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 00000000000..8fae50db760 --- /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 b68373ab0c0..e83101729e4 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 @@ static int HTLen; /* allocated length of handle table */ /****************************************************************** * 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 @@ HMETAFILE GetMetaFile(LPSTR lpFilename) /****************************************************************** * 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 @@ HANDLE CreateMetaFile(LPCTSTR lpFilename) 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 @@ HANDLE CreateMetaFile(LPCTSTR lpFilename) 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 @@ HMETAFILE CloseMetaFile(HDC hdc) /****************************************************************** * 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 @@ BOOL DeleteMetaFile(HMETAFILE hmf) /****************************************************************** * 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 @@ BOOL PlayMetaFile(HDC hdc, HMETAFILE hmf) /****************************************************************** * PlayMetaFileRecord GDI.176 */ + void PlayMetaFileRecord(HDC hdc, HANDLETABLE *ht, METARECORD *mr, WORD nHandles) { @@ -288,6 +346,9 @@ void PlayMetaFileRecord(HDC hdc, HANDLETABLE *ht, METARECORD *mr, 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 @@ void PlayMetaFileRecord(HDC hdc, HANDLETABLE *ht, METARECORD *mr, } 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 @@ void PlayMetaFileRecord(HDC hdc, HANDLETABLE *ht, METARECORD *mr, * * 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 @@ HANDLE GetMetaFileBits(HMETAFILE hmf) * * 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 @@ BOOL MF_WriteRecord(HMETAFILE hmf, METARECORD *mr, WORD rlen) * * 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 @@ int MF_AddHandle(HANDLETABLE *ht, WORD htlen, HANDLE hobj) * * Add a handle to the internal handle table and return the index */ + int MF_AddHandleInternal(HANDLE hobj) { int i; @@ -725,14 +786,19 @@ int MF_AddHandleInternal(HANDLE hobj) /****************************************************************** * 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 @@ BOOL MF_MetaParam1(DC *dc, short func, short param1) { 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 @@ BOOL MF_MetaParam2(DC *dc, short func, short param1, short param2) { 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 @@ BOOL MF_MetaParam6(DC *dc, short func, short param1, short param2, *(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 @@ BOOL MF_MetaParam8(DC *dc, short func, short param1, short param2, { char buffer[22]; METARECORD *mr = (METARECORD *)&buffer; - + HMETAFILE handle; + mr->rdSize = 11; mr->rdFunction = func; *(mr->rdParam) = param8; @@ -827,48 +912,55 @@ BOOL MF_MetaParam8(DC *dc, short func, short param1, short param2, *(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 @@ BOOL MF_CreatePatternBrush(DC *dc, HBRUSH hBrush, LOGBRUSH *logbrush) 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 @@ BOOL MF_CreatePatternBrush(DC *dc, HBRUSH hBrush, LOGBRUSH *logbrush) 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_CreateFontIndirect(DC *dc, HFONT hFont, LOGFONT *logfont) */ 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 @@ BOOL MF_TextOut(DC *dc, short x, short y, LPSTR str, short count) 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_TextOut(DC *dc, short x, short y, LPSTR str, short count) */ 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 @@ BOOL MF_MetaPoly(DC *dc, short func, LPPOINT pt, short count) 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 7688fe9fc80..12efc7a9907 100644 --- a/programs/progman/ChangeLog +++ b/programs/progman/ChangeLog @@ -1,3 +1,8 @@ +Sun Apr 14 20:09:19 1996 Pablo Saratxaga + + * [Fr.rc] (new) + Added French language support. + Sun Mar 24 12:28:22 1996 Ulrich Schmid * [Strings_En.c] [Strings_De.c] (deleted) diff --git a/programs/progman/Fr.rc b/programs/progman/Fr.rc new file mode 100644 index 00000000000..251b5bdbe83 --- /dev/null +++ b/programs/progman/Fr.rc @@ -0,0 +1,122 @@ +/* + * Program Manager + * + * Copyright 1996 Ulrich Schmid + * French Fr.rc by Pablo Saratxaga + */ + +#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 ee8a900bb75..37af3941f76 100644 --- a/programs/progman/Makefile.in +++ b/programs/progman/Makefile.in @@ -3,7 +3,7 @@ MODULE = none 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 561fc274756..1dd5e6d0b5a 100644 --- a/programs/progman/main.c +++ b/programs/progman/main.c @@ -12,6 +12,10 @@ #include #include #include +void LIBWINE_Register_accel(); +void LIBWINE_Register_De(); +void LIBWINE_Register_En(); +void LIBWINE_Register_Fr(); #endif GLOBALS Globals; @@ -39,6 +43,7 @@ int PASCAL WinMain (HANDLE hInstance, HANDLE prev, LPSTR cmdline, int show) LIBWINE_Register_accel(); LIBWINE_Register_De(); LIBWINE_Register_En(); + LIBWINE_Register_Fr(); #endif #ifndef WINELIB @@ -62,8 +67,8 @@ int PASCAL WinMain (HANDLE hInstance, HANDLE prev, LPSTR cmdline, int show) } #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 cb6e16081e0..f33941b40ea 100644 --- a/programs/progman/string.c +++ b/programs/progman/string.c @@ -120,8 +120,8 @@ VOID STRING_SelectLanguageByNumber(UINT num) 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 31be6f58367..eff85ce08e5 100644 --- a/resources/TODO +++ b/resources/TODO @@ -45,6 +45,7 @@ otherwise you'll get an undefined behavour. 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 3a241bd6fe0..3df4265e0c3 100644 --- a/resources/sysres_Fr.rc +++ b/resources/sysres_Fr.rc @@ -144,25 +144,37 @@ FONT 8, "Helv" 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 91ba4565802..5fab00a13c3 100644 --- a/resources/sysres_It.rc +++ b/resources/sysres_It.rc @@ -143,28 +143,39 @@ FONT 8, "Helv" 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 5eccbf4b81f..f84bdda18ff 100644 --- a/windows/defwnd.c +++ b/windows/defwnd.c @@ -141,18 +141,14 @@ LRESULT DefWindowProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) case WM_WINDOWPOSCHANGED: { - /* Note: Windoze uses unknown SWP flags 0x1000 and 0x0800 to - * decide whether to send WM_MOVE or/and WM_SIZE respectively - */ - WINDOWPOS * winPos = (WINDOWPOS *)PTR_SEG_TO_LIN(lParam); WPARAM wp = SIZE_RESTORED; - if (!(winPos->flags & SWP_NOMOVE)) + 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 a22d1deb490..1a533f8a676 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 @@ -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 @@ BOOL MDI_RestoreFrameMenu(WND *, HWND); void ScrollChildren(HWND , UINT , WPARAM , LPARAM ); void CalcChildScroll(HWND, WORD); -/* ----------------- declarations ----------------- */ - static LONG MDI_ChildActivate(WND* ,HWND ); /* -------- Miscellaneous service functions ---------- @@ -55,6 +55,16 @@ static HWND MDI_GetChildByID(WND* wndPtr,int id) 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 @@ HWND MDIDestroyChild(WND *w_parent, MDICLIENTINFO *ci, HWND parent, 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 @@ BOOL MDI_AugmentFrameMenu(MDICLIENTINFO* ci, WND *frame, HWND hChild) 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 @@ BOOL MDI_RestoreFrameMenu( WND *frameWnd, HWND hChild) 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 @@ LRESULT MDIClientWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 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 @@ LRESULT MDIClientWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) ((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 @@ LRESULT MDIClientWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) #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 @@ LRESULT MDIClientWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 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 @@ LRESULT DefMDIChildProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 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 @@ LRESULT DefMDIChildProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 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 @@ BOOL TranslateMDISysAccel(HWND hwndClient, LPMSG msg) 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 d1ac19576d7..78942bc09cc 100644 --- a/windows/message.c +++ b/windows/message.c @@ -201,6 +201,9 @@ static BOOL MSG_PeekHardwareMsg( MSG *msg, HWND hwnd, WORD first, WORD last, 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 @@ BOOL MSG_WaitXEvent( LONG maxWait ) { #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 e8ce1bbb711..31573ff8434 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 @@ void WIN_UpdateNCArea(WND* wnd, BOOL bUpdate) 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 @@ void WIN_UpdateNCArea(WND* wnd, BOOL bUpdate) 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 @@ BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags ) } 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 @@ BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags ) 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 @@ BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags ) 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 @@ BOOL GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase ) 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 @@ BOOL GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase ) } else SetRectEmpty( rect ); } - return (wndPtr->hrgnUpdate != 0); + return (wndPtr->hrgnUpdate > 1); } @@ -423,7 +443,7 @@ int GetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase ) 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 @@ int ExcludeUpdateRgn( HDC hdc, HWND hwnd ) 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 524f285ed93..09ad76a4240 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 @@ BOOL ShowWindow( HWND hwnd, int cmd ) 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 @@ HWND WINPOS_ReorderOwnedPopups(HWND hwndInsertAfter, WND* wndPtr, WORD flags) 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 @@ static void WINPOS_SetXWindowPos( WINDOWPOS *winpos ) 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 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y, /* 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 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y, 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 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y, 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 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y, 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 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y, { 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 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y, 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) );