📄 vnccanvas.java
字号:
int dx, dy, n; int i = y * rfb.framebufferWidth + x; int rowBytes = (w + 7) / 8; byte b; for (dy = 0; dy < h; dy++) { for (dx = 0; dx < w / 8; dx++) { b = src[dy*rowBytes+dx]; for (n = 7; n >= 0; n--) pixels8[i++] = palette[b >> n & 1]; } for (n = 7; n >= 8 - w % 8; n--) { pixels8[i++] = palette[src[dy*rowBytes+dx] >> n & 1]; } i += (rfb.framebufferWidth - w); } } void decodeMonoData(int x, int y, int w, int h, byte[] src, int[] palette) { int dx, dy, n; int i = y * rfb.framebufferWidth + x; int rowBytes = (w + 7) / 8; byte b; for (dy = 0; dy < h; dy++) { for (dx = 0; dx < w / 8; dx++) { b = src[dy*rowBytes+dx]; for (n = 7; n >= 0; n--) pixels24[i++] = palette[b >> n & 1]; } for (n = 7; n >= 8 - w % 8; n--) { pixels24[i++] = palette[src[dy*rowBytes+dx] >> n & 1]; } i += (rfb.framebufferWidth - w); } } // // Decode data processed with the "Gradient" filter. // void decodeGradientData (int x, int y, int w, int h, byte[] buf) { int dx, dy, c; byte[] prevRow = new byte[w * 3]; byte[] thisRow = new byte[w * 3]; byte[] pix = new byte[3]; int[] est = new int[3]; int offset = y * rfb.framebufferWidth + x; for (dy = 0; dy < h; dy++) { /* First pixel in a row */ for (c = 0; c < 3; c++) { pix[c] = (byte)(prevRow[c] + buf[dy * w * 3 + c]); thisRow[c] = pix[c]; } pixels24[offset++] = (pix[0] & 0xFF) << 16 | (pix[1] & 0xFF) << 8 | (pix[2] & 0xFF); /* Remaining pixels of a row */ for (dx = 1; dx < w; dx++) { for (c = 0; c < 3; c++) { est[c] = ((prevRow[dx * 3 + c] & 0xFF) + (pix[c] & 0xFF) - (prevRow[(dx-1) * 3 + c] & 0xFF)); if (est[c] > 0xFF) { est[c] = 0xFF; } else if (est[c] < 0x00) { est[c] = 0x00; } pix[c] = (byte)(est[c] + buf[(dy * w + dx) * 3 + c]); thisRow[dx * 3 + c] = pix[c]; } pixels24[offset++] = (pix[0] & 0xFF) << 16 | (pix[1] & 0xFF) << 8 | (pix[2] & 0xFF); } System.arraycopy(thisRow, 0, prevRow, 0, w * 3); offset += (rfb.framebufferWidth - w); } } // // Display newly updated area of pixels. // void handleUpdatedPixels(int x, int y, int w, int h) { // Draw updated pixels of the off-screen image. pixelsSource.newPixels(x, y, w, h); memGraphics.setClip(x, y, w, h); memGraphics.drawImage(rawPixelsImage, 0, 0, null); memGraphics.setClip(0, 0, rfb.framebufferWidth, rfb.framebufferHeight); } // // Tell JVM to repaint specified desktop area. // void scheduleRepaint(int x, int y, int w, int h) { // Request repaint, deferred if necessary. if (rfb.framebufferWidth == scaledWidth) { repaint(viewer.deferScreenUpdates, x, y, w, h); } else { int sx = x * scalingFactor / 100; int sy = y * scalingFactor / 100; int sw = ((x + w) * scalingFactor + 49) / 100 - sx + 1; int sh = ((y + h) * scalingFactor + 49) / 100 - sy + 1; repaint(viewer.deferScreenUpdates, sx, sy, sw, sh); } } // // Handle events. // public void keyPressed(KeyEvent evt) { processLocalKeyEvent(evt); } public void keyReleased(KeyEvent evt) { processLocalKeyEvent(evt); } public void keyTyped(KeyEvent evt) { evt.consume(); } public void mousePressed(MouseEvent evt) { processLocalMouseEvent(evt, false); } public void mouseReleased(MouseEvent evt) { processLocalMouseEvent(evt, false); } public void mouseMoved(MouseEvent evt) { processLocalMouseEvent(evt, true); } public void mouseDragged(MouseEvent evt) { processLocalMouseEvent(evt, true); } public void processLocalKeyEvent(KeyEvent evt) { if (viewer.rfb != null && rfb.inNormalProtocol) { if (!inputEnabled) { if ((evt.getKeyChar() == 'r' || evt.getKeyChar() == 'R') && evt.getID() == KeyEvent.KEY_PRESSED ) { // Request screen update. try { rfb.writeFramebufferUpdateRequest(0, 0, rfb.framebufferWidth, rfb.framebufferHeight, false); } catch (IOException e) { e.printStackTrace(); } } } else { // Input enabled. synchronized(rfb) { try { rfb.writeKeyEvent(evt); } catch (Exception e) { e.printStackTrace(); } rfb.notify(); } } } // Don't ever pass keyboard events to AWT for default processing. // Otherwise, pressing Tab would switch focus to ButtonPanel etc. evt.consume(); } public void processLocalMouseEvent(MouseEvent evt, boolean moved) { if (viewer.rfb != null && rfb.inNormalProtocol) { if (moved) { softCursorMove(evt.getX(), evt.getY()); } if (rfb.framebufferWidth != scaledWidth) { int sx = (evt.getX() * 100 + scalingFactor/2) / scalingFactor; int sy = (evt.getY() * 100 + scalingFactor/2) / scalingFactor; evt.translatePoint(sx - evt.getX(), sy - evt.getY()); } synchronized(rfb) { try { rfb.writePointerEvent(evt); } catch (Exception e) { e.printStackTrace(); } rfb.notify(); } } } // // Ignored events. // public void mouseClicked(MouseEvent evt) {} public void mouseEntered(MouseEvent evt) {} public void mouseExited(MouseEvent evt) {} ////////////////////////////////////////////////////////////////// // // Handle cursor shape updates (XCursor and RichCursor encodings). // boolean showSoftCursor = false; MemoryImageSource softCursorSource; Image softCursor; int cursorX = 0, cursorY = 0; int cursorWidth, cursorHeight; int origCursorWidth, origCursorHeight; int hotX, hotY; int origHotX, origHotY; // // Handle cursor shape update (XCursor and RichCursor encodings). // synchronized void handleCursorShapeUpdate(int encodingType, int xhot, int yhot, int width, int height) throws IOException { softCursorFree(); if (width * height == 0) return; // Ignore cursor shape data if requested by user. if (viewer.options.ignoreCursorUpdates) { int bytesPerRow = (width + 7) / 8; int bytesMaskData = bytesPerRow * height; if (encodingType == rfb.EncodingXCursor) { rfb.is.skipBytes(6 + bytesMaskData * 2); } else { // rfb.EncodingRichCursor rfb.is.skipBytes(width * height + bytesMaskData); } return; } // Decode cursor pixel data. softCursorSource = decodeCursorShape(encodingType, width, height); // Set original (non-scaled) cursor dimensions. origCursorWidth = width; origCursorHeight = height; origHotX = xhot; origHotY = yhot; // Create off-screen cursor image. createSoftCursor(); // Show the cursor. showSoftCursor = true; repaint(viewer.deferCursorUpdates, cursorX - hotX, cursorY - hotY, cursorWidth, cursorHeight); } // // decodeCursorShape(). Decode cursor pixel data and return // corresponding MemoryImageSource instance. // synchronized MemoryImageSource decodeCursorShape(int encodingType, int width, int height) throws IOException { int bytesPerRow = (width + 7) / 8; int bytesMaskData = bytesPerRow * height; int[] softCursorPixels = new int[width * height]; if (encodingType == rfb.EncodingXCursor) { // Read foreground and background colors of the cursor. byte[] rgb = new byte[6]; rfb.readFully(rgb); int[] colors = { (0xFF000000 | (rgb[3] & 0xFF) << 16 | (rgb[4] & 0xFF) << 8 | (rgb[5] & 0xFF)), (0xFF000000 | (rgb[0] & 0xFF) << 16 | (rgb[1] & 0xFF) << 8 | (rgb[2] & 0xFF)) }; // Read pixel and mask data. byte[] pixBuf = new byte[bytesMaskData]; rfb.readFully(pixBuf); byte[] maskBuf = new byte[bytesMaskData]; rfb.readFully(maskBuf); // Decode pixel data into softCursorPixels[]. byte pixByte, maskByte; int x, y, n, result; int i = 0; for (y = 0; y < height; y++) { for (x = 0; x < width / 8; x++) { pixByte = pixBuf[y * bytesPerRow + x]; maskByte = maskBuf[y * bytesPerRow + x]; for (n = 7; n >= 0; n--) { if ((maskByte >> n & 1) != 0) { result = colors[pixByte >> n & 1]; } else { result = 0; // Transparent pixel } softCursorPixels[i++] = result; } } for (n = 7; n >= 8 - width % 8; n--) { if ((maskBuf[y * bytesPerRow + x] >> n & 1) != 0) { result = colors[pixBuf[y * bytesPerRow + x] >> n & 1]; } else { result = 0; // Transparent pixel } softCursorPixels[i++] = result; } } } else { // encodingType == rfb.EncodingRichCursor // Read pixel and mask data. byte[] pixBuf = new byte[width * height * bytesPixel]; rfb.readFully(pixBuf); byte[] maskBuf = new byte[bytesMaskData]; rfb.readFully(maskBuf); // Decode pixel data into softCursorPixels[]. byte pixByte, maskByte; int x, y, n, result; int i = 0; for (y = 0; y < height; y++) { for (x = 0; x < width / 8; x++) { maskByte = maskBuf[y * bytesPerRow + x]; for (n = 7; n >= 0; n--) { if ((maskByte >> n & 1) != 0) { if (bytesPixel == 1) { result = cm8.getRGB(pixBuf[i]); } else { result = 0xFF000000 | (pixBuf[i * 4 + 2] & 0xFF) << 16 | (pixBuf[i * 4 + 1] & 0xFF) << 8 | (pixBuf[i * 4] & 0xFF); } } else { result = 0; // Transparent pixel } softCursorPixels[i++] = result; } } for (n = 7; n >= 8 - width % 8; n--) { if ((maskBuf[y * bytesPerRow + x] >> n & 1) != 0) { if (bytesPixel == 1) { result = cm8.getRGB(pixBuf[i]); } else { result = 0xFF000000 | (pixBuf[i * 4 + 2] & 0xFF) << 16 | (pixBuf[i * 4 + 1] & 0xFF) << 8 | (pixBuf[i * 4] & 0xFF); } } else { result = 0; // Transparent pixel } softCursorPixels[i++] = result; } } } return new MemoryImageSource(width, height, softCursorPixels, 0, width); } // // createSoftCursor(). Assign softCursor new Image (scaled if necessary). // Uses softCursorSource as a source for new cursor image. // synchronized void createSoftCursor() { if (softCursorSource == null) return; int scaleCursor = viewer.options.scaleCursor; if (scaleCursor == 0 || !inputEnabled) scaleCursor = 100; // Save original cursor coordinates. int x = cursorX - hotX; int y = cursorY - hotY; int w = cursorWidth; int h = cursorHeight; cursorWidth = (origCursorWidth * scaleCursor + 50) / 100; cursorHeight = (origCursorHeight * scaleCursor + 50) / 100; hotX = (origHotX * scaleCursor + 50) / 100; hotY = (origHotY * scaleCursor + 50) / 100; softCursor = Toolkit.getDefaultToolkit().createImage(softCursorSource); if (scaleCursor != 100) { softCursor = softCursor.getScaledInstance(cursorWidth, cursorHeight, Image.SCALE_SMOOTH); } if (showSoftCursor) { // Compute screen area to update. x = Math.min(x, cursorX - hotX); y = Math.min(y, cursorY - hotY); w = Math.max(w, cursorWidth); h = Math.max(h, cursorHeight); repaint(viewer.deferCursorUpdates, x, y, w, h); } } // // softCursorMove(). Moves soft cursor into a particular location. // synchronized void softCursorMove(int x, int y) { int oldX = cursorX; int oldY = cursorY; cursorX = x; cursorY = y; if (showSoftCursor) { repaint(viewer.deferCursorUpdates, oldX - hotX, oldY - hotY, cursorWidth, cursorHeight); repaint(viewer.deferCursorUpdates, cursorX - hotX, cursorY - hotY, cursorWidth, cursorHeight); } } // // softCursorFree(). Remove soft cursor, dispose resources. // synchronized void softCursorFree() { if (showSoftCursor) { showSoftCursor = false; softCursor = null; softCursorSource = null; repaint(viewer.deferCursorUpdates, cursorX - hotX, cursorY - hotY, cursorWidth, cursorHeight); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -