Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions src/xrEngine/Xr_input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,70 @@ bool CInput::get_dik_name(int dik, LPSTR dest_str, int dest_sz)
return (cnt != -1);
}

bool CInput::dik_to_text(int dik, bool shift, bool caps, bool ctrl, bool alt, bool altgr, LPSTR dest, int dest_sz)
{
if (!dest || dest_sz <= 1)
return false;

dest[0] = 0;

const UINT scan = static_cast<UINT>(dik);
const HKL hkl = GetKeyboardLayout(0);

// Convert scan code -> virtual key according to current layout
const UINT vk = MapVirtualKeyEx(scan, MAPVK_VSC_TO_VK_EX, hkl);
if (vk == 0)
return false;

BYTE ks[256] = {};
if (shift) ks[VK_SHIFT] = 0x80;
if (ctrl) ks[VK_CONTROL] = 0x80;
if (alt) ks[VK_MENU] = 0x80;
if (caps) ks[VK_CAPITAL] = 0x01;

// AltGr (usually Right Alt) on Windows behaves like Ctrl+Alt
if (altgr)
{
ks[VK_CONTROL] = 0x80;
ks[VK_MENU] = 0x80;
}

wchar_t wbuf[8] = {};
const int rc = ToUnicodeEx(vk, scan, ks, wbuf, (int)std::size(wbuf), 0, hkl);

if (rc <= 0)
{
// Dead key: clear keyboard state in ToUnicodeEx internal buffer
if (rc == -1)
{
BYTE ks0[256] = {};
wchar_t dummy[8] = {};
ToUnicodeEx(vk, scan, ks0, dummy, (int)std::size(dummy), 0, hkl);
}
return false;
}

// Filter control chars
if (wbuf[0] < 0x20)
return false;

// Convert produced Unicode to CP1251
BOOL usedDefault = FALSE;
const int mb = WideCharToMultiByte(1251, WC_NO_BEST_FIT_CHARS, wbuf, rc, dest, dest_sz - 1, "?", &usedDefault);
if (mb <= 0)
return false;

// Null-terminate
dest[mb] = 0;

// If UI cannot represent it in CP1251, prevent cyrillic output
// Return true to insert '?'
if (usedDefault)
return false;

return true;
}

#define MOUSE_1 (0xED + 100)
#define MOUSE_8 (0xED + 107)

Expand Down
62 changes: 19 additions & 43 deletions src/xrEngine/edit_actions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,55 +77,31 @@ namespace text_editor
m_char_shift = c_shift;
}


void type_pair::on_key_press(line_edit_control* const control)
{
char c = 0;
if (m_translate)
{
c = m_char;
char c_shift = m_char_shift;
string128 buff;
buff[0] = 0;

/*
//setlocale( LC_ALL, "" ); // User-default

// The following 3 lines looks useless

LPSTR loc;
STRCONCAT ( loc, ".", itoa( GetACP(), code_page, 10 ) );
setlocale ( LC_ALL, loc );*/

static _locale_t current_locale = _create_locale(LC_ALL, "");

if (pInput->get_dik_name(m_dik, buff, sizeof(buff)))
char out[16] = {};
const bool shift = control->get_key_state(ks_Shift);
const bool caps = control->get_key_state(ks_CapsLock);
const bool ctrl = control->get_key_state(ks_Ctrl);
const bool alt = control->get_key_state(ks_Alt);
const bool altgr = control->get_key_state(ks_RAlt);

if (m_translate) {
if (pInput->dik_to_text((int)m_dik, shift, caps, ctrl, alt, altgr, out, sizeof(out)))
{
// demonized: add extra check for russian letters
if (std::isalpha(buff[0], std::locale("")) || _isalpha_l(buff[0], current_locale) || buff[0] == char(-1)) // "я" = -1
{
_strlwr_l(buff, current_locale);
c = buff[0];
_strupr_l(buff, current_locale);
c_shift = buff[0];
}
control->insert_text(out);
return;
}

//setlocale( LC_ALL, "C" ); // restore to ANSI

if (control->get_key_state(ks_Shift) != control->get_key_state(ks_CapsLock))
{
c = c_shift;
}
}
else
{
c = m_char;
if (control->get_key_state(ks_Shift) != control->get_key_state(ks_CapsLock))
{
c = m_char_shift;
}
// If unrepresentable, do nothing (or insert fallback char?)
return;
}

// Fallback to old static mapping
char c = m_char;
if (shift != caps)
c = m_char_shift;

control->insert_character(c);
}

Expand Down
26 changes: 7 additions & 19 deletions src/xrEngine/line_edit_control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,25 +108,7 @@ namespace text_editor

static inline bool get_caps_lock_state()
{
#if 0
static bool first_time = true;
static bool is_windows_vista_or_later = false;
if (first_time)
{
first_time = false;
OSVERSIONINFO version_info;
ZeroMemory(&version_info, sizeof(version_info));
version_info.dwOSVersionInfoSize = sizeof(version_info);
GetVersionEx(&version_info);
is_windows_vista_or_later = version_info.dwMajorVersion >= 6;
}

if (is_windows_vista_or_later)
return !!(GetKeyState(VK_CAPITAL) & 1);
else
#else // #if 0
return false;
#endif // #if 0
return (GetKeyState(VK_CAPITAL) & 1) != 0;
}

void line_edit_control::update_key_states()
Expand Down Expand Up @@ -399,6 +381,12 @@ namespace text_editor
m_inserted[0] = c;
}

void line_edit_control::insert_text(LPCSTR s)
{
if (!s) { clear_inserted(); return; }
xr_strcpy(m_inserted, m_buffer_size, s);
}

void line_edit_control::clear_inserted()
{
m_inserted[0] = m_inserted[1] = 0;
Expand Down
1 change: 1 addition & 0 deletions src/xrEngine/line_edit_control.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ namespace text_editor
void assign_callback(u32 const dik, key_state state, Callback const& callback);

void insert_character(char c);
void insert_text(LPCSTR s);

IC bool get_key_state(key_state mask) const { return (mask) ? !!(m_key_state.test(mask)) : true; }
IC void set_key_state(key_state mask, bool value) { m_key_state.set(mask, value); }
Expand Down
1 change: 1 addition & 0 deletions src/xrEngine/xr_input.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ class ENGINE_API CInput
void unacquire();
void acquire(const bool& exclusive);
bool get_dik_name(int dik, LPSTR dest, int dest_sz);
bool dik_to_text(int dik, bool shift, bool caps, bool ctrl, bool alt, bool altgr, LPSTR dest, int dest_sz);

void feedback(u16 s1, u16 s2, float time);
};
Expand Down
Loading