Added support for 4th and 5th (non-mouse-wheel) buttons and
"Internet" keyboard keys.
This commit is contained in:
parent
b840c61f6c
commit
0e58bab76c
|
@ -57,6 +57,7 @@ AC_PATH_XTRA
|
|||
save_CPPFLAGS="$CPPFLAGS"
|
||||
CPPFLAGS="$X_CFLAGS $CPPFLAGS"
|
||||
AC_CHECK_HEADERS([X11/extensions/XTest.h])
|
||||
AC_CHECK_HEADERS([X11/XF86keysym.h])
|
||||
|
||||
AC_CHECK_LIB(Xinerama, XineramaQueryExtension, AC_CHECK_HEADERS([X11/extensions/Xinerama.h]) [X_LIBS="$X_LIBS -lXinerama"], , [$X_LIBS -lXext -lX11 $X_EXTRA_LIBS])
|
||||
CPPFLAGS="$save_CPPFLAGS"
|
||||
|
|
|
@ -21,16 +21,38 @@
|
|||
#include "CArchMiscWindows.h"
|
||||
#include <cstring>
|
||||
|
||||
// X button stuff
|
||||
#if !defined(WM_XBUTTONDOWN)
|
||||
#define WM_XBUTTONDOWN 0x020B
|
||||
#define WM_XBUTTONUP 0x020C
|
||||
#define WM_XBUTTONDBLCLK 0x020D
|
||||
#define WM_NCXBUTTONDOWN 0x00AB
|
||||
#define WM_NCXBUTTONUP 0x00AC
|
||||
#define WM_NCXBUTTONDBLCLK 0x00AD
|
||||
#define MOUSEEVENTF_XDOWN 0x0100
|
||||
#define MOUSEEVENTF_XUP 0x0200
|
||||
#define XBUTTON1 0x0001
|
||||
#define XBUTTON2 0x0002
|
||||
#endif
|
||||
|
||||
//
|
||||
// map virtual key id to a name
|
||||
//
|
||||
|
||||
static const char* g_buttonToName[] = {
|
||||
"button 0",
|
||||
"Left Button",
|
||||
"Middle Button",
|
||||
"Right Button",
|
||||
"X Button 1",
|
||||
"X Button 2"
|
||||
};
|
||||
static const char* g_vkToName[] = {
|
||||
"vk 0x00",
|
||||
"VK_LBUTTON",
|
||||
"VK_RBUTTON",
|
||||
"Left Button",
|
||||
"Right Button",
|
||||
"VK_CANCEL",
|
||||
"VK_MBUTTON",
|
||||
"Middle Button",
|
||||
"vk 0x05",
|
||||
"vk 0x06",
|
||||
"vk 0x07",
|
||||
|
@ -192,24 +214,24 @@ static const char* g_vkToName[] = {
|
|||
"VK_RCONTROL",
|
||||
"VK_LMENU",
|
||||
"VK_RMENU",
|
||||
"vk 0xa6",
|
||||
"vk 0xa7",
|
||||
"vk 0xa8",
|
||||
"vk 0xa9",
|
||||
"vk 0xaa",
|
||||
"vk 0xab",
|
||||
"vk 0xac",
|
||||
"vk 0xad",
|
||||
"vk 0xae",
|
||||
"vk 0xaf",
|
||||
"vk 0xb0",
|
||||
"vk 0xb1",
|
||||
"vk 0xb2",
|
||||
"vk 0xb3",
|
||||
"vk 0xb4",
|
||||
"vk 0xb5",
|
||||
"vk 0xb6",
|
||||
"vk 0xb7",
|
||||
"VK_BROWSER_BACK",
|
||||
"VK_BROWSER_FORWARD",
|
||||
"VK_BROWSER_REFRESH",
|
||||
"VK_BROWSER_STOP",
|
||||
"VK_BROWSER_SEARCH",
|
||||
"VK_BROWSER_FAVORITES",
|
||||
"VK_BROWSER_HOME",
|
||||
"VK_VOLUME_MUTE",
|
||||
"VK_VOLUME_DOWN",
|
||||
"VK_VOLUME_UP",
|
||||
"VK_MEDIA_NEXT_TRACK",
|
||||
"VK_MEDIA_PREV_TRACK",
|
||||
"VK_MEDIA_STOP",
|
||||
"VK_MEDIA_PLAY_PAUSE",
|
||||
"VK_LAUNCH_MAIL",
|
||||
"VK_LAUNCH_MEDIA_SELECT",
|
||||
"VK_LAUNCH_APP1",
|
||||
"VK_LAUNCH_APP2",
|
||||
"vk 0xb8",
|
||||
"vk 0xb9",
|
||||
"vk 0xba",
|
||||
|
@ -384,24 +406,14 @@ KeyModifierMask
|
|||
CMSWindowsPrimaryScreen::getToggleMask() const
|
||||
{
|
||||
KeyModifierMask mask = 0;
|
||||
if (!m_lowLevel) {
|
||||
// get key state from our shadow state
|
||||
if ((m_keys[VK_CAPITAL] & 0x01) != 0)
|
||||
mask |= KeyModifierCapsLock;
|
||||
if ((m_keys[VK_NUMLOCK] & 0x01) != 0)
|
||||
mask |= KeyModifierNumLock;
|
||||
if ((m_keys[VK_SCROLL] & 0x01) != 0)
|
||||
mask |= KeyModifierScrollLock;
|
||||
}
|
||||
else {
|
||||
// get key state from the system when using low level hooks
|
||||
if ((GetKeyState(VK_CAPITAL) & 0x01) != 0)
|
||||
mask |= KeyModifierCapsLock;
|
||||
if ((GetKeyState(VK_NUMLOCK) & 0x01) != 0)
|
||||
mask |= KeyModifierNumLock;
|
||||
if ((GetKeyState(VK_SCROLL) & 0x01) != 0)
|
||||
mask |= KeyModifierScrollLock;
|
||||
}
|
||||
|
||||
// get key state from our shadow state
|
||||
if ((m_keys[VK_CAPITAL] & 0x01) != 0)
|
||||
mask |= KeyModifierCapsLock;
|
||||
if ((m_keys[VK_NUMLOCK] & 0x01) != 0)
|
||||
mask |= KeyModifierNumLock;
|
||||
if ((m_keys[VK_SCROLL] & 0x01) != 0)
|
||||
mask |= KeyModifierScrollLock;
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
@ -409,44 +421,17 @@ CMSWindowsPrimaryScreen::getToggleMask() const
|
|||
bool
|
||||
CMSWindowsPrimaryScreen::isLockedToScreen() const
|
||||
{
|
||||
// virtual key table. the table defines the virtual keys that are
|
||||
// mapped to something (including mouse buttons, OEM and kanji keys
|
||||
// but not unassigned or undefined keys).
|
||||
static const UInt32 s_mappedKeys[] = {
|
||||
0xfbff331e,
|
||||
0x03ffffff,
|
||||
0x3ffffffe,
|
||||
0xffffffff,
|
||||
0x000300ff,
|
||||
0xfc000000,
|
||||
0xf8000001,
|
||||
0x7ffffe5f
|
||||
};
|
||||
|
||||
// check each key. if we're capturing events at a low level we
|
||||
// can query the keyboard state using GetKeyState(). if not we
|
||||
// resort to using our shadow keyboard state since the system's
|
||||
// shadow state won't be in sync (because our window is not
|
||||
// getting keyboard events).
|
||||
if (!m_lowLevel) {
|
||||
// use shadow keyboard state in m_keys
|
||||
for (UInt32 i = 0; i < 256; ++i) {
|
||||
if ((m_keys[i] & 0x80) != 0) {
|
||||
LOG((CLOG_DEBUG "locked by \"%s\"", g_vkToName[i]));
|
||||
return true;
|
||||
}
|
||||
// use shadow keyboard state in m_keys and m_buttons
|
||||
for (UInt32 i = 0; i < sizeof(m_buttons) / sizeof(m_buttons[0]); ++i) {
|
||||
if ((m_buttons[i] & 0x80) != 0) {
|
||||
LOG((CLOG_DEBUG "locked by \"%s\"", g_buttonToName[i]));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (UInt32 i = 0; i < 256 / 32; ++i) {
|
||||
for (UInt32 b = 1, j = 0; j < 32; b <<= 1, ++j) {
|
||||
if ((s_mappedKeys[i] & b) != 0) {
|
||||
if (GetKeyState(i * 32 + j) < 0) {
|
||||
LOG((CLOG_DEBUG "locked by \"%s\"", g_vkToName[i * 32 + j]));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (UInt32 i = 0; i < sizeof(m_keys) / sizeof(m_keys[0]); ++i) {
|
||||
if ((m_keys[i] & 0x80) != 0) {
|
||||
LOG((CLOG_DEBUG "locked by \"%s\"", g_vkToName[i]));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -583,16 +568,9 @@ CMSWindowsPrimaryScreen::onPreDispatch(const CEvent* event)
|
|||
return true;
|
||||
|
||||
case SYNERGY_MSG_MOUSE_BUTTON: {
|
||||
static const int s_vkButton[] = {
|
||||
0, // kButtonNone
|
||||
VK_LBUTTON, // kButtonLeft, etc.
|
||||
VK_MBUTTON,
|
||||
VK_RBUTTON
|
||||
};
|
||||
|
||||
// get which button
|
||||
bool pressed = false;
|
||||
const ButtonID button = mapButton(msg->wParam);
|
||||
const ButtonID button = mapButton(msg->wParam, msg->lParam);
|
||||
|
||||
// ignore message if posted prior to last mark change
|
||||
if (!ignore()) {
|
||||
|
@ -600,19 +578,22 @@ CMSWindowsPrimaryScreen::onPreDispatch(const CEvent* event)
|
|||
case WM_LBUTTONDOWN:
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_XBUTTONDOWN:
|
||||
case WM_LBUTTONDBLCLK:
|
||||
case WM_MBUTTONDBLCLK:
|
||||
case WM_RBUTTONDBLCLK:
|
||||
case WM_XBUTTONDBLCLK:
|
||||
case WM_NCLBUTTONDOWN:
|
||||
case WM_NCMBUTTONDOWN:
|
||||
case WM_NCRBUTTONDOWN:
|
||||
case WM_NCXBUTTONDOWN:
|
||||
case WM_NCLBUTTONDBLCLK:
|
||||
case WM_NCMBUTTONDBLCLK:
|
||||
case WM_NCRBUTTONDBLCLK:
|
||||
case WM_NCXBUTTONDBLCLK:
|
||||
LOG((CLOG_DEBUG1 "event: button press button=%d", button));
|
||||
if (button != kButtonNone) {
|
||||
m_receiver->onMouseDown(button);
|
||||
m_keys[s_vkButton[button]] |= 0x80;
|
||||
}
|
||||
pressed = true;
|
||||
break;
|
||||
|
@ -620,13 +601,14 @@ CMSWindowsPrimaryScreen::onPreDispatch(const CEvent* event)
|
|||
case WM_LBUTTONUP:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_RBUTTONUP:
|
||||
case WM_XBUTTONUP:
|
||||
case WM_NCLBUTTONUP:
|
||||
case WM_NCMBUTTONUP:
|
||||
case WM_NCRBUTTONUP:
|
||||
case WM_NCXBUTTONUP:
|
||||
LOG((CLOG_DEBUG1 "event: button release button=%d", button));
|
||||
if (button != kButtonNone) {
|
||||
m_receiver->onMouseUp(button);
|
||||
m_keys[s_vkButton[button]] &= ~0x80;
|
||||
}
|
||||
pressed = false;
|
||||
break;
|
||||
|
@ -634,8 +616,13 @@ CMSWindowsPrimaryScreen::onPreDispatch(const CEvent* event)
|
|||
}
|
||||
|
||||
// keep our shadow key state up to date
|
||||
if (button != kButtonNone) {
|
||||
updateKey(s_vkButton[button], pressed);
|
||||
if (button >= kButtonLeft && button <= kButtonExtra0 + 1) {
|
||||
if (pressed) {
|
||||
m_buttons[button] |= 0x80;
|
||||
}
|
||||
else {
|
||||
m_buttons[button] &= ~0x80;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1139,24 +1126,24 @@ static const KeyID g_virtualKey[][2] =
|
|||
/* 0xa3 */ kKeyControl_R, kKeyControl_R, // VK_RCONTROL
|
||||
/* 0xa4 */ kKeyAlt_L, kKeyAlt_L, // VK_LMENU
|
||||
/* 0xa5 */ kKeyAlt_R, kKeyAlt_R, // VK_RMENU
|
||||
/* 0xa6 */ kKeyNone, kKeyNone, // unassigned
|
||||
/* 0xa7 */ kKeyNone, kKeyNone, // unassigned
|
||||
/* 0xa8 */ kKeyNone, kKeyNone, // unassigned
|
||||
/* 0xa9 */ kKeyNone, kKeyNone, // unassigned
|
||||
/* 0xaa */ kKeyNone, kKeyNone, // unassigned
|
||||
/* 0xab */ kKeyNone, kKeyNone, // unassigned
|
||||
/* 0xac */ kKeyNone, kKeyNone, // unassigned
|
||||
/* 0xad */ kKeyNone, kKeyNone, // unassigned
|
||||
/* 0xae */ kKeyNone, kKeyNone, // unassigned
|
||||
/* 0xaf */ kKeyNone, kKeyNone, // unassigned
|
||||
/* 0xb0 */ kKeyNone, kKeyNone, // unassigned
|
||||
/* 0xb1 */ kKeyNone, kKeyNone, // unassigned
|
||||
/* 0xb2 */ kKeyNone, kKeyNone, // unassigned
|
||||
/* 0xb3 */ kKeyNone, kKeyNone, // unassigned
|
||||
/* 0xb4 */ kKeyNone, kKeyNone, // unassigned
|
||||
/* 0xb5 */ kKeyNone, kKeyNone, // unassigned
|
||||
/* 0xb6 */ kKeyNone, kKeyNone, // unassigned
|
||||
/* 0xb7 */ kKeyNone, kKeyNone, // unassigned
|
||||
/* 0xa6 */ kKeyNone, kKeyWWWBack, // VK_BROWSER_BACK
|
||||
/* 0xa7 */ kKeyNone, kKeyWWWForward, // VK_BROWSER_FORWARD
|
||||
/* 0xa8 */ kKeyNone, kKeyWWWRefresh, // VK_BROWSER_REFRESH
|
||||
/* 0xa9 */ kKeyNone, kKeyWWWStop, // VK_BROWSER_STOP
|
||||
/* 0xaa */ kKeyNone, kKeyWWWSearch, // VK_BROWSER_SEARCH
|
||||
/* 0xab */ kKeyNone, kKeyWWWFavorites, // VK_BROWSER_FAVORITES
|
||||
/* 0xac */ kKeyNone, kKeyWWWHome, // VK_BROWSER_HOME
|
||||
/* 0xad */ kKeyNone, kKeyAudioMute, // VK_VOLUME_MUTE
|
||||
/* 0xae */ kKeyNone, kKeyAudioDown, // VK_VOLUME_DOWN
|
||||
/* 0xaf */ kKeyNone, kKeyAudioUp, // VK_VOLUME_UP
|
||||
/* 0xb0 */ kKeyNone, kKeyAudioNext, // VK_MEDIA_NEXT_TRACK
|
||||
/* 0xb1 */ kKeyNone, kKeyAudioPrev, // VK_MEDIA_PREV_TRACK
|
||||
/* 0xb2 */ kKeyNone, kKeyAudioStop, // VK_MEDIA_STOP
|
||||
/* 0xb3 */ kKeyNone, kKeyAudioPlay, // VK_MEDIA_PLAY_PAUSE
|
||||
/* 0xb4 */ kKeyNone, kKeyAppMail, // VK_LAUNCH_MAIL
|
||||
/* 0xb5 */ kKeyNone, kKeyAppMedia, // VK_LAUNCH_MEDIA_SELECT
|
||||
/* 0xb6 */ kKeyNone, kKeyAppUser1, // VK_LAUNCH_APP1
|
||||
/* 0xb7 */ kKeyNone, kKeyAppUser2, // VK_LAUNCH_APP2
|
||||
/* 0xb8 */ kKeyNone, kKeyNone, // unassigned
|
||||
/* 0xb9 */ kKeyNone, kKeyNone, // unassigned
|
||||
/* 0xba */ kKeyNone, kKeyNone, // OEM specific
|
||||
|
@ -1407,9 +1394,9 @@ CMSWindowsPrimaryScreen::mapKey(
|
|||
}
|
||||
|
||||
ButtonID
|
||||
CMSWindowsPrimaryScreen::mapButton(WPARAM button) const
|
||||
CMSWindowsPrimaryScreen::mapButton(WPARAM msg, LPARAM button) const
|
||||
{
|
||||
switch (button) {
|
||||
switch (msg) {
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_LBUTTONDBLCLK:
|
||||
case WM_LBUTTONUP:
|
||||
|
@ -1434,6 +1421,21 @@ CMSWindowsPrimaryScreen::mapButton(WPARAM button) const
|
|||
case WM_NCRBUTTONUP:
|
||||
return kButtonRight;
|
||||
|
||||
case WM_XBUTTONDOWN:
|
||||
case WM_XBUTTONDBLCLK:
|
||||
case WM_XBUTTONUP:
|
||||
case WM_NCXBUTTONDOWN:
|
||||
case WM_NCXBUTTONDBLCLK:
|
||||
case WM_NCXBUTTONUP:
|
||||
switch (button) {
|
||||
case XBUTTON1:
|
||||
return kButtonExtra0 + 0;
|
||||
|
||||
case XBUTTON2:
|
||||
return kButtonExtra0 + 1;
|
||||
}
|
||||
return kButtonNone;
|
||||
|
||||
default:
|
||||
return kButtonNone;
|
||||
}
|
||||
|
@ -1446,8 +1448,9 @@ CMSWindowsPrimaryScreen::updateKeys()
|
|||
// up-to-date results. i don't know why that is or why GetKeyState()
|
||||
// should give different results.
|
||||
|
||||
// clear key state
|
||||
// clear key and button state
|
||||
memset(m_keys, 0, sizeof(m_keys));
|
||||
memset(m_buttons, 0, sizeof(m_buttons));
|
||||
|
||||
// we only care about the modifier key states. other keys and the
|
||||
// mouse buttons should be up.
|
||||
|
|
|
@ -87,7 +87,7 @@ private:
|
|||
// key and button queries
|
||||
KeyID mapKey(WPARAM keycode, LPARAM info,
|
||||
KeyModifierMask* maskOut);
|
||||
ButtonID mapButton(WPARAM button) const;
|
||||
ButtonID mapButton(WPARAM msg, LPARAM button) const;
|
||||
void updateKey(UINT vkCode, bool press);
|
||||
bool isModifier(UINT vkCode) const;
|
||||
|
||||
|
@ -108,6 +108,9 @@ private:
|
|||
// map of key state
|
||||
BYTE m_keys[256];
|
||||
|
||||
// map of button state
|
||||
BYTE m_buttons[1 + kButtonExtra0 + 1];
|
||||
|
||||
// last mouse position
|
||||
SInt32 m_x, m_y;
|
||||
|
||||
|
|
|
@ -28,6 +28,42 @@
|
|||
#define SPI_SETMOUSESPEED 113
|
||||
#endif
|
||||
|
||||
// X button stuff
|
||||
#if !defined(WM_XBUTTONDOWN)
|
||||
#define WM_XBUTTONDOWN 0x020B
|
||||
#define WM_XBUTTONUP 0x020C
|
||||
#define WM_XBUTTONDBLCLK 0x020D
|
||||
#define WM_NCXBUTTONDOWN 0x00AB
|
||||
#define WM_NCXBUTTONUP 0x00AC
|
||||
#define WM_NCXBUTTONDBLCLK 0x00AD
|
||||
#define MOUSEEVENTF_XDOWN 0x0100
|
||||
#define MOUSEEVENTF_XUP 0x0200
|
||||
#define XBUTTON1 0x0001
|
||||
#define XBUTTON2 0x0002
|
||||
#endif
|
||||
|
||||
// multimedia keys
|
||||
#if !defined(VK_BROWSER_BACK)
|
||||
#define VK_BROWSER_BACK 0xA6
|
||||
#define VK_BROWSER_FORWARD 0xA7
|
||||
#define VK_BROWSER_REFRESH 0xA8
|
||||
#define VK_BROWSER_STOP 0xA9
|
||||
#define VK_BROWSER_SEARCH 0xAA
|
||||
#define VK_BROWSER_FAVORITES 0xAB
|
||||
#define VK_BROWSER_HOME 0xAC
|
||||
#define VK_VOLUME_MUTE 0xAD
|
||||
#define VK_VOLUME_DOWN 0xAE
|
||||
#define VK_VOLUME_UP 0xAF
|
||||
#define VK_MEDIA_NEXT_TRACK 0xB0
|
||||
#define VK_MEDIA_PREV_TRACK 0xB1
|
||||
#define VK_MEDIA_STOP 0xB2
|
||||
#define VK_MEDIA_PLAY_PAUSE 0xB3
|
||||
#define VK_LAUNCH_MAIL 0xB4
|
||||
#define VK_LAUNCH_MEDIA_SELECT 0xB5
|
||||
#define VK_LAUNCH_APP1 0xB6
|
||||
#define VK_LAUNCH_APP2 0xB7
|
||||
#endif
|
||||
|
||||
//
|
||||
// CMSWindowsSecondaryScreen
|
||||
//
|
||||
|
@ -258,11 +294,12 @@ CMSWindowsSecondaryScreen::mouseDown(ButtonID button)
|
|||
m_screen->syncDesktop();
|
||||
|
||||
// map button id to button flag
|
||||
DWORD flags = mapButton(button, true);
|
||||
DWORD data;
|
||||
DWORD flags = mapButton(button, true, &data);
|
||||
|
||||
// send event
|
||||
if (flags != 0) {
|
||||
mouse_event(flags, 0, 0, 0, 0);
|
||||
mouse_event(flags, 0, 0, data, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -273,11 +310,12 @@ CMSWindowsSecondaryScreen::mouseUp(ButtonID button)
|
|||
m_screen->syncDesktop();
|
||||
|
||||
// map button id to button flag
|
||||
DWORD flags = mapButton(button, false);
|
||||
DWORD data;
|
||||
DWORD flags = mapButton(button, false, &data);
|
||||
|
||||
// send event
|
||||
if (flags != 0) {
|
||||
mouse_event(flags, 0, 0, 0, 0);
|
||||
mouse_event(flags, 0, 0, data, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -606,6 +644,48 @@ CMSWindowsSecondaryScreen::getToggleState() const
|
|||
// map special KeyID keys to virtual key codes. if the key is an
|
||||
// extended key then the entry is the virtual key code | 0x100.
|
||||
// unmapped keys have a 0 entry.
|
||||
static const UINT g_mapE000[] =
|
||||
{
|
||||
/* 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,
|
||||
/* 0xa4 */ 0, 0, VK_BROWSER_BACK|0x100, VK_BROWSER_FORWARD|0x100,
|
||||
/* 0xa8 */ VK_BROWSER_REFRESH|0x100, VK_BROWSER_STOP|0x100,
|
||||
/* 0xaa */ VK_BROWSER_SEARCH|0x100, VK_BROWSER_FAVORITES|0x100,
|
||||
/* 0xac */ VK_BROWSER_HOME|0x100, VK_VOLUME_MUTE|0x100,
|
||||
/* 0xae */ VK_VOLUME_DOWN|0x100, VK_VOLUME_UP|0x100,
|
||||
/* 0xb0 */ VK_MEDIA_NEXT_TRACK|0x100, VK_MEDIA_PREV_TRACK|0x100,
|
||||
/* 0xb2 */ VK_MEDIA_STOP|0x100, VK_MEDIA_PLAY_PAUSE|0x100,
|
||||
/* 0xb4 */ VK_LAUNCH_MAIL|0x100, VK_LAUNCH_MEDIA_SELECT|0x100,
|
||||
/* 0xb6 */ VK_LAUNCH_APP1|0x100, VK_LAUNCH_APP2|0x100,
|
||||
/* 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_mapEE00[] =
|
||||
{
|
||||
/* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
@ -685,8 +765,12 @@ static const UINT g_mapEF00[] =
|
|||
};
|
||||
|
||||
DWORD
|
||||
CMSWindowsSecondaryScreen::mapButton(ButtonID button, bool press) const
|
||||
CMSWindowsSecondaryScreen::mapButton(ButtonID button,
|
||||
bool press, DWORD* inData) const
|
||||
{
|
||||
DWORD dummy;
|
||||
DWORD* data = (inData != NULL) ? inData : &dummy;
|
||||
|
||||
// the system will swap the meaning of left/right for us if
|
||||
// the user has configured a left-handed mouse but we don't
|
||||
// want it to swap since we want the handedness of the
|
||||
|
@ -703,7 +787,8 @@ CMSWindowsSecondaryScreen::mapButton(ButtonID button, bool press) const
|
|||
}
|
||||
}
|
||||
|
||||
// map button id to button flag
|
||||
// map button id to button flag and button data
|
||||
*data = 0;
|
||||
switch (button) {
|
||||
case kButtonLeft:
|
||||
return press ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_LEFTUP;
|
||||
|
@ -714,6 +799,14 @@ CMSWindowsSecondaryScreen::mapButton(ButtonID button, bool press) const
|
|||
case kButtonRight:
|
||||
return press ? MOUSEEVENTF_RIGHTDOWN : MOUSEEVENTF_RIGHTUP;
|
||||
|
||||
case kButtonExtra0 + 0:
|
||||
*data = XBUTTON1;
|
||||
return press ? MOUSEEVENTF_XDOWN : MOUSEEVENTF_XUP;
|
||||
|
||||
case kButtonExtra0 + 1:
|
||||
*data = XBUTTON2;
|
||||
return press ? MOUSEEVENTF_XDOWN : MOUSEEVENTF_XUP;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -727,7 +820,10 @@ CMSWindowsSecondaryScreen::mapKey(Keystrokes& keys, UINT& virtualKey,
|
|||
|
||||
// check for special keys
|
||||
if ((id & 0xfffff000) == 0xe000) {
|
||||
if ((id & 0xff00) == 0xee00) {
|
||||
if ((id & 0xff00) == 0xe000) {
|
||||
virtualKey = g_mapE000[id & 0xff];
|
||||
}
|
||||
else if ((id & 0xff00) == 0xee00) {
|
||||
virtualKey = g_mapEE00[id & 0xff];
|
||||
}
|
||||
else if ((id & 0xff00) == 0xef00) {
|
||||
|
|
|
@ -98,7 +98,8 @@ private:
|
|||
bool isMultimon() const;
|
||||
|
||||
// key and button queries and operations
|
||||
DWORD mapButton(ButtonID button, bool press) const;
|
||||
DWORD mapButton(ButtonID button,
|
||||
bool press, DWORD* data) const;
|
||||
KeyModifierMask mapKey(Keystrokes&, UINT& virtualKey, KeyID,
|
||||
KeyModifierMask, EKeyAction) const;
|
||||
void doKeystrokes(const Keystrokes&, SInt32 count);
|
||||
|
|
|
@ -45,6 +45,20 @@ typedef struct tagMOUSEHOOKSTRUCTWin2000 {
|
|||
#define SM_MOUSEWHEELPRESENT 75
|
||||
#endif
|
||||
|
||||
// X button stuff
|
||||
#if !defined(WM_XBUTTONDOWN)
|
||||
#define WM_XBUTTONDOWN 0x020B
|
||||
#define WM_XBUTTONUP 0x020C
|
||||
#define WM_XBUTTONDBLCLK 0x020D
|
||||
#define WM_NCXBUTTONDOWN 0x00AB
|
||||
#define WM_NCXBUTTONUP 0x00AC
|
||||
#define WM_NCXBUTTONDBLCLK 0x00AD
|
||||
#define MOUSEEVENTF_XDOWN 0x0100
|
||||
#define MOUSEEVENTF_XUP 0x0200
|
||||
#define XBUTTON1 0x0001
|
||||
#define XBUTTON2 0x0002
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// globals
|
||||
|
@ -152,35 +166,41 @@ keyboardHookHandler(WPARAM wParam, LPARAM lParam)
|
|||
|
||||
static
|
||||
bool
|
||||
mouseHookHandler(WPARAM wParam, SInt32 x, SInt32 y, SInt32 wheel)
|
||||
mouseHookHandler(WPARAM wParam, SInt32 x, SInt32 y, SInt32 data)
|
||||
{
|
||||
switch (wParam) {
|
||||
case WM_LBUTTONDOWN:
|
||||
case WM_MBUTTONDOWN:
|
||||
case WM_RBUTTONDOWN:
|
||||
case WM_XBUTTONDOWN:
|
||||
case WM_LBUTTONDBLCLK:
|
||||
case WM_MBUTTONDBLCLK:
|
||||
case WM_RBUTTONDBLCLK:
|
||||
case WM_XBUTTONDBLCLK:
|
||||
case WM_LBUTTONUP:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_RBUTTONUP:
|
||||
case WM_XBUTTONUP:
|
||||
case WM_NCLBUTTONDOWN:
|
||||
case WM_NCMBUTTONDOWN:
|
||||
case WM_NCRBUTTONDOWN:
|
||||
case WM_NCXBUTTONDOWN:
|
||||
case WM_NCLBUTTONDBLCLK:
|
||||
case WM_NCMBUTTONDBLCLK:
|
||||
case WM_NCRBUTTONDBLCLK:
|
||||
case WM_NCXBUTTONDBLCLK:
|
||||
case WM_NCLBUTTONUP:
|
||||
case WM_NCMBUTTONUP:
|
||||
case WM_NCRBUTTONUP:
|
||||
case WM_NCXBUTTONUP:
|
||||
// always relay the event. eat it if relaying.
|
||||
PostThreadMessage(g_threadID, SYNERGY_MSG_MOUSE_BUTTON, wParam, 0);
|
||||
PostThreadMessage(g_threadID, SYNERGY_MSG_MOUSE_BUTTON, wParam, data);
|
||||
return g_relay;
|
||||
|
||||
case WM_MOUSEWHEEL:
|
||||
if (g_relay) {
|
||||
// relay event
|
||||
PostThreadMessage(g_threadID, SYNERGY_MSG_MOUSE_WHEEL, wheel, 0);
|
||||
PostThreadMessage(g_threadID, SYNERGY_MSG_MOUSE_WHEEL, data, 0);
|
||||
}
|
||||
return g_relay;
|
||||
|
||||
|
@ -276,7 +296,10 @@ mouseHook(int code, WPARAM wParam, LPARAM lParam)
|
|||
}
|
||||
}
|
||||
|
||||
// handle the message
|
||||
// handle the message. note that we don't handle X buttons
|
||||
// here. that's okay because they're only supported on
|
||||
// win2k and winxp and up and on those platforms we'll get
|
||||
// get the mouse events through the low level hook.
|
||||
if (mouseHookHandler(wParam, x, y, w)) {
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -699,6 +699,44 @@ CXWindowsPrimaryScreen::mapModifier(unsigned int state) const
|
|||
return mask;
|
||||
}
|
||||
|
||||
// map "Internet" keys to KeyIDs
|
||||
static const KeySym g_map1008FF[] =
|
||||
{
|
||||
/* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x08 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x10 */ 0, kKeyAudioDown, kKeyAudioMute, kKeyAudioUp,
|
||||
/* 0x14 */ kKeyAudioPlay, kKeyAudioStop, kKeyAudioPrev, kKeyAudioNext,
|
||||
/* 0x18 */ kKeyWWWHome, kKeyAppMail, 0, kKeyWWWSearch, 0, 0, 0, 0,
|
||||
/* 0x20 */ 0, 0, 0, 0, 0, 0, kKeyWWWBack, kKeyWWWForward,
|
||||
/* 0x28 */ kKeyWWWStop, kKeyWWWRefresh, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x30 */ kKeyWWWFavorites, 0, kKeyAppMedia, 0, 0, 0, 0, 0,
|
||||
/* 0x38 */ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* 0x40 */ kKeyAppUser1, kKeyAppUser2, 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
|
||||
};
|
||||
|
||||
KeyID
|
||||
CXWindowsPrimaryScreen::mapKey(XKeyEvent* event) const
|
||||
{
|
||||
|
@ -727,6 +765,10 @@ CXWindowsPrimaryScreen::mapKey(XKeyEvent* event) const
|
|||
// MISCELLANY
|
||||
return static_cast<KeyID>(keysym - 0xff00 + 0xef00);
|
||||
|
||||
case 0x1008ff00:
|
||||
// "Internet" keys
|
||||
return g_map1008FF[keysym & 0xff];
|
||||
|
||||
default: {
|
||||
// lookup character in table
|
||||
UInt32 key = CXWindowsUtil::mapKeySymToUCS4(keysym);
|
||||
|
@ -743,10 +785,18 @@ CXWindowsPrimaryScreen::mapKey(XKeyEvent* event) const
|
|||
ButtonID
|
||||
CXWindowsPrimaryScreen::mapButton(unsigned int button) const
|
||||
{
|
||||
// FIXME -- should use button mapping?
|
||||
// first three buttons map to 1, 2, 3 (kButtonLeft, Middle, Right)
|
||||
if (button >= 1 && button <= 3) {
|
||||
return static_cast<ButtonID>(button);
|
||||
}
|
||||
|
||||
// buttons 4 and 5 are ignored here. they're used for the wheel.
|
||||
// buttons 6, 7, etc and up map to 4, 5, etc.
|
||||
else if (button >= 6) {
|
||||
return static_cast<ButtonID>(button - 2);
|
||||
}
|
||||
|
||||
// unknown button
|
||||
else {
|
||||
return kButtonNone;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,9 @@
|
|||
# else
|
||||
# error The XTest extension is required to build synergy
|
||||
# endif
|
||||
# if defined(HAVE_X11_XF86KEYSYM_H)
|
||||
# include <X11/XF86keysym.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
//
|
||||
|
@ -263,7 +266,8 @@ void
|
|||
CXWindowsSecondaryScreen::mouseWheel(SInt32 delta)
|
||||
{
|
||||
// choose button depending on rotation direction
|
||||
const unsigned int xButton = mapButton((delta >= 0) ? 4 : 5);
|
||||
const unsigned int xButton = mapButton(static_cast<ButtonID>(
|
||||
(delta >= 0) ? -1 : -2));
|
||||
if (xButton == 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -573,17 +577,30 @@ CXWindowsSecondaryScreen::getToggleState() const
|
|||
unsigned int
|
||||
CXWindowsSecondaryScreen::mapButton(ButtonID id) const
|
||||
{
|
||||
// map button -1 to button 4 (+wheel)
|
||||
if (id == static_cast<ButtonID>(-1)) {
|
||||
id = 4;
|
||||
}
|
||||
|
||||
// map button -2 to button 5 (-wheel)
|
||||
else if (id == static_cast<ButtonID>(-2)) {
|
||||
id = 5;
|
||||
}
|
||||
|
||||
// map buttons 4, 5, etc. to 6, 7, etc. to make room for buttons
|
||||
// 4 and 5 used to simulate the mouse wheel.
|
||||
else if (id >= 4) {
|
||||
id += 2;
|
||||
}
|
||||
|
||||
// check button is in legal range
|
||||
if (id < 1 || id > m_buttons.size()) {
|
||||
// out of range
|
||||
return 0;
|
||||
}
|
||||
else if (m_buttons[id - 1] == 0) {
|
||||
// button not mapped
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return static_cast<unsigned int>(m_buttons[id - 1]);
|
||||
}
|
||||
|
||||
// map button
|
||||
return static_cast<unsigned int>(m_buttons[id - 1]);
|
||||
}
|
||||
|
||||
KeyModifierMask
|
||||
|
@ -1380,6 +1397,53 @@ CXWindowsSecondaryScreen::isToggleKeysym(KeySym key)
|
|||
}
|
||||
}
|
||||
|
||||
// map special KeyID keys to KeySyms
|
||||
#if defined(HAVE_X11_XF86KEYSYM_H)
|
||||
static const KeySym g_mapE000[] =
|
||||
{
|
||||
/* 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,
|
||||
/* 0xa4 */ 0, 0,
|
||||
/* 0xa6 */ XF86XK_Back, XF86XK_Forward,
|
||||
/* 0xa8 */ XF86XK_Refresh, XF86XK_Stop,
|
||||
/* 0xaa */ XF86XK_Search, XF86XK_Favorites,
|
||||
/* 0xac */ XF86XK_HomePage, XF86XK_AudioMute,
|
||||
/* 0xae */ XF86XK_AudioLowerVolume, XF86XK_AudioRaiseVolume,
|
||||
/* 0xb0 */ XF86XK_AudioNext, XF86XK_AudioPrev,
|
||||
/* 0xb2 */ XF86XK_AudioStop, XF86XK_AudioPlay,
|
||||
/* 0xb4 */ XF86XK_Mail, XF86XK_AudioMedia,
|
||||
/* 0xb6 */ XF86XK_Launch0, XF86XK_Launch1,
|
||||
/* 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
|
||||
};
|
||||
#endif
|
||||
|
||||
CXWindowsSecondaryScreen::KeyCodeIndex
|
||||
CXWindowsSecondaryScreen::findKey(KeyID id, KeyModifierMask& mask) const
|
||||
{
|
||||
|
@ -1388,6 +1452,12 @@ CXWindowsSecondaryScreen::findKey(KeyID id, KeyModifierMask& mask) const
|
|||
if ((id & 0xfffff000) == 0xe000) {
|
||||
// special character
|
||||
switch (id & 0x0000ff00) {
|
||||
#if defined(HAVE_X11_XF86KEYSYM_H)
|
||||
case 0xe000:
|
||||
keysym = g_mapE000[id & 0xff];
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 0xee00:
|
||||
// ISO 9995 Function and Modifier Keys
|
||||
if (id == kKeyLeftTab) {
|
||||
|
|
|
@ -70,8 +70,8 @@ static const KeyModifierID kKeyModifierIDLast = 6;
|
|||
|
||||
//! @name Key identifiers
|
||||
//@{
|
||||
// all identifiers except kKeyNone are equal to the corresponding
|
||||
// X11 keysym - 0x1000.
|
||||
// all identifiers except kKeyNone and those in 0xE000 to 0xE0FF
|
||||
// inclusive are equal to the corresponding X11 keysym - 0x1000.
|
||||
|
||||
// no key
|
||||
static const KeyID kKeyNone = 0x0000;
|
||||
|
@ -211,6 +211,27 @@ static const KeyID kKeyHyper_R = 0xEFEE; /* Right hyper */
|
|||
|
||||
// more function and modifier keys
|
||||
static const KeyID kKeyLeftTab = 0xEE20;
|
||||
|
||||
// extended keys
|
||||
static const KeyID kKeyWWWBack = 0xE0A6;
|
||||
static const KeyID kKeyWWWForward = 0xE0A7;
|
||||
static const KeyID kKeyWWWRefresh = 0xE0A8;
|
||||
static const KeyID kKeyWWWStop = 0xE0A9;
|
||||
static const KeyID kKeyWWWSearch = 0xE0AA;
|
||||
static const KeyID kKeyWWWFavorites = 0xE0AB;
|
||||
static const KeyID kKeyWWWHome = 0xE0AC;
|
||||
static const KeyID kKeyAudioMute = 0xE0AD;
|
||||
static const KeyID kKeyAudioDown = 0xE0AE;
|
||||
static const KeyID kKeyAudioUp = 0xE0AF;
|
||||
static const KeyID kKeyAudioNext = 0xE0B0;
|
||||
static const KeyID kKeyAudioPrev = 0xE0B1;
|
||||
static const KeyID kKeyAudioStop = 0xE0B2;
|
||||
static const KeyID kKeyAudioPlay = 0xE0B3;
|
||||
static const KeyID kKeyAppMail = 0xE0B4;
|
||||
static const KeyID kKeyAppMedia = 0xE0B5;
|
||||
static const KeyID kKeyAppUser1 = 0xE0B6;
|
||||
static const KeyID kKeyAppUser2 = 0xE0B7;
|
||||
|
||||
//@}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -29,6 +29,7 @@ static const ButtonID kButtonNone = 0;
|
|||
static const ButtonID kButtonLeft = 1;
|
||||
static const ButtonID kButtonMiddle = 2;
|
||||
static const ButtonID kButtonRight = 3;
|
||||
static const ButtonID kButtonExtra0 = 4;
|
||||
//@}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue