/*
 * 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 "struct32.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 USER_Driver.pToAscii( 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;
}
