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