mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-31 12:47:43 +00:00
feat(windows): update update windows engine action que from core processor
This commit is contained in:
parent
01d10ce3bf
commit
fb2a246f53
5 changed files with 131 additions and 78 deletions
|
|
@ -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];
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue