spiegel-keyman/windows/src/engine/keyman32/keybd_shift.cpp

185 lines
6 KiB
C++

/*
Name: keybd_shift
Copyright: Copyright (C) SIL International.
Documentation:
Description:
Create Date: 11 Dec 2009
Modified Date: 9 Aug 2015
Authors: mcdurdin
Related Files:
Dependencies:
Bugs:
Todo:
Notes:
History: 11 Dec 2009 - mcdurdin - I934 - x64 - Initial version
12 Mar 2010 - mcdurdin - I934 - x64 - Complete
12 Mar 2010 - mcdurdin - I2229 - Remove hints and warnings
31 Dec 2014 - mcdurdin - I4548 - V9.0 - When Alt is down, release of Ctrl, Shift is not detectable within TIP in some languages
09 Aug 2015 - mcdurdin - I4844 - Tidy up PostDummyKeyEvent calls
*/
#include "keyman64.h"
void do_keybd_event(LPINPUT pInputs, int *n, BYTE vk, BYTE scan, DWORD flags, ULONG_PTR extraInfo) { // I4548
INPUT input;
input.type = INPUT_KEYBOARD;
switch(vk) {
case VK_LCONTROL:
case VK_RCONTROL:
vk = VK_CONTROL;
break;
case VK_LMENU:
case VK_RMENU:
vk = VK_MENU;
break;
}
/*PKEYMAN64THREADDATA _td = ThreadGlobals();
if(!_td) return 0;
if(!_td->app) return 0;
if(flags & KEYEVENTF_KEYUP) {
_td->app->QueueAction(QIT_VKEYUP, vk);
} else {
_td->app->QueueAction(QIT_VKEYDOWN, vk);
}*/
input.ki.wVk = vk;
input.ki.wScan = scan;
input.ki.dwFlags = flags;
input.ki.time = 0;
input.ki.dwExtraInfo = extraInfo;
SendDebugMessageFormat(0, sdmAIDefault, 0, "do_keybd_event(n=%d, vk=%s, scan=%x, flags=%x)", *n, Debug_VirtualKey(vk), scan, flags);
pInputs[*n] = input;
(*n)++;
//if(SendInput(1, &input, sizeof(INPUT)) == 0) {
// SendDebugMessageFormat(0, sdmAIDefault, 0, "do_keybd_event: SendInput failed = %d", GetLastError());
//}
//keybd_event(vk, scan, flags, extraInfo);
}
void keybd_sendprefix(LPINPUT pInputs, int *n, BOOL *FPrefix)
{
if(*FPrefix)
{
do_keybd_event(pInputs, n, _VK_PREFIX, 0xFF, 0, 0); // I4548 // I4844
do_keybd_event(pInputs, n, _VK_PREFIX, 0xFF, KEYEVENTF_KEYUP, 0); // I4548 // I4844
*FPrefix = FALSE;
}
}
BOOL keybd_sendshift(LPINPUT pInputs, int *n, BYTE *kbd, int AShiftState, BYTE vkey, int flags, BOOL *FPrefix)
{
DWORD eventflags = 0;
/* 29 Jul 2003 - mcdurdin - Handle sending correct Right C/A "extendedkey" bit */
if(vkey == VK_RMENU || vkey == VK_RCONTROL) eventflags |= KEYEVENTF_EXTENDEDKEY;
if(AShiftState & flags)
{
if((kbd[vkey] & 0x80) == 0)
{
SendDebugMessageFormat(0, sdmAIDefault, 0, "keybd_sendshift: sending keydown - vkey=%s", Debug_VirtualKey(vkey));
keybd_sendprefix(pInputs, n, FPrefix);
do_keybd_event(pInputs, n, vkey, 0xFF, eventflags, 0); // I4548
return TRUE;
}
}
else
{
if(kbd[vkey] & 0x80)
{
SendDebugMessageFormat(0, sdmAIDefault, 0, "keybd_sendshift: sending keyup - vkey=%s", Debug_VirtualKey(vkey));
keybd_sendprefix(pInputs, n, FPrefix);
do_keybd_event(pInputs, n, vkey, 0xFF, KEYEVENTF_KEYUP|eventflags, 0); // I4548
return TRUE;
}
}
return FALSE;
}
BYTE MapGetAsyncKeyStateToByte(WORD vk) {
SHORT r = GetAsyncKeyState(vk);
return (r&1) | ((r&0x8000)>>8);
}
void GetAsyncKeyboardShiftState(BYTE *kbd) {
const WORD vks[] = {VK_CONTROL, VK_LCONTROL, VK_RCONTROL, VK_MENU, VK_LMENU, VK_RMENU, VK_SHIFT, 0};
memset(kbd, 0, 256);
for(int i = 0; vks[i]; i++) {
kbd[vks[i]] = MapGetAsyncKeyStateToByte(vks[i]);
}
}
BOOL keybd_shift(LPINPUT pInputs, int *n, BOOL FReset, LPBYTE kbd) {
//int AShiftFlags;
BOOL FPrefix = !FReset;
BOOL res = FALSE;
if (!FReset) {
GetKeyboardState(kbd);
// Clear all modifiers
if (kbd[VK_LMENU] & 0x80 || kbd[VK_RMENU] & 0x80 || kbd[VK_MENU] & 0x80) {
res |= keybd_sendshift(pInputs, n, kbd, 0, VK_LMENU, LALTFLAG | K_ALTFLAG, &FPrefix);
res |= keybd_sendshift(pInputs, n, kbd, 0, VK_RMENU, RALTFLAG, &FPrefix);
}
if (kbd[VK_LCONTROL] & 0x80 || kbd[VK_RCONTROL] & 0x80 || kbd[VK_CONTROL] & 0x80) {
res |= keybd_sendshift(pInputs, n, kbd, 0, VK_LCONTROL, LCTRLFLAG | K_CTRLFLAG, &FPrefix);
res |= keybd_sendshift(pInputs, n, kbd, 0, VK_RCONTROL, RCTRLFLAG, &FPrefix);
}
if (kbd[VK_SHIFT] & 0x80) {
res |= keybd_sendshift(pInputs, n, kbd, 0, VK_LSHIFT, K_SHIFTFLAG, &FPrefix);
res |= keybd_sendshift(pInputs, n, kbd, 0, VK_RSHIFT, K_SHIFTFLAG, &FPrefix);
}
} else {
// Reset modifiers to desired output
if (kbd[VK_RMENU] & 0x80) {
kbd[VK_RMENU] = 0;
res |= keybd_sendshift(pInputs, n, kbd, RALTFLAG, VK_RMENU, RALTFLAG, &FPrefix);
} else if (kbd[VK_LMENU] & 0x80 || kbd[VK_MENU] & 0x80) {
kbd[VK_LMENU] = 0;
res |= keybd_sendshift(pInputs, n, kbd, LALTFLAG, VK_LMENU, LALTFLAG | K_ALTFLAG, &FPrefix);
}
if (kbd[VK_RCONTROL] & 0x80) {
kbd[VK_RCONTROL] = 0;
res |= keybd_sendshift(pInputs, n, kbd, RCTRLFLAG, VK_RCONTROL, RCTRLFLAG, &FPrefix);
}
else if (kbd[VK_LCONTROL] & 0x80 || kbd[VK_CONTROL] & 0x80) {
kbd[VK_LCONTROL] = 0;
res |= keybd_sendshift(pInputs, n, kbd, LCTRLFLAG, VK_LCONTROL, LCTRLFLAG | K_CTRLFLAG, &FPrefix);
}
if (kbd[VK_RSHIFT] & 0x80) {
kbd[VK_RSHIFT] = 0;
res |= keybd_sendshift(pInputs, n, kbd, K_SHIFTFLAG, VK_RSHIFT, K_SHIFTFLAG, &FPrefix);
}
else if (kbd[VK_LSHIFT] & 0x80 || kbd[VK_SHIFT] & 0x80) {
kbd[VK_LSHIFT] = 0;
res |= keybd_sendshift(pInputs, n, kbd, K_SHIFTFLAG, VK_LSHIFT, K_SHIFTFLAG, &FPrefix);
}
}
// We only want to put out a prefix code if we are at the start of the output
/*SendDebugMessageFormat(0, sdmAIDefault, 0, "keybd_shift: kbd[CAS]: %x %x %x | %x %x %x | %x %x %x "
"AShiftFlags[CAS]: %d %d %d | %d %d %d | %d",
kbd[VK_CONTROL], kbd[VK_LCONTROL], kbd[VK_RCONTROL], kbd[VK_MENU], kbd[VK_LMENU], kbd[VK_RMENU], kbd[VK_SHIFT], kbd[VK_LSHIFT], kbd[VK_RSHIFT],
AShiftFlags & K_CTRLFLAG ? 1 : 0,
AShiftFlags & LCTRLFLAG ? 1 : 0,
AShiftFlags & RCTRLFLAG ? 1 : 0,
AShiftFlags & K_ALTFLAG ? 1 : 0,
AShiftFlags & LALTFLAG ? 1 : 0,
AShiftFlags & RALTFLAG ? 1 : 0,
AShiftFlags & K_SHIFTFLAG ? 1 : 0);*/
return res;
}