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

📄 xserverdesktop.cc

📁 linux可以运行程序源码
💻 CC
📖 第 1 页 / 共 3 页
字号:
class ModifierState {public:  ModifierState(DeviceIntPtr dev_, int modIndex_)    : dev(dev_), modIndex(modIndex_), nKeys(0), keys(0), pressed(false)  {  }  ~ModifierState() {    for (int i = 0; i < nKeys; i++)      generateXKeyEvent(keys[i], !pressed);    delete [] keys;  }  void press() {    KeyClassPtr keyc = dev->key;    if (!(keyc->state & (1<<modIndex))) {      tempKeyEvent(keyc->modifierKeyMap[modIndex * keyc->maxKeysPerModifier],                   true);      pressed = true;    }  }  void release() {    KeyClassPtr keyc = dev->key;    if (keyc->state & (1<<modIndex)) {      for (int k = 0; k < keyc->maxKeysPerModifier; k++) {        int keycode          = keyc->modifierKeyMap[modIndex * keyc->maxKeysPerModifier + k];        if (keycode && IS_PRESSED(keyc, keycode))          tempKeyEvent(keycode, false);      }    }  }private:  void tempKeyEvent(int keycode, bool down) {    if (keycode) {      if (!keys) keys = new int[dev->key->maxKeysPerModifier];      keys[nKeys++] = keycode;      generateXKeyEvent(keycode, down);    }  }  void generateXKeyEvent(int keycode, bool down) {    xEvent ev;    ev.u.u.type = down ? KeyPress : KeyRelease;    ev.u.u.detail = keycode;    ev.u.keyButtonPointer.time = GetTimeInMillis();    (*dev->c_public.processInputProc)(&ev, dev, 1);    vlog.debug("fake keycode %d %s", keycode, down ? "down" : "up");  }  DeviceIntPtr dev;  int modIndex;  int nKeys;  int* keys;  bool pressed;};// altKeysym is a table of alternative keysyms which have the same meaning.struct altKeysym_t {  KeySym a, b;};altKeysym_t altKeysym[] = {  { XK_Shift_L,        XK_Shift_R },  { XK_Control_L,      XK_Control_R },  { XK_Meta_L,         XK_Meta_R },  { XK_Alt_L,          XK_Alt_R },  { XK_Super_L,        XK_Super_R },  { XK_Hyper_L,        XK_Hyper_R },  { XK_KP_Space,       XK_space },  { XK_KP_Tab,         XK_Tab },  { XK_KP_Enter,       XK_Return },  { XK_KP_F1,          XK_F1 },  { XK_KP_F2,          XK_F2 },  { XK_KP_F3,          XK_F3 },  { XK_KP_F4,          XK_F4 },  { XK_KP_Home,        XK_Home },  { XK_KP_Left,        XK_Left },  { XK_KP_Up,          XK_Up },  { XK_KP_Right,       XK_Right },  { XK_KP_Down,        XK_Down },  { XK_KP_Page_Up,     XK_Page_Up },  { XK_KP_Page_Down,   XK_Page_Down },  { XK_KP_End,         XK_End },  { XK_KP_Begin,       XK_Begin },  { XK_KP_Insert,      XK_Insert },  { XK_KP_Delete,      XK_Delete },  { XK_KP_Equal,       XK_equal },  { XK_KP_Multiply,    XK_asterisk },  { XK_KP_Add,         XK_plus },  { XK_KP_Separator,   XK_comma },  { XK_KP_Subtract,    XK_minus },  { XK_KP_Decimal,     XK_period },  { XK_KP_Divide,      XK_slash },  { XK_KP_0,           XK_0 },  { XK_KP_1,           XK_1 },  { XK_KP_2,           XK_2 },  { XK_KP_3,           XK_3 },  { XK_KP_4,           XK_4 },  { XK_KP_5,           XK_5 },  { XK_KP_6,           XK_6 },  { XK_KP_7,           XK_7 },  { XK_KP_8,           XK_8 },  { XK_KP_9,           XK_9 },};// keyEvent() - work out the best keycode corresponding to the keysym sent by// the viewer.  This is non-trivial because we can't assume much about the// local keyboard layout.  We must also find out which column of the keyboard// mapping the keysym is in, and alter the shift state appropriately.  Column 0// means both shift and "mode_switch" (AltGr) must be released, column 1 means// shift must be pressed and mode_switch released, column 2 means shift must be// released and mode_switch pressed, and column 3 means both shift and// mode_switch must be pressed.void XserverDesktop::keyEvent(rdr::U32 keysym, bool down){  if (keysym == XK_Caps_Lock) {    vlog.debug("Ignoring caps lock");    return;  }  DeviceIntPtr dev = (DeviceIntPtr)LookupKeyboardDevice();  KeyClassPtr keyc = dev->key;  KeySymsPtr keymap = &keyc->curKeySyms;  // find which modifier Mode_switch is on.  int modeSwitchMapIndex = 0;  for (int i = 3; i < 8; i++) {    for (int k = 0; k < keyc->maxKeysPerModifier; k++) {      int keycode = keyc->modifierKeyMap[i * keyc->maxKeysPerModifier + k];      for (int j = 0; j < keymap->mapWidth; j++) {        if (keycode != 0 &&            keymap->map[(keycode - keymap->minKeyCode)                        * keymap->mapWidth + j] == XK_Mode_switch)        {          modeSwitchMapIndex = i;          break;        }      }    }  }  int col = 0;  if (keyc->state & (1<<ShiftMapIndex)) col |= 1;  if (modeSwitchMapIndex && (keyc->state & (1<<modeSwitchMapIndex))) col |= 2;  int kc = KeysymToKeycode(keymap, keysym, &col);  // Sort out the "shifted Tab" mess.  If we are sent a shifted Tab, generate a  // local shifted Tab regardless of what the "shifted Tab" keysym is on the  // local keyboard (it might be Tab, ISO_Left_Tab or HP's private BackTab  // keysym, and quite possibly some others too).  We never get ISO_Left_Tab  // here because it's already been translated in VNCSConnectionST.  if (keysym == XK_Tab && (keyc->state & (1<<ShiftMapIndex)))    col |= 1;  if (kc == 0) {    // Not a direct match in the local keyboard mapping.  Check for alternative    // keysyms with the same meaning.    for (int i = 0; i < sizeof(altKeysym) / sizeof(altKeysym_t); i++) {      if (keysym == altKeysym[i].a)        kc = KeysymToKeycode(keymap, altKeysym[i].b, &col);      else if (keysym == altKeysym[i].b)        kc = KeysymToKeycode(keymap, altKeysym[i].a, &col);      if (kc) break;    }  }  if (kc == 0) {    // Last resort - dynamically add a new key to the keyboard mapping.    for (kc = keymap->maxKeyCode; kc >= keymap->minKeyCode; kc--) {      if (!keymap->map[(kc - keymap->minKeyCode) * keymap->mapWidth]) {        keymap->map[(kc - keymap->minKeyCode) * keymap->mapWidth] = keysym;        col = 0;        SendMappingNotify(MappingKeyboard, kc, 1, serverClient);        vlog.info("Added unknown keysym 0x%x to keycode %d",keysym,kc);        break;      }    }    if (kc < keymap->minKeyCode) {      vlog.info("Keyboard mapping full - ignoring unknown keysym 0x%x",keysym);      return;    }  }  // See if it's a modifier key.  If so, then don't do any auto-repeat, because  // the X server will translate each press into a release followed by a press.  for (int i = 0; i < 8; i++) {    for (int k = 0; k < keyc->maxKeysPerModifier; k++) {      if (kc == keyc->modifierKeyMap[i * keyc->maxKeysPerModifier + k] &&          IS_PRESSED(keyc,kc) && down)        return;    }  }  ModifierState shift(dev, ShiftMapIndex);  ModifierState modeSwitch(dev, modeSwitchMapIndex);  if (down) {    if (col & 1)      shift.press();    else      shift.release();    if (modeSwitchMapIndex) {      if (col & 2)        modeSwitch.press();      else        modeSwitch.release();    }  }  vlog.debug("keycode %d %s", kc, down ? "down" : "up");  xEvent ev;  ev.u.u.type = down ? KeyPress : KeyRelease;  ev.u.u.detail = kc;  ev.u.keyButtonPointer.time = GetTimeInMillis();  (*dev->c_public.processInputProc)(&ev, dev, 1);}void XConvertCase(KeySym sym, KeySym *lower, KeySym *upper){    *lower = sym;    *upper = sym;    switch(sym >> 8) {    case 0: /* Latin 1 */	if ((sym >= XK_A) && (sym <= XK_Z))	    *lower += (XK_a - XK_A);	else if ((sym >= XK_a) && (sym <= XK_z))	    *upper -= (XK_a - XK_A);	else if ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis))	    *lower += (XK_agrave - XK_Agrave);	else if ((sym >= XK_agrave) && (sym <= XK_odiaeresis))	    *upper -= (XK_agrave - XK_Agrave);	else if ((sym >= XK_Ooblique) && (sym <= XK_Thorn))	    *lower += (XK_oslash - XK_Ooblique);	else if ((sym >= XK_oslash) && (sym <= XK_thorn))	    *upper -= (XK_oslash - XK_Ooblique);	break;    case 1: /* Latin 2 */	/* Assume the KeySym is a legal value (ignore discontinuities) */	if (sym == XK_Aogonek)	    *lower = XK_aogonek;	else if (sym >= XK_Lstroke && sym <= XK_Sacute)	    *lower += (XK_lstroke - XK_Lstroke);	else if (sym >= XK_Scaron && sym <= XK_Zacute)	    *lower += (XK_scaron - XK_Scaron);	else if (sym >= XK_Zcaron && sym <= XK_Zabovedot)	    *lower += (XK_zcaron - XK_Zcaron);	else if (sym == XK_aogonek)	    *upper = XK_Aogonek;	else if (sym >= XK_lstroke && sym <= XK_sacute)	    *upper -= (XK_lstroke - XK_Lstroke);	else if (sym >= XK_scaron && sym <= XK_zacute)	    *upper -= (XK_scaron - XK_Scaron);	else if (sym >= XK_zcaron && sym <= XK_zabovedot)	    *upper -= (XK_zcaron - XK_Zcaron);	else if (sym >= XK_Racute && sym <= XK_Tcedilla)	    *lower += (XK_racute - XK_Racute);	else if (sym >= XK_racute && sym <= XK_tcedilla)	    *upper -= (XK_racute - XK_Racute);	break;    case 2: /* Latin 3 */	/* Assume the KeySym is a legal value (ignore discontinuities) */	if (sym >= XK_Hstroke && sym <= XK_Hcircumflex)	    *lower += (XK_hstroke - XK_Hstroke);	else if (sym >= XK_Gbreve && sym <= XK_Jcircumflex)	    *lower += (XK_gbreve - XK_Gbreve);	else if (sym >= XK_hstroke && sym <= XK_hcircumflex)	    *upper -= (XK_hstroke - XK_Hstroke);	else if (sym >= XK_gbreve && sym <= XK_jcircumflex)	    *upper -= (XK_gbreve - XK_Gbreve);	else if (sym >= XK_Cabovedot && sym <= XK_Scircumflex)	    *lower += (XK_cabovedot - XK_Cabovedot);	else if (sym >= XK_cabovedot && sym <= XK_scircumflex)	    *upper -= (XK_cabovedot - XK_Cabovedot);	break;    case 3: /* Latin 4 */	/* Assume the KeySym is a legal value (ignore discontinuities) */	if (sym >= XK_Rcedilla && sym <= XK_Tslash)	    *lower += (XK_rcedilla - XK_Rcedilla);	else if (sym >= XK_rcedilla && sym <= XK_tslash)	    *upper -= (XK_rcedilla - XK_Rcedilla);	else if (sym == XK_ENG)	    *lower = XK_eng;	else if (sym == XK_eng)	    *upper = XK_ENG;	else if (sym >= XK_Amacron && sym <= XK_Umacron)	    *lower += (XK_amacron - XK_Amacron);	else if (sym >= XK_amacron && sym <= XK_umacron)	    *upper -= (XK_amacron - XK_Amacron);	break;    case 6: /* Cyrillic */	/* Assume the KeySym is a legal value (ignore discontinuities) */	if (sym >= XK_Serbian_DJE && sym <= XK_Serbian_DZE)	    *lower -= (XK_Serbian_DJE - XK_Serbian_dje);	else if (sym >= XK_Serbian_dje && sym <= XK_Serbian_dze)	    *upper += (XK_Serbian_DJE - XK_Serbian_dje);	else if (sym >= XK_Cyrillic_YU && sym <= XK_Cyrillic_HARDSIGN)	    *lower -= (XK_Cyrillic_YU - XK_Cyrillic_yu);	else if (sym >= XK_Cyrillic_yu && sym <= XK_Cyrillic_hardsign)	    *upper += (XK_Cyrillic_YU - XK_Cyrillic_yu);        break;    case 7: /* Greek */	/* Assume the KeySym is a legal value (ignore discontinuities) */	if (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_OMEGAaccent)	    *lower += (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);	else if (sym >= XK_Greek_alphaaccent && sym <= XK_Greek_omegaaccent &&		 sym != XK_Greek_iotaaccentdieresis &&		 sym != XK_Greek_upsilonaccentdieresis)	    *upper -= (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);	else if (sym >= XK_Greek_ALPHA && sym <= XK_Greek_OMEGA)	    *lower += (XK_Greek_alpha - XK_Greek_ALPHA);	else if (sym >= XK_Greek_alpha && sym <= XK_Greek_omega &&		 sym != XK_Greek_finalsmallsigma)	    *upper -= (XK_Greek_alpha - XK_Greek_ALPHA);        break;    }}static KeySym KeyCodetoKeySym(KeySymsPtr keymap, int keycode, int col){  register int per = keymap->mapWidth;  register KeySym *syms;  KeySym lsym, usym;  if ((col < 0) || ((col >= per) && (col > 3)) ||      (keycode < keymap->minKeyCode) || (keycode > keymap->maxKeyCode))    return NoSymbol;  syms = &keymap->map[(keycode - keymap->minKeyCode) * per];  if (col < 4) {    if (col > 1) {      while ((per > 2) && (syms[per - 1] == NoSymbol))        per--;      if (per < 3)        col -= 2;    }    if ((per <= (col|1)) || (syms[col|1] == NoSymbol)) {      XConvertCase(syms[col&~1], &lsym, &usym);      if (!(col & 1))        return lsym;      // I'm commenting out this logic because it's incorrect even though it      // was copied from the Xlib sources.  The X protocol book quite clearly      // states that where a group consists of element 1 being a non-alphabetic      // keysym and element 2 being NoSymbol that you treat the second element      // as being the same as the first.  This also tallies with the behaviour      // produced by the installed Xlib on my linux box (I believe this is      // because it uses some XKB code rather than the original Xlib code -      // compare XKBBind.c with KeyBind.c in lib/X11).      // else if (usym == lsym)      //   return NoSymbol;      else        return usym;    }  }  return syms[col];}// KeysymToKeycode() - find the keycode and column corresponding to the given// keysym.  The value of col passed in should be the column determined from the// current shift state.  If the keysym can be found in that column we prefer// that to finding it in a different column (which would require fake events to// alter the shift state).static KeyCode KeysymToKeycode(KeySymsPtr keymap, KeySym ks, int* col){  register int i, j;  j = *col;  for (i = keymap->minKeyCode; i <= keymap->maxKeyCode; i++) {    if (KeyCodetoKeySym(keymap, i, j) == ks)      return i;  }  for (j = 0; j < keymap->mapWidth; j++) {    for (i = keymap->minKeyCode; i <= keymap->maxKeyCode; i++) {      if (KeyCodetoKeySym(keymap, i, j) == ks) {        *col = j;        return i;      }    }  }  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -