/*
 * KEYBOARD driver
 *
 * 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 "windef.h"
#include "wingdi.h"
#include "winuser.h"
#include "wine/keyboard16.h"
#include "win.h"
#include "heap.h"
#include "keyboard.h"
#include "user.h"
#include "message.h"
#include "callback.h"
#include "builtin16.h"
#include "debugtools.h"
#include "winerror.h"

DEFAULT_DEBUG_CHANNEL(keyboard);
DECLARE_DEBUG_CHANNEL(event);

/**********************************************************************/

static LPKEYBD_EVENT_PROC DefKeybEventProc = NULL;
LPBYTE pKeyStateTable = NULL;

/***********************************************************************
 *           KEYBOARD_Inquire			(KEYBOARD.1)
 */
WORD WINAPI KEYBOARD_Inquire(LPKBINFO kbInfo) 
{
  kbInfo->Begin_First_Range = 0;
  kbInfo->End_First_Range = 0;
  kbInfo->Begin_Second_Range = 0;
  kbInfo->End_Second_Range = 0;
  kbInfo->StateSize = 16; 
  
  return sizeof(KBINFO);
}

/***********************************************************************
 *           KEYBOARD_Enable			(KEYBOARD.2)
 */
VOID WINAPI KEYBOARD_Enable( LPKEYBD_EVENT_PROC lpKeybEventProc, 
                             LPBYTE lpKeyState )
{
  static BOOL initDone = FALSE;

  THUNK_Free( (FARPROC)DefKeybEventProc );
  
  DefKeybEventProc = lpKeybEventProc;
  pKeyStateTable = lpKeyState;
  
  /* all states to false */
  memset( lpKeyState, 0, 256 );
  
  if (!initDone) USER_Driver.pInitKeyboard();
  initDone = TRUE;
}

static VOID WINAPI KEYBOARD_CallKeybdEventProc( FARPROC16 proc,
                                                BYTE bVk, BYTE bScan,
                                                DWORD dwFlags, DWORD dwExtraInfo )
{
    CONTEXT86 context;

    memset( &context, 0, sizeof(context) );
    context.SegCs = SELECTOROF( proc );
    context.Eip   = OFFSETOF( proc );
    context.Eax   = bVk | ((dwFlags & KEYEVENTF_KEYUP)? 0x8000 : 0);
    context.Ebx   = bScan | ((dwFlags & KEYEVENTF_EXTENDEDKEY) ? 0x100 : 0);
    context.Esi   = LOWORD( dwExtraInfo );
    context.Edi   = HIWORD( dwExtraInfo );

    CallTo16RegisterShort( &context, 0 );
}

VOID WINAPI WIN16_KEYBOARD_Enable( FARPROC16 proc, LPBYTE lpKeyState )
{
    LPKEYBD_EVENT_PROC thunk = 
      (LPKEYBD_EVENT_PROC)THUNK_Alloc( proc, (RELAY)KEYBOARD_CallKeybdEventProc );

    KEYBOARD_Enable( thunk, lpKeyState );
}

/***********************************************************************
 *           KEYBOARD_Disable			(KEYBOARD.3)
 */
VOID WINAPI KEYBOARD_Disable(VOID)
{
  THUNK_Free( (FARPROC)DefKeybEventProc );
  
  DefKeybEventProc = NULL;
  pKeyStateTable = NULL;
}

/***********************************************************************
 *           KEYBOARD_SendEvent
 */
void KEYBOARD_SendEvent( BYTE bVk, BYTE bScan, DWORD dwFlags,
                         DWORD posX, DWORD posY, DWORD time )
{
  WINE_KEYBDEVENT wke;
  int iWndsLocks;
  
  if ( !DefKeybEventProc ) return;
  
  TRACE_(event)("(%d,%d,%04lX)\n", bVk, bScan, dwFlags );
  
  wke.magic = WINE_KEYBDEVENT_MAGIC;
  wke.posX  = posX;
  wke.posY  = posY;
  wke.time  = time;
  
  /* To avoid deadlocks, we have to suspend all locks on windows structures
     before the program control is passed to the keyboard driver */
  iWndsLocks = WIN_SuspendWndsLock();
  DefKeybEventProc( bVk, bScan, dwFlags, (DWORD)&wke );
  WIN_RestoreWndsLock(iWndsLocks);
}

/**********************************************************************
 *           SetSpeed16      (KEYBOARD.7)
 */
WORD WINAPI SetSpeed16(WORD unused)
{
    FIXME("(%04x): stub\n", unused);
    return 0xffff;
}

/**********************************************************************
 *           ScreenSwitchEnable      (KEYBOARD.100)
 */
VOID WINAPI ScreenSwitchEnable16(WORD unused)
{
  FIXME("(%04x): stub\n", unused);
}

/**********************************************************************
 *           OemKeyScan      (KEYBOARD.128)(USER32.401)
 */
DWORD WINAPI OemKeyScan(WORD wOemChar)
{
  TRACE("*OemKeyScan (%d)\n", wOemChar);

  return wOemChar;
}

/**********************************************************************
 *    	VkKeyScan			[KEYBOARD.129]
 */
/* VkKeyScan translates an ANSI character to a virtual-key and shift code
 * for the current keyboard.
 * high-order byte yields :
 *	0	Unshifted
 *	1	Shift
 *	2	Ctrl
 *	3-5	Shift-key combinations that are not used for characters
 *	6	Ctrl-Alt
 *	7	Ctrl-Alt-Shift
 *	I.e. :	Shift = 1, Ctrl = 2, Alt = 4.
 * FIXME : works ok except for dead chars :
 * VkKeyScan '^'(0x5e, 94) ... got keycode 00 ... returning 00
 * VkKeyScan '`'(0x60, 96) ... got keycode 00 ... returning 00
 */

WORD WINAPI VkKeyScan16(CHAR cChar)
{
    return USER_Driver.pVkKeyScan(cChar);
}

/******************************************************************************
 *    	GetKeyboardType16      (KEYBOARD.130)
 */
INT16 WINAPI GetKeyboardType16(INT16 nTypeFlag)
{
  TRACE("(%d)\n", nTypeFlag);
  switch(nTypeFlag)
    {
    case 0:      /* Keyboard type */
      return 4;    /* AT-101 */
      break;
    case 1:      /* Keyboard Subtype */
      return 0;    /* There are no defined subtypes */
      break;
    case 2:      /* Number of F-keys */
      return 12;   /* We're doing an 101 for now, so return 12 F-keys */
      break;
    default:     
      WARN("Unknown type\n");
      return 0;    /* The book says 0 here, so 0 */
    }
}

/******************************************************************************
 *    	MapVirtualKey16      (KEYBOARD.131)
 *
 * MapVirtualKey translates keycodes from one format to another
 */
UINT16 WINAPI MapVirtualKey16(UINT16 wCode, UINT16 wMapType)
{
    return USER_Driver.pMapVirtualKey(wCode,wMapType);
}

/****************************************************************************
 *	GetKBCodePage16   (KEYBOARD.132)
 */
INT16 WINAPI GetKBCodePage16(void)
{
  TRACE("(void)\n");
  return 850;
}

/****************************************************************************
 *	GetKeyNameText16   (KEYBOARD.133)
 */
INT16 WINAPI GetKeyNameText16(LONG lParam, LPSTR lpBuffer, INT16 nSize)
{
    return USER_Driver.pGetKeyNameText(lParam, lpBuffer, nSize);
}

/****************************************************************************
 *	ToAscii   (KEYBOARD.4)
 *
 * The ToAscii function translates the specified virtual-key code and keyboard
 * state to the corresponding Windows character or characters.
 *
 * If the specified key is a dead key, the return value is negative. Otherwise,
 * it is one of the following values:
 * Value	Meaning
 * 0	The specified virtual key has no translation for the current state of the keyboard.
 * 1	One Windows character was copied to the buffer.
 * 2	Two characters were copied to the buffer. This usually happens when a
 *      dead-key character (accent or diacritic) stored in the keyboard layout cannot
 *      be composed with the specified virtual key to form a single character.
 *
 * FIXME : should do the above (return 2 for non matching deadchar+char combinations)
 *
 */
INT16 WINAPI ToAscii16(UINT16 virtKey,UINT16 scanCode, LPBYTE lpKeyState, 
                       LPVOID lpChar, UINT16 flags) 
{
    return ToAscii( virtKey, scanCode, lpKeyState, lpChar, flags );
}

/***********************************************************************
 *		KEYBOARD_GetBeepActive
 */
BOOL KEYBOARD_GetBeepActive()
{
    return USER_Driver.pGetBeepActive();
}

/***********************************************************************
 *		KEYBOARD_SetBeepActive
 */
void KEYBOARD_SetBeepActive(BOOL bActivate)
{
    USER_Driver.pSetBeepActive(bActivate);
}

/***********************************************************************
 *           MessageBeep16   (USER.104)
 */
void WINAPI MessageBeep16( UINT16 i )
{
    MessageBeep( i );
}

/***********************************************************************
 *           MessageBeep   (USER32.390)
 */
BOOL WINAPI MessageBeep( UINT i )
{
    USER_Driver.pBeep();
    return TRUE;
}
