⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vnckeymap.cpp

📁 realvnc是一个非常流行的远程控制程序
💻 CPP
字号:
//  Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.//  Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.////  This file is part of the VNC system.////  The VNC system is free software; you can redistribute it and/or modify//  it under the terms of the GNU General Public License as published by//  the Free Software Foundation; either version 2 of the License, or//  (at your option) any later version.////  This program is distributed in the hope that it will be useful,//  but WITHOUT ANY WARRANTY; without even the implied warranty of//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the//  GNU General Public License for more details.////  You should have received a copy of the GNU General Public License//  along with this program; if not, write to the Free Software//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,//  USA.//// If the source code for the program is not available from the place from// which you received this file, check http://www.realvnc.com/ or contact// the authors on info@realvnc.com for information on obtaining it.// vncKeymap.cpp// This code originally just mapped between X keysyms and local Windows// virtual keycodes.  Now it actually does the local-end simulation of// key presses, to keep this messy code on one place!#include "vncKeymap.h"#include <rdr/types.h>#define XK_MISCELLANY#include "keysymdef.h"#include "vncService.h"#include <map>// Mapping of X keysyms to windows VK codes.  Ordering here is the same as// keysymdef.h to make checking easierstruct keymap_t {  rdr::U32 keysym;  rdr::U8 vk;  bool extended;};static keymap_t keymap[] = {  // TTY functions  { XK_BackSpace,        VK_BACK, 0 },  { XK_Tab,              VK_TAB, 0 },  { XK_Clear,            VK_CLEAR, 0 },  { XK_Return,           VK_RETURN, 0 },  { XK_Pause,            VK_PAUSE, 0 },  { XK_Escape,           VK_ESCAPE, 0 },  { XK_Delete,           VK_DELETE, 1 },  // Japanese stuff - almost certainly wrong...  { XK_Kanji,            VK_KANJI, 0 },  { XK_Kana_Shift,       VK_KANA, 0 },  // Cursor control & motion  { XK_Home,             VK_HOME, 1 },  { XK_Left,             VK_LEFT, 1 },  { XK_Up,               VK_UP, 1 },  { XK_Right,            VK_RIGHT, 1 },  { XK_Down,             VK_DOWN, 1 },  { XK_Page_Up,          VK_PRIOR, 1 },  { XK_Page_Down,        VK_NEXT, 1 },  { XK_End,              VK_END, 1 },  // Misc functions  { XK_Select,           VK_SELECT, 0 },  { XK_Print,            VK_SNAPSHOT, 0 },  { XK_Execute,          VK_EXECUTE, 0 },  { XK_Insert,           VK_INSERT, 1 },  { XK_Help,             VK_HELP, 0 },  { XK_Break,            VK_CANCEL, 1 },  // Keypad Functions, keypad numbers  { XK_KP_Space,         VK_SPACE, 0 },  { XK_KP_Tab,           VK_TAB, 0 },  { XK_KP_Enter,         VK_RETURN, 1 },  { XK_KP_F1,            VK_F1, 0 },  { XK_KP_F2,            VK_F2, 0 },  { XK_KP_F3,            VK_F3, 0 },  { XK_KP_F4,            VK_F4, 0 },  { XK_KP_Home,          VK_HOME, 0 },  { XK_KP_Left,          VK_LEFT, 0 },  { XK_KP_Up,            VK_UP, 0 },  { XK_KP_Right,         VK_RIGHT, 0 },  { XK_KP_Down,          VK_DOWN, 0 },  { XK_KP_End,           VK_END, 0 },  { XK_KP_Page_Up,       VK_PRIOR, 0 },  { XK_KP_Page_Down,     VK_NEXT, 0 },  { XK_KP_Begin,         VK_CLEAR, 0 },  { XK_KP_Insert,        VK_INSERT, 0 },  { XK_KP_Delete,        VK_DELETE, 0 },  // XXX XK_KP_Equal should map in the same way as ascii '='  { XK_KP_Multiply,      VK_MULTIPLY, 0 },  { XK_KP_Add,           VK_ADD, 0 },  { XK_KP_Separator,     VK_SEPARATOR, 0 },  { XK_KP_Subtract,      VK_SUBTRACT, 0 },  { XK_KP_Decimal,       VK_DECIMAL, 0 },  { XK_KP_Divide,        VK_DIVIDE, 1 },  { XK_KP_0,             VK_NUMPAD0, 0 },  { XK_KP_1,             VK_NUMPAD1, 0 },  { XK_KP_2,             VK_NUMPAD2, 0 },  { XK_KP_3,             VK_NUMPAD3, 0 },  { XK_KP_4,             VK_NUMPAD4, 0 },  { XK_KP_5,             VK_NUMPAD5, 0 },  { XK_KP_6,             VK_NUMPAD6, 0 },  { XK_KP_7,             VK_NUMPAD7, 0 },  { XK_KP_8,             VK_NUMPAD8, 0 },  { XK_KP_9,             VK_NUMPAD9, 0 },  // Auxilliary Functions  { XK_F1,               VK_F1, 0 },  { XK_F2,               VK_F2, 0 },  { XK_F3,               VK_F3, 0 },  { XK_F4,               VK_F4, 0 },  { XK_F5,               VK_F5, 0 },  { XK_F6,               VK_F6, 0 },  { XK_F7,               VK_F7, 0 },  { XK_F8,               VK_F8, 0 },  { XK_F9,               VK_F9, 0 },  { XK_F10,              VK_F10, 0 },  { XK_F11,              VK_F11, 0 },  { XK_F12,              VK_F12, 0 },  { XK_F13,              VK_F13, 0 },  { XK_F14,              VK_F14, 0 },  { XK_F15,              VK_F15, 0 },  { XK_F16,              VK_F16, 0 },  { XK_F17,              VK_F17, 0 },  { XK_F18,              VK_F18, 0 },  { XK_F19,              VK_F19, 0 },  { XK_F20,              VK_F20, 0 },  { XK_F21,              VK_F21, 0 },  { XK_F22,              VK_F22, 0 },  { XK_F23,              VK_F23, 0 },  { XK_F24,              VK_F24, 0 },    // Modifiers      { XK_Shift_L,          VK_SHIFT, 0 },  { XK_Shift_R,          VK_RSHIFT, 0 },  { XK_Control_L,        VK_CONTROL, 0 },  { XK_Control_R,        VK_CONTROL, 1 },  { XK_Alt_L,            VK_MENU, 0 },  { XK_Alt_R,            VK_RMENU, 1 },};// doKeyboardEvent wraps the system keybd_event function and attempts to find// the appropriate scancode corresponding to the supplied virtual keycode.inline void doKeyboardEvent(BYTE vkCode, DWORD flags) {  keybd_event(vkCode, MapVirtualKey(vkCode, 0), flags, 0);}// KeyStateModifier is a class which helps simplify generating a "fake" press// or release of shift, ctrl, alt, etc.  An instance of the class is created// for every key which may need to be pressed or released.  Then either press()// or release() may be called to make sure that the corresponding key is in the// right state.  The destructor of the class automatically reverts to the// previous state.class KeyStateModifier {public:  KeyStateModifier(int vkCode_, int flags_=0)    : vkCode(vkCode_), flags(flags_), pressed(false), released(false)  {}  void press() {    if (!(GetAsyncKeyState(vkCode) & 0x8000)) {      doKeyboardEvent(vkCode, flags);      vnclog.Print(LL_INTINFO, "fake %d down\n", vkCode);      pressed = true;    }  }  void release() {    if (GetAsyncKeyState(vkCode) & 0x8000) {      doKeyboardEvent(vkCode, flags | KEYEVENTF_KEYUP);      vnclog.Print(LL_INTINFO, "fake %d up\n", vkCode);      released = true;    }  }  ~KeyStateModifier() {    if (pressed) {      doKeyboardEvent(vkCode, flags | KEYEVENTF_KEYUP);      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.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;    }  }  void keyEvent(rdr::U32 keysym, bool down)  {    if ((keysym >= 32 && keysym <= 126) ||        (keysym >= 160 && keysym <= 255))    {      // ordinary Latin-1 character      SHORT s = VkKeyScan(keysym);      if (s == -1) {        vnclog.Print(LL_INTWARN, "ignoring unrecognised Latin-1 keysym %d\n",                     keysym);        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);}voidSetShiftState(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");}voidvncKeymap::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 + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -