2006-02-25 20:50:29 +00:00
|
|
|
|
/*
|
|
|
|
|
AppleWin : An Apple //e emulator for Windows
|
|
|
|
|
|
|
|
|
|
Copyright (C) 1994-1996, Michael O'Brien
|
|
|
|
|
Copyright (C) 1999-2001, Oliver Schmidt
|
|
|
|
|
Copyright (C) 2002-2005, Tom Charlesworth
|
2007-04-01 15:24:52 +00:00
|
|
|
|
Copyright (C) 2006-2007, Tom Charlesworth, Michael Pohoreski
|
2006-02-25 20:50:29 +00:00
|
|
|
|
|
|
|
|
|
AppleWin is free software; you can redistribute it and/or modify
|
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
|
|
AppleWin 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 General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with AppleWin; if not, write to the Free Software
|
|
|
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* Description: Keyboard emulation
|
|
|
|
|
*
|
|
|
|
|
* Author: Various
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "StdAfx.h"
|
2010-02-14 21:11:26 +00:00
|
|
|
|
|
2014-08-13 20:30:35 +00:00
|
|
|
|
#include "AppleWin.h"
|
|
|
|
|
#include "Frame.h"
|
|
|
|
|
#include "Keyboard.h"
|
2016-03-21 23:48:02 +00:00
|
|
|
|
#include "Pravets.h"
|
2014-08-13 20:30:35 +00:00
|
|
|
|
#include "Tape.h"
|
2016-03-21 23:48:02 +00:00
|
|
|
|
#include "YamlHelper.h"
|
2006-02-25 20:50:29 +00:00
|
|
|
|
|
|
|
|
|
static bool g_bKeybBufferEnable = false;
|
|
|
|
|
|
|
|
|
|
#define KEY_OLD
|
|
|
|
|
|
2006-06-26 16:59:48 +00:00
|
|
|
|
static BYTE asciicode[2][10] = {
|
|
|
|
|
{0x08,0x0D,0x15,0x2F,0x00,0x00,0x00,0x00,0x00,0x00},
|
|
|
|
|
{0x08,0x0B,0x15,0x0A,0x00,0x00,0x00,0x00,0x00,0x7F}
|
|
|
|
|
}; // Convert PC arrow keys to Apple keycodes
|
|
|
|
|
|
2009-02-14 03:35:19 +00:00
|
|
|
|
bool g_bShiftKey = false;
|
|
|
|
|
bool g_bCtrlKey = false;
|
|
|
|
|
bool g_bAltKey = false;
|
|
|
|
|
|
2009-06-20 13:43:12 +00:00
|
|
|
|
static bool g_bCapsLock = true; //Caps lock key for Apple2 and Lat/Cyr lock for Pravets8
|
2008-06-20 23:47:25 +00:00
|
|
|
|
static bool g_bP8CapsLock = true; //Caps lock key of Pravets 8A/C
|
2006-02-25 20:50:29 +00:00
|
|
|
|
static int lastvirtkey = 0; // Current PC keycode
|
|
|
|
|
static BYTE keycode = 0; // Current Apple keycode
|
|
|
|
|
|
|
|
|
|
#ifdef KEY_OLD
|
|
|
|
|
// Original
|
|
|
|
|
static BOOL keywaiting = 0;
|
|
|
|
|
#else
|
|
|
|
|
// Buffered key input:
|
|
|
|
|
// - Needed on faster PCs where aliasing occurs during short/fast bursts of 6502 code.
|
|
|
|
|
// - Keyboard only sampled during 6502 execution, so if it's run too fast then key presses will be missed.
|
|
|
|
|
const int KEY_BUFFER_MIN_SIZE = 1;
|
|
|
|
|
const int KEY_BUFFER_MAX_SIZE = 2;
|
|
|
|
|
static int g_nKeyBufferSize = KEY_BUFFER_MAX_SIZE; // Circ key buffer size
|
|
|
|
|
static int g_nNextInIdx = 0;
|
|
|
|
|
static int g_nNextOutIdx = 0;
|
|
|
|
|
static int g_nKeyBufferCnt = 0;
|
|
|
|
|
|
|
|
|
|
static struct
|
|
|
|
|
{
|
|
|
|
|
int nVirtKey;
|
|
|
|
|
BYTE nAppleKey;
|
|
|
|
|
} g_nKeyBuffer[KEY_BUFFER_MAX_SIZE];
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static BYTE g_nLastKey = 0x00;
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// ----- ALL GLOBALLY ACCESSIBLE FUNCTIONS ARE BELOW THIS LINE -----
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
|
|
|
|
|
|
void KeybReset()
|
|
|
|
|
{
|
|
|
|
|
#ifdef KEY_OLD
|
|
|
|
|
keywaiting = 0;
|
|
|
|
|
#else
|
|
|
|
|
g_nNextInIdx = 0;
|
|
|
|
|
g_nNextOutIdx = 0;
|
|
|
|
|
g_nKeyBufferCnt = 0;
|
|
|
|
|
g_nLastKey = 0x00;
|
|
|
|
|
|
|
|
|
|
g_nKeyBufferSize = g_bKeybBufferEnable ? KEY_BUFFER_MAX_SIZE : KEY_BUFFER_MIN_SIZE;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
|
|
|
|
|
|
//void KeybSetBufferMode(bool bNewKeybBufferEnable)
|
|
|
|
|
//{
|
|
|
|
|
// if(g_bKeybBufferEnable == bNewKeybBufferEnable)
|
|
|
|
|
// return;
|
|
|
|
|
//
|
|
|
|
|
// g_bKeybBufferEnable = bNewKeybBufferEnable;
|
|
|
|
|
// KeybReset();
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//bool KeybGetBufferMode()
|
|
|
|
|
//{
|
|
|
|
|
// return g_bKeybBufferEnable;
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
//===========================================================================
|
2006-06-26 16:59:48 +00:00
|
|
|
|
bool KeybGetAltStatus ()
|
2006-02-25 20:50:29 +00:00
|
|
|
|
{
|
2006-06-26 16:59:48 +00:00
|
|
|
|
return g_bAltKey;
|
2006-02-25 20:50:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//===========================================================================
|
2006-06-26 16:59:48 +00:00
|
|
|
|
bool KeybGetCapsStatus ()
|
2006-02-25 20:50:29 +00:00
|
|
|
|
{
|
2006-06-26 16:59:48 +00:00
|
|
|
|
return g_bCapsLock;
|
2006-02-25 20:50:29 +00:00
|
|
|
|
}
|
2008-06-20 23:47:25 +00:00
|
|
|
|
//===========================================================================
|
|
|
|
|
bool KeybGetP8CapsStatus()
|
|
|
|
|
{
|
|
|
|
|
return g_bP8CapsLock;
|
|
|
|
|
}
|
|
|
|
|
//===========================================================================
|
|
|
|
|
/*
|
|
|
|
|
bool KeybGetCapsAllowed() //For Pravets 8A/C only
|
|
|
|
|
{
|
|
|
|
|
return g_CapsLockAllowed;
|
|
|
|
|
}
|
|
|
|
|
*/
|
2006-02-25 20:50:29 +00:00
|
|
|
|
//===========================================================================
|
|
|
|
|
bool KeybGetCtrlStatus ()
|
|
|
|
|
{
|
2006-06-26 16:59:48 +00:00
|
|
|
|
return g_bCtrlKey;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
|
bool KeybGetShiftStatus ()
|
|
|
|
|
{
|
|
|
|
|
return g_bShiftKey;
|
2006-02-25 20:50:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
|
void KeybUpdateCtrlShiftStatus()
|
|
|
|
|
{
|
2006-06-26 16:59:48 +00:00
|
|
|
|
g_bShiftKey = (GetKeyState( VK_SHIFT ) & KF_UP) ? true : false; // 0x8000 KF_UP
|
|
|
|
|
g_bCtrlKey = (GetKeyState( VK_CONTROL) & KF_UP) ? true : false;
|
|
|
|
|
g_bAltKey = (GetKeyState( VK_MENU ) & KF_UP) ? true : false;
|
2006-02-25 20:50:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
|
BYTE KeybGetKeycode () // Used by MemCheckPaging() & VideoCheckMode()
|
|
|
|
|
{
|
|
|
|
|
return keycode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
|
void KeybQueueKeypress (int key, BOOL bASCII)
|
|
|
|
|
{
|
|
|
|
|
if (bASCII == ASCII)
|
2006-07-01 06:44:09 +00:00
|
|
|
|
{
|
2009-02-17 02:25:18 +00:00
|
|
|
|
if (g_bFreshReset && key == VK_CANCEL) // OLD HACK: 0x03
|
2006-07-01 06:44:09 +00:00
|
|
|
|
{
|
2009-02-17 02:25:18 +00:00
|
|
|
|
g_bFreshReset = false;
|
2006-07-01 06:44:09 +00:00
|
|
|
|
return; // Swallow spurious CTRL-C caused by CTRL-BREAK
|
|
|
|
|
}
|
2009-01-06 22:02:31 +00:00
|
|
|
|
|
2009-02-17 02:25:18 +00:00
|
|
|
|
g_bFreshReset = false;
|
2006-02-25 20:50:29 +00:00
|
|
|
|
if (key > 0x7F)
|
|
|
|
|
return;
|
|
|
|
|
|
2007-05-28 11:16:42 +00:00
|
|
|
|
if (!IS_APPLE2)
|
2006-07-01 06:44:09 +00:00
|
|
|
|
{
|
2008-06-20 23:47:25 +00:00
|
|
|
|
P8Shift = false;
|
2006-07-01 06:44:09 +00:00
|
|
|
|
if (g_bCapsLock && (key >= 'a') && (key <='z'))
|
2008-06-20 23:47:25 +00:00
|
|
|
|
{
|
|
|
|
|
P8Shift = true;
|
2009-01-06 22:02:31 +00:00
|
|
|
|
keycode = key - 32;
|
2008-06-20 23:47:25 +00:00
|
|
|
|
}
|
2006-07-01 06:44:09 +00:00
|
|
|
|
else
|
2008-06-20 23:47:25 +00:00
|
|
|
|
{
|
2009-01-06 22:02:31 +00:00
|
|
|
|
keycode = key;
|
2008-06-20 23:47:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//The latter line should be applied for Pravtes 8A/C only, but not for Pravets 82/M !!!
|
|
|
|
|
if ((g_bCapsLock == false) && (key >= 'A') && (key <='Z'))
|
|
|
|
|
{
|
2009-01-06 22:02:31 +00:00
|
|
|
|
P8Shift = true;
|
|
|
|
|
if (g_Apple2Type == A2TYPE_PRAVETS8A)
|
|
|
|
|
keycode = key + 32;
|
2008-06-20 23:47:25 +00:00
|
|
|
|
}
|
2009-01-06 22:02:31 +00:00
|
|
|
|
|
2008-06-20 23:47:25 +00:00
|
|
|
|
//Remap some keys for Pravets82/M
|
|
|
|
|
if (g_Apple2Type == A2TYPE_PRAVETS82)
|
2008-07-26 21:44:35 +00:00
|
|
|
|
{
|
2009-01-06 22:02:31 +00:00
|
|
|
|
if (key == 64)
|
|
|
|
|
keycode = 96;
|
|
|
|
|
if (key == '^')
|
|
|
|
|
keycode = '~';
|
|
|
|
|
|
2009-01-09 21:59:22 +00:00
|
|
|
|
if (g_bCapsLock == false) //cyrillic letters
|
2008-06-20 23:47:25 +00:00
|
|
|
|
{
|
|
|
|
|
if (key == '`') keycode = '^';
|
2008-07-26 21:44:35 +00:00
|
|
|
|
if (key == 92) keycode = '@'; // \ to @
|
|
|
|
|
if (key == 124) keycode = 92;
|
2008-06-20 23:47:25 +00:00
|
|
|
|
}
|
2009-01-09 21:59:22 +00:00
|
|
|
|
else //(g_bCapsLock == true) //latin letters
|
2009-01-05 22:59:26 +00:00
|
|
|
|
{
|
2009-01-06 22:02:31 +00:00
|
|
|
|
if (key == 91) keycode = 123;
|
|
|
|
|
if (key == 93) keycode = 125;
|
|
|
|
|
if (key == 124) keycode = 92;
|
2008-07-26 21:44:35 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2009-01-09 21:59:22 +00:00
|
|
|
|
if (g_Apple2Type == A2TYPE_PRAVETS8M) //Pravets 8M charset is still uncertain
|
|
|
|
|
{
|
|
|
|
|
if (g_bCapsLock == false) //cyrillic letters
|
|
|
|
|
{
|
|
|
|
|
if (key == '[') keycode = '{';
|
|
|
|
|
if (key == ']') keycode = '}';
|
|
|
|
|
if (key == '`') keycode = '~'; //96= key `~
|
|
|
|
|
if (key == 92) keycode = 96;
|
|
|
|
|
}
|
|
|
|
|
else //latin letters
|
|
|
|
|
{
|
|
|
|
|
if (key == '`')
|
|
|
|
|
keycode = '^'; //96= key `~
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-06-20 23:47:25 +00:00
|
|
|
|
//Remap some keys for Pravets8A/C, which has a different charset for Pravtes82/M, whose keys MUST NOT be remapped.
|
|
|
|
|
if (g_Apple2Type == A2TYPE_PRAVETS8A) //&& (g_bCapsLock == false))
|
2008-07-26 21:52:35 +00:00
|
|
|
|
{
|
2008-06-20 23:47:25 +00:00
|
|
|
|
if (g_bCapsLock == false) //i.e. cyrillic letters
|
|
|
|
|
{
|
2009-01-06 22:02:31 +00:00
|
|
|
|
if (key == '[') keycode = '{';
|
|
|
|
|
if (key == ']') keycode = '}';
|
|
|
|
|
if (key == '`') keycode = '~';
|
|
|
|
|
if (key == 92) keycode = 96;
|
2010-08-17 07:52:23 +00:00
|
|
|
|
if (GetCapsLockAllowed() == true)
|
2009-01-06 22:02:31 +00:00
|
|
|
|
{
|
|
|
|
|
if ((key == 92) || (key == 124)) keycode = 96; //<2F> to <20>
|
|
|
|
|
//This shall be rewriten, so that enabling CAPS_LOCK (i.e. F10) will not invert these keys values)
|
|
|
|
|
//The same for latin letters.
|
|
|
|
|
if ((key == '{') || (key == '}') || (key == '~') || (key == 124) || (key == '^') || (key == 95))
|
|
|
|
|
P8Shift = true;
|
|
|
|
|
}
|
2008-06-20 23:47:25 +00:00
|
|
|
|
}
|
2009-01-06 22:02:31 +00:00
|
|
|
|
else //i.e. latin letters
|
2008-06-20 23:47:25 +00:00
|
|
|
|
{
|
|
|
|
|
if (GetCapsLockAllowed() == false)
|
|
|
|
|
{
|
2009-01-06 22:02:31 +00:00
|
|
|
|
if (key == '{') keycode = '[';
|
|
|
|
|
if (key == '}') keycode = ']';
|
|
|
|
|
if (key == 124)
|
|
|
|
|
keycode = 92;
|
|
|
|
|
/*if (key == 92)
|
|
|
|
|
keycode = 124;*/
|
2008-07-26 21:44:35 +00:00
|
|
|
|
//Characters ` and ~ cannot be generated in 7bit character mode, so they are replaced with
|
2008-06-20 23:47:25 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2009-01-06 22:02:31 +00:00
|
|
|
|
if (key == '{') keycode = 91;
|
|
|
|
|
if (key == '}') keycode = 93;
|
|
|
|
|
if (key == 124) keycode = 92;
|
|
|
|
|
if ((key == '[') || (key == ']') || (key == 92) || (key == '^') || (key == 95))
|
|
|
|
|
P8Shift= true;
|
|
|
|
|
if (key == 96) //This line shall generate sth. else i.e. ` In fact. this character is not generateable by the pravets keyboard.
|
2008-07-26 21:52:35 +00:00
|
|
|
|
{
|
|
|
|
|
keycode = '^';
|
|
|
|
|
P8Shift= true;
|
|
|
|
|
}
|
2009-01-06 22:02:31 +00:00
|
|
|
|
if (key == 126) keycode = '^';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2006-07-01 06:44:09 +00:00
|
|
|
|
}
|
2006-02-25 20:50:29 +00:00
|
|
|
|
else
|
2006-07-01 06:44:09 +00:00
|
|
|
|
{
|
2008-06-20 23:47:25 +00:00
|
|
|
|
if (g_Apple2Type == A2TYPE_PRAVETS8A)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2009-01-06 22:02:31 +00:00
|
|
|
|
if (key >= '`')
|
|
|
|
|
keycode = key - 32;
|
|
|
|
|
else
|
|
|
|
|
keycode = key;
|
2008-06-20 23:47:25 +00:00
|
|
|
|
}
|
2006-07-01 06:44:09 +00:00
|
|
|
|
}
|
2006-02-25 20:50:29 +00:00
|
|
|
|
lastvirtkey = LOBYTE(VkKeyScan(key));
|
2008-07-26 21:44:35 +00:00
|
|
|
|
}
|
|
|
|
|
else //(bASCII != ASCII)
|
2006-02-25 20:50:29 +00:00
|
|
|
|
{
|
2009-02-17 02:25:18 +00:00
|
|
|
|
// Note: VK_CANCEL is Control-Break
|
2006-06-11 15:49:38 +00:00
|
|
|
|
if ((key == VK_CANCEL) && (GetKeyState(VK_CONTROL) < 0))
|
2006-02-25 20:50:29 +00:00
|
|
|
|
{
|
|
|
|
|
#ifndef KEY_OLD
|
|
|
|
|
g_nNextInIdx = g_nNextOutIdx = g_nKeyBufferCnt = 0;
|
|
|
|
|
#endif
|
2009-02-17 02:25:18 +00:00
|
|
|
|
g_bFreshReset = true;
|
|
|
|
|
CtrlReset();
|
2006-02-25 20:50:29 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((key == VK_INSERT) && (GetKeyState(VK_SHIFT) < 0))
|
|
|
|
|
{
|
|
|
|
|
// Shift+Insert
|
|
|
|
|
ClipboardInitiatePaste();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2007-05-28 11:16:42 +00:00
|
|
|
|
if (!((key >= VK_LEFT) && (key <= VK_DELETE) && asciicode[IS_APPLE2 ? 0 : 1][key - VK_LEFT]))
|
2006-02-25 20:50:29 +00:00
|
|
|
|
return;
|
|
|
|
|
|
2007-05-28 11:16:42 +00:00
|
|
|
|
keycode = asciicode[IS_APPLE2 ? 0 : 1][key - VK_LEFT]; // Convert to Apple arrow keycode
|
2006-02-25 20:50:29 +00:00
|
|
|
|
lastvirtkey = key;
|
|
|
|
|
}
|
|
|
|
|
#ifdef KEY_OLD
|
|
|
|
|
keywaiting = 1;
|
|
|
|
|
#else
|
|
|
|
|
bool bOverflow = false;
|
|
|
|
|
|
|
|
|
|
if(g_nKeyBufferCnt < g_nKeyBufferSize)
|
|
|
|
|
g_nKeyBufferCnt++;
|
|
|
|
|
else
|
|
|
|
|
bOverflow = true;
|
|
|
|
|
|
|
|
|
|
g_nKeyBuffer[g_nNextInIdx].nVirtKey = lastvirtkey;
|
|
|
|
|
g_nKeyBuffer[g_nNextInIdx].nAppleKey = keycode;
|
|
|
|
|
g_nNextInIdx = (g_nNextInIdx + 1) % g_nKeyBufferSize;
|
|
|
|
|
|
|
|
|
|
if(bOverflow)
|
|
|
|
|
g_nNextOutIdx = (g_nNextOutIdx + 1) % g_nKeyBufferSize;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
|
|
|
|
|
|
static HGLOBAL hglb = NULL;
|
|
|
|
|
static LPTSTR lptstr = NULL;
|
|
|
|
|
static bool g_bPasteFromClipboard = false;
|
|
|
|
|
static bool g_bClipboardActive = false;
|
|
|
|
|
|
|
|
|
|
void ClipboardInitiatePaste()
|
|
|
|
|
{
|
|
|
|
|
if (g_bClipboardActive)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
g_bPasteFromClipboard = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void ClipboardDone()
|
|
|
|
|
{
|
|
|
|
|
if (g_bClipboardActive)
|
|
|
|
|
{
|
|
|
|
|
g_bClipboardActive = false;
|
|
|
|
|
GlobalUnlock(hglb);
|
|
|
|
|
CloseClipboard();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void ClipboardInit()
|
|
|
|
|
{
|
|
|
|
|
ClipboardDone();
|
|
|
|
|
|
|
|
|
|
if (!IsClipboardFormatAvailable(CF_TEXT))
|
|
|
|
|
return;
|
|
|
|
|
|
2006-05-14 00:44:38 +00:00
|
|
|
|
if (!OpenClipboard(g_hFrameWindow))
|
2006-02-25 20:50:29 +00:00
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
hglb = GetClipboardData(CF_TEXT);
|
|
|
|
|
if (hglb == NULL)
|
|
|
|
|
{
|
|
|
|
|
CloseClipboard();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
lptstr = (char*) GlobalLock(hglb);
|
|
|
|
|
if (lptstr == NULL)
|
|
|
|
|
{
|
|
|
|
|
CloseClipboard();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g_bPasteFromClipboard = false;
|
|
|
|
|
g_bClipboardActive = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static char ClipboardCurrChar(bool bIncPtr)
|
|
|
|
|
{
|
|
|
|
|
char nKey;
|
|
|
|
|
int nInc = 1;
|
|
|
|
|
|
|
|
|
|
if((lptstr[0] == 0x0D) && (lptstr[1] == 0x0A))
|
|
|
|
|
{
|
|
|
|
|
nKey = 0x0D;
|
|
|
|
|
nInc = 2;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
nKey = lptstr[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(bIncPtr)
|
|
|
|
|
lptstr += nInc;
|
|
|
|
|
|
|
|
|
|
return nKey;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
|
|
2007-05-28 11:16:42 +00:00
|
|
|
|
BYTE __stdcall KeybReadData (WORD, WORD, BYTE, BYTE, ULONG)
|
2006-02-25 20:50:29 +00:00
|
|
|
|
{
|
|
|
|
|
if(g_bPasteFromClipboard)
|
|
|
|
|
ClipboardInit();
|
|
|
|
|
|
|
|
|
|
if(g_bClipboardActive)
|
|
|
|
|
{
|
|
|
|
|
if(*lptstr == 0)
|
|
|
|
|
ClipboardDone();
|
|
|
|
|
else
|
|
|
|
|
return 0x80 | ClipboardCurrChar(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
#ifdef KEY_OLD
|
|
|
|
|
return keycode | (keywaiting ? 0x80 : 0);
|
|
|
|
|
#else
|
|
|
|
|
BYTE nKey = g_nKeyBufferCnt ? 0x80 : 0;
|
|
|
|
|
if(g_nKeyBufferCnt)
|
|
|
|
|
{
|
|
|
|
|
nKey |= g_nKeyBuffer[g_nNextOutIdx].nAppleKey;
|
|
|
|
|
g_nLastKey = g_nKeyBuffer[g_nNextOutIdx].nAppleKey;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
nKey |= g_nLastKey;
|
|
|
|
|
}
|
|
|
|
|
return nKey;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
|
|
2007-05-28 11:16:42 +00:00
|
|
|
|
BYTE __stdcall KeybReadFlag (WORD, WORD, BYTE, BYTE, ULONG)
|
2006-02-25 20:50:29 +00:00
|
|
|
|
{
|
|
|
|
|
if(g_bPasteFromClipboard)
|
|
|
|
|
ClipboardInit();
|
|
|
|
|
|
|
|
|
|
if(g_bClipboardActive)
|
|
|
|
|
{
|
|
|
|
|
if(*lptstr == 0)
|
|
|
|
|
ClipboardDone();
|
|
|
|
|
else
|
|
|
|
|
return 0x80 | ClipboardCurrChar(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
#ifdef KEY_OLD
|
|
|
|
|
keywaiting = 0;
|
|
|
|
|
return keycode | ((GetKeyState(lastvirtkey) < 0) ? 0x80 : 0);
|
|
|
|
|
#else
|
|
|
|
|
BYTE nKey = (GetKeyState(g_nKeyBuffer[g_nNextOutIdx].nVirtKey) < 0) ? 0x80 : 0;
|
|
|
|
|
nKey |= g_nKeyBuffer[g_nNextOutIdx].nAppleKey;
|
|
|
|
|
if(g_nKeyBufferCnt)
|
|
|
|
|
{
|
|
|
|
|
g_nKeyBufferCnt--;
|
|
|
|
|
g_nNextOutIdx = (g_nNextOutIdx + 1) % g_nKeyBufferSize;
|
|
|
|
|
}
|
|
|
|
|
return nKey;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
|
void KeybToggleCapsLock ()
|
|
|
|
|
{
|
2007-05-28 11:16:42 +00:00
|
|
|
|
if (!IS_APPLE2)
|
2006-02-25 20:50:29 +00:00
|
|
|
|
{
|
2006-06-26 16:59:48 +00:00
|
|
|
|
g_bCapsLock = (GetKeyState(VK_CAPITAL) & 1);
|
2006-02-25 20:50:29 +00:00
|
|
|
|
FrameRefreshStatus(DRAW_LEDS);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-06-20 23:47:25 +00:00
|
|
|
|
//===========================================================================
|
|
|
|
|
void KeybToggleP8ACapsLock ()
|
|
|
|
|
{
|
2008-07-28 20:33:22 +00:00
|
|
|
|
_ASSERT(g_Apple2Type == A2TYPE_PRAVETS8A);
|
2009-01-06 22:02:31 +00:00
|
|
|
|
P8CAPS_ON = !P8CAPS_ON;
|
|
|
|
|
FrameRefreshStatus(DRAW_LEDS);
|
|
|
|
|
// g_bP8CapsLock= g_bP8CapsLock?false:true; //The same as the upper, but slower
|
2008-06-20 23:47:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-02-25 20:50:29 +00:00
|
|
|
|
//===========================================================================
|
|
|
|
|
|
2016-03-21 23:48:02 +00:00
|
|
|
|
void KeybSetSnapshot_v1(const BYTE LastKey)
|
|
|
|
|
{
|
|
|
|
|
g_nLastKey = LastKey;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
#define SS_YAML_KEY_LASTKEY "Last Key"
|
|
|
|
|
|
|
|
|
|
static std::string KeybGetSnapshotStructName(void)
|
2006-02-25 20:50:29 +00:00
|
|
|
|
{
|
2016-03-21 23:48:02 +00:00
|
|
|
|
static const std::string name("Keyboard");
|
|
|
|
|
return name;
|
2006-02-25 20:50:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
2016-03-21 23:48:02 +00:00
|
|
|
|
void KeybSaveSnapshot(YamlSaveHelper& yamlSaveHelper)
|
2006-02-25 20:50:29 +00:00
|
|
|
|
{
|
2016-03-21 23:48:02 +00:00
|
|
|
|
YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", KeybGetSnapshotStructName().c_str());
|
|
|
|
|
yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_LASTKEY, g_nLastKey);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void KeybLoadSnapshot(YamlLoadHelper& yamlLoadHelper)
|
|
|
|
|
{
|
|
|
|
|
if (!yamlLoadHelper.GetSubMap(KeybGetSnapshotStructName()))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
g_nLastKey = (BYTE) yamlLoadHelper.LoadUint(SS_YAML_KEY_LASTKEY);
|
|
|
|
|
|
|
|
|
|
yamlLoadHelper.PopMap();
|
2006-02-25 20:50:29 +00:00
|
|
|
|
}
|