Rewrote most of SendMessage/PeekMessage.
Implemented inter-process messaging. Moved most message routines to dlls/user, and split off 16-bit routines to a separate file.
This commit is contained in:
parent
252b0fe099
commit
d253c58b1b
|
@ -18,8 +18,10 @@ C_SRCS = \
|
|||
display.c \
|
||||
exticon.c \
|
||||
lstr.c \
|
||||
message.c \
|
||||
misc.c \
|
||||
mouse.c \
|
||||
msg16.c \
|
||||
network.c \
|
||||
resource.c \
|
||||
text.c \
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,383 @@
|
|||
/*
|
||||
* 16-bit messaging support
|
||||
*
|
||||
* Copyright 2001 Alexandre Julliard
|
||||
*/
|
||||
|
||||
#include "wine/winuser16.h"
|
||||
#include "heap.h"
|
||||
#include "hook.h"
|
||||
#include "message.h"
|
||||
#include "spy.h"
|
||||
#include "task.h"
|
||||
#include "thread.h"
|
||||
#include "win.h"
|
||||
#include "debugtools.h"
|
||||
|
||||
DEFAULT_DEBUG_CHANNEL(msg);
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SendMessage (USER.111)
|
||||
*/
|
||||
LRESULT WINAPI SendMessage16( HWND16 hwnd, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
|
||||
{
|
||||
LRESULT result;
|
||||
|
||||
if (hwnd != HWND_BROADCAST &&
|
||||
GetWindowThreadProcessId( hwnd, NULL ) == GetCurrentThreadId())
|
||||
{
|
||||
/* call 16-bit window proc directly */
|
||||
WND *wndPtr;
|
||||
WNDPROC16 winproc;
|
||||
|
||||
/* first the WH_CALLWNDPROC hook */
|
||||
if (HOOK_IsHooked( WH_CALLWNDPROC ))
|
||||
{
|
||||
CWPSTRUCT16 *cwp;
|
||||
|
||||
if ((cwp = SEGPTR_NEW(CWPSTRUCT16)))
|
||||
{
|
||||
cwp->hwnd = hwnd;
|
||||
cwp->message = msg;
|
||||
cwp->wParam = wparam;
|
||||
cwp->lParam = lparam;
|
||||
HOOK_CallHooks16( WH_CALLWNDPROC, HC_ACTION, 1, SEGPTR_GET(cwp) );
|
||||
hwnd = cwp->hwnd;
|
||||
msg = cwp->message;
|
||||
wparam = cwp->wParam;
|
||||
lparam = cwp->lParam;
|
||||
SEGPTR_FREE( cwp );
|
||||
}
|
||||
}
|
||||
|
||||
if (!(wndPtr = WIN_FindWndPtr( hwnd )))
|
||||
{
|
||||
WARN("invalid hwnd %04x\n", hwnd );
|
||||
return 0;
|
||||
}
|
||||
winproc = (WNDPROC16)wndPtr->winproc;
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
|
||||
SPY_EnterMessage( SPY_SENDMESSAGE16, hwnd, msg, wparam, lparam );
|
||||
result = CallWindowProc16( (WNDPROC16)winproc, hwnd, msg, wparam, lparam );
|
||||
SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg, result, wparam, lparam );
|
||||
}
|
||||
else /* map to 32-bit unicode for inter-thread/process message */
|
||||
{
|
||||
UINT msg32;
|
||||
WPARAM wparam32;
|
||||
|
||||
if (WINPROC_MapMsg16To32W( hwnd, msg, wparam, &msg32, &wparam32, &lparam ) == -1)
|
||||
return 0;
|
||||
result = WINPROC_UnmapMsg16To32W( hwnd, msg32, wparam32, lparam,
|
||||
SendMessageW( hwnd, msg32, wparam32, lparam ) );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* PostMessage (USER.110)
|
||||
*/
|
||||
BOOL16 WINAPI PostMessage16( HWND16 hwnd, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
|
||||
{
|
||||
WPARAM wparam32;
|
||||
UINT msg32;
|
||||
|
||||
switch (WINPROC_MapMsg16To32W( hwnd, msg, wparam, &msg32, &wparam32, &lparam ))
|
||||
{
|
||||
case 0:
|
||||
return PostMessageW( hwnd, msg32, wparam32, lparam );
|
||||
case 1:
|
||||
ERR( "16-bit message %x contains pointer, cannot post\n", msg );
|
||||
return FALSE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* PostAppMessage (USER.116)
|
||||
* PostAppMessage16 (USER32.@)
|
||||
*/
|
||||
BOOL16 WINAPI PostAppMessage16( HTASK16 hTask, UINT16 msg, WPARAM16 wparam, LPARAM lparam )
|
||||
{
|
||||
WPARAM wparam32;
|
||||
UINT msg32;
|
||||
TDB *pTask = TASK_GetPtr( hTask );
|
||||
if (!pTask) return FALSE;
|
||||
|
||||
switch (WINPROC_MapMsg16To32W( 0, msg, wparam, &msg32, &wparam32, &lparam ))
|
||||
{
|
||||
case 0:
|
||||
return PostThreadMessageW( (DWORD)pTask->teb->tid, msg32, wparam32, lparam );
|
||||
case 1:
|
||||
ERR( "16-bit message %x contains pointer, cannot post\n", msg );
|
||||
return FALSE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* InSendMessage (USER.192)
|
||||
*/
|
||||
BOOL16 WINAPI InSendMessage16(void)
|
||||
{
|
||||
return InSendMessage();
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* ReplyMessage (USER.115)
|
||||
*/
|
||||
void WINAPI ReplyMessage16( LRESULT result )
|
||||
{
|
||||
ReplyMessage( result );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* PeekMessage32 (USER.819)
|
||||
*/
|
||||
BOOL16 WINAPI PeekMessage32_16( MSG32_16 *msg16, HWND16 hwnd,
|
||||
UINT16 first, UINT16 last, UINT16 flags,
|
||||
BOOL16 wHaveParamHigh )
|
||||
{
|
||||
MSG msg;
|
||||
|
||||
if (!PeekMessageW( &msg, hwnd, first, last, flags )) return FALSE;
|
||||
|
||||
msg16->msg.hwnd = msg.hwnd;
|
||||
msg16->msg.lParam = msg.lParam;
|
||||
msg16->msg.time = msg.time;
|
||||
msg16->msg.pt.x = (INT16)msg.pt.x;
|
||||
msg16->msg.pt.y = (INT16)msg.pt.y;
|
||||
if (wHaveParamHigh) msg16->wParamHigh = HIWORD(msg.wParam);
|
||||
|
||||
return (WINPROC_MapMsg32WTo16( msg.hwnd, msg.message, msg.wParam,
|
||||
&msg16->msg.message, &msg16->msg.wParam,
|
||||
&msg16->msg.lParam ) != -1);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* PeekMessage (USER.109)
|
||||
*/
|
||||
BOOL16 WINAPI PeekMessage16( MSG16 *msg, HWND16 hwnd,
|
||||
UINT16 first, UINT16 last, UINT16 flags )
|
||||
{
|
||||
return PeekMessage32_16( (MSG32_16 *)msg, hwnd, first, last, flags, FALSE );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetMessage32 (USER.820)
|
||||
*/
|
||||
BOOL16 WINAPI GetMessage32_16( MSG32_16 *msg16, HWND16 hwnd, UINT16 first,
|
||||
UINT16 last, BOOL16 wHaveParamHigh )
|
||||
{
|
||||
MSG msg;
|
||||
|
||||
do
|
||||
{
|
||||
GetMessageW( &msg, hwnd, first, last );
|
||||
msg16->msg.hwnd = msg.hwnd;
|
||||
msg16->msg.lParam = msg.lParam;
|
||||
msg16->msg.time = msg.time;
|
||||
msg16->msg.pt.x = (INT16)msg.pt.x;
|
||||
msg16->msg.pt.y = (INT16)msg.pt.y;
|
||||
if (wHaveParamHigh) msg16->wParamHigh = HIWORD(msg.wParam);
|
||||
}
|
||||
while (WINPROC_MapMsg32WTo16( msg.hwnd, msg.message, msg.wParam,
|
||||
&msg16->msg.message, &msg16->msg.wParam,
|
||||
&msg16->msg.lParam ) == -1);
|
||||
|
||||
TRACE( "message %04x, hwnd %04x, filter(%04x - %04x)\n",
|
||||
msg16->msg.message, hwnd, first, last );
|
||||
|
||||
return msg16->msg.message != WM_QUIT;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetMessage (USER.108)
|
||||
*/
|
||||
BOOL16 WINAPI GetMessage16( MSG16 *msg, HWND16 hwnd, UINT16 first, UINT16 last )
|
||||
{
|
||||
return GetMessage32_16( (MSG32_16 *)msg, hwnd, first, last, FALSE );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* TranslateMessage32 (USER.821)
|
||||
*/
|
||||
BOOL16 WINAPI TranslateMessage32_16( const MSG32_16 *msg, BOOL16 wHaveParamHigh )
|
||||
{
|
||||
MSG msg32;
|
||||
|
||||
msg32.hwnd = msg->msg.hwnd;
|
||||
msg32.message = msg->msg.message;
|
||||
msg32.wParam = MAKEWPARAM( msg->msg.wParam, wHaveParamHigh ? msg->wParamHigh : 0 );
|
||||
msg32.lParam = msg->msg.lParam;
|
||||
return TranslateMessage( &msg32 );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* TranslateMessage (USER.113)
|
||||
*/
|
||||
BOOL16 WINAPI TranslateMessage16( const MSG16 *msg )
|
||||
{
|
||||
return TranslateMessage32_16( (MSG32_16 *)msg, FALSE );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DispatchMessage (USER.114)
|
||||
*/
|
||||
LONG WINAPI DispatchMessage16( const MSG16* msg )
|
||||
{
|
||||
WND * wndPtr;
|
||||
WNDPROC16 winproc;
|
||||
LONG retval;
|
||||
int painting;
|
||||
|
||||
/* Process timer messages */
|
||||
if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
|
||||
{
|
||||
if (msg->lParam)
|
||||
{
|
||||
/* before calling window proc, verify whether timer is still valid;
|
||||
there's a slim chance that the application kills the timer
|
||||
between GetMessage and DispatchMessage API calls */
|
||||
if (!TIMER_IsTimerValid(msg->hwnd, (UINT) msg->wParam, (HWINDOWPROC) msg->lParam))
|
||||
return 0; /* invalid winproc */
|
||||
|
||||
return CallWindowProc16( (WNDPROC16)msg->lParam, msg->hwnd,
|
||||
msg->message, msg->wParam, GetTickCount() );
|
||||
}
|
||||
}
|
||||
|
||||
if (!(wndPtr = WIN_FindWndPtr( msg->hwnd ))) return 0;
|
||||
if (!wndPtr->winproc)
|
||||
{
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
return 0;
|
||||
}
|
||||
winproc = (WNDPROC16)wndPtr->winproc;
|
||||
painting = (msg->message == WM_PAINT);
|
||||
if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
|
||||
SPY_EnterMessage( SPY_DISPATCHMESSAGE16, msg->hwnd, msg->message, msg->wParam, msg->lParam );
|
||||
retval = CallWindowProc16( winproc, msg->hwnd, msg->message, msg->wParam, msg->lParam );
|
||||
SPY_ExitMessage( SPY_RESULT_OK16, msg->hwnd, msg->message, retval, msg->wParam, msg->lParam );
|
||||
|
||||
if (!painting) return retval;
|
||||
|
||||
if ((wndPtr = WIN_FindWndPtr( msg->hwnd )))
|
||||
{
|
||||
if ((wndPtr->flags & WIN_NEEDS_BEGINPAINT) && wndPtr->hrgnUpdate)
|
||||
{
|
||||
ERR( "BeginPaint not called on WM_PAINT for hwnd %04x!\n", msg->hwnd );
|
||||
wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
|
||||
/* Validate the update region to avoid infinite WM_PAINT loop */
|
||||
RedrawWindow( wndPtr->hwndSelf, NULL, 0,
|
||||
RDW_NOFRAME | RDW_VALIDATE | RDW_NOCHILDREN | RDW_NOINTERNALPAINT );
|
||||
}
|
||||
WIN_ReleaseWndPtr( wndPtr );
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DispatchMessage32 (USER.822)
|
||||
*/
|
||||
LONG WINAPI DispatchMessage32_16( const MSG32_16 *msg16, BOOL16 wHaveParamHigh )
|
||||
{
|
||||
if (wHaveParamHigh == FALSE)
|
||||
return DispatchMessage16( &msg16->msg );
|
||||
else
|
||||
{
|
||||
MSG msg;
|
||||
|
||||
msg.hwnd = msg16->msg.hwnd;
|
||||
msg.message = msg16->msg.message;
|
||||
msg.wParam = MAKEWPARAM( msg16->msg.wParam, msg16->wParamHigh );
|
||||
msg.lParam = msg16->msg.lParam;
|
||||
msg.time = msg16->msg.time;
|
||||
msg.pt.x = msg16->msg.pt.x;
|
||||
msg.pt.y = msg16->msg.pt.y;
|
||||
return DispatchMessageA( &msg );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* MsgWaitForMultipleObjects (USER.640)
|
||||
*/
|
||||
DWORD WINAPI MsgWaitForMultipleObjects16( DWORD count, CONST HANDLE *handles,
|
||||
BOOL wait_all, DWORD timeout, DWORD mask )
|
||||
{
|
||||
return MsgWaitForMultipleObjectsEx( count, handles, timeout, mask,
|
||||
wait_all ? MWMO_WAITALL : 0 );
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* SetDoubleClickTime (USER.20)
|
||||
*/
|
||||
void WINAPI SetDoubleClickTime16( UINT16 interval )
|
||||
{
|
||||
SetDoubleClickTime( interval );
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* GetDoubleClickTime (USER.21)
|
||||
*/
|
||||
UINT16 WINAPI GetDoubleClickTime16(void)
|
||||
{
|
||||
return GetDoubleClickTime();
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* PostQuitMessage (USER.6)
|
||||
*/
|
||||
void WINAPI PostQuitMessage16( INT16 exitCode )
|
||||
{
|
||||
PostQuitMessage( exitCode );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SetMessageQueue (USER.266)
|
||||
*/
|
||||
BOOL16 WINAPI SetMessageQueue16( INT16 size )
|
||||
{
|
||||
return SetMessageQueue( size );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetQueueStatus (USER.334)
|
||||
*/
|
||||
DWORD WINAPI GetQueueStatus16( UINT16 flags )
|
||||
{
|
||||
return GetQueueStatus( flags );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetInputState (USER.335)
|
||||
*/
|
||||
BOOL16 WINAPI GetInputState16(void)
|
||||
{
|
||||
return GetInputState();
|
||||
}
|
|
@ -112,8 +112,8 @@ rsrc resources/version16.res
|
|||
105 pascal16 FlashWindow(word word) FlashWindow16
|
||||
106 pascal16 GetKeyState(word) GetKeyState16
|
||||
107 pascal DefWindowProc(word word word long) DefWindowProc16
|
||||
108 pascal16 GetMessage(segptr word word word) GetMessage16
|
||||
109 pascal16 PeekMessage(segptr word word word word) PeekMessage16
|
||||
108 pascal16 GetMessage(ptr word word word) GetMessage16
|
||||
109 pascal16 PeekMessage(ptr word word word word) PeekMessage16
|
||||
110 pascal16 PostMessage(word word word long) PostMessage16
|
||||
111 pascal SendMessage(word word word long) SendMessage16
|
||||
112 pascal16 WaitMessage() WaitMessage
|
||||
|
@ -538,8 +538,8 @@ rsrc resources/version16.res
|
|||
802 stub OPENFILENAME_CALLBACK16
|
||||
803 stub PRINTDLG_CALLBACK16
|
||||
804 stub CHOOSECOLOR_CALLBACK16
|
||||
819 pascal16 PeekMessage32(segptr word word word word word) PeekMessage32_16
|
||||
820 pascal GetMessage32(segptr word word word word) GetMessage32_16
|
||||
819 pascal16 PeekMessage32(ptr word word word word word) PeekMessage32_16
|
||||
820 pascal GetMessage32(ptr word word word word) GetMessage32_16
|
||||
821 pascal16 TranslateMessage32(ptr word) TranslateMessage32_16
|
||||
#821 stub IsDialogMessage32 # FIXME: two ordinal 821???
|
||||
822 pascal DispatchMessage32(ptr word) DispatchMessage32_16
|
||||
|
|
|
@ -11,12 +11,14 @@
|
|||
#include "wine/windef16.h"
|
||||
#include "winproc.h"
|
||||
|
||||
struct tagMSG;
|
||||
|
||||
/* message.c */
|
||||
extern BOOL MSG_InternalGetMessage( struct tagMSG *msg, HWND hwnd, HWND hwndOwner,
|
||||
UINT first, UINT last, WPARAM code,
|
||||
WORD flags, BOOL sendIdle, BOOL* idleSent );
|
||||
extern BOOL MSG_process_raw_hardware_message( MSG *msg, ULONG_PTR extra_info, HWND hwnd_filter,
|
||||
UINT first, UINT last, BOOL remove );
|
||||
extern BOOL MSG_process_cooked_hardware_message( MSG *msg, BOOL remove );
|
||||
extern void MSG_JournalPlayBackMsg(void);
|
||||
|
||||
/* sendmsg.c */
|
||||
extern BOOL MSG_peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, int flags );
|
||||
|
||||
/* timer.c */
|
||||
extern void TIMER_RemoveWindowTimers( HWND hwnd );
|
||||
|
|
|
@ -30,12 +30,15 @@ typedef struct tagPERQUEUEDATA
|
|||
CRITICAL_SECTION cSection; /* Critical section for thread safe access */
|
||||
} PERQUEUEDATA;
|
||||
|
||||
struct received_message_info;
|
||||
|
||||
/* Message queue */
|
||||
typedef struct tagMESSAGEQUEUE
|
||||
{
|
||||
HQUEUE16 self; /* Handle to self (was: reserved) */
|
||||
TEB* teb; /* Thread owning queue */
|
||||
HANDLE server_queue; /* Handle to server-side queue */
|
||||
struct received_message_info *receive_info; /* Info about message being currently received */
|
||||
|
||||
DWORD magic; /* magic number should be QUEUE_MAGIC */
|
||||
DWORD lockCount; /* reference counter */
|
||||
|
@ -69,7 +72,6 @@ extern void QUEUE_Unlock( MESSAGEQUEUE *queue );
|
|||
extern BOOL QUEUE_IsExitingQueue( HQUEUE16 hQueue );
|
||||
extern void QUEUE_SetExitingQueue( HQUEUE16 hQueue );
|
||||
extern void QUEUE_DeleteMsgQueue(void);
|
||||
extern HTASK16 QUEUE_GetQueueTask( HQUEUE16 hQueue );
|
||||
extern void QUEUE_CleanupWindow( HWND hwnd );
|
||||
|
||||
#endif /* __WINE_QUEUE_H */
|
||||
|
|
|
@ -1338,20 +1338,31 @@ struct wait_input_idle_request
|
|||
struct send_message_request
|
||||
{
|
||||
struct request_header __header;
|
||||
int kind;
|
||||
void* id;
|
||||
int type;
|
||||
handle_t win;
|
||||
unsigned int msg;
|
||||
unsigned int wparam;
|
||||
unsigned int lparam;
|
||||
unsigned short x;
|
||||
unsigned short y;
|
||||
int x;
|
||||
int y;
|
||||
unsigned int time;
|
||||
unsigned int info;
|
||||
int timeout;
|
||||
/* VARARG(data,bytes); */
|
||||
};
|
||||
|
||||
enum message_type
|
||||
{
|
||||
MSG_ASCII,
|
||||
MSG_UNICODE,
|
||||
MSG_NOTIFY,
|
||||
MSG_CALLBACK,
|
||||
MSG_OTHER_PROCESS,
|
||||
MSG_POSTED,
|
||||
MSG_HARDWARE_RAW,
|
||||
MSG_HARDWARE_COOKED
|
||||
};
|
||||
enum message_kind { SEND_MESSAGE, POST_MESSAGE, COOKED_HW_MESSAGE, RAW_HW_MESSAGE };
|
||||
#define NB_MSG_KINDS (RAW_HW_MESSAGE+1)
|
||||
|
||||
|
||||
|
||||
|
@ -1362,16 +1373,16 @@ struct get_message_request
|
|||
handle_t get_win;
|
||||
unsigned int get_first;
|
||||
unsigned int get_last;
|
||||
int kind;
|
||||
int type;
|
||||
handle_t win;
|
||||
unsigned int msg;
|
||||
unsigned int wparam;
|
||||
unsigned int lparam;
|
||||
unsigned short x;
|
||||
unsigned short y;
|
||||
int x;
|
||||
int y;
|
||||
unsigned int time;
|
||||
unsigned int info;
|
||||
/* VARARG(data,bytes); */
|
||||
};
|
||||
#define GET_MSG_REMOVE 1
|
||||
#define GET_MSG_SENT_ONLY 2
|
||||
|
@ -1383,6 +1394,7 @@ struct reply_message_request
|
|||
struct request_header __header;
|
||||
unsigned int result;
|
||||
int remove;
|
||||
/* VARARG(data,bytes); */
|
||||
};
|
||||
|
||||
|
||||
|
@ -1392,14 +1404,7 @@ struct get_message_reply_request
|
|||
struct request_header __header;
|
||||
int cancel;
|
||||
unsigned int result;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct in_send_message_request
|
||||
{
|
||||
struct request_header __header;
|
||||
int flags;
|
||||
/* VARARG(data,bytes); */
|
||||
};
|
||||
|
||||
|
||||
|
@ -1639,7 +1644,6 @@ enum request
|
|||
REQ_get_message,
|
||||
REQ_reply_message,
|
||||
REQ_get_message_reply,
|
||||
REQ_in_send_message,
|
||||
REQ_cleanup_window_queue,
|
||||
REQ_set_win_timer,
|
||||
REQ_kill_win_timer,
|
||||
|
@ -1767,7 +1771,6 @@ union generic_request
|
|||
struct get_message_request get_message;
|
||||
struct reply_message_request reply_message;
|
||||
struct get_message_reply_request get_message_reply;
|
||||
struct in_send_message_request in_send_message;
|
||||
struct cleanup_window_queue_request cleanup_window_queue;
|
||||
struct set_win_timer_request set_win_timer;
|
||||
struct kill_win_timer_request kill_win_timer;
|
||||
|
@ -1780,6 +1783,6 @@ union generic_request
|
|||
struct connect_named_pipe_request connect_named_pipe;
|
||||
};
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 48
|
||||
#define SERVER_PROTOCOL_VERSION 49
|
||||
|
||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||
|
|
|
@ -561,8 +561,6 @@ INT16 WINAPI GetWindowRgn16(HWND16,HRGN16);
|
|||
BOOL16 WINAPI IsWindow16(HWND16);
|
||||
INT16 WINAPI LookupIconIdFromDirectory16(LPBYTE,BOOL16);
|
||||
UINT16 WINAPI MapVirtualKey16(UINT16,UINT16);
|
||||
LRESULT WINAPI SendMessageTimeout16(HWND16,UINT16,WPARAM16,LPARAM,UINT16,
|
||||
UINT16,LPWORD);
|
||||
FARPROC16 WINAPI SetWindowsHook16(INT16,HOOKPROC16);
|
||||
HHOOK WINAPI SetWindowsHookEx16(INT16,HOOKPROC16,HINSTANCE16,HTASK16);
|
||||
BOOL16 WINAPI UnhookWindowsHook16(INT16,HOOKPROC16);
|
||||
|
@ -746,8 +744,8 @@ UINT16 WINAPI GetMenuItemID16(HMENU16,INT16);
|
|||
BOOL16 WINAPI GetMenuItemRect16(HWND16,HMENU16,UINT16,LPRECT16);
|
||||
UINT16 WINAPI GetMenuState16(HMENU16,UINT16,UINT16);
|
||||
INT16 WINAPI GetMenuString16(HMENU16,UINT16,LPSTR,INT16,UINT16);
|
||||
BOOL16 WINAPI GetMessage16(SEGPTR,HWND16,UINT16,UINT16);
|
||||
BOOL16 WINAPI GetMessage32_16(SEGPTR,HWND16,UINT16,UINT16,BOOL16);
|
||||
BOOL16 WINAPI GetMessage16(MSG16*,HWND16,UINT16,UINT16);
|
||||
BOOL16 WINAPI GetMessage32_16(MSG32_16*,HWND16,UINT16,UINT16,BOOL16);
|
||||
HWND16 WINAPI GetNextDlgGroupItem16(HWND16,HWND16,BOOL16);
|
||||
HWND16 WINAPI GetNextDlgTabItem16(HWND16,HWND16,BOOL16);
|
||||
HWND16 WINAPI GetNextWindow16(HWND16,WORD);
|
||||
|
@ -825,8 +823,8 @@ BOOL16 WINAPI MoveWindow16(HWND16,INT16,INT16,INT16,INT16,BOOL16);
|
|||
void WINAPI OffsetRect16(LPRECT16,INT16,INT16);
|
||||
BOOL16 WINAPI OpenClipboard16(HWND16);
|
||||
BOOL16 WINAPI OpenIcon16(HWND16);
|
||||
BOOL16 WINAPI PeekMessage16(SEGPTR,HWND16,UINT16,UINT16,UINT16);
|
||||
BOOL16 WINAPI PeekMessage32_16(SEGPTR,HWND16,UINT16,UINT16,UINT16,BOOL16);
|
||||
BOOL16 WINAPI PeekMessage16(MSG16*,HWND16,UINT16,UINT16,UINT16);
|
||||
BOOL16 WINAPI PeekMessage32_16(MSG32_16*,HWND16,UINT16,UINT16,UINT16,BOOL16);
|
||||
BOOL16 WINAPI PostAppMessage16(HTASK16,UINT16,WPARAM16,LPARAM);
|
||||
BOOL16 WINAPI PostMessage16(HWND16,UINT16,WPARAM16,LPARAM);
|
||||
void WINAPI PostQuitMessage16(INT16);
|
||||
|
|
|
@ -1195,20 +1195,31 @@ enum event_op { PULSE_EVENT, SET_EVENT, RESET_EVENT };
|
|||
|
||||
/* Send a message to a thread queue */
|
||||
@REQ(send_message)
|
||||
int kind; /* message kind (see below) */
|
||||
void* id; /* thread id */
|
||||
int type; /* message type */
|
||||
int type; /* message type (see below) */
|
||||
handle_t win; /* window handle */
|
||||
unsigned int msg; /* message code */
|
||||
unsigned int wparam; /* parameters */
|
||||
unsigned int lparam; /* parameters */
|
||||
unsigned short x; /* x position */
|
||||
unsigned short y; /* y position */
|
||||
int x; /* x position */
|
||||
int y; /* y position */
|
||||
unsigned int time; /* message time */
|
||||
unsigned int info; /* extra info */
|
||||
int timeout; /* timeout for reply */
|
||||
VARARG(data,bytes); /* message data for sent messages */
|
||||
@END
|
||||
enum message_kind { SEND_MESSAGE, POST_MESSAGE, COOKED_HW_MESSAGE, RAW_HW_MESSAGE };
|
||||
#define NB_MSG_KINDS (RAW_HW_MESSAGE+1)
|
||||
|
||||
enum message_type
|
||||
{
|
||||
MSG_ASCII, /* Ascii message (from SendMessageA) */
|
||||
MSG_UNICODE, /* Unicode message (from SendMessageW) */
|
||||
MSG_NOTIFY, /* notify message (from SendNotifyMessageW), always Unicode */
|
||||
MSG_CALLBACK, /* callback message (from SendMessageCallbackW), always Unicode */
|
||||
MSG_OTHER_PROCESS, /* sent from other process, may include vararg data, always Unicode */
|
||||
MSG_POSTED, /* posted message (from PostMessageW), always Unicode */
|
||||
MSG_HARDWARE_RAW, /* raw hardware message */
|
||||
MSG_HARDWARE_COOKED /* cooked hardware message */
|
||||
};
|
||||
|
||||
|
||||
/* Get a message from the current queue */
|
||||
|
@ -1218,16 +1229,16 @@ enum message_kind { SEND_MESSAGE, POST_MESSAGE, COOKED_HW_MESSAGE, RAW_HW_MESSAG
|
|||
unsigned int get_first; /* first message code to get */
|
||||
unsigned int get_last; /* last message code to get */
|
||||
@REPLY
|
||||
int kind; /* message kind */
|
||||
int type; /* message type */
|
||||
handle_t win; /* window handle */
|
||||
unsigned int msg; /* message code */
|
||||
unsigned int wparam; /* parameters */
|
||||
unsigned int lparam; /* parameters */
|
||||
unsigned short x; /* x position */
|
||||
unsigned short y; /* y position */
|
||||
int x; /* x position */
|
||||
int y; /* y position */
|
||||
unsigned int time; /* message time */
|
||||
unsigned int info; /* extra info */
|
||||
VARARG(data,bytes); /* message data for sent messages */
|
||||
@END
|
||||
#define GET_MSG_REMOVE 1 /* remove the message */
|
||||
#define GET_MSG_SENT_ONLY 2 /* only get sent messages */
|
||||
|
@ -1237,6 +1248,7 @@ enum message_kind { SEND_MESSAGE, POST_MESSAGE, COOKED_HW_MESSAGE, RAW_HW_MESSAG
|
|||
@REQ(reply_message)
|
||||
unsigned int result; /* message result */
|
||||
int remove; /* should we remove the message? */
|
||||
VARARG(data,bytes); /* message data for sent messages */
|
||||
@END
|
||||
|
||||
|
||||
|
@ -1245,13 +1257,7 @@ enum message_kind { SEND_MESSAGE, POST_MESSAGE, COOKED_HW_MESSAGE, RAW_HW_MESSAG
|
|||
int cancel; /* cancel message if not ready? */
|
||||
@REPLY
|
||||
unsigned int result; /* message result */
|
||||
@END
|
||||
|
||||
|
||||
/* Check if we are processing a sent message */
|
||||
@REQ(in_send_message)
|
||||
@REPLY
|
||||
int flags; /* ISMEX_* flags */
|
||||
VARARG(data,bytes); /* message data for sent messages */
|
||||
@END
|
||||
|
||||
|
||||
|
|
326
server/queue.c
326
server/queue.c
|
@ -17,6 +17,10 @@
|
|||
#include "process.h"
|
||||
#include "request.h"
|
||||
|
||||
enum message_kind { SEND_MESSAGE, POST_MESSAGE, COOKED_HW_MESSAGE, RAW_HW_MESSAGE };
|
||||
#define NB_MSG_KINDS (RAW_HW_MESSAGE+1)
|
||||
|
||||
|
||||
struct message_result
|
||||
{
|
||||
struct message_result *send_next; /* next in sender list */
|
||||
|
@ -26,21 +30,26 @@ struct message_result
|
|||
int replied; /* has it been replied to? */
|
||||
unsigned int result; /* reply result */
|
||||
unsigned int error; /* error code to pass back to sender */
|
||||
void *data; /* message reply data */
|
||||
unsigned int data_size; /* size of message reply data */
|
||||
struct timeout_user *timeout; /* result timeout */
|
||||
};
|
||||
|
||||
struct message
|
||||
{
|
||||
struct message *next; /* next message in list */
|
||||
struct message *prev; /* prev message in list */
|
||||
int type; /* message type (FIXME) */
|
||||
enum message_type type; /* message type */
|
||||
handle_t win; /* window handle */
|
||||
unsigned int msg; /* message code */
|
||||
unsigned int wparam; /* parameters */
|
||||
unsigned int lparam; /* parameters */
|
||||
unsigned short x; /* x position */
|
||||
unsigned short y; /* y position */
|
||||
int x; /* x position */
|
||||
int y; /* y position */
|
||||
unsigned int time; /* message time */
|
||||
unsigned int info; /* extra info */
|
||||
void *data; /* message data for sent messages */
|
||||
unsigned int data_size; /* size of message data */
|
||||
struct message_result *result; /* result in sender queue */
|
||||
};
|
||||
|
||||
|
@ -141,14 +150,21 @@ inline static int is_signaled( struct msg_queue *queue )
|
|||
return ((queue->wake_bits & queue->wake_mask) || (queue->changed_bits & queue->changed_mask));
|
||||
}
|
||||
|
||||
/* set/clear some queue bits */
|
||||
inline static void change_queue_bits( struct msg_queue *queue, unsigned int set, unsigned int clear )
|
||||
/* set some queue bits */
|
||||
inline static void set_queue_bits( struct msg_queue *queue, unsigned int bits )
|
||||
{
|
||||
queue->wake_bits = (queue->wake_bits | set) & ~clear;
|
||||
queue->changed_bits = (queue->changed_bits | set) & ~clear;
|
||||
queue->wake_bits |= bits;
|
||||
queue->changed_bits |= bits;
|
||||
if (is_signaled( queue )) wake_up( &queue->obj, 0 );
|
||||
}
|
||||
|
||||
/* clear some queue bits */
|
||||
inline static void clear_queue_bits( struct msg_queue *queue, unsigned int bits )
|
||||
{
|
||||
queue->wake_bits &= ~bits;
|
||||
queue->changed_bits &= ~bits;
|
||||
}
|
||||
|
||||
/* get the QS_* bit corresponding to a given hardware message */
|
||||
inline static int get_hardware_msg_bit( struct message *msg )
|
||||
{
|
||||
|
@ -203,6 +219,31 @@ static int merge_message( struct message_list *list, const struct message *msg )
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* free a result structure */
|
||||
static void free_result( struct message_result *result )
|
||||
{
|
||||
if (result->timeout) remove_timeout_user( result->timeout );
|
||||
if (result->data) free( result->data );
|
||||
free( result );
|
||||
}
|
||||
|
||||
/* store the message result in the appropriate structure */
|
||||
static void store_message_result( struct message_result *res, unsigned int result,
|
||||
unsigned int error )
|
||||
{
|
||||
res->result = result;
|
||||
res->error = error;
|
||||
res->replied = 1;
|
||||
if (res->timeout)
|
||||
{
|
||||
remove_timeout_user( res->timeout );
|
||||
res->timeout = NULL;
|
||||
}
|
||||
/* wake sender queue if waiting on this result */
|
||||
if (res->sender && res->sender->send_result == res)
|
||||
set_queue_bits( res->sender, QS_SMRESULT );
|
||||
}
|
||||
|
||||
/* free a message when deleting a queue or window */
|
||||
static void free_message( struct message *msg )
|
||||
{
|
||||
|
@ -211,16 +252,12 @@ static void free_message( struct message *msg )
|
|||
{
|
||||
if (result->sender)
|
||||
{
|
||||
result->result = 0;
|
||||
result->error = STATUS_ACCESS_DENIED; /* FIXME */
|
||||
result->replied = 1;
|
||||
result->receiver = NULL;
|
||||
/* wake sender queue if waiting on this result */
|
||||
if (result->sender->send_result == result)
|
||||
change_queue_bits( result->sender, QS_SMRESULT, 0 );
|
||||
store_message_result( result, 0, STATUS_ACCESS_DENIED /*FIXME*/ );
|
||||
}
|
||||
else free( result );
|
||||
else free_result( result );
|
||||
}
|
||||
if (msg->data) free( msg->data );
|
||||
free( msg );
|
||||
}
|
||||
|
||||
|
@ -236,41 +273,59 @@ static void remove_queue_message( struct msg_queue *queue, struct message *msg,
|
|||
switch(kind)
|
||||
{
|
||||
case SEND_MESSAGE:
|
||||
if (!queue->msg_list[kind].first) change_queue_bits( queue, 0, QS_SENDMESSAGE );
|
||||
if (!queue->msg_list[kind].first) clear_queue_bits( queue, QS_SENDMESSAGE );
|
||||
break;
|
||||
case POST_MESSAGE:
|
||||
if (!queue->msg_list[kind].first) change_queue_bits( queue, 0, QS_POSTMESSAGE );
|
||||
if (!queue->msg_list[kind].first) clear_queue_bits( queue, QS_POSTMESSAGE );
|
||||
break;
|
||||
case COOKED_HW_MESSAGE:
|
||||
case RAW_HW_MESSAGE:
|
||||
clr_bit = get_hardware_msg_bit( msg );
|
||||
for (other = queue->msg_list[kind].first; other; other = other->next)
|
||||
if (get_hardware_msg_bit( other ) == clr_bit) break;
|
||||
if (!other) change_queue_bits( queue, 0, clr_bit );
|
||||
if (!other) clear_queue_bits( queue, clr_bit );
|
||||
break;
|
||||
}
|
||||
free_message( msg );
|
||||
}
|
||||
|
||||
/* send a message from the sender queue to the receiver queue */
|
||||
static int send_message( struct msg_queue *send_queue, struct msg_queue *recv_queue,
|
||||
struct message *msg )
|
||||
/* message timed out without getting a reply */
|
||||
static void result_timeout( void *private )
|
||||
{
|
||||
struct message_result *result = private;
|
||||
|
||||
assert( !result->replied );
|
||||
|
||||
result->timeout = NULL;
|
||||
store_message_result( result, 0, STATUS_TIMEOUT );
|
||||
}
|
||||
|
||||
/* allocate and fill a message result structure */
|
||||
static struct message_result *alloc_message_result( struct msg_queue *send_queue,
|
||||
struct msg_queue *recv_queue,
|
||||
unsigned int timeout )
|
||||
{
|
||||
struct message_result *result = mem_alloc( sizeof(*result) );
|
||||
if (!result) return 0;
|
||||
|
||||
/* put the result on the sender result stack */
|
||||
result->sender = send_queue;
|
||||
result->receiver = recv_queue;
|
||||
result->replied = 0;
|
||||
result->send_next = send_queue->send_result;
|
||||
send_queue->send_result = result;
|
||||
|
||||
/* and put the message on the receiver queue */
|
||||
msg->result = result;
|
||||
append_message( &recv_queue->msg_list[SEND_MESSAGE], msg );
|
||||
change_queue_bits( recv_queue, QS_SENDMESSAGE, 0 );
|
||||
return 1;
|
||||
if (result)
|
||||
{
|
||||
/* put the result on the sender result stack */
|
||||
result->sender = send_queue;
|
||||
result->receiver = recv_queue;
|
||||
result->replied = 0;
|
||||
result->data = NULL;
|
||||
result->data_size = 0;
|
||||
result->timeout = NULL;
|
||||
result->send_next = send_queue->send_result;
|
||||
send_queue->send_result = result;
|
||||
if (timeout != -1)
|
||||
{
|
||||
struct timeval when;
|
||||
gettimeofday( &when, 0 );
|
||||
add_timeout( &when, timeout );
|
||||
result->timeout = add_timeout_user( &when, result_timeout, result );
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* receive a message, removing it from the sent queue */
|
||||
|
@ -280,15 +335,19 @@ static void receive_message( struct msg_queue *queue, struct message *msg )
|
|||
|
||||
unlink_message( &queue->msg_list[SEND_MESSAGE], msg );
|
||||
/* put the result on the receiver result stack */
|
||||
result->recv_next = queue->recv_result;
|
||||
queue->recv_result = result;
|
||||
if (result)
|
||||
{
|
||||
result->recv_next = queue->recv_result;
|
||||
queue->recv_result = result;
|
||||
}
|
||||
if (msg->data) free( msg->data );
|
||||
free( msg );
|
||||
if (!queue->msg_list[SEND_MESSAGE].first) change_queue_bits( queue, 0, QS_SENDMESSAGE );
|
||||
if (!queue->msg_list[SEND_MESSAGE].first) clear_queue_bits( queue, QS_SENDMESSAGE );
|
||||
}
|
||||
|
||||
/* set the result of the current received message */
|
||||
static void reply_message( struct msg_queue *queue, unsigned int result,
|
||||
unsigned int error, int remove )
|
||||
unsigned int error, int remove, void *data, size_t len )
|
||||
{
|
||||
struct message_result *res = queue->recv_result;
|
||||
|
||||
|
@ -298,45 +357,17 @@ static void reply_message( struct msg_queue *queue, unsigned int result,
|
|||
res->receiver = NULL;
|
||||
if (!res->sender) /* no one waiting for it */
|
||||
{
|
||||
free( res );
|
||||
free_result( res );
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!res->replied)
|
||||
{
|
||||
res->result = result;
|
||||
res->error = error;
|
||||
res->replied = 1;
|
||||
/* wake sender queue if waiting on this result */
|
||||
if (res->sender && res->sender->send_result == res)
|
||||
change_queue_bits( res->sender, QS_SMRESULT, 0 );
|
||||
if (len && (res->data = memdup( data, len ))) res->data_size = len;
|
||||
store_message_result( res, result, error );
|
||||
}
|
||||
}
|
||||
|
||||
/* retrieve the reply of the current message being sent */
|
||||
static unsigned int get_message_reply( struct msg_queue *queue, int cancel )
|
||||
{
|
||||
struct message_result *res = queue->send_result;
|
||||
unsigned int ret = 0;
|
||||
|
||||
set_error( STATUS_PENDING );
|
||||
|
||||
if (res && (res->replied || cancel))
|
||||
{
|
||||
if (res->replied)
|
||||
{
|
||||
ret = res->result;
|
||||
set_error( res->error );
|
||||
}
|
||||
queue->send_result = res->send_next;
|
||||
res->sender = NULL;
|
||||
if (!res->receiver) free( res );
|
||||
if (!queue->send_result || !queue->send_result->replied)
|
||||
change_queue_bits( queue, 0, QS_SMRESULT );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* empty a message list and free all the messages */
|
||||
static void empty_msg_list( struct message_list *list )
|
||||
{
|
||||
|
@ -359,11 +390,12 @@ static void cleanup_results( struct msg_queue *queue )
|
|||
{
|
||||
next = result->send_next;
|
||||
result->sender = NULL;
|
||||
if (!result->receiver) free( result );
|
||||
if (!result->receiver) free_result( result );
|
||||
result = next;
|
||||
}
|
||||
|
||||
while (queue->recv_result) reply_message( queue, 0, STATUS_ACCESS_DENIED /*FIXME*/, 1 );
|
||||
while (queue->recv_result)
|
||||
reply_message( queue, 0, STATUS_ACCESS_DENIED /*FIXME*/, 1, NULL, 0 );
|
||||
}
|
||||
|
||||
static int msg_queue_add_queue( struct object *obj, struct wait_queue_entry *entry )
|
||||
|
@ -454,9 +486,9 @@ static void set_next_timer( struct msg_queue *queue, struct timer *timer )
|
|||
|
||||
/* set/clear QS_TIMER bit */
|
||||
if (queue->next_timer == queue->first_timer)
|
||||
change_queue_bits( queue, 0, QS_TIMER );
|
||||
clear_queue_bits( queue, QS_TIMER );
|
||||
else
|
||||
change_queue_bits( queue, QS_TIMER, 0 );
|
||||
set_queue_bits( queue, QS_TIMER );
|
||||
}
|
||||
|
||||
/* callback for the next timer expiration */
|
||||
|
@ -504,7 +536,7 @@ static void unlink_timer( struct msg_queue *queue, struct timer *timer )
|
|||
else queue->first_timer = timer->next;
|
||||
/* check if we removed the next timer */
|
||||
if (queue->next_timer == timer) set_next_timer( queue, timer->next );
|
||||
else if (queue->next_timer == queue->first_timer) change_queue_bits( queue, 0, QS_TIMER );
|
||||
else if (queue->next_timer == queue->first_timer) clear_queue_bits( queue, QS_TIMER );
|
||||
}
|
||||
|
||||
/* restart an expired timer */
|
||||
|
@ -620,9 +652,9 @@ DECL_HANDLER(inc_queue_paint_count)
|
|||
if ((queue->paint_count += req->incr) < 0) queue->paint_count = 0;
|
||||
|
||||
if (queue->paint_count)
|
||||
change_queue_bits( queue, QS_PAINT, 0 );
|
||||
set_queue_bits( queue, QS_PAINT );
|
||||
else
|
||||
change_queue_bits( queue, 0, QS_PAINT );
|
||||
clear_queue_bits( queue, QS_PAINT );
|
||||
}
|
||||
else set_error( STATUS_INVALID_PARAMETER );
|
||||
|
||||
|
@ -685,40 +717,64 @@ DECL_HANDLER(send_message)
|
|||
|
||||
if ((msg = mem_alloc( sizeof(*msg) )))
|
||||
{
|
||||
msg->type = req->type;
|
||||
msg->win = req->win;
|
||||
msg->msg = req->msg;
|
||||
msg->wparam = req->wparam;
|
||||
msg->lparam = req->lparam;
|
||||
msg->x = req->x;
|
||||
msg->y = req->y;
|
||||
msg->time = req->time;
|
||||
msg->info = req->info;
|
||||
msg->result = NULL;
|
||||
switch(req->kind)
|
||||
msg->type = req->type;
|
||||
msg->win = req->win;
|
||||
msg->msg = req->msg;
|
||||
msg->wparam = req->wparam;
|
||||
msg->lparam = req->lparam;
|
||||
msg->time = req->time;
|
||||
msg->x = req->x;
|
||||
msg->y = req->y;
|
||||
msg->info = req->info;
|
||||
msg->result = NULL;
|
||||
msg->data = NULL;
|
||||
msg->data_size = 0;
|
||||
|
||||
switch(msg->type)
|
||||
{
|
||||
case SEND_MESSAGE:
|
||||
send_message( send_queue, recv_queue, msg );
|
||||
break;
|
||||
case POST_MESSAGE:
|
||||
append_message( &recv_queue->msg_list[POST_MESSAGE], msg );
|
||||
change_queue_bits( recv_queue, QS_POSTMESSAGE, 0 );
|
||||
break;
|
||||
case COOKED_HW_MESSAGE:
|
||||
case RAW_HW_MESSAGE:
|
||||
if (msg->msg == WM_MOUSEMOVE && merge_message( &recv_queue->msg_list[req->kind], msg ))
|
||||
case MSG_OTHER_PROCESS:
|
||||
msg->data_size = get_req_data_size(req);
|
||||
if (msg->data_size && !(msg->data = memdup( get_req_data(req), msg->data_size )))
|
||||
{
|
||||
free( msg );
|
||||
break;
|
||||
}
|
||||
else
|
||||
/* fall through */
|
||||
case MSG_ASCII:
|
||||
case MSG_UNICODE:
|
||||
case MSG_CALLBACK:
|
||||
if (!(msg->result = alloc_message_result( send_queue, recv_queue, req->timeout )))
|
||||
{
|
||||
append_message( &recv_queue->msg_list[req->kind], msg );
|
||||
change_queue_bits( recv_queue, get_hardware_msg_bit(msg), 0 );
|
||||
free( msg );
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
case MSG_NOTIFY:
|
||||
append_message( &recv_queue->msg_list[SEND_MESSAGE], msg );
|
||||
set_queue_bits( recv_queue, QS_SENDMESSAGE );
|
||||
break;
|
||||
case MSG_POSTED:
|
||||
append_message( &recv_queue->msg_list[POST_MESSAGE], msg );
|
||||
set_queue_bits( recv_queue, QS_POSTMESSAGE );
|
||||
break;
|
||||
case MSG_HARDWARE_RAW:
|
||||
case MSG_HARDWARE_COOKED:
|
||||
{
|
||||
struct message_list *list = ((msg->type == MSG_HARDWARE_RAW) ?
|
||||
&recv_queue->msg_list[RAW_HW_MESSAGE] :
|
||||
&recv_queue->msg_list[COOKED_HW_MESSAGE]);
|
||||
if (msg->msg == WM_MOUSEMOVE && merge_message( list, msg ))
|
||||
{
|
||||
free( msg );
|
||||
break;
|
||||
}
|
||||
append_message( list, msg );
|
||||
set_queue_bits( recv_queue, get_hardware_msg_bit(msg) );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
free( msg );
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
free( msg );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -728,6 +784,8 @@ DECL_HANDLER(send_message)
|
|||
/* store a message contents into the request buffer; helper for get_message */
|
||||
inline static void put_req_message( struct get_message_request *req, const struct message *msg )
|
||||
{
|
||||
int len = min( get_req_data_size(req), msg->data_size );
|
||||
|
||||
req->type = msg->type;
|
||||
req->win = msg->win;
|
||||
req->msg = msg->msg;
|
||||
|
@ -737,16 +795,17 @@ inline static void put_req_message( struct get_message_request *req, const struc
|
|||
req->y = msg->y;
|
||||
req->time = msg->time;
|
||||
req->info = msg->info;
|
||||
if (len) memcpy( get_req_data(req), msg->data, len );
|
||||
set_req_data_size( req, len );
|
||||
}
|
||||
|
||||
/* return a message to the application, removing it from the queue if needed */
|
||||
static void return_message_to_app( struct msg_queue *queue, struct get_message_request *req,
|
||||
struct message *msg, enum message_kind kind )
|
||||
{
|
||||
req->kind = kind;
|
||||
put_req_message( req, msg );
|
||||
/* raw messages always get removed */
|
||||
if ((kind == RAW_HW_MESSAGE) || (req->flags & GET_MSG_REMOVE))
|
||||
if ((msg->type == MSG_HARDWARE_RAW) || (req->flags & GET_MSG_REMOVE))
|
||||
{
|
||||
queue->last_msg = NULL;
|
||||
remove_queue_message( queue, msg, kind );
|
||||
|
@ -784,16 +843,20 @@ DECL_HANDLER(get_message)
|
|||
struct message *msg;
|
||||
struct msg_queue *queue = get_current_queue();
|
||||
|
||||
if (!queue) return;
|
||||
if (!queue)
|
||||
{
|
||||
set_req_data_size( req, 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
/* first check for sent messages */
|
||||
if ((msg = queue->msg_list[SEND_MESSAGE].first))
|
||||
{
|
||||
req->kind = SEND_MESSAGE;
|
||||
put_req_message( req, msg );
|
||||
receive_message( queue, msg );
|
||||
return;
|
||||
}
|
||||
set_req_data_size( req, 0 ); /* only sent messages can have data */
|
||||
if (req->flags & GET_MSG_SENT_ONLY) goto done; /* nothing else to check */
|
||||
|
||||
/* if requested, remove the last returned but not yet removed message */
|
||||
|
@ -831,8 +894,7 @@ DECL_HANDLER(get_message)
|
|||
if ((queue->wake_bits & QS_PAINT) &&
|
||||
(WM_PAINT >= req->get_first) && (WM_PAINT <= req->get_last))
|
||||
{
|
||||
req->kind = POST_MESSAGE;
|
||||
req->type = 0;
|
||||
req->type = MSG_POSTED;
|
||||
req->win = 0;
|
||||
req->msg = WM_PAINT;
|
||||
req->wparam = 0;
|
||||
|
@ -848,8 +910,7 @@ DECL_HANDLER(get_message)
|
|||
if ((timer = find_expired_timer( queue, req->get_win, req->get_first,
|
||||
req->get_last, (req->flags & GET_MSG_REMOVE) )))
|
||||
{
|
||||
req->kind = POST_MESSAGE;
|
||||
req->type = 0;
|
||||
req->type = MSG_POSTED;
|
||||
req->win = timer->win;
|
||||
req->msg = timer->msg;
|
||||
req->wparam = timer->id;
|
||||
|
@ -870,7 +931,8 @@ DECL_HANDLER(get_message)
|
|||
DECL_HANDLER(reply_message)
|
||||
{
|
||||
if (current->queue && current->queue->recv_result)
|
||||
reply_message( current->queue, req->result, 0, req->remove );
|
||||
reply_message( current->queue, req->result, 0, req->remove,
|
||||
get_req_data(req), get_req_data_size(req) );
|
||||
else
|
||||
set_error( STATUS_ACCESS_DENIED );
|
||||
}
|
||||
|
@ -879,26 +941,40 @@ DECL_HANDLER(reply_message)
|
|||
/* retrieve the reply for the last message sent */
|
||||
DECL_HANDLER(get_message_reply)
|
||||
{
|
||||
if (current->queue) req->result = get_message_reply( current->queue, req->cancel );
|
||||
else set_error( STATUS_ACCESS_DENIED );
|
||||
}
|
||||
struct msg_queue *queue = current->queue;
|
||||
size_t data_len = 0;
|
||||
|
||||
|
||||
/* check if we are processing a sent message */
|
||||
DECL_HANDLER(in_send_message)
|
||||
{
|
||||
int flags = 0;
|
||||
|
||||
if (current->queue)
|
||||
if (queue)
|
||||
{
|
||||
struct message_result *result = current->queue->recv_result;
|
||||
if (result)
|
||||
struct message_result *result = queue->send_result;
|
||||
|
||||
set_error( STATUS_PENDING );
|
||||
req->result = 0;
|
||||
|
||||
if (result && (result->replied || req->cancel))
|
||||
{
|
||||
flags |= ISMEX_SEND; /* FIXME */
|
||||
if (result->replied || !result->sender) flags |= ISMEX_REPLIED;
|
||||
if (result->replied)
|
||||
{
|
||||
req->result = result->result;
|
||||
set_error( result->error );
|
||||
if (result->data)
|
||||
{
|
||||
data_len = min( result->data_size, get_req_data_size(req) );
|
||||
memcpy( get_req_data(req), result->data, data_len );
|
||||
free( result->data );
|
||||
result->data = NULL;
|
||||
result->data_size = 0;
|
||||
}
|
||||
}
|
||||
queue->send_result = result->send_next;
|
||||
result->sender = NULL;
|
||||
if (!result->receiver) free_result( result );
|
||||
if (!queue->send_result || !queue->send_result->replied)
|
||||
clear_queue_bits( queue, QS_SMRESULT );
|
||||
}
|
||||
}
|
||||
req->flags = flags;
|
||||
else set_error( STATUS_ACCESS_DENIED );
|
||||
set_req_data_size( req, data_len );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -175,7 +175,6 @@ DECL_HANDLER(send_message);
|
|||
DECL_HANDLER(get_message);
|
||||
DECL_HANDLER(reply_message);
|
||||
DECL_HANDLER(get_message_reply);
|
||||
DECL_HANDLER(in_send_message);
|
||||
DECL_HANDLER(cleanup_window_queue);
|
||||
DECL_HANDLER(set_win_timer);
|
||||
DECL_HANDLER(kill_win_timer);
|
||||
|
@ -302,7 +301,6 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
|
|||
(req_handler)req_get_message,
|
||||
(req_handler)req_reply_message,
|
||||
(req_handler)req_get_message_reply,
|
||||
(req_handler)req_in_send_message,
|
||||
(req_handler)req_cleanup_window_queue,
|
||||
(req_handler)req_set_win_timer,
|
||||
(req_handler)req_kill_win_timer,
|
||||
|
|
|
@ -1457,17 +1457,19 @@ static void dump_wait_input_idle_reply( const struct wait_input_idle_request *re
|
|||
|
||||
static void dump_send_message_request( const struct send_message_request *req )
|
||||
{
|
||||
fprintf( stderr, " kind=%d,", req->kind );
|
||||
fprintf( stderr, " id=%p,", req->id );
|
||||
fprintf( stderr, " type=%d,", req->type );
|
||||
fprintf( stderr, " win=%d,", req->win );
|
||||
fprintf( stderr, " msg=%08x,", req->msg );
|
||||
fprintf( stderr, " wparam=%08x,", req->wparam );
|
||||
fprintf( stderr, " lparam=%08x,", req->lparam );
|
||||
fprintf( stderr, " x=%04x,", req->x );
|
||||
fprintf( stderr, " y=%04x,", req->y );
|
||||
fprintf( stderr, " x=%d,", req->x );
|
||||
fprintf( stderr, " y=%d,", req->y );
|
||||
fprintf( stderr, " time=%08x,", req->time );
|
||||
fprintf( stderr, " info=%08x", req->info );
|
||||
fprintf( stderr, " info=%08x,", req->info );
|
||||
fprintf( stderr, " timeout=%d,", req->timeout );
|
||||
fprintf( stderr, " data=" );
|
||||
cur_pos += dump_varargs_bytes( req );
|
||||
}
|
||||
|
||||
static void dump_get_message_request( const struct get_message_request *req )
|
||||
|
@ -1480,22 +1482,25 @@ static void dump_get_message_request( const struct get_message_request *req )
|
|||
|
||||
static void dump_get_message_reply( const struct get_message_request *req )
|
||||
{
|
||||
fprintf( stderr, " kind=%d,", req->kind );
|
||||
fprintf( stderr, " type=%d,", req->type );
|
||||
fprintf( stderr, " win=%d,", req->win );
|
||||
fprintf( stderr, " msg=%08x,", req->msg );
|
||||
fprintf( stderr, " wparam=%08x,", req->wparam );
|
||||
fprintf( stderr, " lparam=%08x,", req->lparam );
|
||||
fprintf( stderr, " x=%04x,", req->x );
|
||||
fprintf( stderr, " y=%04x,", req->y );
|
||||
fprintf( stderr, " x=%d,", req->x );
|
||||
fprintf( stderr, " y=%d,", req->y );
|
||||
fprintf( stderr, " time=%08x,", req->time );
|
||||
fprintf( stderr, " info=%08x", req->info );
|
||||
fprintf( stderr, " info=%08x,", req->info );
|
||||
fprintf( stderr, " data=" );
|
||||
cur_pos += dump_varargs_bytes( req );
|
||||
}
|
||||
|
||||
static void dump_reply_message_request( const struct reply_message_request *req )
|
||||
{
|
||||
fprintf( stderr, " result=%08x,", req->result );
|
||||
fprintf( stderr, " remove=%d", req->remove );
|
||||
fprintf( stderr, " remove=%d,", req->remove );
|
||||
fprintf( stderr, " data=" );
|
||||
cur_pos += dump_varargs_bytes( req );
|
||||
}
|
||||
|
||||
static void dump_get_message_reply_request( const struct get_message_reply_request *req )
|
||||
|
@ -1505,16 +1510,9 @@ static void dump_get_message_reply_request( const struct get_message_reply_reque
|
|||
|
||||
static void dump_get_message_reply_reply( const struct get_message_reply_request *req )
|
||||
{
|
||||
fprintf( stderr, " result=%08x", req->result );
|
||||
}
|
||||
|
||||
static void dump_in_send_message_request( const struct in_send_message_request *req )
|
||||
{
|
||||
}
|
||||
|
||||
static void dump_in_send_message_reply( const struct in_send_message_request *req )
|
||||
{
|
||||
fprintf( stderr, " flags=%d", req->flags );
|
||||
fprintf( stderr, " result=%08x,", req->result );
|
||||
fprintf( stderr, " data=" );
|
||||
cur_pos += dump_varargs_bytes( req );
|
||||
}
|
||||
|
||||
static void dump_cleanup_window_queue_request( const struct cleanup_window_queue_request *req )
|
||||
|
@ -1739,7 +1737,6 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
|||
(dump_func)dump_get_message_request,
|
||||
(dump_func)dump_reply_message_request,
|
||||
(dump_func)dump_get_message_reply_request,
|
||||
(dump_func)dump_in_send_message_request,
|
||||
(dump_func)dump_cleanup_window_queue_request,
|
||||
(dump_func)dump_set_win_timer_request,
|
||||
(dump_func)dump_kill_win_timer_request,
|
||||
|
@ -1863,7 +1860,6 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
|||
(dump_func)dump_get_message_reply,
|
||||
(dump_func)0,
|
||||
(dump_func)dump_get_message_reply_reply,
|
||||
(dump_func)dump_in_send_message_reply,
|
||||
(dump_func)0,
|
||||
(dump_func)0,
|
||||
(dump_func)0,
|
||||
|
@ -1987,7 +1983,6 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
|||
"get_message",
|
||||
"reply_message",
|
||||
"get_message_reply",
|
||||
"in_send_message",
|
||||
"cleanup_window_queue",
|
||||
"set_win_timer",
|
||||
"kill_win_timer",
|
||||
|
|
|
@ -85,9 +85,8 @@ static void queue_raw_hardware_message( UINT message, WPARAM wParam, LPARAM lPar
|
|||
{
|
||||
SERVER_START_REQ( send_message )
|
||||
{
|
||||
req->kind = RAW_HW_MESSAGE;
|
||||
req->id = (void *)GetCurrentThreadId();
|
||||
req->type = 0;
|
||||
req->type = MSG_HARDWARE_RAW;
|
||||
req->win = 0;
|
||||
req->msg = message;
|
||||
req->wparam = wParam;
|
||||
|
@ -96,6 +95,7 @@ static void queue_raw_hardware_message( UINT message, WPARAM wParam, LPARAM lPar
|
|||
req->y = yPos;
|
||||
req->time = time;
|
||||
req->info = extraInfo;
|
||||
req->timeout = 0;
|
||||
SERVER_CALL();
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
|
1615
windows/message.c
1615
windows/message.c
File diff suppressed because it is too large
Load Diff
|
@ -455,65 +455,25 @@ void QUEUE_CleanupWindow( HWND hwnd )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* QUEUE_GetQueueTask
|
||||
*/
|
||||
HTASK16 QUEUE_GetQueueTask( HQUEUE16 hQueue )
|
||||
{
|
||||
HTASK16 hTask = 0;
|
||||
|
||||
MESSAGEQUEUE *queue = QUEUE_Lock( hQueue );
|
||||
|
||||
if (queue)
|
||||
{
|
||||
hTask = queue->teb->htask16;
|
||||
QUEUE_Unlock( queue );
|
||||
}
|
||||
|
||||
return hTask;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* PostQuitMessage (USER.6)
|
||||
*/
|
||||
void WINAPI PostQuitMessage16( INT16 exitCode )
|
||||
{
|
||||
PostQuitMessage( exitCode );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* PostQuitMessage (USER32.@)
|
||||
*
|
||||
* PostQuitMessage() posts a message to the system requesting an
|
||||
* application to terminate execution. As a result of this function,
|
||||
* the WM_QUIT message is posted to the application, and
|
||||
* PostQuitMessage() returns immediately. The exitCode parameter
|
||||
* specifies an application-defined exit code, which appears in the
|
||||
* _wParam_ parameter of the WM_QUIT message posted to the application.
|
||||
*
|
||||
* CONFORMANCE
|
||||
*
|
||||
* ECMA-234, Win32
|
||||
*/
|
||||
void WINAPI PostQuitMessage( INT exitCode )
|
||||
{
|
||||
PostThreadMessageW( GetCurrentThreadId(), WM_QUIT, exitCode, 0 );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetWindowTask (USER.224)
|
||||
*/
|
||||
HTASK16 WINAPI GetWindowTask16( HWND16 hwnd )
|
||||
{
|
||||
HTASK16 retvalue;
|
||||
WND *wndPtr = WIN_FindWndPtr( hwnd );
|
||||
MESSAGEQUEUE *queue;
|
||||
|
||||
WND *wndPtr = WIN_FindWndPtr( hwnd );
|
||||
if (!wndPtr) return 0;
|
||||
retvalue = QUEUE_GetQueueTask( wndPtr->hmemTaskQ );
|
||||
|
||||
queue = QUEUE_Lock( wndPtr->hmemTaskQ );
|
||||
WIN_ReleaseWndPtr(wndPtr);
|
||||
|
||||
if (!queue) return 0;
|
||||
|
||||
retvalue = queue->teb->htask16;
|
||||
QUEUE_Unlock( queue );
|
||||
|
||||
return retvalue;
|
||||
}
|
||||
|
||||
|
@ -541,25 +501,6 @@ DWORD WINAPI GetWindowThreadProcessId( HWND hwnd, LPDWORD process )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SetMessageQueue (USER.266)
|
||||
*/
|
||||
BOOL16 WINAPI SetMessageQueue16( INT16 size )
|
||||
{
|
||||
return SetMessageQueue( size );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SetMessageQueue (USER32.@)
|
||||
*/
|
||||
BOOL WINAPI SetMessageQueue( INT size )
|
||||
{
|
||||
/* now obsolete the message queue will be expanded dynamically
|
||||
as necessary */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* InitThreadInput (USER.409)
|
||||
*/
|
||||
|
@ -592,14 +533,6 @@ HQUEUE16 WINAPI InitThreadInput16( WORD unknown, WORD flags )
|
|||
return hQueue;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* GetQueueStatus (USER.334)
|
||||
*/
|
||||
DWORD WINAPI GetQueueStatus16( UINT16 flags )
|
||||
{
|
||||
return GetQueueStatus( flags );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* GetQueueStatus (USER32.@)
|
||||
*/
|
||||
|
@ -618,14 +551,6 @@ DWORD WINAPI GetQueueStatus( UINT flags )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* GetInputState (USER.335)
|
||||
*/
|
||||
BOOL16 WINAPI GetInputState16(void)
|
||||
{
|
||||
return GetInputState();
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* GetInputState (USER32.@)
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue