/*
 * Message queues related functions
 *
 * Copyright 1993, 1994 Alexandre Julliard
 */

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/time.h>
#include <sys/types.h>

#include "wine/winbase16.h"
#include "message.h"
#include "winerror.h"
#include "win.h"
#include "heap.h"
#include "hook.h"
#include "input.h"
#include "spy.h"
#include "winpos.h"
#include "dde.h"
#include "queue.h"
#include "winproc.h"
#include "task.h"
#include "process.h"
#include "selectors.h"
#include "thread.h"
#include "options.h"
#include "menu.h"
#include "struct32.h"
#include "debugtools.h"

DEFAULT_DEBUG_CHANNEL(msg)
DECLARE_DEBUG_CHANNEL(key)
DECLARE_DEBUG_CHANNEL(sendmsg)

#define WM_NCMOUSEFIRST         WM_NCMOUSEMOVE
#define WM_NCMOUSELAST          WM_NCMBUTTONDBLCLK

    
typedef enum { SYSQ_MSG_ABANDON, SYSQ_MSG_SKIP, 
               SYSQ_MSG_ACCEPT, SYSQ_MSG_CONTINUE } SYSQ_STATUS;

extern HQUEUE16 hCursorQueue;			 /* queue.c */

DWORD MSG_WineStartTicks; /* Ticks at Wine startup */

static UINT doubleClickSpeed = 452;

/***********************************************************************
 *           MSG_CheckFilter
 */
static BOOL MSG_CheckFilter(DWORD uMsg, DWORD first, DWORD last)
{
   if( first || last )
       return (uMsg >= first && uMsg <= last);
   return TRUE;
}

/***********************************************************************
 *           MSG_SendParentNotify
 *
 * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
 * the window has the WS_EX_NOPARENTNOTIFY style.
 */
static void MSG_SendParentNotify(WND* wndPtr, WORD event, WORD idChild, LPARAM lValue)
{
#define lppt ((LPPOINT16)&lValue)

    /* pt has to be in the client coordinates of the parent window */
    WND *tmpWnd = WIN_LockWndPtr(wndPtr);

    MapWindowPoints16( 0, tmpWnd->hwndSelf, lppt, 1 );
    while (tmpWnd)
    {
        if (!(tmpWnd->dwStyle & WS_CHILD) || (tmpWnd->dwExStyle & WS_EX_NOPARENTNOTIFY))
    {
            WIN_ReleaseWndPtr(tmpWnd);
            break;
        }
	lppt->x += tmpWnd->rectClient.left;
	lppt->y += tmpWnd->rectClient.top;
	WIN_UpdateWndPtr(&tmpWnd,tmpWnd->parent);
	SendMessageA( tmpWnd->hwndSelf, WM_PARENTNOTIFY,
			MAKEWPARAM( event, idChild ), lValue );
    }

#undef lppt
}


/***********************************************************************
 *           MSG_TranslateMouseMsg
 *
 * Translate an mouse hardware event into a real mouse message.
 *
 * Returns:
 *
 *  SYSQ_MSG_ABANDON  - abandon the peek message loop
 *  SYSQ_MSG_CONTINUE - leave the message in the queue and
 *                      continue with the translation loop
 *  SYSQ_MSG_ACCEPT   - proceed to process the translated message
 */
static DWORD MSG_TranslateMouseMsg( HWND hTopWnd, DWORD first, DWORD last,
                                    MSG *msg, BOOL remove, WND* pWndScope,
                                    INT16 *pHitTest, POINT16 *pScreen_pt, BOOL *pmouseClick )
{
    static DWORD   dblclk_time_limit = 0;
    static UINT16     clk_message = 0;
    static HWND16     clk_hwnd = 0;
    static POINT16    clk_pos = { 0, 0 };

    WND *pWnd;
    HWND hWnd;
    INT16 ht, hittest;
    UINT message = msg->message;
    POINT16 screen_pt, pt;
    HANDLE16 hQ = GetFastQueue16();
    MESSAGEQUEUE *queue = (MESSAGEQUEUE *)QUEUE_Lock(hQ);
    BOOL mouseClick = ((message == WM_LBUTTONDOWN) ||
		         (message == WM_RBUTTONDOWN) ||
		         (message == WM_MBUTTONDOWN))?1:0;
    DWORD retvalue;

    /* Find the window to dispatch this mouse message to */

    CONV_POINT32TO16( &msg->pt, &pt );
    
    hWnd = GetCapture();

    /* If no capture HWND, find window which contains the mouse position.
     * Also find the position of the cursor hot spot (hittest) */
    if( !hWnd )
    {
	ht = hittest = WINPOS_WindowFromPoint( pWndScope, pt, &pWnd );
	if( !pWnd ) pWnd = WIN_GetDesktop();
        else WIN_LockWndPtr(pWnd);
	hWnd = pWnd->hwndSelf;
    } 
    else 
    {
        ht = hittest = HTCLIENT;
	pWnd = WIN_FindWndPtr(hWnd);
        if (queue)
            ht = PERQDATA_GetCaptureInfo( queue->pQData );
    }

    /* Save hittest for return */
    *pHitTest = hittest;
        
	/* stop if not the right queue */

    if (pWnd->hmemTaskQ != hQ)
    {
        /* Not for the current task */
        if (queue) QUEUE_ClearWakeBit( queue, QS_MOUSE );
        /* Wake up the other task */
        QUEUE_Unlock( queue );
        queue = (MESSAGEQUEUE *)QUEUE_Lock( pWnd->hmemTaskQ );
        if (queue) QUEUE_SetWakeBit( queue, QS_MOUSE );

        QUEUE_Unlock( queue );
        retvalue = SYSQ_MSG_ABANDON;
        goto END;
    }

	/* check if hWnd is within hWndScope */

    if( hTopWnd && hWnd != hTopWnd )
        if( !IsChild(hTopWnd, hWnd) )
        {
            QUEUE_Unlock( queue );
            retvalue = SYSQ_MSG_CONTINUE;
            goto END;
        }

    /* Was it a mouse click message */
    if( mouseClick )
    {
	/* translate double clicks -
	 * note that ...MOUSEMOVEs can slip in between
	 * ...BUTTONDOWN and ...BUTTONDBLCLK messages */

	if(GetClassLongA(hWnd, GCL_STYLE) & CS_DBLCLKS || ht != HTCLIENT )
	{
           if ((message == clk_message) && (hWnd == clk_hwnd) &&
               (msg->time - dblclk_time_limit < doubleClickSpeed) &&
               (abs(msg->pt.x - clk_pos.x) < GetSystemMetrics(SM_CXDOUBLECLK)/2) &&
               (abs(msg->pt.y - clk_pos.y) < GetSystemMetrics(SM_CYDOUBLECLK)/2))
	   {
	      message += (WM_LBUTTONDBLCLK - WM_LBUTTONDOWN);
	      mouseClick++;   /* == 2 */
	   }
	}
    }
    /* save mouse position */
    screen_pt = pt;
    *pScreen_pt = pt;

    if (hittest != HTCLIENT)
    {
	message += WM_NCMOUSEMOVE - WM_MOUSEMOVE;
	msg->wParam = hittest;
    }
    else
        ScreenToClient16( hWnd, &pt );

	/* check message filter */

    if (!MSG_CheckFilter(message, first, last))
    {
        QUEUE_Unlock(queue);
        retvalue = SYSQ_MSG_CONTINUE;
        goto END;
    }

    /* Update global hCursorQueue */
    hCursorQueue = queue->self;
    
    /* Update static double click conditions */
    if( remove && mouseClick )
    {
	if( mouseClick == 1 )
	{
	    /* set conditions */
	    dblclk_time_limit = msg->time;
	       clk_message = msg->message;
	       clk_hwnd = hWnd;
	       clk_pos = screen_pt;
	} else 
	    /* got double click - zero them out */
	    dblclk_time_limit = clk_hwnd = 0;
    }

    QUEUE_Unlock(queue);

    /* Update message params */
    msg->hwnd    = hWnd;
    msg->message = message;
    msg->lParam  = MAKELONG( pt.x, pt.y );
    retvalue = SYSQ_MSG_ACCEPT;

END:
    WIN_ReleaseWndPtr(pWnd);

    /* Return mouseclick flag */
    *pmouseClick = mouseClick;
    
    return retvalue;
}


/***********************************************************************
 *           MSG_ProcessMouseMsg
 *
 * Processes a translated mouse hardware event.
 * The passed in msg structure should contain the updated hWnd, 
 * lParam, wParam and message fields from MSG_TranslateMouseMsg.
 *
 * Returns:
 *
 *  SYSQ_MSG_SKIP     - Message should be skipped entirely (in this case
 *                      HIWORD contains hit test code). Continue translating..
 *  SYSQ_MSG_ACCEPT   - the translated message must be passed to the user
 *                      MSG_PeekHardwareMsg should return TRUE.
 */
static DWORD MSG_ProcessMouseMsg( MSG *msg, BOOL remove, INT16 hittest,
                                  POINT16 screen_pt, BOOL mouseClick )
{
    WND *pWnd;
    HWND hWnd = msg->hwnd;
    INT16 sendSC = (GetCapture() == 0);
    UINT message = msg->message;
    BOOL eatMsg = FALSE;
    DWORD retvalue;

    pWnd = WIN_FindWndPtr(hWnd);
    
	/* call WH_MOUSE */

    if (HOOK_IsHooked( WH_MOUSE ))
    { 
        SYSQ_STATUS ret = 0;
	MOUSEHOOKSTRUCT16 *hook = SEGPTR_NEW(MOUSEHOOKSTRUCT16);
	if( hook )
	{
	    hook->pt           = screen_pt;
	    hook->hwnd         = hWnd;
	    hook->wHitTestCode = hittest;
	    hook->dwExtraInfo  = 0;
	    ret = HOOK_CallHooks16( WH_MOUSE, remove ? HC_ACTION : HC_NOREMOVE,
	                            message, (LPARAM)SEGPTR_GET(hook) );
	    SEGPTR_FREE(hook);
	}
        if( ret )
        {
            retvalue = MAKELONG((INT16)SYSQ_MSG_SKIP, hittest);
            goto END;
    }
    }


    if ((hittest == HTERROR) || (hittest == HTNOWHERE)) 
	eatMsg = sendSC = 1;
    else if( remove && mouseClick )
    {
        HWND hwndTop = WIN_GetTopParent( hWnd );

	if( sendSC )
	{
            /* Send the WM_PARENTNOTIFY,
	     * note that even for double/nonclient clicks
	     * notification message is still WM_L/M/RBUTTONDOWN.
	     */

            MSG_SendParentNotify( pWnd, msg->message & 0xffff, 0, MAKELPARAM(screen_pt.x, screen_pt.y) );

            /* Activate the window if needed */

            if (hWnd != GetActiveWindow() && hWnd != GetDesktopWindow())
            {
                LONG ret = SendMessageA( hWnd, WM_MOUSEACTIVATE, hwndTop,
                                          MAKELONG( hittest, message ) );

                if ((ret == MA_ACTIVATEANDEAT) || (ret == MA_NOACTIVATEANDEAT))
                         eatMsg = TRUE;

                if (((ret == MA_ACTIVATE) || (ret == MA_ACTIVATEANDEAT))
                        && hwndTop != GetForegroundWindow() )
                {
                      if (!WINPOS_SetActiveWindow( hwndTop, TRUE , TRUE ))
			 eatMsg = TRUE;
                }
            }
	}
    } else sendSC = (remove && sendSC);

     /* Send the WM_SETCURSOR message */

    if (sendSC)
    {
        UINT uSCMessage = message;

        /* Windows sends the normal mouse message as the message parameter
           in the WM_SETCURSOR message even if it's non-client mouse message */

        if (uSCMessage >= WM_NCMOUSEFIRST && uSCMessage <= WM_NCMOUSELAST)
	        uSCMessage += WM_MOUSEFIRST - WM_NCMOUSEFIRST;
        SendMessageA( hWnd, WM_SETCURSOR, hWnd,
                       MAKELONG( hittest, uSCMessage));
    }
    if (eatMsg)
    {
        retvalue = MAKELONG( (UINT16)SYSQ_MSG_SKIP, hittest);
        goto END;
    }

    retvalue = SYSQ_MSG_ACCEPT;
END:
    WIN_ReleaseWndPtr(pWnd);

    return retvalue;
}


