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.
This commit is contained in:
Alexandre Julliard 1996-04-21 14:57:41 +00:00
parent 329f0680e4
commit cdcdede2e3
45 changed files with 2458 additions and 1181 deletions

View File

@ -1,14 +1,15 @@
This is release 960414 of Wine the MS Windows emulator. This is still a
This is release 960421 of Wine the MS Windows emulator. This is still a
developer's only release. There are many bugs and many unimplemented API
features. Most applications still do not work.
Patches should be submitted to "julliard@lrc.epfl.ch". Please don't
forget to include a ChangeLog entry.
WHAT'S NEW with Wine-960414: (see ChangeLog for details)
- Complete rewrite of the edit control.
- Better color selection dialog.
- Win32 heap management.
WHAT'S NEW with Wine-960421: (see ChangeLog for details)
- Preliminary support for W32SYS.DLL.
- Built-in COMMDLG improvements.
- New format and location for registry files.
- Window refresh optimized.
- Lots of bug fixes.
See the README file in the distribution for installation instructions.
@ -17,10 +18,10 @@ Because of lags created by using mirror, this message may reach you before
the release is available at the ftp sites. The sources will be available
from the following locations:
sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960414.tar.gz
tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960414.tar.gz
ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960414.tar.gz
aris.com:/pub/linux/ALPHA/Wine/development/Wine-960414.tar.gz
sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960421.tar.gz
tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960421.tar.gz
ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960421.tar.gz
aris.com:/pub/linux/ALPHA/Wine/development/Wine-960421.tar.gz
It should also be available from any site that mirrors tsx-11 or sunsite.
@ -34,19 +35,25 @@ To avoid overloading the mail host, please subscribe only if you
really intend to test the new releases as soon as they're out.
Wine is available thanks to the work of Bob Amstadt, Dag Asheim,
Martin Ayotte, Ross Biro, Erik Bos, Fons Botman, John Brezak,
Andrew Bulhak, John Burton, Paul Falstad, Olaf Flebbe, Peter Galbavy,
Ramon Garcia, Hans de Graaff, Charles M. Hannum, Cameron Heide,
Jochen Hoenicke, Jeffrey Hsu, Miguel de Icaza, Alexandre Julliard,
Jon Konrath, Scott A. Laird, Martin von Loewis, Kenneth MacDonald,
Peter MacDonald, William Magro, Marcus Meissner, Graham Menhennitt,
David Metcalfe, Michael Patra, John Richardson, Johannes Ruscheinski,
Thomas Sandford, Constantine Sapuntzakis, Daniel Schepler,
Martin Ayotte, Ross Biro, Uwe Bonnes, Erik Bos, Fons Botman, John Brezak,
Andrew Bulhak, John Burton, Niels de Carpentier, Roman Dolejsi,
Frans van Dorsselaer, Paul Falstad, Olaf Flebbe, Peter Galbavy,
Ramon Garcia, Hans de Graaff, Charles M. Hannum, John Harvey,
Cameron Heide, Jochen Hoenicke, Onno Hovers, Jeffrey Hsu,
Miguel de Icaza, Jukka Iivonen, Alexandre Julliard, Jochen Karrer,
Andreas Kirschbaum, Albrecht Kleine, Jon Konrath, Alex Korobka,
Greg Kreider, Anand Kumria, Scott A. Laird, Martin von Loewis,
Kenneth MacDonald, Peter MacDonald, William Magro, Juergen Marquardt,
Marcus Meissner, Graham Menhennitt, David Metcalfe, Steffen Moeller,
Philippe De Muyter, Itai Nahshon, Michael Patra, Jim Peterson,
Robert Pouliot, Keith Reynolds, John Richardson, Johannes Ruscheinski,
Thomas Sandford, Constantine Sapuntzakis, Daniel Schepler, Ulrich Schmid,
Bernd Schmidt, Yngvi Sigurjonsson, Rick Sladkey, William Smith,
Erik Svendsen, Goran Thyni, Jimmy Tirtawangsa, Jon Tombs,
Linus Torvalds, Gregory Trubetskoy, Michael Veksler, Morten Welinder,
Jan Willamowius, Carl Williams, Karl Guenter Wuensch, Eric Youngdale,
and James Youngman.
Erik Svendsen, Tristan Tarrant, Andrew Taylor, Duncan C Thomson,
Goran Thyni, Jimmy Tirtawangsa, Jon Tombs, Linus Torvalds,
Gregory Trubetskoy, Michael Veksler, Sven Verdoolaege, Eric Warnke,
Manfred Weichel, Morten Welinder, Jan Willamowius, Carl Williams,
Karl Guenter Wuensch, Eric Youngdale, and James Youngman.
--
Alexandre Julliard

View File

@ -1,3 +1,96 @@
----------------------------------------------------------------------
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>

View File

@ -98,9 +98,6 @@ D) Known bugs.
- The clipboard is broken. Whenever things go wrong with
cut/copy/paste, it is probably the clipboard that messes up things,
not edit.c.
- With Notepad, if you select New File a couple of times and enter
text, the buffer is sometimes corrupted.
- Switching on/off WordWrap with Notepad sometimes corrupts the buffer.
I am still very actively changing things. Especially I am working

View File

@ -253,12 +253,17 @@ LRESULT ButtonWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
break;
case BM_SETSTATE:
if (!wParam != !(infoPtr->state & BUTTON_HIGHLIGHTED))
if (wParam)
{
if (wParam) infoPtr->state |= BUTTON_HIGHLIGHTED;
else infoPtr->state &= ~BUTTON_HIGHLIGHTED;
PAINT_BUTTON( wndPtr, style, ODA_SELECT );
if (infoPtr->state & BUTTON_HIGHLIGHTED) break;
infoPtr->state |= BUTTON_HIGHLIGHTED;
}
else
{
if (!(infoPtr->state & BUTTON_HIGHLIGHTED)) break;
infoPtr->state &= ~BUTTON_HIGHLIGHTED;
}
PAINT_BUTTON( wndPtr, style, ODA_SELECT );
break;
default:

File diff suppressed because it is too large Load Diff

View File

@ -2227,8 +2227,9 @@ BOOL SetMenu(HWND hWnd, HMENU hMenu)
lpmenu->wFlags &= ~MF_POPUP; /* Can't be a popup */
lpmenu->Height = 0; /* Make sure we recalculate the size */
}
SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
if (IsWindowVisible(hWnd))
SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
return TRUE;
}

View File

@ -94,14 +94,12 @@ static void SCROLL_LoadBitmaps(void)
hRgArrowI = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_RGARROWI));
}
/***********************************************************************
* SCROLL_GetScrollInfo
* SCROLL_GetPtrScrollInfo
*/
static SCROLLINFO *SCROLL_GetScrollInfo( HWND hwnd, int nBar )
static SCROLLINFO *SCROLL_GetPtrScrollInfo( WND* wndPtr, int nBar )
{
HANDLE handle;
WND *wndPtr = WIN_FindWndPtr( hwnd );
if (!wndPtr) return NULL;
switch(nBar)
@ -128,6 +126,15 @@ static SCROLLINFO *SCROLL_GetScrollInfo( HWND hwnd, int nBar )
return (SCROLLINFO *) USER_HEAP_LIN_ADDR( handle );
}
/***********************************************************************
* SCROLL_GetScrollInfo
*/
static SCROLLINFO *SCROLL_GetScrollInfo( HWND hwnd, int nBar )
{
WND *wndPtr = WIN_FindWndPtr( hwnd );
return SCROLL_GetPtrScrollInfo( wndPtr, nBar );
}
/***********************************************************************
* SCROLL_GetScrollBarRect
@ -188,7 +195,7 @@ static BOOL SCROLL_GetScrollBarRect( HWND hwnd, int nBar, RECT *lprect,
if ((pixels -= 3*SYSMETRICS_CXVSCROLL+1) > 0)
{
SCROLLINFO *info = SCROLL_GetScrollInfo( hwnd, nBar );
SCROLLINFO *info = SCROLL_GetPtrScrollInfo( wndPtr, nBar );
if ((info->flags & ESB_DISABLE_BOTH) == ESB_DISABLE_BOTH)
*thumbPos = 0;
else if (info->MinVal == info->MaxVal)
@ -449,7 +456,7 @@ void SCROLL_DrawScrollBar( HWND hwnd, HDC hdc, int nBar )
RECT rect;
BOOL vertical;
WND *wndPtr = WIN_FindWndPtr( hwnd );
SCROLLINFO *infoPtr = SCROLL_GetScrollInfo( hwnd, nBar );
SCROLLINFO *infoPtr = SCROLL_GetPtrScrollInfo( wndPtr, nBar );
if (!wndPtr || !infoPtr ||
((nBar == SB_VERT) && !(wndPtr->dwStyle & WS_VSCROLL)) ||
@ -480,7 +487,7 @@ static void SCROLL_RefreshScrollBar( HWND hwnd, int nBar )
BOOL vertical;
HDC hdc;
WND *wndPtr = WIN_FindWndPtr( hwnd );
SCROLLINFO *infoPtr = SCROLL_GetScrollInfo( hwnd, nBar );
SCROLLINFO *infoPtr = SCROLL_GetPtrScrollInfo( wndPtr, nBar );
if (!wndPtr || !infoPtr ||
((nBar == SB_VERT) && !(wndPtr->dwStyle & WS_VSCROLL)) ||
@ -913,6 +920,38 @@ void SetScrollRange(HWND hwnd, int nBar, int MinVal, int MaxVal, BOOL bRedraw)
if (bRedraw) SCROLL_RefreshScrollBar( hwnd, nBar );
}
/*************************************************************************
* SCROLL_SetNCSbState
*
* This is for CalcChildScroll in windows/mdi.c
*/
DWORD SCROLL_SetNCSbState(WND* wndPtr, int vMin, int vMax, int vPos,
int hMin, int hMax, int hPos)
{
SCROLLINFO *infoPtr = SCROLL_GetPtrScrollInfo(wndPtr, SB_VERT);
wndPtr->dwStyle |= (WS_VSCROLL | WS_HSCROLL);
if( vMin >= vMax )
{ vMin = vMax;
wndPtr->dwStyle &= ~WS_VSCROLL; }
if( vPos > vMax ) vPos = vMax; else if( vPos < vMin ) vPos = vMin;
infoPtr->MinVal = vMin;
infoPtr->MaxVal = vMax;
infoPtr->CurVal = vPos;
infoPtr = SCROLL_GetPtrScrollInfo(wndPtr, SB_HORZ);
if( hMin >= hMax )
{ hMin = hMax;
wndPtr->dwStyle &= ~WS_HSCROLL; }
if( hPos > hMax ) hPos = hMax; else if( hPos < hMin ) hPos = hMin;
infoPtr->MinVal = hMin;
infoPtr->MaxVal = hMax;
infoPtr->CurVal = hPos;
return wndPtr->dwStyle & (WS_VSCROLL | WS_HSCROLL);
}
/*************************************************************************
* GetScrollRange (USER.65)

View File

@ -34,6 +34,7 @@ DLLS = \
toolhelp.spec \
user.spec \
user32.spec \
w32sys.spec \
win87em.spec \
winprocs.spec \
winprocs32.spec \

View File

@ -13,10 +13,10 @@ id 14
12 pascal16 ReplaceText(ptr) ReplaceText
13 pascal FindTextDlgProc(word word word long) FindTextDlgProc
14 pascal ReplaceTextDlgProc(word word word long) ReplaceTextDlgProc
15 stub ChooseFont
#16 pascal FORMATCHARDLGPROC exported, shared data
#18 pascal FONTSTYLEENUMPROC exported, shared data
#19 pascal FONTFAMILYENUMPROC exported, shared data
15 pascal16 ChooseFont(ptr) ChooseFont
16 pascal16 FormatCharDlgProc(word word word long) FormatCharDlgProc
18 pascal16 FontStyleEnumProc(ptr ptr word long) FontStyleEnumProc
19 pascal16 FontFamilyEnumProc(ptr ptr word long) FontFamilyEnumProc
20 pascal16 PrintDlg(ptr) PrintDlg
21 pascal PrintDlgProc(word word word long) PrintDlgProc
22 pascal PrintSetupDlgProc(word word word long) PrintSetupDlgProc

View File

@ -136,7 +136,7 @@ id 3
148 pascal SetBrushOrg(word s_word s_word) SetBrushOrg
149 pascal GetBrushOrg(word) GetBrushOrg
150 pascal16 UnrealizeObject(word) UnrealizeObject
151 stub CopyMetaFile
151 pascal16 CopyMetaFile(word ptr) CopyMetaFile
153 pascal16 CreateIC(ptr ptr ptr ptr) CreateIC
154 pascal GetNearestColor(word long) GetNearestColor
155 stub QueryAbort
@ -150,7 +150,7 @@ id 3
170 stub SetDCStatus
172 pascal16 SetRectRgn(word s_word s_word s_word s_word) SetRectRgn
173 pascal16 GetClipRgn(word) GetClipRgn
175 stub EnumMetaFile
175 pascal16 EnumMetaFile(word word segptr long) EnumMetaFile
176 pascal16 PlayMetaFileRecord(word ptr ptr word) PlayMetaFileRecord
179 pascal16 GetDCState(word) GetDCState
180 pascal16 SetDCState(word word) SetDCState

View File

@ -52,6 +52,7 @@ BUILTIN_DLL dll_builtin_table[] =
DLL_ENTRY( WINPROCS, DLL_FLAG_ALWAYS_USED),
DLL_ENTRY( DDEML, DLL_FLAG_NOT_USED),
DLL_ENTRY( LZEXPAND, 0),
DLL_ENTRY( W32SYS, 0),
/* Win32 DLLs */
DLL_ENTRY( ADVAPI32, 0),
DLL_ENTRY( COMCTL32, 0),

16
if1632/w32sys.spec Normal file
View File

@ -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

View File

@ -31,7 +31,10 @@ id 24
27 pascal EntryAddrProc(word word) MODULE_GetEntryPoint
28 pascal MyAlloc(word word word) MODULE_AllocateSegment
29 pascal16 ActivateAppProc(word long) ACTIVATEAPP_callback
30 pascal FormatCharDlgProc(word word word long) FormatCharDlgProc
31 pascal16 FontStyleEnumProc(ptr ptr word long) FontStyleEnumProc
32 pascal16 FontFamilyEnumProc(ptr ptr word long) FontFamilyEnumProc
# Interrupt vectors 0-255 are ordinals 100-355
# The 'word' parameter are the flags pushed on the stack by the interrupt
100 register INT_Int00Handler(word) INT_DummyHandler

View File

@ -298,6 +298,7 @@ BOOL GetOpenFileName(LPOPENFILENAME lpofn);
BOOL GetSaveFileName(LPOPENFILENAME lpofn);
BOOL PrintDlg(LPPRINTDLG lpPrint);
BOOL ReplaceText(LPFINDREPLACE lpFind);
BOOL ChooseFont(LPCHOOSEFONT lpChFont);
LRESULT FileOpenDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
LRESULT FileSaveDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
@ -306,6 +307,7 @@ LRESULT FindTextDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
LRESULT ReplaceTextDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
LRESULT PrintDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
LRESULT PrintSetupDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
LRESULT FormatCharDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
#endif /* #ifdef COMMDLG_H */

View File

@ -57,6 +57,7 @@ DECLARE_DLL(STORAGE)
DECLARE_DLL(WINPROCS)
DECLARE_DLL(DDEML)
DECLARE_DLL(LZEXPAND)
DECLARE_DLL(W32SYS)
/* 32-bit DLLs */

View File

@ -20,6 +20,7 @@ extern HLOCAL LOCAL_Handle( HANDLE ds, WORD addr );
extern WORD LOCAL_Size( HANDLE ds, HLOCAL handle );
extern WORD LOCAL_Flags( HANDLE ds, HLOCAL handle );
extern WORD LOCAL_HeapSize( HANDLE ds );
extern WORD LOCAL_CountFree( WORD ds );
extern LPSTR LOCAL_Lock( HANDLE ds, HLOCAL handle );
extern BOOL LOCAL_Unlock( HANDLE ds, HLOCAL handle );

View File

@ -37,7 +37,7 @@ typedef struct
HMENU hWindowMenu;
WORD idFirstChild; /* order is 3.1-like up to this point */
HANDLE hFrameTitle;
WORD sbStop;
WORD sbNeedUpdate;
WORD sbRecalc;
HBITMAP obmClose;
HBITMAP obmRestore;

View File

@ -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);

View File

@ -22,6 +22,8 @@ typedef enum
LANG_It /* Italian */
} WINE_LANGUAGE;
extern const char *langNames[];
/* Supported modes */
typedef enum
{

17
include/w32sys.h Normal file
View File

@ -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 */

View File

@ -2322,6 +2322,8 @@ typedef COMPAREITEMSTRUCT FAR* LPCOMPAREITEMSTRUCT;
#define LMEM_ZEROINIT 0x0040
#define LMEM_MODIFY 0x0080
#define LMEM_DISCARDABLE 0x0F00
#define LMEM_DISCARDED 0x4000
#define LMEM_LOCKCOUNT 0x00FF
#define GMEM_FIXED 0x0000
#define GMEM_MOVEABLE 0x0002

View File

@ -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;

View File

@ -89,6 +89,7 @@ typedef struct tagKEYVALUE {
LPWSTR name; /* name of value (UNICODE) or NULL for win31 */
DWORD type; /* type of value */
DWORD len; /* length of data */
DWORD lastmodified; /* time of seconds since 1.1.1970 */
LPBYTE data; /* content, may be strings, binaries, etc. */
} KEYVALUE,*LPKEYVALUE;

View File

@ -47,6 +47,12 @@ typedef struct
#define LOCAL_ARENA_FIXED 1
#define LOCAL_ARENA_MOVEABLE 3
/* Layout of a handle entry table
*
* WORD count of entries
* LOCALHANDLEENTRY[count] entries
* WORD near ptr to next table
*/
typedef struct
{
WORD addr; /* Address of the MOVEABLE block */
@ -56,26 +62,26 @@ typedef struct
typedef struct
{
WORD check; /* Heap checking flag */
WORD freeze; /* Heap frozen flag */
WORD items; /* Count of items on the heap */
WORD first; /* First item of the heap */
WORD pad1; /* Always 0 */
WORD last; /* Last item of the heap */
WORD pad2; /* Always 0 */
BYTE ncompact; /* Compactions counter */
BYTE dislevel; /* Discard level */
DWORD distotal; /* Total bytes discarded */
WORD htable; /* Pointer to handle table */
WORD hfree; /* Pointer to free handle table */
WORD hdelta; /* Delta to expand the handle table */
WORD expand; /* Pointer to expand function (unused) */
WORD pstat; /* Pointer to status structure (unused) */
DWORD notify WINE_PACKED; /* Pointer to LocalNotify() function */
WORD lock; /* Lock count for the heap */
WORD extra; /* Extra bytes to allocate when expanding */
WORD minsize; /* Minimum size of the heap */
WORD magic; /* Magic number */
WORD check; /* 00 Heap checking flag */
WORD freeze; /* 02 Heap frozen flag */
WORD items; /* 04 Count of items on the heap */
WORD first; /* 06 First item of the heap */
WORD pad1; /* 08 Always 0 */
WORD last; /* 0a Last item of the heap */
WORD pad2; /* 0c Always 0 */
BYTE ncompact; /* 0e Compactions counter */
BYTE dislevel; /* 0f Discard level */
DWORD distotal; /* 10 Total bytes discarded */
WORD htable; /* 14 Pointer to handle table */
WORD hfree; /* 16 Pointer to free handle table */
WORD hdelta; /* 18 Delta to expand the handle table */
WORD expand; /* 1a Pointer to expand function (unused) */
WORD pstat; /* 1c Pointer to status structure (unused) */
FARPROC notify WINE_PACKED; /* 1e Pointer to LocalNotify() function */
WORD lock; /* 22 Lock count for the heap */
WORD extra; /* 24 Extra bytes to allocate when expanding */
WORD minsize; /* 26 Minimum size of the heap */
WORD magic; /* 28 Magic number */
} LOCALHEAPINFO;
#ifndef WINELIB
@ -455,8 +461,9 @@ static WORD LOCAL_Compact( WORD ds, WORD minfree, WORD flags )
WORD arena;
WORD freespace = 0;
if (!(pInfo = LOCAL_GetHeap( ds ))) {
dprintf_local( stddeb, "Local_FindFreeBlock: Local heap not found\n" );
if (!(pInfo = LOCAL_GetHeap( ds )))
{
fprintf( stderr, "Local_FindFreeBlock: Local heap not found\n" );
LOCAL_PrintHeap(ds);
return 0;
}
@ -468,6 +475,11 @@ static WORD LOCAL_Compact( WORD ds, WORD minfree, WORD flags )
pArena = ARENA_PTR( ptr, arena );
if (pArena->size >= freespace) freespace = pArena->size;
}
if(freespace < ARENA_HEADER_SIZE)
freespace = 0;
else
freespace -= ARENA_HEADER_SIZE;
if (flags & LMEM_NOCOMPACT) return freespace;
@ -485,8 +497,9 @@ static HLOCAL LOCAL_FindFreeBlock( WORD ds, WORD size )
LOCALARENA *pArena;
WORD arena;
if (!(pInfo = LOCAL_GetHeap( ds ))) {
dprintf_local( stddeb, "Local_FindFreeBlock: Local heap not found\n" );
if (!(pInfo = LOCAL_GetHeap( ds )))
{
fprintf( stderr, "Local_FindFreeBlock: Local heap not found\n" );
LOCAL_PrintHeap(ds);
return 0;
}
@ -516,8 +529,9 @@ static HLOCAL LOCAL_GetBlock( WORD ds, WORD size, WORD flags )
LOCALARENA *pArena;
WORD arena;
if (!(pInfo = LOCAL_GetHeap( ds ))) {
dprintf_local( stddeb, "Local_GetBlock: Local heap not found\n");
if (!(pInfo = LOCAL_GetHeap( ds )))
{
fprintf( stderr, "Local_GetBlock: Local heap not found\n");
LOCAL_PrintHeap(ds);
return 0;
}
@ -540,7 +554,8 @@ static HLOCAL LOCAL_GetBlock( WORD ds, WORD size, WORD flags )
arena = LOCAL_FindFreeBlock( ds, size );
}
if (arena == 0) {
fprintf( stderr, "Local_GetBlock: not enough space!\n" );
fprintf( stderr, "Local_GetBlock: not enough space in heap %04x for %d bytes\n",
ds, size );
return 0;
}
@ -564,6 +579,7 @@ static HLOCAL LOCAL_GetBlock( WORD ds, WORD size, WORD flags )
return arena + ARENA_HEADER_SIZE;
}
/***********************************************************************
* LOCAL_NewHTable
*/
@ -571,56 +587,82 @@ static BOOL LOCAL_NewHTable( WORD ds )
{
char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
LOCALHEAPINFO *pInfo;
LOCALHANDLEENTRY *pEntry;
HLOCAL handle;
int i;
dprintf_local( stddeb, "Local_NewHTable\n" );
if (!(pInfo = LOCAL_GetHeap( ds ))) {
dprintf_local( stddeb, "Local heap not found\n");
LOCAL_PrintHeap(ds);
return FALSE;
if (!(pInfo = LOCAL_GetHeap( ds )))
{
fprintf( stderr, "Local heap not found\n");
LOCAL_PrintHeap(ds);
return FALSE;
}
handle = LOCAL_GetBlock( ds, pInfo->hdelta*4 + 2, LMEM_FIXED );
handle = LOCAL_GetBlock( ds, pInfo->hdelta * sizeof(LOCALHANDLEENTRY)
+ 2 * sizeof(WORD), LMEM_FIXED );
ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
pInfo = LOCAL_GetHeap( ds );
if (handle == 0) return FALSE;
*(WORD *)(ptr + handle) = 0; /* no handles in this block yet */
/* Fill the entry table */
*(WORD *)(ptr + handle) = pInfo->hdelta;
pEntry = (LOCALHANDLEENTRY *)(ptr + handle + sizeof(WORD));
for (i = pInfo->hdelta; i > 0; i--) (pEntry++)->lock = 0xff;
*(WORD *)pEntry = pInfo->htable;
pInfo->htable = handle;
return TRUE;
}
/***********************************************************************
* LOCAL_GetNewHandle
* LOCAL_GetNewHandleEntry
*/
static HLOCAL LOCAL_GetNewHandle( WORD ds )
static HLOCAL LOCAL_GetNewHandleEntry( WORD ds )
{
char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
LOCALHEAPINFO *pInfo;
WORD count;
if (!(pInfo = LOCAL_GetHeap( ds ))) {
dprintf_local( stddeb, "LOCAL_GetNewHandle: Local heap not found\n");
LOCALHANDLEENTRY *pEntry = NULL;
WORD table;
if (!(pInfo = LOCAL_GetHeap( ds )))
{
fprintf( stderr, "LOCAL_GetNewHandleEntry: Local heap not found\n");
LOCAL_PrintHeap(ds);
return 0;
}
/* Check if we need a new handle table */
if (pInfo->htable == 0) {
if (!LOCAL_NewHTable( ds )) return 0;
ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
pInfo = LOCAL_GetHeap( ds );
}
if (*(WORD *)(ptr + pInfo->htable) == pInfo->hdelta) {
if (!LOCAL_NewHTable( ds )) return 0;
ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
pInfo = LOCAL_GetHeap( ds );
/* Find a free slot in existing tables */
table = pInfo->htable;
while (table)
{
WORD count = *(WORD *)(ptr + table);
pEntry = (LOCALHANDLEENTRY *)(ptr + table + sizeof(WORD));
for (; count > 0; count--, pEntry++)
if (pEntry->lock == 0xff) break;
if (count) break;
table = *(WORD *)pEntry;
}
/* increase count */
count = (*(WORD *)(ptr + pInfo->htable))++;
dprintf_local( stddeb, "Local_GetNewHandle: %04x\n", pInfo->htable + 2 + 4*count );
return pInfo->htable + 2 + 4*count;
if (!table) /* We need to create a new table */
{
if (!LOCAL_NewHTable( ds )) return 0;
ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
pInfo = LOCAL_GetHeap( ds );
pEntry = (LOCALHANDLEENTRY *)(ptr + pInfo->htable + sizeof(WORD));
}
/* Now allocate this entry */
pEntry->lock = 0;
dprintf_local( stddeb, "LOCAL_GetNewHandleEntry(%04x): %04x\n",
ds, ((char *)pEntry - ptr) );
return (HLOCAL)((char *)pEntry - ptr);
}
/***********************************************************************
* LOCAL_FreeArena
*/
@ -634,9 +676,11 @@ static HLOCAL LOCAL_FreeArena( WORD ds, WORD arena )
if (!(pInfo = LOCAL_GetHeap( ds ))) return arena;
pArena = ARENA_PTR( ptr, arena );
if ((pArena->prev & 3) == LOCAL_ARENA_FREE) {
if ((pArena->prev & 3) == LOCAL_ARENA_FREE)
{
/* shouldn't happen */
fprintf( stderr, "LocalFreeArena: Trying to free a block twice!\n" );
fprintf( stderr, "LocalFreeArena: Trying to free block %04x twice!\n",
arena );
LOCAL_PrintHeap( ds );
return arena;
}
@ -669,6 +713,59 @@ static HLOCAL LOCAL_FreeArena( WORD ds, WORD arena )
}
/***********************************************************************
* LOCAL_FreeHandleEntry
*
* Free a handle table entry.
*/
static void LOCAL_FreeHandleEntry( WORD ds, HLOCAL handle )
{
char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
LOCALHANDLEENTRY *pEntry = (LOCALHANDLEENTRY *)(ptr + handle);
LOCALHEAPINFO *pInfo;
WORD *pTable;
WORD table, count, i;
if (!(pInfo = LOCAL_GetHeap( ds ))) return;
/* Find the table where this handle comes from */
pTable = &pInfo->htable;
while (*pTable)
{
WORD size = (*(WORD *)(ptr + *pTable)) * sizeof(LOCALHANDLEENTRY);
if ((handle >= *pTable + sizeof(WORD)) &&
(handle < *pTable + sizeof(WORD) + size)) break; /* Found it */
pTable = (WORD *)(ptr + *pTable + sizeof(WORD) + size);
}
if (!*pTable)
{
fprintf(stderr, "LOCAL_FreeHandleEntry: invalid entry %04x\n", handle);
LOCAL_PrintHeap( ds );
return;
}
/* Make the entry free */
pEntry->addr = 0; /* just in case */
pEntry->lock = 0xff;
/* Now check if all entries in this table are free */
pEntry = (LOCALHANDLEENTRY *)(ptr + *pTable + sizeof(WORD));
count = *(WORD *)(ptr + *pTable);
for (i = count; i > 0; i--, pEntry++) if (pEntry->lock != 0xff) return;
/* Remove the table from the linked list and free it */
table = *pTable;
dprintf_local( stddeb, "LOCAL_FreeHandleEntry(%04x): freeing table %04x\n",
ds, table);
*pTable = *((WORD *)(ptr + count * sizeof(*pEntry)) + 1);
LOCAL_FreeArena( ds, ARENA_HEADER( table ) );
}
/***********************************************************************
* LOCAL_Free
*
@ -677,20 +774,23 @@ static HLOCAL LOCAL_FreeArena( WORD ds, WORD arena )
HLOCAL LOCAL_Free( HANDLE ds, HLOCAL handle )
{
char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
WORD arena;
dprintf_local( stddeb, "LocalFree: %04x ds=%04x\n", handle, ds );
if (!handle) { fprintf( stderr, "LOCAL_Free: handle is 0.\n" ); return 0; }
if (HANDLE_FIXED( handle )) {
arena = ARENA_HEADER( handle );
} else {
arena = ARENA_HEADER( *(WORD *)(ptr + handle) );
dprintf_local( stddeb, "LocalFree: real block at %04x\n", arena);
if (HANDLE_FIXED( handle ))
{
if (!LOCAL_FreeArena( ds, ARENA_HEADER( handle ) )) return 0; /* OK */
else return handle; /* couldn't free it */
}
else
{
WORD arena = ARENA_HEADER( *(WORD *)(ptr + handle) );
dprintf_local( stddeb, "LocalFree: real block at %04x\n", arena );
if (LOCAL_FreeArena( ds, arena )) return handle; /* couldn't free it */
LOCAL_FreeHandleEntry( ds, handle );
return 0; /* OK */
}
arena = LOCAL_FreeArena( ds, arena );
if (arena != 0) return handle; /* couldn't free it */
return 0;
}
@ -706,26 +806,26 @@ HLOCAL LOCAL_Alloc( HANDLE ds, WORD flags, WORD size )
dprintf_local( stddeb, "LocalAlloc: %04x %d ds=%04x\n", flags, size, ds );
if (flags & LMEM_MOVEABLE) {
if (flags & LMEM_MOVEABLE)
{
LOCALHANDLEENTRY *plhe;
HLOCAL hmem;
hmem = LOCAL_GetBlock( ds, size + 2, flags );
if (hmem == 0) return 0;
handle = LOCAL_GetNewHandle( ds );
if (handle == 0) {
if (!(hmem = LOCAL_GetBlock( ds, size, flags ))) return 0;
if (!(handle = LOCAL_GetNewHandleEntry( ds )))
{
fprintf( stderr, "LocalAlloc: couldn't get handle\n");
LOCAL_FreeArena( ds, ARENA_HEADER(hmem) );
return 0;
}
ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
*(WORD *)(ptr + hmem) = handle;
plhe = (LOCALHANDLEENTRY *)(ptr + handle);
plhe->addr = hmem + 2;
plhe->addr = hmem;
plhe->flags = (BYTE)(flags >> 8);
plhe->lock = 0;
} else {
handle = LOCAL_GetBlock( ds, size, flags );
}
else handle = LOCAL_GetBlock( ds, size, flags );
return handle;
}
@ -749,14 +849,9 @@ HLOCAL LOCAL_ReAlloc( HANDLE ds, HLOCAL handle, WORD size, WORD flags )
handle, size, flags, ds );
if (!(pInfo = LOCAL_GetHeap( ds ))) return 0;
if (HANDLE_FIXED( handle )) {
blockhandle = handle;
} else {
size += 2;
blockhandle = *(WORD *)(ptr + handle);
dprintf_local( stddeb, " blockhandle %04x (%04x)\n", blockhandle,
*(WORD *)(ptr + blockhandle - 2));
}
if (HANDLE_FIXED( handle )) blockhandle = handle;
else blockhandle = *(WORD *)(ptr + handle);
arena = ARENA_HEADER( blockhandle );
dprintf_local( stddeb, "LocalReAlloc: arena is %04x\n", arena );
pArena = ARENA_PTR( ptr, arena );
@ -811,8 +906,8 @@ HLOCAL LOCAL_ReAlloc( HANDLE ds, HLOCAL handle, WORD size, WORD flags )
ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
memcpy( ptr + newhandle, ptr + (arena + ARENA_HEADER_SIZE), size );
LOCAL_FreeArena( ds, arena );
if (HANDLE_MOVEABLE( handle )) {
newhandle += 2;
if (HANDLE_MOVEABLE( handle ))
{
dprintf_local( stddeb, "LocalReAlloc: fixing handle\n");
*(WORD *)(ptr + handle) = newhandle;
newhandle = handle;
@ -831,7 +926,7 @@ static HLOCAL LOCAL_InternalLock( LPSTR heap, HLOCAL handle )
if (HANDLE_MOVEABLE(handle))
{
LOCALHANDLEENTRY *pEntry = (LOCALHANDLEENTRY *)(heap + handle);
if (pEntry->lock < 255) pEntry->lock++;
if (pEntry->lock < 0xfe) pEntry->lock++;
handle = pEntry->addr;
}
dprintf_local( stddeb, "returning %04x\n", handle );
@ -860,7 +955,7 @@ BOOL LOCAL_Unlock( WORD ds, HLOCAL handle )
if (HANDLE_MOVEABLE(handle))
{
LOCALHANDLEENTRY *pEntry = (LOCALHANDLEENTRY *)(ptr + handle);
if (!pEntry->lock || (pEntry->lock == 255)) return FALSE;
if (!pEntry->lock || (pEntry->lock == 0xff)) return FALSE;
/* For moveable block, return the new lock count */
/* (see _Windows_Internals_ p. 197) */
return --pEntry->lock;
@ -878,20 +973,40 @@ WORD LOCAL_Size( WORD ds, HLOCAL handle )
{
char *ptr = PTR_SEG_OFF_TO_LIN( CURRENT_DS, 0 );
LOCALARENA *pArena;
WORD arena;
dprintf_local( stddeb, "LocalSize: %04x ds=%04x\n", handle, ds );
if (HANDLE_FIXED( handle )) {
arena = ARENA_HEADER( handle );
} else {
arena = ARENA_HEADER( handle = *(WORD *)(ptr + handle) );
}
pArena = ARENA_PTR( ptr, arena );
if (HANDLE_MOVEABLE( handle )) handle = *(WORD *)(ptr + handle);
pArena = ARENA_PTR( ptr, ARENA_HEADER(handle) );
return pArena->next - handle;
}
/***********************************************************************
* LOCAL_Flags
*
* Implementation of LocalFlags().
*/
WORD LOCAL_Flags( WORD ds, HLOCAL handle )
{
char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
if (HANDLE_MOVEABLE(handle))
{
LOCALHANDLEENTRY *pEntry = (LOCALHANDLEENTRY *)(ptr + handle);
dprintf_local( stddeb, "LOCAL_Flags(%04x,%04x): returning %04x\n",
ds, handle, pEntry->lock | (pEntry->flags << 8) );
return pEntry->lock | (pEntry->flags << 8);
}
else
{
dprintf_local( stddeb, "LOCAL_Flags(%04x,%04x): returning 0\n",
ds, handle );
return 0;
}
}
/***********************************************************************
* LOCAL_HeapSize
*
@ -905,6 +1020,67 @@ WORD LOCAL_HeapSize( WORD ds )
}
/***********************************************************************
* LOCAL_CountFree
*
* Implementation of LocalCountFree().
*/
WORD LOCAL_CountFree( WORD ds )
{
WORD arena, total;
LOCALARENA *pArena;
char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
LOCALHEAPINFO *pInfo = LOCAL_GetHeap( ds );
total = 0;
arena = pInfo->first;
pArena = ARENA_PTR( ptr, arena );
for (;;)
{
arena = pArena->free_next;
pArena = ARENA_PTR( ptr, arena );
if (arena == pArena->free_next) break;
total += pArena->size;
}
dprintf_local( stddeb, "LOCAL_CountFree(%04x): returning %d\n", ds, total);
return total;
}
/***********************************************************************
* LOCAL_Handle
*
* Implementation of LocalHandle().
*/
HLOCAL LOCAL_Handle( WORD ds, WORD addr )
{
char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
LOCALHEAPINFO *pInfo;
WORD table;
if (!(pInfo = LOCAL_GetHeap( ds )))
{
fprintf( stderr, "LOCAL_Handle(%04x): Local heap not found\n", ds );
LOCAL_PrintHeap( ds );
return 0;
}
/* Find the address in the entry tables */
table = pInfo->htable;
while (table)
{
WORD count = *(WORD *)(ptr + table);
LOCALHANDLEENTRY *pEntry = (LOCALHANDLEENTRY*)(ptr+table+sizeof(WORD));
for (; count > 0; count--, pEntry++)
if (pEntry->addr == addr) return (HLOCAL)((char *)pEntry - ptr);
table = *(WORD *)pEntry;
}
return (HLOCAL)addr; /* Fixed block handle is addr */
}
/***********************************************************************
* LocalAlloc (KERNEL.5)
*/
@ -964,14 +1140,8 @@ WORD LocalSize( HLOCAL handle )
* LocalHandle (KERNEL.11)
*/
HLOCAL LocalHandle( WORD addr )
{
char *ptr = PTR_SEG_OFF_TO_LIN( CURRENT_DS, 0 );
dprintf_local( stddeb, "LocalHandle: %04x\n", addr );
if (HANDLE_MOVEABLE( addr )) {
addr = *(WORD *)(ptr + addr - 2);
}
return addr;
{
return LOCAL_Handle( CURRENT_DS, addr );
}
@ -980,8 +1150,7 @@ HLOCAL LocalHandle( WORD addr )
*/
WORD LocalFlags( HLOCAL handle )
{
dprintf_local( stddeb, "LocalFlags: %04x\n", handle );
return 0;
return LOCAL_Flags( CURRENT_DS, handle );
}
@ -1000,8 +1169,20 @@ WORD LocalCompact( WORD minfree )
*/
FARPROC LocalNotify( FARPROC func )
{
dprintf_local( stddeb, "LocalNotify: %08lx\n", func );
return 0;
LOCALHEAPINFO *pInfo;
FARPROC oldNotify;
WORD ds = CURRENT_DS;
if (!(pInfo = LOCAL_GetHeap( ds )))
{
fprintf( stderr, "LOCAL_Notify(%04x): Local heap not found\n", ds );
LOCAL_PrintHeap( ds );
return 0;
}
dprintf_local( stddeb, "LocalNotify(%04x): %08lx\n", ds, func );
oldNotify = pInfo->notify;
pInfo->notify = func;
return oldNotify;
}
@ -1020,16 +1201,22 @@ WORD LocalShrink( HLOCAL handle, WORD newsize )
*/
DWORD GetHeapSpaces( HMODULE module )
{
return MAKELONG( 0x7fff, 0xffff );
NE_MODULE *pModule;
WORD ds;
module = GetExePtr( module );
if (!(pModule = MODULE_GetPtr( module ))) return 0;
ds = (NE_SEG_TABLE( pModule ) + pModule->dgroup - 1)->selector;
return MAKELONG( LOCAL_CountFree( ds ), LOCAL_HeapSize( ds ) );
}
/***********************************************************************
* LocalCountFree (KERNEL.161)
*/
void LocalCountFree()
WORD LocalCountFree(void)
{
dprintf_local( stddeb, "LocalCountFree:\n" );
return LOCAL_CountFree( CURRENT_DS );
}
@ -1048,8 +1235,17 @@ WORD LocalHeapSize()
*/
WORD LocalHandleDelta( WORD delta )
{
dprintf_local( stddeb, "LocalHandleDelta: %04x\n", delta );
return 0;
LOCALHEAPINFO *pInfo;
if (!(pInfo = LOCAL_GetHeap( CURRENT_DS )))
{
fprintf( stderr, "LocalHandleDelta: Local heap not found\n");
LOCAL_PrintHeap( CURRENT_DS );
return 0;
}
if (delta) pInfo->hdelta = delta;
dprintf_local(stddeb, "LocalHandleDelta: returning %04x\n", pInfo->hdelta);
return pInfo->hdelta;
}

View File

@ -28,6 +28,7 @@ C_SRCS = \
stress.c \
toolhelp.c \
user.c \
w32sys.c \
winsocket.c \
xmalloc.c

View File

@ -164,7 +164,7 @@ BOOL BuildCommDCB(LPCSTR device, LPDCB lpdcb)
return -1;
strcpy(temp,device+5);
ptr = strtok(temp, ",");
ptr = strtok(temp, ", ");
if (COM[port].baudrate > 0)
lpdcb->BaudRate = COM[port].baudrate;
@ -172,7 +172,7 @@ BOOL BuildCommDCB(LPCSTR device, LPDCB lpdcb)
lpdcb->BaudRate = atoi(ptr);
dprintf_comm(stddeb,"BuildCommDCB: baudrate (%d)\n", lpdcb->BaudRate);
ptr = strtok(NULL, ",");
ptr = strtok(NULL, ", ");
if (islower(*ptr))
*ptr = toupper(*ptr);
@ -199,11 +199,11 @@ BOOL BuildCommDCB(LPCSTR device, LPDCB lpdcb)
return -1;
}
ptr = strtok(NULL, ",");
ptr = strtok(NULL, ", ");
dprintf_comm(stddeb, "BuildCommDCB: charsize (%c)\n", *ptr);
lpdcb->ByteSize = *ptr - '0';
ptr = strtok(NULL, ",");
ptr = strtok(NULL, ", ");
dprintf_comm(stddeb, "BuildCommDCB: stopbits (%c)\n", *ptr);
switch (*ptr) {
case '1':

View File

@ -320,6 +320,8 @@ static LONG FILEDLG_WMInitDialog(HWND hWnd, WPARAM wParam, LPARAM lParam)
LPSTR pstr;
SetWindowLong(hWnd, DWL_USER, lParam);
lpofn = (LPOPENFILENAME)lParam;
if (lpofn->lpstrTitle)
SendMessage( hWnd, WM_SETTEXT, 0, (LPARAM)lpofn->lpstrTitle );
/* read custom filter information */
if (lpofn->lpstrCustomFilter)
{
@ -1120,10 +1122,12 @@ struct CCPRIVATE
LPCHOOSECOLOR lpcc; /* points to public known data structure */
int nextuserdef; /* next free place in user defined color array */
HDC hdcMem; /* color graph used for BitBlt() */
HBITMAP hbmMem; /* color graph bitmap */
RECT fullsize; /* original dialog window size */
UINT msetrgb; /* # of SETRGBSTRING message (today not used) */
RECT old3angle; /* last position of l-marker */
RECT oldcross; /* last position of color/satuation marker */
BOOL updating; /* to prevent recursive WM_COMMAND/EN_UPDATE procesing */
int h;
int s;
int l; /* for temporary storing of hue,sat,lum */
@ -1501,7 +1505,6 @@ static void CC_PaintTriangle(HWND hDlg,int y)
static void CC_PaintCross(HWND hDlg,int x,int y)
{
HDC hDC;
long temp;
int w=GetDialogBaseUnits();
HWND hwnd=GetDlgItem(hDlg,0x2c6);
struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong(hDlg, DWL_USER);
@ -1512,56 +1515,34 @@ static void CC_PaintCross(HWND hDlg,int x,int y)
if (IsWindowVisible(GetDlgItem(hDlg,0x2c6))) /* if full size */
{
GetClientRect(hwnd,&rect);
hDC=GetDC(hwnd);
SelectClipRgn(hDC,CreateRectRgnIndirect(&rect));
hPen=CreatePen(PS_SOLID,2,0);
hPen=SelectObject(hDC,hPen);
temp=(long)rect.right*(long)x;
point.x=temp/(long)MAXHORI;
temp=(long)rect.bottom*(long)y;
point.y=rect.bottom-temp/(long)MAXVERT;
point.x=((long)rect.right*(long)x)/(long)MAXHORI;
point.y=rect.bottom-((long)rect.bottom*(long)y)/(long)MAXVERT;
if (lpp->oldcross.left!=lpp->oldcross.right)
BitBlt(hDC,lpp->oldcross.left,lpp->oldcross.top,
lpp->oldcross.right-lpp->oldcross.left,
lpp->oldcross.bottom-lpp->oldcross.top,
lpp->hdcMem,lpp->oldcross.left,lpp->oldcross.top,SRCCOPY);
lpp->oldcross.left =point.x-w-1;
lpp->oldcross.right =point.x+w+1;
lpp->oldcross.top =point.y-w-1;
lpp->oldcross.bottom=point.y+w+1;
if (point.y+w/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);
}
lpp->oldcross.bottom=point.y+w+1;
MoveTo(hDC,point.x-w,point.y);
LineTo(hDC,point.x+w,point.y);
MoveTo(hDC,point.x,point.y-w);
LineTo(hDC,point.x,point.y+w);
DeleteObject(SelectObject(hDC,hPen));
ReleaseDC(hwnd,hDC);
}
}
#define XSTEPS 36
#define YSTEPS 48
#define XSTEPS 48
#define YSTEPS 24
/***********************************************************************
@ -1575,14 +1556,13 @@ static void CC_PrepareColorGraph(HWND hDlg)
HBRUSH hbrush;
HDC hdc ;
RECT rect,client;
HBITMAP hbmMem;
HCURSOR hcursor=SetCursor(LoadCursor(0,IDC_WAIT));
GetClientRect(hwnd,&client);
hdc=GetDC(hwnd);
lpp->hdcMem = CreateCompatibleDC(hdc);
hbmMem = CreateCompatibleBitmap(hdc,client.right,client.bottom);
SelectObject(lpp->hdcMem,hbmMem);
lpp->hbmMem = CreateCompatibleBitmap(hdc,client.right,client.bottom);
SelectObject(lpp->hdcMem,lpp->hbmMem);
xdif=client.right /XSTEPS;
ydif=client.bottom/YSTEPS+1;
@ -1607,7 +1587,6 @@ static void CC_PrepareColorGraph(HWND hDlg)
}
ReleaseDC(hwnd,hdc);
SetCursor(hcursor);
/* FIXME perhaps we should do it only ONCE for all, like hCDRom,.... ? */
}
/***********************************************************************
@ -1675,17 +1654,20 @@ static void CC_PaintLumBar(HWND hDlg,int hue,int sat)
static void CC_EditSetRGB(HWND hDlg,COLORREF cr)
{
char buffer[10];
struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong(hDlg, DWL_USER);
int r=GetRValue(cr);
int g=GetGValue(cr);
int b=GetBValue(cr);
if (IsWindowVisible(GetDlgItem(hDlg,0x2c6))) /* if full size */
{
lpp->updating=TRUE;
sprintf(buffer,"%d",r);
SetWindowText(GetDlgItem(hDlg,0x2c2),buffer);
sprintf(buffer,"%d",g);
SetWindowText(GetDlgItem(hDlg,0x2c3),buffer);
sprintf(buffer,"%d",b);
SetWindowText(GetDlgItem(hDlg,0x2c4),buffer);
lpp->updating=FALSE;
}
}
@ -1695,14 +1677,18 @@ static void CC_EditSetRGB(HWND hDlg,COLORREF cr)
static void CC_EditSetHSL(HWND hDlg,int h,int s,int l)
{
char buffer[10];
struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong(hDlg, DWL_USER);
lpp->updating=TRUE;
if (IsWindowVisible(GetDlgItem(hDlg,0x2c6))) /* if full size */
{
lpp->updating=TRUE;
sprintf(buffer,"%d",h);
SetWindowText(GetDlgItem(hDlg,0x2bf),buffer);
sprintf(buffer,"%d",s);
SetWindowText(GetDlgItem(hDlg,0x2c0),buffer);
sprintf(buffer,"%d",l);
SetWindowText(GetDlgItem(hDlg,0x2c1),buffer);
lpp->updating=FALSE;
}
CC_PaintLumBar(hDlg,h,s);
}
@ -1911,12 +1897,13 @@ static LRESULT CC_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam)
HDC hdc;
COLORREF *cr;
struct CCPRIVATE * lpp=(struct CCPRIVATE *)GetWindowLong(hDlg, DWL_USER);
dprintf_commdlg(stddeb,"CC_WMCommand wParam=%x lParam=%lx\n",wParam,lParam);
switch (wParam)
{
case 0x2c2: /* edit notify RGB */
case 0x2c3:
case 0x2c4:
if (HIWORD(lParam)==EN_UPDATE)
if (HIWORD(lParam)==EN_UPDATE && !lpp->updating)
{
i=CC_CheckDigitsInEdit(LOWORD(lParam),255);
r=GetRValue(lpp->lpcc->rgbResult);
@ -1946,7 +1933,7 @@ static LRESULT CC_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam)
case 0x2bf: /* edit notify HSL */
case 0x2c0:
case 0x2c1:
if (HIWORD(lParam)==EN_UPDATE)
if (HIWORD(lParam)==EN_UPDATE && !lpp->updating)
{
i=CC_CheckDigitsInEdit(LOWORD(lParam),wParam==0x2bf?239:240);
xx=0;
@ -2131,7 +2118,8 @@ LRESULT ColorDlgProc(HWND hDlg, UINT message,
case WM_INITDIALOG:
return CC_WMInitDialog(hDlg,wParam,lParam);
case WM_NCDESTROY:
/* FIXME: what about lpp->hdcMem ? */
DeleteDC(lpp->hdcMem);
DeleteObject(lpp->hbmMem);
free(lpp);
SetWindowLong(hDlg, DWL_USER, 0L); /* we don't need it anymore */
break;
@ -2158,3 +2146,84 @@ LRESULT ColorDlgProc(HWND hDlg, UINT message,
return FALSE ;
}
/***********************************************************************
* ChooseFont (COMMDLG.15)
--April 1996--
please note: ChooseFont etc. are still under construction
*/
BOOL ChooseFont(LPCHOOSEFONT lpChFont)
{
HANDLE hInst, hDlgTmpl;
BOOL bRet;
dprintf_commdlg(stddeb,"ChoseFont\n");
hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_CHOOSE_FONT );
hInst = WIN_GetWindowInstance( lpChFont->hwndOwner );
bRet = DialogBoxIndirectParam( hInst, hDlgTmpl, lpChFont->hwndOwner,
MODULE_GetWndProcEntry16("FormatCharDlgProc"),
(DWORD)lpChFont );
SYSRES_FreeResource( hDlgTmpl );
return bRet;
}
/***********************************************************************
* FontStyleEnumProc (COMMDLG.18)
*/
int FontStyleEnumProc(LOGFONT *lf ,TEXTMETRIC *tm, int fonttype, LPARAM lParam)
{
dprintf_commdlg(stddeb,"FontStyleEnumProc: font=%s (height=%d)\n",lf->lfFaceName,lf->lfHeight);
return 1;
}
/***********************************************************************
* FontFamilyEnumProc (COMMDLG.19)
*/
int FontFamilyEnumProc(LOGFONT *lf ,TEXTMETRIC *tm, int fonttype, LPARAM lParam)
{
dprintf_commdlg(stddeb,"FontFamilyEnumProc: font=%s\n",lf->lfFaceName);
return 1;
}
/***********************************************************************
* ColorDlgProc (COMMDLG.16)
*/
LRESULT FormatCharDlgProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
FARPROC enumCallback;
switch (wMsg)
{
case WM_INITDIALOG:
dprintf_commdlg(stddeb,"FormatCharDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
ShowWindow(hDlg, SW_SHOWNORMAL);
hdc = GetDC(hDlg);
if (hdc)
{
HCURSOR hcursor=SetCursor(LoadCursor(0,IDC_WAIT));
/*
currently only called for testing of 2 necessary EnumProcs
*/
enumCallback = MODULE_GetWndProcEntry16("FontFamilyEnumProc");
EnumFontFamilies (hdc, NULL,enumCallback ,NULL);
enumCallback = MODULE_GetWndProcEntry16("FontStyleEnumProc");
EnumFontFamilies(hdc, /* for example : */ "COURIER",enumCallback,NULL);
ReleaseDC(hDlg,hdc);
SetCursor(hcursor);
}
return (TRUE);
case WM_COMMAND:
switch (wParam)
{
case IDOK:
EndDialog(hDlg, TRUE);
return(TRUE);
case IDCANCEL:
EndDialog(hDlg, FALSE);
return(TRUE);
}
return(FALSE);
}
return FALSE;
}

View File

@ -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 */

View File

@ -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 @@ split_keypath(LPCWSTR wp,LPWSTR **wpv,int *wpc) {
}
#define FREE_KEY_PATH free(wps[0]);free(wps);
/**
/*
* Shell initialisation, allocates keys.
* FIXME:should set default values too
*/
void
SHELL_Init() {
struct passwd *pwd;
HKEY cl_r_hkey,c_u_hkey;
#define ADD_ROOT_KEY(xx) \
xx = (LPKEYSTRUCT)xmalloc(sizeof(KEYSTRUCT));\
memset(xx,'\0',sizeof(KEYSTRUCT));\
xx->keyname= strdupA2W("<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 @@ SHELL_Init() {
* old registry database files.
*
* Global:
* DWORD version
* DWORD nrofkeys
* KEY keys[nrofkeys]
*
* KEY:
* USTRING name
* USTRING class
* DWORD nrofvalues
* VALUE vals[nrofvalues]
* DWORD nrofsubkeys
* KEY keys[nrofsubkeys]
*
* Value:
* USTRING name
* DWORD type
* DWORD len
* BYTE data[len]
*
* USTRING:
* DWORD len (len==0 means data=NULL)
* BYTE data[len]
* "WINE REGISTRY Version %d"
* subkeys....
* Subkeys:
* keyname
* valuename=lastmodified,type,data
* ...
* subkeys
* ...
* keyname,valuename,stringdata:
* the usual ascii characters from 0x00-0xff (well, not 0x00)
* and \uXXXX as UNICODE value XXXX with XXXX>0xff
* ( "=\\\t" escaped in \uXXXX form.)
* type,lastmodified:
* int
*
*
* All _write_XXX and _read_XXX functions return !0 on sucess.
* FIXME: doesn't save 'class' (what does it mean anyway?), nor flags.
*/
static void
_write_USTRING(FILE *F,LPWSTR wstr,int escapeeq) {
LPWSTR s;
int doescape;
static int
_write_DWORD(FILE *F,DWORD dw) {
return fwrite(&dw,sizeof(dw),1,F);
}
static int
_write_USTRING(FILE *F,LPWSTR str) {
int len;
if (str==NULL) {
if (!_write_DWORD(F,0))
return 0;
} else {
len=strlenW(str)*2+2;
if (!_write_DWORD(F,len))
return 0;
if (!fwrite(str,len,1,F))
return 0;
if (wstr==NULL) {
/* FIXME: NULL equals empty string... I hope
* the empty string isn't a valid valuename
*/
return;
}
s=wstr;
while (*s) {
doescape=0;
if (*s>0xff)
doescape = 1;
if (*s=='\n')
doescape = 1;
if (escapeeq && *s=='=')
doescape = 1;
if (*s=='\\')
fputc(*s,F); /* if \\ than put it twice. */
if (doescape)
fprintf(F,"\\u%04x",*((unsigned short*)s));
else
fputc(*s,F);
s++;
}
return 1;
}
static int
_do_save_subkey(FILE *F,LPKEYSTRUCT lpkey) {
_do_save_subkey(FILE *F,LPKEYSTRUCT lpkey,int level) {
LPKEYSTRUCT lpxkey;
int nrofkeys;
int i;
nrofkeys= 0;
lpxkey = lpkey;
while (lpxkey) {
if (!(lpxkey->flags & REG_OPTION_VOLATILE))
nrofkeys++;
lpxkey = lpxkey->next;
}
if (!_write_DWORD(F,nrofkeys))
return 0;
int i,tabs,j;
lpxkey = lpkey;
while (lpxkey) {
if (!(lpxkey->flags & REG_OPTION_VOLATILE)) {
if (!_write_USTRING(F,lpxkey->keyname))
return 0;
if (!_write_USTRING(F,lpxkey->class))
return 0;
if (!_write_DWORD(F,lpxkey->nrofvalues))
return 0;
for (tabs=level;tabs--;)
fputc('\t',F);
_write_USTRING(F,lpxkey->keyname,1);
fputs("\n",F);
for (i=0;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 @@ _do_save_subkey(FILE *F,LPKEYSTRUCT lpkey) {
static int
_do_savesubreg(FILE *F,LPKEYSTRUCT lpkey) {
if (!_write_DWORD(F,REGISTRY_SAVE_VERSION))
return 0;
return _do_save_subkey(F,lpkey->nextsub);
fprintf(F,"WINE REGISTRY Version %d\n",REGISTRY_SAVE_VERSION);
return _do_save_subkey(F,lpkey->nextsub,0);
}
static void
_SaveSubReg(LPKEYSTRUCT lpkey,char *fn) {
FILE *F;
F=fopen(fn,"wb");
F=fopen(fn,"w");
if (F==NULL) {
fprintf(stddeb,__FILE__":_SaveSubReg:Couldn't open %s for writing: %s\n",
fn,strerror(errno)
@ -337,105 +358,307 @@ _SaveSubReg(LPKEYSTRUCT lpkey,char *fn) {
void
SHELL_SaveRegistry() {
_SaveSubReg(key_classes_root,SAVE_CLASSES_ROOT);
_SaveSubReg(key_current_user,SAVE_CURRENT_USER);
_SaveSubReg(key_local_machine,SAVE_LOCAL_MACHINE);
_SaveSubReg(key_users,SAVE_USERS);
char *fn;
struct passwd *pwd;
pwd=getpwuid(getuid());
if (pwd!=NULL && pwd->pw_dir!=NULL) {
fn=(char*)xmalloc(strlen(pwd->pw_dir)+strlen(WINE_PREFIX)+strlen(SAVE_CURRENT_USER)+2);
strcpy(fn,pwd->pw_dir);
strcat(fn,WINE_PREFIX);
/* create the directory. don't care about errorcodes. */
mkdir(fn,0755); /* drwxr-xr-x */
strcat(fn,"/");
strcat(fn,SAVE_CURRENT_USER);
_SaveSubReg(key_current_user,fn);
free(fn);
fn=(char*)xmalloc(strlen(pwd->pw_dir)+strlen(WINE_PREFIX)+strlen(SAVE_LOCAL_MACHINE)+1);
strcpy(fn,pwd->pw_dir);
strcat(fn,WINE_PREFIX"/"SAVE_LOCAL_MACHINE);
_SaveSubReg(key_local_machine,fn);
free(fn);
} else {
fprintf(stderr,"SHELL_SaveRegistry:failed to get homedirectory of UID %d.\n",getuid());
}
}
/************************ LOAD Registry Function ****************************/
/* FIXME:
* Currently overwrites any old registry data (leaks it away)
* should better be a merge, or ?
/* reads a line including dynamically enlarging the readbuffer and throwing
* away comments
*/
static int
_read_line(FILE *F,char **buf,int *len) {
char *s,*curread;
int mylen,curoff;
static int
_read_DWORD(FILE *F,DWORD *dw) {
return fread(dw,sizeof(DWORD),1,F);
}
static int
_read_USTRING(FILE *F,LPWSTR *str) {
DWORD len;
if (!_read_DWORD(F,&len))
return 0;
if (len==0) {
*str=NULL;
return 1;
}
*str=xmalloc(len);
return fread(*str,len,1,F);
}
static int
_do_load_subkey(FILE *F,LPKEYSTRUCT lpkey) {
DWORD howmuch;
LPKEYSTRUCT *lplpkey,lpxkey;
int i;
if (!_read_DWORD(F,&howmuch))
return 0;
/* no subkeys? */
if (howmuch==0)
return 1;
lplpkey = &(lpkey->nextsub);
while (howmuch--) {
*lplpkey= (LPKEYSTRUCT)xmalloc(sizeof(KEYSTRUCT));
memset(*lplpkey,'\0',sizeof(KEYSTRUCT));
lpxkey = *lplpkey;
if (!_read_USTRING(F,&(lpxkey->keyname)))
return 0;
if (!_read_USTRING(F,&(lpxkey->class)))
return 0;
if (!_read_DWORD(F,&(lpxkey->nrofvalues)))
return 0;
if (lpxkey->nrofvalues) {
lpxkey->values = (LPKEYVALUE)xmalloc(
lpxkey->nrofvalues*sizeof(KEYVALUE)
);
for (i=0;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 @@ _LoadSubReg(LPKEYSTRUCT lpkey,char *fn) {
void
SHELL_LoadRegistry() {
char *fn;
struct passwd *pwd;
if (key_classes_root==NULL)
SHELL_Init();
_LoadSubReg(key_classes_root,SAVE_CLASSES_ROOT);
_LoadSubReg(key_current_user,SAVE_CURRENT_USER);
_LoadSubReg(key_local_machine,SAVE_LOCAL_MACHINE);
_LoadSubReg(key_users,SAVE_USERS);
/* load the machine-wide defaults first */
_LoadSubReg(key_current_user,SAVE_CURRENT_USER_DEFAULT);
_LoadSubReg(key_local_machine,SAVE_LOCAL_MACHINE_DEFAULT);
/* load the user saved registry. overwriting only newer entries */
pwd=getpwuid(getuid());
if (pwd!=NULL && pwd->pw_dir!=NULL) {
fn=(char*)xmalloc(strlen(pwd->pw_dir)+strlen(WINE_PREFIX)+strlen(SAVE_CURRENT_USER)+1);
strcpy(fn,pwd->pw_dir);
strcat(fn,WINE_PREFIX"/"SAVE_CURRENT_USER);
_LoadSubReg(key_current_user,fn);
free(fn);
fn=(char*)xmalloc(strlen(pwd->pw_dir)+strlen(WINE_PREFIX)+strlen(SAVE_LOCAL_MACHINE)+1);
strcpy(fn,pwd->pw_dir);
strcat(fn,WINE_PREFIX"/"SAVE_LOCAL_MACHINE);
_LoadSubReg(key_local_machine,fn);
free(fn);
} else {
fprintf(stderr,"SHELL_LoadRegistry:failed to get homedirectory of UID %d.\n",getuid());
}
/* FIXME: load all users and their resp. pwd->pw_dir/.wine/user.reg
* (later, when a win32 registry editing tool becomes avail.)
*/
}
/********************* API FUNCTIONS ***************************************/
/*
* Open Keys.
* Open Keys.
*
* All functions are stubs to RegOpenKeyExW where all the
* magic happens.
@ -508,6 +753,7 @@ RegOpenKeyExW(
}
split_keypath(lpszSubKey,&wps,&wpc);
i = 0;
while ((i<wpc) && (wps[i][0]=='\0')) i++;
lpxkey = lpNextKey;
while (i<wpc) {
lpxkey=lpNextKey->nextsub;
@ -647,6 +893,7 @@ RegCreateKeyExW(
}
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 @@ RegSetValueExW(
if (lpkey->values[i].data !=NULL)
free(lpkey->values[i].data);
lpkey->values[i].data = (LPBYTE)xmalloc(cbData);
lpkey->values[i].lastmodified = time(NULL);
memcpy(lpkey->values[i].data,lpbData,cbData);
return SHELL_ERROR_SUCCESS;
}

View File

@ -24,30 +24,33 @@ WORD USER_HeapSel = 0;
*/
WORD GetFreeSystemResources( WORD resType )
{
DWORD user, gdi;
int userPercent, gdiPercent;
switch(resType)
{
case GFSR_USERRESOURCES:
user = GetHeapSpaces( USER_HeapSel );
gdi = 0xffffffff;
userPercent = (int)LOCAL_CountFree( USER_HeapSel ) * 100 /
LOCAL_HeapSize( USER_HeapSel );
gdiPercent = 100;
break;
case GFSR_GDIRESOURCES:
gdi = GetHeapSpaces( GDI_HeapSel );
user = 0xffffffff;
gdiPercent = (int)LOCAL_CountFree( GDI_HeapSel ) * 100 /
LOCAL_HeapSize( GDI_HeapSel );
userPercent = 100;
break;
case GFSR_SYSTEMRESOURCES:
user = GetHeapSpaces( USER_HeapSel );
gdi = GetHeapSpaces( GDI_HeapSel );
userPercent = (int)LOCAL_CountFree( USER_HeapSel ) * 100 /
LOCAL_HeapSize( USER_HeapSel );
gdiPercent = (int)LOCAL_CountFree( GDI_HeapSel ) * 100 /
LOCAL_HeapSize( GDI_HeapSel );
break;
default:
return 0;
}
if (user > gdi) return LOWORD(gdi) * 100 / HIWORD(gdi);
else return LOWORD(user) * 100 / HIWORD(user);
return (WORD)MIN( userPercent, gdiPercent );
}

23
misc/w32sys.c Normal file
View File

@ -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;
}

View File

@ -2,6 +2,7 @@
* Metafile functions
*
* Copyright David W. Metcalfe, 1994
* Niels de Carpentier, 1996
*
*/
@ -12,7 +13,7 @@
#include "file.h"
#include "metafile.h"
#include "stddebug.h"
/* #define DEBUG_METAFILE */
#include "callback.h"
#include "debug.h"
#define HTINCR 10 /* handle table allocation size increment */
@ -23,52 +24,60 @@ static int HTLen; /* allocated length of handle table */
/******************************************************************
* GetMetafile GDI.124 By Kenny MacDonald 30 Nov 94
*/
HMETAFILE GetMetaFile(LPSTR lpFilename)
{
HMETAFILE hmf;
METAFILE *mf;
METAHEADER *mh;
HFILE hFile;
DWORD size;
dprintf_metafile(stddeb,"GetMetaFile: %s\n", lpFilename);
if (!lpFilename)
return 0;
hmf = GlobalAlloc(GMEM_MOVEABLE, sizeof(METAFILE));
mf = (METAFILE *)GlobalLock(hmf);
if (!mf) {
GlobalFree(hmf);
return 0;
}
mf->hMetaHdr = GlobalAlloc(GMEM_MOVEABLE, MFHEADERSIZE);
mh = (METAHEADER *)GlobalLock(mf->hMetaHdr);
hmf = GlobalAlloc(GMEM_MOVEABLE, MFHEADERSIZE);
mh = (METAHEADER *)GlobalLock(hmf);
if (!mh) {
GlobalFree(mf->hMetaHdr);
GlobalFree(hmf);
return 0;
}
strcpy(mf->Filename, lpFilename);
mf->wMagic = METAFILE_MAGIC;
if ((mf->hFile = _lopen(lpFilename, OF_READ)) == HFILE_ERROR) {
GlobalFree(mf->hMetaHdr);
if ((hFile = _lopen(lpFilename, OF_READ)) == HFILE_ERROR) {
GlobalFree(hmf);
return 0;
}
if (FILE_Read(mf->hFile, (char *)mh, MFHEADERSIZE) == HFILE_ERROR) {
GlobalFree(mf->hMetaHdr);
if (FILE_Read(hFile, (char *)mh, MFHEADERSIZE) == HFILE_ERROR) {
GlobalFree(hmf);
return 0;
}
_lclose(mf->hFile);
size = mh->mtSize * 2; /* alloc memory for whole metafile */
GlobalUnlock(hmf);
hmf = GlobalReAlloc(hmf,size,GMEM_MOVEABLE);
mh = (METAHEADER *)GlobalLock(hmf);
if (!mh) {
GlobalFree(hmf);
return 0;
}
if (FILE_Read(hFile, (char*)mh + mh->mtHeaderSize * 2,
size - mh->mtHeaderSize * 2) == HFILE_ERROR) {
GlobalFree(hmf);
return 0;
}
_lclose(hFile);
if (mh->mtType != 1) {
GlobalFree(mf->hMetaHdr);
GlobalFree(hmf);
return 0;
}
GlobalUnlock(mf->hMetaHdr);
GlobalUnlock(hmf);
return hmf;
@ -77,34 +86,30 @@ HMETAFILE GetMetaFile(LPSTR lpFilename)
/******************************************************************
* CreateMetafile GDI.125
*/
HANDLE CreateMetaFile(LPCTSTR lpFilename)
{
DC *dc;
HANDLE handle;
METAFILE *mf;
METAHEADER *mh;
HANDLETABLE *ht;
int hFile;
dprintf_metafile(stddeb,"CreateMetaFile: %s\n", lpFilename);
handle = GDI_AllocObject(sizeof(DC), METAFILE_DC_MAGIC);
if (!handle) return 0;
if (!handle)
return 0;
dc = (DC *)GDI_HEAP_LIN_ADDR(handle);
if (!(dc->w.hMetaFile = GlobalAlloc(GMEM_MOVEABLE, sizeof(METAFILE)))) {
if (!(dc->w.hMetaFile = GlobalAlloc(GMEM_MOVEABLE, sizeof(METAHEADER)))) {
GDI_FreeObject(handle);
return 0;
}
mf = (METAFILE *)GlobalLock(dc->w.hMetaFile);
if (!(mf->hMetaHdr = GlobalAlloc(GMEM_MOVEABLE, sizeof(METAHEADER))))
{
GDI_FreeObject(handle);
GlobalFree(dc->w.hMetaFile);
return 0;
}
mh = (METAHEADER *)GlobalLock(mf->hMetaHdr);
mh = (METAHEADER *)GlobalLock(dc->w.hMetaFile);
mf->wMagic = METAFILE_MAGIC;
mh->mtHeaderSize = MFHEADERSIZE / 2;
mh->mtVersion = MFVERSION;
mh->mtSize = MFHEADERSIZE / 2;
@ -114,15 +119,15 @@ HANDLE CreateMetaFile(LPCTSTR lpFilename)
if (lpFilename) /* disk based metafile */
{
mh->mtType = 1;
strcpy(mf->Filename, lpFilename);
mf->hFile = _lcreat(lpFilename, 0);
if (_lwrite(mf->hFile, (char *)mh, MFHEADERSIZE) == -1)
mh->mtType = 1; /* disk */
hFile = _lcreat(lpFilename, 0);
if (_lwrite(hFile, (char *)mh, MFHEADERSIZE) == -1)
{
GlobalFree(mf->hMetaHdr);
GlobalFree(dc->w.hMetaFile);
return 0;
}
mh->mtNoParameters = hFile; /* store file descriptor here */
/* windows probably uses this too*/
}
else /* memory based metafile */
mh->mtType = 0;
@ -131,63 +136,102 @@ HANDLE CreateMetaFile(LPCTSTR lpFilename)
HTLen = HTINCR;
hHT = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,
sizeof(HANDLETABLE) * HTLen);
ht = (HANDLETABLE *)GlobalLock(hHT);
GlobalUnlock(mf->hMetaHdr);
GlobalUnlock(dc->w.hMetaFile);
return handle;
}
/******************************************************************
* CopyMetafile GDI.151 Niels de Carpentier, April 1996
*/
HMETAFILE CopyMetaFile(HMETAFILE hSrcMetaFile, LPCSTR lpFilename)
{
HMETAFILE handle = 0;
METAHEADER *mh;
METAHEADER *mh2;
int hFile;
dprintf_metafile(stddeb,"CopyMetaFile: %s\n", lpFilename);
mh = (METAHEADER *)GlobalLock(hSrcMetaFile);
if (!mh)
return 0;
if (lpFilename) /* disk based metafile */
{
hFile = _lcreat(lpFilename, 0);
if (_lwrite(hFile, (char *)mh, mh->mtSize * 2) == -1)
{
_lclose(hFile);
return 0;
}
_lclose(hFile);
}
else /* memory based metafile */
{
handle = GlobalAlloc(GMEM_MOVEABLE,mh->mtSize * 2);
mh2 = (METAHEADER *)GlobalLock(handle);
memcpy(mh2,mh, mh->mtSize * 2);
GlobalUnlock(handle);
}
return handle;
}
/******************************************************************
* CloseMetafile GDI.126
*/
HMETAFILE CloseMetaFile(HDC hdc)
{
DC *dc;
METAFILE *mf;
METAHEADER *mh;
HMETAFILE hmf;
/* METARECORD *mr = (METARECORD *)&buffer;*/
HFILE hFile;
dprintf_metafile(stddeb,"CloseMetaFile\n");
dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
if (!dc) return 0;
mf = (METAFILE *)GlobalLock(dc->w.hMetaFile);
mh = (METAHEADER *)GlobalLock(mf->hMetaHdr);
if (!dc)
return 0;
mh = (METAHEADER *)GlobalLock(dc->w.hMetaFile);
/* Construct the end of metafile record - this is documented
* in SDK Knowledgebase Q99334.
*/
if (!MF_MetaParam0(dc, META_EOF))
{
GlobalFree(mf->hMetaHdr);
GlobalFree(dc->w.hMetaFile);
return 0;
}
if (mh->mtType == 1) /* disk based metafile */
{
if (_llseek(mf->hFile, 0L, 0) == -1)
{
GlobalFree(mf->hMetaHdr);
GlobalFree(dc->w.hMetaFile);
return 0;
}
if (_lwrite(mf->hFile, (char *)mh, MFHEADERSIZE) == -1)
{
GlobalFree(mf->hMetaHdr);
GlobalFree(dc->w.hMetaFile);
return 0;
}
_lclose(mf->hFile);
hFile = mh->mtNoParameters;
mh->mtNoParameters = 0;
if (_llseek(hFile, 0L, 0) == -1)
{
GlobalFree(dc->w.hMetaFile);
return 0;
}
if (_lwrite(hFile, (char *)mh, MFHEADERSIZE) == -1)
{
GlobalFree(dc->w.hMetaFile);
return 0;
}
_lclose(hFile);
}
/* delete the handle table */
GlobalFree(hHT);
GlobalUnlock(mf->hMetaHdr);
hmf = dc->w.hMetaFile;
GlobalUnlock(hmf);
GDI_FreeObject(hdc);
@ -198,14 +242,14 @@ HMETAFILE CloseMetaFile(HDC hdc)
/******************************************************************
* DeleteMetafile GDI.127
*/
BOOL DeleteMetaFile(HMETAFILE hmf)
{
METAFILE *mf = (METAFILE *)GlobalLock(hmf);
METAHEADER *mh = (METAHEADER *)GlobalLock(hmf);
if (!mf || mf->wMagic != METAFILE_MAGIC)
if (!mh)
return FALSE;
GlobalFree(mf->hMetaHdr);
GlobalFree(hmf);
return TRUE;
}
@ -214,60 +258,73 @@ BOOL DeleteMetaFile(HMETAFILE hmf)
/******************************************************************
* PlayMetafile GDI.123
*/
BOOL PlayMetaFile(HDC hdc, HMETAFILE hmf)
{
METAFILE *mf = (METAFILE *)GlobalLock(hmf);
METAHEADER *mh;
METAHEADER *mh = (METAHEADER *)GlobalLock(hmf);
METARECORD *mr;
HANDLETABLE *ht;
char *buffer = (char *)NULL;
if (mf->wMagic != METAFILE_MAGIC)
return FALSE;
mh = (METAHEADER *)GlobalLock(mf->hMetaHdr);
if (mh->mtType == 1) /* disk based metafile */
{
mf->hFile = _lopen(mf->Filename, OF_READ);
mf->hBuffer = GlobalAlloc(GMEM_MOVEABLE, mh->mtMaxRecord * 2);
buffer = (char *)GlobalLock(mf->hBuffer);
_llseek(mf->hFile, mh->mtHeaderSize * 2, 0);
mf->MetaOffset = mh->mtHeaderSize * 2;
}
else if (mh->mtType == 0) /* memory based metafile */
mf->MetaOffset = mh->mtHeaderSize * 2;
else /* not a valid metafile type */
return FALSE;
int offset = 0;
dprintf_metafile(stddeb,"PlayMetaFile(%04x %04x)\n",hdc,hmf);
/* create the handle table */
hHT = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT,
sizeof(HANDLETABLE) * mh->mtNoObjects);
ht = (HANDLETABLE *)GlobalLock(hHT);
/* loop through metafile playing records */
while (mf->MetaOffset < mh->mtSize * 2)
offset = mh->mtHeaderSize * 2;
while (offset < mh->mtSize * 2)
{
if (mh->mtType == 1) /* disk based metafile */
{
FILE_Read(mf->hFile, buffer, sizeof(METARECORD));
mr = (METARECORD *)buffer;
FILE_Read(mf->hFile, (char *)(mr->rdParam + 1), (mr->rdSize * 2) -
sizeof(METARECORD));
mf->MetaOffset += mr->rdSize * 2;
}
else /* memory based metafile */
{
mr = (METARECORD *)((char *)mh + mf->MetaOffset);
mf->MetaOffset += mr->rdSize * 2;
}
mr = (METARECORD *)((char *)mh + offset);
dprintf_metafile(stddeb,"offset = %04x size = %08lx function = %04x\n",
offset,mr->rdSize,mr->rdFunction);
offset += mr->rdSize * 2;
PlayMetaFileRecord(hdc, ht, mr, mh->mtNoObjects);
}
/* close disk based metafile and free buffer */
if (mh->mtType == 1)
/* free handle table */
GlobalFree(hHT);
return TRUE;
}
/******************************************************************
* EnumMetafile GDI.175
* Niels de carpentier, april 1996
*/
BOOL EnumMetaFile(HDC hdc, HMETAFILE hmf, MFENUMPROC lpEnumFunc,LPARAM lpData)
{
METAHEADER *mh = (METAHEADER *)GlobalLock(hmf);
METARECORD *mr;
HANDLETABLE *ht;
int offset = 0;
dprintf_metafile(stddeb,"EnumMetaFile(%04x, %04x, %08lx, %08lx)\n",
hdc, hmf, (DWORD)lpEnumFunc, lpData);
/* create the handle table */
hHT = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,
sizeof(HANDLETABLE) * mh->mtNoObjects);
ht = (HANDLETABLE *)GlobalLock(hHT);
offset = mh->mtHeaderSize * 2;
/* loop through metafile records */
while (offset < (mh->mtSize * 2))
{
GlobalFree(mf->hBuffer);
_lclose(mf->hFile);
mr = (METARECORD *)((char *)mh + offset);
if (!CallEnumMetafileProc(lpEnumFunc, hdc, MAKE_SEGPTR(ht),
MAKE_SEGPTR(mr), mh->mtNoObjects,
(LONG)lpData))
break;
offset += (mr->rdSize * 2);
}
/* free handle table */
@ -280,6 +337,7 @@ BOOL PlayMetaFile(HDC hdc, HMETAFILE hmf)
/******************************************************************
* PlayMetaFileRecord GDI.176
*/
void PlayMetaFileRecord(HDC hdc, HANDLETABLE *ht, METARECORD *mr,
WORD nHandles)
{
@ -288,6 +346,9 @@ void PlayMetaFileRecord(HDC hdc, HANDLETABLE *ht, METARECORD *mr,
char *ptr;
BITMAPINFOHEADER *infohdr;
dprintf_metafile(stddeb,"PlayMetaFileRecord(%04x %08lx %08lx %04x)\n",
hdc,(LONG)ht, (LONG)mr, nHandles);
switch (mr->rdFunction)
{
case META_EOF:
@ -552,7 +613,52 @@ void PlayMetaFileRecord(HDC hdc, HANDLETABLE *ht, METARECORD *mr,
}
break;
/* End new metafile operations. */
case META_STRETCHDIB:
{
LPSTR bits;
LPBITMAPINFO info;
int offset;
info = (LPBITMAPINFO) &(mr->rdParam[11]);
if (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
{
if (info->bmiHeader.biClrUsed)
{
if (info->bmiHeader.biClrUsed < (1 << info->bmiHeader.biBitCount))
offset = info->bmiHeader.biClrUsed * 4;
else
offset = (1 << info->bmiHeader.biBitCount) * 4;
}
else
offset = (1 << info->bmiHeader.biBitCount) * 4;
}
else if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
{
if (info->bmiHeader.biClrUsed)
{
if (info->bmiHeader.biClrUsed < (1 << info->bmiHeader.biBitCount))
offset = info->bmiHeader.biClrUsed * 3;
else
offset = (1 << info->bmiHeader.biBitCount) * 3;
}
else
offset = (1 << info->bmiHeader.biBitCount) * 3;
}
else
{
fprintf(stderr,"Unknown size for BITMAPHEADER in PlayMetaRecord!\n");
break;
}
offset += info->bmiHeader.biSize;
bits = (LPSTR) info + offset;
StretchDIBits(hdc,mr->rdParam[10],mr->rdParam[9],mr->rdParam[8],
mr->rdParam[7],mr->rdParam[6],mr->rdParam[5],
mr->rdParam[4],mr->rdParam[3],bits,info,
mr->rdParam[2],(DWORD)mr->rdParam[0]);
}
break;
default:
fprintf(stddeb,"PlayMetaFileRecord: Unknown record type %x\n",
mr->rdFunction);
@ -564,33 +670,12 @@ void PlayMetaFileRecord(HDC hdc, HANDLETABLE *ht, METARECORD *mr,
*
* Trade in a meta file object handle for a handle to the meta file memory
*/
HANDLE GetMetaFileBits(HMETAFILE hmf)
{
dprintf_metafile(stddeb,"GetMetaFileBits: hMem out: %04x\n", hmf);
/* save away the meta file bits handle */
METAFILE *mf = (METAFILE *)GlobalLock(hmf);
HANDLE hMem = mf->hMetaHdr;
METAHEADER *mh = (METAHEADER *)GlobalLock(hMem);
dprintf_metafile(stddeb,"GetMetaFileBits: hmf in: %04x\n", hmf);
/* can't get bits of disk based metafile */
/* FIXME: should the disk file be loaded in this case? */
if(mh->mtType == 1) {
fprintf(stderr,
"GetMetaFileBits: application requested bits of disk meta file.\n");
GlobalUnlock(hMem);
GlobalUnlock(hmf);
return FALSE;
}
/* unlock the memory and invalidate the metafile handle */
GlobalUnlock(hMem);
GlobalFree(hmf);
dprintf_metafile(stddeb,"GetMetaFileBits: hMem out: %04x\n", hMem);
return hMem;
return hmf;
}
/******************************************************************
@ -598,76 +683,50 @@ HANDLE GetMetaFileBits(HMETAFILE hmf)
*
* Trade in a meta file memory handle for a handle to a meta file object
*/
HMETAFILE SetMetaFileBits(HANDLE hMem)
{
HMETAFILE hmf;
METAFILE *mf;
METAHEADER *mh = (METAHEADER *)GlobalLock(hMem);
dprintf_metafile(stddeb,"SetMetaFileBits: hmf out: %04x\n", hMem);
dprintf_metafile(stddeb,"SetMetaFileBits: hMem in: %04x\n", hMem);
if (!mh) return FALSE;
/* now it is a memory meta file */
mh->mtType = 0;
hmf = GlobalAlloc(GMEM_MOVEABLE, sizeof(METAFILE));
mf = (METAFILE *)GlobalLock(hmf);
if (!mf) {
GlobalUnlock(hMem);
GlobalFree(hmf);
return FALSE;
}
/* use the supplied memory handle */
mf->hMetaHdr = hMem;
mf->wMagic = METAFILE_MAGIC;
mf->MetaOffset = mh->mtHeaderSize * 2;
mf->hFile = (int) (mf->hBuffer = (HANDLE) NULL);
GlobalUnlock(hMem);
GlobalUnlock(hmf);
dprintf_metafile(stddeb,"SetMetaFileBits: hmf out: %04x\n", hmf);
return hmf;
return hMem;
}
/******************************************************************
* MF_WriteRecord
*/
BOOL MF_WriteRecord(HMETAFILE hmf, METARECORD *mr, WORD rlen)
HMETAFILE MF_WriteRecord(HMETAFILE hmf, METARECORD *mr, WORD rlen)
{
DWORD len;
METAFILE *mf = (METAFILE *)GlobalLock(hmf);
METAHEADER *mh = (METAHEADER *)GlobalLock(mf->hMetaHdr);
METAHEADER *mh = (METAHEADER *)GlobalLock(hmf);
if (mh->mtType == 0) /* memory based metafile */
{
len = mh->mtSize * 2 + rlen;
GlobalUnlock(mf->hMetaHdr);
mf->hMetaHdr = GlobalReAlloc(mf->hMetaHdr, len, GMEM_MOVEABLE);
mh = (METAHEADER *)GlobalLock(mf->hMetaHdr);
GlobalUnlock(hmf);
hmf = GlobalReAlloc(hmf, len, GMEM_MOVEABLE); /* hmf can change */
mh = (METAHEADER *)GlobalLock(hmf);
memcpy((WORD *)mh + mh->mtSize, mr, rlen);
}
else if (mh->mtType == 1) /* disk based metafile */
{
if (_lwrite(mf->hFile, (char *)mr, rlen) == -1)
dprintf_metafile(stddeb,"Writing record to disk\n");
if (_lwrite(mh->mtNoParameters, (char *)mr, rlen) == -1)
{
GlobalUnlock(mf->hMetaHdr);
return FALSE;
GlobalUnlock(hmf);
return 0;
}
}
else
{
GlobalUnlock(mf->hMetaHdr);
return FALSE;
GlobalUnlock(hmf);
return 0;
}
mh->mtSize += rlen / 2;
mh->mtMaxRecord = MAX(mh->mtMaxRecord, rlen / 2);
GlobalUnlock(mf->hMetaHdr);
return TRUE;
GlobalUnlock(hmf);
return hmf;
}
@ -676,6 +735,7 @@ BOOL MF_WriteRecord(HMETAFILE hmf, METARECORD *mr, WORD rlen)
*
* Add a handle to an external handle table and return the index
*/
int MF_AddHandle(HANDLETABLE *ht, WORD htlen, HANDLE hobj)
{
int i;
@ -697,6 +757,7 @@ int MF_AddHandle(HANDLETABLE *ht, WORD htlen, HANDLE hobj)
*
* Add a handle to the internal handle table and return the index
*/
int MF_AddHandleInternal(HANDLE hobj)
{
int i;
@ -725,14 +786,19 @@ int MF_AddHandleInternal(HANDLE hobj)
/******************************************************************
* MF_MetaParam0
*/
BOOL MF_MetaParam0(DC *dc, short func)
{
char buffer[8];
METARECORD *mr = (METARECORD *)&buffer;
HMETAFILE handle;
mr->rdSize = 3;
mr->rdFunction = func;
return MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
dc->w.hMetaFile = handle;
return handle;
}
@ -743,11 +809,15 @@ BOOL MF_MetaParam1(DC *dc, short func, short param1)
{
char buffer[8];
METARECORD *mr = (METARECORD *)&buffer;
HMETAFILE handle;
mr->rdSize = 4;
mr->rdFunction = func;
*(mr->rdParam) = param1;
return MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
dc->w.hMetaFile = handle;
return handle;
}
@ -758,43 +828,54 @@ BOOL MF_MetaParam2(DC *dc, short func, short param1, short param2)
{
char buffer[10];
METARECORD *mr = (METARECORD *)&buffer;
HMETAFILE handle;
mr->rdSize = 5;
mr->rdFunction = func;
*(mr->rdParam) = param2;
*(mr->rdParam + 1) = param1;
return MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
dc->w.hMetaFile = handle;
return handle;
}
/******************************************************************
* MF_MetaParam4
*/
BOOL MF_MetaParam4(DC *dc, short func, short param1, short param2,
short param3, short param4)
{
char buffer[14];
METARECORD *mr = (METARECORD *)&buffer;
HMETAFILE handle;
mr->rdSize = 7;
mr->rdFunction = func;
*(mr->rdParam) = param4;
*(mr->rdParam + 1) = param3;
*(mr->rdParam + 2) = param2;
*(mr->rdParam + 3) = param1;
return MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
dc->w.hMetaFile = handle;
return handle;
}
/******************************************************************
* MF_MetaParam6
*/
BOOL MF_MetaParam6(DC *dc, short func, short param1, short param2,
short param3, short param4, short param5, short param6)
{
char buffer[18];
METARECORD *mr = (METARECORD *)&buffer;
HMETAFILE handle;
mr->rdSize = 9;
mr->rdFunction = func;
*(mr->rdParam) = param6;
@ -803,7 +884,10 @@ BOOL MF_MetaParam6(DC *dc, short func, short param1, short param2,
*(mr->rdParam + 3) = param3;
*(mr->rdParam + 4) = param2;
*(mr->rdParam + 5) = param1;
return MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
dc->w.hMetaFile = handle;
return handle;
}
@ -816,7 +900,8 @@ BOOL MF_MetaParam8(DC *dc, short func, short param1, short param2,
{
char buffer[22];
METARECORD *mr = (METARECORD *)&buffer;
HMETAFILE handle;
mr->rdSize = 11;
mr->rdFunction = func;
*(mr->rdParam) = param8;
@ -827,48 +912,55 @@ BOOL MF_MetaParam8(DC *dc, short func, short param1, short param2,
*(mr->rdParam + 5) = param3;
*(mr->rdParam + 6) = param2;
*(mr->rdParam + 7) = param1;
return MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
dc->w.hMetaFile = handle;
return handle;
}
/******************************************************************
* MF_CreateBrushIndirect
*/
BOOL MF_CreateBrushIndirect(DC *dc, HBRUSH hBrush, LOGBRUSH *logbrush)
{
int index;
BOOL rc;
HMETAFILE handle;
char buffer[sizeof(METARECORD) - 2 + sizeof(LOGBRUSH)];
METARECORD *mr = (METARECORD *)&buffer;
METAFILE *mf;
METAHEADER *mh;
mr->rdSize = (sizeof(METARECORD) + sizeof(LOGBRUSH) - 2) / 2;
mr->rdFunction = META_CREATEBRUSHINDIRECT;
memcpy(&(mr->rdParam), logbrush, sizeof(LOGBRUSH));
if (!MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2))
if (!(dc->w.hMetaFile = MF_WriteRecord(dc->w.hMetaFile,
mr, mr->rdSize * 2)))
return FALSE;
mr->rdSize = sizeof(METARECORD) / 2;
mr->rdFunction = META_SELECTOBJECT;
if ((index = MF_AddHandleInternal(hBrush)) == -1)
return FALSE;
mf = (METAFILE *)GlobalLock(dc->w.hMetaFile);
mh = (METAHEADER *)GlobalLock(mf->hMetaHdr);
mh = (METAHEADER *)GlobalLock(dc->w.hMetaFile);
*(mr->rdParam) = index;
if (index >= mh->mtNoObjects)
mh->mtNoObjects++;
rc = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
GlobalUnlock(mf->hMetaHdr);
GlobalUnlock(dc->w.hMetaFile);
return rc;
handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
dc->w.hMetaFile = handle;
return handle;
}
/******************************************************************
* MF_CreatePatternBrush
*/
BOOL MF_CreatePatternBrush(DC *dc, HBRUSH hBrush, LOGBRUSH *logbrush)
{
DWORD len, bmSize, biSize;
@ -878,9 +970,8 @@ BOOL MF_CreatePatternBrush(DC *dc, HBRUSH hBrush, LOGBRUSH *logbrush)
BITMAPINFO *info;
BITMAPINFOHEADER *infohdr;
int index;
BOOL rc;
HMETAFILE handle;
char buffer[sizeof(METARECORD)];
METAFILE *mf;
METAHEADER *mh;
switch (logbrush->lbStyle)
@ -930,98 +1021,103 @@ BOOL MF_CreatePatternBrush(DC *dc, HBRUSH hBrush, LOGBRUSH *logbrush)
default:
return FALSE;
}
if (!MF_WriteRecord(dc->w.hMetaFile, mr, len))
if (!(dc->w.hMetaFile = MF_WriteRecord(dc->w.hMetaFile, mr, len)))
{
GlobalFree(hmr);
return FALSE;
}
GlobalFree(hmr);
mr = (METARECORD *)&buffer;
mr->rdSize = sizeof(METARECORD) / 2;
mr->rdFunction = META_SELECTOBJECT;
if ((index = MF_AddHandleInternal(hBrush)) == -1)
return FALSE;
mf = (METAFILE *)GlobalLock(dc->w.hMetaFile);
mh = (METAHEADER *)GlobalLock(mf->hMetaHdr);
mh = (METAHEADER *)GlobalLock(dc->w.hMetaFile);
*(mr->rdParam) = index;
if (index >= mh->mtNoObjects)
mh->mtNoObjects++;
rc = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
GlobalUnlock(mf->hMetaHdr);
GlobalUnlock(dc->w.hMetaFile);
return rc;
handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
dc->w.hMetaFile = handle;
return handle;
}
/******************************************************************
* MF_CreatePenIndirect
*/
BOOL MF_CreatePenIndirect(DC *dc, HPEN hPen, LOGPEN *logpen)
{
int index;
BOOL rc;
HMETAFILE handle;
char buffer[sizeof(METARECORD) - 2 + sizeof(LOGPEN)];
METARECORD *mr = (METARECORD *)&buffer;
METAFILE *mf;
METAHEADER *mh;
mr->rdSize = (sizeof(METARECORD) + sizeof(LOGPEN) - 2) / 2;
mr->rdFunction = META_CREATEPENINDIRECT;
memcpy(&(mr->rdParam), logpen, sizeof(LOGPEN));
if (!MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2))
if (!(dc->w.hMetaFile = MF_WriteRecord(dc->w.hMetaFile, mr,
mr->rdSize * 2)))
return FALSE;
mr->rdSize = sizeof(METARECORD) / 2;
mr->rdFunction = META_SELECTOBJECT;
if ((index = MF_AddHandleInternal(hPen)) == -1)
return FALSE;
mf = (METAFILE *)GlobalLock(dc->w.hMetaFile);
mh = (METAHEADER *)GlobalLock(mf->hMetaHdr);
mh = (METAHEADER *)GlobalLock(dc->w.hMetaFile);
*(mr->rdParam) = index;
if (index >= mh->mtNoObjects)
mh->mtNoObjects++;
rc = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
GlobalUnlock(mf->hMetaHdr);
GlobalUnlock(dc->w.hMetaFile);
return rc;
handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
dc->w.hMetaFile = handle;
return handle;
}
/******************************************************************
* MF_CreateFontIndirect
*/
BOOL MF_CreateFontIndirect(DC *dc, HFONT hFont, LOGFONT *logfont)
{
int index;
BOOL rc;
HMETAFILE handle;
char buffer[sizeof(METARECORD) - 2 + sizeof(LOGFONT)];
METARECORD *mr = (METARECORD *)&buffer;
METAFILE *mf;
METAHEADER *mh;
mr->rdSize = (sizeof(METARECORD) + sizeof(LOGFONT) - 2) / 2;
mr->rdFunction = META_CREATEFONTINDIRECT;
memcpy(&(mr->rdParam), logfont, sizeof(LOGFONT));
if (!MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2))
if (!(dc->w.hMetaFile = MF_WriteRecord(dc->w.hMetaFile, mr,
mr->rdSize * 2)))
return FALSE;
mr->rdSize = sizeof(METARECORD) / 2;
mr->rdFunction = META_SELECTOBJECT;
if ((index = MF_AddHandleInternal(hFont)) == -1)
return FALSE;
mf = (METAFILE *)GlobalLock(dc->w.hMetaFile);
mh = (METAHEADER *)GlobalLock(mf->hMetaHdr);
mh = (METAHEADER *)GlobalLock(dc->w.hMetaFile);
*(mr->rdParam) = index;
if (index >= mh->mtNoObjects)
mh->mtNoObjects++;
rc = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
GlobalUnlock(mf->hMetaHdr);
GlobalUnlock(dc->w.hMetaFile);
return rc;
handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
dc->w.hMetaFile = handle;
return handle;
}
@ -1030,7 +1126,7 @@ BOOL MF_CreateFontIndirect(DC *dc, HFONT hFont, LOGFONT *logfont)
*/
BOOL MF_TextOut(DC *dc, short x, short y, LPSTR str, short count)
{
BOOL rc;
HMETAFILE handle;
DWORD len;
HANDLE hmr;
METARECORD *mr;
@ -1047,9 +1143,10 @@ BOOL MF_TextOut(DC *dc, short x, short y, LPSTR str, short count)
memcpy(mr->rdParam + 1, str, count);
*(mr->rdParam + ((count + 1) >> 1) + 1) = y;
*(mr->rdParam + ((count + 1) >> 1) + 2) = x;
rc = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
dc->w.hMetaFile = handle;
GlobalFree(hmr);
return rc;
return handle;
}
@ -1058,7 +1155,7 @@ BOOL MF_TextOut(DC *dc, short x, short y, LPSTR str, short count)
*/
BOOL MF_MetaPoly(DC *dc, short func, LPPOINT pt, short count)
{
BOOL rc;
HMETAFILE handle;
DWORD len;
HANDLE hmr;
METARECORD *mr;
@ -1073,9 +1170,10 @@ BOOL MF_MetaPoly(DC *dc, short func, LPPOINT pt, short count)
mr->rdFunction = func;
*(mr->rdParam) = count;
memcpy(mr->rdParam + 1, pt, count * 4);
rc = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
dc->w.hMetaFile = handle;
GlobalFree(hmr);
return rc;
return handle;
}

View File

@ -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)

122
programs/progman/Fr.rc Normal file
View File

@ -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"

View File

@ -3,7 +3,7 @@ MODULE = none
PROGRAMS = progman
ALL_LIBS = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LDLIBS)
LANGUAGES = En De
LANGUAGES = En De Fr
LICENSELANG = En
MOSTOBJS = \

View File

@ -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 @@ int PASCAL WinMain (HANDLE hInstance, HANDLE prev, LPSTR cmdline, int show)
LIBWINE_Register_accel();
LIBWINE_Register_De();
LIBWINE_Register_En();
LIBWINE_Register_Fr();
#endif
#ifndef WINELIB
@ -62,8 +67,8 @@ int PASCAL WinMain (HANDLE hInstance, HANDLE prev, LPSTR cmdline, int show)
}
#endif
/* Select Language (FIXME) */
#ifndef WINELIB
/* Select Language */
#ifdef WINELIB
Globals.lpszLanguage = langNames[Options.language];
#else
Globals.lpszLanguage = "En";

View File

@ -120,8 +120,8 @@ VOID STRING_SelectLanguageByNumber(UINT num)
if (Globals.hMainMenu) DestroyMenu(Globals.hMainMenu);
Globals.hMainMenu = hMainMenu;
#ifndef WINELIB
/* Update system menus (FIXME) */
#ifdef WINELIB
/* Update system menus */
for (i = 0; langNames[i] && lstrcmp(lang, langNames[i]);) i++;
if (langNames[i]) Options.language = i;

View File

@ -45,6 +45,7 @@ otherwise you'll get an undefined behavour.
Today it works well for:
* English
* German
* French
...to be continued......
Thank you.

View File

@ -144,25 +144,37 @@ FONT 8, "Helv"
PUSHBUTTON "Annuler", 2, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP
}
CHOOSE_COLOR DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 200
CHOOSE_COLOR DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 300, 200
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Couleurs"
FONT 8, "Helv"
{
LTEXT "Couleurs de &base:", 1088, 6, 6, 40, 9
LTEXT "%Couleurs personnalisées:", 1089, 6, 126, 40, 9
LTEXT "Couleur|&Uni", 1090, 100, 146, 40, 9
LTEXT "&Couleur:", 1091, 150, 126, 40, 9
LTEXT "&Sat. :", 1092, 150, 146, 40, 9
LTEXT "&Lum. :", 1093, 150, 166, 40, 9
LTEXT "&Rouge:", 1094, 150, 126, 40, 9
LTEXT "&Vert:", 1095, 150, 146, 40, 9
LTEXT "&Bleu:", 1096, 150, 166, 40, 9
DEFPUSHBUTTON "OK", 1, 6, 182, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
PUSHBUTTON "&Ajouter la couleur", 1024, 120, 182, 100, 14, WS_GROUP | WS_TABSTOP
PUSHBUTTON "&Supprimer la couleur", 1025, 6, 164, 56, 14, WS_GROUP | WS_TABSTOP
PUSHBUTTON "Annuler", 2, 76, 182, 56, 14, WS_GROUP | WS_TABSTOP
LTEXT "Couleurs de &base:", 1088, 4, 4, 140, 10
LTEXT "&Couleurs personnalisés:", 1089, 4, 106, 140, 10
LTEXT "Couleur | &Uni", 1090, 150, 151, 48, 10
LTEXT "&Rouge:", 726 /*1094*/,249,126,24,10
EDITTEXT 706, 275,124,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP
LTEXT "&Vert:",727/*1095*/,249,140,24,10
EDITTEXT 707, 275,138,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP
LTEXT "Bl&eu:",728 /*1096*/,249,154,24,10
EDITTEXT 708, 275,152,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP
LTEXT "&Teinte:" ,723 /*1091*/,202,126,22,10
EDITTEXT 703, 226,124,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP
LTEXT "&Sat.:" ,724 /*1092*/,202,140,22,10
EDITTEXT 704, 226,138,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP
LTEXT "&Lum.:" ,725 /*1093*/,202,154,22,10
EDITTEXT 705, 226,152,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP
CONTROL "" ,720,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP,4,14,140,86
CONTROL "" ,721,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP,4,116,140,28
CONTROL "" ,710,"STATIC",WS_BORDER|SS_SIMPLE|WS_TABSTOP|WS_GROUP, 152,4,118,116 CONTROL "" ,702,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP, 278,4,8,116
CONTROL "" ,702,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP, 278,4,8,116
CONTROL "" ,709,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP, 152,124,40,26
DEFPUSHBUTTON "Ok", 1, 4, 166, 44, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
PUSHBUTTON "Annuler", 2, 52, 166, 44, 14, WS_GROUP | WS_TABSTOP
PUSHBUTTON "Aide", 1038,100,166, 44, 14
PUSHBUTTON "&Ajouter couleur personnalisées", 712/*1024*/, 152, 166, 142, 14, WS_GROUP | WS_TABSTOP
PUSHBUTTON "&Definir couleurs personnalisées >>", 719/*1025*/, 4, 150, 142, 14, WS_GROUP | WS_TABSTOP
PUSHBUTTON "&i",713,300,200,4,14 /* just a dummy: 'i' is like &i in "sol&id" */
}
FIND_TEXT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 236, 62

View File

@ -143,28 +143,39 @@ FONT 8, "Helv"
PUSHBUTTON "Annulla", 2, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP
}
CHOOSE_COLOR DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 200
CHOOSE_COLOR DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 300, 200
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Colore"
FONT 8, "Helv"
{
LTEXT "Colori di &Base:", 1088, 6, 6, 40, 9
LTEXT "Colori &Utente:", 1089, 6, 126, 40, 9
LTEXT "Colore|Sol&ido", 1090, 100, 146, 40, 9
LTEXT "&Tinta:", 1091, 150, 126, 40, 9
LTEXT "&Sat:", 1092, 150, 146, 40, 9
LTEXT "&Lum:", 1093, 150, 166, 40, 9
LTEXT "&Rosso:", 1094, 150, 126, 40, 9
LTEXT "&Verde:", 1095, 150, 146, 40, 9
LTEXT "Bl&u:", 1096, 150, 166, 40, 9
DEFPUSHBUTTON "Ok", 1, 6, 182, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
PUSHBUTTON "&Aggiungi ai Colori Utente", 1024, 120, 182, 100, 14, WS_GROUP | WS_TABSTOP
PUSHBUTTON "&Cancella Colori Utente", 1025, 6, 164, 56, 14, WS_GROUP | WS_TABSTOP
PUSHBUTTON "Annulla", 2, 76, 182, 56, 14, WS_GROUP | WS_TABSTOP
LTEXT "Colori di &Base:", 1088, 4, 4, 140, 10
LTEXT "Colori &Utente:", 1089, 4, 106, 140, 10
LTEXT "Colore | Sol&ido", 1090, 150, 151, 48, 10
LTEXT "&Rosso:", 726 /*1094*/,249,126,24,10
EDITTEXT 706, 275,124,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP
LTEXT "&Verde:",727/*1095*/,249,140,24,10
EDITTEXT 707, 275,138,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP
LTEXT "&Blu:",728 /*1096*/,249,154,24,10
EDITTEXT 708, 275,152,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP
LTEXT "&Tinta:" ,723 /*1091*/,202,126,22,10
EDITTEXT 703, 226,124,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP
LTEXT "&Sat:" ,724 /*1092*/,202,140,22,10
EDITTEXT 704, 226,138,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP
LTEXT "&Lum:" ,725 /*1093*/,202,154,22,10
EDITTEXT 705, 226,152,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP
CONTROL "" ,720,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP,4,14,140,86
CONTROL "" ,721,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP,4,116,140,28
CONTROL "" ,710,"STATIC",WS_BORDER|SS_SIMPLE|WS_TABSTOP|WS_GROUP, 152,4,118,116
CONTROL "" ,702,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP, 278,4,8,116
CONTROL "" ,709,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP, 152,124,40,26
DEFPUSHBUTTON "Ok", 1, 4, 166, 44, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
PUSHBUTTON "Annulla", 2, 52, 166, 44, 14, WS_GROUP | WS_TABSTOP
PUSHBUTTON "Aiuto", 1038,100,166, 44, 14
PUSHBUTTON "&Aggiungi ai Colori Utente", 712/*1024*/, 152, 166, 142, 14, WS_GROUP | WS_TABSTOP
PUSHBUTTON "&Definisci Colori Utente >>", 719/*1025*/, 4, 150, 142, 14, WS_GROUP | WS_TABSTOP
PUSHBUTTON "&i",713,300,200,4,14 /* just a dummy: 'i' is like &i in "sol&id" */
}
FIND_TEXT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 236, 62
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Trova"

View File

@ -141,18 +141,14 @@ LRESULT DefWindowProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
case WM_WINDOWPOSCHANGED:
{
/* Note: Windoze uses unknown SWP flags 0x1000 and 0x0800 to
* decide whether to send WM_MOVE or/and WM_SIZE respectively
*/
WINDOWPOS * winPos = (WINDOWPOS *)PTR_SEG_TO_LIN(lParam);
WPARAM wp = SIZE_RESTORED;
if (!(winPos->flags & SWP_NOMOVE))
if (!(winPos->flags & SWP_NOCLIENTMOVE))
SendMessage( hwnd, WM_MOVE, 0,
MAKELONG( wndPtr->rectClient.left,
wndPtr->rectClient.top ));
if (!(winPos->flags & SWP_NOSIZE))
if (!(winPos->flags & SWP_NOCLIENTSIZE))
{
if( wndPtr->dwStyle & WS_MAXIMIZE ) wp = SIZE_MAXIMIZED;
else if(wndPtr->dwStyle & WS_MINIMIZE ) wp = SIZE_MINIMIZED;

View File

@ -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 @@ BOOL MDI_RestoreFrameMenu(WND *, HWND);
void ScrollChildren(HWND , UINT , WPARAM , LPARAM );
void CalcChildScroll(HWND, WORD);
/* ----------------- declarations ----------------- */
static LONG MDI_ChildActivate(WND* ,HWND );
/* -------- Miscellaneous service functions ----------
@ -55,6 +55,16 @@ static HWND MDI_GetChildByID(WND* wndPtr,int id)
return 0;
}
static void MDI_PostUpdate(HWND hwnd, MDICLIENTINFO* ci, WORD recalc)
{
if( !ci->sbNeedUpdate )
{
ci->sbNeedUpdate = TRUE;
PostMessage( hwnd, WM_MDICALCCHILDSCROLL, 0, 0);
}
ci->sbRecalc = recalc;
}
/**********************************************************************
* MDI_MenuAppendItem
*/
@ -427,9 +437,8 @@ HWND MDIDestroyChild(WND *w_parent, MDICLIENTINFO *ci, HWND parent,
if (flagDestroy)
{
MDI_PostUpdate(GetParent(child), ci, SB_BOTH+1);
DestroyWindow(child);
PostMessage(parent,WM_MDICALCCHILDSCROLL,0,0L);
ci->sbRecalc |= (SB_BOTH+1);
}
}
@ -808,9 +817,8 @@ BOOL MDI_AugmentFrameMenu(MDICLIENTINFO* ci, WND *frame, HWND hChild)
child->dwStyle &= ~WS_SYSMENU;
/* redraw frame */
SetWindowPos(frame->hwndSelf, 0,0,0,0,0, SWP_FRAMECHANGED | SWP_NOSIZE |
SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER );
/* redraw menu */
DrawMenuBar(frame->hwndSelf);
return 1;
}
@ -837,9 +845,8 @@ BOOL MDI_RestoreFrameMenu( WND *frameWnd, HWND hChild)
RemoveMenu(frameWnd->wIDmenu,0,MF_BYPOSITION);
DeleteMenu(frameWnd->wIDmenu,nItems-1,MF_BYPOSITION);
/* redraw frame */
SetWindowPos(hChild, 0,0,0,0,0, SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE |
SWP_NOACTIVATE | SWP_NOZORDER );
DrawMenuBar(frameWnd->hwndSelf);
return 1;
}
@ -962,7 +969,7 @@ LRESULT MDIClientWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
ci->flagChildMaximized = 0;
ci->nActiveChildren = 0;
ci->hFrameTitle = frameWnd->hText;
ci->sbStop = 0;
ci->sbNeedUpdate = 0;
ci->self = hwnd;
ci->obmClose = CreateMDIMenuBitmap();
ci->obmRestore = LoadBitmap(0, MAKEINTRESOURCE(OBM_RESTORE));
@ -1014,11 +1021,11 @@ LRESULT MDIClientWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
((LONG) (ci->flagChildMaximized>0) << 16));
case WM_MDIICONARRANGE:
ci->sbStop = TRUE;
MDIIconArrange(hwnd);
ci->sbStop = FALSE;
SendMessage(hwnd,WM_MDICALCCHILDSCROLL,0,0L);
return 0;
ci->sbNeedUpdate = TRUE;
MDIIconArrange(hwnd);
ci->sbRecalc = SB_BOTH+1;
SendMessage(hwnd,WM_MDICALCCHILDSCROLL,0,0L);
return 0;
case WM_MDIMAXIMIZE:
ShowWindow((HWND)wParam, SW_MAXIMIZE);
@ -1040,17 +1047,17 @@ LRESULT MDIClientWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
#endif
case WM_MDITILE:
ci->sbStop = TRUE;
ci->sbNeedUpdate = TRUE;
ShowScrollBar(hwnd,SB_BOTH,FALSE);
MDITile(hwnd, ci,wParam);
ci->sbStop = FALSE;
ci->sbNeedUpdate = FALSE;
return 0;
case WM_VSCROLL:
case WM_HSCROLL:
ci->sbStop = TRUE;
ci->sbNeedUpdate = TRUE;
ScrollChildren(hwnd,message,wParam,lParam);
ci->sbStop = FALSE;
ci->sbNeedUpdate = FALSE;
return 0;
case WM_SETFOCUS:
@ -1099,18 +1106,16 @@ LRESULT MDIClientWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
rect.right - rect.left, rect.bottom - rect.top, 1);
}
else
{
PostMessage(hwnd,WM_MDICALCCHILDSCROLL,0,0L);
ci->sbRecalc |= (SB_BOTH+1);
}
MDI_PostUpdate(hwnd, ci, SB_BOTH+1);
break;
case WM_MDICALCCHILDSCROLL:
if( !ci->sbStop )
if( ci->sbNeedUpdate )
if( ci->sbRecalc )
{
CalcChildScroll(hwnd, ci->sbRecalc-1);
ci->sbRecalc = 0;
ci->sbRecalc = ci->sbNeedUpdate = 0;
}
return 0;
}
@ -1256,11 +1261,10 @@ LRESULT DefMDIChildProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
return 0;
case WM_SETVISIBLE:
if( !ci->sbStop && !ci->flagChildMaximized)
{
PostMessage(ci->self,WM_MDICALCCHILDSCROLL,0,0L);
ci->sbRecalc |= (SB_BOTH+1);
}
if( ci->flagChildMaximized)
ci->sbNeedUpdate = 0;
else
MDI_PostUpdate(clientWnd->hwndSelf, ci, SB_BOTH+1);
break;
case WM_SIZE:
@ -1305,12 +1309,8 @@ LRESULT DefMDIChildProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
if( switchTo )
SendMessage( switchTo, WM_CHILDACTIVATE, 0, 0L);
}
if( !ci->sbStop )
{
PostMessage(ci->self,WM_MDICALCCHILDSCROLL,0,0L);
ci->sbRecalc |= (SB_BOTH+1);
}
MDI_PostUpdate(clientWnd->hwndSelf, ci, SB_BOTH+1);
break;
case WM_MENUCHAR:
@ -1379,27 +1379,47 @@ BOOL TranslateMDISysAccel(HWND hwndClient, LPMSG msg)
void CalcChildScroll( HWND hwnd, WORD scroll )
{
RECT childRect, clientRect;
WND *pWnd;
INT vmin, vmax, hmin, hmax, vpos, hpos;
BOOL noscroll = FALSE;
WND *pWnd, *Wnd;
if (!(pWnd = WIN_FindWndPtr( hwnd ))) return;
if (!(Wnd = pWnd = WIN_FindWndPtr( hwnd ))) return;
GetClientRect( hwnd, &clientRect );
SetRectEmpty( &childRect );
for (pWnd = pWnd->child; pWnd; pWnd = pWnd->next)
UnionRect( &childRect, &pWnd->rectWindow, &childRect );
for ( pWnd = pWnd->child; pWnd; pWnd = pWnd->next )
{
UnionRect( &childRect, &pWnd->rectWindow, &childRect );
if( pWnd->dwStyle & WS_MAXIMIZE )
noscroll = TRUE;
}
UnionRect( &childRect, &clientRect, &childRect );
if ((scroll == SB_HORZ) || (scroll == SB_BOTH))
{
SetScrollRange( hwnd, SB_HORZ, childRect.left,
childRect.right - clientRect.right, FALSE );
SetScrollPos( hwnd, SB_HORZ, clientRect.left - childRect.left, TRUE );
}
if ((scroll == SB_VERT) || (scroll == SB_BOTH))
{
SetScrollRange( hwnd, SB_VERT, childRect.top,
childRect.bottom - clientRect.bottom, FALSE );
SetScrollPos( hwnd, SB_HORZ, clientRect.top - childRect.top, TRUE );
}
/* jump through the hoops to prevent excessive flashing
*/
hmin = childRect.left; hmax = childRect.right - clientRect.right;
hpos = clientRect.left - childRect.left;
vmin = childRect.top; vmax = childRect.bottom - clientRect.bottom;
vpos = clientRect.top - childRect.top;
if( noscroll )
ShowScrollBar(hwnd, SB_BOTH, FALSE);
else
switch( scroll )
{
case SB_HORZ:
vpos = hpos; vmin = hmin; vmax = hmax;
case SB_VERT:
SetScrollPos(hwnd, scroll, vpos, FALSE);
SetScrollRange(hwnd, scroll, vmin, vmax, TRUE);
break;
case SB_BOTH:
SCROLL_SetNCSbState( Wnd, vmin, vmax, vpos,
hmin, hmax, hpos);
SetWindowPos(hwnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE
| SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
}
}
/***********************************************************************

View File

@ -201,6 +201,9 @@ static BOOL MSG_PeekHardwareMsg( MSG *msg, HWND hwnd, WORD first, WORD last,
MESSAGEQUEUE *sysMsgQueue = QUEUE_GetSysQueue();
int i, pos = sysMsgQueue->nextMessage;
/* If the queue is empty, attempt to fill it */
if (!sysMsgQueue->msgCount && XPending(display)) MSG_WaitXEvent( 0 );
for (i = 0; i < sysMsgQueue->msgCount; i++, pos++)
{
if (pos >= sysMsgQueue->queueSize) pos = 0;
@ -362,11 +365,11 @@ BOOL MSG_WaitXEvent( LONG maxWait )
{
#ifdef CONFIG_IPC
if (DDE_GetRemoteMessage())
if (DDE_GetRemoteMessage())
{
while(DDE_GetRemoteMessage()) ;
return TRUE;
}
while(DDE_GetRemoteMessage()) ;
return TRUE;
}
#endif /* CONFIG_IPC */
XNextEvent( display, &event );

View File

@ -23,13 +23,13 @@
*/
void WIN_UpdateNCArea(WND* wnd, BOOL bUpdate)
{
RECT rect = wnd->rectClient;
POINT pt = {0, 0};
HRGN hClip = 1;
dprintf_nonclient(stddeb,"NCUpdate: hwnd %04x, hrgnUpdate %04x\n",
wnd->hwndSelf, wnd->hrgnUpdate );
/* desktop windows doesn't have nonclient area */
/* desktop window doesn't have nonclient area */
if(wnd == WIN_GetDesktop())
{
wnd->flags &= ~WIN_NEEDS_NCPAINT;
@ -38,7 +38,7 @@ void WIN_UpdateNCArea(WND* wnd, BOOL bUpdate)
if( wnd->hrgnUpdate > 1 )
{
MapWindowPoints(wnd->parent->hwndSelf, 0, (POINT*)&rect, 2);
ClientToScreen(wnd->hwndSelf, &pt);
hClip = CreateRectRgn( 0, 0, 0, 0 );
if (!CombineRgn(hClip, wnd->hrgnUpdate, 0, RGN_COPY) )
@ -46,16 +46,22 @@ void WIN_UpdateNCArea(WND* wnd, BOOL bUpdate)
DeleteObject(hClip);
hClip = 1;
}
else
OffsetRgn(hClip, pt.x, pt.y);
if (bUpdate)
{
HRGN hrgn = CreateRectRgnIndirect(&rect);
/* exclude non-client area from update region */
HRGN hrgn = CreateRectRgn(0, 0, wnd->rectClient.right - wnd->rectClient.left,
wnd->rectClient.bottom - wnd->rectClient.top);
if (hrgn && (CombineRgn(wnd->hrgnUpdate, wnd->hrgnUpdate,
hrgn, RGN_AND) == NULLREGION))
{
DeleteObject(wnd->hrgnUpdate);
wnd->hrgnUpdate = 1;
}
DeleteObject( hrgn );
}
}
@ -204,19 +210,21 @@ BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags )
}
else
{
dprintf_win( stddeb, "RedrawWindow: %04x NULL %04x flags=%04x\n",
dprintf_win(stddeb, "RedrawWindow: %04x NULL %04x flags=%04x\n",
hwnd, hrgnUpdate, flags);
}
GetClientRect( hwnd, &rectClient );
if (flags & RDW_INVALIDATE) /* Invalidate */
{
if (wndPtr->hrgnUpdate) /* Is there already an update region? */
int rgnNotEmpty = COMPLEXREGION;
if (wndPtr->hrgnUpdate > 1) /* Is there already an update region? */
{
if ((hrgn = hrgnUpdate) == 0)
hrgn = CreateRectRgnIndirect( rectUpdate ? rectUpdate :
&rectClient );
CombineRgn( wndPtr->hrgnUpdate, wndPtr->hrgnUpdate, hrgn, RGN_OR );
rgnNotEmpty = CombineRgn( wndPtr->hrgnUpdate, wndPtr->hrgnUpdate, hrgn, RGN_OR );
if (!hrgnUpdate) DeleteObject( hrgn );
}
else /* No update region yet */
@ -226,19 +234,31 @@ BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags )
if (hrgnUpdate)
{
wndPtr->hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 );
CombineRgn( wndPtr->hrgnUpdate, hrgnUpdate, 0, RGN_COPY );
rgnNotEmpty = CombineRgn( wndPtr->hrgnUpdate, hrgnUpdate, 0, RGN_COPY );
}
else wndPtr->hrgnUpdate = CreateRectRgnIndirect( rectUpdate ?
rectUpdate : &rectClient );
}
if (flags & RDW_FRAME) wndPtr->flags |= WIN_NEEDS_NCPAINT;
if (flags & RDW_ERASE) wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
/* check for bogus update region */
if ( rgnNotEmpty == NULLREGION )
{
wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
DeleteObject(wndPtr->hrgnUpdate);
wndPtr->hrgnUpdate=0;
if (!(wndPtr->flags & WIN_INTERNAL_PAINT))
QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
}
else
if (flags & RDW_ERASE) wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
flags |= RDW_FRAME; /* Force invalidating the frame of children */
}
else if (flags & RDW_VALIDATE) /* Validate */
{
/* We need an update region in order to validate anything */
if (wndPtr->hrgnUpdate)
if (wndPtr->hrgnUpdate > 1)
{
if (!hrgnUpdate && !rectUpdate)
{
@ -270,13 +290,13 @@ BOOL RedrawWindow( HWND hwnd, LPRECT rectUpdate, HRGN hrgnUpdate, UINT flags )
if (flags & RDW_INTERNALPAINT)
{
if (!wndPtr->hrgnUpdate && !(wndPtr->flags & WIN_INTERNAL_PAINT))
if ( wndPtr->hrgnUpdate <= 1 && !(wndPtr->flags & WIN_INTERNAL_PAINT))
QUEUE_IncPaintCount( wndPtr->hmemTaskQ );
wndPtr->flags |= WIN_INTERNAL_PAINT;
}
else if (flags & RDW_NOINTERNALPAINT)
{
if (!wndPtr->hrgnUpdate && (wndPtr->flags & WIN_INTERNAL_PAINT))
if ( wndPtr->hrgnUpdate <= 1 && (wndPtr->flags & WIN_INTERNAL_PAINT))
QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
wndPtr->flags &= ~WIN_INTERNAL_PAINT;
}
@ -401,7 +421,7 @@ BOOL GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase )
if (rect)
{
if (wndPtr->hrgnUpdate)
if (wndPtr->hrgnUpdate > 1)
{
HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
if (GetUpdateRgn( hwnd, hrgn, erase ) == ERROR) return FALSE;
@ -410,7 +430,7 @@ BOOL GetUpdateRect( HWND hwnd, LPRECT rect, BOOL erase )
}
else SetRectEmpty( rect );
}
return (wndPtr->hrgnUpdate != 0);
return (wndPtr->hrgnUpdate > 1);
}
@ -423,7 +443,7 @@ int GetUpdateRgn( HWND hwnd, HRGN hrgn, BOOL erase )
WND * wndPtr = WIN_FindWndPtr( hwnd );
if (!wndPtr) return ERROR;
if (!wndPtr->hrgnUpdate)
if (wndPtr->hrgnUpdate <= 1)
{
SetRectRgn( hrgn, 0, 0, 0, 0 );
return NULLREGION;
@ -447,7 +467,8 @@ int ExcludeUpdateRgn( HDC hdc, HWND hwnd )
if ((hrgn = CreateRectRgn( 0, 0, 0, 0 )) != 0)
{
retval = CombineRgn( hrgn, InquireVisRgn(hdc),
wndPtr->hrgnUpdate, RGN_DIFF );
(wndPtr->hrgnUpdate>1)?wndPtr->hrgnUpdate:0,
(wndPtr->hrgnUpdate>1)?RGN_DIFF:RGN_COPY);
if (retval) SelectVisRgn( hdc, hrgn );
DeleteObject( hrgn );
}

View File

@ -20,16 +20,18 @@
/* #define DEBUG_WIN */
#include "debug.h"
#define SWP_NOPOSCHANGE (SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE)
/* ----- external functions ----- */
void FOCUS_SwitchFocus( HWND , HWND );
HRGN DCE_GetVisRgn( HWND, WORD );
/* ----- internal variables ----- */
static HWND hwndActive = 0; /* Currently active window */
static HWND hwndPrevActive = 0; /* Previously active window */
/***********************************************************************
* WINPOS_FindIconPos
*
@ -424,6 +426,7 @@ BOOL ShowWindow( HWND hwnd, int cmd )
switch(cmd)
{
case SW_HIDE:
if (!wasVisible) return FALSE;
swpflags |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE |
SWP_NOACTIVATE | SWP_NOZORDER;
break;
@ -1040,6 +1043,129 @@ HWND WINPOS_ReorderOwnedPopups(HWND hwndInsertAfter, WND* wndPtr, WORD flags)
return hwndInsertAfter;
}
/***********************************************************************
* WINPOS_SizeMoveClean
*
* Make window look nice without excessive repainting
*
* the pain:
*
* visible regions are in window coordinates
* update regions are in window client coordinates
* client and window rectangles are in parent client coordinates
*/
static void WINPOS_SizeMoveClean(WND* Wnd, HRGN oldVisRgn, LPRECT lpOldWndRect, LPRECT lpOldClientRect, BOOL bNoCopy )
{
/* visible regions are in window coordinates */
HRGN newVisRgn = DCE_GetVisRgn(Wnd->hwndSelf, DCX_WINDOW | DCX_CLIPSIBLINGS );
HRGN dirtyRgn = CreateRectRgn(0,0,0,0);
int other, my;
dprintf_win(stddeb,"cleaning up...new wnd=(%i %i-%i %i) old wnd=(%i %i-%i %i)\n\
\t\tnew client=(%i %i-%i %i) old client=(%i %i-%i %i)\n",
Wnd->rectWindow.left, Wnd->rectWindow.top, Wnd->rectWindow.right, Wnd->rectWindow.bottom,
lpOldWndRect->left, lpOldWndRect->top, lpOldWndRect->right, lpOldWndRect->bottom,
Wnd->rectClient.left,Wnd->rectClient.top,Wnd->rectClient.right,Wnd->rectClient.bottom,
lpOldClientRect->left,lpOldClientRect->top,lpOldClientRect->right,lpOldClientRect->bottom);
CombineRgn( dirtyRgn, newVisRgn, 0, RGN_COPY);
if( !bNoCopy )
{
HRGN hRgn = CreateRectRgn( lpOldClientRect->left - lpOldWndRect->left, lpOldClientRect->top - lpOldWndRect->top,
lpOldClientRect->right - lpOldWndRect->left, lpOldClientRect->bottom - lpOldWndRect->top);
CombineRgn( newVisRgn, newVisRgn, oldVisRgn, RGN_AND );
CombineRgn( newVisRgn, newVisRgn, hRgn, RGN_AND );
DeleteObject(hRgn);
}
/* map regions to the parent client area */
OffsetRgn(dirtyRgn, Wnd->rectWindow.left, Wnd->rectWindow.top);
OffsetRgn(oldVisRgn, lpOldWndRect->left, lpOldWndRect->top);
/* compute invalidated region outside Wnd - (in client coordinates of the parent window) */
other = CombineRgn(dirtyRgn, oldVisRgn, dirtyRgn, RGN_DIFF);
/* map visible region to the Wnd client area */
OffsetRgn( newVisRgn, Wnd->rectWindow.left - Wnd->rectClient.left,
Wnd->rectWindow.top - Wnd->rectClient.top );
/* substract previously invalidated region from the Wnd visible region */
my = (Wnd->hrgnUpdate > 1)? CombineRgn( newVisRgn, newVisRgn, Wnd->hrgnUpdate, RGN_DIFF)
: COMPLEXREGION;
if( bNoCopy ) /* invalidate Wnd visible region */
{
if (my != NULLREGION) RedrawWindow( Wnd->hwndSelf, NULL, newVisRgn, RDW_INVALIDATE |
RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE );
}
else /* bitblt old client area */
{
HDC hDC;
int update;
HRGN updateRgn;
/* client rect */
updateRgn = CreateRectRgn( 0,0, Wnd->rectClient.right - Wnd->rectClient.left,
Wnd->rectClient.bottom - Wnd->rectClient.top );
/* clip visible region with client rect */
my = CombineRgn( newVisRgn, newVisRgn, updateRgn, RGN_AND );
/* substract result from client rect to get region that won't be copied */
update = CombineRgn( updateRgn, updateRgn, newVisRgn, RGN_DIFF );
/* Blt valid bits using parent window DC */
if( my != NULLREGION )
{
int xfrom = lpOldClientRect->left;
int yfrom = lpOldClientRect->top;
int xto = Wnd->rectClient.left;
int yto = Wnd->rectClient.top;
/* check if we can skip copying */
if( xfrom != xto || yfrom != yto )
{
/* compute clipping region in parent client coordinates */
OffsetRgn( newVisRgn, Wnd->rectClient.left, Wnd->rectClient.top);
CombineRgn( oldVisRgn, oldVisRgn, newVisRgn, RGN_OR );
hDC = GetDCEx( Wnd->parent->hwndSelf, oldVisRgn, DCX_INTERSECTRGN | DCX_CACHE | DCX_CLIPSIBLINGS);
BitBlt(hDC, xto, yto, lpOldClientRect->right - lpOldClientRect->left + 1,
lpOldClientRect->bottom - lpOldClientRect->top + 1,
hDC, xfrom, yfrom, SRCCOPY );
ReleaseDC( Wnd->parent->hwndSelf, hDC);
}
}
if( update != NULLREGION )
RedrawWindow( Wnd->hwndSelf, NULL, updateRgn, RDW_INVALIDATE |
RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE );
DeleteObject( updateRgn );
}
/* erase uncovered areas */
if( other != NULLREGION )
RedrawWindow( Wnd->parent->hwndSelf, NULL, dirtyRgn,
RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE );
DeleteObject(dirtyRgn);
DeleteObject(newVisRgn);
}
/***********************************************************************
* WINPOS_SetXWindowPos
@ -1088,10 +1214,13 @@ static void WINPOS_SetXWindowPos( WINDOWPOS *winpos )
BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y,
INT cx, INT cy, WORD flags )
{
WINDOWPOS winpos;
WND *wndPtr;
RECT newWindowRect, newClientRect;
int result;
WINDOWPOS winpos;
WND * wndPtr;
RECT newWindowRect, newClientRect;
HRGN visRgn = 0;
int result = 0;
dprintf_win(stddeb,"SetWindowPos: hwnd %04x, flags %08x\n", hwnd, flags);
/* Check window handle */
@ -1130,10 +1259,19 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y,
/* TOPMOST not supported yet */
if ((hwndInsertAfter == HWND_TOPMOST) ||
(hwndInsertAfter == HWND_NOTOPMOST)) hwndInsertAfter = HWND_TOP;
/* hwndInsertAfter must be a sibling of the window */
if ((hwndInsertAfter != HWND_TOP) && (hwndInsertAfter != HWND_BOTTOM) &&
(wndPtr->parent != WIN_FindWndPtr(hwndInsertAfter)->parent))
return FALSE;
if ((hwndInsertAfter != HWND_TOP) && (hwndInsertAfter != HWND_BOTTOM))
{
WND* wnd = WIN_FindWndPtr(hwndInsertAfter);
if( wnd->parent != wndPtr->parent ) return FALSE;
if( wnd->next == wndPtr ) flags |= SWP_NOZORDER;
}
else
if (hwndInsertAfter == HWND_TOP)
flags |= ( wndPtr->parent->child == wndPtr)? SWP_NOZORDER: 0;
else /* HWND_BOTTOM */
flags |= ( wndPtr->next )? 0: SWP_NOZORDER;
/* Fill the WINDOWPOS structure */
@ -1166,8 +1304,13 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y,
newWindowRect.top = winpos.y;
newWindowRect.right += winpos.x - wndPtr->rectWindow.left;
newWindowRect.bottom += winpos.y - wndPtr->rectWindow.top;
OffsetRect(&newClientRect, winpos.x - wndPtr->rectWindow.left,
winpos.y - wndPtr->rectWindow.top );
}
winpos.flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
/* Reposition window in Z order */
if (!(winpos.flags & SWP_NOZORDER))
@ -1186,17 +1329,42 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y,
else WINPOS_MoveWindowZOrder( winpos.hwnd, hwndInsertAfter );
}
/* Send WM_NCCALCSIZE message to get new client area */
if ( !wndPtr->window && !(flags & SWP_NOREDRAW) &&
(!(flags & SWP_NOMOVE) || !(flags & SWP_NOSIZE) || (flags & SWP_FRAMECHANGED)) )
visRgn = DCE_GetVisRgn(hwnd, DCX_WINDOW | DCX_CLIPSIBLINGS);
result = WINPOS_SendNCCalcSize( winpos.hwnd, TRUE, &newWindowRect,
/* Send WM_NCCALCSIZE message to get new client area */
if( (flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE )
{
result = WINPOS_SendNCCalcSize( winpos.hwnd, TRUE, &newWindowRect,
&wndPtr->rectWindow, &wndPtr->rectClient,
&winpos, &newClientRect );
/* FIXME: Should handle result here */
/* FIXME: WVR_ALIGNxxx */
if( newClientRect.left != wndPtr->rectClient.left ||
newClientRect.top != wndPtr->rectClient.top )
winpos.flags &= ~SWP_NOCLIENTMOVE;
if( (newClientRect.right - newClientRect.left !=
wndPtr->rectClient.right - wndPtr->rectClient.left) ||
(newClientRect.bottom - newClientRect.top !=
wndPtr->rectClient.bottom - wndPtr->rectClient.top) )
winpos.flags &= ~SWP_NOCLIENTSIZE;
}
else
if( !(flags & SWP_NOMOVE) && (newClientRect.left != wndPtr->rectClient.left ||
newClientRect.top != wndPtr->rectClient.top) )
winpos.flags &= ~SWP_NOCLIENTMOVE;
/* Perform the moving and resizing */
if (wndPtr->window)
{
RECT oldWindowRect = wndPtr->rectWindow;
RECT oldClientRect = wndPtr->rectClient;
HWND bogusInsertAfter = winpos.hwndInsertAfter;
winpos.hwndInsertAfter = hwndInsertAfter;
@ -1205,44 +1373,66 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y,
wndPtr->rectWindow = newWindowRect;
wndPtr->rectClient = newClientRect;
winpos.hwndInsertAfter = bogusInsertAfter;
/* FIXME: should do something like WINPOS_SizeMoveClean */
if( (oldClientRect.left - oldWindowRect.left !=
newClientRect.left - newWindowRect.left) ||
(oldClientRect.top - oldWindowRect.top !=
newClientRect.top - newWindowRect.top) )
RedrawWindow(wndPtr->hwndSelf, NULL, 0, RDW_ALLCHILDREN | RDW_FRAME | RDW_ERASE);
else
if( winpos.flags & SWP_FRAMECHANGED )
{
WORD wErase = 0;
RECT rect;
if( oldClientRect.right > newClientRect.right )
{
rect.left = newClientRect.right; rect.top = newClientRect.top;
rect.right = oldClientRect.right; rect.bottom = newClientRect.bottom;
wErase = 1;
RedrawWindow(wndPtr->hwndSelf, &rect, 0, RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
}
if( oldClientRect.bottom > newClientRect.bottom )
{
rect.left = newClientRect.left; rect.top = newClientRect.bottom;
rect.right = (wErase)?oldClientRect.right:newClientRect.right;
rect.bottom = oldClientRect.bottom;
wErase = 1;
RedrawWindow(wndPtr->hwndSelf, &rect, 0, RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
}
if( !wErase ) wndPtr->flags |= WIN_NEEDS_NCPAINT;
}
}
else
{
RECT oldWindowRect = wndPtr->rectWindow;
RECT oldClientRect = wndPtr->rectClient;
wndPtr->rectWindow = newWindowRect;
wndPtr->rectClient = newClientRect;
if (!(flags & SWP_NOREDRAW) &&
(!(flags & SWP_NOSIZE) || !(flags & SWP_NOMOVE) ||
(!(flags & SWP_NOZORDER) && (hwndInsertAfter != HWND_TOP))))
{
HRGN hrgn1 = CreateRectRgnIndirect( &oldWindowRect );
HRGN hrgn2 = CreateRectRgnIndirect( &wndPtr->rectWindow );
HRGN hrgn3 = CreateRectRgn( 0, 0, 0, 0 );
CombineRgn( hrgn3, hrgn1, hrgn2, RGN_DIFF );
RedrawWindow( wndPtr->parent->hwndSelf, NULL, hrgn3,
RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE );
if( !(flags & SWP_NOREDRAW) )
{
BOOL bNoCopy = (flags & SWP_NOCOPYBITS) ||
(result >= WVR_HREDRAW && result < WVR_VALIDRECTS);
/* DCE_GetVisRgn should be called for old coordinates
* and for new, then OffsetRgn and CombineRgn -
* voila, a nice update region to use here - AK.
*/
if ((oldWindowRect.left != wndPtr->rectWindow.left) ||
(oldWindowRect.top != wndPtr->rectWindow.top))
{
RedrawWindow( winpos.hwnd, NULL, 0, RDW_INVALIDATE |
RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE );
}
else
if( CombineRgn( hrgn3, hrgn2, hrgn1, RGN_DIFF) != NULLREGION )
RedrawWindow( winpos.hwnd, NULL, hrgn3, RDW_INVALIDATE |
RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE );
if( (winpos.flags & SWP_NOPOSCHANGE) != SWP_NOPOSCHANGE )
{
/* optimize cleanup by BitBlt'ing where possible */
DeleteObject( hrgn1 );
DeleteObject( hrgn2 );
DeleteObject( hrgn3 );
}
WINPOS_SizeMoveClean(wndPtr, visRgn, &oldWindowRect, &oldClientRect, bNoCopy);
DeleteObject(visRgn);
}
else
if( winpos.flags & SWP_FRAMECHANGED )
RedrawWindow( winpos.hwnd, NULL, 0, RDW_NOCHILDREN | RDW_FRAME );
}
DeleteObject(visRgn);
}
if (flags & SWP_SHOWWINDOW)
@ -1271,8 +1461,7 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y,
{
if (!(flags & SWP_NOREDRAW))
RedrawWindow( wndPtr->parent->hwndSelf, &wndPtr->rectWindow, 0,
RDW_INVALIDATE | RDW_FRAME |
RDW_ALLCHILDREN | RDW_ERASE );
RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE );
}
if ((winpos.hwnd == GetFocus()) || IsChild(winpos.hwnd, GetFocus()))
@ -1303,18 +1492,12 @@ BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y,
EVENT_DummyMotionNotify(); /* Simulate a mouse event to set the cursor */
if ((flags & SWP_FRAMECHANGED) && !(flags & SWP_NOREDRAW))
RedrawWindow( winpos.hwnd, NULL, 0,
RDW_ALLCHILDREN | /*FIXME: this should not be necessary*/
RDW_INVALIDATE | RDW_FRAME | RDW_ERASE );
if (!(flags & SWP_DEFERERASE))
RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0,
RDW_ALLCHILDREN | RDW_ERASENOW );
/* And last, send the WM_WINDOWPOSCHANGED message */
winpos.flags |= SWP_NOMOVE; /* prevent looping.. window is already moved ??? (FIXME)*/
if (!(winpos.flags & SWP_NOSENDCHANGING))
SendMessage( winpos.hwnd, WM_WINDOWPOSCHANGED,
0, (LPARAM)MAKE_SEGPTR(&winpos) );