📄 cconn.cxx
字号:
menu.addEntry("Exit viewer", ID_EXIT); menu.addEntry(0, 0); menu.addEntry("Full screen", ID_FULLSCREEN); menu.check(ID_FULLSCREEN, fullScreen); menu.addEntry(0, 0); menu.addEntry("Ctrl", ID_CTRL); menu.addEntry("Alt", ID_ALT); CharArray menuKeyStr(menuKey.getData()); CharArray sendMenuKey(6+strlen(menuKeyStr.buf)); sprintf(sendMenuKey.buf, "Send %s", menuKeyStr.buf); menu.addEntry(sendMenuKey.buf, ID_F8); menu.addEntry("Send Ctrl-Alt-Del", ID_CTRLALTDEL); menu.addEntry(0, 0); menu.addEntry("Refresh screen", ID_REFRESH); menu.addEntry(0, 0); menu.addEntry("New connection...", ID_NEWCONN); menu.addEntry("Options...", ID_OPTIONS); menu.addEntry("Connection info...", ID_INFO); menu.addEntry("About VNCviewer...", ID_ABOUT); menu.addEntry(0, 0); menu.addEntry("Dismiss menu", ID_DISMISS); menu.toplevel("VNC Menu", this); menu.setBorderWidth(1);}void CConn::showMenu(int x, int y) { menu.check(ID_FULLSCREEN, fullScreen); menu.move(x, y); menu.raise(); menu.map();}void CConn::menuSelect(long id, TXMenu* m) { switch (id) { case ID_NEWCONN: { menu.unmap(); if (fullScreen) { fullScreen = false; if (viewport) recreateViewport(); } int pid = fork(); if (pid < 0) { perror("fork"); exit(1); } if (pid == 0) { delete sock; close(ConnectionNumber(dpy)); struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 200*1000; select(0, 0, 0, 0, &tv); execlp(programName, programName, 0); perror("execlp"); exit(1); } break; } case ID_OPTIONS: menu.unmap(); options.show(); break; case ID_INFO: { menu.unmap(); char pfStr[100]; char spfStr[100]; cp.pf().print(pfStr, 100); serverPF.print(spfStr, 100); int secType = getCurrentCSecurity()->getType(); char infoText[1024]; sprintf(infoText, "Desktop name: %.80s\n" "Host: %.80s port: %d\n" "Size: %d x %d\n" "Pixel format: %s\n" "(server default %s)\n" "Requested encoding: %s\n" "Last used encoding: %s\n" "Line speed estimate: %d kbit/s\n" "Protocol version: %d.%d\n" "Security method: %s\n", cp.name(), serverHost, serverPort, cp.width, cp.height, pfStr, spfStr, encodingName(currentEncoding), encodingName(lastServerEncoding), sock->inStream().kbitsPerSecond(), cp.majorVersion, cp.minorVersion, secTypeName(secType)); info.setText(infoText); info.show(); break; } case ID_FULLSCREEN: menu.unmap(); fullScreen = !fullScreen; if (viewport) recreateViewport(); break; case ID_REFRESH: menu.unmap(); writer()->writeFramebufferUpdateRequest(Rect(0, 0, cp.width, cp.height), false); break; case ID_F8: menu.unmap(); if (!viewOnly) { writer()->keyEvent(menuKeysym, true); writer()->keyEvent(menuKeysym, false); } break; case ID_CTRLALTDEL: menu.unmap(); if (!viewOnly) { writer()->keyEvent(XK_Control_L, true); writer()->keyEvent(XK_Alt_L, true); writer()->keyEvent(XK_Delete, true); writer()->keyEvent(XK_Delete, false); writer()->keyEvent(XK_Alt_L, false); writer()->keyEvent(XK_Control_L, false); } break; case ID_CTRL: menu.unmap(); if (!viewOnly) { ctrlDown = !ctrlDown; writer()->keyEvent(XK_Control_L, ctrlDown); menu.check(ID_CTRL, ctrlDown); } break; case ID_ALT: menu.unmap(); if (!viewOnly) { altDown = !altDown; writer()->keyEvent(XK_Alt_L, altDown); menu.check(ID_ALT, altDown); } break; case ID_ABOUT: menu.unmap(); about.show(); break; case ID_DISMISS: menu.unmap(); break; case ID_EXIT: exit(1); break; }}// OptionsDialogCallback. setOptions() sets the options dialog's checkboxes// etc to reflect our flags. getOptions() sets our flags according to the// options dialog's checkboxes.void CConn::setOptions() { options.autoSelect.checked(autoSelect); options.fullColour.checked(fullColour); options.veryLowColour.checked(!fullColour && lowColourLevel == 0); options.lowColour.checked(!fullColour && lowColourLevel == 1); options.mediumColour.checked(!fullColour && lowColourLevel == 2); options.zrle.checked(currentEncoding == encodingZRLE); options.hextile.checked(currentEncoding == encodingHextile); options.raw.checked(currentEncoding == encodingRaw); options.viewOnly.checked(viewOnly); options.acceptClipboard.checked(acceptClipboard); options.sendClipboard.checked(sendClipboard); options.sendPrimary.checked(sendPrimary); if (state() == RFBSTATE_NORMAL) options.shared.disabled(true); else options.shared.checked(shared); options.fullScreen.checked(fullScreen); options.useLocalCursor.checked(useLocalCursor); options.dotWhenNoCursor.checked(dotWhenNoCursor);}void CConn::getOptions() { autoSelect = options.autoSelect.checked(); if (fullColour != options.fullColour.checked()) formatChange = true; fullColour = options.fullColour.checked(); if (!fullColour) { int newLowColourLevel = (options.veryLowColour.checked() ? 0 : options.lowColour.checked() ? 1 : 2); if (newLowColourLevel != lowColourLevel) { lowColourLevel.setParam(newLowColourLevel); formatChange = true; } } unsigned int newEncoding = (options.zrle.checked() ? encodingZRLE : options.hextile.checked() ? encodingHextile : encodingRaw); if (newEncoding != currentEncoding) { currentEncoding = newEncoding; encodingChange = true; } viewOnly.setParam(options.viewOnly.checked()); acceptClipboard.setParam(options.acceptClipboard.checked()); sendClipboard.setParam(options.sendClipboard.checked()); sendPrimary.setParam(options.sendPrimary.checked()); shared = options.shared.checked(); setShared(shared); if (fullScreen != options.fullScreen.checked()) { fullScreen = options.fullScreen.checked(); if (viewport) recreateViewport(); } useLocalCursor.setParam(options.useLocalCursor.checked()); if (cp.supportsLocalCursor != useLocalCursor) { cp.supportsLocalCursor = useLocalCursor; encodingChange = true; if (desktop) desktop->resetLocalCursor(); } dotWhenNoCursor.setParam(options.dotWhenNoCursor.checked()); checkEncodings();}void CConn::recreateViewport(){ TXViewport* oldViewport = viewport; viewport = new TXViewport(dpy, cp.width, cp.height); desktop->setViewport(viewport); CharArray windowNameStr(windowName.getData()); if (!windowNameStr.buf[0]) { windowNameStr.replaceBuf(new char[256]); sprintf(windowNameStr.buf,"VNC: %.240s",cp.name()); } viewport->toplevel(windowNameStr.buf, this, argc, argv); viewport->setBumpScroll(fullScreen); XSetWindowAttributes attr; attr.override_redirect = fullScreen; XChangeWindowAttributes(dpy, viewport->win(), CWOverrideRedirect, &attr); XChangeWindowAttributes(dpy, menu.win(), CWOverrideRedirect, &attr); XChangeWindowAttributes(dpy, options.win(), CWOverrideRedirect, &attr); XChangeWindowAttributes(dpy, about.win(), CWOverrideRedirect, &attr); XChangeWindowAttributes(dpy, info.win(), CWOverrideRedirect, &attr); reconfigureViewport(); menu.setTransientFor(viewport->win()); viewport->map(); if (fullScreen) { XGrabKeyboard(dpy, desktop->win(), True, GrabModeAsync, GrabModeAsync, CurrentTime); } else { XUngrabKeyboard(dpy, CurrentTime); } if (oldViewport) delete oldViewport;}void CConn::reconfigureViewport(){ viewport->setMaxSize(cp.width, cp.height); if (fullScreen) { viewport->resize(DisplayWidth(dpy,DefaultScreen(dpy)), DisplayHeight(dpy,DefaultScreen(dpy))); } else { int w = cp.width; int h = cp.height; if (w + wmDecorationWidth >= DisplayWidth(dpy,DefaultScreen(dpy))) w = DisplayWidth(dpy,DefaultScreen(dpy)) - wmDecorationWidth; if (h + wmDecorationHeight >= DisplayHeight(dpy,DefaultScreen(dpy))) h = DisplayHeight(dpy,DefaultScreen(dpy)) - wmDecorationHeight; int x = (DisplayWidth(dpy,DefaultScreen(dpy)) - w - wmDecorationWidth) / 2; int y = (DisplayHeight(dpy,DefaultScreen(dpy)) - h - wmDecorationHeight)/2; CharArray geometryStr(geometry.getData()); viewport->setGeometry(geometryStr.buf, x, y, w, h); }}// autoSelectFormatAndEncoding() chooses the format and encoding appropriate// to the connection speed:// Above 16Mbps (timing for at least a second), same machine, switch to raw// Above 3Mbps, switch to hextile// Below 1.5Mbps, switch to ZRLE// Above 1Mbps, switch to full colour modevoid CConn::autoSelectFormatAndEncoding(){ int kbitsPerSecond = sock->inStream().kbitsPerSecond(); unsigned int newEncoding = currentEncoding; if (kbitsPerSecond > 16000 && sameMachine && sock->inStream().timeWaited() >= 10000) { newEncoding = encodingRaw; } else if (kbitsPerSecond > 3000) { newEncoding = encodingHextile; } else if (kbitsPerSecond < 1500) { newEncoding = encodingZRLE; } if (newEncoding != currentEncoding) { vlog.info("Throughput %d kbit/s - changing to %s encoding", kbitsPerSecond, encodingName(newEncoding)); currentEncoding = newEncoding; encodingChange = true; } if (kbitsPerSecond > 1000) { if (!fullColour) { vlog.info("Throughput %d kbit/s - changing to full colour", kbitsPerSecond); fullColour = true; formatChange = true; } }}// checkEncodings() sends a setEncodings message if one is needed.void CConn::checkEncodings(){ if (encodingChange && writer()) { vlog.info("Using %s encoding",encodingName(currentEncoding)); writer()->writeSetEncodings(currentEncoding, true); encodingChange = false; }}// requestNewUpdate() requests an update from the server, having set the// format and encoding appropriately.void CConn::requestNewUpdate(){ if (formatChange) { if (fullColour) { desktop->setPF(fullColourPF); } else { if (lowColourLevel == 0) desktop->setPF(PixelFormat(8,3,0,1,1,1,1,2,1,0)); else if (lowColourLevel == 1) desktop->setPF(PixelFormat(8,6,0,1,3,3,3,4,2,0)); else desktop->setPF(PixelFormat(8,8,0,0)); } char str[256]; desktop->getPF().print(str, 256); vlog.info("Using pixel format %s",str); cp.setPF(desktop->getPF()); writer()->writeSetPixelFormat(cp.pf()); } checkEncodings(); writer()->writeFramebufferUpdateRequest(Rect(0, 0, cp.width, cp.height), !formatChange); formatChange = false;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -