mirror of
https://github.com/debauchee/barrier.git
synced 2024-11-23 09:43:24 +03:00
f15c9df85b
clipboard owner support (MS windows done, X windows partial) added key transfer on ms windows mutex fixes in CClient (had race conditions) faster debug output in ms windows changed temporary screen name to "secondary" network fixes on ms windows (poll returned wrong result) fixed transparent cursor on ms windows
920 lines
27 KiB
C++
920 lines
27 KiB
C++
#include "CMSWindowsSecondaryScreen.h"
|
|
#include "CMSWindowsClipboard.h"
|
|
#include "CClient.h"
|
|
#include "CClipboard.h"
|
|
#include "CThread.h"
|
|
#include "CLog.h"
|
|
#include <assert.h>
|
|
|
|
//
|
|
// CMSWindowsSecondaryScreen
|
|
//
|
|
|
|
CMSWindowsSecondaryScreen::CMSWindowsSecondaryScreen() :
|
|
m_client(NULL),
|
|
m_window(NULL),
|
|
m_nextClipboardWindow(NULL)
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
CMSWindowsSecondaryScreen::~CMSWindowsSecondaryScreen()
|
|
{
|
|
assert(m_window == NULL);
|
|
}
|
|
|
|
static CString s_log;
|
|
static CString s_logMore;
|
|
static HWND s_debug = NULL;
|
|
static HWND s_debugLog = NULL;
|
|
static DWORD s_thread = 0;
|
|
static BOOL CALLBACK WINAPI debugProc(HWND, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch (msg) {
|
|
case WM_INITDIALOG:
|
|
return TRUE;
|
|
|
|
case WM_CLOSE:
|
|
PostQuitMessage(0);
|
|
return TRUE;
|
|
|
|
case WM_APP:
|
|
if (!s_logMore.empty()) {
|
|
if (s_log.size() > 20000)
|
|
s_log = s_logMore;
|
|
else
|
|
s_log += s_logMore;
|
|
s_logMore = "";
|
|
SendMessage(s_debugLog, WM_SETTEXT, FALSE, (LPARAM)(LPCTSTR)s_log.c_str());
|
|
SendMessage(s_debugLog, EM_SETSEL, s_log.size(), s_log.size());
|
|
SendMessage(s_debugLog, EM_SCROLLCARET, 0, 0);
|
|
}
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
static void debugOutput(const char* msg)
|
|
{
|
|
s_logMore += msg;
|
|
PostMessage(s_debug, WM_APP, 0, 0);
|
|
}
|
|
|
|
void CMSWindowsSecondaryScreen::run()
|
|
{
|
|
CLog::setOutputter(&debugOutput);
|
|
log((CLOG_INFO "entering event loop"));
|
|
doRun();
|
|
log((CLOG_INFO "exiting event loop"));
|
|
CLog::setOutputter(NULL);
|
|
}
|
|
|
|
void CMSWindowsSecondaryScreen::stop()
|
|
{
|
|
log((CLOG_INFO "requesting event loop stop"));
|
|
doStop();
|
|
}
|
|
|
|
void CMSWindowsSecondaryScreen::open(CClient* client)
|
|
{
|
|
assert(m_client == NULL);
|
|
assert(client != NULL);
|
|
|
|
log((CLOG_INFO "opening screen"));
|
|
|
|
// set the client
|
|
m_client = client;
|
|
|
|
// open the display
|
|
openDisplay();
|
|
}
|
|
|
|
void CMSWindowsSecondaryScreen::close()
|
|
{
|
|
assert(m_client != NULL);
|
|
|
|
log((CLOG_INFO "closing screen"));
|
|
|
|
// close the display
|
|
closeDisplay();
|
|
|
|
// done with client
|
|
m_client = NULL;
|
|
}
|
|
|
|
void CMSWindowsSecondaryScreen::enter(SInt32 x, SInt32 y)
|
|
{
|
|
assert(m_window != NULL);
|
|
|
|
log((CLOG_INFO "entering screen at %d,%d", x, y));
|
|
|
|
// warp to requested location
|
|
SInt32 w, h;
|
|
getScreenSize(&w, &h);
|
|
mouse_event(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE,
|
|
(DWORD)((65535.99 * x) / (w - 1)),
|
|
(DWORD)((65535.99 * y) / (h - 1)),
|
|
0, 0);
|
|
|
|
// show cursor
|
|
log((CLOG_INFO "show cursor"));
|
|
ShowWindow(m_window, SW_HIDE);
|
|
}
|
|
|
|
void CMSWindowsSecondaryScreen::leave()
|
|
{
|
|
assert(m_window != NULL);
|
|
|
|
log((CLOG_INFO "leaving screen"));
|
|
|
|
// move hider window under the mouse (rather than moving the mouse
|
|
// somewhere else on the screen)
|
|
POINT point;
|
|
GetCursorPos(&point);
|
|
MoveWindow(m_window, point.x, point.y, 1, 1, FALSE);
|
|
|
|
// raise and show the hider window. take activation.
|
|
log((CLOG_INFO "hide cursor"));
|
|
ShowWindow(m_window, SW_SHOWNORMAL);
|
|
|
|
// if we think we own the clipboard but we don't then somebody
|
|
// grabbed the clipboard on this screen without us knowing.
|
|
// tell the server that this screen grabbed the clipboard.
|
|
//
|
|
// this works around bugs in the clipboard viewer chain.
|
|
// sometimes NT will simply never send WM_DRAWCLIPBOARD
|
|
// messages for no apparent reason and rebooting fixes the
|
|
// problem. since we don't want a broken clipboard until the
|
|
// next reboot we do this double check. clipboard ownership
|
|
// won't be reflected on other screens until we leave but at
|
|
// least the clipboard itself will work.
|
|
HWND clipboardOwner = GetClipboardOwner();
|
|
if (m_clipboardOwner != clipboardOwner) {
|
|
m_clipboardOwner = clipboardOwner;
|
|
if (m_clipboardOwner != m_window) {
|
|
m_client->onClipboardChanged();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CMSWindowsSecondaryScreen::keyDown(
|
|
KeyID key, KeyModifierMask mask)
|
|
{
|
|
const UINT vkey = mapKey(key, mask);
|
|
if (vkey != 0) {
|
|
const UINT code = MapVirtualKey(vkey, 0);
|
|
keybd_event(vkey, code, 0, 0);
|
|
}
|
|
}
|
|
|
|
void CMSWindowsSecondaryScreen::keyRepeat(
|
|
KeyID key, KeyModifierMask mask, SInt32 count)
|
|
{
|
|
const UINT vkey = mapKey(key, mask);
|
|
if (vkey != 0) {
|
|
const UINT code = MapVirtualKey(vkey, 0);
|
|
for (SInt32 i = 0; i < count; ++i) {
|
|
keybd_event(vkey, code, KEYEVENTF_KEYUP, 0);
|
|
keybd_event(vkey, code, 0, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CMSWindowsSecondaryScreen::keyUp(
|
|
KeyID key, KeyModifierMask mask)
|
|
{
|
|
const UINT vkey = mapKey(key, mask);
|
|
if (vkey != 0) {
|
|
const UINT code = MapVirtualKey(vkey, 0);
|
|
keybd_event(vkey, code, KEYEVENTF_KEYUP, 0);
|
|
}
|
|
}
|
|
|
|
void CMSWindowsSecondaryScreen::mouseDown(ButtonID button)
|
|
{
|
|
// map button id to button flag
|
|
DWORD flags;
|
|
switch (button) {
|
|
case kButtonLeft:
|
|
flags = MOUSEEVENTF_LEFTDOWN;
|
|
break;
|
|
|
|
case kButtonMiddle:
|
|
flags = MOUSEEVENTF_MIDDLEDOWN;
|
|
break;
|
|
|
|
case kButtonRight:
|
|
flags = MOUSEEVENTF_RIGHTDOWN;
|
|
break;
|
|
|
|
default:
|
|
return;
|
|
}
|
|
|
|
// send event
|
|
mouse_event(flags, 0, 0, 0, 0);
|
|
}
|
|
|
|
void CMSWindowsSecondaryScreen::mouseUp(ButtonID button)
|
|
{
|
|
// map button id to button flag
|
|
DWORD flags;
|
|
switch (button) {
|
|
case kButtonLeft:
|
|
flags = MOUSEEVENTF_LEFTUP;
|
|
break;
|
|
|
|
case kButtonMiddle:
|
|
flags = MOUSEEVENTF_MIDDLEUP;
|
|
break;
|
|
|
|
case kButtonRight:
|
|
flags = MOUSEEVENTF_RIGHTUP;
|
|
break;
|
|
|
|
default:
|
|
return;
|
|
}
|
|
|
|
// send event
|
|
mouse_event(flags, 0, 0, 0, 0);
|
|
}
|
|
|
|
void CMSWindowsSecondaryScreen::mouseMove(SInt32 x, SInt32 y)
|
|
{
|
|
SInt32 w, h;
|
|
getScreenSize(&w, &h);
|
|
mouse_event(MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE,
|
|
(SInt32)(65535.99 * x / (w - 1)),
|
|
(SInt32)(65535.99 * y / (h - 1)),
|
|
0, 0);
|
|
}
|
|
|
|
void CMSWindowsSecondaryScreen::mouseWheel(SInt32 delta)
|
|
{
|
|
mouse_event(MOUSEEVENTF_WHEEL, 0, 0, delta, 0);
|
|
}
|
|
|
|
void CMSWindowsSecondaryScreen::setClipboard(
|
|
const IClipboard* src)
|
|
{
|
|
assert(m_window != NULL);
|
|
|
|
CMSWindowsClipboard dst(m_window);
|
|
CClipboard::copy(&dst, src);
|
|
}
|
|
|
|
void CMSWindowsSecondaryScreen::grabClipboard()
|
|
{
|
|
assert(m_window != NULL);
|
|
|
|
CMSWindowsClipboard clipboard(m_window);
|
|
if (clipboard.open()) {
|
|
clipboard.close();
|
|
}
|
|
}
|
|
|
|
void CMSWindowsSecondaryScreen::getSize(
|
|
SInt32* width, SInt32* height) const
|
|
{
|
|
getScreenSize(width, height);
|
|
}
|
|
|
|
SInt32 CMSWindowsSecondaryScreen::getJumpZoneSize() const
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
void CMSWindowsSecondaryScreen::getClipboard(
|
|
IClipboard* dst) const
|
|
{
|
|
assert(m_window != NULL);
|
|
|
|
CMSWindowsClipboard src(m_window);
|
|
CClipboard::copy(dst, &src);
|
|
}
|
|
|
|
#include "resource.h" // FIXME
|
|
|
|
void CMSWindowsSecondaryScreen::onOpenDisplay()
|
|
{
|
|
assert(m_window == NULL);
|
|
|
|
// create debug dialog
|
|
s_thread = GetCurrentThreadId();;
|
|
s_debug = CreateDialog(getInstance(), MAKEINTRESOURCE(IDD_SYNERGY), NULL, &debugProc);
|
|
s_debugLog = ::GetDlgItem(s_debug, IDC_LOG);
|
|
CLog::setOutputter(&debugOutput);
|
|
ShowWindow(s_debug, SW_SHOWNORMAL);
|
|
|
|
// initialize clipboard owner to current owner. we don't want
|
|
// to take ownership of the clipboard just by starting up.
|
|
m_clipboardOwner = GetClipboardOwner();
|
|
|
|
// create the cursor hiding window. this window is used to hide the
|
|
// cursor when it's not on the screen. the window is hidden as soon
|
|
// as the cursor enters the screen or the display's real cursor is
|
|
// moved.
|
|
m_window = CreateWindowEx(WS_EX_TOPMOST |
|
|
WS_EX_TRANSPARENT | WS_EX_TOOLWINDOW,
|
|
(LPCTSTR)getClass(), "Synergy",
|
|
WS_POPUP,
|
|
0, 0, 1, 1, NULL, NULL,
|
|
getInstance(),
|
|
NULL);
|
|
|
|
// hide the cursor
|
|
leave();
|
|
|
|
// install our clipboard snooper
|
|
m_nextClipboardWindow = SetClipboardViewer(m_window);
|
|
}
|
|
|
|
void CMSWindowsSecondaryScreen::onCloseDisplay()
|
|
{
|
|
assert(m_window != NULL);
|
|
|
|
// remove clipboard snooper
|
|
ChangeClipboardChain(m_window, m_nextClipboardWindow);
|
|
m_nextClipboardWindow = NULL;
|
|
|
|
// destroy window
|
|
DestroyWindow(m_window);
|
|
m_window = NULL;
|
|
|
|
CLog::setOutputter(NULL);
|
|
DestroyWindow(s_debug);
|
|
s_debug = NULL;
|
|
s_thread = 0;
|
|
}
|
|
|
|
bool CMSWindowsSecondaryScreen::onPreTranslate(MSG* msg)
|
|
{
|
|
if (IsDialogMessage(s_debug, msg)) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
LRESULT CMSWindowsSecondaryScreen::onEvent(
|
|
HWND hwnd, UINT msg,
|
|
WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch (msg) {
|
|
// FIXME -- handle display changes
|
|
case WM_PAINT:
|
|
ValidateRect(hwnd, NULL);
|
|
return 0;
|
|
|
|
case WM_ACTIVATEAPP:
|
|
if (wParam == FALSE) {
|
|
// some other app activated. hide the hider window.
|
|
log((CLOG_INFO "show cursor"));
|
|
ShowWindow(m_window, SW_HIDE);
|
|
}
|
|
break;
|
|
|
|
case WM_DRAWCLIPBOARD:
|
|
log((CLOG_DEBUG "clipboard was taken"));
|
|
|
|
// first pass it on
|
|
SendMessage(m_nextClipboardWindow, msg, wParam, lParam);
|
|
|
|
// now notify client that somebody changed the clipboard (unless
|
|
// we're now the owner, in which case it's because we took
|
|
// ownership).
|
|
m_clipboardOwner = GetClipboardOwner();
|
|
if (m_clipboardOwner != m_window) {
|
|
m_client->onClipboardChanged();
|
|
}
|
|
return 0;
|
|
|
|
case WM_CHANGECBCHAIN:
|
|
if (m_nextClipboardWindow == (HWND)wParam)
|
|
m_nextClipboardWindow = (HWND)lParam;
|
|
else
|
|
SendMessage(m_nextClipboardWindow, msg, wParam, lParam);
|
|
return 0;
|
|
}
|
|
return DefWindowProc(hwnd, msg, wParam, lParam);
|
|
}
|
|
|
|
static const UINT g_latin1[] =
|
|
{
|
|
/* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x08 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x18 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x28 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x38 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x48 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x50 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x58 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x68 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x78 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x88 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x98 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xa0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xa8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xb0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xb8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xc0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xc8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xd0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xd8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xe0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xe8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xf0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xf8 */ 0, 0, 0, 0, 0, 0, 0, 0
|
|
};
|
|
static const UINT g_latin2[] =
|
|
{
|
|
/* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x08 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x18 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x28 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x38 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x48 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x50 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x58 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x68 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x78 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x88 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x98 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xa0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xa8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xb0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xb8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xc0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xc8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xd0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xd8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xe0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xe8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xf0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xf8 */ 0, 0, 0, 0, 0, 0, 0, 0
|
|
};
|
|
static const UINT g_latin3[] =
|
|
{
|
|
/* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x08 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x18 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x28 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x38 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x48 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x50 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x58 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x68 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x78 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x88 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x98 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xa0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xa8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xb0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xb8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xc0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xc8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xd0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xd8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xe0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xe8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xf0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xf8 */ 0, 0, 0, 0, 0, 0, 0, 0
|
|
};
|
|
static const UINT g_latin4[] =
|
|
{
|
|
/* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x08 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x18 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x28 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x38 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x48 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x50 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x58 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x68 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x78 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x88 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x98 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xa0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xa8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xb0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xb8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xc0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xc8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xd0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xd8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xe0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xe8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xf0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xf8 */ 0, 0, 0, 0, 0, 0, 0, 0
|
|
};
|
|
static const UINT g_latin5[] =
|
|
{
|
|
/* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x08 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x18 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x28 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x38 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x48 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x50 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x58 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x68 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x78 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x88 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x98 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xa0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xa8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xb0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xb8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xc0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xc8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xd0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xd8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xe0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xe8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xf0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xf8 */ 0, 0, 0, 0, 0, 0, 0, 0
|
|
};
|
|
static const UINT g_latin6[] =
|
|
{
|
|
/* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x08 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x18 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x28 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x38 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x48 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x50 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x58 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x68 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x78 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x88 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x98 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xa0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xa8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xb0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xb8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xc0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xc8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xd0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xd8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xe0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xe8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xf0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xf8 */ 0, 0, 0, 0, 0, 0, 0, 0
|
|
};
|
|
static const UINT g_latin7[] =
|
|
{
|
|
/* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x08 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x18 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x28 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x38 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x48 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x50 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x58 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x68 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x78 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x88 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x98 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xa0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xa8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xb0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xb8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xc0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xc8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xd0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xd8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xe0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xe8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xf0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xf8 */ 0, 0, 0, 0, 0, 0, 0, 0
|
|
};
|
|
static const UINT g_latin8[] =
|
|
{
|
|
/* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x08 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x18 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x28 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x38 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x48 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x50 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x58 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x68 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x78 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x88 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x98 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xa0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xa8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xb0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xb8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xc0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xc8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xd0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xd8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xe0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xe8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xf0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xf8 */ 0, 0, 0, 0, 0, 0, 0, 0
|
|
};
|
|
static const UINT g_latin9[] =
|
|
{
|
|
/* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x08 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x18 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x28 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x38 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x48 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x50 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x58 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x68 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x78 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x88 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x98 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xa0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xa8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xb0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xb8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xc0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xc8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xd0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xd8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xe0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xe8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xf0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xf8 */ 0, 0, 0, 0, 0, 0, 0, 0
|
|
};
|
|
static const UINT g_terminal[] =
|
|
{
|
|
/* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x08 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x18 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x28 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x38 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x48 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x50 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x58 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x68 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x78 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x88 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x98 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xa0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xa8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xb0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xb8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xc0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xc8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xd0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xd8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xe0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xe8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xf0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xf8 */ 0, 0, 0, 0, 0, 0, 0, 0
|
|
};
|
|
static const UINT g_function[] =
|
|
{
|
|
/* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x08 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x18 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x28 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x38 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x48 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x50 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x58 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x68 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x78 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x88 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x98 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xa0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xa8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xb0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xb8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xc0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xc8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xd0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xd8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xe0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xe8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xf0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xf8 */ 0, 0, 0, 0, 0, 0, 0, 0
|
|
};
|
|
// FIXME -- will this work?
|
|
// 0x100 + = shift
|
|
// 0x200 + = ctrl
|
|
// 0x400 + = alt
|
|
/* XK_KP_Space to XK_KP_Equal */
|
|
static const UINT g_miscellany[] =
|
|
{
|
|
/* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x08 */ VK_BACK, VK_TAB, /*0x100 +*/ VK_RETURN, VK_CLEAR, 0, VK_RETURN, 0, 0,
|
|
/* 0x10 */ 0, 0, 0, VK_PAUSE, VK_SCROLL, 0/*sys-req*/, 0, 0,
|
|
/* 0x18 */ 0, 0, 0, VK_ESCAPE, 0, 0, 0, 0,
|
|
/* 0x20 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x28 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x38 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x48 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x50 */ VK_HOME, VK_LEFT, VK_UP, VK_RIGHT,
|
|
/* 0x54 */ VK_DOWN, VK_PRIOR, VK_NEXT, VK_END,
|
|
/* 0x58 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x60 */ VK_SELECT, VK_SNAPSHOT, VK_EXECUTE, VK_INSERT, 0, 0, 0, VK_APPS,
|
|
/* 0x68 */ 0, 0, VK_HELP, VK_CANCEL, 0, 0, 0, 0,
|
|
/* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x78 */ 0, 0, 0, 0, 0, 0, VK_MODECHANGE, VK_NUMLOCK,
|
|
/* 0x80 */ VK_SPACE, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0x88 */ 0, VK_TAB, 0, 0, 0, VK_RETURN, 0, 0,
|
|
/* 0x90 */ 0, 0, 0, 0, 0, VK_HOME, VK_LEFT, VK_UP,
|
|
/* 0x98 */ VK_RIGHT, VK_DOWN, VK_PRIOR, VK_NEXT,
|
|
/* 0x9c */ VK_END, 0, VK_INSERT, VK_DELETE,
|
|
/* 0xa0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xa8 */ 0, 0, VK_MULTIPLY, VK_ADD,
|
|
/* 0xac */ VK_SEPARATOR, VK_SUBTRACT, VK_DECIMAL, VK_DIVIDE,
|
|
/* 0xb0 */ VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3,
|
|
/* 0xb4 */ VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7,
|
|
/* 0xb8 */ VK_NUMPAD8, VK_NUMPAD9, 0, 0, 0, 0, VK_F1, VK_F2,
|
|
/* 0xc0 */ VK_F3, VK_F4, VK_F5, VK_F6, VK_F7, VK_F8, VK_F9, VK_F10,
|
|
/* 0xc8 */ VK_F11, VK_F12, VK_F13, VK_F14, VK_F15, VK_F16, VK_F17, VK_F18,
|
|
/* 0xd0 */ VK_F19, VK_F20, VK_F21, VK_F22, VK_F23, VK_F24, 0, 0,
|
|
/* 0xd8 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* FIXME -- want to use LSHIFT, LCONTROL, and LMENU but those don't seem
|
|
* to affect the shift state for VkKeyScan. */
|
|
/* 0xe0 */ 0, VK_SHIFT, VK_RSHIFT, VK_CONTROL,
|
|
/* 0xe4 */ VK_RCONTROL, VK_CAPITAL, 0, VK_LWIN,
|
|
/* 0xe8 */ VK_RWIN, VK_MENU, VK_RMENU, 0, 0, 0, 0, 0,
|
|
/* 0xf0 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
/* 0xf8 */ 0, 0, 0, 0, 0, 0, 0, VK_DELETE
|
|
};
|
|
static const UINT* g_katakana = NULL;
|
|
static const UINT* g_arabic = NULL;
|
|
static const UINT* g_cyrillic = NULL;
|
|
static const UINT* g_greek = NULL;
|
|
static const UINT* g_technical = NULL;
|
|
static const UINT* g_special = NULL;
|
|
static const UINT* g_publishing = NULL;
|
|
static const UINT* g_apl = NULL;
|
|
static const UINT* g_hebrew = NULL;
|
|
static const UINT* g_thai = NULL;
|
|
static const UINT* g_korean = NULL;
|
|
static const UINT* g_armenian = NULL;
|
|
static const UINT* g_georgian = NULL;
|
|
static const UINT* g_azeri = NULL;
|
|
static const UINT* g_vietnamese = NULL;
|
|
static const UINT* g_currency = NULL;
|
|
static const UINT* g_mapTable[] =
|
|
{
|
|
/* 0x00 */ g_latin1, g_latin2, g_latin3, g_latin4,
|
|
/* 0x04 */ g_katakana, g_arabic, g_cyrillic, g_greek,
|
|
/* 0x08 */ g_technical, g_special, g_publishing, g_apl,
|
|
/* 0x0c */ g_hebrew, g_thai, g_korean, NULL,
|
|
/* 0x10 */ NULL, NULL, g_latin8, g_latin9,
|
|
/* 0x14 */ g_armenian, g_georgian, g_azeri, NULL,
|
|
/* 0x18 */ NULL, NULL, NULL, NULL, NULL, NULL, g_vietnamese, NULL,
|
|
/* 0x20 */ g_currency, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
/* 0x28 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
/* 0x30 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
/* 0x38 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
/* 0x40 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
/* 0x48 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
/* 0x50 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
/* 0x58 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
/* 0x60 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
/* 0x68 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
/* 0x70 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
/* 0x78 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
/* 0x80 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
/* 0x88 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
/* 0x90 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
/* 0x98 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
/* 0xa0 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
/* 0xa8 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
/* 0xb0 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
/* 0xb8 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
/* 0xc0 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
/* 0xc8 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
/* 0xd0 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
/* 0xd8 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
/* 0xe0 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
/* 0xe8 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
/* 0xf0 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
/* 0xf8 */ NULL, NULL, NULL, NULL,
|
|
/* 0xfc */ NULL, g_terminal, g_function, g_miscellany
|
|
};
|
|
|
|
UINT CMSWindowsSecondaryScreen::mapKey(
|
|
KeyID id, KeyModifierMask /*mask*/) const
|
|
{
|
|
const UInt32 mapID = ((id >> 8) & 0xff);
|
|
const UInt32 code = (id & 0xff);
|
|
|
|
// lookup the key table
|
|
const UINT* map = g_mapTable[mapID];
|
|
if (map == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
if (mapID == 0) {
|
|
SHORT scan = VkKeyScan(code);
|
|
if (scan != 0xffff) {
|
|
// FIXME -- must ensure shift state is correct. that means
|
|
// tracking the shift state from the moment we enter until
|
|
// the moment we leave (and probably disallowing leave if
|
|
// any shift keys are down). if current shift state is
|
|
// correct then do nothing extra, otherwise must surround
|
|
// injected key event with injected shift key events to
|
|
// get shift key in correct state then back to the previous
|
|
// state.
|
|
return (UINT)LOBYTE(scan);
|
|
}
|
|
}
|
|
|
|
// lookup the key in the table
|
|
return map[code];
|
|
}
|