feat(windows): update update windows engine action que from core processor

This commit is contained in:
Ross 2021-07-13 16:59:40 +10:00
parent 01d10ce3bf
commit fb2a246f53
5 changed files with 131 additions and 78 deletions

View file

@ -116,6 +116,11 @@ WCHAR *AIWin2000Unicode::ContextBufMax(int n)
{
return context->BufMax(n);
}
void AIWin2000Unicode::SetContext(const WCHAR* buf)
{
return context->Set(buf);
}
BYTE SavedKbdState[256];

View file

@ -1,18 +1,18 @@
/*
Name: aiWin2000Unicode
Copyright: Copyright (C) SIL International.
Documentation:
Description:
Documentation:
Description:
Create Date: 27 Jan 2009
Modified Date: 23 Jun 2014
Authors: mcdurdin
Related Files:
Dependencies:
Related Files:
Dependencies:
Bugs:
Todo:
Notes:
Bugs:
Todo:
Notes:
History: 27 Jan 2009 - mcdurdin - I1797 - Add fallback for AIWin2000 app integration
11 Dec 2009 - mcdurdin - I934 - x64 - Initial version
24 Jun 2010 - mcdurdin - I2436 - Add space to context for AIWin2000Unicode when not matched
@ -43,7 +43,7 @@ public:
virtual BOOL QueueAction(int ItemType, DWORD dwData);
/* Information functions */
virtual BOOL CanHandleWindow(HWND ahwnd);
virtual BOOL IsWindowHandled(HWND ahwnd);
virtual BOOL HandleWindow(HWND ahwnd);
@ -56,9 +56,10 @@ public:
virtual void AddContext(WCHAR ch); //I2436
virtual WCHAR *ContextBuf(int n);
virtual WCHAR *ContextBufMax(int n);
virtual void SetContext(const WCHAR* buf);
/* Queue and sending functions */
virtual BOOL SendActions(); // I4196
virtual BOOL QueueDebugInformation(int ItemType, LPGROUP Group, LPKEY Rule, PWSTR fcontext, PWSTR foutput, DWORD_PTR dwExtraFlags);
};

View file

@ -24,6 +24,7 @@
void IntSaveKeyboardOption(LPCSTR key, LPINTKEYBOARDINFO kp, int nStoreToSave);
BOOL IntLoadKeyboardOptions(LPCSTR key, LPINTKEYBOARDINFO kp);
BOOL IntLoadKeyboardOptionsCore(LPCSTR key, LPINTKEYBOARDINFO kp, km_kbp_state* const state);
void IntSaveKeyboardOptionREGCore(LPCSTR REGKey, LPINTKEYBOARDINFO kp, LPCWSTR key, LPCWSTR value);
void LoadKeyboardOptions(LPINTKEYBOARDINFO kp)
{ // I3594
@ -145,6 +146,25 @@ void SaveKeyboardOption(LPINTKEYBOARDINFO kp, int nStoreToSave)
IntSaveKeyboardOption(REGSZ_KeyboardOptions, kp, nStoreToSave);
}
void SaveKeyboardOptionREGCore(LPINTKEYBOARDINFO kp, LPCWSTR key, LPCWSTR value)
{
IntSaveKeyboardOptionREGCore(REGSZ_KeyboardOptions, kp, key, value);
}
void IntSaveKeyboardOptionREGCore(LPCSTR REGKey, LPINTKEYBOARDINFO kp, LPCWSTR key, LPCWSTR value)
{
assert(REGKey != NULL);
assert(kp != NULL);
assert(kp->coreKeyboard != NULL);
assert(kp->coreKeyboardOptions != NULL);
// TODO: 5011 just check for yourself that the core processor now checks if there size limit of the keyboard store has been reached.
RegistryFullAccess r(HKEY_CURRENT_USER);
if (r.OpenKey(REGSZ_KeymanActiveKeyboards, TRUE) && r.OpenKey(kp->Name, TRUE) && r.OpenKey(REGKey, TRUE))
{
std::wstring tempValue(value);
r.WriteString(key, &tempValue[0]);
}
}
BOOL IntLoadKeyboardOptions(LPCSTR key, LPINTKEYBOARDINFO kp)
{
@ -171,7 +191,7 @@ BOOL IntLoadKeyboardOptions(LPCSTR key, LPINTKEYBOARDINFO kp)
{
if(kp->Keyboard->dpStoreArray[i].dpName != NULL && _wcsicmp(kp->Keyboard->dpStoreArray[i].dpName, buf) == 0)
{
kp->KeyboardOptions[i].Value = new WCHAR[wcslen(val)+1]; // is this a memory leak as
kp->KeyboardOptions[i].Value = new WCHAR[wcslen(val)+1]; // is this a memory leak as
wcscpy_s(kp->KeyboardOptions[i].Value, wcslen(val)+1, val);
kp->KeyboardOptions[i].OriginalStore = kp->Keyboard->dpStoreArray[i].dpString;
@ -233,21 +253,16 @@ BOOL IntLoadKeyboardOptionsCore(LPCSTR key, LPINTKEYBOARDINFO kp, km_kbp_state*
{
buf[255] = 0;
WCHAR val[256];
WCHAR* PWVAL;
if (r.ReadString(buf, val, sizeof(val) / sizeof(val[0])) && val[0])
{
val[255] = 0;
keyboardOpts[n].scope = KM_KBP_OPT_KEYBOARD;
size_t charSize = strlen(key) + 1;
wchar_t* KeyWCHAR = new WCHAR[charSize];
size_t convertedChars = 0;
mbstowcs_s(&convertedChars, KeyWCHAR, charSize, key, _TRUNCATE);
keyboardOpts[n].key = reinterpret_cast<char16_t*>(KeyWCHAR);
PWVAL = new WCHAR[wcslen(val) + 1]; // is this a memory leak as
wcscpy_s(PWVAL, wcslen(val) + 1, val);
keyboardOpts[n].value = reinterpret_cast<char16_t*>(PWVAL);
std::wstring tempKey(buf);
keyboardOpts[n].key = reinterpret_cast<char16_t*>(&tempKey[0]);
std::wstring tempValue(value);
keyboardOpts[n].value = reinterpret_cast<char16_t*>(&tempValue[0]);
}
n++;
}

View file

@ -32,3 +32,5 @@ void LoadSharedKeyboardOptions(LPINTKEYBOARDINFO kp);
* @param state core keyboard state used to update keyboard options
*/
void LoadKeyboardOptionsREGCore(LPINTKEYBOARDINFO kp, km_kbp_state* state);
void SaveKeyboardOptionREGCore(LPINTKEYBOARDINFO kp, LPCWSTR key, LPCWSTR value);

View file

@ -109,8 +109,8 @@ BOOL ProcessHook()
LPGROUP gp = _td->state.startgroup;
fOutputKeystroke = FALSE; // TODO: 5011 no longer needs to be global
fOutputKeystroke = FALSE; // TODO: 5442 no longer needs to be global once we use core processor
BOOL isUsingCoreProcessor = Globals::get_CoreIntegration();
//
// If we are running in the debugger, don't do a second run through
//
@ -122,9 +122,6 @@ BOOL ProcessHook()
//app->NoSetShift = FALSE;
_td->app->ReadContext();
/// TODO: 5011 Could set context of the core engine here (every time there is a ReadContext or Write Context)
// To make sure they are syncronised. However it also probably safest to read the context just before processing an event
// also.
if(_td->state.msg.message == wm_keymankeydown) { // I4827
if (ShouldDebug(sdmKeyboard)) {
@ -144,70 +141,103 @@ BOOL ProcessHook()
_td->app->QueueDebugInformation(QID_BEGIN_ANSI, NULL, NULL, NULL, NULL, (DWORD_PTR) &keyinfo);
}
/// TODO: 5011 Need to make sure the context is set correctly before processing event
// WCHAR buf[MAXCONTEXT];
// _td->app->GetWindowContext(buf, MAXCONTEXT);
// km_kbp_context_item *citems = nullptr;
// km_kbp_context_items_from_utf16(buf, &citems);
// km_kbp_context_set(km_kbp_state_context(_td->activeKbState), citems);
// km_kbp_context_items_dispose(citems);
/// TODO: 5011 km_kbp_process_event(_td->activeKbState, state.vkey, "modifier_state")
ProcessGroup(gp);
if (isUsingCoreProcessor) {
PWSTR buf;
buf = _td->app->ContextBufMax(MAXCONTEXT);
km_kbp_context_item *citems = nullptr;
km_kbp_context_items_from_utf16(reinterpret_cast<char16_t*>(buf), &citems);
km_kbp_context_set(km_kbp_state_context(_td->state.lpActiveKBState), citems);
km_kbp_context_items_dispose(citems);
km_kbp_process_event(_td->state.lpActiveKBState, _td->state.vkey, static_cast<uint16_t>(Globals::get_ShiftState()));
}
else {
ProcessGroup(gp); // TODO: 5442 remove
}
/// TODO: 5011 process all the actions and data munge them into here.
/// Need to update(replace) the platform layer keyman32 context with the context from the core engine
//buf[0] = 0; // clear buffer
//size_t contextSize;
//km_kbp_context_items_to_utf16(_td->activeKbState,buf, &contextSize);
// call a public function to set the Context Or if we aren't going to update the interface for aiTIP
// Then reset the context and call append for each char in buf.
km_kbp_cp buf[MAXCONTEXT];
size_t contextSize;
km_kbp_context_item* context_items;
km_kbp_context* LPCONTEXT = km_kbp_state_context(_td->state.lpActiveKBState);
if (km_kbp_context_get(LPCONTEXT, &context_items) == KM_KBP_STATUS_OK) {
km_kbp_context_items_to_utf16(context_items, NULL, &contextSize);
//buf = new km_kbp_cp[contextSize];
km_kbp_context_items_to_utf16(context_items, buf, &contextSize);
}
km_kbp_context_items_dispose(context_items);
_td->app->SetContext(reinterpret_cast<wchar_t*>(buf));
// Now that we have updated the context update that action queue in the AIINT
// for (auto act = km_kbp_state_action_items(_td->activeKbState, nullptr); act->type != KM_KBP_IT_END; act++) {
for (auto act = km_kbp_state_action_items(_td->state.lpActiveKBState, nullptr); act->type != KM_KBP_IT_END; act++) {
// switch (act.type)
// {
// case KM_KBP_IT_END:
// // error assert(false);
// break;
// case KM_KBP_IT_ALERT:
// _td->app->QueueAction(QIT_BELL, 0);
// break;
// case KM_KBP_IT_CHAR:
// // unicode scalar value is stored in
// //act->character;
// _td->app->QueueAction(QIT_CHAR,Convert_to_utf16(act->character));
// break;
// case KM_KBP_IT_MARKER:
// // act->marker
// _td->app->QueueAction(QIT_DEADKEY,Convert_To_KEY(act->marker));
// break;
// case KM_KBP_IT_BACK:
// /// TODO: 5011 The context is changed in processing engine so this may not match the cached context in the (this) keyman32 layer.
// _td->app->QueueAction(QIT_BACK,BK_DEADKEY);
// break;
// case KM_KBP_IT_PERSIST_OPT:
// /// update keyboard options at the platform layer.
// break;
// case KM_KBP_IT_INVALIDATE_CONTEXT:
// // Reset context
// _td->app->ResetContext();
// break;
// case KM_KBP_IT_EMIT_KEYSTROKE:
// fOutputKeystroke = TRUE;
// break;
// default:
// assert(false); // NOT SUPPORTED
// break;
switch (act->type)
{
case KM_KBP_IT_END:
// error assert(false);
break;
case KM_KBP_IT_ALERT:
_td->app->QueueAction(QIT_BELL, 0);
break;
case KM_KBP_IT_CHAR:
if (Uni_IsSMP(act->character)) {
_td->app->QueueAction(QIT_CHAR, (Uni_UTF32ToSurrogate1(act->character)));
_td->app->QueueAction(QIT_CHAR, (Uni_UTF32ToSurrogate2(act->character)));
}
else {
_td->app->QueueAction(QIT_CHAR, act->character);
}
break;
case KM_KBP_IT_BACK:
// TODO: extract exact infor from DEADKEY in actin tiem
_td->app->QueueAction(QIT_BACK,BK_DEADKEY);
break;
case KM_KBP_IT_PERSIST_OPT:
/// update keyboard options at the platform layer. ie this where keyboardoptions.cpp will have save keyboard option that needs to be written
if (act->option != NULL)
{
// Allocate for 1 option plus 1 pad struct of 0's
km_kbp_option_item* keyboardOpts = new km_kbp_option_item[2];
memmove(&(keyboardOpts[0]), act->option, sizeof(km_kbp_option_item));
km_kbp_status eventStatus = km_kbp_state_options_update(_td->state.lpActiveKBState, keyboardOpts);
if (eventStatus != KM_KBP_STATUS_OK)
{
// log warning "problem saving option for km_kbp_keyboard");
}
delete[] keyboardOpts;
// }
// Put the keyboard option into Windows Registry
if (act->option != NULL && act->option->key != NULL &&
act->option->value != NULL)
{
// log"Saving keyboard option to registry");
SaveKeyboardOptionREGCore(_td->lpActiveKeyboard, reinterpret_cast<LPCWSTR>(act->option->key), reinterpret_cast<LPCWSTR>(act->option->value));
}
}
break;
case KM_KBP_IT_INVALIDATE_CONTEXT:
// Reset context
_td->app->ResetContext();
break;
case KM_KBP_IT_EMIT_KEYSTROKE:
fOutputKeystroke = TRUE;
break;
case KM_KBP_IT_MARKER:
break;
default:
assert(false); // NOT SUPPORTED
break;
}
// }
}
/// TODO: 5011 process this in action items iterations. Do we want to process this when we find the action in the list from the core engine or
// do we process the emit key stroke with whatever we have queued up to this point.
/// TODO: 5011 Emit Keystroke will always be the last action item if it exits in the action item quue
if (fOutputKeystroke && !_td->app->IsQueueEmpty()) {
//
// #2759: The keyboard has requested that the default output