/*
 * USER Input processing
 *
 * Copyright 1993 Bob Amstadt
 * Copyright 1996 Albrecht Kleine 
 * Copyright 1997 David Faure
 * Copyright 1998 Morten Welinder
 * Copyright 1998 Ulrich Weigand
 *
 */

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>

#include "winuser.h"
#include "wine/winbase16.h"
#include "wine/winuser16.h"
#include "wine/keyboard16.h"
#include "win.h"
#include "heap.h"
#include "input.h"
#include "keyboard.h"
#include "mouse.h"
#include "message.h"
#include "sysmetrics.h"
#include "debug.h"
#include "debugtools.h"
#include "struct32.h"
#include "winerror.h"
#include "task.h"

static BOOL InputEnabled = TRUE;
static BOOL SwappedButtons = FALSE;

BOOL MouseButtonsStates[3];
BOOL AsyncMouseButtonsStates[3];
BYTE InputKeyStateTable[256];
BYTE QueueKeyStateTable[256];
BYTE AsyncKeyStateTable[256];

typedef union
{
    struct
    {
	unsigned long count : 16;
	unsigned long code : 8;
	unsigned long extended : 1;
	unsigned long unused : 2;
	unsigned long win_internal : 2;
	unsigned long context : 1;
	unsigned long previous : 1;
	unsigned long transition : 1;
    } lp1;
    unsigned long lp2;
} KEYLP;

/***********************************************************************
 *           keybd_event   (USER32.583)
 */
void WINAPI keybd_event( BYTE bVk, BYTE bScan,
                         DWORD dwFlags, DWORD dwExtraInfo )
{
    DWORD posX, posY, time, extra;
    WORD message;
    KEYLP keylp;
    keylp.lp2 = 0;

    if (!InputEnabled) return;

    /*
     * If we are called by the Wine keyboard driver, use the additional
     * info pointed to by the dwExtraInfo argument.
     * Otherwise, we need to determine that info ourselves (probably
     * less accurate, but we can't help that ...).
     */
    if (   !IsBadReadPtr( (LPVOID)dwExtraInfo, sizeof(WINE_KEYBDEVENT) )
        && ((WINE_KEYBDEVENT *)dwExtraInfo)->magic == WINE_KEYBDEVENT_MAGIC )
    {
        WINE_KEYBDEVENT *wke = (WINE_KEYBDEVENT *)dwExtraInfo;
        posX = wke->posX;
        posY = wke->posY;
        time = wke->time;
        extra = 0;
    }
    else
    {
        DWORD keyState;
        time = GetTickCount();
        extra = dwExtraInfo;

        if ( !EVENT_QueryPointer( &posX, &posY, &keyState ))
            return;
    }


    keylp.lp1.count = 1;
    keylp.lp1.code = bScan;
    keylp.lp1.extended = (dwFlags & KEYEVENTF_EXTENDEDKEY) != 0;
    keylp.lp1.win_internal = 0; /* this has something to do with dialogs,
                                * don't remember where I read it - AK */
                                /* it's '1' under windows, when a dialog box appears
                                 * and you press one of the underlined keys - DF*/

    if ( dwFlags & KEYEVENTF_KEYUP )
    {
        BOOL sysKey = (InputKeyStateTable[VK_MENU] & 0x80)
                && !(InputKeyStateTable[VK_CONTROL] & 0x80)
                && !(dwFlags & KEYEVENTF_WINE_FORCEEXTENDED); /* for Alt from AltGr */

        InputKeyStateTable[bVk] &= ~0x80;
        keylp.lp1.previous = 1;
        keylp.lp1.transition = 1;
        message = sysKey ? WM_SYSKEYUP : WM_KEYUP;
    }
    else
    {
        keylp.lp1.previous = (InputKeyStateTable[bVk] & 0x80) != 0;
        keylp.lp1.transition = 0;

        if (!(InputKeyStateTable[bVk] & 0x80))
            InputKeyStateTable[bVk] ^= 0x01;
        InputKeyStateTable[bVk] |= 0x80;

        message = (InputKeyStateTable[VK_MENU] & 0x80)
              && !(InputKeyStateTable[VK_CONTROL] & 0x80)
              ? WM_SYSKEYDOWN : WM_KEYDOWN;
    }

    if ( message == WM_SYSKEYDOWN || message == WM_SYSKEYUP )
        keylp.lp1.context = (InputKeyStateTable[VK_MENU] & 0x80) != 0; /* 1 if alt */


    TRACE(key, "            wParam=%04X, lParam=%08lX\n", bVk, keylp.lp2 );
    TRACE(key, "            InputKeyState=%X\n", InputKeyStateTable[bVk] );

    hardware_event( message, bVk, keylp.lp2, posX, posY, time, extra );
}

/***********************************************************************
 *           mouse_event   (USER32.584)
 */
void WINAPI mouse_event( DWORD dwFlags, DWORD dx, DWORD dy,
                         DWORD cButtons, DWORD dwExtraInfo )
{
    DWORD posX, posY, keyState, time, extra;

    if (!InputEnabled) return;

    /*
     * If we are called by the Wine mouse driver, use the additional
     * info pointed to by the dwExtraInfo argument.
     * Otherwise, we need to determine that info ourselves (probably
     * less accurate, but we can't help that ...).
     */
    if (   !IsBadReadPtr( (LPVOID)dwExtraInfo, sizeof(WINE_MOUSEEVENT) )
        && ((WINE_MOUSEEVENT *)dwExtraInfo)->magic == WINE_MOUSEEVENT_MAGIC )
    {
        WINE_MOUSEEVENT *wme = (WINE_MOUSEEVENT *)dwExtraInfo;
        keyState = wme->keyState;
        time = wme->time;
        extra = (DWORD)wme->hWnd;

        assert( dwFlags & MOUSEEVENTF_ABSOLUTE );
        posX = (dx * SYSMETRICS_CXSCREEN) >> 16;
        posY = (dy * SYSMETRICS_CYSCREEN) >> 16;
    }
    else
    {
        time = GetTickCount();
        extra = dwExtraInfo;

        if ( !EVENT_QueryPointer( &posX, &posY, &keyState ))
            return;

        if ( dwFlags & MOUSEEVENTF_MOVE )
        {
            if ( dwFlags & MOUSEEVENTF_ABSOLUTE )
            {
                posX = (dx * SYSMETRICS_CXSCREEN) >> 16;
                posY = (dy * SYSMETRICS_CYSCREEN) >> 16;
            }
            else
            {
                posX += dx;
                posY += dy;
            }
            /* We have to actually move the cursor */
            SetCursorPos( posX, posY );
        }
    }

    if ( dwFlags & MOUSEEVENTF_MOVE )
    {
        hardware_event( WM_MOUSEMOVE,
                        keyState, 0L, posX, posY, time, extra );
    }
    if ( dwFlags & (!SwappedButtons? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_RIGHTDOWN) )
    {
        MouseButtonsStates[0] = AsyncMouseButtonsStates[0] = TRUE;
        hardware_event( WM_LBUTTONDOWN,
                        keyState, 0L, posX, posY, time, extra );
    }
    if ( dwFlags & (!SwappedButtons? MOUSEEVENTF_LEFTUP : MOUSEEVENTF_RIGHTUP) )
    {
        MouseButtonsStates[0] = FALSE;
        hardware_event( WM_LBUTTONUP,
                        keyState, 0L, posX, posY, time, extra );
    }
    if ( dwFlags & (!SwappedButtons? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_LEFTDOWN) )
    {
        MouseButtonsStates[2] = AsyncMouseButtonsStates[2] = TRUE;
        hardware_event( WM_RBUTTONDOWN,
                        keyState, 0L, posX, posY, time, extra );
    }
    if ( dwFlags & (!SwappedButtons? MOUSEEVENTF_RIGHTUP : MOUSEEVENTF_LEFTUP) )
    {
        MouseButtonsStates[2] = FALSE;
        hardware_event( WM_RBUTTONUP,
                        keyState, 0L, posX, posY, time, extra );
    }
    if ( dwFlags & MOUSEEVENTF_MIDDLEDOWN )
    {
        MouseButtonsStates[1] = AsyncMouseButtonsStates[1] = TRUE;
        hardware_event( WM_MBUTTONDOWN,
                        keyState, 0L, posX, posY, time, extra );
    }
    if ( dwFlags & MOUSEEVENTF_MIDDLEUP )
    {
        MouseButtonsStates[1] = FALSE;
        hardware_event( WM_MBUTTONUP,
                        keyState, 0L, posX, posY, time, extra );
    }
}

/**********************************************************************
 *                      EnableHardwareInput   (USER.331)
 */
BOOL16 WINAPI EnableHardwareInput16(BOOL16 bEnable)
{
  BOOL16 bOldState = InputEnabled;
  FIXME(event,"(%d) - stub\n", bEnable);
  InputEnabled = bEnable;
  return bOldState;
}


/***********************************************************************
 *           SwapMouseButton16   (USER.186)
 */
BOOL16 WINAPI SwapMouseButton16( BOOL16 fSwap )
{
    BOOL16 ret = SwappedButtons;
    SwappedButtons = fSwap;
    return ret;
}


/***********************************************************************
 *           SwapMouseButton32   (USER32.537)
 */
BOOL WINAPI SwapMouseButton( BOOL fSwap )
{
    BOOL ret = SwappedButtons;
    SwappedButtons = fSwap;
    return ret;
}

/**********************************************************************
 *              EVENT_Capture
 *
 * We need this to be able to generate double click messages
 * when menu code captures mouse in the window without CS_DBLCLK style.
 */
HWND EVENT_Capture(HWND hwnd, INT16 ht)
{
    HWND capturePrev = 0, captureWnd = 0;
    MESSAGEQUEUE *pMsgQ = 0, *pCurMsgQ = 0;
    WND* wndPtr = 0;
    INT16 captureHT = 0;

    /* Get the messageQ for the current thread */
    if (!(pCurMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() )))
    {
        WARN( win, "\tCurrent message queue not found. Exiting!\n" );
        goto CLEANUP;
    }
    
    /* Get the current capture window from the perQ data of the current message Q */
    capturePrev = PERQDATA_GetCaptureWnd( pCurMsgQ->pQData );

    if (!hwnd)
    {
        captureWnd = 0L;
        captureHT = 0;
    }
    else
    {
        wndPtr = WIN_FindWndPtr( hwnd );
        if (wndPtr)
        {
            TRACE(win, "(0x%04x)\n", hwnd );
            captureWnd   = hwnd;
            captureHT    = ht;
        }
    }

    /* Update the perQ capture window and send messages */
    if( capturePrev != captureWnd )
    {
        if (wndPtr)
        {
            /* Retrieve the message queue associated with this window */
            pMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( wndPtr->hmemTaskQ );
            if ( !pMsgQ )
            {
                WARN( win, "\tMessage queue not found. Exiting!\n" );
                goto CLEANUP;
            }
    
            /* Make sure that message queue for the window we are setting capture to
             * shares the same perQ data as the current threads message queue.
             */
            if ( pCurMsgQ->pQData != pMsgQ->pQData )
                goto CLEANUP;
        }

        PERQDATA_SetCaptureWnd( pCurMsgQ->pQData, captureWnd );
        PERQDATA_SetCaptureInfo( pCurMsgQ->pQData, captureHT );
        
        if( capturePrev )
    {
        WND* wndPtr = WIN_FindWndPtr( capturePrev );
        if( wndPtr && (wndPtr->flags & WIN_ISWIN32) )
            SendMessageA( capturePrev, WM_CAPTURECHANGED, 0L, hwnd);
            WIN_ReleaseWndPtr(wndPtr);
    }
}

CLEANUP:
    /* Unlock the queues before returning */
    if ( pMsgQ )
        QUEUE_Unlock( pMsgQ );
    if ( pCurMsgQ )
        QUEUE_Unlock( pCurMsgQ );
    
    WIN_ReleaseWndPtr(wndPtr);
    return capturePrev;
}


/**********************************************************************
 *              SetCapture16   (USER.18)
 */
HWND16 WINAPI SetCapture16( HWND16 hwnd )
{
    return (HWND16)EVENT_Capture( hwnd, HTCLIENT );
}


/**********************************************************************
 *              SetCapture32   (USER32.464)
 */
HWND WINAPI SetCapture( HWND hwnd )
{
    return EVENT_Capture( hwnd, HTCLIENT );
}


/**********************************************************************
 *              ReleaseCapture   (USER.19) (USER32.439)
 */
BOOL WINAPI ReleaseCapture(void)
{
    return (EVENT_Capture( 0, 0 ) != 0);
}


/**********************************************************************
 *              GetCapture16   (USER.236)
 */
HWND16 WINAPI GetCapture16(void)
{
    return (HWND16)GetCapture();
}

/**********************************************************************
 *              GetCapture32   (USER32.208)
 */
