Commit 8b915630 authored by Alexandre Julliard's avatar Alexandre Julliard

Release 960616

Sun Jun 16 16:51:31 1996 Alexandre Julliard <julliard@lrc.epfl.ch> * [memory/heap.c] Fixed bug in HeapRealloc (thanks to Bruce Milner). * [misc/wsprintf.c] Fixed argument size for %c format in wsprintf16(). * [objects/dc.c] Don't free hFirstBitmap for saved DCs. * [windows/event.c] Added timer handling in EVENT_WaitXEvent(). * [windows/message.c] In MSG_TranslateMouseMsg and MSG_TranslateKbdMsg, check if the event is for the current task; if not, wake the other task. * [windows/queue.c] [include/queue.h] Added 'self' handle in queue structure. * [windows/timer.c] Added TIMER_ExpireTimers() function to mark expired timers and wake up the corresponding tasks. Thu Jun 13 01:46:33 EDT 1996 William Magro <wmagro@tc.cornell.edu> * [windows/mapping.c] First point in list was mapped multiple times in DPtoLP and LPtoDP. Other points were not mapped. Wed Jun 12 18:08:45 1996 Alex Korobka <alex@phm30.pharm.sunysb.edu> * [misc/shell.c] Some fixes for ExtractIcon function family. * [documentation/user_module] Chapter about windowing and messaging subsystems.
parent d90840e1
This is release 960611 of Wine, the MS Windows emulator. This is still a
This is release 960616 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 correctly.
Patches should be submitted to "julliard@lrc.epfl.ch". Please don't
forget to include a ChangeLog entry.
WHAT'S NEW with Wine-960611: (see ChangeLog for details)
- (surprise) More Win32 code.
WHAT'S NEW with Wine-960616: (see ChangeLog for details)
- Inter-task messaging begins to work.
- Lots of bug fixes.
See the README file in the distribution for installation instructions.
......@@ -15,10 +15,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-960611.tar.gz
tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960611.tar.gz
ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960611.tar.gz
aris.com:/pub/linux/ALPHA/Wine/development/Wine-960611.tar.gz
sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960616.tar.gz
tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960616.tar.gz
ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960616.tar.gz
aris.com:/pub/linux/ALPHA/Wine/development/Wine-960616.tar.gz
It should also be available from any site that mirrors tsx-11 or sunsite.
......
----------------------------------------------------------------------
Sun Jun 16 16:51:31 1996 Alexandre Julliard <julliard@lrc.epfl.ch>
* [memory/heap.c]
Fixed bug in HeapRealloc (thanks to Bruce Milner).
* [misc/wsprintf.c]
Fixed argument size for %c format in wsprintf16().
* [objects/dc.c]
Don't free hFirstBitmap for saved DCs.
* [windows/event.c]
Added timer handling in EVENT_WaitXEvent().
* [windows/message.c]
In MSG_TranslateMouseMsg and MSG_TranslateKbdMsg, check if the
event is for the current task; if not, wake the other task.
* [windows/queue.c] [include/queue.h]
Added 'self' handle in queue structure.
* [windows/timer.c]
Added TIMER_ExpireTimers() function to mark expired timers and
wake up the corresponding tasks.
Thu Jun 13 01:46:33 EDT 1996 William Magro <wmagro@tc.cornell.edu>
* [windows/mapping.c]
First point in list was mapped multiple times in DPtoLP and
LPtoDP. Other points were not mapped.
Wed Jun 12 18:08:45 1996 Alex Korobka <alex@phm30.pharm.sunysb.edu>
* [misc/shell.c]
Some fixes for ExtractIcon function family.
* [documentation/user_module]
Chapter about windowing and messaging subsystems.
----------------------------------------------------------------------
Tue Jun 11 15:20:43 1996 Alexandre Julliard <julliard@lrc.epfl.ch>
* [debugger/break.c] [loader/signal.c]
......
......@@ -13,7 +13,6 @@
extern DWORD MSG_WineStartTicks; /* Ticks at Wine startup */
/* message.c */
extern BOOL MSG_GetHardwareMessage( LPMSG16 msg );
extern BOOL MSG_InternalGetMessage( SEGPTR msg, HWND hwnd, HWND hwndOwner,
short code, WORD flags, BOOL sendIdle );
......@@ -21,13 +20,16 @@ extern BOOL MSG_InternalGetMessage( SEGPTR msg, HWND hwnd, HWND hwndOwner,
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);
extern LONG TIMER_GetNextExpiration(void);
extern void TIMER_ExpireTimers(void);
extern BOOL TIMER_GetTimerMsg( MSG16 *msg, HWND hwnd,
HQUEUE hQueue, BOOL remove );
/* event.c */
extern BOOL EVENT_WaitXEvent( LONG maxWait );
extern BOOL EVENT_WaitXEvent( BOOL sleep );
extern void EVENT_Synchronize(void);
extern void EVENT_ProcessEvent( XEvent *event );
extern void EVENT_RegisterWindow( Window w, HWND hwnd );
extern void EVENT_RegisterWindow( WND *pWnd );
extern void EVENT_DummyMotionNotify(void);
#endif /* __WINE_MESSAGE_H */
......@@ -32,7 +32,7 @@ typedef struct tagMESSAGEQUEUE
WORD queueSize; /* 0c Size of the queue */
DWORD GetMessageTimeVal WINE_PACKED; /* 0e Value for GetMessageTime */
DWORD GetMessagePosVal WINE_PACKED; /* 12 Value for GetMessagePos */
WORD reserved1; /* 16 Unknown */
HQUEUE self; /* 16 Handle to self (was: reserved) */
DWORD GetMessageExtraInfoVal; /* 18 Value for GetMessageExtraInfo */
WORD reserved2; /* 1c Unknown */
LPARAM lParam WINE_PACKED; /* 1e Next 4 values set by SendMessage */
......@@ -75,6 +75,7 @@ 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_ClearWakeBit( MESSAGEQUEUE *queue, WORD bit );
extern void QUEUE_ReceiveMessage( MESSAGEQUEUE *queue );
extern void QUEUE_WaitBits( WORD bits );
extern void QUEUE_IncPaintCount( HQUEUE hQueue );
......
......@@ -469,6 +469,7 @@ DECL_WINELIB_TYPE(LPNCCALCSIZE_PARAMS);
/* CallMsgFilter() values */
#define MSGF_DIALOGBOX 0
#define MSGF_MESSAGEBOX 1
#define MSGF_MENU 2
#define MSGF_MOVE 3
#define MSGF_SIZE 4
......
......@@ -84,7 +84,7 @@ WNDPROC MODULE_GetWndProcEntry16( char *name )
MAP_STR_TO_PROC("ColorDlgProc",ColorDlgProc);
MAP_STR_TO_PROC("ComboBoxWndProc",ComboBoxWndProc);
MAP_STR_TO_PROC("ComboLBoxWndProc",ComboLBoxWndProc);
MAP_STR_TO_PROC("DefDlgProc",DefDlgProc);
MAP_STR_TO_PROC("DefDlgProc",DefDlgProc16);
MAP_STR_TO_PROC("EditWndProc",EditWndProc);
MAP_STR_TO_PROC("FileOpenDlgProc",FileOpenDlgProc);
MAP_STR_TO_PROC("FileSaveDlgProc",FileSaveDlgProc);
......
......@@ -677,7 +677,7 @@ void TASK_Reschedule(void)
/* Flush any X events that happened in the meantime */
EVENT_WaitXEvent( 0 );
EVENT_WaitXEvent( FALSE );
/* Find a task to yield to */
......@@ -707,7 +707,7 @@ void TASK_Reschedule(void)
/* No task found, wait for some events to come in */
EVENT_WaitXEvent( TIMER_GetNextExp() );
EVENT_WaitXEvent( TRUE );
}
if (hTask == hCurrentTask) return; /* Nothing to do */
......
......@@ -1005,6 +1005,7 @@ LPVOID HeapReAlloc( HANDLE32 heap, DWORD flags, LPVOID ptr, DWORD size )
SetLastError( ERROR_OUTOFMEMORY );
return NULL;
}
HEAP_ShrinkBlock( subheap, pArena, size );
}
else /* Do it the hard way */
{
......@@ -1029,6 +1030,7 @@ LPVOID HeapReAlloc( HANDLE32 heap, DWORD flags, LPVOID ptr, DWORD size )
+ sizeof(ARENA_FREE) - sizeof(ARENA_INUSE);
pInUse->threadId = GetCurrentTask();
pInUse->magic = ARENA_INUSE_MAGIC;
HEAP_ShrinkBlock( subheap, pInUse, size );
memcpy( pInUse + 1, pArena + 1, oldSize );
/* Free the previous block */
......@@ -1038,11 +1040,7 @@ LPVOID HeapReAlloc( HANDLE32 heap, DWORD flags, LPVOID ptr, DWORD size )
pArena = pInUse;
}
}
/* Shrink the block */
HEAP_ShrinkBlock( subheap, pArena, size );
else HEAP_ShrinkBlock( subheap, pArena, size ); /* Shrink the block */
/* Clear the extra bytes if needed */
......
......@@ -129,7 +129,7 @@ BOOL CLIPBOARD_RequestXSelection()
WIN_GetXWindow(hWnd),CurrentTime);
/* TODO: need time-out for broken clients */
while(wait_for_selection) EVENT_WaitXEvent(-1);
while(wait_for_selection) EVENT_WaitXEvent( TRUE );
return (BOOL)ClipFormats[0].wDataPresent;
}
......
......@@ -501,7 +501,7 @@ HICON InternalExtractIcon(HINSTANCE hInstance, LPCSTR lpszExeFileName, UINT nIco
for( i = nIconIndex; i < nIconIndex + n; i++ )
{
hIcon = SHELL_LoadResource( hInstance, hFile, pIconDir + (i - nIconIndex),
hIcon = SHELL_LoadResource( hInstance, hFile, pIconDir + i,
*(WORD*)pData );
RetPtr[i-nIconIndex] = GetIconID( hIcon, 3 );
GlobalFree16(hIcon);
......@@ -547,18 +547,40 @@ HICON ExtractIcon(HINSTANCE hInstance, LPCSTR lpszExeFileName, WORD nIconIndex)
/*************************************************************************
* ExtractAssociatedIcon [SHELL.36]
*
* Return icon for given file (either from file itself or from associated
* executable) and patch parameters if needed.
*/
HICON ExtractAssociatedIcon(HINSTANCE hInst,LPSTR lpIconPath, LPWORD lpiIcon)
{
HICON hIcon = ExtractIcon(hInst, lpIconPath, *lpiIcon);
/* MAKEINTRESOURCE(2) seems to be "default" icon according to Progman
*
* For data files it probably should call FindExecutable and load
* icon from there. As of now FindExecutable is empty stub.
*/
if( hIcon < 2 )
{
if( hIcon == 1 ) /* no icons found in given file */
{
char tempPath[0x80];
UINT uRet = FindExecutable(lpIconPath,NULL,tempPath);
if( uRet > 32 && tempPath[0] )
{
strcpy(lpIconPath,tempPath);
hIcon = ExtractIcon(hInst, lpIconPath, *lpiIcon);
if( hIcon > 2 ) return hIcon;
}
else hIcon = 0;
}
if( hIcon < 2 ) hIcon = LoadIcon( hInst, MAKEINTRESOURCE(2));
if( hIcon == 1 )
*lpiIcon = 2; /* MSDOS icon - we found .exe but no icons in it */
else
*lpiIcon = 6; /* generic icon - found nothing */
GetModuleFileName(hInst, lpIconPath, 0x80);
hIcon = LoadIcon( hInst, MAKEINTRESOURCE(*lpiIcon));
}
return hIcon;
}
......
......@@ -248,7 +248,7 @@ INT16 wvsnprintf16( LPSTR buffer, UINT16 maxlen, LPCSTR spec, LPCVOID args )
{
case WPR_CHAR:
cur_arg = (DWORD)*(CHAR *)args;
args = (CHAR *)args + 1;
args = (WORD *)args + 1;
break;
case WPR_STRING:
cur_arg = (DWORD)PTR_SEG_TO_LIN( *(SEGPTR *)args );
......
......@@ -621,9 +621,9 @@ BOOL DeleteDC( HDC hdc )
SelectObject( hdc, STOCK_WHITE_BRUSH );
SelectObject( hdc, STOCK_SYSTEM_FONT );
XFreeGC( display, dc->u.x.gc );
if (dc->w.flags & DC_MEMORY) DeleteObject( dc->w.hFirstBitmap );
}
if (dc->w.flags & DC_MEMORY) DeleteObject( dc->w.hFirstBitmap );
if (dc->w.hClipRgn) DeleteObject( dc->w.hClipRgn );
if (dc->w.hVisRgn) DeleteObject( dc->w.hVisRgn );
if (dc->w.hGCClipRgn) DeleteObject( dc->w.hGCClipRgn );
......
......@@ -200,7 +200,7 @@ static BOOL CLASS_FreeClass( CLASS *classPtr )
if (classPtr->hbrBackground) DeleteObject( classPtr->hbrBackground );
GlobalDeleteAtom( classPtr->atomName );
CLASS_SetMenuNameA( classPtr, NULL );
CLASS_SetWndProc( classPtr, (WNDPROC16)0, WIN_PROC_16 );
CLASS_SetWndProc( classPtr, (HANDLE32)0, WIN_PROC_16 );
HeapFree( SystemHeap, 0, classPtr );
return TRUE;
}
......
......@@ -159,7 +159,6 @@ BOOL DCE_InvalidateDCE(WND* wndScope, RECT16* pRectUpdate)
dprintf_dc(stddeb,"\tgot hwnd %04x\n", wndCurrent->hwndSelf);
if( wndCurrent->parent != wndScope )
MapWindowPoints16(wndCurrent->parent->hwndSelf, wndScope->hwndSelf,
(LPPOINT16)&wndRect, 2);
if( IntersectRect16(&wndRect,&wndRect,pRectUpdate) )
......
......@@ -48,6 +48,7 @@ BOOL16 DPtoLP16( HDC16 hdc, LPPOINT16 points, INT16 count )
{
points->x = XDPTOLP( dc, points->x );
points->y = YDPTOLP( dc, points->y );
points++;
}
return TRUE;
}
......@@ -65,6 +66,7 @@ BOOL32 DPtoLP32( HDC32 hdc, LPPOINT32 points, INT32 count )
{
points->x = XDPTOLP( dc, points->x );
points->y = YDPTOLP( dc, points->y );
points++;
}
return TRUE;
}
......@@ -82,6 +84,7 @@ BOOL16 LPtoDP16( HDC16 hdc, LPPOINT16 points, INT16 count )
{
points->x = XLPTODP( dc, points->x );
points->y = YLPTODP( dc, points->y );
points++;
}
return TRUE;
}
......@@ -99,6 +102,7 @@ BOOL32 LPtoDP32( HDC32 hdc, LPPOINT32 points, INT32 count )
{
points->x = XLPTODP( dc, points->x );
points->y = YLPTODP( dc, points->y );
points++;
}
return TRUE;
}
......
......@@ -29,9 +29,6 @@
extern BYTE* KeyStateTable; /* event.c */
extern WPARAM lastEventChar; /* event.c */
extern BOOL TIMER_CheckTimer( LONG *next, MSG16 *msg,
HWND hwnd, BOOL remove ); /* timer.c */
DWORD MSG_WineStartTicks; /* Ticks at Wine startup */
static WORD doubleClickSpeed = 452;
......@@ -68,9 +65,8 @@ static BOOL MSG_TranslateMouseMsg( MSG16 *msg, BOOL remove )
/* Find the window */
if (GetCapture())
if ((msg->hwnd = GetCapture()) != 0)
{
msg->hwnd = GetCapture();
ScreenToClient16( msg->hwnd, &pt );
msg->lParam = MAKELONG( pt.x, pt.y );
/* No need to further process the message */
......@@ -80,6 +76,16 @@ static BOOL MSG_TranslateMouseMsg( MSG16 *msg, BOOL remove )
}
hittest = WINPOS_WindowFromPoint( msg->pt, &pWnd );
if (pWnd->hmemTaskQ != GetTaskQueue(0))
{
/* Not for the current task */
MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) );
if (queue) QUEUE_ClearWakeBit( queue, QS_MOUSE );
/* Wake up the other task */
queue = (MESSAGEQUEUE *)GlobalLock16( pWnd->hmemTaskQ );
if (queue) QUEUE_SetWakeBit( queue, QS_MOUSE );
return FALSE;
}
msg->hwnd = pWnd->hwndSelf;
if ((hittest != HTERROR) && mouseClick)
{
......@@ -172,6 +178,8 @@ static BOOL MSG_TranslateMouseMsg( MSG16 *msg, BOOL remove )
*/
static BOOL MSG_TranslateKeyboardMsg( MSG16 *msg, BOOL remove )
{
WND *pWnd;
/* Should check Ctrl-Esc and PrintScreen here */
msg->hwnd = GetFocus();
......@@ -185,6 +193,17 @@ static BOOL MSG_TranslateKeyboardMsg( MSG16 *msg, BOOL remove )
if( msg->message < WM_SYSKEYDOWN )
msg->message += WM_SYSKEYDOWN - WM_KEYDOWN;
}
pWnd = WIN_FindWndPtr( msg->hwnd );
if (pWnd && (pWnd->hmemTaskQ != GetTaskQueue(0)))
{
/* Not for the current task */
MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) );
if (queue) QUEUE_ClearWakeBit( queue, QS_KEY );
/* Wake up the other task */
queue = (MESSAGEQUEUE *)GlobalLock16( pWnd->hmemTaskQ );
if (queue) QUEUE_SetWakeBit( queue, QS_KEY );
return FALSE;
}
return !HOOK_CallHooks( WH_KEYBOARD, remove ? HC_ACTION : HC_NOREMOVE,
msg->wParam, msg->lParam );
}
......@@ -202,7 +221,7 @@ static BOOL MSG_PeekHardwareMsg( MSG16 *msg, HWND hwnd, WORD first, WORD last,
int i, pos = sysMsgQueue->nextMessage;
/* If the queue is empty, attempt to fill it */
if (!sysMsgQueue->msgCount && XPending(display)) EVENT_WaitXEvent( 0 );
if (!sysMsgQueue->msgCount && XPending(display)) EVENT_WaitXEvent( FALSE );
for (i = 0; i < sysMsgQueue->msgCount; i++, pos++)
{
......@@ -267,38 +286,6 @@ WORD GetDoubleClickTime()
/***********************************************************************
* MSG_GetHardwareMessage
*
* Like GetMessage(), but only return mouse and keyboard events.
* Used internally for window moving and resizing. Mouse messages
* are not translated.
* Warning: msg->hwnd is always 0.
*/
BOOL MSG_GetHardwareMessage( LPMSG16 msg )
{
#if 0
int pos;
XEvent event;
MESSAGEQUEUE *sysMsgQueue = QUEUE_GetSysQueue();
while(1)
{
if ((pos = QUEUE_FindMsg( sysMsgQueue, 0, 0, 0 )) != -1)
{
*msg = sysMsgQueue->messages[pos].msg;
QUEUE_RemoveMsg( sysMsgQueue, pos );
break;
}
XNextEvent( display, &event );
EVENT_ProcessEvent( &event );
}
#endif
MSG_PeekMessage( msg, 0, WM_KEYFIRST, WM_MOUSELAST, PM_REMOVE, 0 );
return TRUE;
}
/***********************************************************************
* MSG_SendMessage
*
* Implementation of an inter-task SendMessage.
......@@ -381,7 +368,6 @@ static BOOL MSG_PeekMessage( LPMSG16 msg, HWND hwnd, WORD first, WORD last,
int pos, mask;
MESSAGEQUEUE *msgQueue;
HQUEUE hQueue;
LONG nextExp; /* Next timer expiration time */
#ifdef CONFIG_IPC
DDE_TestDDE(hwnd); /* do we have dde handling in the window ?*/
......@@ -490,10 +476,8 @@ static BOOL MSG_PeekMessage( LPMSG16 msg, HWND hwnd, WORD first, WORD last,
}
if ((msgQueue->wakeBits & mask) & QS_TIMER)
{
if (TIMER_CheckTimer( &nextExp, msg, hwnd, flags & PM_REMOVE ))
break; /* Got a timer msg */
if (TIMER_GetTimerMsg(msg, hwnd, hQueue, flags & PM_REMOVE)) break;
}
else nextExp = -1; /* No timeout needed */
if (peek)
{
......@@ -792,24 +776,7 @@ LRESULT SendMessage32W(HWND32 hwnd, UINT32 msg, WPARAM32 wParam, LPARAM lParam)
*/
void WaitMessage( void )
{
MSG16 msg;
MESSAGEQUEUE *queue;
LONG nextExp = -1; /* Next timer expiration time */
#ifdef CONFIG_IPC
DDE_GetRemoteMessage();
#endif /* CONFIG_IPC */
if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return;
if ((queue->wPostQMsg) ||
(queue->wakeBits & (QS_SENDMESSAGE | QS_PAINT)) ||
(queue->msgCount) || (QUEUE_GetSysQueue()->msgCount) )
return;
if ((queue->wakeBits & QS_TIMER) &&
TIMER_CheckTimer( &nextExp, &msg, 0, FALSE))
return;
/* FIXME: (dde) must check DDE & X-events simultaneously */
EVENT_WaitXEvent( nextExp );
QUEUE_WaitBits( QS_ALLINPUT );
}
......
......@@ -16,6 +16,7 @@
#include "menu.h"
#include "winpos.h"
#include "scroll.h"
#include "stackframe.h"
#include "nonclient.h"
#include "graphics.h"
#include "queue.h"
......@@ -907,7 +908,8 @@ static LONG NC_StartSizeMove( HWND hwnd, WPARAM wParam, POINT16 *capturePoint )
SetCapture(hwnd);
while(!hittest)
{
MSG_GetHardwareMessage( &msg );
MSG_InternalGetMessage( MAKE_SEGPTR(&msg), 0, 0, MSGF_SIZE,
PM_REMOVE, FALSE );
switch(msg.message)
{
case WM_MOUSEMOVE:
......@@ -1046,7 +1048,8 @@ static void NC_DoSizeMove( HWND hwnd, WORD wParam, POINT16 pt )
{
int dx = 0, dy = 0;
MSG_GetHardwareMessage( &msg );
MSG_InternalGetMessage( MAKE_SEGPTR(&msg), 0, 0, MSGF_SIZE,
PM_REMOVE, FALSE );
/* Exit on button-up, Return, or Esc */
if ((msg.message == WM_LBUTTONUP) ||
......@@ -1148,7 +1151,7 @@ static void NC_TrackMinMaxBox( HWND hwnd, WORD wParam )
do
{
BOOL oldstate = pressed;
MSG_GetHardwareMessage( &msg );
MSG_InternalGetMessage( MAKE_SEGPTR(&msg), 0, 0, 0, PM_REMOVE, FALSE );
pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
if (pressed != oldstate)
......
......@@ -16,6 +16,8 @@
static HQUEUE hFirstQueue = 0;
static HQUEUE hmemSysMsgQueue = 0;
static MESSAGEQUEUE *pMouseQueue = NULL; /* Queue for last mouse message */
static MESSAGEQUEUE *pKbdQueue = NULL; /* Queue for last kbd message */
static HQUEUE hDoomedQueue = 0;
static MESSAGEQUEUE *sysMsgQueue = NULL;
......@@ -111,6 +113,7 @@ static HQUEUE QUEUE_CreateMsgQueue( int size )
if (!(hQueue = GlobalAlloc16( GMEM_FIXED | GMEM_ZEROINIT, queueSize )))
return 0;
msgQueue = (MESSAGEQUEUE *) GlobalLock16( hQueue );
msgQueue->self = hQueue;
msgQueue->msgSize = sizeof(QMSG);
msgQueue->queueSize = size;
msgQueue->wWinVersion = pTask ? pTask->version : 0;
......@@ -144,6 +147,7 @@ BOOL QUEUE_DeleteMsgQueue( HQUEUE hQueue )
pPrev = &msgQ->next;
}
if (*pPrev) *pPrev = msgQueue->next;
msgQueue->self = 0;
GlobalFree16( hQueue );
return 1;
}
......@@ -181,6 +185,8 @@ MESSAGEQUEUE *QUEUE_GetSysQueue(void)
*/
void QUEUE_SetWakeBit( MESSAGEQUEUE *queue, WORD bit )
{
if (bit & QS_MOUSE) pMouseQueue = queue;
if (bit & QS_KEY) pKbdQueue = queue;
queue->changeBits |= bit;
queue->wakeBits |= bit;
if (queue->wakeMask & bit)
......@@ -192,6 +198,16 @@ void QUEUE_SetWakeBit( MESSAGEQUEUE *queue, WORD bit )
/***********************************************************************
* QUEUE_ClearWakeBit
*/
void QUEUE_ClearWakeBit( MESSAGEQUEUE *queue, WORD bit )
{
queue->changeBits &= ~bit;
queue->wakeBits &= ~bit;
}
/***********************************************************************
* QUEUE_WaitBits
*
* See "Windows Internals", p.447
......@@ -233,16 +249,22 @@ void QUEUE_ReceiveMessage( MESSAGEQUEUE *queue )
WPARAM wParam;
LPARAM lParam;
LRESULT result = 0;
HQUEUE oldSender;
printf( "ReceiveMessage\n" );
if (!(queue->wakeBits & QS_SENDMESSAGE)) return;
if (!(senderQ = (MESSAGEQUEUE*)GlobalLock16( queue->hSendingTask))) return;
/* Remove sending queue from the list */
oldSender = queue->InSendMessageHandle;
queue->InSendMessageHandle = queue->hSendingTask;
queue->hSendingTask = senderQ->hPrevSendingTask;
senderQ->hPrevSendingTask = 0;
if (!queue->hSendingTask) queue->wakeBits &= ~QS_SENDMESSAGE;
if (!queue->hSendingTask)
{
queue->wakeBits &= ~QS_SENDMESSAGE;
queue->changeBits &= ~QS_SENDMESSAGE;
}
/* Get the parameters from the sending task */
hwnd = senderQ->hWnd;
......@@ -257,13 +279,21 @@ void QUEUE_ReceiveMessage( MESSAGEQUEUE *queue )
/* Call the window procedure */
/* FIXME: should we use CallWindowProc here? */
if (IsWindow( hwnd )) result = SendMessage16( hwnd, msg, wParam, lParam );
if (IsWindow( hwnd ))
{
DWORD extraInfo = queue->GetMessageExtraInfoVal;
queue->GetMessageExtraInfoVal = senderQ->GetMessageExtraInfoVal;
result = SendMessage16( hwnd, msg, wParam, lParam );
queue->GetMessageExtraInfoVal = extraInfo; /* Restore extra info */
}
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->InSendMessageHandle = oldSender;
}
......@@ -373,15 +403,18 @@ static void QUEUE_WakeSomeone( UINT message )
if (!(hwnd = GetSysModalWindow()))
{
hwnd = (wakeBit == QS_KEY) ? GetFocus() : GetCapture();
if (!hwnd) hwnd = GetActiveWindow();
if (wakeBit == QS_KEY)
{
if (!(hwnd = GetFocus())) hwnd = GetActiveWindow();
}
else hwnd = GetCapture();
}
if (hwnd)
{
WND *wndPtr = WIN_FindWndPtr( hwnd );
if (wndPtr) queue = (MESSAGEQUEUE *)GlobalLock16( wndPtr->hmemTaskQ );
}
else
else if (!(queue = pMouseQueue))
{
hQueue = hFirstQueue;
while (hQueue)
......
......@@ -19,7 +19,7 @@ typedef struct tagTIMER
WORD id;
WORD timeout;
struct tagTIMER *next;
DWORD expires;
DWORD expires; /* Next expiration, or 0 if already expired */
FARPROC proc;
} TIMER;
......@@ -70,6 +70,7 @@ static void TIMER_RemoveTimer( TIMER * pTimer )
while (*ppTimer && (*ppTimer != pTimer)) ppTimer = &(*ppTimer)->next;
if (*ppTimer) *ppTimer = pTimer->next;
pTimer->next = NULL;
if (!pTimer->expires) QUEUE_DecTimerCount( pTimer->hq );
}
......@@ -81,7 +82,6 @@ static void TIMER_RemoveTimer( TIMER * pTimer )
static void TIMER_ClearTimer( TIMER * pTimer )
{
TIMER_RemoveTimer( pTimer );
QUEUE_DecTimerCount( pTimer->hq );
pTimer->hwnd = 0;
pTimer->msg = 0;
pTimer->id = 0;
......@@ -151,44 +151,58 @@ static void TIMER_RestartTimer( TIMER * pTimer, DWORD curTime )
/***********************************************************************
* TIMER_GetNextExp
* TIMER_GetNextExpiration
*
* Return next timer expiration time, or -1 if none.
*/
LONG TIMER_GetNextExp(void)
LONG TIMER_GetNextExpiration(void)
{
return pNextTimer ? EXPIRE_TIME( pNextTimer, GetTickCount() ) : -1;
}
/***********************************************************************
* TIMER_CheckTimer
* TIMER_ExpireTimers
*
* Check whether a timer has expired, and create a message if necessary.
* Otherwise, return time until next timer expiration in 'next'.
* If 'hwnd' is not NULL, only consider timers for this window.
* If 'remove' is TRUE, remove all expired timers up to the returned one.
* Mark expired timers and wake the appropriate queues.
*/
BOOL TIMER_CheckTimer( LONG *next, MSG16 *msg, HWND hwnd, BOOL remove )
void TIMER_ExpireTimers(void)
{
TIMER * pTimer = pNextTimer;
TIMER *pTimer = pNextTimer;
DWORD curTime = GetTickCount();
while (pTimer && !pTimer->expires) /* Skip already expired timers */
pTimer = pTimer->next;
while (pTimer && (pTimer->expires <= curTime))
{
pTimer->expires = 0;
QUEUE_IncTimerCount( pTimer->hq );
pTimer = pTimer->next;
}
}
/***********************************************************************
* TIMER_GetTimerMsg
*
* Build a message for an expired timer.
*/
BOOL TIMER_GetTimerMsg( MSG16 *msg, HWND hwnd, HQUEUE hQueue, BOOL remove )
{
TIMER *pTimer = pNextTimer;
DWORD curTime = GetTickCount();
if (hwnd) /* Find first timer for this window */
while (pTimer && (pTimer->hwnd != hwnd)) pTimer = pTimer->next;
else /* Find first timer for this queue */
while (pTimer && (pTimer->hq != hQueue)) pTimer = pTimer->next;
if (!pTimer) *next = -1;
else *next = EXPIRE_TIME( pTimer, curTime );
if (*next != 0) return FALSE; /* No timer expired */
if (!pTimer || (pTimer->expires > curTime)) return FALSE; /* No timer */
if (remove) TIMER_RestartTimer( pTimer, curTime ); /* Restart it */
if (remove) /* Restart all timers before pTimer, and then pTimer itself */
{
while (pNextTimer != pTimer) TIMER_RestartTimer( pNextTimer, curTime );
TIMER_RestartTimer( pTimer, curTime );
}
dprintf_timer( stddeb, "Timer expired: %04x, %04x, %04x, %08lx\n",
pTimer->hwnd, pTimer->msg, pTimer->id, (DWORD)pTimer->proc);
dprintf_timer(stddeb, "Timer expired: %p, %04x, %04x, %04x, %08lx\n",
pTimer, pTimer->hwnd, pTimer->msg, pTimer->id, (DWORD)pTimer->proc);
/* Build the message */
msg->hwnd = pTimer->hwnd;
msg->message = pTimer->msg;
......@@ -218,10 +232,10 @@ static WORD TIMER_SetTimer( HWND hwnd, WORD id, WORD timeout,
(pTimer->timeout != 0))
{
/* Got one: set new values and return */
TIMER_RemoveTimer( pTimer );
pTimer->timeout = timeout;
pTimer->expires = GetTickCount() + timeout;
pTimer->proc = proc;
TIMER_RemoveTimer( pTimer );
pTimer->expires = GetTickCount() + timeout;
TIMER_InsertTimer( pTimer );
return id;
}
......@@ -248,7 +262,6 @@ static WORD TIMER_SetTimer( HWND hwnd, WORD id, WORD timeout,
dprintf_timer(stddeb, "Timer added: %p, %04x, %04x, %04x, %08lx\n",
pTimer, pTimer->hwnd, pTimer->msg, pTimer->id, (DWORD)pTimer->proc);
TIMER_InsertTimer( pTimer );
QUEUE_IncTimerCount( pTimer->hq );
if (!id)
return TRUE;
else
......
......@@ -347,7 +347,7 @@ static void WIN_DestroyWindow( HWND hwnd )
if (wndPtr->hSysMenu) DestroyMenu( wndPtr->hSysMenu );
if (wndPtr->window) XDestroyWindow( display, wndPtr->window );
if (wndPtr->class->style & CS_OWNDC) DCE_FreeDCE( wndPtr->hdce );
WIN_SetWndProc( wndPtr, (WNDPROC16)0, WIN_PROC_16 );
WIN_SetWndProc( wndPtr, (HANDLE32)0, WIN_PROC_16 );
wndPtr->class->cWindows--;
USER_HEAP_FREE( hwnd );
}
......@@ -426,7 +426,7 @@ BOOL WIN_CreateDesktopWindow(void)
pWndDesktop->hProp = 0;
pWndDesktop->userdata = 0;
EVENT_RegisterWindow( pWndDesktop->window, hwndDesktop );
EVENT_RegisterWindow( pWndDesktop );
SendMessage32A( hwndDesktop, WM_NCCREATE, 0, 0 );
if ((hdc = GetDC( hwndDesktop )) != 0)
{
......@@ -628,7 +628,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
Window win = WIN_GetXWindow( cs->hwndParent );
if (win) XSetTransientForHint( display, wndPtr->window, win );
}
EVENT_RegisterWindow( wndPtr->window, hwnd );
EVENT_RegisterWindow( wndPtr );
}
/* Set the window menu */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment