/*
 * DOS interrupt 16h handler
 *
 * Copyright 1998 Joseph Pranevich
 * Copyright 1999 Ove Kåven
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"

#include <stdlib.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif

#include "dosexe.h"
#include "wincon.h"
#include "wine/debug.h"
#include "windef.h"
#include "wingdi.h"
#include "winuser.h"

WINE_DEFAULT_DEBUG_CHANNEL(int);

/**********************************************************************
 *	    DOSVM_Int16Handler
 *
 * Handler for int 16h (keyboard)
 *
 * NOTE:
 *
 *    KEYB.COM (DOS >3.2) adds functions to this interrupt, they are
 *    not currently listed here.
 */

void WINAPI DOSVM_Int16Handler( CONTEXT *context )
{
   BIOSDATA *data = NULL;
   BYTE ascii, scan;

   switch (AH_reg(context)) {

   case 0x00: /* Get Keystroke */
      /* Returns: AH = Scan code
                  AL = ASCII character */
      TRACE("Get Keystroke\n");
      DOSVM_Int16ReadChar(&ascii, &scan, context);
      SET_AL( context, ascii );
      SET_AH( context, scan );
      break;

   case 0x01: /* Check for Keystroke */
      /* Returns: ZF set if no keystroke */
      /*          AH = Scan code */
      /*          AL = ASCII character */
      TRACE("Check for Keystroke\n");
      if (!DOSVM_Int16ReadChar(&ascii, &scan, NULL))
      {
          SET_ZFLAG(context);
      }
      else
      {
          SET_AL( context, ascii );
          SET_AH( context, scan );
          RESET_ZFLAG(context);
      }
      /* don't miss the opportunity to break some tight timing loop in DOS
       * programs causing 100% CPU usage (by doing a Sleep here) */
      Sleep(5);
      break;

   case 0x02: /* Get Shift Flags */

      /* read value from BIOS data segment's keyboard status flags field */
      data = DOSVM_BiosData();
      SET_AL( context, data->KbdFlags1 );

      TRACE("Get Shift Flags: returning 0x%02x\n", AL_reg(context));
      break;

   case 0x03: /* Set Typematic Rate and Delay */
      FIXME("Set Typematic Rate and Delay - Not Supported\n");
      break;
      
   case 0x05:/*simulate  Keystroke*/ 
      FIXME("Simulating a keystroke is not supported yet\n");
      break;

   case 0x09: /* Get Keyboard Functionality */
      FIXME("Get Keyboard Functionality - Not Supported\n");
      /* As a temporary measure, say that "nothing" is supported... */
      SET_AL( context, 0 );
      break;

   case 0x0a: /* Get Keyboard ID */
      FIXME("Get Keyboard ID - Not Supported\n");
      break;

   case 0x10: /* Get Enhanced Keystroke */
      TRACE("Get Enhanced Keystroke - Partially supported\n");
      /* Returns: AH = Scan code
                  AL = ASCII character */
      DOSVM_Int16ReadChar(&ascii, &scan, context);
      SET_AL( context, ascii );
      SET_AH( context, scan );
      break;


   case 0x11: /* Check for Enhanced Keystroke */
      /* Returns: ZF set if no keystroke */
      /*          AH = Scan code */
      /*          AL = ASCII character */
      TRACE("Check for Enhanced Keystroke - Partially supported\n");
      if (!DOSVM_Int16ReadChar(&ascii, &scan, NULL))
      {
          SET_ZFLAG(context);
      }
      else
      {
          SET_AL( context, ascii );
          SET_AH( context, scan );
          RESET_ZFLAG(context);
      }
      break;

   case 0x12: /* Get Extended Shift States */
      FIXME("Get Extended Shift States - Not Supported\n");
      break;

   default:
      FIXME("Unknown INT 16 function - 0x%x\n", AH_reg(context));
      break;

   }
}

/**********************************************************************
 *	    DOSVM_Int16ReadChar
 *
 * Either peek into keyboard buffer or wait for next keystroke.
 *
 * If waitctx is NULL, return TRUE if buffer had keystrokes and
 * FALSE if buffer is empty. Returned keystroke will be left into buffer.
 * 
 * If waitctx is non-NULL, wait until keystrokes are available.
 * Return value will always be TRUE and returned keystroke will be
 * removed from buffer.
 */
int DOSVM_Int16ReadChar(BYTE *ascii, BYTE *scan, CONTEXT *waitctx)
{
    BIOSDATA *data = DOSVM_BiosData();
    WORD CurOfs = data->NextKbdCharPtr;

    /* check if there's data in buffer */
    if (waitctx)
    {
        /* wait until input is available... */
        while (CurOfs == data->FirstKbdCharPtr)
            DOSVM_Wait( waitctx );
    }
    else
    {
        if (CurOfs == data->FirstKbdCharPtr)
            return FALSE;
    }

    /* read from keyboard queue */
    TRACE( "(%p,%p,%p) -> %02x %02x\n", ascii, scan, waitctx,
           ((BYTE*)data)[CurOfs], ((BYTE*)data)[CurOfs+1] );

    if (ascii) *ascii = ((BYTE*)data)[CurOfs];
    if (scan) *scan = ((BYTE*)data)[CurOfs+1];

    if (waitctx) 
    {
        CurOfs += 2;
        if (CurOfs >= data->KbdBufferEnd) CurOfs = data->KbdBufferStart;
        data->NextKbdCharPtr = CurOfs;
    }

    return TRUE;
}

int DOSVM_Int16AddChar(BYTE ascii,BYTE scan)
{
  BIOSDATA *data = DOSVM_BiosData();
  WORD CurOfs = data->FirstKbdCharPtr;
  WORD NextOfs = CurOfs + 2;

  TRACE("(%02x,%02x)\n",ascii,scan);
  if (NextOfs >= data->KbdBufferEnd) NextOfs = data->KbdBufferStart;
  /* check if buffer is full */
  if (NextOfs == data->NextKbdCharPtr) return 0;

  /* okay, insert character in ring buffer */
  ((BYTE*)data)[CurOfs] = ascii;
  ((BYTE*)data)[CurOfs+1] = scan;

  data->FirstKbdCharPtr = NextOfs;
  return 1;
}
