mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-13 04:09:25 +00:00
141 lines
5.4 KiB
C++
141 lines
5.4 KiB
C++
/*
|
|
Copyright: Copyright (C) 2003-2018 SIL International.
|
|
Authors: mcdurdin
|
|
*/
|
|
#include "kmx_processor.h"
|
|
|
|
using namespace km::kbp;
|
|
using namespace kmx;
|
|
|
|
#define MAX_RSHIFT 24
|
|
#define MAX_KSHIFT 18
|
|
|
|
static KMX_DWORD legalKeyStates[MAX_KSHIFT] = {
|
|
0, LCTRLFLAG, RCTRLFLAG, LALTFLAG, LALTFLAG|LCTRLFLAG, LALTFLAG|RCTRLFLAG, RALTFLAG, RALTFLAG|LCTRLFLAG, RALTFLAG|RCTRLFLAG,
|
|
K_SHIFTFLAG, K_SHIFTFLAG|LCTRLFLAG, K_SHIFTFLAG|RCTRLFLAG, K_SHIFTFLAG|LALTFLAG, K_SHIFTFLAG|LALTFLAG|LCTRLFLAG, K_SHIFTFLAG|LALTFLAG|RCTRLFLAG, K_SHIFTFLAG|RALTFLAG, K_SHIFTFLAG|RALTFLAG|LCTRLFLAG, K_SHIFTFLAG|RALTFLAG|RCTRLFLAG
|
|
};
|
|
|
|
static KMX_DWORD legalRuleStates[MAX_RSHIFT] = {
|
|
0, LCTRLFLAG, RCTRLFLAG, LALTFLAG, LALTFLAG|LCTRLFLAG, LALTFLAG|RCTRLFLAG, RALTFLAG, RALTFLAG|LCTRLFLAG, RALTFLAG|RCTRLFLAG,
|
|
K_SHIFTFLAG, K_SHIFTFLAG|LCTRLFLAG, K_SHIFTFLAG|RCTRLFLAG, K_SHIFTFLAG|LALTFLAG, K_SHIFTFLAG|LALTFLAG|LCTRLFLAG, K_SHIFTFLAG|LALTFLAG|RCTRLFLAG, K_SHIFTFLAG|RALTFLAG, K_SHIFTFLAG|RALTFLAG|LCTRLFLAG, K_SHIFTFLAG|RALTFLAG|RCTRLFLAG,
|
|
K_CTRLFLAG, K_ALTFLAG, K_CTRLFLAG|K_ALTFLAG, K_SHIFTFLAG|K_CTRLFLAG, K_SHIFTFLAG|K_ALTFLAG, K_SHIFTFLAG|K_CTRLFLAG|K_ALTFLAG
|
|
};
|
|
|
|
// Simulate RALT -> LCtrl+RAlt -> columns marked with *
|
|
//
|
|
// Truth table: matching key states
|
|
// 1 = yes match always
|
|
// 2 = RAlt mapped as LCtrl+RAlt by keyboard driver
|
|
// 4 = Simulate RAlt with Ctrl+Alt
|
|
//
|
|
// x = key states, y = rule states
|
|
// CAPITAL LETTERS = RIGHT KEY, LOWER CASE LETTERS = LEFT KEY
|
|
static KMX_BYTE states[MAX_RSHIFT][MAX_KSHIFT] = {
|
|
// Simulate RAlt ==> * *
|
|
// 0 c C a ac aC A Ac AC s sc sC sa sac saC sA sAc sAC <-- Key states
|
|
/* 0 */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
/* c */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
/* C */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
/* a */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
/* ac */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
/* aC */ { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
/* A */ { 0, 0, 0, 0, 4, 4, 1, 6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
/* Ac */ { 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Note: RALT will also trigger LCtrl+RAlt because we cannot distinguish reliably through TSF???
|
|
/* AC */ { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
/* s */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
/* sc */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
|
|
/* sC */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
|
|
/* sa */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
|
|
/* sac */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 },
|
|
/* saC */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
|
|
/* sA */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 1, 6, 4 },
|
|
/* sAc */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 },
|
|
/* sAC */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
|
|
|
|
/* Either Ctrl/Alt rules */
|
|
|
|
// 0 c C a ac aC A Ac AC s sc sC sa sac saC sA sAc sAC <-- Key states
|
|
/* C */ { 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
/* A */ { 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
/* CA */ { 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
/* SC */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0 },
|
|
/* SA */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0 },
|
|
/* SCA */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1 }
|
|
|
|
/* ^ rule states */
|
|
};
|
|
|
|
|
|
/*
|
|
* KMX_BOOL IsEquivalentShift( KMX_UINT rshift, KMX_UINT kshift );
|
|
*
|
|
* Parameters: rshift Rule shift state flag set to compare.
|
|
* kshift Current shift state flag set to compare.
|
|
*
|
|
* Returns: TRUE if the shift states are equivalent.
|
|
*
|
|
* IsEquivalentShift will compare rshift and kshift and check the generic
|
|
* K_CTRLFLAG and K_ALTFLAG as well as specific keys correctly.
|
|
*/
|
|
|
|
KMX_BOOL KMX_Processor::IsEquivalentShift(KMX_UINT rshift, KMX_UINT kshift) {
|
|
//
|
|
// The rule shift must have ISVIRTUALKEY bit set for virt.keys
|
|
//
|
|
|
|
if(rshift == 0) return FALSE;
|
|
|
|
//
|
|
// Test CAPS-specific rules
|
|
//
|
|
|
|
if( (rshift & NOTCAPITALFLAG) && (kshift & CAPITALFLAG) ) return FALSE;
|
|
if( (rshift & CAPITALFLAG) && !(kshift & CAPITALFLAG) ) return FALSE;
|
|
|
|
//
|
|
// Ignore CAPS, NUM and SCROLL
|
|
//
|
|
|
|
rshift &= K_MODIFIERFLAG;
|
|
kshift &= K_MODIFIERFLAG;
|
|
|
|
//
|
|
// Find rule state index and key state index
|
|
// If not found, it's not a supported combination, e.g. LCTRL|RCTRL
|
|
// TODO: unwind these loops if you're feeling optimistic
|
|
//
|
|
|
|
int i;
|
|
|
|
for(i = 0; i < MAX_RSHIFT; i++) {
|
|
if(rshift == legalRuleStates[i]) {
|
|
rshift = i;
|
|
break;
|
|
}
|
|
}
|
|
if(i == MAX_RSHIFT) return FALSE;
|
|
|
|
for(i = 0; i < MAX_KSHIFT; i++) {
|
|
if(kshift == legalKeyStates[i]) {
|
|
kshift = i;
|
|
break;
|
|
}
|
|
}
|
|
if(i == MAX_KSHIFT) return FALSE;
|
|
|
|
//
|
|
// Time of truth: is it a valid state?
|
|
//
|
|
|
|
switch(states[rshift][kshift]) {
|
|
case 0: return FALSE;
|
|
case 1: return TRUE;
|
|
case 2: return m_environment.baseLayoutGivesCtrlRAltForRAlt(); // This state is used when TSF gives us a bogus RALT instead of LCtrl+RAlt
|
|
case 4: return m_environment.simulateAltGr(); // I4583
|
|
case 6: return m_environment.baseLayoutGivesCtrlRAltForRAlt() || m_environment.simulateAltGr(); // I4583
|
|
}
|
|
|
|
return FALSE; // should never happen
|
|
}
|
|
|
|
|