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

📄 rfbproto.java

📁 JAVA版vpn客户端,是在web上实现远程访问的最佳方式.
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
    b[15] = (byte) greenShift;    b[16] = (byte) blueShift;    os.write(b);  }  //  // Write a FixColourMapEntries message.  The values in the red, green and  // blue arrays are from 0 to 65535.  //  void writeFixColourMapEntries(int firstColour, int nColours,				int[] red, int[] green, int[] blue)       throws IOException  {    byte[] b = new byte[6 + nColours * 6];    b[0] = (byte) FixColourMapEntries;    b[2] = (byte) ((firstColour >> 8) & 0xff);    b[3] = (byte) (firstColour & 0xff);    b[4] = (byte) ((nColours >> 8) & 0xff);    b[5] = (byte) (nColours & 0xff);    for (int i = 0; i < nColours; i++) {      b[6 + i * 6]     = (byte) ((red[i] >> 8) & 0xff);      b[6 + i * 6 + 1] = (byte) (red[i] & 0xff);      b[6 + i * 6 + 2] = (byte) ((green[i] >> 8) & 0xff);      b[6 + i * 6 + 3] = (byte) (green[i] & 0xff);      b[6 + i * 6 + 4] = (byte) ((blue[i] >> 8) & 0xff);      b[6 + i * 6 + 5] = (byte) (blue[i] & 0xff);    }     os.write(b);  }  //  // Write a SetEncodings message  //  void writeSetEncodings(int[] encs, int len) throws IOException {    byte[] b = new byte[4 + 4 * len];    b[0] = (byte) SetEncodings;    b[2] = (byte) ((len >> 8) & 0xff);    b[3] = (byte) (len & 0xff);    for (int i = 0; i < len; i++) {      b[4 + 4 * i] = (byte) ((encs[i] >> 24) & 0xff);      b[5 + 4 * i] = (byte) ((encs[i] >> 16) & 0xff);      b[6 + 4 * i] = (byte) ((encs[i] >> 8) & 0xff);      b[7 + 4 * i] = (byte) (encs[i] & 0xff);    }    os.write(b);  }  //  // Write a ClientCutText message  //  void writeClientCutText(String text) throws IOException {    byte[] b = new byte[8 + text.length()];    b[0] = (byte) ClientCutText;    b[4] = (byte) ((text.length() >> 24) & 0xff);    b[5] = (byte) ((text.length() >> 16) & 0xff);    b[6] = (byte) ((text.length() >> 8) & 0xff);    b[7] = (byte) (text.length() & 0xff);    System.arraycopy(text.getBytes(), 0, b, 8, text.length());    os.write(b);  }  //  // A buffer for putting pointer and keyboard events before being sent.  This  // is to ensure that multiple RFB events generated from a single Java Event   // will all be sent in a single network packet.  The maximum possible  // length is 4 modifier down events, a single key event followed by 4  // modifier up events i.e. 9 key events or 72 bytes.  //  byte[] eventBuf = new byte[72];  int eventBufLen;  // Useful shortcuts for modifier masks.  final static int CTRL_MASK  = InputEvent.CTRL_MASK;  final static int SHIFT_MASK = InputEvent.SHIFT_MASK;  final static int META_MASK  = InputEvent.META_MASK;  final static int ALT_MASK   = InputEvent.ALT_MASK;  //  // Write a pointer event message.  We may need to send modifier key events  // around it to set the correct modifier state.  //  int pointerMask = 0;  void writePointerEvent(MouseEvent evt) throws IOException {    int modifiers = evt.getModifiers();    int mask2 = 2;    int mask3 = 4;    if (viewer.options.reverseMouseButtons2And3) {      mask2 = 4;      mask3 = 2;    }    // Note: For some reason, AWT does not set BUTTON1_MASK on left    // button presses. Here we think that it was the left button if    // modifiers do not include BUTTON2_MASK or BUTTON3_MASK.    if (evt.getID() == MouseEvent.MOUSE_PRESSED) {      if ((modifiers & InputEvent.BUTTON2_MASK) != 0) {        pointerMask = mask2;        modifiers &= ~ALT_MASK;      } else if ((modifiers & InputEvent.BUTTON3_MASK) != 0) {        pointerMask = mask3;        modifiers &= ~META_MASK;      } else {        pointerMask = 1;      }    } else if (evt.getID() == MouseEvent.MOUSE_RELEASED) {      pointerMask = 0;      if ((modifiers & InputEvent.BUTTON2_MASK) != 0) {        modifiers &= ~ALT_MASK;      } else if ((modifiers & InputEvent.BUTTON3_MASK) != 0) {        modifiers &= ~META_MASK;      }    }    eventBufLen = 0;    writeModifierKeyEvents(modifiers);    int x = evt.getX();    int y = evt.getY();    if (x < 0) x = 0;    if (y < 0) y = 0;    eventBuf[eventBufLen++] = (byte) PointerEvent;    eventBuf[eventBufLen++] = (byte) pointerMask;    eventBuf[eventBufLen++] = (byte) ((x >> 8) & 0xff);    eventBuf[eventBufLen++] = (byte) (x & 0xff);    eventBuf[eventBufLen++] = (byte) ((y >> 8) & 0xff);    eventBuf[eventBufLen++] = (byte) (y & 0xff);    //    // Always release all modifiers after an "up" event    //    if (pointerMask == 0) {      writeModifierKeyEvents(0);    }    os.write(eventBuf, 0, eventBufLen);  }  //  // Write a key event message.  We may need to send modifier key events  // around it to set the correct modifier state.  Also we need to translate  // from the Java key values to the X keysym values used by the RFB protocol.  //  void writeKeyEvent(KeyEvent evt) throws IOException {    int keyChar = evt.getKeyChar();    //    // Ignore event if only modifiers were pressed.    //    // Some JVMs return 0 instead of CHAR_UNDEFINED in getKeyChar().    if (keyChar == 0)      keyChar = KeyEvent.CHAR_UNDEFINED;    if (keyChar == KeyEvent.CHAR_UNDEFINED) {      int code = evt.getKeyCode();      if (code == KeyEvent.VK_CONTROL || code == KeyEvent.VK_SHIFT ||          code == KeyEvent.VK_META || code == KeyEvent.VK_ALT)        return;    }    //    // Key press or key release?    //    boolean down = (evt.getID() == KeyEvent.KEY_PRESSED);    int key;    if (evt.isActionKey()) {      //      // An action key should be one of the following.      // If not then just ignore the event.      //      switch(evt.getKeyCode()) {      case KeyEvent.VK_HOME:      key = 0xff50; break;      case KeyEvent.VK_LEFT:      key = 0xff51; break;      case KeyEvent.VK_UP:        key = 0xff52; break;      case KeyEvent.VK_RIGHT:     key = 0xff53; break;      case KeyEvent.VK_DOWN:      key = 0xff54; break;      case KeyEvent.VK_PAGE_UP:   key = 0xff55; break;      case KeyEvent.VK_PAGE_DOWN: key = 0xff56; break;      case KeyEvent.VK_END:       key = 0xff57; break;      case KeyEvent.VK_INSERT:    key = 0xff63; break;      case KeyEvent.VK_F1:        key = 0xffbe; break;      case KeyEvent.VK_F2:        key = 0xffbf; break;      case KeyEvent.VK_F3:        key = 0xffc0; break;      case KeyEvent.VK_F4:        key = 0xffc1; break;      case KeyEvent.VK_F5:        key = 0xffc2; break;      case KeyEvent.VK_F6:        key = 0xffc3; break;      case KeyEvent.VK_F7:        key = 0xffc4; break;      case KeyEvent.VK_F8:        key = 0xffc5; break;      case KeyEvent.VK_F9:        key = 0xffc6; break;      case KeyEvent.VK_F10:       key = 0xffc7; break;      case KeyEvent.VK_F11:       key = 0xffc8; break;      case KeyEvent.VK_F12:       key = 0xffc9; break;      default:        return;      }    } else {      //      // A "normal" key press.  Ordinary ASCII characters go straight through.      // For CTRL-<letter>, CTRL is sent separately so just send <letter>.      // Backspace, tab, return, escape and delete have special keysyms.      // Anything else we ignore.      //      key = keyChar;      if (key < 0x20) {        if (evt.isControlDown()) {          key += 0x60;        } else {          switch(key) {          case KeyEvent.VK_BACK_SPACE: key = 0xff08; break;          case KeyEvent.VK_TAB:        key = 0xff09; break;          case KeyEvent.VK_ENTER:      key = 0xff0d; break;          case KeyEvent.VK_ESCAPE:     key = 0xff1b; break;          }        }      } else if (key == 0x7f) {	// Delete	key = 0xffff;      } else if (key > 0xff) {	// JDK1.1 on X incorrectly passes some keysyms straight through,	// so we do too.  JDK1.1.4 seems to have fixed this.	// The keysyms passed are 0xff00 .. XK_BackSpace .. XK_Delete	// Also, we pass through foreign currency keysyms (0x20a0..0x20af).	if ((key < 0xff00 || key > 0xffff) &&	    !(key >= 0x20a0 && key <= 0x20af))	  return;      }    }    // Fake keyPresses for keys that only generates keyRelease events    if ((key == 0xe5) || (key == 0xc5) || // XK_aring / XK_Aring	(key == 0xe4) || (key == 0xc4) || // XK_adiaeresis / XK_Adiaeresis	(key == 0xf6) || (key == 0xd6) || // XK_odiaeresis / XK_Odiaeresis	(key == 0xa7) || (key == 0xbd) || // XK_section / XK_onehalf	(key == 0xa3)) {                  // XK_sterling      // Make sure we do not send keypress events twice on platforms      // with correct JVMs (those that actually report KeyPress for all      // keys)	      if (down)	brokenKeyPressed = true;      if (!down && !brokenKeyPressed) {	// We've got a release event for this key, but haven't received        // a press. Fake it. 	eventBufLen = 0;	writeModifierKeyEvents(evt.getModifiers());	writeKeyEvent(key, true);	os.write(eventBuf, 0, eventBufLen);      }      if (!down)	brokenKeyPressed = false;      }    eventBufLen = 0;    writeModifierKeyEvents(evt.getModifiers());    writeKeyEvent(key, down);    // Always release all modifiers after an "up" event    if (!down)      writeModifierKeyEvents(0);    os.write(eventBuf, 0, eventBufLen);  }  //  // Add a raw key event with the given X keysym to eventBuf.  //  void writeKeyEvent(int keysym, boolean down) {    eventBuf[eventBufLen++] = (byte) KeyboardEvent;    eventBuf[eventBufLen++] = (byte) (down ? 1 : 0);    eventBuf[eventBufLen++] = (byte) 0;    eventBuf[eventBufLen++] = (byte) 0;    eventBuf[eventBufLen++] = (byte) ((keysym >> 24) & 0xff);    eventBuf[eventBufLen++] = (byte) ((keysym >> 16) & 0xff);    eventBuf[eventBufLen++] = (byte) ((keysym >> 8) & 0xff);    eventBuf[eventBufLen++] = (byte) (keysym & 0xff);  }  //  // Write key events to set the correct modifier state.  //  int oldModifiers = 0;  void writeModifierKeyEvents(int newModifiers) {    if ((newModifiers & CTRL_MASK) != (oldModifiers & CTRL_MASK))      writeKeyEvent(0xffe3, (newModifiers & CTRL_MASK) != 0);    if ((newModifiers & SHIFT_MASK) != (oldModifiers & SHIFT_MASK))      writeKeyEvent(0xffe1, (newModifiers & SHIFT_MASK) != 0);    if ((newModifiers & META_MASK) != (oldModifiers & META_MASK))      writeKeyEvent(0xffe7, (newModifiers & META_MASK) != 0);    if ((newModifiers & ALT_MASK) != (oldModifiers & ALT_MASK))      writeKeyEvent(0xffe9, (newModifiers & ALT_MASK) != 0);    oldModifiers = newModifiers;  }  //  // Compress and write the data into the recorded session file. This  // method assumes the recording is on (rec != null).  //  void recordCompressedData(byte[] data, int off, int len) throws IOException {    Deflater deflater = new Deflater();    deflater.setInput(data, off, len);    int bufSize = len + len / 100 + 12;    byte[] buf = new byte[bufSize];    deflater.finish();    int compressedSize = deflater.deflate(buf);    recordCompactLen(compressedSize);    rec.write(buf, 0, compressedSize);  }  void recordCompressedData(byte[] data) throws IOException {    recordCompressedData(data, 0, data.length);  }  //  // Write an integer in compact representation (1..3 bytes) into the  // recorded session file. This method assumes the recording is on  // (rec != null).  //  void recordCompactLen(int len) throws IOException {    byte[] buf = new byte[3];    int bytes = 0;    buf[bytes++] = (byte)(len & 0x7F);    if (len > 0x7F) {      buf[bytes-1] |= 0x80;      buf[bytes++] = (byte)(len >> 7 & 0x7F);      if (len > 0x3FFF) {	buf[bytes-1] |= 0x80;	buf[bytes++] = (byte)(len >> 14 & 0xFF);      }    }    rec.write(buf, 0, bytes);  }  public void startTiming() {    timing = true;    // Carry over up to 1s worth of previous rate for smoothing.    if (timeWaitedIn100us > 10000) {      timedKbits = timedKbits * 10000 / timeWaitedIn100us;      timeWaitedIn100us = 10000;    }  }  public void stopTiming() {    timing = false;     if (timeWaitedIn100us < timedKbits/2)      timeWaitedIn100us = timedKbits/2; // upper limit 20Mbit/s  }  public long kbitsPerSecond() {    return timedKbits * 10000 / timeWaitedIn100us;  }  public long timeWaited() {    return timeWaitedIn100us;  }  public void readFully(byte b[]) throws IOException {    readFully(b, 0, b.length);  }  public void readFully(byte b[], int off, int len) throws IOException {    long before = 0;    if (timing)      before = System.currentTimeMillis();    is.readFully(b, off, len);    if (timing) {      long after = System.currentTimeMillis();      long newTimeWaited = (after - before) * 10;      int newKbits = len * 8 / 1000;      // limit rate to between 10kbit/s and 40Mbit/s      if (newTimeWaited > newKbits*1000) newTimeWaited = newKbits*1000;      if (newTimeWaited < newKbits/4)    newTimeWaited = newKbits/4;      timeWaitedIn100us += newTimeWaited;      timedKbits += newKbits;    }  }}

⌨️ 快捷键说明

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