/***********************************************************************
 *           MSG_TranslateKbdMsg
 *
 * Translate an keyboard hardware event into a real message.
 */
static DWORD MSG_TranslateKbdMsg( HWND hTopWnd, DWORD first, DWORD last,
				  MSG *msg, BOOL remove )
{
    WORD message = msg->message;
    HWND hWnd = GetFocus();
    WND *pWnd;

      /* Should check Ctrl-Esc and PrintScreen here */

    if (!hWnd)
    {
	  /* Send the message to the active window instead,  */
	  /* translating messages to their WM_SYS equivalent */

	hWnd = GetActiveWindow();

	if( message < WM_SYSKEYDOWN )
	    message += WM_SYSKEYDOWN - WM_KEYDOWN;
    }
    pWnd = WIN_FindWndPtr( hWnd );
    if (pWnd && (pWnd->hmemTaskQ != GetFastQueue16()))
    {
        /* Not for the current task */
        MESSAGEQUEUE *queue = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() );
        if (queue) QUEUE_ClearWakeBit( queue, QS_KEY );
        QUEUE_Unlock( queue );
        
        /* Wake up the other task */
        queue = (MESSAGEQUEUE *)QUEUE_Lock( pWnd->hmemTaskQ );
        if (queue) QUEUE_SetWakeBit( queue, QS_KEY );
        QUEUE_Unlock( queue );
        WIN_ReleaseWndPtr(pWnd);
        return SYSQ_MSG_ABANDON;
    }
    WIN_ReleaseWndPtr(pWnd);

    if (hTopWnd && hWnd != hTopWnd)
	if (!IsChild(hTopWnd, hWnd)) return SYSQ_MSG_CONTINUE;
    if (!MSG_CheckFilter(message, first, last)) return SYSQ_MSG_CONTINUE;

    msg->hwnd = hWnd;
    msg->message = message;

    return SYSQ_MSG_ACCEPT;
}


/***********************************************************************
 *           MSG_ProcessKbdMsg
 *
 *  Processes a translated keyboard message
 */
static DWORD MSG_ProcessKbdMsg( MSG *msg, BOOL remove )
{
    /* Handle F1 key by sending out WM_HELP message */
    if ((msg->message == WM_KEYUP) && 
	(msg->wParam == VK_F1) &&
	remove &&
	(msg->hwnd != GetDesktopWindow()) &&
	!MENU_IsMenuActive())
    {   
	HELPINFO hi;
	WND *pWnd = WIN_FindWndPtr(msg->hwnd);

	if (NULL != pWnd)
	{
	    hi.cbSize = sizeof(HELPINFO);
	    hi.iContextType = HELPINFO_WINDOW;
	    hi.iCtrlId = pWnd->wIDmenu; 
	    hi.hItemHandle = msg->hwnd;
	    hi.dwContextId = pWnd->helpContext;
	    hi.MousePos = msg->pt;
	    SendMessageA(msg->hwnd, WM_HELP, 0, (LPARAM)&hi);
	}
        WIN_ReleaseWndPtr(pWnd);
    }

    return (HOOK_CallHooks16( WH_KEYBOARD, remove ? HC_ACTION : HC_NOREMOVE,
			      LOWORD (msg->wParam), msg->lParam )
            ? SYSQ_MSG_SKIP : SYSQ_MSG_ACCEPT);
}


/***********************************************************************
 *           MSG_JournalRecordMsg
 *
 * Build an EVENTMSG structure and call JOURNALRECORD hook
 */
static void MSG_JournalRecordMsg( MSG *msg )
{
    EVENTMSG *event = (EVENTMSG *) HeapAlloc(SystemHeap, 0, sizeof(EVENTMSG));
    if (!event) return;
    event->message = msg->message;
    event->time = msg->time;
    if ((msg->message >= WM_KEYFIRST) && (msg->message <= WM_KEYLAST))
    {
        event->paramL = (msg->wParam & 0xFF) | (HIWORD(msg->lParam) << 8);
        event->paramH = msg->lParam & 0x7FFF;  
        if (HIWORD(msg->lParam) & 0x0100)
            event->paramH |= 0x8000;               /* special_key - bit */
        HOOK_CallHooksA( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)event );
    }
    else if ((msg->message >= WM_MOUSEFIRST) && (msg->message <= WM_MOUSELAST))
    {
        event->paramL = LOWORD(msg->lParam);       /* X pos */
        event->paramH = HIWORD(msg->lParam);       /* Y pos */ 
        ClientToScreen16( msg->hwnd, (LPPOINT16)&event->paramL );
        HOOK_CallHooksA( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)event );
    }
    else if ((msg->message >= WM_NCMOUSEFIRST) &&
             (msg->message <= WM_NCMOUSELAST))
    {
        event->paramL = LOWORD(msg->lParam);       /* X pos */
        event->paramH = HIWORD(msg->lParam);       /* Y pos */ 
        event->message += WM_MOUSEMOVE-WM_NCMOUSEMOVE;/* give no info about NC area */
        HOOK_CallHooksA( WH_JOURNALRECORD, HC_ACTION, 0, (LPARAM)event );
    }
    
    HeapFree(SystemHeap, 0, event);
}

/***********************************************************************
 *          MSG_JournalPlayBackMsg
 *
 * Get an EVENTMSG struct via call JOURNALPLAYBACK hook function 
 */
static int MSG_JournalPlayBackMsg(void)
{
 EVENTMSG *tmpMsg;
 long wtime,lParam,wParam;
 WORD keyDown,i,result=0;

 if ( HOOK_IsHooked( WH_JOURNALPLAYBACK ) )
 {
  tmpMsg = (EVENTMSG *) HeapAlloc(SystemHeap, 0, sizeof(EVENTMSG));
  if (!tmpMsg) return result;
  
  wtime=HOOK_CallHooksA( WH_JOURNALPLAYBACK, HC_GETNEXT, 0,
                           (LPARAM) tmpMsg );
  /*  TRACE(msg,"Playback wait time =%ld\n",wtime); */
  if (wtime<=0)
  {
   wtime=0;
   if ((tmpMsg->message>= WM_KEYFIRST) && (tmpMsg->message <= WM_KEYLAST))
   {
     wParam=tmpMsg->paramL & 0xFF;
     lParam=MAKELONG(tmpMsg->paramH&0x7ffff,tmpMsg->paramL>>8);
     if (tmpMsg->message == WM_KEYDOWN || tmpMsg->message == WM_SYSKEYDOWN)
     {
       for (keyDown=i=0; i<256 && !keyDown; i++)
          if (InputKeyStateTable[i] & 0x80)
            keyDown++;
       if (!keyDown)
         lParam |= 0x40000000;       
       AsyncKeyStateTable[wParam]=InputKeyStateTable[wParam] |= 0x80;
     }  
     else                                       /* WM_KEYUP, WM_SYSKEYUP */
     {
       lParam |= 0xC0000000;      
       AsyncKeyStateTable[wParam]=InputKeyStateTable[wParam] &= ~0x80;
     }
     if (InputKeyStateTable[VK_MENU] & 0x80)
       lParam |= 0x20000000;     
     if (tmpMsg->paramH & 0x8000)              /*special_key bit*/
       lParam |= 0x01000000;
     hardware_event( tmpMsg->message & 0xffff, LOWORD(wParam), lParam,
                     0, 0, tmpMsg->time, 0 );
   }
   else
   {
    if ((tmpMsg->message>= WM_MOUSEFIRST) && (tmpMsg->message <= WM_MOUSELAST))
    {
     switch (tmpMsg->message)
     {
      case WM_LBUTTONDOWN:
          MouseButtonsStates[0]=AsyncMouseButtonsStates[0]=TRUE;break;
      case WM_LBUTTONUP:
          MouseButtonsStates[0]=AsyncMouseButtonsStates[0]=FALSE;break;
      case WM_MBUTTONDOWN:
          MouseButtonsStates[1]=AsyncMouseButtonsStates[1]=TRUE;break;
      case WM_MBUTTONUP:
          MouseButtonsStates[1]=AsyncMouseButtonsStates[1]=FALSE;break;
      case WM_RBUTTONDOWN:
          MouseButtonsStates[2]=AsyncMouseButtonsStates[2]=TRUE;break;
      case WM_RBUTTONUP:
          MouseButtonsStates[2]=AsyncMouseButtonsStates[2]=FALSE;break;      
     }
     AsyncKeyStateTable[VK_LBUTTON]= InputKeyStateTable[VK_LBUTTON] = MouseButtonsStates[0] ? 0x80 : 0;
     AsyncKeyStateTable[VK_MBUTTON]= InputKeyStateTable[VK_MBUTTON] = MouseButtonsStates[1] ? 0x80 : 0;
     AsyncKeyStateTable[VK_RBUTTON]= InputKeyStateTable[VK_RBUTTON] = MouseButtonsStates[2] ? 0x80 : 0;
     SetCursorPos(tmpMsg->paramL,tmpMsg->paramH);
     lParam=MAKELONG(tmpMsg->paramL,tmpMsg->paramH);
     wParam=0;             
     if (MouseButtonsStates[0]) wParam |= MK_LBUTTON;
     if (MouseButtonsStates[1]) wParam |= MK_MBUTTON;
     if (MouseButtonsStates[2]) wParam |= MK_RBUTTON;
     hardware_event( tmpMsg->message & 0xffff, LOWORD (wParam), lParam,
                     tmpMsg->paramL, tmpMsg->paramH, tmpMsg->time, 0 );
    }
   }
   HOOK_CallHooksA( WH_JOURNALPLAYBACK, HC_SKIP, 0,
                      (LPARAM) tmpMsg);
  }
  else
  {
      
    if( tmpMsg->message == WM_QUEUESYNC )
        if (HOOK_IsHooked( WH_CBT ))
            HOOK_CallHooksA( WH_CBT, HCBT_QS, 0, 0L);

    result= QS_MOUSE | QS_KEY; /* ? */
  }
  HeapFree(SystemHeap, 0, tmpMsg);
 }
 return result;
} 

/***********************************************************************
 *           MSG_PeekHardwareMsg
 *
 * Peek for a hardware message matching the hwnd and message filters.
 */
static BOOL MSG_PeekHardwareMsg( MSG *msg, HWND hwnd, DWORD first, DWORD last,
                                   BOOL remove )
{
    /* FIXME: should deal with MSG32 instead of MSG16 */
    
    DWORD status = SYSQ_MSG_ACCEPT;
    MESSAGEQUEUE *sysMsgQueue = QUEUE_GetSysQueue();
    enum { MOUSE_MSG = 0, KEYBOARD_MSG, HARDWARE_MSG } msgType;
    QMSG *nextqmsg, *qmsg = 0;
    BOOL bRet = FALSE;

    EnterCriticalSection(&sysMsgQueue->cSection);

    /* Loop through the Q and translate the message we wish to process
     * while we own the lock. Based on the translation status (abandon/cont/accept)
     * we then process the message accordingly
     */

    for ( qmsg = sysMsgQueue->firstMsg; qmsg; qmsg = nextqmsg )
    {
        INT16 hittest;
        POINT16 screen_pt;
        BOOL mouseClick;

        *msg = qmsg->msg;

        nextqmsg = qmsg->nextMsg;

          /* Translate message */

        if ((msg->message >= WM_MOUSEFIRST) && (msg->message <= WM_MOUSELAST))
        {
            HWND hWndScope = (HWND)qmsg->extraInfo;
            WND *tmpWnd = (Options.managed && IsWindow(hWndScope) ) 
                           ? WIN_FindWndPtr(hWndScope) : WIN_GetDesktop();

            status = MSG_TranslateMouseMsg(hwnd, first, last, msg, remove, tmpWnd,
                                           &hittest, &screen_pt, &mouseClick );
	    msgType = MOUSE_MSG;
            
            WIN_ReleaseWndPtr(tmpWnd);

        }
        else if ((msg->message >= WM_KEYFIRST) && (msg->message <= WM_KEYLAST))
        {
            status = MSG_TranslateKbdMsg(hwnd, first, last, msg, remove);
	    msgType = KEYBOARD_MSG;
        }
        else /* Non-standard hardware event */
        {
            HARDWAREHOOKSTRUCT16 *hook;
	    msgType = HARDWARE_MSG;
            if ((hook = SEGPTR_NEW(HARDWAREHOOKSTRUCT16)))
            {
                BOOL ret;
                hook->hWnd     = msg->hwnd;
                hook->wMessage = msg->message & 0xffff;
                hook->wParam   = LOWORD (msg->wParam);
                hook->lParam   = msg->lParam;
                ret = HOOK_CallHooks16( WH_HARDWARE,
                                        remove ? HC_ACTION : HC_NOREMOVE,
                                        0, (LPARAM)SEGPTR_GET(hook) );
                SEGPTR_FREE(hook);
                if (ret) 
		{
                    QUEUE_RemoveMsg( sysMsgQueue, qmsg );
		    continue;
		}
		status = SYSQ_MSG_ACCEPT; 
            }
        }

        
	switch (LOWORD(status))
	{
	   case SYSQ_MSG_ACCEPT:
           {
               /* Remove the message from the system msg Q while it is still locked,
                * before accepting it */
               if (remove)
               {
                   if (HOOK_IsHooked( WH_JOURNALRECORD )) MSG_JournalRecordMsg( msg );
                   QUEUE_RemoveMsg( sysMsgQueue, qmsg );
               }
               /* Now actually process the message, after we unlock the system msg Q.
                * We should not hold on to the crst since SendMessage calls during processing 
                * will potentially cause callbacks to PeekMessage from the application.
                * If we're holding the crst and QUEUE_WaitBits is called with a
                * QS_SENDMESSAGE mask we will deadlock in hardware_event() when a
                * message is being posted to the Q.
                */
               LeaveCriticalSection(&sysMsgQueue->cSection);
               if( msgType == KEYBOARD_MSG )
                   status = MSG_ProcessKbdMsg( msg, remove );
               else if ( msgType == MOUSE_MSG )
                   status = MSG_ProcessMouseMsg( msg, remove, hittest, screen_pt, mouseClick );

               /* Reclaim the sys msg Q crst */
               EnterCriticalSection(&sysMsgQueue->cSection);
               
               /* Pass the translated message to the user if it was accepted */
               if (status == SYSQ_MSG_ACCEPT)
		break;

               /* If not accepted, fall through into the SYSQ_MSG_SKIP case */
           }
                
	   case SYSQ_MSG_SKIP:
                if (HOOK_IsHooked( WH_CBT ))
                {
                   if( msgType == KEYBOARD_MSG )
		       HOOK_CallHooks16( WH_CBT, HCBT_KEYSKIPPED, 
                                         LOWORD (msg->wParam), msg->lParam );
		   else if ( msgType == MOUSE_MSG )
		   {
                       MOUSEHOOKSTRUCT16 *hook = SEGPTR_NEW(MOUSEHOOKSTRUCT16);
                       if (hook)
                       {
                           CONV_POINT32TO16( &msg->pt,&hook->pt );
                           hook->hwnd         = msg->hwnd;
                           hook->wHitTestCode = HIWORD(status);
                           hook->dwExtraInfo  = 0;
                           HOOK_CallHooks16( WH_CBT, HCBT_CLICKSKIPPED ,msg->message & 0xffff,
                                          (LPARAM)SEGPTR_GET(hook) );
                           SEGPTR_FREE(hook);
                       }
                   }
                }

                /* If the message was removed earlier set up nextqmsg so that we start 
                 * at the top of the queue again.  We need to do this since our next pointer
                 * could be invalid due to us unlocking the system message Q to process the message.
                 * If not removed just refresh nextqmsg to point to the next msg.
                 */
		if (remove)
                    nextqmsg = sysMsgQueue->firstMsg;
                else
                    nextqmsg = qmsg->nextMsg;

		continue;
                
	   case SYSQ_MSG_CONTINUE:
		continue;

	   case SYSQ_MSG_ABANDON: 
               bRet = FALSE;
               goto END;
	}

        bRet = TRUE;
        goto END;
    }

END:
    LeaveCriticalSection(&sysMsgQueue->cSection);
    return bRet;
}


/**********************************************************************
 *           SetDoubleClickTime16   (USER.20)
 */
void WINAPI SetDoubleClickTime16( UINT16 interval )
{
    SetDoubleClickTime( interval );
}		


/**********************************************************************
 *           SetDoubleClickTime   (USER32.480)
 */
BOOL WINAPI SetDoubleClickTime( UINT interval )
{
    doubleClickSpeed = interval ? interval : 500;
    return TRUE;
}		


/**********************************************************************
 *           GetDoubleClickTime16   (USER.21)
 */
UINT16 WINAPI GetDoubleClickTime16(void)
{
    return doubleClickSpeed;
}		


/**********************************************************************
 *           GetDoubleClickTime   (USER32.239)
 */
UINT WINAPI GetDoubleClickTime(void)
{
    return doubleClickSpeed;
}		


/***********************************************************************
 *           MSG_SendMessageInterThread
 *
 * Implementation of an inter-task SendMessage.
 * Return values:
 *    0 if error or timeout
 *    1 if successflul
 */
static LRESULT MSG_SendMessageInterThread( HQUEUE16 hDestQueue,
                                           HWND hwnd, UINT msg,
                                           WPARAM wParam, LPARAM lParam,
                                           DWORD timeout, WORD flags,
                                           LRESULT *pRes)
{
    MESSAGEQUEUE *queue, *destQ;
    SMSG         *smsg;
    LRESULT      retVal = 1;
    int          iWndsLocks;
    
    *pRes = 0;

    if (IsTaskLocked16() || !IsWindow(hwnd))
        return 0;

    /* create a SMSG structure to hold SendMessage() parameters */
    if (! (smsg = (SMSG *) HeapAlloc( SystemHeap, 0, sizeof(SMSG) )) )
        return 0;
    if (!(queue = (MESSAGEQUEUE*)QUEUE_Lock( GetFastQueue16() ))) return 0;

    if (!(destQ = (MESSAGEQUEUE*)QUEUE_Lock( hDestQueue )))
    {
        QUEUE_Unlock( queue );
        return 0;
    }

    TRACE_(sendmsg)("SM: %s [%04x] (%04x -> %04x)\n",
		    SPY_GetMsgName(msg), msg, queue->self, hDestQueue );

    /* fill up SMSG structure */
    smsg->hWnd = hwnd;
    smsg->msg = msg;
    smsg->wParam = wParam;
    smsg->lParam = lParam;
    
    smsg->lResult = 0;
    smsg->hSrcQueue = GetFastQueue16();
    smsg->hDstQueue = hDestQueue;
    smsg->flags = flags;

    /* add smsg struct in the processing SM list of the source queue */
    QUEUE_AddSMSG(queue, SM_PROCESSING_LIST, smsg);

    /* add smsg struct in the pending list of the destination queue */
    if (QUEUE_AddSMSG(destQ, SM_PENDING_LIST, smsg) == FALSE)
        return 0;

    iWndsLocks = WIN_SuspendWndsLock();

    /* force destination task to run next, if 16 bit threads */
    if ( THREAD_IsWin16(NtCurrentTeb()) && THREAD_IsWin16(destQ->teb) )
        DirectedYield16( destQ->teb->htask16 );

    /* wait for the result, note that 16-bit apps almost always get out of
     * DirectedYield() with SMSG_HAVE_RESULT flag already set */

    while ( TRUE )
    {
        /*
         * The sequence is crucial to avoid deadlock situations:
         * - first, we clear the QS_SMRESULT bit
         * - then, we check the SMSG_HAVE_RESULT bit
         * - only if this isn't set, we enter the wait state.
         *
         * As the receiver first sets the SMSG_HAVE_RESULT and then wakes us,
         * we are guaranteed that -should we now clear the QS_SMRESULT that
         * was signalled already by the receiver- we will not start waiting.
         */

        if ( smsg->flags & SMSG_HAVE_RESULT )
        {
got:
             *pRes = smsg->lResult;
             TRACE_(sendmsg)("smResult = %08x\n", (unsigned)*pRes );
             break;
        }

        QUEUE_ClearWakeBit( queue, QS_SMRESULT );

        if ( smsg->flags & SMSG_HAVE_RESULT )
             goto got;

        if(  QUEUE_WaitBits( QS_SMRESULT, timeout ) == 0 )
        {
             /* return with timeout */
             SetLastError( 0 );
             retVal = 0;
             break;
        }
    }
    WIN_RestoreWndsLock(iWndsLocks);

    /* remove the smsg from the processingg list of the source queue */
    QUEUE_RemoveSMSG( queue, SM_PROCESSING_LIST, smsg );

    /* Note: the destination thread is in charge of removing the smsg from
       the pending list */

    /* In the case of an early reply (or a timeout), sender thread will
       released the smsg structure if the receiver thread is done
       (SMSG_RECEIVED set). If the receiver thread isn't done,
       SMSG_RECEIVER_CLEANS_UP flag is set, and it will be the receiver
       responsability to released smsg */
        EnterCriticalSection( &queue->cSection );
    
        if (smsg->flags & SMSG_RECEIVED)
            HeapFree(SystemHeap, 0, smsg);
        else
            smsg->flags |= SMSG_RECEIVER_CLEANS;
        
        LeaveCriticalSection( &queue->cSection );


    QUEUE_Unlock( queue );
    QUEUE_Unlock( destQ );
    
    TRACE_(sendmsg)("done!\n");
    return retVal;
}


/***********************************************************************
 *           ReplyMessage16   (USER.115)
 */
void WINAPI ReplyMessage16( LRESULT result )
{
    ReplyMessage( result );
}

/***********************************************************************
 *           ReplyMessage   (USER.115)
 */
BOOL WINAPI ReplyMessage( LRESULT result )
{
    MESSAGEQUEUE *senderQ = 0;
    MESSAGEQUEUE *queue = 0;
    SMSG         *smsg;
    BOOL       ret = FALSE;

    if (!(queue = (MESSAGEQUEUE*)QUEUE_Lock( GetFastQueue16() )))
        return FALSE;

    TRACE_(sendmsg)("ReplyMessage, queue %04x\n", queue->self);


    if (    !(smsg = queue->smWaiting)
         || !(senderQ = QUEUE_Lock( smsg->hSrcQueue )) )
        goto ReplyMessageEnd;

    if ( !(smsg->flags & SMSG_ALREADY_REPLIED) )
    {
        /* This is the first reply, so pass result to sender */

        TRACE_(sendmsg)("\trpm: smResult = %08lx\n", (long) result );

        EnterCriticalSection(&senderQ->cSection);
        
        smsg->lResult = result;
        smsg->flags |= SMSG_ALREADY_REPLIED;

        /* check if it's an early reply (called by the application) or
           a regular reply (called by ReceiveMessage) */
        if ( !(smsg->flags & SMSG_SENDING_REPLY) )
            smsg->flags |= SMSG_EARLY_REPLY;

        smsg->flags |= SMSG_HAVE_RESULT;

        LeaveCriticalSection(&senderQ->cSection);

        /* tell the sending task that its reply is ready */
        QUEUE_SetWakeBit( senderQ, QS_SMRESULT );

        /* switch directly to sending task (16 bit thread only) */
        if ( THREAD_IsWin16( NtCurrentTeb() ) && THREAD_IsWin16( senderQ->teb ) )
            DirectedYield16( senderQ->teb->htask16 );

        ret = TRUE;
    }
    
    if (smsg->flags & SMSG_SENDING_REPLY)
    {
        /* remove msg from the waiting list, since this  is the last
          ReplyMessage */
        QUEUE_RemoveSMSG( queue, SM_WAITING_LIST, smsg );
        
        EnterCriticalSection(&senderQ->cSection);
        
        /* tell the sender we're all done with smsg structure */
        smsg->flags |= SMSG_RECEIVED;

        /* sender will set SMSG_RECEIVER_CLEANS_UP if it wants the
         receiver to clean up smsg, it could only happens when there is
         an early reply or a timeout */
        if ( smsg->flags & SMSG_RECEIVER_CLEANS )
        {
            TRACE_(sendmsg)("Receiver cleans up!\n" );
            HeapFree( SystemHeap, 0, smsg );
        }
        
        LeaveCriticalSection(&senderQ->cSection);
    }

ReplyMessageEnd:
    if ( senderQ )
    QUEUE_Unlock( senderQ );
    if ( queue )
    QUEUE_Unlock( queue );

    return ret;
}

/***********************************************************************
 *           MSG_ConvertMsg
 */
static BOOL MSG_ConvertMsg( MSG *msg, int srcType, int dstType )
{
    UINT16 msg16;
    MSGPARAM16 mp16;

    switch ( MAKELONG( srcType, dstType ) )
    {
    case MAKELONG( QMSG_WIN16,  QMSG_WIN16 ):
    case MAKELONG( QMSG_WIN32A, QMSG_WIN32A ):
    case MAKELONG( QMSG_WIN32W, QMSG_WIN32W ):
        return TRUE;

    case MAKELONG( QMSG_WIN16, QMSG_WIN32A ):
        switch ( WINPROC_MapMsg16To32A( msg->message, msg->wParam,
                                       &msg->message, &msg->wParam, &msg->lParam ) )
        {
        case 0:
            return TRUE;
        case 1:
            /* Pointer messages were mapped --> need to free allocated memory and fail */
            WINPROC_UnmapMsg16To32A( msg->hwnd, msg->message, msg->wParam, msg->lParam, 0 );
        default:
            return FALSE;
        }

    case MAKELONG( QMSG_WIN16, QMSG_WIN32W ):
        switch ( WINPROC_MapMsg16To32W( msg->hwnd, msg->message, msg->wParam,
                                       &msg->message, &msg->wParam, &msg->lParam ) )
        {
        case 0:
            return TRUE;
        case 1:
            /* Pointer messages were mapped --> need to free allocated memory and fail */
            WINPROC_UnmapMsg16To32W( msg->hwnd, msg->message, msg->wParam, msg->lParam, 0 );
        default:
            return FALSE;
        }

    case MAKELONG( QMSG_WIN32A, QMSG_WIN16 ):
        mp16.lParam = msg->lParam;
        switch ( WINPROC_MapMsg32ATo16( msg->hwnd, msg->message, msg->wParam,
                                        &msg16, &mp16.wParam, &mp16.lParam ) )
        {
        case 0:
            msg->message = msg16; 
            msg->wParam  = mp16.wParam;
            msg->lParam  = mp16.lParam;
            return TRUE;
        case 1:
            /* Pointer messages were mapped --> need to free allocated memory and fail */
            WINPROC_UnmapMsg32ATo16( msg->hwnd, msg->message, msg->wParam, msg->lParam, &mp16 );
        default:
            return FALSE;
        }

    case MAKELONG( QMSG_WIN32W, QMSG_WIN16 ):
        mp16.lParam = msg->lParam;
        switch ( WINPROC_MapMsg32WTo16( msg->hwnd, msg->message, msg->wParam,
                                        &msg16, &mp16.wParam, &mp16.lParam ) )
        {
        case 0:
            msg->message = msg16; 
            msg->wParam  = mp16.wParam;
            msg->lParam  = mp16.lParam;
            return TRUE;
        case 1:
            /* Pointer messages were mapped --> need to free allocated memory and fail */
            WINPROC_UnmapMsg32WTo16( msg->hwnd, msg->message, msg->wParam, msg->lParam, &mp16 );
        default:
            return FALSE;
        }

    case MAKELONG( QMSG_WIN32A, QMSG_WIN32W ):
        switch ( WINPROC_MapMsg32ATo32W( msg->hwnd, msg->message, msg->wParam, &msg->lParam ) )
        {
        case 0:
            return TRUE;
        case 1:
            /* Pointer messages were mapped --> need to free allocated memory and fail */
            WINPROC_UnmapMsg32ATo32W( msg->hwnd, msg->message, msg->wParam, msg->lParam );
        default:
            return FALSE;
        }

    case MAKELONG( QMSG_WIN32W, QMSG_WIN32A ):
        switch ( WINPROC_MapMsg32WTo32A( msg->hwnd, msg->message, msg->wParam, &msg->lParam ) )
        {
        case 0:
            return TRUE;
        case 1:
            /* Pointer messages were mapped --> need to free allocated memory and fail */
            WINPROC_UnmapMsg32WTo32A( msg->hwnd, msg->message, msg->wParam, msg->lParam );
        default:
            return FALSE;
        }

    default:    
        FIXME( "Invalid message type(s): %d / %d\n", srcType, dstType );
        return FALSE;
    }
}

/***********************************************************************
 *           MSG_PeekMessage
 */
static BOOL MSG_PeekMessage( int type, LPMSG msg, HWND hwnd, 
                             DWORD first, DWORD last, WORD flags, BOOL peek )
{
    int mask;
    MESSAGEQUEUE *msgQueue;
    HQUEUE16 hQueue;
    POINT16 pt16;
    int iWndsLocks;

    mask = QS_POSTMESSAGE | QS_SENDMESSAGE;  /* Always selected */
    if (first || last)
    {
        if ((first <= WM_KEYLAST) && (last >= WM_KEYFIRST)) mask |= QS_KEY;
        if ( ((first <= WM_MOUSELAST) && (last >= WM_MOUSEFIRST)) ||
             ((first <= WM_NCMOUSELAST) && (last >= WM_NCMOUSEFIRST)) ) 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_TIMER | QS_PAINT;

    if (IsTaskLocked16()) flags |= PM_NOYIELD;

    /* Never yield on Win32 threads */
    if (!THREAD_IsWin16(NtCurrentTeb())) flags |= PM_NOYIELD;

    iWndsLocks = WIN_SuspendWndsLock();

    while(1)
    {    
        QMSG *qmsg;
        
	hQueue   = GetFastQueue16();
        msgQueue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue );
        if (!msgQueue)
        {
            WIN_RestoreWndsLock(iWndsLocks);
            return FALSE;
        }
        msgQueue->changeBits = 0;

        /* First handle a message put by SendMessage() */

	while (msgQueue->wakeBits & QS_SENDMESSAGE)
            QUEUE_ReceiveMessage( msgQueue );

        /* Now handle a WM_QUIT message */

        if (msgQueue->wPostQMsg &&
	   (!first || WM_QUIT >= first) && 
	   (!last || WM_QUIT <= last) )
        {
            msg->hwnd    = hwnd;
            msg->message = WM_QUIT;
            msg->wParam  = msgQueue->wExitCode;
            msg->lParam  = 0;
            if (flags & PM_REMOVE) msgQueue->wPostQMsg = 0;
            break;
        }
    
        /* Now find a normal message */

  retry:
        if (((msgQueue->wakeBits & mask) & QS_POSTMESSAGE) &&
            ((qmsg = QUEUE_FindMsg( msgQueue, hwnd, first, last )) != 0))
        {
            /* Try to convert message to requested type */
            MSG tmpMsg = qmsg->msg;
            if ( !MSG_ConvertMsg( &tmpMsg, qmsg->type, type ) )
            {
                ERR( "Message of wrong type contains pointer parameters. Skipped!\n ");
                QUEUE_RemoveMsg( msgQueue, qmsg );
                goto retry;
            }

            *msg = tmpMsg;
            msgQueue->GetMessageTimeVal      = msg->time;
            CONV_POINT32TO16(&msg->pt, &pt16);
            msgQueue->GetMessagePosVal       = *(DWORD *)&pt16;
            msgQueue->GetMessageExtraInfoVal = qmsg->extraInfo;

            if (flags & PM_REMOVE) QUEUE_RemoveMsg( msgQueue, qmsg );
            break;
        }

        msgQueue->changeBits |= MSG_JournalPlayBackMsg();

        /* 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;
            CONV_POINT32TO16(&msg->pt, &pt16);
	    msgQueue->GetMessagePosVal       = *(DWORD *)&pt16;
	    msgQueue->GetMessageExtraInfoVal = 0;  /* Always 0 for now */
            break;
        }

        /* Check again for SendMessage */

 	while (msgQueue->wakeBits & QS_SENDMESSAGE)
            QUEUE_ReceiveMessage( msgQueue );

        /* Now find a WM_PAINT message */

	if ((msgQueue->wakeBits & mask) & QS_PAINT)
	{
	    WND* wndPtr;
	    msg->hwnd = WIN_FindWinToRepaint( hwnd , hQueue );
	    msg->message = WM_PAINT;
	    msg->wParam = 0;
	    msg->lParam = 0;

	    if ((wndPtr = WIN_FindWndPtr(msg->hwnd)))
	    {
                if( wndPtr->dwStyle & WS_MINIMIZE &&
                    (HICON) GetClassLongA(wndPtr->hwndSelf, GCL_HICON) )
                {
                    msg->message = WM_PAINTICON;
                    msg->wParam = 1;
                }

                if( !hwnd || msg->hwnd == hwnd || IsChild16(hwnd,msg->hwnd) )
                {
                    if( wndPtr->flags & WIN_INTERNAL_PAINT && !wndPtr->hrgnUpdate)
                    {
                        wndPtr->flags &= ~WIN_INTERNAL_PAINT;
                        QUEUE_DecPaintCount( hQueue );
                    }
                    WIN_ReleaseWndPtr(wndPtr);
                    break;
                }
                WIN_ReleaseWndPtr(wndPtr);
	    }
	}

        /* Check for timer messages, but yield first */

        if (!(flags & PM_NOYIELD))
        {
            UserYield16();
            while (msgQueue->wakeBits & QS_SENDMESSAGE)
                QUEUE_ReceiveMessage( msgQueue );
        }
	if ((msgQueue->wakeBits & mask) & QS_TIMER)
	{
	    if (TIMER_GetTimerMsg(msg, hwnd, hQueue, flags & PM_REMOVE)) break;
	}

        if (peek)
        {
            if (!(flags & PM_NOYIELD)) UserYield16();
            
            QUEUE_Unlock( msgQueue );
            WIN_RestoreWndsLock(iWndsLocks);
            return FALSE;
        }
        msgQueue->wakeMask = mask;
        QUEUE_WaitBits( mask, INFINITE );
        QUEUE_Unlock( msgQueue );
    }

    WIN_RestoreWndsLock(iWndsLocks);
    
    /* instead of unlocking queue for every break condition, all break
       condition will fall here */
    QUEUE_Unlock( msgQueue );
    
      /* We got a message */
    if (flags & PM_REMOVE)
    {
	WORD message = msg->message;

	if (message == WM_KEYDOWN || message == WM_SYSKEYDOWN)
	{
	    BYTE *p = &QueueKeyStateTable[msg->wParam & 0xff];

	    if (!(*p & 0x80))
		*p ^= 0x01;
	    *p |= 0x80;
	}
	else if (message == WM_KEYUP || message == WM_SYSKEYUP)
	    QueueKeyStateTable[msg->wParam & 0xff] &= ~0x80;
    }

    if (peek)
        return TRUE;

    else
        return (msg->message != WM_QUIT);
}

/***********************************************************************
 *           MSG_InternalGetMessage
 *
 * GetMessage() function for internal use. Behave like GetMessage(),
 * but also call message filters and optionally send WM_ENTERIDLE messages.
 * 'hwnd' must be the handle of the dialog or menu window.
 * 'code' is the message filter value (MSGF_??? codes).
 */
BOOL MSG_InternalGetMessage( int type, MSG *msg, HWND hwnd, HWND hwndOwner,
                             WPARAM code, WORD flags, BOOL sendIdle, BOOL* idleSent ) 
{
    for (;;)
    {
	if (sendIdle)
	{
	    if (!MSG_PeekMessage( type, msg, 0, 0, 0, flags, TRUE ))
	    {
		  /* No message present -> send ENTERIDLE and wait */
                if (IsWindow(hwndOwner))
		{
                    SendMessageA( hwndOwner, WM_ENTERIDLE,
                                   code, (LPARAM)hwnd );

		    if (idleSent!=NULL)
		      *idleSent=TRUE;
		}
		MSG_PeekMessage( type, msg, 0, 0, 0, flags, FALSE );
	    }
	}
	else  /* Always wait for a message */
	    MSG_PeekMessage( type, msg, 0, 0, 0, flags, FALSE );

        /* Call message filters */

        if (HOOK_IsHooked( WH_SYSMSGFILTER ) || HOOK_IsHooked( WH_MSGFILTER ))
        {
            MSG *pmsg = HeapAlloc( SystemHeap, 0, sizeof(MSG) );
            if (pmsg)
            {
                BOOL ret;
                *pmsg = *msg;
                ret = (HOOK_CallHooksA( WH_SYSMSGFILTER, code, 0,
                                          (LPARAM) pmsg ) ||
                       HOOK_CallHooksA( WH_MSGFILTER, code, 0,
                                          (LPARAM) pmsg ));
                       
                HeapFree( SystemHeap, 0, pmsg );
                if (ret)
                {
                    /* Message filtered -> remove it from the queue */
                    /* if it's still there. */
                    if (!(flags & PM_REMOVE))
                        MSG_PeekMessage( type, msg, 0, 0, 0, PM_REMOVE, TRUE );
                    continue;
                }
            }
        }

        return (msg->message != WM_QUIT);
    }
}


/***********************************************************************
 *         PeekMessage32_16   (USER.819)
 */
BOOL16 WINAPI PeekMessage32_16( LPMSG16_32 lpmsg16_32, HWND16 hwnd,
                                UINT16 first, UINT16 last, UINT16 flags, 
                                BOOL16 wHaveParamHigh )
{
    BOOL ret;
    MSG msg;

    ret = MSG_PeekMessage( QMSG_WIN16, &msg, hwnd, first, last, flags, TRUE );

    lpmsg16_32->msg.hwnd    = msg.hwnd;
    lpmsg16_32->msg.message = msg.message;
    lpmsg16_32->msg.wParam  = LOWORD(msg.wParam);
    lpmsg16_32->msg.lParam  = msg.lParam;
    lpmsg16_32->msg.time    = msg.time;
    lpmsg16_32->msg.pt.x    = (INT16)msg.pt.x;
    lpmsg16_32->msg.pt.y    = (INT16)msg.pt.y;

    if ( wHaveParamHigh )
        lpmsg16_32->wParamHigh = HIWORD(msg.wParam);

    return ret;
}

/***********************************************************************
 *           PeekMessage16   (USER.109)
 */
BOOL16 WINAPI PeekMessage16( LPMSG16 lpmsg, HWND16 hwnd, 
                             UINT16 first, UINT16 last, UINT16 flags )
{
    return PeekMessage32_16( (LPMSG16_32)lpmsg, hwnd, first, last, flags, FALSE );
}

/***********************************************************************
 *         PeekMessageA
 */
BOOL WINAPI PeekMessageA( LPMSG lpmsg, HWND hwnd,
                          UINT min, UINT max, UINT wRemoveMsg)
{
    return MSG_PeekMessage( QMSG_WIN32A, lpmsg, hwnd, min, max, wRemoveMsg, TRUE );
}

/***********************************************************************
 *         PeekMessageW             Check queue for messages
 *
 * Checks for a message in the thread's queue, filtered as for
 * GetMessage(). Returns immediately whether a message is available
 * or not.
 *
 * Whether a retrieved message is removed from the queue is set by the
 * _wRemoveMsg_ flags, which should be one of the following values:
 *
 *    PM_NOREMOVE    Do not remove the message from the queue. 
 *
 *    PM_REMOVE      Remove the message from the queue.
 *
 * In addition, PM_NOYIELD may be combined into _wRemoveMsg_ to
 * request that the system not yield control during PeekMessage();
 * however applications may not rely on scheduling behavior.
 * 
 * RETURNS
 *
 *  Nonzero if a message is available and is retrieved, zero otherwise.
 *
 * CONFORMANCE
 *
 * ECMA-234, Win32
 *
 */
BOOL WINAPI PeekMessageW( 
  LPMSG lpmsg,    /* buffer to receive message */
  HWND hwnd,      /* restrict to messages for hwnd */
  UINT min,       /* minimum message to receive */
  UINT max,       /* maximum message to receive */
  UINT wRemoveMsg /* removal flags */ 
) 
{
    return MSG_PeekMessage( QMSG_WIN32W, lpmsg, hwnd, min, max, wRemoveMsg, TRUE );
}


/***********************************************************************
 *          GetMessage32_16   (USER.820)
 */
BOOL16 WINAPI GetMessage32_16( SEGPTR msg16_32, HWND16 hWnd, UINT16 first,
                               UINT16 last, BOOL16 wHaveParamHigh )
{
    MSG32_16 *lpmsg16_32 = (MSG32_16 *)PTR_SEG_TO_LIN(msg16_32);
    MSG msg;

    MSG_PeekMessage( QMSG_WIN16, &msg, hWnd, first, last, PM_REMOVE, FALSE );

    lpmsg16_32->msg.hwnd    = msg.hwnd;
    lpmsg16_32->msg.message = msg.message;
    lpmsg16_32->msg.wParam  = LOWORD(msg.wParam);
    lpmsg16_32->msg.lParam  = msg.lParam;
    lpmsg16_32->msg.time    = msg.time;
    lpmsg16_32->msg.pt.x    = (INT16)msg.pt.x;
    lpmsg16_32->msg.pt.y    = (INT16)msg.pt.y;

    if ( wHaveParamHigh )
        lpmsg16_32->wParamHigh = HIWORD(msg.wParam);

    TRACE( "message %04x, hwnd %04x, filter(%04x - %04x)\n",
           lpmsg16_32->msg.message, hWnd, first, last );

    HOOK_CallHooks16( WH_GETMESSAGE, HC_ACTION, 0, (LPARAM)msg16_32 );
    return lpmsg16_32->msg.message != WM_QUIT;
}

/***********************************************************************
 *           GetMessage16   (USER.108)
 */
BOOL16 WINAPI GetMessage16( SEGPTR msg, HWND16 hwnd, UINT16 first, UINT16 last)
{
    return GetMessage32_16( msg, hwnd, first, last, FALSE );
}

/***********************************************************************
 *          GetMessageA   (USER32.270)
 */
BOOL WINAPI GetMessageA( MSG *lpmsg, HWND hwnd, UINT min, UINT max )
{
    MSG_PeekMessage( QMSG_WIN32A, lpmsg, hwnd, min, max, PM_REMOVE, FALSE );
    
    TRACE( "message %04x, hwnd %04x, filter(%04x - %04x)\n", 
           lpmsg->message, hwnd, min, max );
    
    HOOK_CallHooksA( WH_GETMESSAGE, HC_ACTION, 0, (LPARAM)lpmsg );
    return lpmsg->message != WM_QUIT;
}

/***********************************************************************
 *          GetMessageW   (USER32.274) Retrieve next message
 *
 * GetMessage retrieves the next event from the calling thread's
 * queue and deposits it in *lpmsg.
 *
 * If _hwnd_ is not NULL, only messages for window _hwnd_ and its
 * children as specified by IsChild() are retrieved. If _hwnd_ is NULL
 * all application messages are retrieved.
 *
 * _min_ and _max_ specify the range of messages of interest. If
 * min==max==0, no filtering is performed. Useful examples are
 * WM_KEYFIRST and WM_KEYLAST to retrieve keyboard input, and
 * WM_MOUSEFIRST and WM_MOUSELAST to retrieve mouse input.
 *
 * WM_PAINT messages are not removed from the queue; they remain until
 * processed. Other messages are removed from the queue.
 *
 * RETURNS
 *
 * -1 on error, 0 if message is WM_QUIT, nonzero otherwise.
 *
 * CONFORMANCE
 *
 * ECMA-234, Win32
 * 
 */
BOOL WINAPI GetMessageW(
  MSG* lpmsg, /* buffer to receive message */
  HWND hwnd,  /* restrict to messages for hwnd */
  UINT min,   /* minimum message to receive */
  UINT max    /* maximum message to receive */
) 
{
    MSG_PeekMessage( QMSG_WIN32W, lpmsg, hwnd, min, max, PM_REMOVE, FALSE );
    
    TRACE( "message %04x, hwnd %04x, filter(%04x - %04x)\n", 
           lpmsg->message, hwnd, min, max );
    
    HOOK_CallHooksW( WH_GETMESSAGE, HC_ACTION, 0, (LPARAM)lpmsg );
    return lpmsg->message != WM_QUIT;
}

/***********************************************************************
 *           MSG_PostToQueue
 */
static BOOL MSG_PostToQueue( HQUEUE16 hQueue, int type, HWND hwnd, 
                             UINT message, WPARAM wParam, LPARAM lParam )
{
    MSG msg;

    if ( !hQueue ) return FALSE;

    msg.hwnd    = hwnd;
    msg.message = message;
    msg.wParam  = wParam;
    msg.lParam  = lParam;
    msg.time    = GetTickCount();
    msg.pt.x    = 0;
    msg.pt.y    = 0;

    return QUEUE_AddMsg( hQueue, type, &msg, 0 );
}

/***********************************************************************
 *           MSG_PostMessage
 */
static BOOL MSG_PostMessage( int type, HWND hwnd, UINT message, 
                             WPARAM wParam, LPARAM lParam )
{
    HQUEUE16 hQueue;
    WND *wndPtr;

    if (hwnd == HWND_BROADCAST)
    {
        WND *pDesktop = WIN_GetDesktop();
        TRACE("HWND_BROADCAST !\n");
        
        for (wndPtr=WIN_LockWndPtr(pDesktop->child); wndPtr; WIN_UpdateWndPtr(&wndPtr,wndPtr->next))
        {
            if (wndPtr->dwStyle & WS_POPUP || wndPtr->dwStyle & WS_CAPTION)
            {
                TRACE("BROADCAST Message to hWnd=%04x m=%04X w=%04X l=%08lX !\n",
                      wndPtr->hwndSelf, message, wParam, lParam);
                MSG_PostToQueue( wndPtr->hmemTaskQ, type, 
                                 wndPtr->hwndSelf, message, wParam, lParam );
            }
        }
        WIN_ReleaseDesktop();
        TRACE("End of HWND_BROADCAST !\n");
        return TRUE;
    }

    wndPtr = WIN_FindWndPtr( hwnd );
    hQueue = wndPtr? wndPtr->hmemTaskQ : 0;
    WIN_ReleaseWndPtr(wndPtr);

    return MSG_PostToQueue( hQueue, type, hwnd, message, wParam, lParam );
}

/***********************************************************************
 *           PostMessage16   (USER.110)
 */
BOOL16 WINAPI PostMessage16( HWND16 hwnd, UINT16 message, WPARAM16 wParam,
                             LPARAM lParam )
{
    return (BOOL16) MSG_PostMessage( QMSG_WIN16, hwnd, message, wParam, lParam );
}

/***********************************************************************
 *           PostMessageA   (USER32.419)
 */
BOOL WINAPI PostMessageA( HWND hwnd, UINT message, WPARAM wParam,
                          LPARAM lParam )
{
    return MSG_PostMessage( QMSG_WIN32A, hwnd, message, wParam, lParam );
}

/***********************************************************************
 *           PostMessageW   (USER32.420)
 */
BOOL WINAPI PostMessageW( HWND hwnd, UINT message, WPARAM wParam,
                          LPARAM lParam )
{
    return MSG_PostMessage( QMSG_WIN32W, hwnd, message, wParam, lParam );
}

/***********************************************************************
 *           PostAppMessage16   (USER.116)
 */
BOOL16 WINAPI PostAppMessage16( HTASK16 hTask, UINT16 message, 
                                WPARAM16 wParam, LPARAM lParam )
{
    return MSG_PostToQueue( GetTaskQueue16(hTask), QMSG_WIN16, 
                            0, message, wParam, lParam );
}

/**********************************************************************
 *           PostThreadMessageA    (USER32.422)
 */
BOOL WINAPI PostThreadMessageA( DWORD idThread, UINT message,
                                WPARAM wParam, LPARAM lParam )
{
    return MSG_PostToQueue( GetThreadQueue16(idThread), QMSG_WIN32A, 
                            0, message, wParam, lParam );
}

/**********************************************************************
 *           PostThreadMessageW    (USER32.423)
 */
BOOL WINAPI PostThreadMessageW( DWORD idThread, UINT message,
                                 WPARAM wParam, LPARAM lParam )
{
    return MSG_PostToQueue( GetThreadQueue16(idThread), QMSG_WIN32W, 
                            0, message, wParam, lParam );
}


/************************************************************************
 *	     MSG_CallWndProcHook32
 */
static void  MSG_CallWndProcHook( LPMSG pmsg, BOOL bUnicode )
{
   CWPSTRUCT cwp;

   cwp.lParam = pmsg->lParam;
   cwp.wParam = pmsg->wParam;
   cwp.message = pmsg->message;
   cwp.hwnd = pmsg->hwnd;

   if (bUnicode) HOOK_CallHooksW(WH_CALLWNDPROC, HC_ACTION, 1, (LPARAM)&cwp);
   else HOOK_CallHooksA( WH_CALLWNDPROC, HC_ACTION, 1, (LPARAM)&cwp );

   pmsg->lParam = cwp.lParam;
   pmsg->wParam = cwp.wParam;
   pmsg->message = cwp.message;
   pmsg->hwnd = cwp.hwnd;
}


/***********************************************************************
 *           MSG_SendMessage
 *
 * return values: 0 if timeout occurs
 *                1 otherwise
 */
static LRESULT MSG_SendMessage( HWND hwnd, UINT msg, WPARAM wParam,
                         LPARAM lParam, DWORD timeout, WORD flags,
                         LRESULT *pRes)
{
    WND * wndPtr = 0;
    WND **list, **ppWnd;
    LRESULT ret = 1;

    *pRes = 0;

    if (hwnd == HWND_BROADCAST|| hwnd == HWND_TOPMOST)
    {
        *pRes = 1;
        
        if (!(list = WIN_BuildWinArray( WIN_GetDesktop(), 0, NULL )))
        {
            WIN_ReleaseDesktop();
            return 1;
        }
        WIN_ReleaseDesktop();

        TRACE("HWND_BROADCAST !\n");
        for (ppWnd = list; *ppWnd; ppWnd++)
        {
            WIN_UpdateWndPtr(&wndPtr,*ppWnd);
            if (!IsWindow(wndPtr->hwndSelf)) continue;
            if (wndPtr->dwStyle & WS_POPUP || wndPtr->dwStyle & WS_CAPTION)
            {
                TRACE("BROADCAST Message to hWnd=%04x m=%04X w=%04lX l=%08lX !\n",
                      wndPtr->hwndSelf, msg, (DWORD)wParam, lParam);
                MSG_SendMessage( wndPtr->hwndSelf, msg, wParam, lParam,
                               timeout, flags, pRes);
            }
        }
        WIN_ReleaseWndPtr(wndPtr);
        WIN_ReleaseWinArray(list);
        TRACE("End of HWND_BROADCAST !\n");
        return 1;
    }

    if (HOOK_IsHooked( WH_CALLWNDPROC ))
    {
        if (flags & SMSG_UNICODE)
            MSG_CallWndProcHook( (LPMSG)&hwnd, TRUE);
        else if (flags & SMSG_WIN32)
            MSG_CallWndProcHook( (LPMSG)&hwnd, FALSE);
        else
        {
	LPCWPSTRUCT16 pmsg;

	if ((pmsg = SEGPTR_NEW(CWPSTRUCT16)))
	{
                pmsg->hwnd   = hwnd & 0xffff;
                pmsg->message= msg & 0xffff;
                pmsg->wParam = wParam & 0xffff;
	    pmsg->lParam = lParam;
	    HOOK_CallHooks16( WH_CALLWNDPROC, HC_ACTION, 1,
			      (LPARAM)SEGPTR_GET(pmsg) );
	    hwnd   = pmsg->hwnd;
	    msg    = pmsg->message;
	    wParam = pmsg->wParam;
	    lParam = pmsg->lParam;
	    SEGPTR_FREE( pmsg );
	}
    }
    }

    if (!(wndPtr = WIN_FindWndPtr( hwnd )))
    {
        WARN("invalid hwnd %04x\n", hwnd );
        return 0;
    }
    if (QUEUE_IsExitingQueue(wndPtr->hmemTaskQ))
    {
        ret = 0;  /* Don't send anything if the task is dying */
        goto END;
    }
    if (flags & SMSG_WIN32)
        SPY_EnterMessage( SPY_SENDMESSAGE, hwnd, msg, wParam, lParam );
    else
    SPY_EnterMessage( SPY_SENDMESSAGE16, hwnd, msg, wParam, lParam );

    if (wndPtr->hmemTaskQ != GetFastQueue16())
        ret = MSG_SendMessageInterThread( wndPtr->hmemTaskQ, hwnd, msg,
                                          wParam, lParam, timeout, flags, pRes );
    else
    {
        /* Call the right CallWindowProc flavor */
        if (flags & SMSG_UNICODE)
            *pRes = CallWindowProcW( (WNDPROC)wndPtr->winproc,
                                     hwnd, msg, wParam, lParam );
        else if (flags & SMSG_WIN32)
            *pRes = CallWindowProcA( (WNDPROC)wndPtr->winproc,
                                hwnd, msg, wParam, lParam );
        else
            *pRes = CallWindowProc16( (WNDPROC16)wndPtr->winproc,
                                    (HWND16) hwnd, (UINT16) msg,
                                    (WPARAM16) wParam, lParam );
    }

    if (flags & SMSG_WIN32)
        SPY_ExitMessage( SPY_RESULT_OK, hwnd, msg, *pRes );
    else
    SPY_ExitMessage( SPY_RESULT_OK16, hwnd, msg, *pRes );
END:
    WIN_ReleaseWndPtr(wndPtr);
    return ret;
}


/***********************************************************************
 *           SendMessage16   (USER.111)
 */
LRESULT WINAPI SendMessage16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam,
                              LPARAM lParam)
{
    LRESULT res;
    MSG_SendMessage(hwnd, msg, wParam, lParam, INFINITE, 0, &res);
    return res;
}


/***********************************************************************
 *           SendMessageA   (USER32.454)
 */
LRESULT WINAPI SendMessageA( HWND hwnd, UINT msg, WPARAM wParam,
                               LPARAM lParam )
        {
    LRESULT res;

    MSG_SendMessage(hwnd, msg, wParam, lParam, INFINITE,
                    SMSG_WIN32, &res);

    return res;
}


/***********************************************************************
 *           SendMessageW   (USER32.459)  Send Window Message
 *
 *  Sends a message to the window procedure of the specified window.
 *  SendMessage() will not return until the called window procedure
 *  either returns or calls ReplyMessage().
 *
 *  Use PostMessage() to send message and return immediately. A window
 *  procedure may use InSendMessage() to detect
 *  SendMessage()-originated messages.
 *
 *  Applications which communicate via HWND_BROADCAST may use
 *  RegisterWindowMessage() to obtain a unique message to avoid conflicts
 *  with other applications.
 *
 * CONFORMANCE
 * 
 *  ECMA-234, Win32 
 */
LRESULT WINAPI SendMessageW( 
  HWND hwnd,    /* Window to send message to. If HWND_BROADCAST, 
                 the message will be sent to all top-level windows. */

  UINT msg,      /* message */
  WPARAM wParam, /* message parameter */
  LPARAM lParam    /* additional message parameter */
) {
    LRESULT res;

    MSG_SendMessage(hwnd, msg, wParam, lParam, INFINITE,
                    SMSG_WIN32 | SMSG_UNICODE, &res);

    return res;
}


/***********************************************************************
 *           SendMessageTimeout16    (not a WINAPI)
 */
LRESULT WINAPI SendMessageTimeout16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam,
				     LPARAM lParam, UINT16 flags,
				     UINT16 timeout, LPWORD resultp)
{
    LRESULT ret;
    LRESULT msgRet;
    
    /* FIXME: need support for SMTO_BLOCK */
    
    ret = MSG_SendMessage(hwnd, msg, wParam, lParam, timeout, 0, &msgRet);
    if (resultp) *resultp = (WORD) msgRet;
    return ret;
}


/***********************************************************************
 *           SendMessageTimeoutA   (USER32.457)
 */
LRESULT WINAPI SendMessageTimeoutA( HWND hwnd, UINT msg, WPARAM wParam,
				      LPARAM lParam, UINT flags,
				      UINT timeout, LPDWORD resultp)
{
    LRESULT ret;
    LRESULT msgRet;

    /* FIXME: need support for SMTO_BLOCK */
    
    ret = MSG_SendMessage(hwnd, msg, wParam, lParam, timeout, SMSG_WIN32,
                          &msgRet);

    if (resultp) *resultp = (DWORD) msgRet;
    return ret;
}


/***********************************************************************
 *           SendMessageTimeoutW   (USER32.458)
 */
LRESULT WINAPI SendMessageTimeoutW( HWND hwnd, UINT msg, WPARAM wParam,
				      LPARAM lParam, UINT flags,
				      UINT timeout, LPDWORD resultp)
{
    LRESULT ret;
    LRESULT msgRet;
    
    /* FIXME: need support for SMTO_BLOCK */

    ret = MSG_SendMessage(hwnd, msg, wParam, lParam, timeout,
                          SMSG_WIN32 | SMSG_UNICODE, &msgRet);
    
    if (resultp) *resultp = (DWORD) msgRet;
    return ret;
}


/***********************************************************************
 *  WaitMessage    (USER.112) (USER32.578)  Suspend thread pending messages
 *
 * WaitMessage() suspends a thread until events appear in the thread's
 * queue.
 *
 * BUGS
 *
 * Is supposed to return BOOL under Win32.
 *
 * Thread-local message queues are not supported.
 *
 * CONFORMANCE
 *
 * ECMA-234, Win32
 * 
 */
void WINAPI WaitMessage( void )
{
    QUEUE_WaitBits( QS_ALLINPUT, INFINITE );
}

/***********************************************************************
 *           MsgWaitForMultipleObjects    (USER32.400)
 */
DWORD WINAPI MsgWaitForMultipleObjects( DWORD nCount, HANDLE *pHandles,
                                        BOOL fWaitAll, DWORD dwMilliseconds,
                                        DWORD dwWakeMask )
{
    DWORD i;
    HANDLE handles[MAXIMUM_WAIT_OBJECTS];
    DWORD ret;
    PDB * pdb = PROCESS_Current();

    HQUEUE16 hQueue = GetFastQueue16();
    MESSAGEQUEUE *msgQueue = (MESSAGEQUEUE *)QUEUE_Lock( hQueue );
    if (!msgQueue) return WAIT_FAILED;

    if (nCount > MAXIMUM_WAIT_OBJECTS-1)
    {
        SetLastError( ERROR_INVALID_PARAMETER );
        QUEUE_Unlock( msgQueue );
        return WAIT_FAILED;
    }

    msgQueue->changeBits = 0;
    msgQueue->wakeMask = dwWakeMask;

    if (THREAD_IsWin16(NtCurrentTeb()))
    {
      /*
       * This is a temporary solution to a big problem.
       * You see, the main thread of all Win32 programs is created as a 16 bit
       * task. This means that if you want on an event using Win32 synchronization
       * methods, the 16 bit scheduler is stopped and things might just stop happening.
       * This implements a semi-busy loop that checks the handles to wait on and
       * also the message queue. When either one is ready, the wait function returns.
       *
       * This will all go away when the real Win32 threads are implemented for all
       * the threads of an applications. Including the main thread.
       */
      DWORD curTime = GetCurrentTime();

      do
      {
	/*
	 * Check the handles in the list.
	 */
	SetEvent ( pdb->idle_event );
	ret = WaitForMultipleObjects(nCount, pHandles, fWaitAll, 5L);

	/*
	 * If the handles have been triggered, return.
	 */
	if (ret != WAIT_TIMEOUT)
	  break;

	/*
	 * Then, let the 16 bit scheduler do it's thing.
	 */
	Yield16();

	/*
	 * If a message matching the wait mask has arrived, return.
	 */
	if (msgQueue->changeBits & dwWakeMask)
	{
	  ret = nCount;
	  break;
	}

	/*
	 * And continue doing this until we hit the timeout.
	 */
      } while ((dwMilliseconds == INFINITE) || (GetCurrentTime()-curTime < dwMilliseconds) );
    }
    else
    {
    /* Add the thread event to the handle list */
      for (i = 0; i < nCount; i++)
	handles[i] = pHandles[i];
      handles[nCount] = msgQueue->hEvent;

      if ( pdb->main_queue == INVALID_HANDLE_VALUE16 ) pdb->main_queue = hQueue;
      if ( pdb->main_queue == hQueue ) SetEvent ( pdb->idle_event );
      ret = WaitForMultipleObjects( nCount+1, handles, fWaitAll, dwMilliseconds );
      if ( pdb->main_queue == hQueue ) ResetEvent ( pdb->idle_event );

    } 

    QUEUE_Unlock( msgQueue );
    
    return ret;
}



struct accent_char
{
    BYTE ac_accent;
    BYTE ac_char;
    BYTE ac_result;
};

static const struct accent_char accent_chars[] =
{
/* A good idea should be to read /usr/X11/lib/X11/locale/iso8859-x/Compose */
    {'`', 'A', '\300'},  {'`', 'a', '\340'},
    {'\'', 'A', '\301'}, {'\'', 'a', '\341'},
    {'^', 'A', '\302'},  {'^', 'a', '\342'},
    {'~', 'A', '\303'},  {'~', 'a', '\343'},
    {'"', 'A', '\304'},  {'"', 'a', '\344'},
    {'O', 'A', '\305'},  {'o', 'a', '\345'},
    {'0', 'A', '\305'},  {'0', 'a', '\345'},
    {'A', 'A', '\305'},  {'a', 'a', '\345'},
    {'A', 'E', '\306'},  {'a', 'e', '\346'},
    {',', 'C', '\307'},  {',', 'c', '\347'},
    {'`', 'E', '\310'},  {'`', 'e', '\350'},
    {'\'', 'E', '\311'}, {'\'', 'e', '\351'},
    {'^', 'E', '\312'},  {'^', 'e', '\352'},
    {'"', 'E', '\313'},  {'"', 'e', '\353'},
    {'`', 'I', '\314'},  {'`', 'i', '\354'},
    {'\'', 'I', '\315'}, {'\'', 'i', '\355'},
    {'^', 'I', '\316'},  {'^', 'i', '\356'},
    {'"', 'I', '\317'},  {'"', 'i', '\357'},
    {'-', 'D', '\320'},  {'-', 'd', '\360'},
    {'~', 'N', '\321'},  {'~', 'n', '\361'},
    {'`', 'O', '\322'},  {'`', 'o', '\362'},
    {'\'', 'O', '\323'}, {'\'', 'o', '\363'},
    {'^', 'O', '\324'},  {'^', 'o', '\364'},
    {'~', 'O', '\325'},  {'~', 'o', '\365'},
    {'"', 'O', '\326'},  {'"', 'o', '\366'},
    {'/', 'O', '\330'},  {'/', 'o', '\370'},
    {'`', 'U', '\331'},  {'`', 'u', '\371'},
    {'\'', 'U', '\332'}, {'\'', 'u', '\372'},
    {'^', 'U', '\333'},  {'^', 'u', '\373'},
    {'"', 'U', '\334'},  {'"', 'u', '\374'},
    {'\'', 'Y', '\335'}, {'\'', 'y', '\375'},
    {'T', 'H', '\336'},  {'t', 'h', '\376'},
    {'s', 's', '\337'},  {'"', 'y', '\377'},
    {'s', 'z', '\337'},  {'i', 'j', '\377'},
	/* iso-8859-2 uses this */
    {'<', 'L', '\245'},  {'<', 'l', '\265'},	/* caron */
    {'<', 'S', '\251'},  {'<', 's', '\271'},
    {'<', 'T', '\253'},  {'<', 't', '\273'},
    {'<', 'Z', '\256'},  {'<', 'z', '\276'},
    {'<', 'C', '\310'},  {'<', 'c', '\350'},
    {'<', 'E', '\314'},  {'<', 'e', '\354'},
    {'<', 'D', '\317'},  {'<', 'd', '\357'},
    {'<', 'N', '\322'},  {'<', 'n', '\362'},
    {'<', 'R', '\330'},  {'<', 'r', '\370'},
    {';', 'A', '\241'},  {';', 'a', '\261'},	/* ogonek */
    {';', 'E', '\312'},  {';', 'e', '\332'},
    {'\'', 'Z', '\254'}, {'\'', 'z', '\274'},	/* acute */
    {'\'', 'R', '\300'}, {'\'', 'r', '\340'},
    {'\'', 'L', '\305'}, {'\'', 'l', '\345'},
    {'\'', 'C', '\306'}, {'\'', 'c', '\346'},
    {'\'', 'N', '\321'}, {'\'', 'n', '\361'},
/*  collision whith S, from iso-8859-9 !!! */
    {',', 'S', '\252'},  {',', 's', '\272'},	/* cedilla */
    {',', 'T', '\336'},  {',', 't', '\376'},
    {'.', 'Z', '\257'},  {'.', 'z', '\277'},	/* dot above */
    {'/', 'L', '\243'},  {'/', 'l', '\263'},	/* slash */
    {'/', 'D', '\320'},  {'/', 'd', '\360'},
    {'(', 'A', '\303'},  {'(', 'a', '\343'},	/* breve */
    {'\275', 'O', '\325'}, {'\275', 'o', '\365'},	/* double acute */
    {'\275', 'U', '\334'}, {'\275', 'u', '\374'},
    {'0', 'U', '\332'},  {'0', 'u', '\372'},	/* ring above */
	/* iso-8859-3 uses this */
    {'/', 'H', '\241'},  {'/', 'h', '\261'},	/* slash */
    {'>', 'H', '\246'},  {'>', 'h', '\266'},	/* circumflex */
    {'>', 'J', '\254'},  {'>', 'j', '\274'},
    {'>', 'C', '\306'},  {'>', 'c', '\346'},
    {'>', 'G', '\330'},  {'>', 'g', '\370'},
    {'>', 'S', '\336'},  {'>', 's', '\376'},
/*  collision whith G( from iso-8859-9 !!!   */
    {'(', 'G', '\253'},  {'(', 'g', '\273'},	/* breve */
    {'(', 'U', '\335'},  {'(', 'u', '\375'},
/*  collision whith I. from iso-8859-3 !!!   */
    {'.', 'I', '\251'},  {'.', 'i', '\271'},	/* dot above */
    {'.', 'C', '\305'},  {'.', 'c', '\345'},
    {'.', 'G', '\325'},  {'.', 'g', '\365'},
	/* iso-8859-4 uses this */
    {',', 'R', '\243'},  {',', 'r', '\263'},	/* cedilla */
    {',', 'L', '\246'},  {',', 'l', '\266'},
    {',', 'G', '\253'},  {',', 'g', '\273'},
    {',', 'N', '\321'},  {',', 'n', '\361'},
    {',', 'K', '\323'},  {',', 'k', '\363'},
    {'~', 'I', '\245'},  {'~', 'i', '\265'},	/* tilde */
    {'-', 'E', '\252'},  {'-', 'e', '\272'},	/* macron */
    {'-', 'A', '\300'},  {'-', 'a', '\340'},
    {'-', 'I', '\317'},  {'-', 'i', '\357'},
    {'-', 'O', '\322'},  {'-', 'o', '\362'},
    {'-', 'U', '\336'},  {'-', 'u', '\376'},
    {'/', 'T', '\254'},  {'/', 't', '\274'},	/* slash */
    {'.', 'E', '\314'},  {'.', 'e', '\344'},	/* dot above */
    {';', 'I', '\307'},  {';', 'i', '\347'},	/* ogonek */
    {';', 'U', '\331'},  {';', 'u', '\371'},
	/* iso-8859-9 uses this */
	/* iso-8859-9 has really bad choosen G( S, and I. as they collide
	 * whith the same letters on other iso-8859-x (that is they are on
	 * different places :-( ), if you use turkish uncomment these and
	 * comment out the lines in iso-8859-2 and iso-8859-3 sections
	 * FIXME: should be dynamic according to chosen language
	 *	  if/when Wine has turkish support.  
	 */ 
/*  collision whith G( from iso-8859-3 !!!   */
/*  {'(', 'G', '\320'},  {'(', 'g', '\360'}, */	/* breve */
/*  collision whith S, from iso-8859-2 !!! */
/*  {',', 'S', '\336'},  {',', 's', '\376'}, */	/* cedilla */
/*  collision whith I. from iso-8859-3 !!!   */
/*  {'.', 'I', '\335'},  {'.', 'i', '\375'}, */	/* dot above */
};


/***********************************************************************
 *           MSG_DoTranslateMessage
 *
 * Implementation of TranslateMessage.
 *
 * TranslateMessage translates virtual-key messages into character-messages,
 * as follows :
 * WM_KEYDOWN/WM_KEYUP combinations produce a WM_CHAR or WM_DEADCHAR message.
 * ditto replacing WM_* with WM_SYS*
 * This produces WM_CHAR messages only for keys mapped to ASCII characters
 * by the keyboard driver.
 */
static BOOL MSG_DoTranslateMessage( UINT message, HWND hwnd,
                                      WPARAM wParam, LPARAM lParam )
{
    static int dead_char;
    BYTE wp[2];
    
    if (message != WM_MOUSEMOVE && message != WM_TIMER)
        TRACE("(%s, %04X, %08lX)\n",
		     SPY_GetMsgName(message), wParam, lParam );
    if(message >= WM_KEYFIRST && message <= WM_KEYLAST)
        TRACE_(key)("(%s, %04X, %08lX)\n",
		     SPY_GetMsgName(message), wParam, lParam );

    if ((message != WM_KEYDOWN) && (message != WM_SYSKEYDOWN))	return FALSE;

    TRACE_(key)("Translating key %04X, scancode %04X\n",
                 wParam, HIWORD(lParam) );

    /* FIXME : should handle ToAscii yielding 2 */
    switch (ToAscii(wParam, HIWORD(lParam),
                      QueueKeyStateTable,(LPWORD)wp, 0)) 
    {
    case 1 :
        message = (message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
        /* Should dead chars handling go in ToAscii ? */
        if (dead_char)
        {
            int i;

            if (wp[0] == ' ') wp[0] =  dead_char;
            if (dead_char == 0xa2) dead_char = '(';
            else if (dead_char == 0xa8) dead_char = '"';
	    else if (dead_char == 0xb2) dead_char = ';';
            else if (dead_char == 0xb4) dead_char = '\'';
            else if (dead_char == 0xb7) dead_char = '<';
            else if (dead_char == 0xb8) dead_char = ',';
            else if (dead_char == 0xff) dead_char = '.';
            for (i = 0; i < sizeof(accent_chars)/sizeof(accent_chars[0]); i++)
                if ((accent_chars[i].ac_accent == dead_char) &&
                    (accent_chars[i].ac_char == wp[0]))
                {
                    wp[0] = accent_chars[i].ac_result;
                    break;
                }
            dead_char = 0;
        }
        TRACE_(key)("1 -> PostMessage(%s)\n", SPY_GetMsgName(message));
        PostMessage16( hwnd, message, wp[0], lParam );
        return TRUE;

    case -1 :
        message = (message == WM_KEYDOWN) ? WM_DEADCHAR : WM_SYSDEADCHAR;
        dead_char = wp[0];
        TRACE_(key)("-1 -> PostMessage(%s)\n",
                     SPY_GetMsgName(message));
        PostMessage16( hwnd, message, wp[0], lParam );
        return TRUE;
    }
    return FALSE;
}


/***********************************************************************
 *           TranslateMessage16   (USER.113)
 */
BOOL16 WINAPI TranslateMessage16( const MSG16 *msg )
{
    return MSG_DoTranslateMessage( msg->message, msg->hwnd,
                                   msg->wParam, msg->lParam );
}


/***********************************************************************
 *           TranslateMessage32   (USER.821)
 */
BOOL16 WINAPI TranslateMessage32_16( const MSG32_16 *msg, BOOL16 wHaveParamHigh )
{
    WPARAM wParam;

    if (wHaveParamHigh)
        wParam = MAKELONG(msg->msg.wParam, msg->wParamHigh);
    else
        wParam = (WPARAM)msg->msg.wParam;

    return MSG_DoTranslateMessage( msg->msg.message, msg->msg.hwnd,
                                   wParam, msg->msg.lParam );
}

/***********************************************************************
 *           TranslateMessage   (USER32.556)
 */
BOOL WINAPI TranslateMessage( const MSG *msg )
{
    return MSG_DoTranslateMessage( msg->message, msg->hwnd,
                                   msg->wParam, msg->lParam );
}


/***********************************************************************
 *           DispatchMessage16   (USER.114)
 */
LONG WINAPI DispatchMessage16( const MSG16* msg )
{
    WND * wndPtr;
    LONG retval;
    int painting;
    
      /* Process timer messages */
    if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
    {
	if (msg->lParam)
        {
	    return CallWindowProc16( (WNDPROC16)msg->lParam, msg->hwnd,
                                   msg->message, msg->wParam, GetTickCount() );
        }
    }

    if (!msg->hwnd) return 0;
    if (!(wndPtr = WIN_FindWndPtr( msg->hwnd ))) return 0;
    if (!wndPtr->winproc)
    {
        retval = 0;
        goto END;
    }
    painting = (msg->message == WM_PAINT);
    if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;

    SPY_EnterMessage( SPY_DISPATCHMESSAGE16, msg->hwnd, msg->message,
                      msg->wParam, msg->lParam );
    retval = CallWindowProc16( (WNDPROC16)wndPtr->winproc,
                               msg->hwnd, msg->message,
                               msg->wParam, msg->lParam );
    SPY_ExitMessage( SPY_RESULT_OK16, msg->hwnd, msg->message, retval );

    WIN_ReleaseWndPtr(wndPtr);
    wndPtr = WIN_FindWndPtr(msg->hwnd);
    if (painting && wndPtr &&
        (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 */
        ValidateRect( msg->hwnd, NULL );
    }
END:
    WIN_ReleaseWndPtr(wndPtr);
    return retval;
}


/***********************************************************************
 *           DispatchMessage32   (USER.822)
 */
LONG WINAPI DispatchMessage32_16( const MSG32_16* lpmsg16_32, BOOL16 wHaveParamHigh )
{
    if (wHaveParamHigh == FALSE)
        return DispatchMessage16(&(lpmsg16_32->msg));
    else
    {
        MSG msg;

        msg.hwnd = lpmsg16_32->msg.hwnd;
        msg.message = lpmsg16_32->msg.message;
        msg.wParam = MAKELONG(lpmsg16_32->msg.wParam, lpmsg16_32->wParamHigh);
        msg.lParam = lpmsg16_32->msg.lParam;
        msg.time = lpmsg16_32->msg.time;
        msg.pt.x = (INT)lpmsg16_32->msg.pt.x;
        msg.pt.y = (INT)lpmsg16_32->msg.pt.y;
        return DispatchMessageA(&msg);
    }
}

/***********************************************************************
 *           DispatchMessageA   (USER32.141)
 */
LONG WINAPI DispatchMessageA( const MSG* msg )
{
    WND * wndPtr;
    LONG retval;
    int painting;
    
      /* Process timer messages */
    if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
    {
	if (msg->lParam)
        {
/*            HOOK_CallHooks32A( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */
	    return CallWindowProcA( (WNDPROC)msg->lParam, msg->hwnd,
                                   msg->message, msg->wParam, GetTickCount() );
        }
    }

    if (!msg->hwnd) return 0;
    if (!(wndPtr = WIN_FindWndPtr( msg->hwnd ))) return 0;
    if (!wndPtr->winproc)
    {
        retval = 0;
        goto END;
    }
    painting = (msg->message == WM_PAINT);
    if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
/*    HOOK_CallHooks32A( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */

    SPY_EnterMessage( SPY_DISPATCHMESSAGE, msg->hwnd, msg->message,
                      msg->wParam, msg->lParam );
    retval = CallWindowProcA( (WNDPROC)wndPtr->winproc,
                                msg->hwnd, msg->message,
                                msg->wParam, msg->lParam );
    SPY_ExitMessage( SPY_RESULT_OK, msg->hwnd, msg->message, retval );

    WIN_ReleaseWndPtr(wndPtr);
    wndPtr = WIN_FindWndPtr(msg->hwnd);

    if (painting && wndPtr &&
        (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 */
        ValidateRect( msg->hwnd, NULL );
    }
END:
    WIN_ReleaseWndPtr(wndPtr);
    return retval;
}


/***********************************************************************
 *           DispatchMessageW   (USER32.142)     Process Message
 *
 * Process the message specified in the structure *_msg_.
 *
 * If the lpMsg parameter points to a WM_TIMER message and the
 * parameter of the WM_TIMER message is not NULL, the lParam parameter
 * points to the function that is called instead of the window
 * procedure.
 *  
 * The message must be valid.
 *
 * RETURNS
 *
 *   DispatchMessage() returns the result of the window procedure invoked.
 *
 * CONFORMANCE
 *
 *   ECMA-234, Win32 
 *
 */
LONG WINAPI DispatchMessageW( const MSG* msg )
{
    WND * wndPtr;
    LONG retval;
    int painting;
    
      /* Process timer messages */
    if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
    {
	if (msg->lParam)
        {
/*            HOOK_CallHooks32W( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */
	    return CallWindowProcW( (WNDPROC)msg->lParam, msg->hwnd,
                                   msg->message, msg->wParam, GetTickCount() );
        }
    }

    if (!msg->hwnd) return 0;
    if (!(wndPtr = WIN_FindWndPtr( msg->hwnd ))) return 0;
    if (!wndPtr->winproc)
    {
        retval = 0;
        goto END;
    }
    painting = (msg->message == WM_PAINT);
    if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
/*    HOOK_CallHooks32W( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */

    SPY_EnterMessage( SPY_DISPATCHMESSAGE, msg->hwnd, msg->message,
                      msg->wParam, msg->lParam );
    retval = CallWindowProcW( (WNDPROC)wndPtr->winproc,
                                msg->hwnd, msg->message,
                                msg->wParam, msg->lParam );
    SPY_ExitMessage( SPY_RESULT_OK, msg->hwnd, msg->message, retval );

    WIN_ReleaseWndPtr(wndPtr);
    wndPtr = WIN_FindWndPtr(msg->hwnd);

    if (painting && wndPtr &&
        (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 */
        ValidateRect( msg->hwnd, NULL );
    }
END:
    WIN_ReleaseWndPtr(wndPtr);
    return retval;
}


/***********************************************************************
 *           RegisterWindowMessageA   (USER.118) (USER32.437)
 */
WORD WINAPI RegisterWindowMessageA( LPCSTR str )
{
    TRACE("%s\n", str );
    return GlobalAddAtomA( str );
}


/***********************************************************************
 *           RegisterWindowMessageW   (USER32.438)
 */
WORD WINAPI RegisterWindowMessageW( LPCWSTR str )
{
    TRACE("%p\n", str );
    return GlobalAddAtomW( str );
}


/***********************************************************************
 *           GetCurrentTime16    (USER.15)
 *
 * (effectively identical to GetTickCount)
 */
DWORD WINAPI GetCurrentTime16(void)
{
    return GetTickCount();
}


/***********************************************************************
 *           InSendMessage16    (USER.192)
 */
BOOL16 WINAPI InSendMessage16(void)
{
    return InSendMessage();
}


/***********************************************************************
 *           InSendMessage    (USER32.320)
 */
BOOL WINAPI InSendMessage(void)
{
    MESSAGEQUEUE *queue;
    BOOL ret;

    if (!(queue = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() )))
        return 0;
    ret = (BOOL)queue->smWaiting;

    QUEUE_Unlock( queue );
    return ret;
}

/***********************************************************************
 *           BroadcastSystemMessage    (USER32.12)
 */
LONG WINAPI BroadcastSystemMessage(
	DWORD dwFlags,LPDWORD recipients,UINT uMessage,WPARAM wParam,
	LPARAM lParam
) {
	FIXME_(sendmsg)("(%08lx,%08lx,%08x,%08x,%08lx): stub!\n",
	      dwFlags,*recipients,uMessage,wParam,lParam
	);
	return 0;
}

/***********************************************************************
 *           SendNotifyMessageA    (USER32.460)
 * FIXME
 *  The message sended with PostMessage has to be put in the queue
 *  with a higher priority as the other "Posted" messages.
 *  QUEUE_AddMsg has to be modifyed.
 */
BOOL WINAPI SendNotifyMessageA(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{	BOOL ret = TRUE;
	FIXME("(%04x,%08x,%08x,%08lx) not complete\n",
	      hwnd, msg, wParam, lParam);
	      
	if ( GetCurrentThreadId() == GetWindowThreadProcessId ( hwnd, NULL))
	{	ret=SendMessageA ( hwnd, msg, wParam, lParam );
	}
	else
	{	PostMessageA ( hwnd, msg, wParam, lParam );
	}
	return ret;
}

/***********************************************************************
 *           SendNotifyMessageW    (USER32.461)
 * FIXME
 *  The message sended with PostMessage has to be put in the queue
 *  with a higher priority as the other "Posted" messages.
 *  QUEUE_AddMsg has to be modifyed.
 */
BOOL WINAPI SendNotifyMessageW(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{       BOOL ret = TRUE;
	FIXME("(%04x,%08x,%08x,%08lx) not complete\n",
	      hwnd, msg, wParam, lParam);

	if ( GetCurrentThreadId() == GetWindowThreadProcessId ( hwnd, NULL))
	{       ret=SendMessageW ( hwnd, msg, wParam, lParam );
	}
	else
	{       PostMessageW ( hwnd, msg, wParam, lParam );
	}
	return ret;
}

/***********************************************************************
 *           SendMessageCallbackA
 * FIXME: It's like PostMessage. The callback gets called when the message
 * is processed. We have to modify the message processing for a exact
 * implementation...
 */
BOOL WINAPI SendMessageCallbackA(
	HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam,
	FARPROC lpResultCallBack,DWORD dwData)
{	
	FIXME("(0x%04x,0x%04x,0x%08x,0x%08lx,%p,0x%08lx),stub!\n",
              hWnd,Msg,wParam,lParam,lpResultCallBack,dwData);
	if ( hWnd == HWND_BROADCAST)
	{	PostMessageA( hWnd, Msg, wParam, lParam);
		FIXME("Broadcast: Callback will not be called!\n");
		return TRUE;
	}
	(lpResultCallBack)( hWnd, Msg, dwData, SendMessageA ( hWnd, Msg, wParam, lParam ));
		return TRUE;
}
/***********************************************************************
 *           SendMessageCallbackW
 * FIXME: It's like PostMessage. The callback gets called when the message
 * is processed. We have to modify the message processing for a exact
 * implementation...
 */
BOOL WINAPI SendMessageCallbackW(
	HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam,
	FARPROC lpResultCallBack,DWORD dwData)
{	
	FIXME("(0x%04x,0x%04x,0x%08x,0x%08lx,%p,0x%08lx),stub!\n",
              hWnd,Msg,wParam,lParam,lpResultCallBack,dwData);
	if ( hWnd == HWND_BROADCAST)
	{	PostMessageW( hWnd, Msg, wParam, lParam);
		FIXME("Broadcast: Callback will not be called!\n");
		return TRUE;
	}
	(lpResultCallBack)( hWnd, Msg, dwData, SendMessageA ( hWnd, Msg, wParam, lParam ));
		return TRUE;
}