HWND WINAPI GetCapture(void)
{
    MESSAGEQUEUE *pCurMsgQ = 0;
    HWND hwndCapture = 0;

    /* Get the messageQ for the current thread */
    if (!(pCurMsgQ = (MESSAGEQUEUE *)QUEUE_Lock( GetFastQueue16() )))
{
        TRACE( win, "GetCapture32:  Current message queue not found. Exiting!\n" );
        return 0;
    }
    
    /* Get the current capture window from the perQ data of the current message Q */
    hwndCapture = PERQDATA_GetCaptureWnd( pCurMsgQ->pQData );

    QUEUE_Unlock( pCurMsgQ );
    return hwndCapture;
}

/**********************************************************************
 *           GetKeyState      (USER.106)
 */
INT16 WINAPI GetKeyState16(INT16 vkey)
{
    return GetKeyState(vkey);
}

/**********************************************************************
 *           GetKeyState      (USER32.249)
 *
 * An application calls the GetKeyState function in response to a
 * keyboard-input message.  This function retrieves the state of the key
 * at the time the input message was generated.  (SDK 3.1 Vol 2. p 390)
 */
INT16 WINAPI GetKeyState(INT vkey)
{
    INT retval;

    switch (vkey)
	{
	case VK_LBUTTON : /* VK_LBUTTON is 1 */
	    retval = MouseButtonsStates[0] ? 0x8000 : 0;
	    break;
	case VK_MBUTTON : /* VK_MBUTTON is 4 */
	    retval = MouseButtonsStates[1] ? 0x8000 : 0;
	    break;
	case VK_RBUTTON : /* VK_RBUTTON is 2 */
	    retval = MouseButtonsStates[2] ? 0x8000 : 0;
	    break;
	default :
	    if (vkey >= 'a' && vkey <= 'z')
		vkey += 'A' - 'a';
	    retval = ( (WORD)(QueueKeyStateTable[vkey] & 0x80) << 8 ) |
		       (WORD)(QueueKeyStateTable[vkey] & 0x01);
	}
    /* TRACE(key, "(0x%x) -> %x\n", vkey, retval); */
    return retval;
}

/**********************************************************************
 *           GetKeyboardState      (USER.222)(USER32.254)
 *
 * An application calls the GetKeyboardState function in response to a
 * keyboard-input message.  This function retrieves the state of the keyboard
 * at the time the input message was generated.  (SDK 3.1 Vol 2. p 387)
 */
VOID WINAPI GetKeyboardState(LPBYTE lpKeyState)
{
    TRACE(key, "(%p)\n", lpKeyState);
    if (lpKeyState != NULL) {
	QueueKeyStateTable[VK_LBUTTON] = MouseButtonsStates[0] ? 0x80 : 0;
	QueueKeyStateTable[VK_MBUTTON] = MouseButtonsStates[1] ? 0x80 : 0;
	QueueKeyStateTable[VK_RBUTTON] = MouseButtonsStates[2] ? 0x80 : 0;
	memcpy(lpKeyState, QueueKeyStateTable, 256);
    }
}

/**********************************************************************
 *          SetKeyboardState      (USER.223)(USER32.484)
 */
VOID WINAPI SetKeyboardState(LPBYTE lpKeyState)
{
    TRACE(key, "(%p)\n", lpKeyState);
    if (lpKeyState != NULL) {
	memcpy(QueueKeyStateTable, lpKeyState, 256);
	MouseButtonsStates[0] = (QueueKeyStateTable[VK_LBUTTON] != 0);
	MouseButtonsStates[1] = (QueueKeyStateTable[VK_MBUTTON] != 0);
	MouseButtonsStates[2] = (QueueKeyStateTable[VK_RBUTTON] != 0);
    }
}

/**********************************************************************
 *           GetAsyncKeyState32      (USER32.207)
 *
 *	Determine if a key is or was pressed.  retval has high-order 
 * bit set to 1 if currently pressed, low-order bit set to 1 if key has
 * been pressed.
 *
 *	This uses the variable AsyncMouseButtonsStates and
 * AsyncKeyStateTable (set in event.c) which have the mouse button
 * number or key number (whichever is applicable) set to true if the
 * mouse or key had been depressed since the last call to 
 * GetAsyncKeyState.
 */
WORD WINAPI GetAsyncKeyState(INT nKey)
{
    short retval;	

    switch (nKey) {
     case VK_LBUTTON:
	retval = (AsyncMouseButtonsStates[0] ? 0x0001 : 0) | 
                 (MouseButtonsStates[0] ? 0x8000 : 0);
	break;
     case VK_MBUTTON:
	retval = (AsyncMouseButtonsStates[1] ? 0x0001 : 0) | 
                 (MouseButtonsStates[1] ? 0x8000 : 0);
	break;
     case VK_RBUTTON:
	retval = (AsyncMouseButtonsStates[2] ? 0x0001 : 0) | 
                 (MouseButtonsStates[2] ? 0x8000 : 0);
	break;
     default:
	retval = AsyncKeyStateTable[nKey] | 
	  	((InputKeyStateTable[nKey] & 0x80) ? 0x8000 : 0); 
	break;
    }

    /* all states to false */
    memset( AsyncMouseButtonsStates, 0, sizeof(AsyncMouseButtonsStates) );
    memset( AsyncKeyStateTable, 0, sizeof(AsyncKeyStateTable) );

    TRACE(key, "(%x) -> %x\n", nKey, retval);
    return retval;
}

/**********************************************************************
 *            GetAsyncKeyState16        (USER.249)
 */
WORD WINAPI GetAsyncKeyState16(INT16 nKey)
{
    return GetAsyncKeyState(nKey);
}

/**********************************************************************
 *           KBD_translate_accelerator
 *
 * FIXME: should send some WM_INITMENU or/and WM_INITMENUPOPUP  -messages
 */
static BOOL KBD_translate_accelerator(HWND hWnd,LPMSG msg,
                                        BYTE fVirt,WORD key,WORD cmd)
{
    BOOL	sendmsg = FALSE;

    if(msg->wParam == key) 
    {
    	if (msg->message == WM_CHAR) {
        if ( !(fVirt & FALT) && !(fVirt & FVIRTKEY) )
        {
   	  TRACE(accel,"found accel for WM_CHAR: ('%c')\n",
			msg->wParam&0xff);
   	  sendmsg=TRUE;
   	}  
      } else {
       if(fVirt & FVIRTKEY) {
	INT mask = 0;
        TRACE(accel,"found accel for virt_key %04x (scan %04x)\n",
  	                       msg->wParam,0xff & HIWORD(msg->lParam));                
	if(GetKeyState(VK_SHIFT) & 0x8000) mask |= FSHIFT;
	if(GetKeyState(VK_CONTROL) & 0x8000) mask |= FCONTROL;
	if(GetKeyState(VK_MENU) & 0x8000) mask |= FALT;
	if(mask == (fVirt & (FSHIFT | FCONTROL | FALT)))
          sendmsg=TRUE;			    
        else
          TRACE(accel,", but incorrect SHIFT/CTRL/ALT-state\n");
       }
       else
       {
         if (!(msg->lParam & 0x01000000))  /* no special_key */
         {
           if ((fVirt & FALT) && (msg->lParam & 0x20000000))
           {                                                   /* ^^ ALT pressed */
	    TRACE(accel,"found accel for Alt-%c\n", msg->wParam&0xff);
	    sendmsg=TRUE;	    
	   } 
         } 
       }
      } 

      if (sendmsg)      /* found an accelerator, but send a message... ? */
      {
        INT16  iSysStat,iStat,mesg=0;
        HMENU16 hMenu;
        
        if (msg->message == WM_KEYUP || msg->message == WM_SYSKEYUP)
          mesg=1;
        else 
         if (GetCapture())
           mesg=2;
         else
          if (!IsWindowEnabled(hWnd))
            mesg=3;
          else
          {
	    WND* wndPtr = WIN_FindWndPtr(hWnd);

            hMenu = (wndPtr->dwStyle & WS_CHILD) ? 0 : (HMENU)wndPtr->wIDmenu;
	    iSysStat = (wndPtr->hSysMenu) ? GetMenuState(GetSubMenu16(wndPtr->hSysMenu, 0),
					    cmd, MF_BYCOMMAND) : -1 ;
	    iStat = (hMenu) ? GetMenuState(hMenu,
					    cmd, MF_BYCOMMAND) : -1 ;

            WIN_ReleaseWndPtr(wndPtr);
            
            if (iSysStat!=-1)
            {
              if (iSysStat & (MF_DISABLED|MF_GRAYED))
                mesg=4;
              else
                mesg=WM_SYSCOMMAND;
            }
            else
            {
              if (iStat!=-1)
              {
                if (IsIconic(hWnd))
                  mesg=5;
                else
                {
                 if (iStat & (MF_DISABLED|MF_GRAYED))
                   mesg=6;
                 else
                   mesg=WM_COMMAND;  
                }   
              }
              else
               mesg=WM_COMMAND;  
            }
          }
          if ( mesg==WM_COMMAND || mesg==WM_SYSCOMMAND )
          {
              TRACE(accel,", sending %s, wParam=%0x\n",
                  mesg==WM_COMMAND ? "WM_COMMAND" : "WM_SYSCOMMAND",
                  cmd);
	      SendMessageA(hWnd, mesg, cmd, 0x00010000L);
	  }
	  else
	  {
	   /*  some reasons for NOT sending the WM_{SYS}COMMAND message: 
	    *   #0: unknown (please report!)
	    *   #1: for WM_KEYUP,WM_SYSKEYUP
	    *   #2: mouse is captured
	    *   #3: window is disabled 
	    *   #4: it's a disabled system menu option
	    *   #5: it's a menu option, but window is iconic
	    *   #6: it's a menu option, but disabled
	    */
	    TRACE(accel,", but won't send WM_{SYS}COMMAND, reason is #%d\n",mesg);
	    if(mesg==0)
	      ERR(accel, " unknown reason - please report!");
	  }          
          return TRUE;         
      }
    }
    return FALSE;
}

/**********************************************************************
 *      TranslateAccelerator32      (USER32.551)(USER32.552)(USER32.553)
 */
INT WINAPI TranslateAccelerator(HWND hWnd, HACCEL hAccel, LPMSG msg)
{
    /* YES, Accel16! */
    LPACCEL16	lpAccelTbl = (LPACCEL16)LockResource16(hAccel);
    int 	i;

    TRACE(accel,"hwnd=0x%x hacc=0x%x msg=0x%x wp=0x%x lp=0x%lx\n", hWnd, hAccel, msg->message, msg->wParam, msg->lParam);
    
    if (hAccel == 0 || msg == NULL ||
	(msg->message != WM_KEYDOWN &&
	 msg->message != WM_KEYUP &&
	 msg->message != WM_SYSKEYDOWN &&
	 msg->message != WM_SYSKEYUP &&
	 msg->message != WM_CHAR)) {
      WARN(accel, "erraneous input parameters\n");
      SetLastError(ERROR_INVALID_PARAMETER);
      return 0;
    }

    TRACE(accel, "TranslateAccelerators hAccel=%04x, hWnd=%04x,"
	  "msg->hwnd=%04x, msg->message=%04x\n",
	  hAccel,hWnd,msg->hwnd,msg->message);

    i = 0;
    do
    {
    	if (KBD_translate_accelerator(hWnd,msg,lpAccelTbl[i].fVirt,
                                      lpAccelTbl[i].key,lpAccelTbl[i].cmd))
		return 1;
    } while ((lpAccelTbl[i++].fVirt & 0x80) == 0);
    WARN(accel, "couldn't translate accelerator key\n");
    return 0;
}

/**********************************************************************
 *           TranslateAccelerator16      (USER.178)
 */	
INT16 WINAPI TranslateAccelerator16(HWND16 hWnd, HACCEL16 hAccel, LPMSG16 msg)
{
    LPACCEL16	lpAccelTbl = (LPACCEL16)LockResource16(hAccel);
    int 	i;
    MSG	msg32;
    
    if (hAccel == 0 || msg == NULL ||
	(msg->message != WM_KEYDOWN &&
	 msg->message != WM_KEYUP &&
	 msg->message != WM_SYSKEYDOWN &&
	 msg->message != WM_SYSKEYUP &&
	 msg->message != WM_CHAR)) {
      WARN(accel, "erraneous input parameters\n");
      SetLastError(ERROR_INVALID_PARAMETER);
      return 0;
    }

    TRACE(accel, "TranslateAccelerators hAccel=%04x, hWnd=%04x,\
msg->hwnd=%04x, msg->message=%04x\n", hAccel,hWnd,msg->hwnd,msg->message);
    STRUCT32_MSG16to32(msg,&msg32);


    i = 0;
    do
    {
    	if (KBD_translate_accelerator(hWnd,&msg32,lpAccelTbl[i].fVirt,
                                      lpAccelTbl[i].key,lpAccelTbl[i].cmd))
		return 1;
    } while ((lpAccelTbl[i++].fVirt & 0x80) == 0);
    WARN(accel, "couldn't translate accelerator key\n");
    return 0;
}


/**********************************************************************
 *           VkKeyScanA      (USER32.573)
 */
WORD WINAPI VkKeyScanA(CHAR cChar)
{
	return VkKeyScan16(cChar);
}

/******************************************************************************
 *    	VkKeyScanW      (USER32.576)
 */
WORD WINAPI VkKeyScanW(WCHAR cChar)
{
	return VkKeyScanA((CHAR)cChar); /* FIXME: check unicode */
}

/**********************************************************************
 *           VkKeyScanExA      (USER32.574)
 */
WORD WINAPI VkKeyScanExA(CHAR cChar, HKL dwhkl)
{
				/* FIXME: complete workaround this is */
				return VkKeyScan16(cChar);
}

/******************************************************************************
 *      VkKeyScanExW      (USER32.575)
 */
WORD WINAPI VkKeyScanExW(WCHAR cChar, HKL dwhkl)
{
				/* FIXME: complete workaround this is */
				return VkKeyScanA((CHAR)cChar); /* FIXME: check unicode */
}
 
/******************************************************************************
 *    	GetKeyboardType32      (USER32.255)
 */
INT WINAPI GetKeyboardType(INT nTypeFlag)
{
  return GetKeyboardType16(nTypeFlag);
}

/******************************************************************************
 *    	MapVirtualKey32A      (USER32.383)
 */
UINT WINAPI MapVirtualKeyA(UINT code, UINT maptype)
{
    return MapVirtualKey16(code,maptype);
}

/******************************************************************************
 *    	MapVirtualKey32W      (USER32.385)
 */
UINT WINAPI MapVirtualKeyW(UINT code, UINT maptype)
{
    return MapVirtualKey16(code,maptype);
}

/******************************************************************************
 *    	MapVirtualKeyEx32A      (USER32.384)
 */
UINT WINAPI MapVirtualKeyEx32A(UINT code, UINT maptype, HKL hkl)
{
    if (hkl)
    	FIXME(keyboard,"(%d,%d,0x%08lx), hkl unhandled!\n",code,maptype,(DWORD)hkl);
    return MapVirtualKey16(code,maptype);
}

/****************************************************************************
 *	GetKBCodePage32   (USER32.246)
 */
UINT WINAPI GetKBCodePage(void)
{
    return GetKBCodePage16();
}

/****************************************************************************
 *      GetKeyboardLayoutName16   (USER.477)
 */
INT16 WINAPI GetKeyboardLayoutName16(LPSTR pwszKLID)
{
	return GetKeyboardLayoutNameA(pwszKLID);
}

/***********************************************************************
 *           GetKeyboardLayout			(USER32.250)
 *
 * FIXME: - device handle for keyboard layout defaulted to 
 *          the language id. This is the way Windows default works.
 *        - the thread identifier (dwLayout) is also ignored.
 */
HKL WINAPI GetKeyboardLayout(DWORD dwLayout)
{
        HKL layout;
        layout = GetSystemDefaultLCID(); /* FIXME */
        layout |= (layout<<16);          /* FIXME */
        TRACE(keyboard,"returning %08x\n",layout);
        return layout;
}

/****************************************************************************
 *	GetKeyboardLayoutName32A   (USER32.252)
 */
INT WINAPI GetKeyboardLayoutNameA(LPSTR pwszKLID)
{
        sprintf(pwszKLID, "%08x",GetKeyboardLayout(0));
        return 1;
}

/****************************************************************************
 *	GetKeyboardLayoutName32W   (USER32.253)
 */
INT WINAPI GetKeyboardLayoutNameW(LPWSTR pwszKLID)
{
	LPSTR buf = HEAP_xalloc( GetProcessHeap(), 0, strlen("00000409")+1);
	int res = GetKeyboardLayoutNameA(buf);
	lstrcpyAtoW(pwszKLID,buf);
	HeapFree( GetProcessHeap(), 0, buf );
	return res;
}

/****************************************************************************
 *	GetKeyNameText32A   (USER32.247)
 */
INT WINAPI GetKeyNameTextA(LONG lParam, LPSTR lpBuffer, INT nSize)
{
	return GetKeyNameText16(lParam,lpBuffer,nSize);
}

/****************************************************************************
 *	GetKeyNameText32W   (USER32.248)
 */
INT WINAPI GetKeyNameTextW(LONG lParam, LPWSTR lpBuffer, INT nSize)
{
	LPSTR buf = HEAP_xalloc( GetProcessHeap(), 0, nSize );
	int res = GetKeyNameTextA(lParam,buf,nSize);

	lstrcpynAtoW(lpBuffer,buf,nSize);
	HeapFree( GetProcessHeap(), 0, buf );
	return res;
}

/****************************************************************************
 *	ToAscii32      (USER32.546)
 */
INT WINAPI ToAscii( UINT virtKey,UINT scanCode,LPBYTE lpKeyState,
                        LPWORD lpChar,UINT flags )
{
    return ToAscii16(virtKey,scanCode,lpKeyState,lpChar,flags);
}

/****************************************************************************
 *	ToAscii32      (USER32.547)
 */
INT WINAPI ToAsciiEx( UINT virtKey, UINT scanCode, LPBYTE lpKeyState,
                      LPWORD lpChar, UINT flags, HKL dwhkl )
{
		/* FIXME: need true implementation */
    return ToAscii16(virtKey,scanCode,lpKeyState,lpChar,flags);
}

/**********************************************************************
 *           ActivateKeyboardLayout32      (USER32.1)
 *
 * Call ignored. WINE supports only system default keyboard layout.
 */
HKL WINAPI ActivateKeyboardLayout(HKL hLayout, UINT flags)
{
    TRACE(keyboard, "(%d, %d)\n", hLayout, flags);
    ERR(keyboard,"Only default system keyboard layout supported. Call ignored.\n");
    return 0;
}


/***********************************************************************
 *           GetKeyboardLayoutList		(USER32.251)
 *
 * FIXME: Supports only the system default language and layout and 
 *          returns only 1 value.
 *
 * Return number of values available if either input parm is 
 *  0, per MS documentation.
 *
 */
INT WINAPI GetKeyboardLayoutList(INT nBuff,HKL *layouts)
{
        TRACE(keyboard,"(%d,%p)\n",nBuff,layouts);
        if (!nBuff || !layouts)
            return 1;
	if (layouts)
		layouts[0] = GetKeyboardLayout(0);
	return 1;
}


/***********************************************************************
 *           RegisterHotKey			(USER32.433)
 */
BOOL WINAPI RegisterHotKey(HWND hwnd,INT id,UINT modifiers,UINT vk) {
	FIXME(keyboard,"(0x%08x,%d,0x%08x,%d): stub\n",hwnd,id,modifiers,vk);
	return TRUE;
}

/***********************************************************************
 *           UnregisterHotKey			(USER32.565)
 */
BOOL WINAPI UnregisterHotKey(HWND hwnd,INT id) {
	FIXME(keyboard,"(0x%08x,%d): stub\n",hwnd,id);
	return TRUE;
}


/***********************************************************************
 *           ToUnicode32                       (USER32.548)
 */
INT WINAPI ToUnicode(
  UINT wVirtKey,
  UINT wScanCode,
  PBYTE  lpKeyState,
  LPWSTR pwszBuff,
  int    cchBuff,
  UINT wFlags) {

       FIXME(keyboard,": stub\n");
       return 0;
}

/***********************************************************************
 *           LoadKeyboardLayout32A                (USER32.367)
 * Call ignored. WINE supports only system default keyboard layout.
 */
HKL WINAPI LoadKeyboardLayoutA(LPCSTR pwszKLID, UINT Flags)
{
    TRACE(keyboard, "(%s, %d)\n", pwszKLID, Flags);
    ERR(keyboard,"Only default system keyboard layout supported. Call ignored.\n");
  return 0; 
}

/***********************************************************************
 *           LoadKeyboardLayout32W                (USER32.368)
 */
HKL WINAPI LoadKeyboardLayoutW(LPCWSTR pwszKLID, UINT Flags)
{
    LPSTR buf = HEAP_xalloc( GetProcessHeap(), 0, strlen("00000409")+1);
    int res;
    lstrcpynWtoA(buf,pwszKLID,8);
    buf[8] = 0;
    res = LoadKeyboardLayoutA(buf, Flags);
    HeapFree( GetProcessHeap(), 0, buf );
    return res;
}
