vnckeymap.cpp
来自「这是一个比较复杂的远程控制工具,分为服务器与客户斋,让你了解socket编程的知」· C++ 代码 · 共 721 行 · 第 1/2 页
CPP
721 行
vnclog.Print(LL_INTINFO, "fake %d up\n", vkCode);
} else if (released) {
doKeyboardEvent(vkCode, flags);
vnclog.Print(LL_INTINFO, "fake %d down\n", vkCode);
}
}
int vkCode;
int flags;
bool pressed;
bool released;
};
// Keymapper - a single instance of this class is used to generate Windows key
// events.
void doKeyEventWithModifiers(BYTE vkCode, BYTE modifierState, bool down)
{
KeyStateModifier ctrl(VK_CONTROL);
KeyStateModifier alt(VK_MENU);
KeyStateModifier shift(VK_SHIFT);
if (down) {
if (modifierState & 2) ctrl.press();
if (modifierState & 4) alt.press();
if (modifierState & 1) {
shift.press();
} else {
shift.release();
}
}
doKeyboardEvent(vkCode, down ? 0 : KEYEVENTF_KEYUP);
}
class Keymapper {
public:
Keymapper()
{
for (int i = 0; i < sizeof(keymap) / sizeof(keymap_t); i++) {
vkMap[keymap[i].keysym] = keymap[i].vk;
extendedMap[keymap[i].keysym] = keymap[i].extended;
}
// Find dead characters for the current keyboard layout
// XXX how could we handle the keyboard layout changing?
BYTE keystate[256];
memset(keystate, 0, 256);
for (int j = 0; j < sizeof(latin1DeadChars); j++) {
SHORT s = VkKeyScan(latin1DeadChars[j]);
if (s != -1) {
BYTE vkCode = LOBYTE(s);
BYTE modifierState = HIBYTE(s);
keystate[VK_SHIFT] = (modifierState & 1) ? 0x80 : 0;
keystate[VK_CONTROL] = (modifierState & 2) ? 0x80 : 0;
keystate[VK_MENU] = (modifierState & 4) ? 0x80 : 0;
rdr::U8 chars[2];
int nchars = ToAscii(vkCode, 0, keystate, (WORD*)&chars, 0);
if (nchars < 0) {
vnclog.Print(LL_INTWARN, "Found dead key 0x%x '%c'",
latin1DeadChars[j], latin1DeadChars[j]);
deadChars.push_back(latin1DeadChars[j]);
ToAscii(vkCode, 0, keystate, (WORD*)&chars, 0);
}
}
}
}
void keyEvent(rdr::U32 keysym, bool down)
{
vnclog.Print(LL_INTWARN, " keysym 0x%x",keysym);
if (keysym>=XK_dead_grave && keysym <=XK_dead_belowdot)// && down)
{
keysymDead=keysym;
vnclog.Print(LL_INTWARN, " ************** DEAD KEY");
//we have a dead key
//Record dead key
return;
}
if ((keysym >= 32 && keysym <= 126) ||
(keysym >= 160 && keysym <= 255))
{
if (keysymDead!=0 && down)
{
vnclog.Print(LL_INTWARN, " Compose dead 0x%x 0x%x",keysymDead,keysym);
switch (keysymDead)
{
case XK_dead_grave:
switch(keysym)
{
case XK_A: keysym=XK_Agrave;break;
case XK_E: keysym=XK_Egrave;break;
case XK_I: keysym=XK_Igrave;break;
case XK_O: keysym=XK_Ograve;break;
case XK_U: keysym=XK_Ugrave;break;
case XK_a: keysym=XK_agrave;break;
case XK_e: keysym=XK_egrave;break;
case XK_i: keysym=XK_igrave;break;
case XK_o: keysym=XK_ograve;break;
case XK_u: keysym=XK_ugrave;break;
}
case XK_dead_acute:
switch(keysym)
{
case XK_A: keysym=XK_Aacute;break;
case XK_E: keysym=XK_Eacute;break;
case XK_I: keysym=XK_Iacute;break;
case XK_O: keysym=XK_Oacute;break;
case XK_U: keysym=XK_Uacute;break;
case XK_a: keysym=XK_aacute;break;
case XK_e: keysym=XK_eacute;break;
case XK_i: keysym=XK_iacute;break;
case XK_o: keysym=XK_oacute;break;
case XK_u: keysym=XK_uacute;break;
case XK_y: keysym=XK_yacute;break;
case XK_Y: keysym=XK_Yacute;break;
}
case XK_dead_circumflex:
switch(keysym)
{
case XK_A: keysym=XK_Acircumflex;break;
case XK_E: keysym=XK_Ecircumflex;break;
case XK_I: keysym=XK_Icircumflex;break;
case XK_O: keysym=XK_Ocircumflex;break;
case XK_U: keysym=XK_Ucircumflex;break;
case XK_a: keysym=XK_acircumflex;break;
case XK_e: keysym=XK_ecircumflex;break;
case XK_i: keysym=XK_icircumflex;break;
case XK_o: keysym=XK_ocircumflex;break;
case XK_u: keysym=XK_ucircumflex;break;
}
case XK_dead_tilde:
switch(keysym)
{
case XK_A : keysym=XK_Ntilde;break;
case XK_O : keysym=XK_Otilde;break;
case XK_a : keysym=XK_atilde;break;
case XK_n : keysym=XK_ntilde;break;
case XK_o : keysym=XK_otilde;break;
}
case XK_dead_diaeresis:
switch(keysym)
{
case XK_A: keysym=XK_Adiaeresis;break;
case XK_E: keysym=XK_Ediaeresis;break;
case XK_I: keysym=XK_Idiaeresis;break;
case XK_O: keysym=XK_Odiaeresis;break;
case XK_U: keysym=XK_Udiaeresis;break;
case XK_a: keysym=XK_adiaeresis;break;
case XK_e: keysym=XK_ediaeresis;break;
case XK_i: keysym=XK_idiaeresis;break;
case XK_o: keysym=XK_odiaeresis;break;
case XK_u: keysym=XK_udiaeresis;break;
case XK_y: keysym=XK_ydiaeresis;break;
}
case XK_dead_cedilla:
switch(keysym)
{
case XK_C: keysym=XK_Ccedilla;break;
case XK_c: keysym=XK_ccedilla;break;
}
}
keysymDead=0;
vnclog.Print(LL_INTWARN, " Composed 0x%x",keysym);
}
// ordinary Latin-1 character
SHORT s = VkKeyScan(keysym);
vnclog.Print(LL_INTWARN, " SHORT s %i",s);
if (s == -1)
{
if (down) {
vnclog.Print(LL_INTWARN, "down");
// not a single keypress - try synthesizing dead chars.
{
vnclog.Print(LL_INTWARN, " Found key");
//Lookup ascii representation
int ascii=0;
for (ascii=0;ascii<256;ascii++)
{
if (keysym==ascii_to_x[ascii]) break;
}
rdr::U8 a0=ascii/100;
ascii=ascii%100;
rdr::U8 a1=ascii/10;
ascii=ascii%10;
rdr::U8 a2=ascii;
if (ascii!=255)
{
keybd_event(VK_MENU,MapVirtualKey( VK_MENU, 0 ), 0 ,0);
keybd_event(VK_NUMPAD0+a0, MapVirtualKey(VK_NUMPAD0+a0, 0), 0, 0);
keybd_event(VK_NUMPAD0+a0, MapVirtualKey(VK_NUMPAD0+a0, 0),KEYEVENTF_KEYUP,0);
keybd_event(VK_NUMPAD0+a1, MapVirtualKey(VK_NUMPAD0+a1, 0),0,0);
keybd_event(VK_NUMPAD0+a1, MapVirtualKey(VK_NUMPAD0+a1, 0),KEYEVENTF_KEYUP, 0);
keybd_event(VK_NUMPAD0+a2, MapVirtualKey(VK_NUMPAD0+a2, 0) ,0, 0);
keybd_event(VK_NUMPAD0+a2, MapVirtualKey(VK_NUMPAD0+a2, 0),KEYEVENTF_KEYUP, 0);
keybd_event(VK_MENU, MapVirtualKey( VK_MENU, 0 ),KEYEVENTF_KEYUP, 0);
return;
}
}
vnclog.Print(LL_INTWARN, "ignoring unrecognised Latin-1 keysym 0x%x",keysym);
}
return;
}
/*if (s == -1) {
vnclog.Print(LL_INTWARN, "ignoring unrecognised Latin-1 keysym %d\n",
keysym);
keybd_event( VK_MENU, MapVirtualKey(VK_MENU, 0),0, 0);
keybd_event( VK_MENU, MapVirtualKey(VK_MENU, 0),KEYEVENTF_KEYUP, 0);
return;
}*/
BYTE vkCode = LOBYTE(s);
KeyStateModifier ctrl(VK_CONTROL);
KeyStateModifier alt(VK_MENU);
KeyStateModifier shift(VK_SHIFT);
KeyStateModifier lshift(VK_LSHIFT);
KeyStateModifier rshift(VK_RSHIFT);
if (down) {
BYTE modifierState = HIBYTE(s);
if (modifierState & 2) ctrl.press();
if (modifierState & 4) alt.press();
if (modifierState & 1) {
shift.press();
} else {
if (vncService::IsWin95()) {
shift.release();
} else {
lshift.release();
rshift.release();
}
}
}
vnclog.Print(LL_INTINFO,
"latin-1 key: keysym %d(0x%x) vkCode 0x%x down %d\n",
keysym, keysym, vkCode, down);
doKeyboardEvent(vkCode, down ? 0 : KEYEVENTF_KEYUP);
} else {
// see if it's a recognised keyboard key, otherwise ignore it
if (vkMap.find(keysym) == vkMap.end()) {
vnclog.Print(LL_INTWARN, "ignoring unknown keysym %d\n",keysym);
return;
}
BYTE vkCode = vkMap[keysym];
DWORD flags = 0;
if (extendedMap[keysym]) flags |= KEYEVENTF_EXTENDEDKEY;
if (!down) flags |= KEYEVENTF_KEYUP;
// vnclog.Print(LL_INTINFO,
// "keyboard key: keysym %d(0x%x) vkCode 0x%x ext %d down %d\n",
// keysym, keysym, vkCode, extendedMap[keysym], down);
if (down && (vkCode == VK_DELETE) &&
((GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0) &&
((GetAsyncKeyState(VK_MENU) & 0x8000) != 0) &&
vncService::IsWinNT())
{
vncService::SimulateCtrlAltDel();
return;
}
if (vncService::IsWin95()) {
switch (vkCode) {
case VK_RSHIFT: vkCode = VK_SHIFT; break;
case VK_RCONTROL: vkCode = VK_CONTROL; break;
case VK_RMENU: vkCode = VK_MENU; break;
}
}
doKeyboardEvent(vkCode, flags);
}
}
private:
std::map<rdr::U32,rdr::U8> vkMap;
std::map<rdr::U32,bool> extendedMap;
} key_mapper;
void vncKeymap::keyEvent(CARD32 keysym, bool down)
{
key_mapper.keyEvent(keysym, down);
}
void
SetShiftState(BYTE key, BOOL down)
{
BOOL keystate = (GetAsyncKeyState(key) & 0x8000) != 0;
// This routine sets the specified key to the desired value (up or down)
if ((keystate && down) || ((!keystate) && (!down)))
return;
vnclog.Print(LL_INTINFO,
VNCLOG("setshiftstate %d - (%s->%s)\n"),
key, keystate ? "down" : "up",
down ? "down" : "up");
// Now send a key event to set the key to the new value
doKeyboardEvent(key, down ? 0 : KEYEVENTF_KEYUP);
keystate = (GetAsyncKeyState(key) & 0x8000) != 0;
vnclog.Print(LL_INTINFO,
VNCLOG("new state %d (%s)\n"),
key, keystate ? "down" : "up");
}
void
vncKeymap::ClearShiftKeys()
{
if (vncService::IsWinNT())
{
// On NT, clear both sets of keys
// LEFT
SetShiftState(VK_LSHIFT, FALSE);
SetShiftState(VK_LCONTROL, FALSE);
SetShiftState(VK_LMENU, FALSE);
// RIGHT
SetShiftState(VK_RSHIFT, FALSE);
SetShiftState(VK_RCONTROL, FALSE);
SetShiftState(VK_RMENU, FALSE);
}
else
{
// Otherwise, we can't distinguish the keys anyway...
// Clear the shift key states
SetShiftState(VK_SHIFT, FALSE);
SetShiftState(VK_CONTROL, FALSE);
SetShiftState(VK_MENU, FALSE);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?