Release 960528
Tue May 28 19:36:36 1996 Alexandre Julliard <julliard@lrc.epfl.ch>
* [controls/combo.c]
Destroy the listbox and edit control when destroying the
combo. This should prevent crashes on application exit.
* [misc/system.c] [if1632/system.spec]
Implemented InquireSystem().
* [loader/task.c] [windows/message.c] [windows/queue.c]
First attempt at inter-task SendMessage(). Still has a lot of
problems.
Tue May 28 14:26:04 1996 Peter Bajusz <hyp-x@inf.bme.hu>
* [windows/mdi.c]
Fixed MDITile with iconic children.
Mon May 27 20:28:18 1996 Albrecht Kleine <kleine@ak.sax.de>
* [misc/commdlg.c]
ChooseFont dialog:
- complete rewrite of FontFamilyEnumProc() and FontStyleEnumProc()
not real available font types (e.g. "Bold") can not selected
- supporting more CF_LIMITSIZE- and CF_...ONLY- flags
* [objects/font.c]
In FONT_MatchFont perform check if "lfFaceName" is family from X11
only if "lfFaceName" is a windows font family then do a call of
FONT_TranslateName() : this results in better font selections in
ChooseFont() or applications like charmap.exe or write.exe.
Added a ParseFontParms() call if necessary in function
FONT_MatchFont(): we need a font name as basis for GetTextFace()
even if there isn't one...
* [resources/TODO]
Inventory of resource translations in sysres_??.rc
Fri May 24 16:33:28 1996 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
* [misc/registry.c]
_w95_loadreg: use offset to determine next RGDB position too.
Thu May 23 19:35:38 1996 Greg Kreider <kreider@natlab.research.philips.com>
* [controls/combo.c]
Fixed size of combo, lbox, and button (lb sometimes off by 2 pixels).
* [misc/main.c]
Result of option "-fixedmap" is to turn flag on.
Thu May 23 19:15:41 1996 Ronan Waide <root@waider.ie>
* [misc/shell.c]
ShellExecute and FindExecutable now both use common code to
determine the required executable file.
diff --git a/ANNOUNCE b/ANNOUNCE
index e675cea..b2c5356 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,13 +1,12 @@
-This is release 960521 of Wine the MS Windows emulator. This is still a
+This is release 960528 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-960521: (see ChangeLog for details)
- - Even more Win32 support.
- - Winhelp clone should compile OK.
+WHAT'S NEW with Wine-960528: (see ChangeLog for details)
+ - First attempt at inter-task SendMessage(); still broken.
- Lots of bug fixes.
See the README file in the distribution for installation instructions.
@@ -16,10 +15,10 @@
the release is available at the ftp sites. The sources will be available
from the following locations:
- sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960521.tar.gz
- tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960521.tar.gz
- ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960521.tar.gz
- aris.com:/pub/linux/ALPHA/Wine/development/Wine-960521.tar.gz
+ sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960528.tar.gz
+ tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960528.tar.gz
+ ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960528.tar.gz
+ aris.com:/pub/linux/ALPHA/Wine/development/Wine-960528.tar.gz
It should also be available from any site that mirrors tsx-11 or sunsite.
diff --git a/ChangeLog b/ChangeLog
index 2a032fd..488637b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,62 @@
----------------------------------------------------------------------
+Tue May 28 19:36:36 1996 Alexandre Julliard <julliard@lrc.epfl.ch>
+
+ * [controls/combo.c]
+ Destroy the listbox and edit control when destroying the
+ combo. This should prevent crashes on application exit.
+
+ * [misc/system.c] [if1632/system.spec]
+ Implemented InquireSystem().
+
+ * [loader/task.c] [windows/message.c] [windows/queue.c]
+ First attempt at inter-task SendMessage(). Still has a lot of
+ problems.
+
+Tue May 28 14:26:04 1996 Peter Bajusz <hyp-x@inf.bme.hu>
+
+ * [windows/mdi.c]
+ Fixed MDITile with iconic children.
+
+Mon May 27 20:28:18 1996 Albrecht Kleine <kleine@ak.sax.de>
+
+ * [misc/commdlg.c]
+ ChooseFont dialog:
+ - complete rewrite of FontFamilyEnumProc() and FontStyleEnumProc()
+ not real available font types (e.g. "Bold") can not selected
+ - supporting more CF_LIMITSIZE- and CF_...ONLY- flags
+
+ * [objects/font.c]
+ In FONT_MatchFont perform check if "lfFaceName" is family from X11
+ only if "lfFaceName" is a windows font family then do a call of
+ FONT_TranslateName() : this results in better font selections in
+ ChooseFont() or applications like charmap.exe or write.exe.
+ Added a ParseFontParms() call if necessary in function
+ FONT_MatchFont(): we need a font name as basis for GetTextFace()
+ even if there isn't one...
+
+ * [resources/TODO]
+ Inventory of resource translations in sysres_??.rc
+
+Fri May 24 16:33:28 1996 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
+
+ * [misc/registry.c]
+ _w95_loadreg: use offset to determine next RGDB position too.
+
+Thu May 23 19:35:38 1996 Greg Kreider <kreider@natlab.research.philips.com>
+
+ * [controls/combo.c]
+ Fixed size of combo, lbox, and button (lb sometimes off by 2 pixels).
+
+ * [misc/main.c]
+ Result of option "-fixedmap" is to turn flag on.
+
+Thu May 23 19:15:41 1996 Waider <root@waider.ie>
+
+ * [misc/shell.c]
+ ShellExecute and FindExecutable now both use common code to
+ determine the required executable file.
+
+----------------------------------------------------------------------
Tue May 21 14:06:07 1996 Alexandre Julliard <julliard@lrc.epfl.ch>
* [controls/button.c]
diff --git a/controls/combo.c b/controls/combo.c
index 37e6718..409f720 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -145,7 +145,6 @@
{
case CBS_SIMPLE: /* edit control, list always visible */
lboxrect=rect;
- lboxrect.left +=8;
dprintf_combo(stddeb,"CBS_SIMPLE\n");
style= WS_BORDER | WS_CHILD | WS_VISIBLE | WS_VSCROLL;
SetRectEmpty16(&lphc->RectButton);
@@ -162,10 +161,9 @@
lphc->RectButton = rect;
lphc->RectButton.left = lphc->RectButton.right - 6 - CBitWidth;
lphc->RectButton.bottom = lphc->RectButton.top + lphl->StdItemHeight;
- SetWindowPos(hwnd, 0, 0, 0, rect.right - rect.left + 2*SYSMETRICS_CXBORDER,
+ SetWindowPos(hwnd, 0, 0, 0, rect.right -rect.left + 2*SYSMETRICS_CXBORDER,
lphl->StdItemHeight + 2*SYSMETRICS_CYBORDER,
- SWP_NOMOVE | SWP_NOZORDER);
- rect.right=lphc->RectButton.left - 8;
+ SWP_NOMOVE | SWP_NOZORDER | SWP_NOSENDCHANGING);
dprintf_combo(stddeb,(cstyle & 3)==CBS_DROPDOWN ? "CBS_DROPDOWN\n": "CBS_DROPDOWNLIST\n");
break;
@@ -175,8 +173,9 @@
if ((cstyle & 3) != CBS_DROPDOWNLIST)
lphc->hWndEdit = CreateWindow16(MAKE_SEGPTR(editName), (SEGPTR)0,
- WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | ES_LEFT | WS_BORDER,
- 0, 0, rect.right, lphl->StdItemHeight,
+ WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE | ES_LEFT,
+ 0, 0, rect.right-6-CBitWidth,
+ lphl->StdItemHeight+2*SYSMETRICS_CYBORDER,
hwnd, (HMENU)ID_EDIT, WIN_GetWindowInstance(hwnd), 0L);
lboxrect.top+=lphc->LBoxTop;
@@ -210,11 +209,10 @@
*/
static LRESULT CBDestroy(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
- LPHEADLIST lphl = ComboGetListHeader(hwnd);
+ LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
- ListBoxResetContent(lphl);
- DestroyListBoxStruct(lphl);
- dprintf_combo(stddeb,"Combo WM_DESTROY %p !\n", lphl);
+ if (lphc->hWndEdit) DestroyWindow( lphc->hWndEdit );
+ if (lphc->hWndLBox) DestroyWindow( lphc->hWndLBox );
return 0;
}
@@ -233,8 +231,16 @@
RECT16 rect;
hdc = BeginPaint16(hwnd, &ps);
+
+ GetClientRect16(hwnd, &rect);
+ CBCheckSize(hwnd);
+ /* 1 for button border */
+ rect.right = lphc->RectButton.left - 1;
+
if (hComboBit != 0 && !IsRectEmpty16(&lphc->RectButton))
{
+ Rectangle(hdc,lphc->RectButton.left-1,lphc->RectButton.top-1,
+ lphc->RectButton.right+1,lphc->RectButton.bottom+1);
GRAPH_DrawReliefRect(hdc, &lphc->RectButton, 2, 2, FALSE);
GRAPH_DrawBitmap(hdc, hComboBit,
lphc->RectButton.left + 2,lphc->RectButton.top + 2,
@@ -258,11 +264,6 @@
#endif
if (hBrush == 0) hBrush = GetStockObject(WHITE_BRUSH);
- GetClientRect16(hwnd, &rect);
-
- CBCheckSize(hwnd);
- rect.right -= (lphc->RectButton.right - lphc->RectButton.left);
-
lpls = ListBoxGetItem(lphl,lphl->ItemFocused);
if (lpls != NULL) {
FillRect16(hdc, &rect, hBrush);
@@ -630,17 +631,17 @@
LONG cstyle = GetWindowLong(hwnd,GWL_STYLE);
RECT16 cRect,wRect;
- /* TODO - The size of combo's and their listboxes is still broken */
-
if (lphc->hWndLBox == 0) return FALSE;
GetClientRect16(hwnd,&cRect);
GetWindowRect16(hwnd,&wRect);
- dprintf_combo(stddeb,"CBCheckSize: cRect %d,%d-%d,%d wRect %d,%d-%d,%d\n",
- cRect.left,cRect.top,cRect.right,cRect.bottom,
+ dprintf_combo(stddeb,
+ "CBCheckSize: hwnd %04x Rect %d,%d-%d,%d wRect %d,%d-%d,%d\n",
+ hwnd,cRect.left,cRect.top,cRect.right,cRect.bottom,
wRect.left,wRect.top,wRect.right,wRect.bottom);
if ((cstyle & 3) == CBS_SIMPLE ) return TRUE ;
+
if ((cRect.bottom - cRect.top) >
(lphl->StdItemHeight + 2*SYSMETRICS_CYBORDER)) {
SetWindowPos(hwnd, 0, 0, 0,
@@ -649,23 +650,29 @@
SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE );
GetClientRect16(hwnd,&cRect);
GetWindowRect16(hwnd,&wRect);
+
+ lphc->RectButton.right = cRect.right;
+ lphc->RectButton.left = cRect.right - 2*SYSMETRICS_CXBORDER - 4
+ - CBitWidth;
+ lphc->RectButton.top = cRect.top;
+ lphc->RectButton.bottom = cRect.bottom;
}
- switch (cstyle & 3) {
- case CBS_SIMPLE:
- break;
- case CBS_DROPDOWN:
- case CBS_DROPDOWNLIST:
+ if (cRect.right < lphc->RectButton.left) {
+ /* if the button is outside the window, move it in */
+ if ((wRect.right - wRect.left - 2*SYSMETRICS_CXBORDER) == (cRect.right - cRect.left)) {
lphc->RectButton.right = cRect.right;
lphc->RectButton.left = cRect.right - 2*SYSMETRICS_CXBORDER - 4
- CBitWidth;
lphc->RectButton.top = cRect.top;
lphc->RectButton.bottom = cRect.bottom;
- break;
- default:
- fprintf(stderr,"CBCheckSize: style %lx not recognized!\n",cstyle);
- return FALSE;
}
+ /* otherwise we need to make the client include the button */
+ else
+ SetWindowPos(hwnd, 0, 0, 0, lphc->RectButton.right,
+ lphl->StdItemHeight+2*SYSMETRICS_CYBORDER,
+ SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE );
+ }
CBLCheckSize(hwnd);
return TRUE;
@@ -1116,7 +1123,7 @@
LPLISTSTRUCT lpls;
HWND hWndLBox;
RECT16 cRect,wRect,lRect,lwRect;
- int totheight;
+ int totheight,dw;
char className[80];
GetClassName32A(hwnd,className,80);
@@ -1143,12 +1150,16 @@
for (lpls=lphl->lpFirst; lpls != NULL; lpls=lpls->lpNext)
totheight += lpls->mis.itemHeight;
+ dw = cRect.right-cRect.left+2*SYSMETRICS_CXBORDER+SYSMETRICS_CXVSCROLL;
+ dw -= lwRect.right-lwRect.left;
+ dw -= SYSMETRICS_CXVSCROLL;
+
/* TODO: This isn't really what windows does */
- if (lRect.bottom-lRect.top < 3*lphl->StdItemHeight) {
- dprintf_combo(stddeb," Changing; totHeight %d StdItemHght %d\n",
- totheight,lphl->StdItemHeight);
+ if ((lRect.bottom-lRect.top < 3*lphl->StdItemHeight) || dw) {
+ dprintf_combo(stddeb," Changing; totHeight %d StdItemHght %d dw %d\n",
+ totheight,lphl->StdItemHeight,dw);
SetWindowPos(hWndLBox, 0, lRect.left, lRect.top,
- lwRect.right-lwRect.left, totheight+2*SYSMETRICS_CYBORDER,
+ lwRect.right-lwRect.left+dw, totheight+2*SYSMETRICS_CYBORDER,
SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE );
}
return TRUE;
diff --git a/if1632/system.spec b/if1632/system.spec
index 0b727a1..1352396 100644
--- a/if1632/system.spec
+++ b/if1632/system.spec
@@ -1,12 +1,12 @@
name system
type win16
-1 stub InquireSystem
+1 pascal InquireSystem(word word word) InquireSystem
2 stub CreateSystemTimer
3 stub KillSystemTimer
4 stub EnableSystemTimers
5 stub DisableSystemTimers
-6 pascal GetSystemmsecCount() GetTickCount
+6 pascal GetSystemMSecCount() GetTickCount
7 return Get80x87SaveSize 0 94
8 stub Save80x87State
9 stub Restore80x87State
diff --git a/if1632/user.spec b/if1632/user.spec
index e9b2b7c..2444720 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -114,7 +114,7 @@
112 pascal16 WaitMessage() WaitMessage
113 pascal16 TranslateMessage(ptr) TranslateMessage
114 pascal DispatchMessage(ptr) DispatchMessage
-115 stub ReplyMessage
+115 pascal16 ReplyMessage(long) ReplyMessage
116 pascal16 PostAppMessage(word word word long) PostAppMessage
118 pascal16 RegisterWindowMessage(segptr) RegisterWindowMessage16
117 stub WindowFromDC
@@ -315,7 +315,7 @@
325 pascal16 PaintRect(word word word word ptr) PaintRect
326 pascal16 GetControlBrush(word word word) GetControlBrush
331 pascal16 EnableHardwareInput(word) EnableHardwareInput
-332 return UserYield 0 0
+332 pascal16 UserYield() UserYield
333 stub IsUserIdle
334 pascal GetQueueStatus(word) GetQueueStatus
335 pascal16 GetInputState() GetInputState
@@ -426,6 +426,11 @@
482 pascal16 EnableScrollBar(word word word) EnableScrollBar
483 pascal16 SystemParametersInfo(word word ptr word) SystemParametersInfo
#484 __GP
+# Stubs for Hebrew version
+489 pascal16 USER_489() stub_USER_489
+490 pascal16 USER_490() stub_USER_490
+492 pascal16 USER_492() stub_USER_492
+496 pascal16 USER_496() stub_USER_496
499 pascal16 WNetErrorText(word ptr word) WNetErrorText
501 pascal16 WNetOpenJob(ptr ptr word ptr) WNetOpenJob
502 pascal16 WNetCloseJob(word ptr ptr) WNetCloseJob
@@ -514,10 +519,6 @@
890 stub InstallIMT
891 stub UninstallIMT
# Stubs for Hebrew version
-489 pascal16 USER_489() stub_USER_489
-490 pascal16 USER_490() stub_USER_490
-492 pascal16 USER_492() stub_USER_492
-496 pascal16 USER_496() stub_USER_496
902 pascal16 USER_902() stub_USER_902
905 pascal16 USER_905() stub_USER_905
906 pascal16 USER_906() stub_USER_906
diff --git a/include/commdlg.h b/include/commdlg.h
index 84965e4..624822b 100644
--- a/include/commdlg.h
+++ b/include/commdlg.h
@@ -283,19 +283,6 @@
#define CDERR_NOHOOK 0x000B
#define CDERR_REGISTERMSGFAIL 0x000C
-/************************************************************************
-* COMMDLG Resources placed in Wine SYSRES.DLL *
-************************************************************************/
-
-#define OPENFILEDLG 3
-#define SAVEFILEDLG 4
-#define PRINTDLG 5
-#define PRINTSETUPDLG 6
-#define FONTDLG 7
-#define COLORDLG 8
-#define FINDDLG 9
-#define REPLACEDLG 10
-
BOOL ChooseColor(LPCHOOSECOLOR lpChCol);
DWORD CommDlgExtendedError(void);
BOOL FindText(LPFINDREPLACE lpFind);
diff --git a/include/event.h b/include/event.h
deleted file mode 100644
index 4019f1d..0000000
--- a/include/event.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __WINE_EVENT_H
-#define __WINE_EVENT_H
-
-extern void EVENT_ProcessEvent( XEvent *event ); /* event.c */
-extern void EVENT_RegisterWindow( Window w, HWND hwnd ); /* event.c */
-extern void EVENT_DummyMotionNotify(void); /* event.c */
-
-#endif /* __WINE_EVENT_H */
diff --git a/include/message.h b/include/message.h
index 870695c..1fc0266 100644
--- a/include/message.h
+++ b/include/message.h
@@ -7,14 +7,27 @@
#ifndef __WINE_MESSAGE_H
#define __WINE_MESSAGE_H
-#include "windows.h"
+#include "win.h"
+#include "queue.h"
extern DWORD MSG_WineStartTicks; /* Ticks at Wine startup */
-extern void MSG_Synchronize();
-extern BOOL MSG_WaitXEvent( LONG maxWait );
+/* message.c */
extern BOOL MSG_GetHardwareMessage( LPMSG msg );
extern BOOL MSG_InternalGetMessage( SEGPTR msg, HWND hwnd, HWND hwndOwner,
short code, WORD flags, BOOL sendIdle );
+/* timer.c */
+extern void TIMER_RemoveWindowTimers( HWND hwnd );
+extern void TIMER_RemoveQueueTimers( HQUEUE hqueue );
+extern void TIMER_SwitchQueue( HQUEUE hOldQueue, HQUEUE hNewQueue );
+extern LONG TIMER_GetNextExp(void);
+
+/* event.c */
+extern BOOL EVENT_WaitXEvent( LONG maxWait );
+extern void EVENT_Synchronize(void);
+extern void EVENT_ProcessEvent( XEvent *event );
+extern void EVENT_RegisterWindow( Window w, HWND hwnd );
+extern void EVENT_DummyMotionNotify(void);
+
#endif /* __WINE_MESSAGE_H */
diff --git a/include/queue.h b/include/queue.h
index fba9398..6230b89 100644
--- a/include/queue.h
+++ b/include/queue.h
@@ -42,16 +42,17 @@
DWORD SendMessageReturn; /* 28 Return value for SendMessage */
WORD wPostQMsg; /* 2c PostQuitMessage flag */
WORD wExitCode; /* 2e PostQuitMessage exit code */
- WORD reserved3[3]; /* 30 Unknown */
+ WORD flags; /* 30 Queue flags */
+ WORD reserved3[2]; /* 32 Unknown */
WORD wWinVersion; /* 36 Expected Windows version */
HQUEUE InSendMessageHandle; /* 38 Queue of task that sent a message */
HTASK hSendingTask; /* 3a Handle of task that sent a message */
HTASK hPrevSendingTask; /* 3c Handle of previous sender */
WORD wPaintCount; /* 3e Number of WM_PAINT needed */
WORD wTimerCount; /* 40 Number of timers for this task */
- WORD tempStatus; /* 42 State reset by GetQueueStatus */
- WORD status; /* 44 Queue state */
- WORD wakeMask; /* 46 Task wake-up mask */
+ WORD changeBits; /* 42 Changed wake-up bits */
+ WORD wakeBits; /* 44 Queue wake-up bits */
+ WORD wakeMask; /* 46 Queue wake-up mask */
WORD SendMsgReturnPtrs[3]; /* 48 Near ptr to return values (?) */
HANDLE hCurHook; /* 4e Current hook */
HANDLE hooks[WH_NB_HOOKS]; /* 50 Task hooks list */
@@ -63,9 +64,19 @@
#pragma pack(4)
#endif
+/* Extra (undocumented) queue wake bits; not sure about the values */
+#define QS_SMRESULT 0x0100 /* Queue has a SendMessage() result */
+#define QS_SMPARAMSFREE 0x0200 /* SendMessage() parameters are available */
+
+/* Queue flags */
+#define QUEUE_FLAG_REPLIED 0x0001 /* Replied to a SendMessage() */
+
extern void QUEUE_DumpQueue( HQUEUE hQueue );
extern void QUEUE_WalkQueues(void);
extern MESSAGEQUEUE *QUEUE_GetSysQueue(void);
+extern void QUEUE_SetWakeBit( MESSAGEQUEUE *queue, WORD bit );
+extern void QUEUE_ReceiveMessage( MESSAGEQUEUE *queue );
+extern void QUEUE_WaitBits( WORD bits );
extern void QUEUE_IncPaintCount( HQUEUE hQueue );
extern void QUEUE_DecPaintCount( HQUEUE hQueue );
extern void QUEUE_IncTimerCount( HQUEUE hQueue );
diff --git a/include/windows.h b/include/windows.h
index 5d64c15..03cf15b 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -3188,6 +3188,7 @@
BOOL PlayMetaFile(HDC,HANDLE);
void PlayMetaFileRecord(HDC,LPHANDLETABLE,LPMETARECORD,WORD);
BOOL PostAppMessage(HANDLE,WORD,WORD,LONG);
+void PostEvent(HTASK);
BOOL PostMessage(HWND,WORD,WORD,LONG);
void PostQuitMessage(INT);
WORD PrestoChangoSelector(WORD,WORD);
@@ -3211,7 +3212,7 @@
BOOL RemoveFontResource(LPSTR);
BOOL RemoveMenu(HMENU,UINT,UINT);
HANDLE RemoveProp(HWND,SEGPTR);
-void ReplyMessage(LONG);
+void ReplyMessage(LRESULT);
HDC ResetDC(HDC,LPVOID);
BOOL ResizePalette(HPALETTE16,UINT);
BOOL RestoreDC(HDC,short);
@@ -3338,6 +3339,7 @@
SEGPTR WIN16_GlobalLock16(HGLOBAL16);
SEGPTR WIN16_LockResource(HANDLE);
SEGPTR WIN16_lstrcpyn(SEGPTR,SEGPTR,WORD);
+BOOL WaitEvent(HTASK);
void WaitMessage(void);
int WaitSoundState(int);
HANDLE WinExec(LPSTR,WORD);
diff --git a/loader/task.c b/loader/task.c
index 44443f6..db91fd0 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -7,6 +7,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+
#include "windows.h"
#include "task.h"
#include "callback.h"
@@ -16,6 +17,7 @@
#include "debugger.h"
#include "global.h"
#include "instance.h"
+#include "message.h"
#include "miscemu.h"
#include "module.h"
#include "neexe.h"
@@ -33,7 +35,6 @@
/* Must not be greater than 64k, or MAKE_SEGPTR won't work */
#define STACK32_SIZE 0x10000
-extern void TIMER_SwitchQueue(HQUEUE, HQUEUE );
extern void USER_AppExit(HTASK, HINSTANCE, HQUEUE );
/* ------ Internal variables ------ */
@@ -441,13 +442,8 @@
pTask->hPrevInstance = hPrevInstance;
pTask->hModule = hModule;
pTask->hParent = hCurrentTask;
-#ifdef WINELIB
- pTask->curdrive = 'C' - 'A' + 0x80;
- strcpy( pTask->curdir, "\\" );
-#else
pTask->curdrive = filename[0] - 'A' + 0x80;
strcpy( pTask->curdir, filename+2 );
-#endif
pTask->magic = TDB_MAGIC;
pTask->nCmdShow = cmdShow;
@@ -631,7 +627,7 @@
if (hTaskToKill && (hTaskToKill != hCurrentTask))
{
/* If another task is already marked for destruction, */
- /* we call kill it now, as we are in another context. */
+ /* we can kill it now, as we are in another context. */
TASK_DeleteTask( hTaskToKill );
}
@@ -679,11 +675,11 @@
hTaskToKill = 0;
}
- /* If current task is locked, simply return */
+ /* Flush any X events that happened in the meantime */
- if (hLockedTask) return;
+ EVENT_WaitXEvent( 0 );
- /* Find a task to yield to */
+ /* Find a task to yield to */
pOldTask = (TDB *)GlobalLock16( hCurrentTask );
if (pOldTask && pOldTask->hYieldTo)
@@ -695,23 +691,26 @@
hTask = 0;
}
- if (!hTask)
+ while (!hTask)
{
+ /* Find a task that has an event pending */
+
hTask = hFirstTask;
while (hTask)
{
pNewTask = (TDB *)GlobalLock16( hTask );
- if (pNewTask->nEvents && (hTask != hCurrentTask)) break;
+ if (pNewTask->nEvents) break;
hTask = pNewTask->hNext;
}
+ if (hLockedTask && (hTask != hLockedTask)) hTask = 0;
+ if (hTask) break;
+
+ /* No task found, wait for some events to come in */
+
+ EVENT_WaitXEvent( TIMER_GetNextExp() );
}
- /* If there's a task to kill, switch to any other task, */
- /* even if it doesn't have events pending. */
-
- if (!hTask && hTaskToKill) hTask = hFirstTask;
-
- if (!hTask) return; /* Do nothing */
+ if (hTask == hCurrentTask) return; /* Nothing to do */
pNewTask = (TDB *)GlobalLock16( hTask );
dprintf_task( stddeb, "Switching to task %04x (%.8s)\n",
@@ -842,8 +841,9 @@
return FALSE;
}
TASK_SCHEDULE();
- /* When we get back here, we have an event (or the task is the only one) */
+ /* When we get back here, we have an event */
if (pTask->nEvents > 0) pTask->nEvents--;
+ else fprintf( stderr, "WaitEvent: reschedule returned without event\n" );
return TRUE;
}
@@ -921,12 +921,28 @@
*/
void DirectedYield( HTASK hTask )
{
- TDB *pCurTask;
+ TDB *pCurTask = (TDB *)GlobalLock16( hCurrentTask );
+ pCurTask->hYieldTo = hTask;
+ OldYield();
+}
- if ((pCurTask = (TDB *)GlobalLock16( hCurrentTask )) != NULL)
- pCurTask->hYieldTo = hTask;
+
+/***********************************************************************
+ * UserYield (USER.332)
+ */
+void UserYield(void)
+{
+ TDB *pCurTask = (TDB *)GlobalLock16( hCurrentTask );
+ MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( pCurTask->hQueue );
+ /* Handle sent messages */
+ if (queue && (queue->wakeBits & QS_SENDMESSAGE))
+ QUEUE_ReceiveMessage( queue );
OldYield();
+
+ queue = (MESSAGEQUEUE *)GlobalLock16( pCurTask->hQueue );
+ if (queue && (queue->wakeBits & QS_SENDMESSAGE))
+ QUEUE_ReceiveMessage( queue );
}
@@ -935,7 +951,10 @@
*/
void Yield(void)
{
- DirectedYield( 0 );
+ TDB *pCurTask = (TDB *)GlobalLock16( hCurrentTask );
+ if (pCurTask) pCurTask->hYieldTo = 0;
+ if (pCurTask && pCurTask->hQueue) UserYield();
+ else OldYield();
}
@@ -1177,11 +1196,7 @@
/* Check the owner for module handle */
-#ifndef WINELIB
owner = FarGetOwner( handle );
-#else
- owner = NULL;
-#endif
if (!(ptr = GlobalLock16( owner ))) return 0;
if (((NE_MODULE *)ptr)->magic == NE_SIGNATURE) return owner;
diff --git a/memory/global.c b/memory/global.c
index 022ad4e..c8e4d5d 100644
--- a/memory/global.c
+++ b/memory/global.c
@@ -820,9 +820,6 @@
#endif
}
-#ifndef WINELIB
-
-#endif /* WINELIB */
/***********************************************************************
* GlobalAlloc32 (KERNEL32.315)
diff --git a/memory/local.c b/memory/local.c
index 00c564d..7bc0546 100644
--- a/memory/local.c
+++ b/memory/local.c
@@ -310,11 +310,16 @@
dprintf_local(stddeb, "LocalInit: %04x %04x-%04x\n", selector, start, end);
if (!selector) selector = CURRENT_DS;
- pHeapInfo = LOCAL_GetHeap(selector);
- if (pHeapInfo) {
- fprintf( stderr, "LocalInit: Heap %04x initialized twice.\n", selector);
- if (debugging_local) LOCAL_PrintHeap(selector);
+ if (debugging_heap)
+ {
+ /* If debugging_heap is set, the global heap blocks are cleared */
+ /* before use, so we can test for double initialization. */
+ if (LOCAL_GetHeap(selector))
+ {
+ fprintf( stderr, "LocalInit: Heap %04x initialized twice.\n", selector);
+ if (debugging_local) LOCAL_PrintHeap(selector);
+ }
}
if (start == 0) {
diff --git a/misc/Makefile.in b/misc/Makefile.in
index b2030ee..6ef8e00 100644
--- a/misc/Makefile.in
+++ b/misc/Makefile.in
@@ -26,6 +26,7 @@
sound.c \
spy.c \
stress.c \
+ system.c \
toolhelp.c \
user.c \
ver.c \
diff --git a/misc/clipboard.c b/misc/clipboard.c
index bbac7a2..0cc5848 100644
--- a/misc/clipboard.c
+++ b/misc/clipboard.c
@@ -150,7 +150,7 @@
XInternAtom(display,"PRIMARY_TEXT",False),
WIN_GetXWindow(hWndClipboardOwner),CurrentTime);
/* TODO: need time-out for broken clients */
- while(wait_for_selection)MSG_WaitXEvent(-1);
+ while(wait_for_selection) EVENT_WaitXEvent(-1);
}
while(TRUE) {
if (lpFormat == NULL) return 0;
diff --git a/misc/commdlg.c b/misc/commdlg.c
index a0569f7..9dae2c0 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -2144,7 +2144,7 @@
{
HANDLE hInst, hDlgTmpl;
BOOL bRet;
- dprintf_commdlg(stddeb,"ChoseFont\n");
+ dprintf_commdlg(stddeb,"ChooseFont\n");
hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_CHOOSE_FONT );
hInst = WIN_GetWindowInstance( lpChFont->hwndOwner );
bRet = DialogBoxIndirectParam( hInst, hDlgTmpl, lpChFont->hwndOwner,
@@ -2178,6 +2178,7 @@
return FALSE;
}
+
/***********************************************************************
* FontFamilyEnumProc (COMMDLG.19)
*/
@@ -2186,73 +2187,135 @@
int i;
WORD w;
HWND hwnd=LOWORD(lParam);
+ HWND hDlg=GetParent(hwnd);
+ LPCHOOSEFONT lpcf=(LPCHOOSEFONT)GetWindowLong(hDlg, DWL_USER);
dprintf_commdlg(stddeb,"FontFamilyEnumProc: font=%s (nFontType=%d)\n",
lplf->lfFaceName,nFontType);
+
+ if (lpcf->Flags & CF_FIXEDPITCHONLY)
+ if (!(lplf->lfPitchAndFamily & FIXED_PITCH))
+ return 1;
+ if (lpcf->Flags & CF_ANSIONLY)
+ if (lplf->lfCharSet != ANSI_CHARSET)
+ return 1;
+ if (lpcf->Flags & CF_TTONLY)
+ if (!(nFontType & 0x0004)) /* this means 'TRUETYPE_FONTTYPE' */
+ return 1;
+
i=SendMessage16(hwnd,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR(lplf->lfFaceName));
if (i!=CB_ERR)
{
w=(lplf->lfCharSet << 8) | lplf->lfPitchAndFamily;
SendMessage16(hwnd, CB_SETITEMDATA,i,MAKELONG(nFontType,w));
- return 1 ;
+ return 1 ; /* store some important font information */
}
else
return 0;
}
+/*************************************************************************
+ * SetFontStylesToCombo2 [internal]
+ *
+ * Fill font style information into combobox (without using font.c directly)
+ */
+static int SetFontStylesToCombo2(HWND hwnd, HDC hdc, LPLOGFONT lplf ,LPTEXTMETRIC lptm)
+{
+ #define FSTYLES 4
+ struct FONTSTYLE
+ { int italic;
+ int weight;
+ char stname[20]; };
+ static struct FONTSTYLE fontstyles[FSTYLES]={
+ { 0,FW_NORMAL,"Regular"},{0,FW_BOLD,"Bold"},
+ { 1,FW_NORMAL,"Italic"}, {1,FW_BOLD,"Bold Italic"}};
+ HFONT hf;
+ int i,j;
+
+ for (i=0;i<FSTYLES;i++)
+ {
+ lplf->lfItalic=fontstyles[i].italic;
+ lplf->lfWeight=fontstyles[i].weight;
+ hf=CreateFontIndirect(lplf);
+ hf=SelectObject(hdc,hf);
+ GetTextMetrics(hdc,lptm);
+ hf=SelectObject(hdc,hf);
+ DeleteObject(hf);
+
+ if (lptm->tmWeight==fontstyles[i].weight &&
+ lptm->tmItalic==fontstyles[i].italic) /* font successful created ? */
+ {
+ j=SendMessage16(hwnd,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR(fontstyles[i].stname));
+ if (j==CB_ERR) return 1;
+ j=SendMessage16(hwnd, CB_SETITEMDATA, j,
+ MAKELONG(fontstyles[i].weight,fontstyles[i].italic));
+ if (j==CB_ERR) return 1;
+ }
+ }
+ return 0;
+ }
+
+/*************************************************************************
+ * SetFontSizesToCombo3 [internal]
+ */
+static int SetFontSizesToCombo3(HWND hwnd, LPLOGFONT lplf, LPCHOOSEFONT lpcf)
+{
+ int sizes[]={8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72,0};
+ int h,i,j;
+ char buffer[20];
+
+ for (i=0;sizes[i] && !lplf->lfHeight;i++)
+ {
+ h=lplf->lfHeight ? lplf->lfHeight : sizes[i];
+
+ if ( (!(lpcf->Flags & CF_LIMITSIZE)) ||
+ ((lpcf->Flags & CF_LIMITSIZE) && (h >= lpcf->nSizeMin) && (h <= lpcf->nSizeMax)))
+ {
+ sprintf(buffer,"%2d",h);
+ j=SendMessage16(hwnd,CB_FINDSTRING,-1,(LPARAM)MAKE_SEGPTR(buffer));
+ if (j==CB_ERR)
+ {
+ j=SendMessage16(hwnd,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR(buffer));
+ if (j==CB_ERR) return 1;
+ j=SendMessage16(hwnd, CB_SETITEMDATA, j, h);
+ if (j==CB_ERR) return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+
/***********************************************************************
* FontStyleEnumProc (COMMDLG.18)
*/
int FontStyleEnumProc(LPLOGFONT lplf ,LPTEXTMETRIC lptm, int nFontType, LPARAM lParam)
{
- int j;
- char buffer[20];
-/* HWND hcmb2=LOWORD(lParam);*/
+ HWND hcmb2=LOWORD(lParam);
HWND hcmb3=HIWORD(lParam);
- LPLOGFONT lf=lplf;
-
+ HWND hDlg=GetParent(hcmb3);
+ LPCHOOSEFONT lpcf=(LPCHOOSEFONT)GetWindowLong(hDlg, DWL_USER);
+ int i;
+
dprintf_commdlg(stddeb,"FontStyleEnumProc: (nFontType=%d)\n",nFontType);
dprintf_commdlg(stddeb," %s h=%d w=%d e=%d o=%d wg=%d i=%d u=%d s=%d ch=%d op=%d cp=%d q=%d pf=%xh\n",
- lf->lfFaceName,lf->lfHeight,lf->lfWidth,lf->lfEscapement,lf->lfOrientation,
- lf->lfWeight,lf->lfItalic,lf->lfUnderline,lf->lfStrikeOut,lf->lfCharSet,
- lf->lfOutPrecision,lf->lfClipPrecision,lf->lfQuality,lf->lfPitchAndFamily);
+ lplf->lfFaceName,lplf->lfHeight,lplf->lfWidth,lplf->lfEscapement,lplf->lfOrientation,
+ lplf->lfWeight,lplf->lfItalic,lplf->lfUnderline,lplf->lfStrikeOut,lplf->lfCharSet,
+ lplf->lfOutPrecision,lplf->lfClipPrecision,lplf->lfQuality,lplf->lfPitchAndFamily);
-#if 1 /* VERSION A: use some predefined height values */
- /* FIXME: if (!(nFontType & RASTER_FONTTYPE))......... */
- {
- int sizes[]={8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72,0};
- int i;
- if (!SendMessage16(hcmb3,CB_GETCOUNT,0,0))
- {
- i=0;
- while (sizes[i])
- {
- sprintf(buffer,"%d",sizes[i]);
- j=SendMessage16(hcmb3,CB_INSERTSTRING,-1,(LPARAM)MAKE_SEGPTR(buffer));
- SendMessage16(hcmb3, CB_SETITEMDATA, j, MAKELONG(sizes[i],0));
- i++;
- }
- }
- }
- return 0;
-#endif
+ if (SetFontSizesToCombo3(hcmb3, lplf ,lpcf))
+ return 0;
-#if 0 /* VERSION B: use only lplf->lfHeight values */
+ if (!SendMessage16(hcmb2,CB_GETCOUNT,0,0))
{
- if (lplf->lfHeight)
- {
- sprintf(buffer,"%3d",lplf->lfHeight);
- j=SendMessage16(hcmb3,CB_FINDSTRING,-1,(LPARAM)MAKE_SEGPTR(buffer));
- if (j==CB_ERR)
- {
- j=SendMessage16(hcmb3,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR(buffer));
- SendMessage16(hcmb3, CB_SETITEMDATA, j, MAKELONG(lplf->lfHeight,lplf->lfWidth));
- }
- }
+ HDC hdc= (lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC) ? lpcf->hDC : GetDC(hDlg);
+ i=SetFontStylesToCombo2(hcmb2,hdc,lplf,lptm);
+ if (!(lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC))
+ ReleaseDC(hDlg,hdc);
+ if (i)
+ return 0;
}
return 1 ;
-#endif
-
}
@@ -2264,7 +2327,6 @@
HDC hdc;
int i,j,res,init=0;
long l;
- char buffer[32];
FARPROC enumCallback = MODULE_GetWndProcEntry16("FontFamilyEnumProc");
LPLOGFONT lpxx;
HCURSOR hcursor=SetCursor(LoadCursor(0,IDC_WAIT));
@@ -2308,21 +2370,6 @@
ShowWindow(GetDlgItem(hDlg,grp1),SW_HIDE);
ShowWindow(GetDlgItem(hDlg,stc4),SW_HIDE);
}
-
- /* perhaps this stuff should be moved to FontStyleEnumProc() ?? */
- strcpy(buffer,"Regular"); /* LoadString(hInst,.... ,buffer,LF_FACESIZE);*/
- j=SendDlgItemMessage16(hDlg,cmb2,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR(buffer));
- SendDlgItemMessage16(hDlg,cmb2, CB_SETITEMDATA, j, MAKELONG(FW_NORMAL,0));
- strcpy(buffer,"Bold"); /* LoadString(hInst,.... ,buffer,LF_FACESIZE);*/
- j=SendDlgItemMessage16(hDlg,cmb2,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR(buffer));
- SendDlgItemMessage16(hDlg,cmb2, CB_SETITEMDATA, j, MAKELONG(FW_BOLD,0));
- strcpy(buffer,"Italic"); /* LoadString(hInst,.... ,buffer,LF_FACESIZE);*/
- j=SendDlgItemMessage16(hDlg,cmb2,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR(buffer));
- SendDlgItemMessage16(hDlg,cmb2, CB_SETITEMDATA, j, MAKELONG(FW_NORMAL,1));
- strcpy(buffer,"Bold Italic"); /* LoadString(hInst,.... ,buffer,LF_FACESIZE);*/
- j=SendDlgItemMessage16(hDlg,cmb2,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR(buffer));
- SendDlgItemMessage16(hDlg,cmb2, CB_SETITEMDATA, j, MAKELONG(FW_BOLD,1));
-
hdc= (lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC) ? lpcf->hDC : GetDC(hDlg);
if (hdc)
{
@@ -2530,9 +2577,7 @@
hdc=(lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC) ? lpcf->hDC : GetDC(hDlg);
if (hdc)
{
- /* only if cmb2 is refilled in FontStyleEnumProc():
- SendDlgItemMessage(hDlg,cmb2,CB_RESETCONTENT,0,0);
- */
+ SendDlgItemMessage16(hDlg,cmb2,CB_RESETCONTENT,0,0);
SendDlgItemMessage16(hDlg,cmb3,CB_RESETCONTENT,0,0);
i=SendDlgItemMessage16(hDlg,cmb1,CB_GETCURSEL,0,0);
if (i!=CB_ERR)
@@ -2588,14 +2633,12 @@
}
i=SendDlgItemMessage16(hDlg,cmb3,CB_GETCURSEL,0,0);
if (i!=CB_ERR)
- {
- l=SendDlgItemMessage16(hDlg,cmb3,CB_GETITEMDATA,i,0);
- lpxx->lfHeight=-LOWORD(l);
- lpxx->lfWidth = 0; /* FYI: lfWidth is in HIWORD(l); */
- }
+ lpxx->lfHeight=-LOWORD(SendDlgItemMessage16(hDlg,cmb3,CB_GETITEMDATA,i,0));
+ else
+ lpxx->lfHeight=0;
lpxx->lfStrikeOut=IsDlgButtonChecked(hDlg,chx1);
lpxx->lfUnderline=IsDlgButtonChecked(hDlg,chx2);
- lpxx->lfOrientation=lpxx->lfEscapement=0;
+ lpxx->lfWidth=lpxx->lfOrientation=lpxx->lfEscapement=0;
lpxx->lfOutPrecision=OUT_DEFAULT_PRECIS;
lpxx->lfClipPrecision=CLIP_DEFAULT_PRECIS;
lpxx->lfQuality=DEFAULT_QUALITY;
@@ -2663,6 +2706,8 @@
case WM_COMMAND:
return CFn_WMCommand(hDlg,wParam,lParam);
case WM_CHOOSEFONT_GETLOGFONT:
+ dprintf_commdlg(stddeb,
+ "FormatCharDlgProc // WM_CHOOSEFONT_GETLOGFONT lParam=%08lX\n", lParam);
/* FIXME: current logfont back to caller */
break;
}
diff --git a/misc/main.c b/misc/main.c
index d1e23ad..85455f7 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -121,7 +121,7 @@
{ "-language", ".language", XrmoptionSepArg, (caddr_t)"En" },
{ "-name", ".name", XrmoptionSepArg, (caddr_t)NULL },
{ "-privatemap", ".privatemap", XrmoptionNoArg, (caddr_t)"on" },
- { "-fixedmap", ".fixedmap", XrmoptionNoArg, (caddr_t)NULL },
+ { "-fixedmap", ".fixedmap", XrmoptionNoArg, (caddr_t)"on" },
{ "-synchronous", ".synchronous", XrmoptionNoArg, (caddr_t)"on" },
{ "-debug", ".debug", XrmoptionNoArg, (caddr_t)"on" },
{ "-debugmsg", ".debugmsg", XrmoptionSepArg, (caddr_t)NULL },
diff --git a/misc/registry.c b/misc/registry.c
index b9c781b..faaf190 100644
--- a/misc/registry.c
+++ b/misc/registry.c
@@ -810,7 +810,8 @@
*
* RGDB_section:
* 00: "RGDB" - magic
- * 04...1F: ?
+ * 04: DWORD offset to next RGDB section (perhaps WORD)
+ * 08...1F: ?
* 20.....: disk keys
*
* disk key:
@@ -1004,10 +1005,10 @@
HFILE hfd;
int fd,lastmodified;
char magic[5];
- unsigned long nr,pos,i,where,version,rgdbsection,end;
+ unsigned long nr,pos,i,where,version,rgdbsection,end,off_next_rgdb;
struct _w95key *keys;
int nrofdkes;
- unsigned char *data,*curdata;
+ unsigned char *data,*curdata,*nextrgdb;
OFSTRUCT ofs;
struct stat stbuf;
@@ -1083,8 +1084,15 @@
continue;
}
if (keys[nr].dkeaddr) {
+ int x;
+
+ for (x=sizeof(dke);x--;)
+ if (((char*)&dke)[x])
+ break;
+ if (x==-1)
+ break; /* finished reading if we got only 0 */
if (nr)
- dprintf_reg(stddeb,"key doubled? nr=%ld,key->dkeaddr=%lx,dkeaddr=%lx\n",nr,keys[i].dkeaddr,dkeaddr);
+ dprintf_reg(stddeb,"key doubled? nr=%ld,key->dkeaddr=%lx,dkeaddr=%lx\n",nr,keys[nr].dkeaddr,dkeaddr);
continue;
}
nr2da[i].nr = nr;
@@ -1116,7 +1124,8 @@
_lclose(hfd);
curdata = data;
memcpy(magic,curdata,4);
- curdata+=4;
+ memcpy(&off_next_rgdb,curdata+4,4);
+ nextrgdb = curdata+off_next_rgdb;
if (strcmp(magic,"RGDB")) {
dprintf_reg(stddeb,"third IFF header not RGDB, but %s\n",magic);
return;
@@ -1128,6 +1137,17 @@
struct _w95key *key,xkey;
bytesread = 0;
+ if (curdata>=nextrgdb) {
+ curdata = nextrgdb;
+ if (!strncmp(curdata,"RGDB",4)) {
+ memcpy(&off_next_rgdb,curdata+4,4);
+ nextrgdb = curdata+off_next_rgdb;
+ curdata+=0x20;
+ } else {
+ dprintf_reg(stddeb,"at end of RGDB section, but no next header. Breaking.\n");
+ break;
+ }
+ }
#define XREAD(whereto,len) \
if ((curdata-data+len)<end) {\
memcpy(whereto,curdata,len);\
@@ -1150,7 +1170,7 @@
continue;
}
if (dkh.nrLS == 0xFFFE) {
- dprintf_reg(stddeb,"0xFFFE at %lx\n",lseek(fd,0,SEEK_CUR)-bytesread);
+ dprintf_reg(stddeb,"0xFFFE at %x\n",curdata-data);
break;
}
dprintf_reg(stddeb,"haven't found nr %ld.\n",nr);
diff --git a/misc/shell.c b/misc/shell.c
index 0aff5cb..4ee423e 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -105,97 +105,14 @@
return bRet;
}
-
/*************************************************************************
- * ShellExecute [SHELL.20]
+ * SHELL_FindExecutable
+ * Utility for code sharing between FindExecutable and ShellExecute
*/
-HINSTANCE ShellExecute(HWND hWnd, LPCSTR lpOperation, LPCSTR lpFile, LPSTR lpParameters, LPCSTR lpDirectory, INT iShowCmd)
-{
- char cmd[400];
- char *p,*x;
- long len;
- char subclass[200];
-
- /* OK. We are supposed to lookup the program associated with lpFile,
- * then to execute it using that program. If lpFile is a program,
- * we have to pass the parameters. If an instance is already running,
- * we might have to send DDE commands.
- *
- * FIXME: Should also look up WIN.INI [Extensions] section?
- */
-
- dprintf_exec(stddeb, "ShellExecute(%04x,'%s','%s','%s','%s',%x)\n",
- hWnd, lpOperation ? lpOperation:"<null>", lpFile ? lpFile:"<null>",
- lpParameters ? lpParameters : "<null>",
- lpDirectory ? lpDirectory : "<null>", iShowCmd);
-
- if (lpFile==NULL) return 0; /* should not happen */
- if (lpOperation==NULL) /* default is open */
- lpOperation="open";
- p=strrchr(lpFile,'.');
- if (p!=NULL) {
- x=p; /* the suffixes in the register database are lowercased */
- while (*x) {*x=tolower(*x);x++;}
- }
- if (p==NULL || !strcmp(p,".exe")) {
- p=".exe";
- if (lpParameters) {
- sprintf(cmd,"%s %s",lpFile,lpParameters);
- } else {
- strcpy(cmd,lpFile);
- }
- } else {
- len=200;
- if (RegQueryValue16((HKEY)HKEY_CLASSES_ROOT,p,subclass,&len)==SHELL_ERROR_SUCCESS) {
- if (len>20)
- fprintf(stddeb,"ShellExecute:subclass with len %ld? (%s), please report.\n",len,subclass);
- subclass[len]='\0';
- strcat(subclass,"\\shell\\");
- strcat(subclass,lpOperation);
- strcat(subclass,"\\command");
- dprintf_exec(stddeb,"ShellExecute:looking for %s.\n",subclass);
- len=400;
- if (RegQueryValue16((HKEY)HKEY_CLASSES_ROOT,subclass,cmd,&len)==SHELL_ERROR_SUCCESS) {
- char *t;
- dprintf_exec(stddeb,"ShellExecute:...got %s\n",cmd);
- cmd[len]='\0';
- t=strstr(cmd,"%1");
- if (t==NULL) {
- strcat(cmd," ");
- strcat(cmd,lpFile);
- } else {
- char *s;
- s=xmalloc(len+strlen(lpFile)+10);
- strncpy(s,cmd,t-cmd);
- s[t-cmd]='\0';
- strcat(s,lpFile);
- strcat(s,t+2);
- strcpy(cmd,s);
- free(s);
- }
- /* does this use %x magic too? */
- if (lpParameters) {
- strcat(cmd," ");
- strcat(cmd,lpParameters);
- }
- } else {
- fprintf(stddeb,"ShellExecute: No %s\\shell\\%s\\command found for \"%s\" suffix.\n",subclass,lpOperation,p);
- return (HINSTANCE)31; /* unknown type */
- }
- } else {
- fprintf(stddeb,"ShellExecute: No operation found for \"%s\" suffix.\n",p);
- return (HINSTANCE)31; /* file not found */
- }
- }
- dprintf_exec(stddeb,"ShellExecute:starting %s\n",cmd);
- return WinExec(cmd,iShowCmd);
-}
-
-
-/*************************************************************************
- * FindExecutable [SHELL.21]
- */
-HINSTANCE FindExecutable(LPCSTR lpFile, LPCSTR lpDirectory, LPSTR lpResult)
+static HINSTANCE SHELL_FindExecutable( LPCSTR lpFile,
+ LPCSTR lpDirectory,
+ LPCSTR lpOperation,
+ LPSTR lpResult)
{
char *extension = NULL; /* pointer to file extension */
char tmpext[5]; /* local copy to mung as we please */
@@ -208,7 +125,7 @@
char *tok; /* token pointer */
int i; /* random counter */
- dprintf_exec(stddeb, "FindExecutable: File %s, Dir %s\n",
+ dprintf_exec(stddeb, "SHELL_FindExecutable: File %s, Dir %s\n",
(lpFile != NULL?lpFile:"-"),
(lpDirectory != NULL?lpDirectory:"-"));
@@ -216,7 +133,7 @@
/* trap NULL parameters on entry */
if (( lpFile == NULL ) || ( lpDirectory == NULL ) ||
- ( lpResult == NULL ))
+ ( lpResult == NULL ) || ( lpOperation == NULL ))
{
/* FIXME - should throw a warning, perhaps! */
return 2; /* File not found. Close enough, I guess. */
@@ -236,7 +153,7 @@
else
tmpext[4]='\0';
for (i=0;i<strlen(tmpext);i++) tmpext[i]=tolower(tmpext[i]);
- dprintf_exec(stddeb, "FindExecutable: %s file\n", tmpext);
+ dprintf_exec(stddeb, "SHELL_FindExecutable: %s file\n", tmpext);
/* Three places to check: */
/* 1. win.ini, [windows], programs (NB no leading '.') */
@@ -259,7 +176,8 @@
{
strcpy(lpResult, lpFile); /* Need to perhaps check that */
/* the file has a path attached */
- dprintf_exec(stddeb, "FindExecutable: found %s\n", lpResult);
+ dprintf_exec(stddeb, "SHELL_FindExecutable: found %s\n",
+ lpResult);
return 33; /* Greater than 32 to indicate success FIXME */
/* what are the correct values here? */
}
@@ -271,10 +189,13 @@
&filetypelen ) == SHELL_ERROR_SUCCESS )
{
filetype[filetypelen]='\0';
- dprintf_exec(stddeb, "File type: %s\n", filetype);
+ dprintf_exec(stddeb, "SHELL_FindExecutable: File type: %s\n",
+ filetype);
- /* Looking for ...buffer\shell\open\command */
- strcat( filetype, "\\shell\\open\\command" );
+ /* Looking for ...buffer\shell\lpOperation\command */
+ strcat( filetype, "\\shell\\" );
+ strcat( filetype, lpOperation );
+ strcat( filetype, "\\command" );
if (RegQueryValue16( (HKEY)HKEY_CLASSES_ROOT, filetype, command,
&commandlen ) == SHELL_ERROR_SUCCESS )
@@ -320,6 +241,70 @@
}
}
+ dprintf_exec(stddeb, "SHELL_FindExecutable: returning %s\n", lpResult);
+ return retval;
+}
+
+/*************************************************************************
+ * ShellExecute [SHELL.20]
+ */
+HINSTANCE ShellExecute(HWND hWnd, LPCSTR lpOperation, LPCSTR lpFile,
+ LPSTR lpParameters, LPCSTR lpDirectory,
+ INT iShowCmd)
+{
+ HINSTANCE retval=31;
+ char cmd[256];
+
+ dprintf_exec(stddeb, "ShellExecute(%04x,'%s','%s','%s','%s',%x)\n",
+ hWnd, lpOperation ? lpOperation:"<null>", lpFile ? lpFile:"<null>",
+ lpParameters ? lpParameters : "<null>",
+ lpDirectory ? lpDirectory : "<null>", iShowCmd);
+
+ if (lpFile==NULL) return 0; /* should not happen */
+ if (lpOperation==NULL) /* default is open */
+ lpOperation="open";
+
+ retval = SHELL_FindExecutable( lpFile, lpDirectory, lpOperation, cmd );
+
+ if ( retval <= 32 )
+ {
+ return retval;
+ }
+
+ if (lpParameters)
+ {
+ strcat(cmd," ");
+ strcat(cmd,lpParameters);
+ }
+
+ dprintf_exec(stddeb,"ShellExecute:starting %s\n",cmd);
+ return WinExec(cmd,iShowCmd);
+}
+
+/*************************************************************************
+ * FindExecutable [SHELL.21]
+ */
+HINSTANCE FindExecutable(LPCSTR lpFile, LPCSTR lpDirectory, LPSTR lpResult)
+{
+ HINSTANCE retval=31; /* default - 'No association was found' */
+
+ dprintf_exec(stddeb, "FindExecutable: File %s, Dir %s\n",
+ (lpFile != NULL?lpFile:"-"),
+ (lpDirectory != NULL?lpDirectory:"-"));
+
+ lpResult[0]='\0'; /* Start off with an empty return string */
+
+ /* trap NULL parameters on entry */
+ if (( lpFile == NULL ) || ( lpDirectory == NULL ) ||
+ ( lpResult == NULL ))
+ {
+ /* FIXME - should throw a warning, perhaps! */
+ return 2; /* File not found. Close enough, I guess. */
+ }
+
+ retval = SHELL_FindExecutable( lpFile, lpDirectory, "open",
+ lpResult );
+
dprintf_exec(stddeb, "FindExecutable: returning %s\n", lpResult);
return retval;
}
diff --git a/misc/system.c b/misc/system.c
new file mode 100644
index 0000000..2b17178
--- /dev/null
+++ b/misc/system.c
@@ -0,0 +1,33 @@
+/*
+ * SYSTEM DLL routines
+ *
+ * Copyright 1996 Alexandre Julliard
+ */
+
+#include <stdio.h>
+#include "windows.h"
+
+
+/***********************************************************************
+ * InquireSystem (SYSTEM.1)
+ */
+DWORD InquireSystem( WORD code, WORD drive, BOOL enable )
+{
+ WORD drivetype;
+
+ switch(code)
+ {
+ case 0: /* Get timer resolution */
+ return 54925;
+
+ case 1: /* Get drive type */
+ drivetype = GetDriveType( drive );
+ return MAKELONG( drivetype, drivetype );
+
+ case 2: /* Enable one-drive logic */
+ fprintf( stderr, "InquireSystem(2): set single-drive %d not supported\n", enable );
+ return 0;
+ }
+ fprintf( stderr, "InquireSystem: unknown code %d\n", code );
+ return 0;
+}
diff --git a/misc/user.c b/misc/user.c
index 448d536..b20b262 100644
--- a/misc/user.c
+++ b/misc/user.c
@@ -21,7 +21,6 @@
#ifndef WINELIB
-extern void TIMER_NukeTimers(HWND, HQUEUE);
extern HTASK TASK_GetNextTask(HTASK);
extern void QUEUE_SetDoomedQueue(HQUEUE);
@@ -127,7 +126,7 @@
/* Nuke timers */
- TIMER_NukeTimers( 0, hQueue );
+ TIMER_RemoveQueueTimers( hQueue );
HOOK_FreeQueueHooks( hQueue );
diff --git a/objects/font.c b/objects/font.c
index ab57ab2..ff7c0c6 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -26,6 +26,7 @@
#define MAX_FONTS 256
static LPLOGFONT lpLogFontList[MAX_FONTS] = { NULL };
+static int ParseFontParms(LPSTR lpFont, WORD wParmsNo, LPSTR lpRetStr, WORD wMaxSiz);
#define CI_NONEXISTCHAR(cs) (((cs)->width == 0) && \
(((cs)->rbearing|(cs)->lbearing| \
@@ -99,6 +100,27 @@
return TRUE;
}
+/***********************************************************************
+ * FONT_ChkX11Family
+ *
+ * returns a valid X11 equivalent if a Windows face name
+ * is like a X11 family - or NULL if translation is needed
+ */
+static char *FONT_ChkX11Family(char *winFaceName )
+{
+ static char x11fam[32+2]; /* will be returned */
+ int i;
+
+ for(i = 0; lpLogFontList[i] != NULL; i++)
+ if( !strcasecmp(winFaceName, lpLogFontList[i]->lfFaceName) )
+ {
+ strcpy(x11fam,"*-");
+ return strcat(x11fam,winFaceName);
+ }
+ return NULL; /* a FONT_TranslateName() call is needed */
+}
+
+
/***********************************************************************
* FONT_TranslateName
@@ -171,7 +193,10 @@
charset = (font->lfCharSet == ANSI_CHARSET) ? "iso8859-1" : "*-*";
if (*font->lfFaceName) {
- family = FONT_TranslateName( font->lfFaceName );
+ family = FONT_ChkX11Family(font->lfFaceName);
+ /*--do _not_ translate if lfFaceName is family from X11 A.K.*/
+ if (!family)
+ family = FONT_TranslateName( font->lfFaceName );
/* FIX ME: I don't if that's correct but it works J.M. */
spacing = '*';
}
@@ -196,7 +221,6 @@
family = "*-*";
break;
}
-
oldheight = height;
oldspacing = spacing;
while (TRUE) {
@@ -239,6 +263,10 @@
}
}
dprintf_font(stddeb," Found '%s'\n", *names );
+ if (!*font->lfFaceName)
+ ParseFontParms(*names, 2, font->lfFaceName , LF_FACESIZE-1);
+ /* we need a font name for function GetTextFace() even if there isn't one ;-) */
+
fontStruct = XLoadQueryFont( display, *names );
XFreeFontNames( names );
return fontStruct;
@@ -878,7 +906,10 @@
}
dprintf_font(stddeb,"InitFontsList // names[%d]='%s' \n", i, names[i]);
ParseFontParms(names[i], 2, str, sizeof(str));
+#if 0
+ /* not necessary because new function FONT_ChkX11Family() */
if (strcmp(str, "fixed") == 0) strcat(str, "sys");
+#endif
AnsiUpper(str);
strcpy(lpNewFont->lfFaceName, str);
ParseFontParms(names[i], 8, str, sizeof(str));
diff --git a/resources/TODO b/resources/TODO
index dbd7c26..1263235 100644
--- a/resources/TODO
+++ b/resources/TODO
@@ -28,15 +28,11 @@
Frans van Dorsselaer
dorssel@rulhm1.LeidenUniv.nl
***************************************************************
-1996, April, 7th
+1996, May
Subject: ChooseColor
===========
-Today I introduced ChooseColor() to commdlg.c.
-Because this old resource was insufficient I wrote a new one
-(including some new static contols).
-
Please delete the old CHOOSECOLOR in YOUR sysres_??.rc
and insert the new CHOOSECOLOR from sysres_En.rc to YOUR
language file and translate this as you like it -
@@ -48,6 +44,7 @@
* French
* Italian
* Korean
+* Finnish
...to be continued......
Thank you.
@@ -56,15 +53,16 @@
kleine@ak.sax.de
**************************************************************
-1996, May, 2nd
+1996, May
-Subject ChooseFont
+Subject: ChooseFont
Just like ChooseColor, please copy CHOSEFONT from sysres_EN.rc,
and translate it to your language. It's okay for:
* English
* German
+* Finnish
.....
Thank you.
diff --git a/windows/event.c b/windows/event.c
index be015bf..53beabe 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -9,11 +9,15 @@
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <errno.h>
#include <X11/keysym.h>
#include <X11/Xlib.h>
#include <X11/Xresource.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
+
#include "windows.h"
#include "gdi.h"
#include "heap.h"
@@ -260,6 +264,91 @@
/***********************************************************************
+ * EVENT_WaitXEvent
+ *
+ * Wait for an X event, but at most maxWait milliseconds (-1 for no timeout).
+ * Return TRUE if an event is pending, FALSE on timeout or error
+ * (for instance lost connection with the server).
+ */
+BOOL EVENT_WaitXEvent( LONG maxWait )
+{
+ fd_set read_set;
+ struct timeval timeout;
+ XEvent event;
+ int fd = ConnectionNumber(display);
+
+ if (!XPending(display) && (maxWait != -1))
+ {
+ FD_ZERO( &read_set );
+ FD_SET( fd, &read_set );
+
+ timeout.tv_usec = (maxWait % 1000) * 1000;
+ timeout.tv_sec = maxWait / 1000;
+
+#ifdef CONFIG_IPC
+ sigsetjmp(env_wait_x, 1);
+ stop_wait_op= CONT;
+
+ if (DDE_GetRemoteMessage()) {
+ while(DDE_GetRemoteMessage())
+ ;
+ return TRUE;
+ }
+ stop_wait_op= STOP_WAIT_X;
+ /* The code up to the next "stop_wait_op= CONT" must be reentrant */
+ if (select( fd+1, &read_set, NULL, NULL, &timeout ) != 1 &&
+ !XPending(display)) {
+ stop_wait_op= CONT;
+ return FALSE;
+ } else {
+ stop_wait_op= CONT;
+ }
+#else /* CONFIG_IPC */
+ if (select( fd+1, &read_set, NULL, NULL, &timeout ) != 1)
+ return FALSE; /* Timeout or error */
+#endif /* CONFIG_IPC */
+
+ }
+
+ /* Process the event (and possibly others that occurred in the meantime) */
+ do
+ {
+
+#ifdef CONFIG_IPC
+ if (DDE_GetRemoteMessage())
+ {
+ while(DDE_GetRemoteMessage()) ;
+ return TRUE;
+ }
+#endif /* CONFIG_IPC */
+
+ XNextEvent( display, &event );
+ EVENT_ProcessEvent( &event );
+ }
+ while (XPending( display ));
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * EVENT_Synchronize
+ *
+ * Synchronize with the X server. Should not be used too often.
+ */
+void EVENT_Synchronize()
+{
+ XEvent event;
+
+ XSync( display, False );
+ while (XPending( display ))
+ {
+ XNextEvent( display, &event );
+ EVENT_ProcessEvent( &event );
+ }
+}
+
+
+/***********************************************************************
* EVENT_XStateToKeyState
*
* Translate a X event state (Button1Mask, ShiftMask, etc...) to
diff --git a/windows/mdi.c b/windows/mdi.c
index 22efc97..b515e58 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -773,12 +773,16 @@
if( !listTop )
break;
- if( listTop->hChild )
+ /* skip iconized childs from tiling */
+ while (!listTop->hChild)
{
- SetWindowPos(listTop->hChild, 0, x, y, xsize, ysize,
- SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
- y += ysize;
- }
+ listPrev = listTop->prev;
+ free(listTop);
+ listTop = listPrev;
+ }
+ SetWindowPos(listTop->hChild, 0, x, y, xsize, ysize,
+ SWP_DRAWFRAME | SWP_NOACTIVATE | SWP_NOZORDER);
+ y += ysize;
listPrev = listTop->prev;
free(listTop);
listTop = listPrev;
diff --git a/windows/message.c b/windows/message.c
index 7e1799b..aef426c 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -8,14 +8,12 @@
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
-#include <errno.h>
#include "message.h"
#include "win.h"
#include "gdi.h"
#include "sysmetrics.h"
#include "hook.h"
-#include "event.h"
#include "spy.h"
#include "winpos.h"
#include "atom.h"
@@ -204,7 +202,7 @@
int i, pos = sysMsgQueue->nextMessage;
/* If the queue is empty, attempt to fill it */
- if (!sysMsgQueue->msgCount && XPending(display)) MSG_WaitXEvent( 0 );
+ if (!sysMsgQueue->msgCount && XPending(display)) EVENT_WaitXEvent( 0 );
for (i = 0; i < sysMsgQueue->msgCount; i++, pos++)
{
@@ -278,6 +276,7 @@
*/
BOOL MSG_GetHardwareMessage( LPMSG msg )
{
+#if 0
int pos;
XEvent event;
MESSAGEQUEUE *sysMsgQueue = QUEUE_GetSysQueue();
@@ -293,92 +292,83 @@
XNextEvent( display, &event );
EVENT_ProcessEvent( &event );
}
+#endif
+ MSG_PeekMessage( msg, 0, WM_KEYFIRST, WM_MOUSELAST, PM_REMOVE, 0 );
return TRUE;
}
/***********************************************************************
- * MSG_Synchronize
+ * MSG_SendMessage
*
- * Synchronize with the X server. Should not be used too often.
+ * Implementation of an inter-task SendMessage.
*/
-void MSG_Synchronize()
+LRESULT MSG_SendMessage( HQUEUE hDestQueue, HWND hwnd, UINT msg,
+ WPARAM wParam, LPARAM lParam )
{
- XEvent event;
+ MESSAGEQUEUE *queue, *destQ;
- XSync( display, False );
- while (XPending( display ))
+ if (!(queue = (MESSAGEQUEUE*)GlobalLock16( GetTaskQueue(0) ))) return 0;
+ if (!(destQ = (MESSAGEQUEUE*)GlobalLock16( hDestQueue ))) return 0;
+
+ if (IsTaskLocked())
{
- XNextEvent( display, &event );
- EVENT_ProcessEvent( &event );
- }
+ fprintf( stderr, "SendMessage: task is locked\n" );
+ return 0;
+ }
+
+ if (queue->hWnd)
+ {
+ fprintf( stderr, "Nested SendMessage() not supported\n" );
+ return 0;
+ }
+ queue->hWnd = hwnd;
+ queue->msg = msg;
+ queue->wParam = wParam;
+ queue->lParam = lParam;
+ queue->hPrevSendingTask = destQ->hSendingTask;
+ destQ->hSendingTask = GetTaskQueue(0);
+ QUEUE_SetWakeBit( destQ, QS_SENDMESSAGE );
+
+ /* Wait for the result */
+
+ printf( "SendMessage %04x to %04x\n", msg, hDestQueue );
+
+ if (!(queue->wakeBits & QS_SMRESULT))
+ {
+ DirectedYield( hDestQueue );
+ QUEUE_WaitBits( QS_SMRESULT );
+ }
+ printf( "SendMessage %04x to %04x: got %08x\n",
+ msg, hDestQueue, queue->SendMessageReturn );
+ queue->wakeBits &= ~QS_SMRESULT;
+ return queue->SendMessageReturn;
}
/***********************************************************************
- * MSG_WaitXEvent
- *
- * Wait for an X event, but at most maxWait milliseconds (-1 for no timeout).
- * Return TRUE if an event is pending, FALSE on timeout or error
- * (for instance lost connection with the server).
+ * ReplyMessage (USER.115)
*/
-BOOL MSG_WaitXEvent( LONG maxWait )
+void ReplyMessage( LRESULT result )
{
- fd_set read_set;
- struct timeval timeout;
- XEvent event;
- int fd = ConnectionNumber(display);
+ MESSAGEQUEUE *senderQ;
+ MESSAGEQUEUE *queue;
- if (!XPending(display) && (maxWait != -1))
+ printf( "ReplyMessage\n " );
+ if (!(queue = (MESSAGEQUEUE*)GlobalLock16( GetTaskQueue(0) ))) return;
+ if (!(senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->InSendMessageHandle)))
+ return;
+ for (;;)
{
- FD_ZERO( &read_set );
- FD_SET( fd, &read_set );
-
- timeout.tv_usec = (maxWait % 1000) * 1000;
- timeout.tv_sec = maxWait / 1000;
-
-#ifdef CONFIG_IPC
- sigsetjmp(env_wait_x, 1);
- stop_wait_op= CONT;
-
- if (DDE_GetRemoteMessage()) {
- while(DDE_GetRemoteMessage())
- ;
- return TRUE;
- }
- stop_wait_op= STOP_WAIT_X;
- /* The code up to the next "stop_wait_op= CONT" must be reentrant */
- if (select( fd+1, &read_set, NULL, NULL, &timeout ) != 1 &&
- !XPending(display)) {
- stop_wait_op= CONT;
- return FALSE;
- } else {
- stop_wait_op= CONT;
- }
-#else /* CONFIG_IPC */
- if (select( fd+1, &read_set, NULL, NULL, &timeout ) != 1)
- return FALSE; /* Timeout or error */
-#endif /* CONFIG_IPC */
-
+ if (queue->wakeBits & QS_SENDMESSAGE) QUEUE_ReceiveMessage( queue );
+ else if (senderQ->wakeBits & QS_SMRESULT) Yield();
+ else break;
}
-
- /* Process the event (and possibly others that occurred in the meantime) */
- do
- {
-
-#ifdef CONFIG_IPC
- if (DDE_GetRemoteMessage())
- {
- while(DDE_GetRemoteMessage()) ;
- return TRUE;
- }
-#endif /* CONFIG_IPC */
-
- XNextEvent( display, &event );
- EVENT_ProcessEvent( &event );
- }
- while (XPending( display ));
- return TRUE;
+ printf( "ReplyMessage: res = %08x\n", result );
+ senderQ->SendMessageReturn = result;
+ queue->InSendMessageHandle = 0;
+ QUEUE_SetWakeBit( senderQ, QS_SMRESULT );
+ DirectedYield( queue->hSendingTask );
}
@@ -397,58 +387,51 @@
DDE_TestDDE(hwnd); /* do we have dde handling in the window ?*/
DDE_GetRemoteMessage();
#endif /* CONFIG_IPC */
-
+
+ mask = QS_POSTMESSAGE | QS_SENDMESSAGE; /* Always selected */
if (first || last)
{
- mask = QS_POSTMESSAGE; /* Always selectioned */
if ((first <= WM_KEYLAST) && (last >= WM_KEYFIRST)) mask |= QS_KEY;
if ((first <= WM_MOUSELAST) && (last >= WM_MOUSEFIRST)) mask |= QS_MOUSE;
if ((first <= WM_TIMER) && (last >= WM_TIMER)) mask |= QS_TIMER;
if ((first <= WM_SYSTIMER) && (last >= WM_SYSTIMER)) mask |= QS_TIMER;
if ((first <= WM_PAINT) && (last >= WM_PAINT)) mask |= QS_PAINT;
}
- else mask = QS_MOUSE | QS_KEY | QS_POSTMESSAGE | QS_TIMER | QS_PAINT;
+ else mask |= QS_MOUSE | QS_KEY | QS_TIMER | QS_PAINT;
+
+ if (IsTaskLocked()) flags |= PM_NOYIELD;
while(1)
{
hQueue = GetTaskQueue(0);
msgQueue = (MESSAGEQUEUE *)GlobalLock16( hQueue );
if (!msgQueue) return FALSE;
+ msgQueue->changeBits = 0;
- /* First handle a message put by SendMessage() */
- if (msgQueue->status & QS_SENDMESSAGE)
- {
- if (!hwnd || (msgQueue->hWnd == hwnd))
- {
- if ((!first && !last) ||
- ((msgQueue->msg >= first) && (msgQueue->msg <= last)))
- {
- msg->hwnd = msgQueue->hWnd;
- msg->message = msgQueue->msg;
- msg->wParam = msgQueue->wParam;
- msg->lParam = msgQueue->lParam;
- if (flags & PM_REMOVE) msgQueue->status &= ~QS_SENDMESSAGE;
- break;
- }
- }
- }
+ /* First handle a message put by SendMessage() */
+
+ if (msgQueue->wakeBits & QS_SENDMESSAGE)
+ QUEUE_ReceiveMessage( msgQueue );
- /* Now find a normal message */
- pos = QUEUE_FindMsg( msgQueue, hwnd, first, last );
- if (pos != -1)
- {
- QMSG *qmsg = &msgQueue->messages[pos];
- *msg = qmsg->msg;
- msgQueue->GetMessageTimeVal = msg->time;
- msgQueue->GetMessagePosVal = *(DWORD *)&msg->pt;
- msgQueue->GetMessageExtraInfoVal = qmsg->extraInfo;
+ /* Now find a normal message */
- if (flags & PM_REMOVE) QUEUE_RemoveMsg( msgQueue, pos );
- break;
- }
+ if (((msgQueue->wakeBits & mask) & QS_POSTMESSAGE) &&
+ ((pos = QUEUE_FindMsg( msgQueue, hwnd, first, last )) != -1))
+ {
+ QMSG *qmsg = &msgQueue->messages[pos];
+ *msg = qmsg->msg;
+ msgQueue->GetMessageTimeVal = msg->time;
+ msgQueue->GetMessagePosVal = *(DWORD *)&msg->pt;
+ msgQueue->GetMessageExtraInfoVal = qmsg->extraInfo;
- /* Now find a hardware event */
- if (MSG_PeekHardwareMsg( msg, hwnd, first, last, flags & PM_REMOVE ))
+ if (flags & PM_REMOVE) QUEUE_RemoveMsg( msgQueue, pos );
+ break;
+ }
+
+ /* Now find a hardware event */
+
+ if (((msgQueue->wakeBits & mask) & (QS_MOUSE | QS_KEY)) &&
+ MSG_PeekHardwareMsg( msg, hwnd, first, last, flags & PM_REMOVE ))
{
/* Got one */
msgQueue->GetMessageTimeVal = msg->time;
@@ -457,7 +440,8 @@
break;
}
- /* Now handle a WM_QUIT message */
+ /* Now handle a WM_QUIT message */
+
if (msgQueue->wPostQMsg)
{
msg->hwnd = hwnd;
@@ -467,8 +451,14 @@
break;
}
- /* Now find a WM_PAINT message */
- if ((msgQueue->status & QS_PAINT) && (mask & QS_PAINT))
+ /* Check again for SendMessage */
+
+ if (msgQueue->wakeBits & QS_SENDMESSAGE)
+ QUEUE_ReceiveMessage( msgQueue );
+
+ /* Now find a WM_PAINT message */
+
+ if ((msgQueue->wakeBits & mask) & QS_PAINT)
{
msg->hwnd = WIN_FindWinToRepaint( hwnd , hQueue );
msg->message = WM_PAINT;
@@ -490,23 +480,28 @@
}
}
- /* Finally handle WM_TIMER messages */
- if ((msgQueue->status & QS_TIMER) && (mask & QS_TIMER))
+ /* Check for timer messages, but yield first */
+
+ if (!(flags & PM_NOYIELD))
+ {
+ UserYield();
+ if (msgQueue->wakeBits & QS_SENDMESSAGE)
+ QUEUE_ReceiveMessage( msgQueue );
+ }
+ if ((msgQueue->wakeBits & mask) & QS_TIMER)
{
if (TIMER_CheckTimer( &nextExp, msg, hwnd, flags & PM_REMOVE ))
break; /* Got a timer msg */
}
else nextExp = -1; /* No timeout needed */
- Yield();
-
- /* Wait until something happens */
if (peek)
{
- if (!MSG_WaitXEvent( 0 )) return FALSE; /* No pending event */
+ if (!(flags & PM_NOYIELD)) UserYield();
+ return FALSE;
}
- else /* Wait for an event, then restart the loop */
- MSG_WaitXEvent( nextExp );
+ msgQueue->wakeMask = mask;
+ QUEUE_WaitBits( mask );
}
/* We got a message */
@@ -534,7 +529,9 @@
0, 0, 0, flags, TRUE ))
{
/* No message present -> send ENTERIDLE and wait */
- SendMessage16( hwndOwner, WM_ENTERIDLE, code, (LPARAM)hwnd );
+ if (IsWindow(hwndOwner))
+ SendMessage16( hwndOwner, WM_ENTERIDLE,
+ code, (LPARAM)hwnd );
MSG_PeekMessage( (MSG *)PTR_SEG_TO_LIN(msg),
0, 0, 0, flags, FALSE );
}
@@ -679,6 +676,7 @@
return TRUE;
}
+
HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, 1,
(LPARAM)MAKE_SEGPTR(&msgstruct) );
hwnd = msgstruct.hWnd;
@@ -686,12 +684,21 @@
wParam = msgstruct.wParam;
lParam = msgstruct.lParam;
- SPY_EnterMessage( SPY_SENDMESSAGE16, hwnd, msg, wParam, lParam );
- if (!(wndPtr = WIN_FindWndPtr( hwnd )))
+ if (!(wndPtr = WIN_FindWndPtr( hwnd )))
{
- SPY_ExitMessage( SPY_RESULT_INVALIDHWND16, hwnd, msg, 0 );
+ fprintf( stderr, "SendMessage16: invalid hwnd %04x\n", hwnd );
return 0;
}
+ if (wndPtr->hmemTaskQ != GetTaskQueue(0))
+ {
+#if 0
+ fprintf( stderr, "SendMessage16: intertask message not supported\n" );
+ return 0;
+#endif
+ return MSG_SendMessage( wndPtr->hmemTaskQ, hwnd, msg, wParam, lParam );
+ }
+
+ SPY_EnterMessage( SPY_SENDMESSAGE16, hwnd, msg, wParam, lParam );
ret = CallWindowProc16( wndPtr->lpfnWndProc, hwnd, msg, wParam, lParam );
SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg, ret );
return ret;
@@ -719,12 +726,18 @@
/* FIXME: call hooks */
- SPY_EnterMessage( SPY_SENDMESSAGE32, hwnd, msg, wParam, lParam );
- if (!(wndPtr = WIN_FindWndPtr( hwnd )))
+ if (!(wndPtr = WIN_FindWndPtr( hwnd )))
{
- SPY_ExitMessage( SPY_RESULT_INVALIDHWND32, hwnd, msg, 0 );
+ fprintf( stderr, "SendMessage32A: invalid hwnd %08x\n", hwnd );
return 0;
}
+ if (wndPtr->hmemTaskQ != GetTaskQueue(0))
+ {
+ fprintf( stderr, "SendMessage32A: intertask message not supported\n" );
+ return 0;
+ }
+
+ SPY_EnterMessage( SPY_SENDMESSAGE32, hwnd, msg, wParam, lParam );
ret = CallWindowProc32A( (WNDPROC32)wndPtr->lpfnWndProc,
hwnd, msg, wParam, lParam );
SPY_ExitMessage( SPY_RESULT_OK32, hwnd, msg, ret );
@@ -753,12 +766,18 @@
/* FIXME: call hooks */
- SPY_EnterMessage( SPY_SENDMESSAGE32, hwnd, msg, wParam, lParam );
- if (!(wndPtr = WIN_FindWndPtr( hwnd )))
+ if (!(wndPtr = WIN_FindWndPtr( hwnd )))
{
- SPY_ExitMessage( SPY_RESULT_INVALIDHWND32, hwnd, msg, 0 );
+ fprintf( stderr, "SendMessage32W: invalid hwnd %08x\n", hwnd );
return 0;
}
+ if (wndPtr->hmemTaskQ != GetTaskQueue(0))
+ {
+ fprintf( stderr, "SendMessage32W: intertask message not supported\n" );
+ return 0;
+ }
+
+ SPY_EnterMessage( SPY_SENDMESSAGE32, hwnd, msg, wParam, lParam );
ret = CallWindowProc32W( (WNDPROC32)wndPtr->lpfnWndProc,
hwnd, msg, wParam, lParam );
SPY_ExitMessage( SPY_RESULT_OK32, hwnd, msg, ret );
@@ -781,14 +800,14 @@
if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return;
if ((queue->wPostQMsg) ||
- (queue->status & (QS_SENDMESSAGE | QS_PAINT)) ||
+ (queue->wakeBits & (QS_SENDMESSAGE | QS_PAINT)) ||
(queue->msgCount) || (QUEUE_GetSysQueue()->msgCount) )
return;
- if ((queue->status & QS_TIMER) &&
+ if ((queue->wakeBits & QS_TIMER) &&
TIMER_CheckTimer( &nextExp, &msg, 0, FALSE))
return;
/* FIXME: (dde) must check DDE & X-events simultaneously */
- MSG_WaitXEvent( nextExp );
+ EVENT_WaitXEvent( nextExp );
}
@@ -927,14 +946,13 @@
/***********************************************************************
- * InSendMessage (USER.192
- *
- * According to the book, this should return true iff the current message
- * was send from another application. In that case, the application should
- * invoke ReplyMessage before calling message relevant API.
- * Currently, Wine will always return FALSE, as there is no other app.
+ * InSendMessage (USER.192)
*/
BOOL InSendMessage()
{
- return FALSE;
+ MESSAGEQUEUE *queue;
+
+ if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) )))
+ return 0;
+ return (BOOL)queue->InSendMessageHandle;
}
diff --git a/windows/queue.c b/windows/queue.c
index 5935bac..e465ebb 100644
--- a/windows/queue.c
+++ b/windows/queue.c
@@ -7,6 +7,7 @@
#include <stdlib.h>
#include "module.h"
#include "queue.h"
+#include "task.h"
#include "win.h"
#include "stddebug.h"
#include "debug.h"
@@ -63,7 +64,7 @@
pq->nextFreeMessage, (unsigned)pq->lParam, pq->queueSize,
(unsigned)pq->SendMessageReturn, pq->wWinVersion, pq->InSendMessageHandle,
pq->wPaintCount, pq->hSendingTask, pq->wTimerCount,
- pq->hPrevSendingTask, pq->status, pq->wakeMask, pq->hCurHook);
+ pq->hPrevSendingTask, pq->wakeBits, pq->wakeMask, pq->hCurHook);
}
@@ -102,6 +103,7 @@
HQUEUE hQueue;
MESSAGEQUEUE * msgQueue;
int queueSize;
+ TDB *pTask = (TDB *)GlobalLock16( GetCurrentTask() );
dprintf_msg(stddeb,"Creating message queue...\n");
@@ -111,7 +113,7 @@
msgQueue = (MESSAGEQUEUE *) GlobalLock16( hQueue );
msgQueue->msgSize = sizeof(QMSG);
msgQueue->queueSize = size;
- msgQueue->wWinVersion = 0; /* FIXME? */
+ msgQueue->wWinVersion = pTask ? pTask->version : 0;
GlobalUnlock16( hQueue );
return hQueue;
}
@@ -173,6 +175,99 @@
/***********************************************************************
+ * QUEUE_SetWakeBit
+ *
+ * See "Windows Internals", p.449
+ */
+void QUEUE_SetWakeBit( MESSAGEQUEUE *queue, WORD bit )
+{
+ queue->changeBits |= bit;
+ queue->wakeBits |= bit;
+ if (queue->wakeMask & bit)
+ {
+ queue->wakeMask = 0;
+ PostEvent( queue->hTask );
+ }
+}
+
+
+/***********************************************************************
+ * QUEUE_WaitBits
+ *
+ * See "Windows Internals", p.447
+ */
+void QUEUE_WaitBits( WORD bits )
+{
+ MESSAGEQUEUE *queue;
+
+ for (;;)
+ {
+ if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return;
+ if (queue->changeBits & bits)
+ {
+ /* One of the bits is set; we can return */
+ queue->wakeMask = 0;
+ return;
+ }
+ if (queue->wakeBits & QS_SENDMESSAGE)
+ {
+ /* Process the sent message immediately */
+ QUEUE_ReceiveMessage( queue );
+ }
+ queue->wakeMask = bits | QS_SENDMESSAGE;
+ WaitEvent( 0 );
+ }
+}
+
+
+/***********************************************************************
+ * QUEUE_ReceiveMessage
+ *
+ * This routine is called when a sent message is waiting for the queue.
+ */
+void QUEUE_ReceiveMessage( MESSAGEQUEUE *queue )
+{
+ MESSAGEQUEUE *senderQ;
+ HWND hwnd;
+ UINT msg;
+ WPARAM wParam;
+ LPARAM lParam;
+ LRESULT result = 0;
+
+ printf( "ReceiveMessage\n" );
+ if (!(queue->wakeBits & QS_SENDMESSAGE)) return;
+ if (!(senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->hSendingTask))) return;
+
+ /* Remove sending queue from the list */
+ queue->InSendMessageHandle = queue->hSendingTask;
+ queue->hSendingTask = senderQ->hPrevSendingTask;
+ senderQ->hPrevSendingTask = 0;
+ if (!queue->hSendingTask) queue->wakeBits &= ~QS_SENDMESSAGE;
+
+ /* Get the parameters from the sending task */
+ hwnd = senderQ->hWnd;
+ msg = senderQ->msg;
+ wParam = senderQ->wParam;
+ lParam = senderQ->lParam;
+ senderQ->hWnd = 0;
+ QUEUE_SetWakeBit( senderQ, QS_SMPARAMSFREE );
+
+ printf( "ReceiveMessage: calling wnd proc %04x %04x %04x %08x\n",
+ hwnd, msg, wParam, lParam );
+
+ /* Call the window procedure */
+ /* FIXME: should we use CallWindowProc here? */
+ if (IsWindow( hwnd )) result = SendMessage16( hwnd, msg, wParam, lParam );
+
+ printf( "ReceiveMessage: wnd proc %04x %04x %04x %08x ret = %08x\n",
+ hwnd, msg, wParam, lParam, result );
+
+ /* Return the result to the sender task */
+ ReplyMessage( result );
+}
+
+
+/***********************************************************************
* QUEUE_AddMsg
*
* Add a message to the queue. Return FALSE if queue is full.
@@ -199,8 +294,7 @@
else pos = 0;
msgQueue->nextFreeMessage = pos;
msgQueue->msgCount++;
- msgQueue->status |= QS_POSTMESSAGE;
- msgQueue->tempStatus |= QS_POSTMESSAGE;
+ QUEUE_SetWakeBit( msgQueue, QS_POSTMESSAGE );
return TRUE;
}
@@ -258,8 +352,47 @@
else msgQueue->nextFreeMessage = msgQueue->queueSize-1;
}
msgQueue->msgCount--;
- if (!msgQueue->msgCount) msgQueue->status &= ~QS_POSTMESSAGE;
- msgQueue->tempStatus = 0;
+ if (!msgQueue->msgCount) msgQueue->wakeBits &= ~QS_POSTMESSAGE;
+}
+
+
+/***********************************************************************
+ * QUEUE_WakeSomeone
+ *
+ * Wake a queue upon reception of a hardware event.
+ */
+static void QUEUE_WakeSomeone( UINT message )
+{
+ HWND hwnd;
+ WORD wakeBit;
+ HQUEUE hQueue;
+ MESSAGEQUEUE *queue = NULL;
+
+ if ((message >= WM_KEYFIRST) && (message <= WM_KEYLAST)) wakeBit = QS_KEY;
+ else wakeBit = (message == WM_MOUSEMOVE) ? QS_MOUSEMOVE : QS_MOUSEBUTTON;
+
+ if (!(hwnd = GetSysModalWindow()))
+ {
+ hwnd = (wakeBit == QS_KEY) ? GetFocus() : GetCapture();
+ if (!hwnd) hwnd = GetActiveWindow();
+ }
+ if (hwnd)
+ {
+ WND *wndPtr = WIN_FindWndPtr( hwnd );
+ if (wndPtr) queue = (MESSAGEQUEUE *)GlobalLock16( wndPtr->hmemTaskQ );
+ }
+ else
+ {
+ hQueue = hFirstQueue;
+ while (hQueue)
+ {
+ queue = GlobalLock16( hQueue );
+ if (queue->wakeBits & wakeBit) break;
+ hQueue = queue->next;
+ }
+ }
+ if (!queue) printf( "WakeSomeone: no one found\n" );
+ if (queue) QUEUE_SetWakeBit( queue, wakeBit );
}
@@ -274,7 +407,7 @@
{
MSG *msg;
int pos;
-
+
if (!sysMsgQueue) return;
pos = sysMsgQueue->nextFreeMessage;
@@ -315,6 +448,7 @@
else pos = 0;
sysMsgQueue->nextFreeMessage = pos;
sysMsgQueue->msgCount++;
+ QUEUE_WakeSomeone( message );
}
@@ -337,8 +471,7 @@
if (!(queue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return;
queue->wPaintCount++;
- queue->status |= QS_PAINT;
- queue->tempStatus |= QS_PAINT;
+ QUEUE_SetWakeBit( queue, QS_PAINT );
}
@@ -351,7 +484,7 @@
if (!(queue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return;
queue->wPaintCount--;
- if (!queue->wPaintCount) queue->status &= ~QS_PAINT;
+ if (!queue->wPaintCount) queue->wakeBits &= ~QS_PAINT;
}
@@ -364,8 +497,7 @@
if (!(queue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return;
queue->wTimerCount++;
- queue->status |= QS_TIMER;
- queue->tempStatus |= QS_TIMER;
+ QUEUE_SetWakeBit( queue, QS_TIMER );
}
@@ -378,7 +510,7 @@
if (!(queue = (MESSAGEQUEUE *)GlobalLock16( hQueue ))) return;
queue->wTimerCount--;
- if (!queue->wTimerCount) queue->status &= ~QS_TIMER;
+ if (!queue->wTimerCount) queue->wakeBits &= ~QS_TIMER;
}
@@ -448,8 +580,8 @@
DWORD ret;
if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
- ret = MAKELONG( queue->tempStatus, queue->status );
- queue->tempStatus = 0;
+ ret = MAKELONG( queue->changeBits, queue->wakeBits );
+ queue->changeBits = 0;
return ret & MAKELONG( flags, flags );
}
@@ -462,7 +594,7 @@
MESSAGEQUEUE *queue;
if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return FALSE;
- return queue->status & (QS_KEY | QS_MOUSEBUTTON);
+ return queue->wakeBits & (QS_KEY | QS_MOUSEBUTTON);
}
diff --git a/windows/timer.c b/windows/timer.c
index 9f8cc4a..189fc36 100644
--- a/windows/timer.c
+++ b/windows/timer.c
@@ -65,69 +65,78 @@
*/
static void TIMER_RemoveTimer( TIMER * pTimer )
{
- if (pTimer == pNextTimer) pNextTimer = pTimer->next;
- else
- {
- TIMER * ptr = pNextTimer;
- while (ptr && (ptr->next != pTimer)) ptr = ptr->next;
- if (ptr) ptr->next = pTimer->next;
- }
+ TIMER **ppTimer = &pNextTimer;
+
+ while (*ppTimer && (*ppTimer != pTimer)) ppTimer = &(*ppTimer)->next;
+ if (*ppTimer) *ppTimer = pTimer->next;
pTimer->next = NULL;
}
+
+/***********************************************************************
+ * TIMER_ClearTimer
+ *
+ * Clear and remove a timer.
+ */
+static void TIMER_ClearTimer( TIMER * pTimer )
+{
+ TIMER_RemoveTimer( pTimer );
+ QUEUE_DecTimerCount( pTimer->hq );
+ pTimer->hwnd = 0;
+ pTimer->msg = 0;
+ pTimer->id = 0;
+ pTimer->timeout = 0;
+ pTimer->proc = 0;
+}
+
+
/***********************************************************************
* TIMER_SwitchQueue
*/
void TIMER_SwitchQueue(HQUEUE old, HQUEUE new)
{
- TIMER* pT = pNextTimer;
+ TIMER * pT = pNextTimer;
- while(pT)
- {
- if( pT->hq == old ) pT->hq = new;
- pT = pT->next;
- }
-
-}
-
-/***********************************************************************
- * TIMER_NukeTimers
- *
- * Trash all timers that are bound to the hwnd or hq
- */
-void TIMER_NukeTimers(HWND hwnd, HQUEUE hq)
-{
- HQUEUE hQToUpdate = ( hwnd ) ? GetTaskQueue( GetWindowTask( hwnd ) )
- : hq;
- TIMER* pT = pNextTimer;
- TIMER* pTnext;
-
- if( !pT ) return;
-
- while( (hwnd && pT->hwnd == hwnd) ||
- (hq && pT->hq == hq) )
- {
- QUEUE_DecTimerCount( hQToUpdate );
- if( !(pT = pNextTimer = pNextTimer->next) )
- return;
- }
-
- /* pT points to the "good" timer */
-
- while( (pTnext = pT->next) )
+ while (pT)
{
- while( (hwnd && pTnext->hwnd == hwnd) ||
- (hq && pTnext->hq == hq) )
- {
- QUEUE_DecTimerCount( hQToUpdate );
- if( !(pT->next = pTnext->next) )
- return;
- }
-
- pT = pT->next;
+ if (pT->hq == old) pT->hq = new;
+ pT = pT->next;
}
}
+
+/***********************************************************************
+ * TIMER_RemoveWindowTimers
+ *
+ * Remove all timers for a given window.
+ */
+void TIMER_RemoveWindowTimers( HWND hwnd )
+{
+ int i;
+ TIMER *pTimer;
+
+ for (i = NB_TIMERS, pTimer = TimersArray; i > 0; i--, pTimer++)
+ if ((pTimer->hwnd == hwnd) && pTimer->timeout)
+ TIMER_ClearTimer( pTimer );
+}
+
+
+/***********************************************************************
+ * TIMER_RemoveQueueTimers
+ *
+ * Remove all timers for a given queue.
+ */
+void TIMER_RemoveQueueTimers( HQUEUE hqueue )
+{
+ int i;
+ TIMER *pTimer;
+
+ for (i = NB_TIMERS, pTimer = TimersArray; i > 0; i--, pTimer++)
+ if ((pTimer->hq == hqueue) && pTimer->timeout)
+ TIMER_ClearTimer( pTimer );
+}
+
+
/***********************************************************************
* TIMER_RestartTimers
*
@@ -142,6 +151,17 @@
/***********************************************************************
+ * TIMER_GetNextExp
+ *
+ * Return next timer expiration time, or -1 if none.
+ */
+LONG TIMER_GetNextExp(void)
+{
+ return pNextTimer ? EXPIRE_TIME( pNextTimer, GetTickCount() ) : -1;
+}
+
+
+/***********************************************************************
* TIMER_CheckTimer
*
* Check whether a timer has expired, and create a message if necessary.
@@ -243,9 +263,8 @@
{
int i;
TIMER * pTimer;
- HQUEUE hq;
- /* Find the timer */
+ /* Find the timer */
for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
if ((pTimer->hwnd == hwnd) && (pTimer->id == id) &&
@@ -255,17 +274,9 @@
if (!sys && (pTimer->msg != WM_TIMER)) return FALSE;
else if (sys && (pTimer->msg != WM_SYSTIMER)) return FALSE;
- /* Delete the timer */
+ /* Delete the timer */
- hq = pTimer->hq;
-
- pTimer->hwnd = 0;
- pTimer->msg = 0;
- pTimer->id = 0;
- pTimer->timeout = 0;
- pTimer->proc = 0;
- TIMER_RemoveTimer( pTimer );
- QUEUE_DecTimerCount( hq );
+ TIMER_ClearTimer( pTimer );
return TRUE;
}
diff --git a/windows/win.c b/windows/win.c
index 51e419c..c89ef23 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -15,10 +15,10 @@
#include "dce.h"
#include "sysmetrics.h"
#include "cursoricon.h"
-#include "event.h"
#include "heap.h"
#include "hook.h"
#include "menu.h"
+#include "message.h"
#include "nonclient.h"
#include "string32.h"
#include "queue.h"
@@ -333,6 +333,7 @@
if (!wndPtr) return;
WIN_UnlinkWindow( hwnd ); /* Remove the window from the linked list */
+ TIMER_RemoveWindowTimers( hwnd );
wndPtr->dwMagic = 0; /* Mark it as invalid */
wndPtr->hwndSelf = 0;
if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
diff --git a/windows/winpos.c b/windows/winpos.c
index 841b63e..74a8942 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -10,7 +10,6 @@
#include "module.h"
#include "user.h"
#include "win.h"
-#include "event.h"
#include "hook.h"
#include "message.h"
#include "queue.h"
@@ -883,23 +882,17 @@
}
/* set prev active wnd to current active wnd and send notification */
- if( (hwndPrevActive = hwndActive) )
+ if ((hwndPrevActive = hwndActive) && IsWindow(hwndPrevActive))
{
-/* FIXME: need a Win32 translation for WINELIB32 */
- if( !SendMessage16(hwndPrevActive, WM_NCACTIVATE, 0, MAKELONG(hWnd,wIconized)) )
+ if (!SendMessage16( hwndPrevActive, WM_NCACTIVATE, FALSE, 0 ))
{
if (GetSysModalWindow() != hWnd) return 0;
/* disregard refusal if hWnd is sysmodal */
}
-#ifdef WINELIB32
- SendMessage32A( hwndActive, WM_ACTIVATE,
- MAKEWPARAM( WA_INACTIVE, wIconized ),
- (LPARAM)hWnd );
-#else
- SendMessage16(hwndPrevActive, WM_ACTIVATE, WA_INACTIVE,
- MAKELONG(hWnd,wIconized));
-#endif
+ SendMessage32A( hwndPrevActive, WM_ACTIVATE,
+ MAKEWPARAM( WA_INACTIVE, wIconized ),
+ (LPARAM)hWnd );
/* check if something happened during message processing */
if( hwndPrevActive != hwndActive ) return 0;
@@ -972,9 +965,7 @@
wndTemp->hwndLastActive = hWnd;
wIconized = HIWORD(wndTemp->dwStyle & WS_MINIMIZE);
-/* FIXME: Needs a Win32 translation for WINELIB32 */
- SendMessage16( hWnd, WM_NCACTIVATE, 1,
- MAKELONG(hwndPrevActive,wIconized));
+ SendMessage16( hWnd, WM_NCACTIVATE, TRUE, 0 );
#ifdef WINELIB32
SendMessage32A( hWnd, WM_ACTIVATE,
MAKEWPARAM( (fMouse)?WA_CLICKACTIVE:WA_ACTIVE, wIconized),
@@ -1704,7 +1695,7 @@
/* Repaint the window */
- if (wndPtr->window) MSG_Synchronize(); /* Wait for all expose events */
+ if (wndPtr->window) EVENT_Synchronize(); /* Wait for all expose events */
EVENT_DummyMotionNotify(); /* Simulate a mouse event to set the cursor */