From 3591fa5b9673a587e78c043a6a9f5988ac22e237 Mon Sep 17 00:00:00 2001 From: DRC Date: Thu, 3 Nov 2011 19:01:18 +0000 Subject: [PATCH] The Tight decoding optimizations broke the build of the legacy viewers, so this seems like a good time to get rid of them like we discussed. git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4759 3789f03b-4d11-0410-bbf8-ca57d06f2519 --- CMakeLists.txt | 118 +-- unix/CMakeLists.txt | 4 - unix/vncviewer/AboutDialog.h | 42 - unix/vncviewer/CConn.cxx | 1038 ------------------ unix/vncviewer/CConn.h | 141 --- unix/vncviewer/CMakeLists.txt | 13 - unix/vncviewer/DesktopWindow.cxx | 580 ---------- unix/vncviewer/DesktopWindow.h | 142 --- unix/vncviewer/InfoDialog.h | 60 -- unix/vncviewer/OptionsDialog.h | 314 ------ unix/vncviewer/PasswdDialog.h | 72 -- unix/vncviewer/ServerDialog.h | 91 -- unix/vncviewer/buildtime.c | 18 - unix/vncviewer/gettext.h | 271 ----- unix/vncviewer/parameters.h | 49 - unix/vncviewer/vncviewer.cxx | 423 -------- unix/vncviewer/vncviewer.man | 224 ---- win/CMakeLists.txt | 4 - win/vncviewer/CConn.cxx | 863 --------------- win/vncviewer/CConn.h | 169 --- win/vncviewer/CConnOptions.cxx | 507 --------- win/vncviewer/CConnOptions.h | 104 -- win/vncviewer/CConnThread.cxx | 197 ---- win/vncviewer/CConnThread.h | 57 - win/vncviewer/CMakeLists.txt | 36 - win/vncviewer/ConnectingDialog.cxx | 161 --- win/vncviewer/ConnectingDialog.h | 65 -- win/vncviewer/ConnectionDialog.cxx | 72 -- win/vncviewer/ConnectionDialog.h | 52 - win/vncviewer/DesktopWindow.cxx | 1350 ------------------------ win/vncviewer/DesktopWindow.h | 294 ------ win/vncviewer/InfoDialog.cxx | 65 -- win/vncviewer/InfoDialog.h | 48 - win/vncviewer/ListenServer.h | 55 - win/vncviewer/ListenTrayIcon.h | 95 -- win/vncviewer/MRU.h | 133 --- win/vncviewer/OptionsDialog.cxx | 420 -------- win/vncviewer/OptionsDialog.h | 48 - win/vncviewer/UserPasswdDialog.cxx | 85 -- win/vncviewer/UserPasswdDialog.h | 58 - win/vncviewer/ViewerToolBar.cxx | 104 -- win/vncviewer/ViewerToolBar.h | 35 - win/vncviewer/buildTime.cxx | 18 - win/vncviewer/cursor1.cur | Bin 326 -> 0 bytes win/vncviewer/resource.h | 119 --- win/vncviewer/toolbar.bmp | Bin 2166 -> 0 bytes win/vncviewer/vncviewer.bmp | Bin 2852 -> 0 bytes win/vncviewer/vncviewer.cxx | 310 ------ win/vncviewer/vncviewer.exe.manifest | 22 - win/vncviewer/vncviewer.exe.manifest64 | 22 - win/vncviewer/vncviewer.ico | Bin 25214 -> 0 bytes win/vncviewer/vncviewer.rc | 594 ----------- 52 files changed, 55 insertions(+), 9707 deletions(-) delete mode 100644 unix/vncviewer/AboutDialog.h delete mode 100644 unix/vncviewer/CConn.cxx delete mode 100644 unix/vncviewer/CConn.h delete mode 100644 unix/vncviewer/CMakeLists.txt delete mode 100644 unix/vncviewer/DesktopWindow.cxx delete mode 100644 unix/vncviewer/DesktopWindow.h delete mode 100644 unix/vncviewer/InfoDialog.h delete mode 100644 unix/vncviewer/OptionsDialog.h delete mode 100644 unix/vncviewer/PasswdDialog.h delete mode 100644 unix/vncviewer/ServerDialog.h delete mode 100644 unix/vncviewer/buildtime.c delete mode 100644 unix/vncviewer/gettext.h delete mode 100644 unix/vncviewer/parameters.h delete mode 100644 unix/vncviewer/vncviewer.cxx delete mode 100644 unix/vncviewer/vncviewer.man delete mode 100644 win/vncviewer/CConn.cxx delete mode 100644 win/vncviewer/CConn.h delete mode 100644 win/vncviewer/CConnOptions.cxx delete mode 100644 win/vncviewer/CConnOptions.h delete mode 100644 win/vncviewer/CConnThread.cxx delete mode 100644 win/vncviewer/CConnThread.h delete mode 100644 win/vncviewer/CMakeLists.txt delete mode 100644 win/vncviewer/ConnectingDialog.cxx delete mode 100644 win/vncviewer/ConnectingDialog.h delete mode 100644 win/vncviewer/ConnectionDialog.cxx delete mode 100644 win/vncviewer/ConnectionDialog.h delete mode 100644 win/vncviewer/DesktopWindow.cxx delete mode 100644 win/vncviewer/DesktopWindow.h delete mode 100644 win/vncviewer/InfoDialog.cxx delete mode 100644 win/vncviewer/InfoDialog.h delete mode 100644 win/vncviewer/ListenServer.h delete mode 100644 win/vncviewer/ListenTrayIcon.h delete mode 100644 win/vncviewer/MRU.h delete mode 100644 win/vncviewer/OptionsDialog.cxx delete mode 100644 win/vncviewer/OptionsDialog.h delete mode 100644 win/vncviewer/UserPasswdDialog.cxx delete mode 100644 win/vncviewer/UserPasswdDialog.h delete mode 100644 win/vncviewer/ViewerToolBar.cxx delete mode 100644 win/vncviewer/ViewerToolBar.h delete mode 100644 win/vncviewer/buildTime.cxx delete mode 100644 win/vncviewer/cursor1.cur delete mode 100644 win/vncviewer/resource.h delete mode 100644 win/vncviewer/toolbar.bmp delete mode 100644 win/vncviewer/vncviewer.bmp delete mode 100644 win/vncviewer/vncviewer.cxx delete mode 100644 win/vncviewer/vncviewer.exe.manifest delete mode 100644 win/vncviewer/vncviewer.exe.manifest64 delete mode 100644 win/vncviewer/vncviewer.ico delete mode 100644 win/vncviewer/vncviewer.rc diff --git a/CMakeLists.txt b/CMakeLists.txt index d39a2b86..1c378685 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,9 +23,6 @@ set(VERSION 1.1.80) # The RC version must always be four comma-separated numbers set(RCVERSION 1,1,80,0) -# Manual toggle until we can deprecate the old viewers -option(BUILD_NEW_VNCVIEWER "Build the new FLTK based vncviewer instead of the old ones" ON) - # Compatibility variables for the migration from autotools add_definitions(-DPACKAGE_NAME="${CMAKE_PROJECT_NAME}") add_definitions(-DPACKAGE_VERSION="${VERSION}") @@ -270,72 +267,69 @@ if(BUILD_JAVA) endif() # Check for FLTK -if(BUILD_NEW_VNCVIEWER) - set(FLTK_SKIP_FLUID TRUE) - set(FLTK_SKIP_OPENGL TRUE) - set(FLTK_SKIP_IMAGES TRUE) - set(FLTK_SKIP_FORMS TRUE) - find_package(FLTK) - - if(NOT APPLE) - # No proper handling for extra X11 libs that FLTK might need... - if(X11_Xft_FOUND) - set(FLTK_LIBRARIES ${FLTK_LIBRARIES} ${X11_Xft_LIB}) - endif() - if(X11_Xinerama_FOUND) - set(FLTK_LIBRARIES ${FLTK_LIBRARIES} ${X11_Xinerama_LIB}) - endif() - if(X11_Xfixes_FOUND) - set(FLTK_LIBRARIES ${FLTK_LIBRARIES} ${X11_Xfixes_LIB}) - endif() - if(X11_Xcursor_FOUND) - set(FLTK_LIBRARIES ${FLTK_LIBRARIES} ${X11_Xcursor_LIB}) - endif() +set(FLTK_SKIP_FLUID TRUE) +set(FLTK_SKIP_OPENGL TRUE) +set(FLTK_SKIP_IMAGES TRUE) +set(FLTK_SKIP_FORMS TRUE) +find_package(FLTK) + +if(NOT APPLE) + # No proper handling for extra X11 libs that FLTK might need... + if(X11_Xft_FOUND) + set(FLTK_LIBRARIES ${FLTK_LIBRARIES} ${X11_Xft_LIB}) + endif() + if(X11_Xinerama_FOUND) + set(FLTK_LIBRARIES ${FLTK_LIBRARIES} ${X11_Xinerama_LIB}) + endif() + if(X11_Xfixes_FOUND) + set(FLTK_LIBRARIES ${FLTK_LIBRARIES} ${X11_Xfixes_LIB}) endif() + if(X11_Xcursor_FOUND) + set(FLTK_LIBRARIES ${FLTK_LIBRARIES} ${X11_Xcursor_LIB}) + endif() +endif() - if(FLTK_FOUND) - set(CMAKE_REQUIRED_INCLUDES ${FLTK_INCLUDE_DIR}) - set(CMAKE_REQUIRED_LIBRARIES ${FLTK_LIBRARIES}) +if(FLTK_FOUND) + set(CMAKE_REQUIRED_INCLUDES ${FLTK_INCLUDE_DIR}) + set(CMAKE_REQUIRED_LIBRARIES ${FLTK_LIBRARIES}) - # FLTK STR #2599 - check_cxx_source_compiles("#include \nint main(int c, char** v) { void (Fl_Widget::*foo)() = &Fl_Widget::set_simple_keyboard; return 0; }" HAVE_FLTK_DEAD_KEYS) + # FLTK STR #2599 + check_cxx_source_compiles("#include \nint main(int c, char** v) { void (Fl_Widget::*foo)() = &Fl_Widget::set_simple_keyboard; return 0; }" HAVE_FLTK_DEAD_KEYS) - # FLTK STR #2636 - check_cxx_source_compiles("#include \nint main(int c, char** v) { Fl::add_clipboard_notify(NULL, NULL); return 0; }" HAVE_FLTK_CLIPBOARD) + # FLTK STR #2636 + check_cxx_source_compiles("#include \nint main(int c, char** v) { Fl::add_clipboard_notify(NULL, NULL); return 0; }" HAVE_FLTK_CLIPBOARD) - # FLTK STR #2638 - check_cxx_source_compiles("#include \nint main(int c, char** v) { return FL_Volume_Down; }" HAVE_FLTK_MEDIAKEYS) + # FLTK STR #2638 + check_cxx_source_compiles("#include \nint main(int c, char** v) { return FL_Volume_Down; }" HAVE_FLTK_MEDIAKEYS) - # FLTK STR #2641 - check_cxx_source_compiles("#include \nint main(int c, char** v) { return FL_FULLSCREEN; }" HAVE_FLTK_FULLSCREEN) + # FLTK STR #2641 + check_cxx_source_compiles("#include \nint main(int c, char** v) { return FL_FULLSCREEN; }" HAVE_FLTK_FULLSCREEN) - # FLTK STR #2660 - check_cxx_source_compiles("#include \nint main(int c, char** v) { void (Fl_Window::*foo)(const Fl_RGB_Image*,int,int) = &Fl_Window::cursor; return 0; }" HAVE_FLTK_CURSOR) + # FLTK STR #2660 + check_cxx_source_compiles("#include \nint main(int c, char** v) { void (Fl_Window::*foo)(const Fl_RGB_Image*,int,int) = &Fl_Window::cursor; return 0; }" HAVE_FLTK_CURSOR) - set(CMAKE_REQUIRED_INCLUDES) - set(CMAKE_REQUIRED_LIBRARIES) - endif() + set(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_REQUIRED_LIBRARIES) +endif() - option(USE_INCLUDED_FLTK - "Force the use of the FLTK library bundled with the TigerVNC source") - if(NOT FLTK_FOUND OR NOT HAVE_FLTK_DEAD_KEYS OR NOT HAVE_FLTK_CLIPBOARD - OR NOT HAVE_FLTK_MEDIAKEYS OR NOT HAVE_FLTK_FULLSCREEN - OR NOT HAVE_FLTK_CURSOR) - set(USE_INCLUDED_FLTK 1) - endif() - if(USE_INCLUDED_FLTK) - set(FLTK_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/common/fltk) - set(FLTK_LIBRARIES) - if(APPLE) - set(FLTK_LIBRARIES "-framework Carbon -framework Cocoa -framework ApplicationServices") - elseif(NOT WIN32) - set(FLTK_LIBRARIES "-ldl") - endif() - message(STATUS "Using included FLTK library") +option(USE_INCLUDED_FLTK + "Force the use of the FLTK library bundled with the TigerVNC source") +if(NOT FLTK_FOUND OR NOT HAVE_FLTK_DEAD_KEYS OR NOT HAVE_FLTK_CLIPBOARD + OR NOT HAVE_FLTK_MEDIAKEYS OR NOT HAVE_FLTK_FULLSCREEN + OR NOT HAVE_FLTK_CURSOR) + set(USE_INCLUDED_FLTK 1) +endif() +if(USE_INCLUDED_FLTK) + set(FLTK_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/common/fltk) + set(FLTK_LIBRARIES) + if(APPLE) + set(FLTK_LIBRARIES "-framework Carbon -framework Cocoa -framework ApplicationServices") + elseif(NOT WIN32) + set(FLTK_LIBRARIES "-ldl") endif() - + message(STATUS "Using included FLTK library") endif() - + # Check for GNUTLS library option(ENABLE_GNUTLS "Enable protocol encryption and advanced authentication" ON) if(ENABLE_GNUTLS) @@ -421,12 +415,10 @@ else() endif() endif() -if(BUILD_NEW_VNCVIEWER) - if(ENABLE_NLS) - add_subdirectory(po) - endif() - add_subdirectory(vncviewer) +if(ENABLE_NLS) + add_subdirectory(po) endif() +add_subdirectory(vncviewer) include(cmake/BuildPackages.cmake) diff --git a/unix/CMakeLists.txt b/unix/CMakeLists.txt index bb2f871b..3ffe79c9 100644 --- a/unix/CMakeLists.txt +++ b/unix/CMakeLists.txt @@ -4,9 +4,5 @@ add_subdirectory(vncconfig) add_subdirectory(vncpasswd) add_subdirectory(x0vncserver) -if(NOT BUILD_NEW_VNCVIEWER) -add_subdirectory(vncviewer) -endif() - install(PROGRAMS vncserver DESTINATION bin) install(FILES vncserver.man DESTINATION man/man1 RENAME vncserver.1) diff --git a/unix/vncviewer/AboutDialog.h b/unix/vncviewer/AboutDialog.h deleted file mode 100644 index ff7290a1..00000000 --- a/unix/vncviewer/AboutDialog.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ -// -// AboutDialog.h -// - -#ifndef __ABOUTDIALOG_H__ -#define __ABOUTDIALOG_H__ - -#include "TXMsgBox.h" -#include "parameters.h" - -#include "gettext.h" -#define _(String) gettext (String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) - -extern char buildtime[]; - -class AboutDialog : public TXMsgBox { -public: - AboutDialog(Display* dpy) - : TXMsgBox(dpy, aboutText, MB_OK, _("About TigerVNC Viewer")) { - } -}; - -#endif diff --git a/unix/vncviewer/CConn.cxx b/unix/vncviewer/CConn.cxx deleted file mode 100644 index f93a3d60..00000000 --- a/unix/vncviewer/CConn.cxx +++ /dev/null @@ -1,1038 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * Copyright 2009 Pierre Ossman for Cendio AB - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ -// -// CConn.cxx -// - -#include -#include "CConn.h" -#include -#include -#include -#include -#include -#ifdef HAVE_GNUTLS -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include - -#include "TXViewport.h" -#include "DesktopWindow.h" -#include "ServerDialog.h" -#include "PasswdDialog.h" -#include "parameters.h" - -using namespace rdr; -using namespace rfb; -using namespace std; - -static rfb::LogWriter vlog("CConn"); - -IntParameter debugDelay("DebugDelay","Milliseconds to display inverted " - "pixel data - a debugging feature", 0); - -StringParameter menuKey("MenuKey", "The key which brings up the popup menu", - "F8"); -StringParameter windowName("name", "The X window name", ""); - -CConn::CConn(Display* dpy_, int argc_, char** argv_, network::Socket* sock_, - char* vncServerName, bool reverse) - : dpy(dpy_), argc(argc_), - argv(argv_), serverHost(0), serverPort(0), sock(sock_), viewport(0), - desktop(0), desktopEventHandler(0), - currentEncoding(encodingTight), lastServerEncoding((unsigned int)-1), - fullColour(::fullColour), - autoSelect(::autoSelect), shared(::shared), formatChange(false), - encodingChange(false), sameMachine(false), fullScreen(::fullScreen), - ctrlDown(false), altDown(false), - menuKeysym(0), menu(dpy, this), options(dpy, this), about(dpy), info(dpy), - reverseConnection(reverse), firstUpdate(true), pendingUpdate(false) -{ - CharArray menuKeyStr(menuKey.getData()); - menuKeysym = XStringToKeysym(menuKeyStr.buf); - - setShared(shared); - CSecurity::upg = this; /* Security instance is created in CConnection constructor. */ -#ifdef HAVE_GNUTLS - CSecurityTLS::msg = this; -#endif - - CharArray encStr(preferredEncoding.getData()); - int encNum = encodingNum(encStr.buf); - if (encNum != -1) { - currentEncoding = encNum; - } - cp.supportsDesktopResize = true; - cp.supportsExtendedDesktopSize = true; - cp.supportsDesktopRename = true; - cp.supportsLocalCursor = useLocalCursor; - cp.customCompressLevel = customCompressLevel; - cp.compressLevel = compressLevel; - cp.noJpeg = noJpeg; - cp.qualityLevel = qualityLevel; - initMenu(); - - if (sock) { - char* name = sock->getPeerEndpoint(); - vlog.info("Accepted connection from %s", name); - if (name) free(name); - } else { - if (vncServerName) { - getHostAndPort(vncServerName, &serverHost, &serverPort); - } else { - ServerDialog dlg(dpy, &options, &about); - if (!dlg.show() || dlg.entry.getText()[0] == 0) { - exit(1); - } - getHostAndPort(dlg.entry.getText(), &serverHost, &serverPort); - } - - sock = new network::TcpSocket(serverHost, serverPort); - vlog.info("connected to host %s port %d", serverHost, serverPort); - } - - sameMachine = sock->sameMachine(); - sock->inStream().setBlockCallback(this); - setServerName(serverHost); - setStreams(&sock->inStream(), &sock->outStream()); - initialiseProtocol(); -} - -CConn::~CConn() { - free(serverHost); - delete desktop; - delete viewport; - delete sock; -} - -bool CConn::showMsgBox(int flags, const char* title, const char* text) -{ - CharArray titleText(12 + strlen(title) + 1); - sprintf(titleText.buf, "VNC Viewer: %s", title); - - TXMsgBox msgBox(dpy,text,flags,titleText.buf); - return msgBox.show(); -} - -// deleteWindow() is called when the user closes the desktop or menu windows. - -void CConn::deleteWindow(TXWindow* w) { - if (w == &menu) { - menu.unmap(); - } else if (w == viewport) { - exit(1); - } -} - -// handleEvent() filters all events on the desktop and menu. Most are passed -// straight through. The exception is the F8 key. When pressed on the -// desktop, it is used to bring up the menu. An F8 press or release on the -// menu is passed through as if it were on the desktop. - -void CConn::handleEvent(TXWindow* w, XEvent* ev) -{ - KeySym ks; - char str[256]; - - switch (ev->type) { - case KeyPress: - case KeyRelease: - XLookupString(&ev->xkey, str, 256, &ks, NULL); - if (ks == menuKeysym && (ev->xkey.state & (ShiftMask|ControlMask)) == 0) { - if (w == desktop && ev->type == KeyPress) { - showMenu(ev->xkey.x_root, ev->xkey.y_root); - break; - } else if (w == &menu) { - if (ev->type == KeyPress) menu.unmap(); - desktopEventHandler->handleEvent(w, ev); - break; - } - } - // drop through - - default: - if (w == desktop) desktopEventHandler->handleEvent(w, ev); - else if (w == &menu) menuEventHandler->handleEvent(w, ev); - } -} - -// blockCallback() is called when reading from the socket would block. We -// process X events until the socket is ready for reading again. - -void CConn::blockCallback() { - fd_set rfds; - do { - struct timeval tv; - struct timeval* tvp = 0; - - // Process any incoming X events - TXWindow::handleXEvents(dpy); - - // Process expired timers and get the time until the next one - int timeoutMs = Timer::checkTimeouts(); - if (timeoutMs) { - tv.tv_sec = timeoutMs / 1000; - tv.tv_usec = (timeoutMs % 1000) * 1000; - tvp = &tv; - } - - // If there are X requests pending then poll, don't wait! - if (XPending(dpy)) { - tv.tv_usec = tv.tv_sec = 0; - tvp = &tv; - } - - // Wait for X events, VNC traffic, or the next timer expiry - FD_ZERO(&rfds); - FD_SET(ConnectionNumber(dpy), &rfds); - FD_SET(sock->getFd(), &rfds); - int n = select(FD_SETSIZE, &rfds, 0, 0, tvp); - if (n < 0) throw rdr::SystemException("select",errno); - } while (!(FD_ISSET(sock->getFd(), &rfds))); -} - - -// getPasswd() is called by the CSecurity object when it needs us to read a -// password from the user. - -void CConn::getUserPasswd(char** user, char** password) -{ - CharArray passwordFileStr(passwordFile.getData()); - if (!user && passwordFileStr.buf[0]) { - FILE* fp = fopen(passwordFileStr.buf, "r"); - if (!fp) throw rfb::Exception("Opening password file failed"); - ObfuscatedPasswd obfPwd(256); - obfPwd.length = fread(obfPwd.buf, 1, obfPwd.length, fp); - fclose(fp); - PlainPasswd passwd(obfPwd); - *password = passwd.takeBuf(); - return; - } - - const char* secType = secTypeName(csecurity->getType()); - const char* titlePrefix = _("VNC authentication"); - unsigned int titleLen = strlen(titlePrefix) + strlen(secType) + 4; - CharArray title(titleLen); - snprintf(title.buf, titleLen, "%s [%s]", titlePrefix, secType); - PasswdDialog dlg(dpy, title.buf, !user); - if (!dlg.show()) throw rfb::Exception("Authentication cancelled"); - if (user) - *user = strDup(dlg.userEntry.getText()); - *password = strDup(dlg.passwdEntry.getText()); -} - -// CConnection callback methods - -// serverInit() is called when the serverInit message has been received. At -// this point we create the desktop window and display it. We also tell the -// server the pixel format and encodings to use and request the first update. -void CConn::serverInit() { - CConnection::serverInit(); - - // If using AutoSelect with old servers, start in FullColor - // mode. See comment in autoSelectFormatAndEncoding. - if (cp.beforeVersion(3, 8) && autoSelect) { - fullColour = true; - } - - serverPF = cp.pf(); - desktop = new DesktopWindow(dpy, cp.width, cp.height, serverPF, this); - desktopEventHandler = desktop->setEventHandler(this); - desktop->addEventMask(KeyPressMask | KeyReleaseMask); - fullColourPF = desktop->getPF(); - if (!serverPF.trueColour) - fullColour = true; - recreateViewport(); - formatChange = encodingChange = true; - requestNewUpdate(); -} - -// setDesktopSize() is called when the desktop size changes (including when -// it is set initially). -void CConn::setDesktopSize(int w, int h) { - CConnection::setDesktopSize(w,h); - resizeFramebuffer(); -} - -// setExtendedDesktopSize() is a more advanced version of setDesktopSize() -void CConn::setExtendedDesktopSize(int reason, int result, int w, int h, - const rfb::ScreenSet& layout) { - CConnection::setExtendedDesktopSize(reason, result, w, h, layout); - - if ((reason == reasonClient) && (result != resultSuccess)) { - vlog.error("SetDesktopSize failed: %d", result); - return; - } - - resizeFramebuffer(); -} - -// setName() is called when the desktop name changes -void CConn::setName(const char* name) { - CConnection::setName(name); - - CharArray windowNameStr(windowName.getData()); - if (!windowNameStr.buf[0]) { - windowNameStr.replaceBuf(new char[256]); - snprintf(windowNameStr.buf, 256, _("TigerVNC: %.240s"), cp.name()); - } - - if (viewport) { - viewport->setName(windowNameStr.buf); - } -} - -// framebufferUpdateStart() is called at the beginning of an update. -// Here we try to send out a new framebuffer update request so that the -// next update can be sent out in parallel with us decoding the current -// one. We cannot do this if we're in the middle of a format change -// though. -void CConn::framebufferUpdateStart() { - if (!formatChange) { - pendingUpdate = true; - requestNewUpdate(); - } else - pendingUpdate = false; -} - -// framebufferUpdateEnd() is called at the end of an update. -// For each rectangle, the FdInStream will have timed the speed -// of the connection, allowing us to select format and encoding -// appropriately, and then request another incremental update. -void CConn::framebufferUpdateEnd() { - if (debugDelay != 0) { - XSync(dpy, False); - struct timeval tv; - tv.tv_sec = debugDelay / 1000; - tv.tv_usec = (debugDelay % 1000) * 1000; - select(0, 0, 0, 0, &tv); - std::list::iterator i; - for (i = debugRects.begin(); i != debugRects.end(); i++) { - desktop->invertRect(*i); - } - debugRects.clear(); - } - desktop->framebufferUpdateEnd(); - - if (firstUpdate) { - int width, height; - - if (cp.supportsSetDesktopSize && - sscanf(desktopSize.getValueStr(), "%dx%d", &width, &height) == 2) { - ScreenSet layout; - - layout = cp.screenLayout; - - if (layout.num_screens() == 0) - layout.add_screen(rfb::Screen()); - else if (layout.num_screens() != 1) { - ScreenSet::iterator iter; - - while (true) { - iter = layout.begin(); - ++iter; - - if (iter == layout.end()) - break; - - layout.remove_screen(iter->id); - } - } - - layout.begin()->dimensions.tl.x = 0; - layout.begin()->dimensions.tl.y = 0; - layout.begin()->dimensions.br.x = width; - layout.begin()->dimensions.br.y = height; - - writer()->writeSetDesktopSize(width, height, layout); - } - - firstUpdate = false; - } - - // A format change prevented us from sending this before the update, - // so make sure to send it now. - if (formatChange && !pendingUpdate) - requestNewUpdate(); - - // Compute new settings based on updated bandwidth values - if (autoSelect) - autoSelectFormatAndEncoding(); - - // Make sure that the X11 handling and the timers gets some CPU time - // in case of back to back framebuffer updates. - TXWindow::handleXEvents(dpy); - Timer::checkTimeouts(); -} - -// The rest of the callbacks are fairly self-explanatory... - -void CConn::setColourMapEntries(int firstColour, int nColours, rdr::U16* rgbs) -{ - desktop->setColourMapEntries(firstColour, nColours, rgbs); -} - -void CConn::bell() { XBell(dpy, 0); } - -void CConn::serverCutText(const char* str, rdr::U32 len) { - desktop->serverCutText(str,len); -} - -// We start timing on beginRect and stop timing on endRect, to -// avoid skewing the bandwidth estimation as a result of the server -// being slow or the network having high latency -void CConn::beginRect(const Rect& r, int encoding) -{ - sock->inStream().startTiming(); - if (encoding != encodingCopyRect) { - lastServerEncoding = encoding; - } -} - -void CConn::endRect(const Rect& r, int encoding) -{ - sock->inStream().stopTiming(); - if (debugDelay != 0) { - desktop->invertRect(r); - debugRects.push_back(r); - } -} - -void CConn::fillRect(const rfb::Rect& r, rfb::Pixel p) { - desktop->fillRect(r,p); -} -void CConn::imageRect(const rfb::Rect& r, void* p) { - desktop->imageRect(r,p); -} -void CConn::copyRect(const rfb::Rect& r, int sx, int sy) { - desktop->copyRect(r,sx,sy); -} -void CConn::setCursor(int width, int height, const Point& hotspot, - void* data, void* mask) { - desktop->setCursor(width, height, hotspot, data, mask); -} - - -// Menu stuff - menuSelect() is called when the user selects a menu option. - -enum { ID_OPTIONS, ID_INFO, ID_FULLSCREEN, ID_REFRESH, ID_F8, ID_CTRLALTDEL, - ID_ABOUT, ID_DISMISS, ID_EXIT, ID_NEWCONN, ID_CTRL, ID_ALT }; - -void CConn::initMenu() { - menuEventHandler = menu.setEventHandler(this); - menu.addEventMask(KeyPressMask | KeyReleaseMask); - 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(64); - snprintf(sendMenuKey.buf, 64, _("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 TigerVNC viewer..."), 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); - if (x + menu.width() > viewport->width()) - x = viewport->width() - menu.width(); - if (y + menu.height() > viewport->height()) - y = viewport->height() - menu.height(); - 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, NULL); - 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 = csecurity->getType(); - char infoText[1024]; - snprintf(infoText, sizeof(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(); - if (!formatChange) { - writer()->writeFramebufferUpdateRequest(Rect(0, 0, cp.width, cp.height), - false); - pendingUpdate = true; - } - 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() { - char digit[2] = "0"; - 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.tight.checked(currentEncoding == encodingTight); - options.zrle.checked(currentEncoding == encodingZRLE); - options.hextile.checked(currentEncoding == encodingHextile); - options.raw.checked(currentEncoding == encodingRaw); - - options.customCompressLevel.checked(customCompressLevel); - digit[0] = '0' + compressLevel; - options.compressLevel.setText(digit); - options.noJpeg.checked(!noJpeg); - digit[0] = '0' + qualityLevel; - options.qualityLevel.setText(digit); - - options.viewOnly.checked(viewOnly); - options.acceptClipboard.checked(acceptClipboard); - options.sendClipboard.checked(sendClipboard); - options.sendPrimary.checked(sendPrimary); - if (state() == RFBSTATE_NORMAL) { - options.shared.disabled(true); -#ifdef HAVE_GNUTLS - options.secVeNCrypt.disabled(true); - options.encNone.disabled(true); - options.encTLS.disabled(true); - options.encX509.disabled(true); - options.ca.disabled(true); - options.crl.disabled(true); - options.secNone.disabled(true); - options.secVnc.disabled(true); - options.secPlain.disabled(true); -#endif - } else { - options.shared.checked(shared); - -#ifdef HAVE_GNUTLS - /* Process non-VeNCrypt sectypes */ - list secTypes = security->GetEnabledSecTypes(); - list::iterator i; - for (i = secTypes.begin(); i != secTypes.end(); i++) { - switch (*i) { - case secTypeVeNCrypt: - options.secVeNCrypt.checked(true); - break; - case secTypeNone: - options.encNone.checked(true); - options.secNone.checked(true); - break; - case secTypeVncAuth: - options.encNone.checked(true); - options.secVnc.checked(true); - break; - } - } - - /* Process VeNCrypt subtypes */ - if (options.secVeNCrypt.checked()) { - list secTypesExt = security->GetEnabledExtSecTypes(); - list::iterator iext; - for (iext = secTypesExt.begin(); iext != secTypesExt.end(); iext++) { - switch (*iext) { - case secTypePlain: - options.encNone.checked(true); - options.secPlain.checked(true); - break; - case secTypeTLSNone: - options.encTLS.checked(true); - options.secNone.checked(true); - break; - case secTypeTLSVnc: - options.encTLS.checked(true); - options.secVnc.checked(true); - break; - case secTypeTLSPlain: - options.encTLS.checked(true); - options.secPlain.checked(true); - break; - case secTypeX509None: - options.encX509.checked(true); - options.secNone.checked(true); - break; - case secTypeX509Vnc: - options.encX509.checked(true); - options.secVnc.checked(true); - break; - case secTypeX509Plain: - options.encX509.checked(true); - options.secPlain.checked(true); - break; - } - } - } -#endif - } - 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; - } - } - int newEncoding = (options.tight.checked() ? encodingTight : - options.zrle.checked() ? encodingZRLE : - options.hextile.checked() ? encodingHextile : - encodingRaw); - if (newEncoding != currentEncoding) { - currentEncoding = newEncoding; - encodingChange = true; - } - - customCompressLevel.setParam(options.customCompressLevel.checked()); - if (cp.customCompressLevel != customCompressLevel) { - cp.customCompressLevel = customCompressLevel; - encodingChange = true; - } - compressLevel.setParam(options.compressLevel.getText()); - if (cp.compressLevel != compressLevel) { - cp.compressLevel = compressLevel; - encodingChange = true; - } - noJpeg.setParam(!options.noJpeg.checked()); - if (cp.noJpeg != noJpeg) { - cp.noJpeg = noJpeg; - encodingChange = true; - } - qualityLevel.setParam(options.qualityLevel.getText()); - if (cp.qualityLevel != qualityLevel) { - cp.qualityLevel = qualityLevel; - 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()); - if (desktop) - desktop->setNoCursor(); - checkEncodings(); - -#ifdef HAVE_GNUTLS - /* Process security types which don't use encryption */ - if (options.encNone.checked()) { - if (options.secNone.checked()) - security->EnableSecType(secTypeNone); - if (options.secVnc.checked()) - security->EnableSecType(secTypeVncAuth); - if (options.secPlain.checked()) - security->EnableSecType(secTypePlain); - } else { - security->DisableSecType(secTypeNone); - security->DisableSecType(secTypeVncAuth); - security->DisableSecType(secTypePlain); - } - - /* Process security types which use TLS encryption */ - if (options.encTLS.checked()) { - if (options.secNone.checked()) - security->EnableSecType(secTypeTLSNone); - if (options.secVnc.checked()) - security->EnableSecType(secTypeTLSVnc); - if (options.secPlain.checked()) - security->EnableSecType(secTypeTLSPlain); - } else { - security->DisableSecType(secTypeTLSNone); - security->DisableSecType(secTypeTLSVnc); - security->DisableSecType(secTypeTLSPlain); - } - - /* Process security types which use X509 encryption */ - if (options.encX509.checked()) { - if (options.secNone.checked()) - security->EnableSecType(secTypeX509None); - if (options.secVnc.checked()) - security->EnableSecType(secTypeX509Vnc); - if (options.secPlain.checked()) - security->EnableSecType(secTypeX509Plain); - } else { - security->DisableSecType(secTypeX509None); - security->DisableSecType(secTypeX509Vnc); - security->DisableSecType(secTypeX509Plain); - } - - /* Process *None security types */ - if (options.secNone.checked()) { - if (options.encNone.checked()) - security->EnableSecType(secTypeNone); - if (options.encTLS.checked()) - security->EnableSecType(secTypeTLSNone); - if (options.encX509.checked()) - security->EnableSecType(secTypeX509None); - } else { - security->DisableSecType(secTypeNone); - security->DisableSecType(secTypeTLSNone); - security->DisableSecType(secTypeX509None); - } - - /* Process *Vnc security types */ - if (options.secVnc.checked()) { - if (options.encNone.checked()) - security->EnableSecType(secTypeVncAuth); - if (options.encTLS.checked()) - security->EnableSecType(secTypeTLSVnc); - if (options.encX509.checked()) - security->EnableSecType(secTypeX509Vnc); - } else { - security->DisableSecType(secTypeVncAuth); - security->DisableSecType(secTypeTLSVnc); - security->DisableSecType(secTypeX509Vnc); - } - - /* Process *Plain security types */ - if (options.secPlain.checked()) { - if (options.encNone.checked()) - security->EnableSecType(secTypePlain); - if (options.encTLS.checked()) - security->EnableSecType(secTypeTLSPlain); - if (options.encX509.checked()) - security->EnableSecType(secTypeX509Plain); - } else { - security->DisableSecType(secTypePlain); - security->DisableSecType(secTypeTLSPlain); - security->DisableSecType(secTypeX509Plain); - } - - CSecurityTLS::x509ca.setParam(options.ca.getText()); - CSecurityTLS::x509crl.setParam(options.crl.getText()); -#endif -} - -void CConn::resizeFramebuffer() -{ - if (!desktop) - return; - if ((desktop->width() == cp.width) && (desktop->height() == cp.height)) - return; - - desktop->resize(cp.width, cp.height); - recreateViewport(); -} - -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]); - snprintf(windowNameStr.buf, 256, _("TigerVNC: %.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); - } -} - -// Note: The method below is duplicated in win/vncviewer/CConn.cxx! - -// autoSelectFormatAndEncoding() chooses the format and encoding appropriate -// to the connection speed: -// -// First we wait for at least one second of bandwidth measurement. -// -// Above 16Mbps (i.e. LAN), we choose the second highest JPEG quality, -// which should be perceptually lossless. -// -// If the bandwidth is below that, we choose a more lossy JPEG quality. -// -// If the bandwidth drops below 256 Kbps, we switch to palette mode. -// -// Note: The system here is fairly arbitrary and should be replaced -// with something more intelligent at the server end. -// -void CConn::autoSelectFormatAndEncoding() -{ - int kbitsPerSecond = sock->inStream().kbitsPerSecond(); - unsigned int timeWaited = sock->inStream().timeWaited(); - bool newFullColour = fullColour; - int newQualityLevel = qualityLevel; - - // Always use Tight - if (currentEncoding != encodingTight) { - currentEncoding = encodingTight; - encodingChange = true; - } - - // Check that we have a decent bandwidth measurement - if ((kbitsPerSecond == 0) || (timeWaited < 10000)) - return; - - // Select appropriate quality level - if (!noJpeg) { - if (kbitsPerSecond > 16000) - newQualityLevel = 8; - else - newQualityLevel = 6; - - if (newQualityLevel != qualityLevel) { - vlog.info("Throughput %d kbit/s - changing to quality %d ", - kbitsPerSecond, newQualityLevel); - cp.qualityLevel = newQualityLevel; - qualityLevel.setParam(newQualityLevel); - encodingChange = true; - } - } - - if (cp.beforeVersion(3, 8)) { - // Xvnc from TightVNC 1.2.9 sends out FramebufferUpdates with - // cursors "asynchronously". If this happens in the middle of a - // pixel format change, the server will encode the cursor with - // the old format, but the client will try to decode it - // according to the new format. This will lead to a - // crash. Therefore, we do not allow automatic format change for - // old servers. - return; - } - - // Select best color level - newFullColour = (kbitsPerSecond > 256); - if (newFullColour != fullColour) { - vlog.info("Throughput %d kbit/s - full color is now %s", - kbitsPerSecond, - newFullColour ? "enabled" : "disabled"); - fullColour = newFullColour; - 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) { - - /* Catch incorrect requestNewUpdate calls */ - assert(pendingUpdate == false); - - 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; -} diff --git a/unix/vncviewer/CConn.h b/unix/vncviewer/CConn.h deleted file mode 100644 index 929e5b55..00000000 --- a/unix/vncviewer/CConn.h +++ /dev/null @@ -1,141 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * Copyright 2009 Pierre Ossman for Cendio AB - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ -// -// CConn represents a client connection to a VNC server. -// - -#ifndef __CCONN_H__ -#define __CCONN_H__ - -#include -#include -#include -#include -#include -#include - -#include "TXWindow.h" -#include "AboutDialog.h" -#include "InfoDialog.h" -#include "TXMenu.h" -#include "OptionsDialog.h" - -class TXWindow; -class TXViewport; -class DesktopWindow; -namespace network { class Socket; } - -class CConn : public rfb::CConnection, public rfb::UserPasswdGetter, - public TXDeleteWindowCallback, - public rdr::FdInStreamBlockCallback, - public TXMenuCallback , public OptionsDialogCallback, - public TXEventHandler, public rfb::UserMsgBox -{ -public: - - CConn(Display* dpy_, int argc_, char** argv_, network::Socket* sock_, - char* vncServerName, bool reverse=false); - ~CConn(); - - // TXDeleteWindowCallback methods - void deleteWindow(TXWindow* w); - - // FdInStreamBlockCallback methods - void blockCallback(); - - // UserPasswdGetter methods - virtual void getUserPasswd(char** user, char** password); - - // UserMsgBox methods - virtual bool showMsgBox(int flags, const char* title, const char* text); - - // TXMenuCallback methods - void menuSelect(long id, TXMenu* m); - - // OptionsDialogCallback methods - virtual void setOptions(); - virtual void getOptions(); - - // TXEventHandler callback method - virtual void handleEvent(TXWindow* w, XEvent* ev); - - // CConnection callback methods - void serverInit(); - void setDesktopSize(int w, int h); - void setExtendedDesktopSize(int reason, int result, int w, int h, - const rfb::ScreenSet& layout); - void setName(const char* name); - void setColourMapEntries(int firstColour, int nColours, rdr::U16* rgbs); - void bell(); - void serverCutText(const char* str, rdr::U32 len); - void framebufferUpdateStart(); - void framebufferUpdateEnd(); - void beginRect(const rfb::Rect& r, int encoding); - void endRect(const rfb::Rect& r, int encoding); - void fillRect(const rfb::Rect& r, rfb::Pixel p); - void imageRect(const rfb::Rect& r, void* p); - void copyRect(const rfb::Rect& r, int sx, int sy); - void setCursor(int width, int height, const rfb::Point& hotspot, - void* data, void* mask); - -private: - - void resizeFramebuffer(); - void recreateViewport(); - void reconfigureViewport(); - void initMenu(); - void showMenu(int x, int y); - void autoSelectFormatAndEncoding(); - void checkEncodings(); - void requestNewUpdate(); - - Display* dpy; - int argc; - char** argv; - char* serverHost; - int serverPort; - network::Socket* sock; - rfb::PixelFormat serverPF; - TXViewport* viewport; - DesktopWindow* desktop; - TXEventHandler* desktopEventHandler; - rfb::PixelFormat fullColourPF; - std::list debugRects; - int currentEncoding, lastServerEncoding; - bool fullColour; - bool autoSelect; - bool shared; - bool formatChange; - bool encodingChange; - bool sameMachine; - bool fullScreen; - bool ctrlDown; - bool altDown; - KeySym menuKeysym; - TXMenu menu; - TXEventHandler* menuEventHandler; - OptionsDialog options; - AboutDialog about; - InfoDialog info; - bool reverseConnection; - bool firstUpdate; - bool pendingUpdate; -}; - -#endif diff --git a/unix/vncviewer/CMakeLists.txt b/unix/vncviewer/CMakeLists.txt deleted file mode 100644 index 0a292680..00000000 --- a/unix/vncviewer/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -include_directories(${X11_INCLUDE_DIR}) - -include_directories(${CMAKE_SOURCE_DIR}/common) -include_directories(${CMAKE_SOURCE_DIR}/unix/tx) -include_directories(${CMAKE_SOURCE_DIR}/intl) - -add_executable(vncviewer - buildtime.c - CConn.cxx - DesktopWindow.cxx - vncviewer.cxx) - -target_link_libraries(vncviewer tx rfb network rdr os ${X11_LIBRARIES}) diff --git a/unix/vncviewer/DesktopWindow.cxx b/unix/vncviewer/DesktopWindow.cxx deleted file mode 100644 index 234e0049..00000000 --- a/unix/vncviewer/DesktopWindow.cxx +++ /dev/null @@ -1,580 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ -// -// DesktopWindow.cxx -// - -#include "DesktopWindow.h" -#include "CConn.h" -#include -#include -#include -#include -#include -#include -#include "parameters.h" - -#ifndef XK_ISO_Left_Tab -#define XK_ISO_Left_Tab 0xFE20 -#endif - -static rdr::U8 reverseBits[] = { - 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, - 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, - 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4, - 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, - 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, - 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, - 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, - 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, - 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, - 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, - 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1, - 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, - 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, - 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, - 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd, - 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, - 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, - 0x33, 0xb3, 0x73, 0xf3, 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, - 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7, - 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, - 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, - 0x3f, 0xbf, 0x7f, 0xff -}; - -using namespace rfb; - -static rfb::LogWriter vlog("DesktopWindow"); - -DesktopWindow::DesktopWindow(Display* dpy, int w, int h, - const rfb::PixelFormat& serverPF, - CConn* cc_, TXWindow* parent) - : TXWindow(dpy, w, h, parent), cc(cc_), im(0), updateTimer(this), - cursorVisible(false), cursorAvailable(false), currentSelectionTime(0), - newSelection(0), gettingInitialSelectionTime(true), - newServerCutText(false), serverCutText_(0), - setColourMapEntriesTimer(this), viewport(0), - pointerEventTimer(this), - lastButtonMask(0) -{ - setEventHandler(this); - gc = XCreateGC(dpy, win(), 0, 0); - addEventMask(ExposureMask | ButtonPressMask | ButtonReleaseMask | - PointerMotionMask | KeyPressMask | KeyReleaseMask | - EnterWindowMask | LeaveWindowMask); - createXCursors(); - setNoCursor(); - im = new TXImage(dpy, width(), height()); - if (!serverPF.trueColour) - im->setPF(serverPF); - XConvertSelection(dpy, sendPrimary ? XA_PRIMARY : xaCLIPBOARD, xaTIMESTAMP, - xaSELECTION_TIME, win(), CurrentTime); - memset(downKeysym, 0, 256*4); -} - -DesktopWindow::~DesktopWindow() -{ - XFreeGC(dpy, gc); - XFreeCursor(dpy, dotCursor); - XFreeCursor(dpy, noCursor); - if (localXCursor) - XFreeCursor(dpy, localXCursor); - delete im; -} - -void DesktopWindow::setViewport(TXViewport* viewport_) -{ - viewport = viewport_; - viewport->setChild(this); -} - -// Cursor stuff - -void DesktopWindow::createXCursors() -{ - static char dotSource[] = { 0x00, 0x0e, 0x0e, 0x0e, 0x00 }; - static char dotMask[] = { 0x1f, 0x1f, 0x1f, 0x1f, 0x1f }; - Pixmap source = XCreateBitmapFromData(dpy, win(), dotSource, 5, 5); - Pixmap mask = XCreateBitmapFromData(dpy, win(), dotMask, 5, 5); - XColor fg, bg; - fg.red = fg.green = fg.blue = 0; - bg.red = bg.green = bg.blue = 0xffff; - dotCursor = XCreatePixmapCursor(dpy, source, mask, &fg, &bg, 2, 2); - XFreePixmap(dpy, source); - XFreePixmap(dpy, mask); - char zero = 0; - Pixmap empty = XCreateBitmapFromData(dpy, win(), &zero, 1, 1); - noCursor = XCreatePixmapCursor(dpy, empty, empty, &fg, &bg, 0, 0); - XFreePixmap(dpy, empty); - localXCursor = 0; -} - -void DesktopWindow::setCursor(int width, int height, const Point& hotspot, - void* data, void* mask) -{ - if (!useLocalCursor) return; - - hideLocalCursor(); - - int mask_len = ((width+7)/8) * height; - - int i; - for (i = 0; i < mask_len; i++) - if (((rdr::U8*)mask)[i]) break; - - if (i == mask_len) { - if (dotWhenNoCursor) - vlog.debug("cursor is empty - using dot"); - setNoCursor(); - cursorAvailable = false; - return; - } - - cursor.hotspot = hotspot; - - cursor.setSize(width, height); - cursor.setPF(getPF()); - cursor.imageRect(cursor.getRect(), data); - - cursorBacking.setSize(width, height); - cursorBacking.setPF(getPF()); - - delete [] cursor.mask.buf; - cursor.mask.buf = new rdr::U8[mask_len]; - memcpy(cursor.mask.buf, mask, mask_len); - - Pixel pix0, pix1; - rdr::U8Array bitmap(cursor.getBitmap(&pix0, &pix1)); - if (bitmap.buf && cursor.getRect().contains(cursor.hotspot)) { - int bytesPerRow = (cursor.width() + 7) / 8; - for (int j = 0; j < cursor.height(); j++) { - for (int i = 0; i < bytesPerRow; i++) { - bitmap.buf[j * bytesPerRow + i] - = reverseBits[bitmap.buf[j * bytesPerRow + i]]; - cursor.mask.buf[j * bytesPerRow + i] - = reverseBits[cursor.mask.buf[j * bytesPerRow + i]]; - } - } - Pixmap source = XCreateBitmapFromData(dpy, win(), (char*)bitmap.buf, - cursor.width(), cursor.height()); - Pixmap mask = XCreateBitmapFromData(dpy, win(), (char*)cursor.mask.buf, - cursor.width(), cursor.height()); - Colour rgb; - XColor fg, bg; - getPF().rgbFromPixel(pix1, im->getColourMap(), &rgb); - fg.red = rgb.r; fg.green = rgb.g; fg.blue = rgb.b; - getPF().rgbFromPixel(pix0, im->getColourMap(), &rgb); - bg.red = rgb.r; bg.green = rgb.g; bg.blue = rgb.b; - if (localXCursor) - XFreeCursor(dpy, localXCursor); - localXCursor = XCreatePixmapCursor(dpy, source, mask, &fg, &bg, - cursor.hotspot.x, cursor.hotspot.y); - XDefineCursor(dpy, win(), localXCursor); - XFreePixmap(dpy, source); - XFreePixmap(dpy, mask); - cursorAvailable = false; - return; - } - - if (!cursorAvailable) { - XDefineCursor(dpy, win(), noCursor); - cursorAvailable = true; - } - - showLocalCursor(); -} - -void DesktopWindow::resetLocalCursor() -{ - hideLocalCursor(); - setNoCursor(); - cursorAvailable = false; -} - -void DesktopWindow::hideLocalCursor() -{ - // - Blit the cursor backing store over the cursor - if (cursorVisible) { - cursorVisible = false; - im->imageRect(cursorBackingRect, cursorBacking.data); - damageRect(cursorBackingRect); - } -} - -void DesktopWindow::showLocalCursor() -{ - if (cursorAvailable && !cursorVisible) { - if (!getPF().equal(cursor.getPF()) || - cursor.getRect().is_empty()) { - vlog.error("attempting to render invalid local cursor"); - setNoCursor(); - cursorAvailable = false; - return; - } - cursorVisible = true; - - rfb::Rect cursorRect = (cursor.getRect().translate(cursorPos). - translate(cursor.hotspot.negate())); - cursorBackingRect = cursorRect.intersect(im->getRect()); - im->getImage(cursorBacking.data, cursorBackingRect); - - im->maskRect(cursorRect, cursor.data, cursor.mask.buf); - damageRect(cursorBackingRect); - } -} - -// setColourMapEntries() changes some of the entries in the colourmap. -// Unfortunately these messages are often sent one at a time, so we delay the -// settings taking effect by 100ms. This is because recalculating the internal -// translation table can be expensive. -void DesktopWindow::setColourMapEntries(int firstColour, int nColours, - rdr::U16* rgbs) -{ - im->setColourMapEntries(firstColour, nColours, rgbs); - if (!setColourMapEntriesTimer.isStarted()) - setColourMapEntriesTimer.start(100); -} - -void DesktopWindow::serverCutText(const char* str, rdr::U32 len) -{ - if (acceptClipboard) { - newServerCutText = true; - delete [] serverCutText_; - serverCutText_ = new char[len+1]; - memcpy(serverCutText_, str, len); - serverCutText_[len] = 0; - } -} - - -// Update the actual window with the changed parts of the framebuffer. - -void DesktopWindow::framebufferUpdateEnd() -{ - updateWindow(); -} - - -// invertRect() flips all the bits in every pixel in the given rectangle - -void DesktopWindow::invertRect(const Rect& r) -{ - int stride; - rdr::U8* p = im->getPixelsRW(r, &stride); - for (int y = 0; y < r.height(); y++) { - for (int x = 0; x < r.width(); x++) { - switch (getPF().bpp) { - case 8: ((rdr::U8* )p)[x+y*stride] ^= 0xff; break; - case 16: ((rdr::U16*)p)[x+y*stride] ^= 0xffff; break; - case 32: ((rdr::U32*)p)[x+y*stride] ^= 0xffffffff; break; - } - } - } - damageRect(r); -} - - -// resize() - resize the window and the image, taking care to remove the local -// cursor first. -void DesktopWindow::resize(int w, int h) -{ - hideLocalCursor(); - TXWindow::resize(w, h); - im->resize(w, h); -} - - -// Copy the areas of the framebuffer that have been changed (damaged) -// to the displayed window. - -void DesktopWindow::updateWindow() -{ - Rect r; - - updateTimer.stop(); - - r = damage.get_bounding_rect(); - damage.clear(); - - im->put(win(), gc, r); - XFlush(dpy); -} - - -bool DesktopWindow::handleTimeout(rfb::Timer* timer) -{ - if (timer == &setColourMapEntriesTimer) { - im->updateColourMap(); - im->put(win(), gc, im->getRect()); - } else if (timer == &pointerEventTimer) { - if (!viewOnly) { - cc->writer()->pointerEvent(lastPointerPos, lastButtonMask); - } - } else if (timer == &updateTimer) { - updateWindow(); - } - return false; -} - - -void DesktopWindow::handlePointerEvent(const Point& pos, int buttonMask) -{ - if (!viewOnly) { - if (pointerEventInterval == 0 || buttonMask != lastButtonMask) { - cc->writer()->pointerEvent(pos, buttonMask); - } else { - if (!pointerEventTimer.isStarted()) - pointerEventTimer.start(pointerEventInterval); - } - lastPointerPos = pos; - lastButtonMask = buttonMask; - } - // - If local cursor rendering is enabled then use it - if (cursorAvailable) { - // - Render the cursor! - if (!pos.equals(cursorPos)) { - hideLocalCursor(); - if (im->getRect().contains(pos)) { - cursorPos = pos; - showLocalCursor(); - } - updateWindow(); - } - } -} - - -// handleXEvent() handles the various X events on the window -void DesktopWindow::handleEvent(TXWindow* w, XEvent* ev) -{ - switch (ev->type) { - case GraphicsExpose: - case Expose: - im->put(win(), gc, Rect(ev->xexpose.x, ev->xexpose.y, - ev->xexpose.x + ev->xexpose.width, - ev->xexpose.y + ev->xexpose.height)); - break; - - case MotionNotify: - while (XCheckTypedWindowEvent(dpy, win(), MotionNotify, ev)); - if (viewport && viewport->bumpScrollEvent(&ev->xmotion)) break; - handlePointerEvent(Point(ev->xmotion.x, ev->xmotion.y), - (ev->xmotion.state & 0x1f00) >> 8); - break; - - case ButtonPress: - handlePointerEvent(Point(ev->xbutton.x, ev->xbutton.y), - (((ev->xbutton.state & 0x1f00) >> 8) | - (1 << (ev->xbutton.button-1)))); - break; - - case ButtonRelease: - handlePointerEvent(Point(ev->xbutton.x, ev->xbutton.y), - (((ev->xbutton.state & 0x1f00) >> 8) & - ~(1 << (ev->xbutton.button-1)))); - break; - - case KeyPress: - if (!viewOnly) { - KeySym ks; - char keyname[256]; - XLookupString(&ev->xkey, keyname, 256, &ks, NULL); - bool fakeShiftPress = false; - - // Turn ISO_Left_Tab into shifted Tab - if (ks == XK_ISO_Left_Tab) { - fakeShiftPress = !(ev->xkey.state & ShiftMask); - ks = XK_Tab; - } - - if (fakeShiftPress) - cc->writer()->keyEvent(XK_Shift_L, true); - - downKeysym[ev->xkey.keycode] = ks; - cc->writer()->keyEvent(ks, true); - - if (fakeShiftPress) - cc->writer()->keyEvent(XK_Shift_L, false); - break; - } - - case KeyRelease: - if (!viewOnly) { - if (downKeysym[ev->xkey.keycode]) { - cc->writer()->keyEvent(downKeysym[ev->xkey.keycode], false); - downKeysym[ev->xkey.keycode] = 0; - } - } - break; - - case EnterNotify: - newSelection = 0; - if (sendPrimary && !selectionOwner(XA_PRIMARY)) { - XConvertSelection(dpy, XA_PRIMARY, xaTIMESTAMP, xaSELECTION_TIME, - win(), ev->xcrossing.time); - } else if (!selectionOwner(xaCLIPBOARD)) { - XConvertSelection(dpy, xaCLIPBOARD, xaTIMESTAMP, xaSELECTION_TIME, - win(), ev->xcrossing.time); - } - break; - - case LeaveNotify: - if (serverCutText_ && newServerCutText) { - newServerCutText = false; - vlog.debug("acquiring primary and clipboard selections"); - XStoreBytes(dpy, serverCutText_, strlen(serverCutText_)); - ownSelection(XA_PRIMARY, ev->xcrossing.time); - ownSelection(xaCLIPBOARD, ev->xcrossing.time); - currentSelectionTime = ev->xcrossing.time; - } - // Release all keys - this should probably done on a FocusOut event, but - // LeaveNotify is near enough... - for (int i = 8; i < 256; i++) { - if (downKeysym[i]) { - cc->writer()->keyEvent(downKeysym[i], false); - downKeysym[i] = 0; - } - } - break; - } -} - -// selectionRequest() is called when we are the selection owner and another X -// client has requested the selection. We simply put the server's cut text -// into the requested property. TXWindow will handle the rest. -bool DesktopWindow::selectionRequest(Window requestor, - Atom selection, Atom property) -{ - XChangeProperty(dpy, requestor, property, XA_STRING, 8, - PropModeReplace, (unsigned char*)serverCutText_, - strlen(serverCutText_)); - return true; -} - - -// selectionNotify() is called when we have requested any information about a -// selection from the selection owner. Note that there are two selections, -// PRIMARY and CLIPBOARD, plus the cut buffer, and we try to use whichever is -// the most recent of the three. -// -// There are two different "targets" for which selectionNotify() is called, the -// timestamp and the actual string value of the selection. We always use the -// timestamp to decide which selection to retrieve. -// -// The first time selectionNotify() is called is when we are trying to find the -// timestamp of the selections at initialisation. This should be called first -// for PRIMARY, then we call XConvertSelection() for CLIPBOARD. The second -// time should be the result for CLIPBOARD. At this stage we've got the -// "currentSelectionTime" so we return. -// -// Subsequently selectionNotify() is called whenever the mouse enters the -// viewer window. Again, the first time it is called should be the timestamp -// for PRIMARY, and we then request the timestamp for CLIPBOARD. When -// selectionNotify() is called again with the timestamp for CLIPBOARD, we now -// know if either selection is "new" i.e. later than the previous value of -// currentSelectionTime. The last thing to check is the timestamp on the cut -// buffer. If the cut buffer is newest we send that to the server, otherwise -// if one of the selections was newer, we request the string value of that -// selection. -// -// Finally, if we get selectionNotify() called for the string value of a -// selection, we sent that to the server. -// -// As a final minor complication, when one of the selections is actually owned -// by us, we don't request the details for it. - -// TIME_LATER treats 0 as meaning a long time ago, so a==0 means a cannot be -// later than b. This is different to the usual meaning of CurrentTime. -#define TIME_LATER(a, b) ((a) != 0 && ((b) == 0 || (long)((a) - (b)) > 0)) - - -void DesktopWindow::selectionNotify(XSelectionEvent* ev, Atom type, int format, - int nitems, void* data) -{ - if (ev->requestor != win()) - return; - - if (ev->target == xaTIMESTAMP) { - if (ev->property == xaSELECTION_TIME) { - if (data && format == 32 && nitems == 1) { - Time t = *(rdr::U32 *)data; - vlog.debug("selection (%d) time is %d, later %d", - ev->selection, t, TIME_LATER(t, currentSelectionTime)); - if (TIME_LATER(t, currentSelectionTime)) { - currentSelectionTime = t; - newSelection = ev->selection; - } - } - } else { - vlog.debug("no selection (%d)",ev->selection); - } - - if (ev->selection == XA_PRIMARY) { - if (!selectionOwner(xaCLIPBOARD)) { - XConvertSelection(dpy, xaCLIPBOARD, xaTIMESTAMP, xaSELECTION_TIME, - win(), ev->time); - return; - } - } else if (ev->selection != xaCLIPBOARD) { - vlog.error("unknown selection %d",ev->selection); - return; - } - - if (gettingInitialSelectionTime) { - gettingInitialSelectionTime = false; - return; - } - - if (!sendClipboard) return; - if (sendPrimary) { - vlog.debug("cut buffer time is %d, later %d", cutBufferTime, - TIME_LATER(cutBufferTime, currentSelectionTime)); - if (TIME_LATER(cutBufferTime, currentSelectionTime)) { - currentSelectionTime = cutBufferTime; - int len; - char* str = XFetchBytes(dpy, &len); - if (str) { - if (!viewOnly) { - vlog.debug("sending cut buffer to server"); - cc->writer()->clientCutText(str, len); - } - XFree(str); - return; - } - } - } - if (newSelection) { - XConvertSelection(dpy, newSelection, XA_STRING, xaSELECTION_STRING, - win(), CurrentTime); - } - - } else if (ev->target == XA_STRING) { - if (!sendClipboard) return; - if (ev->property == xaSELECTION_STRING) { - if (data && format == 8) { - if (!viewOnly) { - vlog.debug("sending %s selection to server", - ev->selection == XA_PRIMARY ? "primary" : - ev->selection == xaCLIPBOARD ? "clipboard" : "unknown" ); - cc->writer()->clientCutText((char*)data, nitems); - } - } - } - } -} diff --git a/unix/vncviewer/DesktopWindow.h b/unix/vncviewer/DesktopWindow.h deleted file mode 100644 index eb8d59dc..00000000 --- a/unix/vncviewer/DesktopWindow.h +++ /dev/null @@ -1,142 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ -// -// DesktopWindow is a TXWindow representing a VNC desktop. -// - -#ifndef __DESKTOPWINDOW_H__ -#define __DESKTOPWINDOW_H__ - -#include -#include -#include -#include -#include "TXWindow.h" -#include "TXViewport.h" -#include "TXImage.h" -#include "parameters.h" - -class CConn; - -class DesktopWindow : public TXWindow, public TXEventHandler, - public rfb::Timer::Callback { -public: - - DesktopWindow(Display* dpy, int w, int h, - const rfb::PixelFormat& serverPF, CConn* cc_, - TXWindow* parent=0); - ~DesktopWindow(); - - void setViewport(TXViewport* viewport); - - // getPF() and setPF() get and set the TXImage's pixel format - const rfb::PixelFormat& getPF() { return im->getPF(); } - void setPF(const rfb::PixelFormat& pf) { im->setPF(pf); } - - // setCursor() sets the shape of the local cursor - void setCursor(int width, int height, const rfb::Point& hotspot, - void* data, void* mask); - - // resetLocalCursor() stops the rendering of the local cursor - void resetLocalCursor(); - - // setNoCursor() sets what to display when no cursor is defined - if dot or - // nothing. - inline void setNoCursor() { - XDefineCursor(dpy, win(), dotWhenNoCursor ? dotCursor : noCursor); - } - - // Methods forwarded from CConn - void setColourMapEntries(int firstColour, int nColours, rdr::U16* rgbs); - void serverCutText(const char* str, rdr::U32 len); - void framebufferUpdateEnd(); - - void fillRect(const rfb::Rect& r, rfb::Pixel pix) { - if (r.overlaps(cursorBackingRect)) hideLocalCursor(); - im->fillRect(r, pix); - damageRect(r); - showLocalCursor(); - } - void imageRect(const rfb::Rect& r, void* pixels) { - if (r.overlaps(cursorBackingRect)) hideLocalCursor(); - im->imageRect(r, pixels); - damageRect(r); - showLocalCursor(); - } - void copyRect(const rfb::Rect& r, int srcX, int srcY) { - if (r.overlaps(cursorBackingRect) || - cursorBackingRect.overlaps(rfb::Rect(srcX, srcY, - srcX+r.width(), srcY+r.height()))) - hideLocalCursor(); - im->copyRect(r, rfb::Point(r.tl.x-srcX, r.tl.y-srcY)); - damageRect(r); - showLocalCursor(); - } - void invertRect(const rfb::Rect& r); - - // TXWindow methods - virtual void resize(int w, int h); - virtual bool selectionRequest(Window requestor, - Atom selection, Atom property); - virtual void selectionNotify(XSelectionEvent* ev, Atom type, int format, - int nitems, void* data); - virtual void handleEvent(TXWindow* w, XEvent* ev); - -private: - - void createXCursors(); - void hideLocalCursor(); - void showLocalCursor(); - void damageRect(const rfb::Rect& r) { - damage.assign_union(rfb::Region(r)); - if (!updateTimer.isStarted()) - updateTimer.start(100); - }; - void updateWindow(); - bool handleTimeout(rfb::Timer* timer); - void handlePointerEvent(const rfb::Point& pos, int buttonMask); - - CConn* cc; - TXImage* im; - GC gc; - rfb::Region damage; - rfb::Timer updateTimer; - ::Cursor dotCursor, noCursor, localXCursor; - - rfb::Cursor cursor; - bool cursorVisible; // Is cursor currently rendered? - bool cursorAvailable; // Is cursor available for rendering? - rfb::Point cursorPos; - rfb::ManagedPixelBuffer cursorBacking; - rfb::Rect cursorBackingRect; - - Time currentSelectionTime; - Atom newSelection; - bool gettingInitialSelectionTime; - bool newServerCutText; - char* serverCutText_; - - rfb::Timer setColourMapEntriesTimer; - TXViewport* viewport; - rfb::Timer pointerEventTimer; - rfb::Point lastPointerPos; - int lastButtonMask; - rdr::U32 downKeysym[256]; -}; - -#endif diff --git a/unix/vncviewer/InfoDialog.h b/unix/vncviewer/InfoDialog.h deleted file mode 100644 index a95f57be..00000000 --- a/unix/vncviewer/InfoDialog.h +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ -// -// InfoDialog.h -// - -#ifndef __INFODIALOG_H__ -#define __INFODIALOG_H__ - -#include "TXDialog.h" -#include "TXLabel.h" -#include "TXButton.h" - -extern char buildtime[]; - -class InfoDialog : public TXDialog, public TXButtonCallback { -public: - InfoDialog(Display* dpy) - : TXDialog(dpy, 1, 1, _("VNC connection info")), - infoLabel(dpy, "", this, 1, 1, TXLabel::left), - okButton(dpy, "OK", this, this, 60) - { - infoLabel.xPad = 8; - infoLabel.move(0, yPad*4); - setBorderWidth(1); - } - - void setText(char* infoText) { - infoLabel.setText(infoText); - resize(infoLabel.width(), - infoLabel.height() + okButton.height() + yPad*12); - - okButton.move((width() - okButton.width()) / 2, - height() - yPad*4 - okButton.height()); - } - - virtual void buttonActivate(TXButton* b) { - unmap(); - } - - TXLabel infoLabel; - TXButton okButton; -}; - -#endif diff --git a/unix/vncviewer/OptionsDialog.h b/unix/vncviewer/OptionsDialog.h deleted file mode 100644 index a3303fe9..00000000 --- a/unix/vncviewer/OptionsDialog.h +++ /dev/null @@ -1,314 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ -// -// OptionsDialog.h -// - -#ifndef __OPTIONSDIALOG_H__ -#define __OPTIONSDIALOG_H__ - -#include "TXDialog.h" -#include "TXLabel.h" -#include "TXEntry.h" -#include "TXButton.h" -#include "TXCheckbox.h" -#include "parameters.h" - -#define SECOND_COL_XPAD 350 - -class OptionsDialogCallback { -public: - virtual void setOptions() = 0; - virtual void getOptions() = 0; -}; - -class OptionsDialog : public TXDialog, public TXButtonCallback, - public TXCheckboxCallback, public TXEntryCallback { -public: - OptionsDialog(Display* dpy, OptionsDialogCallback* cb_) - : TXDialog(dpy, 450, 450, _("VNC Viewer: Connection Options")), cb(cb_), - - /* Encoding and color level */ - formatAndEnc(dpy, _("Encoding and Color Level:"), this), - inputs(dpy, _("Inputs:"), this), - misc(dpy, _("Misc:"), this), - autoSelect(dpy, _("Auto select"), this, false, this), - fullColour(dpy, _("Full (all available colors)"), this, true, this), - mediumColour(dpy, _("Medium (256 colors)"), this, true, this), - lowColour(dpy, _("Low (64 colors)"), this, true, this), - veryLowColour(dpy, _("Very low (8 colors)"), this, true, this), - tight(dpy, "Tight", this, true, this), - zrle(dpy, "ZRLE", this, true, this), - hextile(dpy, "Hextile", this, true, this), - raw(dpy, "Raw", this, true, this), - - /* Compression */ - customCompressLevel(dpy, _("Custom compression level:"), this, false, this), - compressLevel(dpy, this, this, false, 30), - compressLevelLabel(dpy, _("level (1=fast, 9=best)"), this), - noJpeg(dpy, _("Allow JPEG compression:"), this, false, this), - qualityLevel(dpy, this, this, false, 30), - qualityLevelLabel(dpy, _("quality (1=poor, 9=best)"), this), - - /* Inputs */ - viewOnly(dpy, _("View only (ignore mouse & keyboard)"), this, false, this), - acceptClipboard(dpy, _("Accept clipboard from server"), this, false, this), - sendClipboard(dpy, _("Send clipboard to server"), this, false, this), - sendPrimary(dpy, _("Send primary selection & cut buffer as clipboard"), - this, false, this), - - /* Misc */ - shared(dpy, _("Shared (don't disconnect other viewers)"), this, false,this), - fullScreen(dpy, _("Full-screen mode"), this, false, this), - useLocalCursor(dpy, _("Render cursor locally"), this, false, this), - dotWhenNoCursor(dpy, _("Show dot when no cursor"), this, false, this), - okButton(dpy, _("OK"), this, this, 60), - cancelButton(dpy, _("Cancel"), this, this, 60) - -#ifdef HAVE_GNUTLS - , - /* Security */ - security(dpy, _("Security:"), this), - secVeNCrypt(dpy, _("Extended encryption and authentication methods (VeNCrypt)"), - this, false, this), - - /* Encryption */ - encryption(dpy, _("Session encryption:"), this), - encNone(dpy, _("None"), this, false, this), - encTLS(dpy, _("TLS with anonymous certificates"), this, false, this), - encX509(dpy, _("TLS with X509 certificates"), this, false, this), - cacert(dpy, _("Path to X509 CA certificate"), this), - ca(dpy, this, this, false, 350), - crlcert(dpy, _("Path to X509 CRL file"), this), - crl(dpy, this, this, false, 350), - - /* Authentication */ - authentication(dpy, _("Authentication:"), this), - secNone(dpy, _("None"), this, false, this), - secVnc(dpy, _("Standard VNC (insecure without encryption)"), - this, false, this), - secPlain(dpy, _("Username and password (insecure without encryption)"), - this, false, this) -#endif - { - /* Render the first collumn */ - int y = yPad; - formatAndEnc.move(xPad, y); - y += formatAndEnc.height(); - autoSelect.move(xPad, y); - int x2 = xPad + autoSelect.width() + xPad*5; - y += autoSelect.height(); - tight.move(xPad, y); - fullColour.move(x2, y); - y += tight.height(); - zrle.move(xPad, y); - mediumColour.move(x2, y); - y += zrle.height(); - hextile.move(xPad, y); - lowColour.move(x2, y); - y += hextile.height(); - raw.move(xPad, y); - veryLowColour.move(x2, y); - y += raw.height() + yPad*2; - - customCompressLevel.move(xPad, y); - y += customCompressLevel.height(); - compressLevel.move(xPad*10, y); - compressLevelLabel.move(xPad*20, y); - y += compressLevel.height(); - - noJpeg.move(xPad, y); - y += noJpeg.height(); - qualityLevel.move(xPad*10, y); - qualityLevelLabel.move(xPad*20, y); - y += qualityLevel.height(); - - y += yPad*4; - inputs.move(xPad, y); - y += inputs.height(); - viewOnly.move(xPad, y); - y += viewOnly.height(); - acceptClipboard.move(xPad, y); - y += acceptClipboard.height(); - sendClipboard.move(xPad, y); - y += sendClipboard.height(); - sendPrimary.move(xPad, y); - y += sendPrimary.height(); - - y += yPad*4; - misc.move(xPad, y); - y += misc.height(); - shared.move(xPad, y); - y += shared.height(); - fullScreen.move(xPad, y); - y += fullScreen.height(); - useLocalCursor.move(xPad, y); - y += useLocalCursor.height(); - dotWhenNoCursor.move(xPad, y); - y += dotWhenNoCursor.height(); - -#ifdef HAVE_GNUTLS - /* Render the second collumn */ - y = yPad; - xPad += SECOND_COL_XPAD; - resize(750, height()); - - security.move(xPad, y); - y += security.height(); - secVeNCrypt.move(xPad, y); - y += secVeNCrypt.height(); - - encryption.move(xPad, y); - y += encryption.height(); - encNone.move(xPad, y); - y += encNone.height(); - encTLS.move(xPad, y); - y += encTLS.height(); - encX509.move(xPad, y); - y += encX509.height(); - cacert.move(xPad, y); - y += cacert.height(); - ca.move(xPad, y); - y += ca.height(); - crlcert.move(xPad, y); - y += crlcert.height(); - crl.move(xPad, y); - y += crl.height(); - - authentication.move(xPad, y); - y += authentication.height(); - secNone.move(xPad, y); - y += secNone.height(); - secVnc.move(xPad, y); - y += secVnc.height(); - secPlain.move(xPad, y); - y += secPlain.height(); - - xPad -= SECOND_COL_XPAD; -#endif - - /* Render "OK" and "Cancel" buttons */ - okButton.move(width() - xPad*12 - cancelButton.width() - okButton.width(), - height() - yPad*4 - okButton.height()); - cancelButton.move(width() - xPad*6 - cancelButton.width(), - height() - yPad*4 - cancelButton.height()); - - setBorderWidth(1); - } - - virtual void initDialog() { - if (cb) cb->setOptions(); - tight.disabled(autoSelect.checked()); - zrle.disabled(autoSelect.checked()); - hextile.disabled(autoSelect.checked()); - raw.disabled(autoSelect.checked()); - fullColour.disabled(autoSelect.checked()); - mediumColour.disabled(autoSelect.checked()); - lowColour.disabled(autoSelect.checked()); - veryLowColour.disabled(autoSelect.checked()); - sendPrimary.disabled(!sendClipboard.checked()); - dotWhenNoCursor.disabled(!useLocalCursor.checked()); - compressLevel.disabled(!customCompressLevel.checked()); - qualityLevel.disabled(autoSelect.checked() || !noJpeg.checked()); - } - - virtual void takeFocus(Time time) { - //XSetInputFocus(dpy, entry.win, RevertToParent, time); - } - - virtual void buttonActivate(TXButton* b) { - if (b == &okButton) { - if (cb) cb->getOptions(); - unmap(); - } else if (b == &cancelButton) { - unmap(); - } - } - - virtual void checkboxSelect(TXCheckbox* checkbox) { - if (checkbox == &autoSelect) { - tight.disabled(autoSelect.checked()); - zrle.disabled(autoSelect.checked()); - hextile.disabled(autoSelect.checked()); - raw.disabled(autoSelect.checked()); - fullColour.disabled(autoSelect.checked()); - mediumColour.disabled(autoSelect.checked()); - lowColour.disabled(autoSelect.checked()); - veryLowColour.disabled(autoSelect.checked()); - qualityLevel.disabled(autoSelect.checked() || !noJpeg.checked()); - } else if (checkbox == &fullColour || checkbox == &mediumColour || - checkbox == &lowColour || checkbox == &veryLowColour) { - fullColour.checked(checkbox == &fullColour); - mediumColour.checked(checkbox == &mediumColour); - lowColour.checked(checkbox == &lowColour); - veryLowColour.checked(checkbox == &veryLowColour); - } else if (checkbox == &tight || checkbox == &zrle || checkbox == &hextile || checkbox == &raw) { - tight.checked(checkbox == &tight); - zrle.checked(checkbox == &zrle); - hextile.checked(checkbox == &hextile); - raw.checked(checkbox == &raw); - } else if (checkbox == &sendClipboard) { - sendPrimary.disabled(!sendClipboard.checked()); - } else if (checkbox == &useLocalCursor) { - dotWhenNoCursor.disabled(!useLocalCursor.checked()); - } else if (checkbox == &customCompressLevel) { - compressLevel.disabled(!customCompressLevel.checked()); - } else if (checkbox == &noJpeg) { - qualityLevel.disabled(autoSelect.checked() || !noJpeg.checked()); -#ifdef HAVE_GNUTLS - } else if (checkbox == &secVeNCrypt) { - encTLS.checked(false); - encTLS.disabled(!secVeNCrypt.checked()); - encX509.checked(false); - encX509.disabled(!secVeNCrypt.checked()); - secPlain.checked(false); - secPlain.disabled(!secVeNCrypt.checked()); -#endif - } - } - - virtual void entryCallback(TXEntry* e, Detail detail, Time time) { - } - - OptionsDialogCallback* cb; - TXLabel formatAndEnc, inputs, misc; - TXCheckbox autoSelect; - TXCheckbox fullColour, mediumColour, lowColour, veryLowColour; - TXCheckbox tight, zrle, hextile, raw; - - TXCheckbox customCompressLevel; TXEntry compressLevel; TXLabel compressLevelLabel; - TXCheckbox noJpeg; TXEntry qualityLevel; TXLabel qualityLevelLabel; - - TXCheckbox viewOnly, acceptClipboard, sendClipboard, sendPrimary; - TXCheckbox shared, fullScreen, useLocalCursor, dotWhenNoCursor; - TXButton okButton, cancelButton; - -#ifdef HAVE_GNUTLS - TXLabel security; - TXCheckbox secVeNCrypt; - - TXLabel encryption; - TXCheckbox encNone, encTLS, encX509; - TXLabel cacert; TXEntry ca; TXLabel crlcert; TXEntry crl; - - TXLabel authentication; - TXCheckbox secNone, secVnc, secPlain; -#endif -}; - -#endif diff --git a/unix/vncviewer/PasswdDialog.h b/unix/vncviewer/PasswdDialog.h deleted file mode 100644 index 7b62b8e1..00000000 --- a/unix/vncviewer/PasswdDialog.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ -// -// PasswdDialog.h -// - -#ifndef __PASSWDDIALOG_H__ -#define __PASSWDDIALOG_H__ - -#include "TXDialog.h" -#include "TXLabel.h" -#include "TXEntry.h" - -class PasswdDialog : public TXDialog, public TXEntryCallback { -public: - PasswdDialog(Display* dpy, const char* title, bool userDisabled) - : TXDialog(dpy, 320, 100, title, true), - userLabel(dpy, _("Username:"), this, 120), - userEntry(dpy, this, this, false, 180), - passwdLabel(dpy, _("Password:"), this, 120), - passwdEntry(dpy, this, this, true, 180) - { - userLabel.move(0, 20); - userEntry.move(userLabel.width(), 18); - userEntry.disabled(userDisabled); - passwdLabel.move(0, 60); - passwdEntry.move(passwdLabel.width(), 58); - } - - void takeFocus(Time time) { - if (!userEntry.disabled()) - XSetInputFocus(dpy, userEntry.win(), RevertToParent, time); - else - XSetInputFocus(dpy, passwdEntry.win(), RevertToParent, time); - } - - void entryCallback(TXEntry* e, Detail detail, Time time) { - if (e == &userEntry) { - if (detail == ENTER || detail == NEXT_FOCUS || detail == PREV_FOCUS) - XSetInputFocus(dpy, passwdEntry.win(), RevertToParent, time); - } else if (e == &passwdEntry) { - if (detail == ENTER) { - ok = true; - done = true; - } else if (detail == NEXT_FOCUS || detail == PREV_FOCUS) { - XSetInputFocus(dpy, userEntry.win(), RevertToParent, time); - } - } - } - - TXLabel userLabel; - TXEntry userEntry; - TXLabel passwdLabel; - TXEntry passwdEntry; -}; - -#endif diff --git a/unix/vncviewer/ServerDialog.h b/unix/vncviewer/ServerDialog.h deleted file mode 100644 index f6980dc7..00000000 --- a/unix/vncviewer/ServerDialog.h +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ -// -// ServerDialog.h -// - -#ifndef __SERVERDIALOG_H__ -#define __SERVERDIALOG_H__ - -#include "TXDialog.h" -#include "TXLabel.h" -#include "TXEntry.h" -#include "TXButton.h" -#include "OptionsDialog.h" -#include "AboutDialog.h" - -class ServerDialog : public TXDialog, public TXEntryCallback, - public TXButtonCallback { -public: - ServerDialog(Display* dpy, OptionsDialog* options_, AboutDialog* about_) - : TXDialog(dpy, 355, 120, _("VNC Viewer: Connection Details"), true), - label(dpy, _("VNC server:"), this, 100), - entry(dpy, this, this, false, 180), - aboutButton(dpy, _("About..."), this, this, 70), - optionsButton(dpy, _("Options..."), this, this, 70), - okButton(dpy, _("OK"), this, this, 70), - cancelButton(dpy, _("Cancel"), this, this, 70), - options(options_), about(about_) - { - label.move(0, 30); - entry.move(label.width(), 28); - int x = width(); - int y = height() - yPad*4 - cancelButton.height(); - x -= cancelButton.width() + xPad*4; - cancelButton.move(x, y); - x -= okButton.width() + xPad*4; - okButton.move(x, y); - x -= optionsButton.width() + xPad*4; - optionsButton.move(x, y); - x -= aboutButton.width() + xPad*4; - aboutButton.move(x, y); - } - - virtual void takeFocus(Time time) { - XSetInputFocus(dpy, entry.win(), RevertToParent, time); - } - - virtual void entryCallback(TXEntry* e, Detail detail, Time time) { - if (detail == ENTER) { - ok = true; - done = true; - } - } - - virtual void buttonActivate(TXButton* b) { - if (b == &okButton) { - ok = true; - done = true; - } else if (b == &cancelButton) { - ok = false; - done = true; - } else if (b == &optionsButton) { - options->show(); - } else if (b == &aboutButton) { - about->show(); - } - } - - TXLabel label; - TXEntry entry; - TXButton aboutButton, optionsButton, okButton, cancelButton; - OptionsDialog* options; - AboutDialog* about; -}; - -#endif diff --git a/unix/vncviewer/buildtime.c b/unix/vncviewer/buildtime.c deleted file mode 100644 index 3f4c3690..00000000 --- a/unix/vncviewer/buildtime.c +++ /dev/null @@ -1,18 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ -char buildtime[] = __DATE__ " " __TIME__; diff --git a/unix/vncviewer/gettext.h b/unix/vncviewer/gettext.h deleted file mode 100644 index 209921e6..00000000 --- a/unix/vncviewer/gettext.h +++ /dev/null @@ -1,271 +0,0 @@ -/* Convenience header for conditional use of GNU . - Copyright (C) 1995-1998, 2000-2002, 2004-2006 Free Software Foundation, Inc. - - This program 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, 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 - Library 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - USA. */ - -#ifndef _LIBGETTEXT_H -#define _LIBGETTEXT_H 1 - -/* NLS can be disabled through the configure --disable-nls option. */ -#if ENABLE_NLS - -/* Get declarations of GNU message catalog functions. */ -# include - -/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by - the gettext() and ngettext() macros. This is an alternative to calling - textdomain(), and is useful for libraries. */ -# ifdef DEFAULT_TEXT_DOMAIN -# undef gettext -# define gettext(Msgid) \ - dgettext (DEFAULT_TEXT_DOMAIN, Msgid) -# undef ngettext -# define ngettext(Msgid1, Msgid2, N) \ - dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N) -# endif - -#else - -/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which - chokes if dcgettext is defined as a macro. So include it now, to make - later inclusions of a NOP. We don't include - as well because people using "gettext.h" will not include , - and also including would fail on SunOS 4, whereas - is OK. */ -#if defined(__sun) -# include -#endif - -/* Many header files from the libstdc++ coming with g++ 3.3 or newer include - , which chokes if dcgettext is defined as a macro. So include - it now, to make later inclusions of a NOP. */ -#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3) -# include -# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H -# include -# endif -#endif - -/* Disabled NLS. - The casts to 'const char *' serve the purpose of producing warnings - for invalid uses of the value returned from these functions. - On pre-ANSI systems without 'const', the config.h file is supposed to - contain "#define const". */ -# define gettext(Msgid) ((const char *) (Msgid)) -# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid)) -# define dcgettext(Domainname, Msgid, Category) \ - ((void) (Category), dgettext (Domainname, Msgid)) -# define ngettext(Msgid1, Msgid2, N) \ - ((N) == 1 \ - ? ((void) (Msgid2), (const char *) (Msgid1)) \ - : ((void) (Msgid1), (const char *) (Msgid2))) -# define dngettext(Domainname, Msgid1, Msgid2, N) \ - ((void) (Domainname), ngettext (Msgid1, Msgid2, N)) -# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ - ((void) (Category), dngettext(Domainname, Msgid1, Msgid2, N)) -# define textdomain(Domainname) ((const char *) (Domainname)) -# define bindtextdomain(Domainname, Dirname) \ - ((void) (Domainname), (const char *) (Dirname)) -# define bind_textdomain_codeset(Domainname, Codeset) \ - ((void) (Domainname), (const char *) (Codeset)) - -#endif - -/* A pseudo function call that serves as a marker for the automated - extraction of messages, but does not call gettext(). The run-time - translation is done at a different place in the code. - The argument, String, should be a literal string. Concatenated strings - and other string expressions won't work. - The macro's expansion is not parenthesized, so that it is suitable as - initializer for static 'char[]' or 'const char[]' variables. */ -#define gettext_noop(String) String - -/* The separator between msgctxt and msgid in a .mo file. */ -#define GETTEXT_CONTEXT_GLUE "\004" - -/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a - MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be - short and rarely need to change. - The letter 'p' stands for 'particular' or 'special'. */ -#ifdef DEFAULT_TEXT_DOMAIN -# define pgettext(Msgctxt, Msgid) \ - pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) -#else -# define pgettext(Msgctxt, Msgid) \ - pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) -#endif -#define dpgettext(Domainname, Msgctxt, Msgid) \ - pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) -#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \ - pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category) -#ifdef DEFAULT_TEXT_DOMAIN -# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ - npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) -#else -# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ - npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) -#endif -#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ - npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) -#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \ - npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category) - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static const char * -pgettext_aux (const char *domain, - const char *msg_ctxt_id, const char *msgid, - int category) -{ - const char *translation = dcgettext (domain, msg_ctxt_id, category); - if (translation == msg_ctxt_id) - return msgid; - else - return translation; -} - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static const char * -npgettext_aux (const char *domain, - const char *msg_ctxt_id, const char *msgid, - const char *msgid_plural, unsigned long int n, - int category) -{ - const char *translation = - dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); - if (translation == msg_ctxt_id || translation == msgid_plural) - return (n == 1 ? msgid : msgid_plural); - else - return translation; -} - -/* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID - can be arbitrary expressions. But for string literals these macros are - less efficient than those above. */ - -#include - -#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \ - (((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \ - /* || __STDC_VERSION__ >= 199901L */ ) - -#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS -#include -#endif - -#define pgettext_expr(Msgctxt, Msgid) \ - dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES) -#define dpgettext_expr(Domainname, Msgctxt, Msgid) \ - dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES) - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static const char * -dcpgettext_expr (const char *domain, - const char *msgctxt, const char *msgid, - int category) -{ - size_t msgctxt_len = strlen (msgctxt) + 1; - size_t msgid_len = strlen (msgid) + 1; - const char *translation; -#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - char msg_ctxt_id[msgctxt_len + msgid_len]; -#else - char buf[1024]; - char *msg_ctxt_id = - (msgctxt_len + msgid_len <= sizeof (buf) - ? buf - : (char *) malloc (msgctxt_len + msgid_len)); - if (msg_ctxt_id != NULL) -#endif - { - memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); - msg_ctxt_id[msgctxt_len - 1] = '\004'; - memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); - translation = dcgettext (domain, msg_ctxt_id, category); -#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - if (msg_ctxt_id != buf) - free (msg_ctxt_id); -#endif - if (translation != msg_ctxt_id) - return translation; - } - return msgid; -} - -#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \ - dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) -#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ - dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static const char * -dcnpgettext_expr (const char *domain, - const char *msgctxt, const char *msgid, - const char *msgid_plural, unsigned long int n, - int category) -{ - size_t msgctxt_len = strlen (msgctxt) + 1; - size_t msgid_len = strlen (msgid) + 1; - const char *translation; -#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - char msg_ctxt_id[msgctxt_len + msgid_len]; -#else - char buf[1024]; - char *msg_ctxt_id = - (msgctxt_len + msgid_len <= sizeof (buf) - ? buf - : (char *) malloc (msgctxt_len + msgid_len)); - if (msg_ctxt_id != NULL) -#endif - { - memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); - msg_ctxt_id[msgctxt_len - 1] = '\004'; - memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); - translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); -#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS - if (msg_ctxt_id != buf) - free (msg_ctxt_id); -#endif - if (!(translation == msg_ctxt_id || translation == msgid_plural)) - return translation; - } - return (n == 1 ? msgid : msgid_plural); -} - -#endif /* _LIBGETTEXT_H */ diff --git a/unix/vncviewer/parameters.h b/unix/vncviewer/parameters.h deleted file mode 100644 index 7e4960af..00000000 --- a/unix/vncviewer/parameters.h +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ -#ifndef __PARAMETERS_H__ -#define __PARAMETERS_H__ - -#include - -extern rfb::IntParameter pointerEventInterval; -extern rfb::IntParameter wmDecorationWidth; -extern rfb::IntParameter wmDecorationHeight; -extern rfb::StringParameter passwordFile; -extern rfb::BoolParameter useLocalCursor; -extern rfb::BoolParameter dotWhenNoCursor; -extern rfb::BoolParameter autoSelect; -extern rfb::BoolParameter fullColour; -extern rfb::IntParameter lowColourLevel; -extern rfb::StringParameter preferredEncoding; -extern rfb::BoolParameter viewOnly; -extern rfb::BoolParameter shared; -extern rfb::BoolParameter acceptClipboard; -extern rfb::BoolParameter sendClipboard; -extern rfb::BoolParameter sendPrimary; -extern rfb::StringParameter desktopSize; -extern rfb::BoolParameter fullScreen; -extern rfb::StringParameter geometry; -extern rfb::BoolParameter customCompressLevel; -extern rfb::IntParameter compressLevel; -extern rfb::BoolParameter noJpeg; -extern rfb::IntParameter qualityLevel; - -extern char aboutText[]; -extern char* programName; - -#endif diff --git a/unix/vncviewer/vncviewer.cxx b/unix/vncviewer/vncviewer.cxx deleted file mode 100644 index e418267d..00000000 --- a/unix/vncviewer/vncviewer.cxx +++ /dev/null @@ -1,423 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ -// -// All-new VNC viewer for X. -// - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "TXWindow.h" -#include "TXMsgBox.h" -#include "CConn.h" - -#include "gettext.h" -#define _(String) gettext (String) -#define gettext_noop(String) String -#define N_(String) gettext_noop (String) - -rfb::LogWriter vlog("main"); - -using namespace network; -using namespace rfb; -using namespace std; - -IntParameter pointerEventInterval("PointerEventInterval", - "Time in milliseconds to rate-limit" - " successive pointer events", 0); -IntParameter wmDecorationWidth("WMDecorationWidth", "Width of window manager " - "decoration around a window", 6); -IntParameter wmDecorationHeight("WMDecorationHeight", "Height of window " - "manager decoration around a window", 24); -StringParameter passwordFile("PasswordFile", - "Password file for VNC authentication", ""); -AliasParameter passwd("passwd", "Alias for PasswordFile", &passwordFile); - -BoolParameter useLocalCursor("UseLocalCursor", - "Render the mouse cursor locally", true); -BoolParameter dotWhenNoCursor("DotWhenNoCursor", - "Show the dot cursor when the server sends an " - "invisible cursor", true); -BoolParameter autoSelect("AutoSelect", - "Auto select pixel format and encoding. " - "Default if PreferredEncoding and FullColor are not specified.", - true); -BoolParameter fullColour("FullColor", - "Use full color", true); -AliasParameter fullColourAlias("FullColour", "Alias for FullColor", &fullColour); -IntParameter lowColourLevel("LowColorLevel", - "Color level to use on slow connections. " - "0 = Very Low (8 colors), 1 = Low (64 colors), " - "2 = Medium (256 colors)", 2); -AliasParameter lowColourLevelAlias("LowColourLevel", "Alias for LowColorLevel", &lowColourLevel); -StringParameter preferredEncoding("PreferredEncoding", - "Preferred encoding to use (Tight, ZRLE, Hextile or" - " Raw)", "Tight"); -BoolParameter fullScreen("FullScreen", "Full screen mode", false); -BoolParameter viewOnly("ViewOnly", - "Don't send any mouse or keyboard events to the server", - false); -BoolParameter shared("Shared", - "Don't disconnect other viewers upon connection - " - "share the desktop instead", - false); -BoolParameter acceptClipboard("AcceptClipboard", - "Accept clipboard changes from the server", - true); -BoolParameter sendClipboard("SendClipboard", - "Send clipboard changes to the server", true); -BoolParameter sendPrimary("SendPrimary", - "Send the primary selection and cut buffer to the " - "server as well as the clipboard selection", - true); - -StringParameter desktopSize("DesktopSize", - "Reconfigure desktop size on the server on " - "connect (if possible)", ""); - -BoolParameter listenMode("listen", "Listen for connections from VNC servers", - false); -StringParameter geometry("geometry", "X geometry specification", ""); -StringParameter displayname("display", "The X display", ""); - -StringParameter via("via", "Gateway to tunnel via", ""); - -BoolParameter customCompressLevel("CustomCompressLevel", - "Use custom compression level. " - "Default if CompressLevel is specified.", false); - -IntParameter compressLevel("CompressLevel", - "Use specified compression level" - "0 = Low, 9 = High", - 6); - -BoolParameter noJpeg("NoJPEG", - "Disable lossy JPEG compression in Tight encoding.", - false); - -IntParameter qualityLevel("QualityLevel", - "JPEG quality level. " - "0 = Low, 9 = High", - 8); - -char aboutText[1024]; -char* programName; -extern char buildtime[]; - -static void CleanupSignalHandler(int sig) -{ - // CleanupSignalHandler allows C++ object cleanup to happen because it calls - // exit() rather than the default which is to abort. - vlog.info("CleanupSignalHandler called"); - exit(1); -} - -// XLoginIconifier is a class which iconifies the XDM login window when it has -// grabbed the keyboard, thus releasing the grab, allowing the viewer to use -// the keyboard. It remaps the xlogin window on exit. -class XLoginIconifier { -public: - Display* dpy; - Window xlogin; - XLoginIconifier() : dpy(0), xlogin(0) {} - void iconify(Display* dpy_) { - dpy = dpy_; - if (XGrabKeyboard(dpy, DefaultRootWindow(dpy), False, GrabModeSync, - GrabModeSync, CurrentTime) == GrabSuccess) { - XUngrabKeyboard(dpy, CurrentTime); - } else { - xlogin = TXWindow::windowWithName(dpy, DefaultRootWindow(dpy), "xlogin"); - if (xlogin) { - XIconifyWindow(dpy, xlogin, DefaultScreen(dpy)); - XSync(dpy, False); - } - } - } - ~XLoginIconifier() { - if (xlogin) { - fprintf(stderr,"~XLoginIconifier remapping xlogin\n"); - XMapWindow(dpy, xlogin); - XFlush(dpy); - sleep(1); - } - } -}; - -static XLoginIconifier xloginIconifier; - -static void usage() -{ - fprintf(stderr, - "\nusage: %s [parameters] [host:displayNum] [parameters]\n" - " %s [parameters] -listen [port] [parameters]\n", - programName,programName); - fprintf(stderr,"\n" - "Parameters can be turned on with - or off with -=0\n" - "Parameters which take a value can be specified as " - "- \n" - "Other valid forms are = -= " - "--=\n" - "Parameter names are case-insensitive. The parameters are:\n\n"); - Configuration::listParams(79, 14); - exit(1); -} - -/* Tunnelling support. */ -static void -interpretViaParam (char **gatewayHost, char **remoteHost, - int *remotePort, char **vncServerName, - int localPort) -{ - const int SERVER_PORT_OFFSET = 5900; - char *pos = strchr (*vncServerName, ':'); - if (pos == NULL) - *remotePort = SERVER_PORT_OFFSET; - else { - int portOffset = SERVER_PORT_OFFSET; - size_t len; - *pos++ = '\0'; - len = strlen (pos); - if (*pos == ':') { - /* Two colons is an absolute port number, not an offset. */ - pos++; - len--; - portOffset = 0; - } - if (!len || strspn (pos, "-0123456789") != len ) - usage (); - *remotePort = atoi (pos) + portOffset; - } - - if (**vncServerName != '\0') - *remoteHost = *vncServerName; - - *gatewayHost = strDup (via.getValueStr ()); - *vncServerName = new char[50]; - sprintf (*vncServerName, "localhost::%d", localPort); -} - -#ifndef HAVE_SETENV -int -setenv(const char *envname, const char * envval, int overwrite) -{ - if (envname && envval) { - char * envp = NULL; - envp = (char*)malloc(strlen(envname) + strlen(envval) + 2); - if (envp) { - // The putenv API guarantees memory leaks when - // changing environment variables repeatedly. - sprintf(envp, "%s=%s", envname, envval); - - // Cannot free envp - putenv(envp); - return(0); - } - } - return(-1); -} -#endif - -static void -createTunnel (const char *gatewayHost, const char *remoteHost, - int remotePort, int localPort) -{ - char *cmd = getenv ("VNC_VIA_CMD"); - char *percent; - char lport[10], rport[10]; - sprintf (lport, "%d", localPort); - sprintf (rport, "%d", remotePort); - setenv ("G", gatewayHost, 1); - setenv ("H", remoteHost, 1); - setenv ("R", rport, 1); - setenv ("L", lport, 1); - if (!cmd) - cmd = "/usr/bin/ssh -f -L \"$L\":\"$H\":\"$R\" \"$G\" sleep 20"; - /* Compatibility with TigerVNC's method. */ - while ((percent = strchr (cmd, '%')) != NULL) - *percent = '$'; - system (cmd); -} - -int main(int argc, char** argv) -{ - setlocale(LC_ALL, ""); - bindtextdomain(PACKAGE_NAME, LOCALEDIR); - textdomain(PACKAGE_NAME); - - const char englishAbout[] = N_("TigerVNC Viewer for X version %s - built %s\n" - "Copyright (C) 1999-2011 TigerVNC Team and many others (see README.txt)\n" - "See http://www.tigervnc.org for information on TigerVNC."); - - rfb::SecurityClient::setDefaults(); - - // Write about text to console, still using normal locale codeset - snprintf(aboutText, sizeof(aboutText), - gettext(englishAbout), PACKAGE_VERSION, buildtime); - fprintf(stderr,"\n%s\n", aboutText); - - // Set gettext codeset to what our GUI toolkit uses. Since we are - // passing strings from strerror/gai_strerror to the GUI, these must - // be in GUI codeset as well. - bind_textdomain_codeset(PACKAGE_NAME, "iso-8859-1"); - bind_textdomain_codeset("libc", "iso-8859-1"); - - // Re-create the aboutText for the GUI, now using GUI codeset - snprintf(aboutText, sizeof(aboutText), - gettext(englishAbout), PACKAGE_VERSION, buildtime); - - rfb::initStdIOLoggers(); - rfb::LogWriter::setLogParams("*:stderr:30"); - - signal(SIGHUP, CleanupSignalHandler); - signal(SIGINT, CleanupSignalHandler); - signal(SIGTERM, CleanupSignalHandler); - - programName = argv[0]; - char* vncServerName = 0; - Display* dpy = 0; - - Configuration::enableViewerParams(); - - for (int i = 1; i < argc; i++) { - if (Configuration::setParam(argv[i])) - continue; - - if (argv[i][0] == '-') { - if (i+1 < argc) { - if (Configuration::setParam(&argv[i][1], argv[i+1])) { - i++; - continue; - } - } - usage(); - } - - vncServerName = argv[i]; - } - - // Create .vnc in the user's home directory if it doesn't already exist - char* homeDir = NULL; - if (getvnchomedir(&homeDir) == -1) { - vlog.error("Could not create VNC home directory: can't obtain home " - "directory path."); - } else { - int result = mkdir(homeDir, 0755); - if (result == -1 && errno != EEXIST) - vlog.error("Could not create VNC home directory: %s.", strerror(errno)); - delete [] homeDir; - } - - if (!::autoSelect.hasBeenSet()) { - // Default to AutoSelect=0 if -PreferredEncoding or -FullColor is used - ::autoSelect.setParam(!::preferredEncoding.hasBeenSet() - && !::fullColour.hasBeenSet() - && !::fullColourAlias.hasBeenSet()); - } - if (!::fullColour.hasBeenSet() && !::fullColourAlias.hasBeenSet()) { - // Default to FullColor=0 if AutoSelect=0 && LowColorLevel is set - if (!::autoSelect && (::lowColourLevel.hasBeenSet() || - ::lowColourLevelAlias.hasBeenSet())) { - ::fullColour.setParam(false); - } - } - if (!::customCompressLevel.hasBeenSet()) { - // Default to CustomCompressLevel=1 if CompressLevel is used. - ::customCompressLevel.setParam(::compressLevel.hasBeenSet()); - } - - try { - /* Tunnelling support. */ - if (strlen (via.getValueStr ()) > 0) { - char *gatewayHost = ""; - char *remoteHost = "localhost"; - int localPort = findFreeTcpPort (); - int remotePort; - if (!vncServerName) - usage(); - interpretViaParam (&gatewayHost, &remoteHost, &remotePort, - &vncServerName, localPort); - createTunnel (gatewayHost, remoteHost, remotePort, localPort); - } - - Socket* sock = 0; - - if (listenMode) { - int port = 5500; - if (vncServerName && isdigit(vncServerName[0])) - port = atoi(vncServerName); - - TcpListener listener(NULL, port); - - vlog.info("Listening on port %d\n",port); - - while (true) { - sock = listener.accept(); - int pid = fork(); - if (pid < 0) { perror("fork"); exit(1); } - if (pid == 0) break; // child - delete sock; - int status; - while (wait3(&status, WNOHANG, 0) > 0) ; - } - } - - CharArray displaynameStr(displayname.getData()); - if (!(dpy = XOpenDisplay(TXWindow::strEmptyToNull(displaynameStr.buf)))) { - fprintf(stderr,"%s: unable to open display \"%s\"\n", - programName, XDisplayName(displaynameStr.buf)); - exit(1); - } - - TXWindow::init(dpy, "Vncviewer"); - xloginIconifier.iconify(dpy); - CConn cc(dpy, argc, argv, sock, vncServerName, listenMode); - - // X events are processed whenever reading from the socket would block. - - while (true) { - cc.getInStream()->check(1); - cc.processMsg(); - } - - } catch (rdr::EndOfStream& e) { - vlog.info(e.str()); - } catch (rdr::Exception& e) { - vlog.error(e.str()); - if (dpy) { - TXMsgBox msgBox(dpy, e.str(), MB_OK, "VNC Viewer: Information"); - msgBox.show(); - } - return 1; - } - - return 0; -} diff --git a/unix/vncviewer/vncviewer.man b/unix/vncviewer/vncviewer.man deleted file mode 100644 index 8646e027..00000000 --- a/unix/vncviewer/vncviewer.man +++ /dev/null @@ -1,224 +0,0 @@ -.TH vncviewer 1 "05 May 2004" "TigerVNC" "Virtual Network Computing" -.SH NAME -vncviewer \- VNC viewer for X -.SH SYNOPSIS -.B vncviewer -.RI [ options ] -.RI [ host ][: display# ] -.br -.B vncviewer -.RI [ options ] -.RI [ host ][:: port ] -.br -.B vncviewer -.RI [ options ] -.B \-listen -.RI [ port ] -.SH DESCRIPTION -.B vncviewer -is a viewer (client) for Virtual Network Computing. This manual page documents -version 4 for the X window system. - -If you run the viewer with no arguments it will prompt you for a VNC server to -connect to. Alternatively, specify the VNC server as an argument, e.g.: - -.RS -vncviewer snoopy:2 -.RE - -where 'snoopy' is the name of the machine, and '2' is the display number of the -VNC server on that machine. Either the machine name or display number can be -omitted. So for example ":1" means display number 1 on the same machine, and -"snoopy" means "snoopy:0" i.e. display 0 on machine "snoopy". - -If the VNC server is successfully contacted, you will be prompted for a -password to authenticate you. If the password is correct, a window will appear -showing the desktop of the VNC server. - -.SH AUTOMATIC PROTOCOL SELECTION - -The viewer tests the speed of the connection to the server and chooses the -encoding and pixel format (color level) appropriately. This makes it much -easier to use than previous versions where the user had to specify arcane -command line arguments. - -The viewer normally starts out assuming the link is slow, using the -encoding with the best compression. If it turns out that the link is -fast enough it switches to an encoding which compresses less but is -faster to generate, thus improving the interactive feel. - -The viewer normally starts in full-color mode, but switches to -low-color mode if the bandwidth is insufficient. However, this only -occurs when communicating with servers supporting protocol 3.8 or -newer, since many old servers does not support color mode changes -safely. - -Automatic selection can be turned off by setting the -\fBAutoSelect\fP parameter to false, or from the options dialog. - -.SH POPUP MENU -The viewer has a popup menu containing entries which perform various actions. -It is usually brought up by pressing F8, but this can be configured with the -MenuKey parameter. Actions which the popup menu can perform include: -.RS 2 -.IP * 2 -switching in and out of full-screen mode -.IP * -quitting the viewer -.IP * -generating key events, e.g. sending ctrl-alt-del -.IP * -accessing the options dialog and various other dialogs -.RE -.PP -By default, key presses in the popup menu get sent to the VNC server and -dismiss the popup. So to get an F8 through to the VNC server simply press it -twice. - -.SH FULL SCREEN MODE -A full-screen mode is supported. This is particularly useful when connecting -to a remote screen which is the same size as your local one. If the remote -screen is bigger, you can scroll by bumping the mouse against the edge of the -screen. - -Unfortunately this mode doesn't work completely with all window managers, since -it breaks the X window management conventions. - -.SH OPTIONS (PARAMETERS) -You can get a list of parameters by giving \fB\-h\fP as a command-line option -to vncviewer. Parameters can be turned on with -\fIparam\fP or off with --\fIparam\fP=0. Parameters which take a value can be specified as --\fIparam\fP \fIvalue\fP. Other valid forms are \fIparam\fP\fB=\fP\fIvalue\fP --\fIparam\fP=\fIvalue\fP --\fIparam\fP=\fIvalue\fP. Parameter names are -case-insensitive. - -Many of the parameters can also be set graphically via the options dialog box. -This can be accessed from the popup menu or from the "Connection details" -dialog box. - -.TP -.B \-display \fIXdisplay\fP -Specifies the X display on which the VNC viewer window should appear. - -.TP -.B \-geometry \fIgeometry\fP -Standard X position and sizing specification. - -.TP -.B \-listen \fI[port]\fP -Causes vncviewer to listen on the given port (default 5500) for reverse -connections from a VNC server. WinVNC supports reverse connections initiated -using the 'Add New Client' menu option or the '\-connect' command-line option. -Xvnc supports reverse connections with a helper program called -.B vncconfig. - -.TP -.B \-passwd \fIpassword-file\fP -If you are on a filesystem which gives you access to the password file used by -the server, you can specify it here to avoid typing it in. It will usually be -"~/.vnc/passwd". - -.TP -.B \-Shared -When you make a connection to a VNC server, all other existing connections are -normally closed. This option requests that they be left open, allowing you to -share the desktop with someone already using it. - -.TP -.B \-ViewOnly -Specifies that no keyboard or mouse events should be sent to the server. -Useful if you want to view a desktop without interfering; often needs to be -combined with -.B \-Shared. - -.TP -.B \-FullScreen -Start in full-screen mode. - -.TP -.B \-DesktopSize \fIwidth\fPx\fIheight\fP -Instead of keeping the existing remote screen size, the client will attempt to -switch to the specified since when connecting. If the server does not support -the SetDesktopSize message then the screen will retain the original size. - -.TP -.B \-AutoSelect -Use automatic selection of encoding and pixel format (default is on). Normally -the viewer tests the speed of the connection to the server and chooses the -encoding and pixel format appropriately. Turn it off with \fB-AutoSelect=0\fP. - -.TP -.B \-FullColor, \-FullColour -Tells the VNC server to send full-color pixels in the best format for this -display. This is default. - -.TP -.B \-LowColorLevel, \-LowColourLevel \fIlevel\fP -Selects the reduced color level to use on slow links. \fIlevel\fP can range -from 0 to 2, 0 meaning 8 colors, 1 meaning 64 colors (the default), 2 meaning -256 colors. Note that decision if reduced color level is used is made by -vncviewer. If you would like to force vncviewer to use reduced color level -use \fB-AutoSelect=0\fP parameter. - -.TP -.B \-PreferredEncoding \fIencoding\fP -This option specifies the preferred encoding to use from one of "Tight", "ZRLE", -"hextile" or "raw". - -.TP -.B -UseLocalCursor -Render the mouse cursor locally if the server supports it (default is on). -This can make the interactive performance feel much better over slow links. - -.TP -.B \-WMDecorationWidth \fIw\fP, \-WMDecorationHeight \fIh\fP -The total width and height taken up by window manager decorations. This is -used to calculate the maximum size of the VNC viewer window. Default is -width 6, height 24. - -.TP -.B \-log \fIlogname\fP:\fIdest\fP:\fIlevel\fP -Configures the debug log settings. \fIdest\fP can currently be \fBstderr\fP or -\fBstdout\fP, and \fIlevel\fP is between 0 and 100, 100 meaning most verbose -output. \fIlogname\fP is usually \fB*\fP meaning all, but you can target a -specific source file if you know the name of its "LogWriter". Default is -\fB*:stderr:30\fP. - -.TP -.B \-MenuKey \fIkeysym-name\fP -This option specifies the key which brings up the popup menu. The key is -specified as an X11 keysym name (these can be obtained by removing the XK_ -prefix from the entries in "/usr/include/X11/keysymdef.h"). Default is F8. - -.TP -\fB\-via\fR \fIgateway\fR -Automatically create encrypted TCP tunnel to the \fIgateway\fR machine -before connection, connect to the \fIhost\fR through that tunnel -(TigerVNC\-specific). By default, this option invokes SSH local port -forwarding, assuming that SSH client binary can be accessed as -/usr/bin/ssh. Note that when using the \fB\-via\fR option, the host -machine name should be specified as known to the gateway machine, e.g. -"localhost" denotes the \fIgateway\fR, not the machine where vncviewer -was launched. The environment variable \fIVNC_VIA_CMD\fR can override -the default tunnel command of -\fB/usr/bin/ssh\ -f\ -L\ "$L":"$H":"$R"\ "$G"\ sleep\ 20\fR. The tunnel -command is executed with the environment variables \fIL\fR, \fIH\fR, -\fIR\fR, and \fIG\fR taken the values of the local port number, the remote -host, the port number on the remote host, and the gateway machine -respectively. - -.SH SEE ALSO -.BR Xvnc (1), -.BR vncpasswd (1), -.BR vncconfig (1), -.BR vncserver (1) -.br -http://www.tigervnc.org - -.SH AUTHOR -Tristan Richardson, RealVNC Ltd. - -VNC was originally developed by the RealVNC team while at Olivetti -Research Ltd / AT&T Laboratories Cambridge. TightVNC additions were -implemented by Constantin Kaplinsky. Many other people participated in -development, testing and support. diff --git a/win/CMakeLists.txt b/win/CMakeLists.txt index f8b5d5d6..24f3fc4c 100644 --- a/win/CMakeLists.txt +++ b/win/CMakeLists.txt @@ -4,10 +4,6 @@ configure_file(resdefs.h.in ${CMAKE_CURRENT_BINARY_DIR}/resdefs.h) add_subdirectory(rfb_win32) -if(NOT BUILD_NEW_VNCVIEWER) -add_subdirectory(vncviewer) -endif() - if(BUILD_WINVNC) add_subdirectory(vncconfig) add_subdirectory(winvnc) diff --git a/win/vncviewer/CConn.cxx b/win/vncviewer/CConn.cxx deleted file mode 100644 index b067134a..00000000 --- a/win/vncviewer/CConn.cxx +++ /dev/null @@ -1,863 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_GNUTLS -#include -#endif -#include -#include - -using namespace rfb; -using namespace rfb::win32; -using namespace rdr; - -// - Statics & consts - -static LogWriter vlog("CConn"); - - -const int IDM_FULLSCREEN = ID_FULLSCREEN; -const int IDM_SEND_MENU_KEY = ID_SEND_MENU_KEY; -const int IDM_SEND_CAD = ID_SEND_CAD; -const int IDM_SEND_CTLESC = ID_SEND_CTLESC; -const int IDM_ABOUT = ID_ABOUT; -const int IDM_OPTIONS = ID_OPTIONS; -const int IDM_INFO = ID_INFO; -const int IDM_NEWCONN = ID_NEW_CONNECTION; -const int IDM_REQUEST_REFRESH = ID_REQUEST_REFRESH; -const int IDM_CTRL_KEY = ID_CTRL_KEY; -const int IDM_ALT_KEY = ID_ALT_KEY; -const int IDM_CONN_SAVE_AS = ID_CONN_SAVE_AS; -const int IDM_ZOOM_IN = ID_ZOOM_IN; -const int IDM_ZOOM_OUT = ID_ZOOM_OUT; -const int IDM_ACTUAL_SIZE = ID_ACTUAL_SIZE; -const int IDM_AUTO_SIZE = ID_AUTO_SIZE; - - -static IntParameter debugDelay("DebugDelay","Milliseconds to display inverted " - "pixel data - a debugging feature", 0); - -const int scaleValues[9] = {10, 25, 50, 75, 90, 100, 125, 150, 200}; -const int scaleCount = 9; - - -// -// -=- CConn implementation -// - -RegKey CConn::userConfigKey; - - -CConn::CConn() - : window(0), sameMachine(false), encodingChange(false), formatChange(false), - lastUsedEncoding_(encodingRaw), sock(0), sockEvent(CreateEvent(0, TRUE, FALSE, 0)), - reverseConnection(false), requestUpdate(false), firstUpdate(true), - pendingUpdate(false), isClosed_(false) { -} - -CConn::~CConn() { - delete window; -} - -bool CConn::initialise(network::Socket* s, bool reverse) { - // Set the server's name for MRU purposes - CharArray endpoint(s->getPeerEndpoint()); - - if (!options.host.buf) - options.setHost(endpoint.buf); - setServerName(options.host.buf); - - // Initialise the underlying CConnection - setStreams(&s->inStream(), &s->outStream()); - - // Enable processing of window messages while blocked on I/O - s->inStream().setBlockCallback(this); - - // Initialise the viewer options - applyOptions(options); - - CSecurity::upg = this; -#ifdef HAVE_GNUTLS - CSecurityTLS::msg = this; -#endif - - // Start the RFB protocol - sock = s; - reverseConnection = reverse; - initialiseProtocol(); - - return true; -} - - -void -CConn::applyOptions(CConnOptions& opt) { - // - If any encoding-related settings have changed then we must - // notify the server of the new settings - encodingChange |= ((options.useLocalCursor != opt.useLocalCursor) || - (options.useDesktopResize != opt.useDesktopResize) || - (options.customCompressLevel != opt.customCompressLevel) || - (options.compressLevel != opt.compressLevel) || - (options.noJpeg != opt.noJpeg) || - (options.qualityLevel != opt.qualityLevel) || - (options.preferredEncoding != opt.preferredEncoding)); - - // - If the preferred pixel format has changed then notify the server - formatChange |= (options.fullColour != opt.fullColour); - if (!opt.fullColour) - formatChange |= (options.lowColourLevel != opt.lowColourLevel); - - // - Save the new set of options - options = opt; - - // - Set optional features in ConnParams - cp.supportsLocalCursor = options.useLocalCursor; - cp.supportsDesktopResize = options.useDesktopResize; - cp.supportsExtendedDesktopSize = options.useDesktopResize; - cp.supportsDesktopRename = true; - cp.customCompressLevel = options.customCompressLevel; - cp.compressLevel = options.compressLevel; - cp.noJpeg = options.noJpeg; - cp.qualityLevel = options.qualityLevel; - - // - Configure connection sharing on/off - setShared(options.shared); - - // - Whether to use protocol 3.3 for legacy compatibility - setProtocol3_3(options.protocol3_3); - - // - Apply settings that affect the window, if it is visible - if (window) { - window->setMonitor(options.monitor.buf); - window->setFullscreen(options.fullScreen); - window->setEmulate3(options.emulate3); - window->setPointerEventInterval(options.pointerEventInterval); - window->setMenuKey(options.menuKey); - window->setDisableWinKeys(options.disableWinKeys); - window->setShowToolbar(options.showToolbar); - window->printScale(); - if (options.autoScaling) { - window->setAutoScaling(true); - } else { - window->setAutoScaling(false); - window->setDesktopScale(options.scale); - } - if (!options.useLocalCursor) - window->setCursor(0, 0, Point(), 0, 0); - } - - security->SetSecTypes(options.secTypes); -} - - -void -CConn::displayChanged() { - // Display format has changed - recalculate the full-colour pixel format - calculateFullColourPF(); -} - - -bool -CConn::sysCommand(WPARAM wParam, LPARAM lParam) { - // - If it's one of our (F8 Menu) messages - switch (wParam) { - case IDM_FULLSCREEN: - options.fullScreen = !window->isFullscreen(); - window->setFullscreen(options.fullScreen); - return true; - case IDM_ZOOM_IN: - case IDM_ZOOM_OUT: - { - if (options.autoScaling) { - options.scale = window->getDesktopScale(); - options.autoScaling = false; - window->setAutoScaling(false); - } - if (wParam == (unsigned)IDM_ZOOM_IN) { - for (int i = 0; i < scaleCount; i++) - if (options.scale < scaleValues[i]) { - options.scale = scaleValues[i]; - break; - } - } else { - for (int i = scaleCount-1; i >= 0; i--) - if (options.scale > scaleValues[i]) { - options.scale = scaleValues[i]; - break; - } - } - if (options.scale != window->getDesktopScale()) - window->setDesktopScale(options.scale); - } - return true; - case IDM_ACTUAL_SIZE: - if (options.autoScaling) { - options.autoScaling = false; - window->setAutoScaling(false); - } - options.scale = 100; - window->setDesktopScale(100); - return true; - case IDM_AUTO_SIZE: - options.autoScaling = !options.autoScaling; - window->setAutoScaling(options.autoScaling); - if (!options.autoScaling) options.scale = window->getDesktopScale(); - return true; - case IDM_SHOW_TOOLBAR: - options.showToolbar = !window->isToolbarEnabled(); - window->setShowToolbar(options.showToolbar); - return true; - case IDM_CTRL_KEY: - window->kbd.keyEvent(this, VK_CONTROL, 0, !window->kbd.keyPressed(VK_CONTROL)); - return true; - case IDM_ALT_KEY: - window->kbd.keyEvent(this, VK_MENU, 0, !window->kbd.keyPressed(VK_MENU)); - return true; - case IDM_SEND_MENU_KEY: - window->kbd.keyEvent(this, options.menuKey, 0, true); - window->kbd.keyEvent(this, options.menuKey, 0, false); - return true; - case IDM_SEND_CAD: - window->kbd.keyEvent(this, VK_CONTROL, 0, true); - window->kbd.keyEvent(this, VK_MENU, 0, true); - window->kbd.keyEvent(this, VK_DELETE, 0x1000000, true); - window->kbd.keyEvent(this, VK_DELETE, 0x1000000, false); - window->kbd.keyEvent(this, VK_MENU, 0, false); - window->kbd.keyEvent(this, VK_CONTROL, 0, false); - return true; - case IDM_SEND_CTLESC: - window->kbd.keyEvent(this, VK_CONTROL, 0, true); - window->kbd.keyEvent(this, VK_ESCAPE, 0, true); - window->kbd.keyEvent(this, VK_ESCAPE, 0, false); - window->kbd.keyEvent(this, VK_CONTROL, 0, false); - return true; - case IDM_REQUEST_REFRESH: - try { - writer()->writeFramebufferUpdateRequest(Rect(0,0,cp.width,cp.height), false); - requestUpdate = false; - } catch (rdr::Exception& e) { - close(e.str()); - } - return true; - case IDM_NEWCONN: - { - new CConnThread; - } - return true; - case IDM_OPTIONS: - // Update the monitor device name in the CConnOptions instance - options.monitor.replaceBuf(window->getMonitor()); - showOptionsDialog(); - return true; - case IDM_INFO: - infoDialog.showDialog(this); - return true; - case IDM_ABOUT: - AboutDialog::instance.showDialog(); - return true; - case IDM_CONN_SAVE_AS: - return true; - }; - return false; -} - - -void -CConn::closeWindow() { - vlog.info("window closed"); - close(); -} - - -void -CConn::refreshMenu(bool enableSysItems) { - HMENU menu = GetSystemMenu(window->getHandle(), FALSE); - - if (!enableSysItems) { - // Gray out menu items that might cause a World Of Pain - EnableMenuItem(menu, SC_SIZE, MF_BYCOMMAND | MF_GRAYED); - EnableMenuItem(menu, SC_MOVE, MF_BYCOMMAND | MF_GRAYED); - EnableMenuItem(menu, SC_RESTORE, MF_BYCOMMAND | MF_ENABLED); - EnableMenuItem(menu, SC_MINIMIZE, MF_BYCOMMAND | MF_ENABLED); - EnableMenuItem(menu, SC_MAXIMIZE, MF_BYCOMMAND | MF_ENABLED); - } - - // Update the modifier key menu items - UINT ctrlCheckFlags = window->kbd.keyPressed(VK_CONTROL) ? MF_CHECKED : MF_UNCHECKED; - UINT altCheckFlags = window->kbd.keyPressed(VK_MENU) ? MF_CHECKED : MF_UNCHECKED; - CheckMenuItem(menu, IDM_CTRL_KEY, MF_BYCOMMAND | ctrlCheckFlags); - CheckMenuItem(menu, IDM_ALT_KEY, MF_BYCOMMAND | altCheckFlags); - - // Ensure that the Send menu item has the correct text - if (options.menuKey) { - TCharArray menuKeyStr(options.menuKeyName()); - TCharArray tmp(_tcslen(menuKeyStr.buf) + 6); - _stprintf(tmp.buf, _T("Send %s"), menuKeyStr.buf); - if (!ModifyMenu(menu, IDM_SEND_MENU_KEY, MF_BYCOMMAND | MF_STRING, IDM_SEND_MENU_KEY, tmp.buf)) - InsertMenu(menu, IDM_SEND_CAD, MF_BYCOMMAND | MF_STRING, IDM_SEND_MENU_KEY, tmp.buf); - } else { - RemoveMenu(menu, IDM_SEND_MENU_KEY, MF_BYCOMMAND); - } - - // Set the menu fullscreen option tick - CheckMenuItem(menu, IDM_FULLSCREEN, (window->isFullscreen() ? MF_CHECKED : 0) | MF_BYCOMMAND); - - // Set the menu toolbar option tick - int toolbarFlags = window->isToolbarEnabled() ? MF_CHECKED : 0; - CheckMenuItem(menu, IDM_SHOW_TOOLBAR, MF_BYCOMMAND | toolbarFlags); - - // In the full-screen mode, "Show toolbar" should be grayed. - toolbarFlags = window->isFullscreen() ? MF_GRAYED : MF_ENABLED; - EnableMenuItem(menu, IDM_SHOW_TOOLBAR, MF_BYCOMMAND | toolbarFlags); -} - - -void -CConn::blockCallback() { - // - An InStream has blocked on I/O while processing an RFB message - // We re-enable socket event notifications, so we'll know when more - // data is available, then we sit and dispatch window events until - // the notification arrives. - if (!isClosed()) { - if (WSAEventSelect(sock->getFd(), sockEvent, FD_READ | FD_CLOSE) == SOCKET_ERROR) - throw rdr::SystemException("Unable to wait for sokcet data", WSAGetLastError()); - } - while (true) { - // If we have closed then we can't block waiting for data - if (isClosed()) - throw rdr::EndOfStream(); - - // Wait for socket data, or a message to process - DWORD result = MsgWaitForMultipleObjects(1, &sockEvent.h, FALSE, INFINITE, QS_ALLINPUT); - if (result == WAIT_FAILED) { - // - The wait operation failed - raise an exception - throw rdr::SystemException("blockCallback wait error", GetLastError()); - } - - // - There should be a message in the message queue - MSG msg; - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { - // IMPORTANT: We mustn't call TranslateMessage() here, because instead we - // call ToAscii() in CKeyboard::keyEvent(). ToAscii() stores dead key - // state from one call to the next, which would be messed up by calls to - // TranslateMessage() (actually it looks like TranslateMessage() calls - // ToAscii() internally). - DispatchMessage(&msg); - } - - if (result == WAIT_OBJECT_0) - // - Network event notification. Return control to I/O routine. - break; - } - - // Before we return control to the InStream, reset the network event - WSAEventSelect(sock->getFd(), sockEvent, 0); - ResetEvent(sockEvent); -} - - -void CConn::keyEvent(rdr::U32 key, bool down) { - if (!options.sendKeyEvents) return; - try { - writer()->keyEvent(key, down); - } catch (rdr::Exception& e) { - close(e.str()); - } -} -void CConn::pointerEvent(const Point& pos, int buttonMask) { - if (!options.sendPtrEvents) return; - try { - writer()->pointerEvent(pos, buttonMask); - } catch (rdr::Exception& e) { - close(e.str()); - } -} -void CConn::clientCutText(const char* str, int len) { - if (!options.clientCutText) return; - if (state() != RFBSTATE_NORMAL) return; - try { - writer()->clientCutText(str, len); - } catch (rdr::Exception& e) { - close(e.str()); - } -} - -void -CConn::setColourMapEntries(int first, int count, U16* rgbs) { - vlog.debug("setColourMapEntries: first=%d, count=%d", first, count); - int i; - for (i=0;isetColour(i+first, rgbs[i*3], rgbs[i*3+1], rgbs[i*3+2]); - // *** change to 0, 256? - window->refreshWindowPalette(first, count); -} - -void -CConn::bell() { - if (options.acceptBell) - MessageBeep((UINT)-1); -} - - -void -CConn::setDesktopSize(int w, int h) { - vlog.debug("setDesktopSize %dx%d", w, h); - - // Resize the window's buffer - if (window) - window->setSize(w, h); - - // Tell the underlying CConnection - CConnection::setDesktopSize(w, h); -} - - -void -CConn::setExtendedDesktopSize(int reason, int result, int w, int h, - const rfb::ScreenSet& layout) { - if ((reason == (signed)reasonClient) && (result != (signed)resultSuccess)) { - vlog.error("SetDesktopSize failed: %d", result); - return; - } - - // Resize the window's buffer - if (window) - window->setSize(w, h); - - // Tell the underlying CConnection - CConnection::setExtendedDesktopSize(reason, result, w, h, layout); -} - - -void -CConn::setCursor(int w, int h, const Point& hotspot, void* data, void* mask) { - if (!options.useLocalCursor) return; - - // Set the window to use the new cursor - window->setCursor(w, h, hotspot, data, mask); -} - - -void -CConn::close(const char* reason) { - // If already closed then ignore this - if (isClosed()) - return; - - // Hide the window, if it exists - if (window) - ShowWindow(window->getHandle(), SW_HIDE); - - // Save the reason & flag that we're closed & shutdown the socket - isClosed_ = true; - closeReason_.replaceBuf(strDup(reason)); - sock->shutdown(); -} - -bool CConn::showMsgBox(int flags, const char* title, const char* text) -{ - UINT winflags = 0; - int ret; - - /* Translate flags */ - if ((flags & M_OK) != 0) - winflags |= MB_OK; - if ((flags & M_OKCANCEL) != 0) - winflags |= MB_OKCANCEL; - if ((flags & M_YESNO) != 0) - winflags |= MB_YESNO; - if ((flags & M_ICONERROR) != 0) - winflags |= MB_ICONERROR; - if ((flags & M_ICONQUESTION) != 0) - winflags |= MB_ICONQUESTION; - if ((flags & M_ICONWARNING) != 0) - winflags |= MB_ICONWARNING; - if ((flags & M_ICONINFORMATION) != 0) - winflags |= MB_ICONINFORMATION; - if ((flags & M_DEFBUTTON1) != 0) - winflags |= MB_DEFBUTTON1; - if ((flags & M_DEFBUTTON2) != 0) - winflags |= MB_DEFBUTTON2; - - ret = MessageBox(NULL, text, title, flags); - return (ret == IDOK || ret == IDYES) ? true : false; -} - -void -CConn::showOptionsDialog() { - optionsDialog.showDialog(this); -} - - -void -CConn::framebufferUpdateStart() { - if (!formatChange) { - requestUpdate = pendingUpdate = true; - requestNewUpdate(); - } else - pendingUpdate = false; -} - - -void -CConn::framebufferUpdateEnd() { - if (debugDelay != 0) { - vlog.debug("debug delay %d",(int)debugDelay); - UpdateWindow(window->getHandle()); - Sleep(debugDelay); - std::list::iterator i; - for (i = debugRects.begin(); i != debugRects.end(); i++) { - window->invertRect(*i); - } - debugRects.clear(); - } - window->framebufferUpdateEnd(); - - if (firstUpdate) { - int width, height; - - if (cp.supportsSetDesktopSize && - sscanf(options.desktopSize.buf, "%dx%d", &width, &height) == 2) { - ScreenSet layout; - - layout = cp.screenLayout; - - if (layout.num_screens() == 0) - layout.add_screen(rfb::Screen()); - else if (layout.num_screens() != 1) { - ScreenSet::iterator iter; - - while (true) { - iter = layout.begin(); - ++iter; - - if (iter == layout.end()) - break; - - layout.remove_screen(iter->id); - } - } - - layout.begin()->dimensions.tl.x = 0; - layout.begin()->dimensions.tl.y = 0; - layout.begin()->dimensions.br.x = width; - layout.begin()->dimensions.br.y = height; - - writer()->writeSetDesktopSize(width, height, layout); - } - - firstUpdate = false; - } - - // Always request the next update - requestUpdate = true; - - // A format change prevented us from sending this before the update, - // so make sure to send it now. - if (formatChange && !pendingUpdate) - requestNewUpdate(); - - if (options.autoSelect) - autoSelectFormatAndEncoding(); - - // Check that at least part of the window has changed - if (!GetUpdateRect(window->getHandle(), 0, FALSE)) { - if (!(GetWindowLong(window->getHandle(), GWL_STYLE) & WS_MINIMIZE)) - requestNewUpdate(); - } - - // Make sure the local cursor is shown - window->showCursor(); -} - - -// Note: The method below is duplicated in win/vncviewer/CConn.cxx! - -// autoSelectFormatAndEncoding() chooses the format and encoding appropriate -// to the connection speed: -// -// First we wait for at least one second of bandwidth measurement. -// -// Above 16Mbps (i.e. LAN), we choose the second highest JPEG quality, -// which should be perceptually lossless. -// -// If the bandwidth is below that, we choose a more lossy JPEG quality. -// -// If the bandwidth drops below 256 Kbps, we switch to palette mode. -// -// Note: The system here is fairly arbitrary and should be replaced -// with something more intelligent at the server end. -// -void CConn::autoSelectFormatAndEncoding() -{ - int kbitsPerSecond = sock->inStream().kbitsPerSecond(); - unsigned int timeWaited = sock->inStream().timeWaited(); - bool newFullColour = options.fullColour; - int newQualityLevel = options.qualityLevel; - - // Always use Tight - options.preferredEncoding = encodingTight; - - // Check that we have a decent bandwidth measurement - if ((kbitsPerSecond == 0) || (timeWaited < 10000)) - return; - - // Select appropriate quality level - if (!options.noJpeg) { - if (kbitsPerSecond > 16000) - newQualityLevel = 8; - else - newQualityLevel = 6; - - if (newQualityLevel != options.qualityLevel) { - vlog.info("Throughput %d kbit/s - changing to quality %d ", - kbitsPerSecond, newQualityLevel); - cp.qualityLevel = newQualityLevel; - options.qualityLevel = newQualityLevel; - encodingChange = true; - } - } - - if (cp.beforeVersion(3, 8)) { - // Xvnc from TightVNC 1.2.9 sends out FramebufferUpdates with - // cursors "asynchronously". If this happens in the middle of a - // pixel format change, the server will encode the cursor with - // the old format, but the client will try to decode it - // according to the new format. This will lead to a - // crash. Therefore, we do not allow automatic format change for - // old servers. - return; - } - - // Select best color level - newFullColour = (kbitsPerSecond > 256); - if (newFullColour != options.fullColour) { - vlog.info("Throughput %d kbit/s - full color is now %s", - kbitsPerSecond, - newFullColour ? "enabled" : "disabled"); - options.fullColour = newFullColour; - formatChange = true; - } -} - -void -CConn::requestNewUpdate() { - if (!requestUpdate) return; - - if (formatChange) { - - /* Catch incorrect requestNewUpdate calls */ - assert(pendingUpdate == false); - - // Select the required pixel format - if (options.fullColour) { - window->setPF(fullColourPF); - } else { - switch (options.lowColourLevel) { - case 0: - window->setPF(PixelFormat(8,3,0,1,1,1,1,2,1,0)); - break; - case 1: - window->setPF(PixelFormat(8,6,0,1,3,3,3,4,2,0)); - break; - case 2: - window->setPF(PixelFormat(8,8,0,0,0,0,0,0,0,0)); - break; - } - } - - // Print the current pixel format - char str[256]; - window->getPF().print(str, 256); - vlog.info("Using pixel format %s",str); - - // Save the connection pixel format and tell server to use it - cp.setPF(window->getPF()); - writer()->writeSetPixelFormat(cp.pf()); - - // Correct the local window's palette - if (!window->getNativePF().trueColour) - window->refreshWindowPalette(0, 1 << cp.pf().depth); - } - - if (encodingChange) { - vlog.info("Using %s encoding",encodingName(options.preferredEncoding)); - writer()->writeSetEncodings(options.preferredEncoding, true); - } - - writer()->writeFramebufferUpdateRequest(Rect(0, 0, cp.width, cp.height), - !formatChange); - - encodingChange = formatChange = requestUpdate = false; -} - - -void -CConn::calculateFullColourPF() { - // If the server is palette based then use palette locally - // Also, don't bother doing bgr222 - if (!serverDefaultPF.trueColour || (serverDefaultPF.depth < 6)) { - fullColourPF = serverDefaultPF; - options.fullColour = true; - } else { - // If server is trueColour, use lowest depth PF - PixelFormat native = window->getNativePF(); - if ((serverDefaultPF.bpp < native.bpp) || - ((serverDefaultPF.bpp == native.bpp) && - (serverDefaultPF.depth < native.depth))) - fullColourPF = serverDefaultPF; - else - fullColourPF = window->getNativePF(); - } - formatChange = true; -} - - -void -CConn::setName(const char* name) { - if (window) - window->setName(name); - CConnection::setName(name); -} - - -void CConn::serverInit() { - CConnection::serverInit(); - - // If using AutoSelect with old servers, start in FullColor - // mode. See comment in autoSelectFormatAndEncoding. - if (cp.beforeVersion(3, 8) && options.autoSelect) { - options.fullColour = true; - } - - // Show the window - window = new DesktopWindow(this); - - // Update the window menu - HMENU wndmenu = GetSystemMenu(window->getHandle(), FALSE); - int toolbarChecked = options.showToolbar ? MF_CHECKED : 0; - - AppendMenu(wndmenu, MF_SEPARATOR, 0, 0); - AppendMenu(wndmenu, MF_STRING, IDM_FULLSCREEN, _T("&Full screen")); - AppendMenu(wndmenu, MF_STRING | toolbarChecked, IDM_SHOW_TOOLBAR, - _T("Show tool&bar")); - AppendMenu(wndmenu, MF_SEPARATOR, 0, 0); - AppendMenu(wndmenu, MF_STRING, IDM_CTRL_KEY, _T("Ctr&l")); - AppendMenu(wndmenu, MF_STRING, IDM_ALT_KEY, _T("Al&t")); - AppendMenu(wndmenu, MF_STRING, IDM_SEND_CAD, _T("Send Ctrl-Alt-&Del")); - AppendMenu(wndmenu, MF_STRING, IDM_SEND_CTLESC, _T("Send Ctrl-&Esc")); - AppendMenu(wndmenu, MF_STRING, IDM_REQUEST_REFRESH, _T("Refres&h Screen")); - AppendMenu(wndmenu, MF_SEPARATOR, 0, 0); - AppendMenu(wndmenu, MF_STRING, IDM_NEWCONN, _T("Ne&w Connection...")); - AppendMenu(wndmenu, MF_STRING, IDM_OPTIONS, _T("&Options...")); - AppendMenu(wndmenu, MF_STRING, IDM_INFO, _T("Connection &Info...")); - AppendMenu(wndmenu, MF_STRING, IDM_ABOUT, _T("&About...")); - - // Set window attributes - window->setName(cp.name()); - window->setShowToolbar(options.showToolbar); - window->setSize(cp.width, cp.height); - applyOptions(options); - - // Save the server's current format - serverDefaultPF = cp.pf(); - - // Calculate the full-colour format to use - calculateFullColourPF(); - - // Request the initial update - vlog.info("requesting initial update"); - formatChange = encodingChange = requestUpdate = true; - requestNewUpdate(); -} - -void -CConn::serverCutText(const char* str, rdr::U32 len) { - if (!options.serverCutText) return; - window->serverCutText(str, len); -} - - -void CConn::beginRect(const Rect& r, int encoding) { - sock->inStream().startTiming(); -} - -void CConn::endRect(const Rect& r, int encoding) { - sock->inStream().stopTiming(); - lastUsedEncoding_ = encoding; - if (debugDelay != 0) { - window->invertRect(r); - debugRects.push_back(r); - } -} - -void CConn::fillRect(const Rect& r, Pixel pix) { - window->fillRect(r, pix); -} -void CConn::imageRect(const Rect& r, void* pixels) { - window->imageRect(r, pixels); -} -void CConn::copyRect(const Rect& r, int srcX, int srcY) { - window->copyRect(r, srcX, srcY); -} - -void CConn::getUserPasswd(char** user, char** password) { - if (!user && options.passwordFile.buf[0]) { - FILE* fp = fopen(options.passwordFile.buf, "rb"); - if (fp) { - char data[256]; - int datalen = fread(data, 1, 256, fp); - fclose(fp); - if (datalen == 8) { - ObfuscatedPasswd obfPwd; - obfPwd.buf = data; - obfPwd.length = datalen; - PlainPasswd passwd(obfPwd); - obfPwd.takeBuf(); - *password = strDup(passwd.buf); - memset(data, 0, sizeof(data)); - } - } - } - if (user && options.userName.buf) - *user = strDup(options.userName.buf); - if (password && options.password.buf) - *password = strDup(options.password.buf); - if ((user && !*user) || (password && !*password)) { - // Missing username or password - prompt the user - UserPasswdDialog userPasswdDialog; - userPasswdDialog.setCSecurity(csecurity); - userPasswdDialog.getUserPasswd(user, password); - } - if (user) options.setUserName(*user); - if (password) options.setPassword(*password); -} - diff --git a/win/vncviewer/CConn.h b/win/vncviewer/CConn.h deleted file mode 100644 index d3b3b206..00000000 --- a/win/vncviewer/CConn.h +++ /dev/null @@ -1,169 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -// -=- CConn.h - -// Windows-specific implementation of CConnection - -#ifndef __RFB_WIN32_CCONN_H__ -#define __RFB_WIN32_CCONN_H__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -namespace rfb { - - namespace win32 { - - class CConn : public CConnection, - UserPasswdGetter, - DesktopWindow::Callback, - rdr::FdInStreamBlockCallback, - UserMsgBox - { - public: - CConn(); - ~CConn(); - - // - Start the VNC session on the supplied socket - // The socket must already be connected to a host - bool initialise(network::Socket* s, bool reverse=false); - - // - Set/get the session options - void applyOptions(CConnOptions& opt); - const CConnOptions& getOptions() const { return options; }; - - // - Show the options dialog for the connection - void showOptionsDialog(); - - // - Close the socket & set the reason for closure - void close(const char* reason=0); - bool isClosed() const { return isClosed_; } - const char* closeReason() const { return closeReason_.buf; } - - // - Last received encoding, for the Info dialog - int lastUsedEncoding() const { return lastUsedEncoding_; } - - // - Get at the DesktopWindow, if any - DesktopWindow* getWindow() { return window; } - - // - Get at the underlying Socket - network::Socket* getSocket() { return sock; } - - // - Get the server's preferred format - const PixelFormat& getServerDefaultPF() const { return serverDefaultPF; } - - // - Display message box - virtual bool showMsgBox(int flags, const char* title, const char* text); - - // Global user-config registry key - static RegKey userConfigKey; - - protected: - // InputHandler interface (via DesktopWindow::Callback) - void keyEvent(rdr::U32 key, bool down); - void pointerEvent(const Point& pos, int buttonMask); - void clientCutText(const char* str, int len); - - // DesktopWindow::Callback interface - void displayChanged(); - void paintCompleted() {} - bool sysCommand(WPARAM wParam, LPARAM lParam); - void closeWindow(); - void refreshMenu(bool enableSysCommands); - - // CConnection interface - void setColourMapEntries(int firstColour, int nColours, rdr::U16* rgbs); - void bell(); - void framebufferUpdateStart(); - void framebufferUpdateEnd(); - void setDesktopSize(int w, int h); - void setExtendedDesktopSize(int reason, int result, int w, int h, - const rfb::ScreenSet& layout); - void setCursor(int w, int h, const Point& hotspot, void* data, void* mask); - void setName(const char* name); - void serverInit(); - void serverCutText(const char* str, rdr::U32 len); - void beginRect(const Rect& r, int encoding); - void endRect(const Rect& r, int encoding); - void fillRect(const Rect& r, Pixel pix); - void imageRect(const Rect& r, void* pixels); - void copyRect(const Rect& r, int srcX, int srcY); - - // rdr::FdInStreamBlockCallback interface - void blockCallback(); - - // UserPasswdGetter interface - // (overridden to allow a pre-supplied username & password) - void getUserPasswd(char** user, char** password); - - // CConn-specific internal interface - void autoSelectFormatAndEncoding(); - void requestNewUpdate(); - void calculateFullColourPF(); - - // The desktop window - DesktopWindow* window; - - // Info and Options dialogs - OptionsDialog optionsDialog; - InfoDialog infoDialog; - - // VNC Viewer options - CConnOptions options; - - // Pixel format and encoding - PixelFormat serverDefaultPF; - PixelFormat fullColourPF; - bool sameMachine; - bool encodingChange; - bool formatChange; - int lastUsedEncoding_; - - // Networking and RFB protocol - network::Socket* sock; - Handle sockEvent; - bool reverseConnection; - bool requestUpdate; - bool firstUpdate; - bool pendingUpdate; - - // Debugging/logging - std::list debugRects; - CharArray closeReason_; - bool isClosed_; - }; - - }; - -}; - -#endif - - diff --git a/win/vncviewer/CConnOptions.cxx b/win/vncviewer/CConnOptions.cxx deleted file mode 100644 index 3152db9e..00000000 --- a/win/vncviewer/CConnOptions.cxx +++ /dev/null @@ -1,507 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace rfb; -using namespace rfb::win32; - -static StringParameter passwordFile("PasswordFile", - "Password file for VNC authentication", ""); - -// - Settings stored in the registry & in .vnc files, by Save Defaults and -// Save Configuration respectively. - -static BoolParameter useLocalCursor("UseLocalCursor", "Render the mouse cursor locally", true); -static BoolParameter useDesktopResize("UseDesktopResize", "Support dynamic desktop resizing", true); - -static BoolParameter fullColour("FullColor", - "Use full color", true); -static AliasParameter fullColourAlias("FullColour", "Alias for FullColor", &fullColour); - -static IntParameter lowColourLevel("LowColorLevel", - "Color level to use on slow connections. " - "0 = Very Low (8 colors), 1 = Low (64 colors), 2 = Medium (256 colors)", - 2); -static AliasParameter lowColourLevelAlias("LowColourLevel", "Alias for LowColorLevel", &lowColourLevel); - -static BoolParameter fullScreen("FullScreen", - "Use the whole display to show the remote desktop." - "(Press F8 to access the viewer menu)", - false); -static StringParameter preferredEncoding("PreferredEncoding", - "Preferred encoding to use (Tight, ZRLE, Hextile or" - " Raw)", "Tight"); -static BoolParameter autoSelect("AutoSelect", - "Auto select pixel format and encoding. " - "Default if PreferredEncoding and FullColor are not specified.", - true); -static BoolParameter sharedConnection("Shared", - "Allow existing connections to the server to continue." - "(Default is to disconnect all other clients)", - false); - -StringParameter desktopSize("DesktopSize", - "Reconfigure desktop size on the server on " - "connect (if possible)", ""); - -static BoolParameter sendPtrEvents("SendPointerEvents", - "Send pointer (mouse) events to the server.", true); -static BoolParameter sendKeyEvents("SendKeyEvents", - "Send key presses (and releases) to the server.", true); - -static BoolParameter clientCutText("ClientCutText", - "Send clipboard changes to the server.", true); -static BoolParameter serverCutText("ServerCutText", - "Accept clipboard changes from the server.", true); - -static BoolParameter disableWinKeys("DisableWinKeys", - "Pass special Windows keys directly to the server.", true); - -static BoolParameter protocol3_3("Protocol3.3", - "Only use protocol version 3.3", false); - -static IntParameter ptrEventInterval("PointerEventInterval", - "The interval to delay between sending one pointer event " - "and the next.", 0); -static BoolParameter emulate3("Emulate3", - "Emulate middle mouse button when left and right buttons " - "are used simulatenously.", false); - -static BoolParameter acceptBell("AcceptBell", - "Produce a system beep when requested to by the server.", - true); - -static BoolParameter showToolbar("ShowToolbar", "Show toolbar by default.", true); - -static StringParameter monitor("Monitor", "The monitor to open the VNC Viewer window on, if available.", ""); -static StringParameter menuKey("MenuKey", "The key which brings up the popup menu", "F8"); -static BoolParameter autoReconnect("AutoReconnect", "Offer to reconnect to the remote server if the connection" - "is dropped because an error occurs.", true); - -static BoolParameter customCompressLevel("CustomCompressLevel", - "Use custom compression level. " - "Default if CompressLevel is specified.", false); - -static IntParameter compressLevel("CompressLevel", - "Use specified compression level" - "0 = Low, 9 = High", - 6); - -static BoolParameter noJpeg("NoJPEG", - "Disable lossy JPEG compression in Tight encoding.", - false); - -static IntParameter qualityLevel("QualityLevel", - "JPEG quality level. " - "0 = Low, 9 = High", - 8); - -static BoolParameter autoScaling("AutoScaling", - "Auto rescale local copy of the remote desktop to the client window.", - false); -static IntParameter scale("Scale", - "Scale local copy of the remote desktop, in percent", - 100); - -CConnOptions::CConnOptions() -: useLocalCursor (::useLocalCursor), -useDesktopResize(::useDesktopResize), -fullScreen(::fullScreen), -fullColour(::fullColour), -lowColourLevel(::lowColourLevel), -preferredEncoding(encodingTight), -autoSelect(::autoSelect), -shared(::sharedConnection), -desktopSize(::desktopSize.getData()), -sendPtrEvents(::sendPtrEvents), -sendKeyEvents(::sendKeyEvents), -showToolbar(::showToolbar), -clientCutText(::clientCutText), -serverCutText(::serverCutText), -disableWinKeys(::disableWinKeys), -emulate3(::emulate3), -pointerEventInterval(ptrEventInterval), -protocol3_3(::protocol3_3), -acceptBell(::acceptBell), -autoScaling(::autoScaling), -scale(::scale), -monitor(::monitor.getData()), -autoReconnect(::autoReconnect), -customCompressLevel(::customCompressLevel), -compressLevel(::compressLevel), -noJpeg(::noJpeg), -qualityLevel(::qualityLevel), -passwordFile(::passwordFile.getData()) -{ - char *sectypes; - - if (autoSelect) { - preferredEncoding = encodingTight; - } else { - CharArray encodingName(::preferredEncoding.getData()); - preferredEncoding = encodingNum(encodingName.buf); - } - setMenuKey(CharArray(::menuKey.getData()).buf); - - if (!::autoSelect.hasBeenSet()) { - // Default to AutoSelect=0 if -PreferredEncoding or -FullColor is used - autoSelect = (!::preferredEncoding.hasBeenSet() - && !::fullColour.hasBeenSet() - && !::fullColourAlias.hasBeenSet()); - } - if (!::customCompressLevel.hasBeenSet()) { - // Default to CustomCompressLevel=1 if CompressLevel is used. - customCompressLevel = ::compressLevel.hasBeenSet(); - } - - sectypes = SecurityClient::secTypes.getDefaultStr(); - secTypes = parseSecTypes(sectypes); - delete [] sectypes; -} - - -void CConnOptions::readFromFile(const char* filename) { - FILE* f = fopen(filename, "r"); - if (!f) - throw rdr::Exception("Failed to read configuration file"); - - try { - char line[4096]; - CharArray section; - - CharArray hostTmp; - int portTmp = 0; - - while (!feof(f)) { - // Read the next line - if (!fgets(line, sizeof(line), f)) { - if (feof(f)) - break; - throw rdr::SystemException("fgets", ferror(f)); - } - int len=strlen(line); - if (line[len-1] == '\n') { - line[len-1] = 0; - len--; - } - - // Process the line - if (line[0] == ';') { - // Comment - } else if (line[0] == '[') { - // Entering a new section - if (!strSplit(&line[1], ']', §ion.buf, 0)) - throw rdr::Exception("bad Section"); - } else { - // Reading an option - CharArray name; - CharArray value; - if (!strSplit(line, '=', &name.buf, &value.buf)) - throw rdr::Exception("bad Name/Value pair"); - - if (stricmp(section.buf, "Connection") == 0) { - if (stricmp(name.buf, "Host") == 0) { - hostTmp.replaceBuf(value.takeBuf()); - } else if (stricmp(name.buf, "Port") == 0) { - portTmp = atoi(value.buf); - } else if (stricmp(name.buf, "UserName") == 0) { - userName.replaceBuf(value.takeBuf()); - } else if (stricmp(name.buf, "Password") == 0) { - ObfuscatedPasswd obfPwd; - rdr::HexInStream::hexStrToBin(value.buf, (char**)&obfPwd.buf, &obfPwd.length); - PlainPasswd passwd(obfPwd); - password.replaceBuf(passwd.takeBuf()); - } - } else if (stricmp(section.buf, "Options") == 0) { - // V4 options - if (stricmp(name.buf, "UseLocalCursor") == 0) { - useLocalCursor = atoi(value.buf); - } else if (stricmp(name.buf, "UseDesktopResize") == 0) { - useDesktopResize = atoi(value.buf); - } else if (stricmp(name.buf, "FullScreen") == 0) { - fullScreen = atoi(value.buf); - } else if (stricmp(name.buf, "FullColour") == 0) { - fullColour = atoi(value.buf); - } else if (stricmp(name.buf, "LowColourLevel") == 0) { - lowColourLevel = atoi(value.buf); - } else if (stricmp(name.buf, "PreferredEncoding") == 0) { - preferredEncoding = encodingNum(value.buf); - } else if ((stricmp(name.buf, "AutoDetect") == 0) || - (stricmp(name.buf, "AutoSelect") == 0)) { - autoSelect = atoi(value.buf); - } else if (stricmp(name.buf, "Shared") == 0) { - shared = atoi(value.buf); - } else if (stricmp(name.buf, "SendPtrEvents") == 0) { - sendPtrEvents = atoi(value.buf); - } else if (stricmp(name.buf, "SendKeyEvents") == 0) { - sendKeyEvents = atoi(value.buf); - } else if (stricmp(name.buf, "SendCutText") == 0) { - clientCutText = atoi(value.buf); - } else if (stricmp(name.buf, "AcceptCutText") == 0) { - serverCutText = atoi(value.buf); - } else if (stricmp(name.buf, "DisableWinKeys") == 0) { - disableWinKeys = atoi(value.buf); - } else if (stricmp(name.buf, "AcceptBell") == 0) { - acceptBell = atoi(value.buf); - } else if (stricmp(name.buf, "Emulate3") == 0) { - emulate3 = atoi(value.buf); - } else if (stricmp(name.buf, "ShowToolbar") == 0) { - showToolbar = atoi(value.buf); - } else if (stricmp(name.buf, "PointerEventInterval") == 0) { - pointerEventInterval = atoi(value.buf); - } else if (stricmp(name.buf, "Monitor") == 0) { - monitor.replaceBuf(value.takeBuf()); - } else if (stricmp(name.buf, "MenuKey") == 0) { - setMenuKey(value.buf); - } else if (stricmp(name.buf, "AutoReconnect") == 0) { - autoReconnect = atoi(value.buf); - - } else if (stricmp(name.buf, "CustomCompressLevel") == 0) { - customCompressLevel = atoi(value.buf); - } else if (stricmp(name.buf, "CompressLevel") == 0) { - compressLevel = atoi(value.buf); - } else if (stricmp(name.buf, "NoJPEG") == 0) { - noJpeg = atoi(value.buf); - } else if (stricmp(name.buf, "QualityLevel") == 0) { - qualityLevel = atoi(value.buf); - // Legacy options - } else if (stricmp(name.buf, "Preferred_Encoding") == 0) { - preferredEncoding = atoi(value.buf); - } else if (stricmp(name.buf, "8bit") == 0) { - fullColour = !atoi(value.buf); - } else if (stricmp(name.buf, "FullScreen") == 0) { - fullScreen = atoi(value.buf); - } else if (stricmp(name.buf, "ViewOnly") == 0) { - sendPtrEvents = sendKeyEvents = !atoi(value.buf); - } else if (stricmp(name.buf, "DisableClipboard") == 0) { - clientCutText = serverCutText = !atoi(value.buf); - } else if (stricmp(name.buf, "AutoScaling") == 0) { - autoScaling = atoi(value.buf); - } else if (stricmp(name.buf, "Scale") == 0) { - scale = atoi(value.buf); - } else if (stricmp(name.buf, "SecurityTypes") == 0) { - secTypes = parseSecTypes(value.buf); - } - } - } - } - fclose(f); f=0; - - // Process the Host and Port - if (hostTmp.buf) { - int hostLen = strlen(hostTmp.buf) + 2 + 17; - host.replaceBuf(new char[hostLen]); - strCopy(host.buf, hostTmp.buf, hostLen); - if (portTmp) { - strncat(host.buf, "::", hostLen-1); - char tmp[16]; - sprintf(tmp, "%d", portTmp); - strncat(host.buf, tmp, hostLen-1); - } - } - - // If AutoSelect is enabled then override the preferred encoding - if (autoSelect) - preferredEncoding = encodingZRLE; - - setConfigFileName(filename); - } catch (rdr::Exception&) { - if (f) fclose(f); - throw; - } -} - -void CConnOptions::writeToFile(const char* filename) { - FILE* f = fopen(filename, "w"); - if (!f) - throw rdr::Exception("Failed to write configuration file"); - - try { - // - Split server into host and port and save - fprintf(f, "[Connection]\n"); - - fprintf(f, "Host=%s\n", host.buf); - if (userName.buf) - fprintf(f, "UserName=%s\n", userName.buf); - if (password.buf) { - // - Warn the user before saving the password - if (MsgBox(0, _T("Do you want to include the VNC Password in this configuration file?\n") - _T("Storing the password is more convenient but poses a security risk."), - MB_YESNO | MB_DEFBUTTON2 | MB_ICONWARNING) == IDYES) { - ObfuscatedPasswd obfPwd(password); - CharArray obfuscatedHex(rdr::HexOutStream::binToHexStr(obfPwd.buf, obfPwd.length)); - fprintf(f, "Password=%s\n", obfuscatedHex.buf); - } - } - - // - Save the other options - fprintf(f, "[Options]\n"); - - fprintf(f, "UseLocalCursor=%d\n", (int)useLocalCursor); - fprintf(f, "UseDesktopResize=%d\n", (int)useDesktopResize); - fprintf(f, "FullScreen=%d\n", (int)fullScreen); - fprintf(f, "FullColour=%d\n", (int)fullColour); - fprintf(f, "LowColourLevel=%d\n", lowColourLevel); - fprintf(f, "PreferredEncoding=%s\n", encodingName(preferredEncoding)); - fprintf(f, "AutoSelect=%d\n", (int)autoSelect); - fprintf(f, "Shared=%d\n", (int)shared); - fprintf(f, "SendPtrEvents=%d\n", (int)sendPtrEvents); - fprintf(f, "SendKeyEvents=%d\n", (int)sendKeyEvents); - fprintf(f, "SendCutText=%d\n", (int)clientCutText); - fprintf(f, "AcceptCutText=%d\n", (int)serverCutText); - fprintf(f, "DisableWinKeys=%d\n", (int)disableWinKeys); - fprintf(f, "AcceptBell=%d\n", (int)acceptBell); - fprintf(f, "Emulate3=%d\n", (int)emulate3); - fprintf(f, "ShowToolbar=%d\n", (int)showToolbar); - fprintf(f, "PointerEventInterval=%d\n", pointerEventInterval); - if (monitor.buf) - fprintf(f, "Monitor=%s\n", monitor.buf); - fprintf(f, "MenuKey=%s\n", CharArray(menuKeyName()).buf); - fprintf(f, "AutoReconnect=%d\n", (int)autoReconnect); - fprintf(f, "CustomCompressLevel=%d\n", customCompressLevel); - fprintf(f, "CompressLevel=%d\n", compressLevel); - fprintf(f, "NoJPEG=%d\n", noJpeg); - fprintf(f, "QualityLevel=%d\n", qualityLevel); - fprintf(f, "AutoScaling=%d\n", (int)autoScaling); - fprintf(f, "Scale=%d\n", scale); - - fprintf(f, "SecurityTypes="); - std::list::iterator i; - for (i = secTypes.begin(); i != secTypes.end(); i++) - fprintf(f, "%s,", secTypeName(*i)); - fprintf(f, "\n"); - - fclose(f); f=0; - - setConfigFileName(filename); - } catch (rdr::Exception&) { - if (f) fclose(f); - throw; - } -} - - -void CConnOptions::writeDefaults() { - RegKey key; - key.createKey(HKEY_CURRENT_USER, _T("Software\\TigerVNC\\VNCviewer4")); - key.setBool(_T("UseLocalCursor"), useLocalCursor); - key.setBool(_T("UseDesktopResize"), useDesktopResize); - key.setBool(_T("FullScreen"), fullScreen); - key.setBool(_T("FullColour"), fullColour); - key.setInt(_T("LowColourLevel"), lowColourLevel); - key.setString(_T("PreferredEncoding"), TStr(encodingName(preferredEncoding))); - key.setBool(_T("AutoSelect"), autoSelect); - key.setBool(_T("Shared"), shared); - key.setBool(_T("SendPointerEvents"), sendPtrEvents); - key.setBool(_T("SendKeyEvents"), sendKeyEvents); - key.setBool(_T("ClientCutText"), clientCutText); - key.setBool(_T("ServerCutText"), serverCutText); - key.setBool(_T("DisableWinKeys"), disableWinKeys); - key.setBool(_T("Protocol3.3"), protocol3_3); - key.setBool(_T("AcceptBell"), acceptBell); - key.setBool(_T("ShowToolbar"), showToolbar); - key.setBool(_T("Emulate3"), emulate3); - key.setInt(_T("PointerEventInterval"), pointerEventInterval); - if (monitor.buf) - key.setString(_T("Monitor"), TStr(monitor.buf)); - key.setString(_T("MenuKey"), TCharArray(menuKeyName()).buf); - key.setBool(_T("AutoReconnect"), autoReconnect); - key.setInt(_T("CustomCompressLevel"), customCompressLevel); - key.setInt(_T("CompressLevel"), compressLevel); - key.setInt(_T("NoJPEG"), noJpeg); - key.setInt(_T("QualityLevel"), qualityLevel); - key.setBool(_T("AutoScaling"), autoScaling); - key.setInt(_T("Scale"), scale); -} - - -void CConnOptions::setUserName(const char* user) {userName.replaceBuf(strDup(user));} -void CConnOptions::setPassword(const char* pwd) {password.replaceBuf(strDup(pwd));} -void CConnOptions::setConfigFileName(const char* cfn) {configFileName.replaceBuf(strDup(cfn));} -void CConnOptions::setHost(const char* h) {host.replaceBuf(strDup(h));} -void CConnOptions::setMonitor(const char* m) {monitor.replaceBuf(strDup(m));} - -void CConnOptions::setMenuKey(const char* keyName) { - if (!keyName[0]) { - menuKey = 0; - } else { - menuKey = VK_F8; - if (keyName[0] == 'F') { - UINT fKey = atoi(&keyName[1]); - if (fKey >= 1 && fKey <= 12) - menuKey = fKey-1 + VK_F1; - } - } -} -char* CConnOptions::menuKeyName() { - int fNum = (menuKey-VK_F1)+1; - if (fNum<1 || fNum>12) - return strDup(""); - CharArray menuKeyStr(4); - sprintf(menuKeyStr.buf, "F%d", fNum); - return menuKeyStr.takeBuf(); -} - - -CConnOptions& CConnOptions::operator=(const CConnOptions& o) { - useLocalCursor = o.useLocalCursor; - useDesktopResize = o.useDesktopResize; - fullScreen = o.fullScreen; - fullColour = o.fullColour; - lowColourLevel = o.lowColourLevel; - preferredEncoding = o.preferredEncoding; - autoSelect = o.autoSelect; - shared = o.shared; - sendPtrEvents = o.sendPtrEvents; - sendKeyEvents = o.sendKeyEvents; - clientCutText = o.clientCutText; - serverCutText = o.serverCutText; - disableWinKeys = o.disableWinKeys; - emulate3 = o.emulate3; - pointerEventInterval = o.pointerEventInterval; - protocol3_3 = o.protocol3_3; - acceptBell = o.acceptBell; - showToolbar = o.showToolbar; - setUserName(o.userName.buf); - setPassword(o.password.buf); - setConfigFileName(o.configFileName.buf); - setHost(o.host.buf); - setMonitor(o.monitor.buf); - menuKey = o.menuKey; - autoReconnect = o.autoReconnect; - customCompressLevel = o.customCompressLevel; - compressLevel = o.compressLevel; - noJpeg = o.noJpeg; - qualityLevel = o.qualityLevel; - autoScaling = o.autoScaling; - scale = o.scale; - secTypes = o.secTypes; - - return *this; -} diff --git a/win/vncviewer/CConnOptions.h b/win/vncviewer/CConnOptions.h deleted file mode 100644 index 76f0d68e..00000000 --- a/win/vncviewer/CConnOptions.h +++ /dev/null @@ -1,104 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -// -=- CConnOptions.h - -// Definition of the CConnOptions class, responsible for storing the -// current & requested VNC Viewer options. - -#ifndef __RFB_WIN32_CCONN_OPTIONS_H__ -#define __RFB_WIN32_CCONN_OPTIONS_H__ - -#include -#include - -#include - -namespace rfb { - - namespace win32 { - - // - // -=- Options structure. Each viewer option has a corresponding - // entry in CConnOptions. The viewer options are set by calling - // CConn::applyOptions(...) - // The CConnOptions structure automatically picks up the default - // value of each option from the Configuration system - // The readFromFile and writeFromFile methods can be used to load - // and save VNC configuration files. readFromFile is backwards - // compatible with 3.3 releases, while writeToFile is not. - - class CConnOptions { - public: - CConnOptions(); - CConnOptions(const CConnOptions& o) {operator=(o);} - CConnOptions& operator=(const CConnOptions& o); - void readFromFile(const char* filename_); - void writeToFile(const char* filename_); - void writeDefaults(); - bool useLocalCursor; - bool useDesktopResize; - bool fullScreen; - bool fullColour; - int lowColourLevel; - int preferredEncoding; - bool autoSelect; - bool shared; - CharArray desktopSize; - bool sendPtrEvents; - bool sendKeyEvents; - bool showToolbar; - bool clientCutText; - bool serverCutText; - bool disableWinKeys; - bool emulate3; - int pointerEventInterval; - bool protocol3_3; - bool acceptBell; - bool autoScaling; - int scale; - std::list secTypes; - CharArray userName; - void setUserName(const char* user); - PlainPasswd password; - void setPassword(const char* pwd); - CharArray configFileName; - void setConfigFileName(const char* cfn); - CharArray host; - void setHost(const char* h); - CharArray monitor; - void setMonitor(const char* m); - unsigned int menuKey; - void setMenuKey(const char* keyName); - char* menuKeyName(); - bool autoReconnect; - - bool customCompressLevel; - int compressLevel; - bool noJpeg; - int qualityLevel; - - CharArray passwordFile; - }; - - - }; - -}; - -#endif diff --git a/win/vncviewer/CConnThread.cxx b/win/vncviewer/CConnThread.cxx deleted file mode 100644 index ea3a20a4..00000000 --- a/win/vncviewer/CConnThread.cxx +++ /dev/null @@ -1,197 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -// -=- CConnThread.cxx - -// A CConnThread instance is created for each new connection. -// The CConnThread creates the corresponding CConn instance -// and manages it. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace rfb; -using namespace win32; - -static LogWriter vlog("CConnThread"); - -static std::set threads; -static Mutex threadsLock; -static Handle noMoreThreads(CreateEvent(0, TRUE, FALSE, 0)); - - -CConnThread::CConnThread() : Thread("CConnThread"), isConfig(false), - sock(0), reverse(false) { - vlog.info("CConnThread (dialog)"); - setDeleteAfterRun(); - Lock l(threadsLock); - threads.insert(this); - start(); -} - -CConnThread::CConnThread(const char* hostOrConfig_, bool isConfig_) - : Thread("CConnThread"), hostOrConfig(strDup(hostOrConfig_)), - isConfig(isConfig_), sock(0), reverse(false) { - vlog.info("CConnThread (host/port)"); - setDeleteAfterRun(); - Lock l(threadsLock); - threads.insert(this); - start(); -} - -CConnThread::CConnThread(network::Socket* sock_, bool reverse_) - : Thread("CConnThread"), isConfig(false), sock(sock_), reverse(reverse_) { - vlog.info("CConnThread (reverse connection)"); - setDeleteAfterRun(); - Lock l(threadsLock); - threads.insert(this); - start(); -} - -CConnThread::~CConnThread() { - Lock l(threadsLock); - threads.erase(this); - if (threads.empty()) - SetEvent(noMoreThreads); - delete sock; -} - - -void CConnThread::run() { - CConnOptions options; - bool reconnect; - - do { - { - CConn conn; - reconnect = false; - - // If there is no socket object then set the host & port info - if (!sock && !options.host.buf) { - try { - if (isConfig) { - // A configuration file name was specified - load it - CharArray filename(hostOrConfig.takeBuf()); - options.readFromFile(filename.buf); - } else { - // An actual hostname (and possibly port) was specified - options.host.replaceBuf(hostOrConfig.takeBuf()); - } - - if (!options.host.buf) { - // No host was specified - prompt for one - ConnectionDialog connDlg(&conn); - if (!connDlg.showDialog()) - return; - options = conn.getOptions(); - options.setHost(CStr(connDlg.hostname.buf)); - } - } catch (rdr::Exception& e) { - MsgBox(0, TStr(e.str()), MB_ICONERROR | MB_OK); - return; - } - } - - // Apply the connection options to the CConn - conn.applyOptions(options); - - if (!sock) { - // There is no existing connection - better make one - const char* hostAndPort = conn.getOptions().host.buf; - - try { - ConnectingDialog dlg; - sock = dlg.connect(hostAndPort); - - // If the connection was cancelled by the user, just quit - if (!sock) - return; - } catch(rdr::Exception& e) { - MsgBox(NULL, TStr(e.str()), MB_ICONERROR | MB_OK); - return; - } - - // Try to add the caller to the MRU - MRU::addToMRU(hostAndPort); - } - - // Run the RFB protocol over the connected socket - conn.initialise(sock, reverse); - while (!conn.isClosed()) { - try { - conn.getInStream()->check(1,1); - conn.processMsg(); - } catch (rdr::EndOfStream) { - if (conn.state() == CConnection::RFBSTATE_NORMAL) - conn.close(); - else - conn.close("The connection closed unexpectedly"); - } catch (rfb::AuthCancelledException) { - conn.close(); - } catch (rfb::AuthFailureException& e) { - // Clear the password, in case we auto-reconnect - options = conn.getOptions(); - options.password.replaceBuf(0); - conn.applyOptions(options); - conn.close(e.str()); - } catch (rdr::Exception& e) { - conn.close(e.str()); - } - } - - // If there is a cause for closing the connection logged then display it - if (conn.closeReason()) { - reconnect = !reverse && conn.getOptions().autoReconnect; - if (!reconnect) { - MsgBox(0, TStr(conn.closeReason()), MB_ICONINFORMATION | MB_OK); - } else { - options = conn.getOptions(); - const char* format = "%s\nDo you wish to attempt to reconnect to %s?"; - CharArray message(strlen(conn.closeReason()) + strlen(format) + - strlen(conn.getOptions().host.buf)); - sprintf(message.buf, format, conn.closeReason(), conn.getOptions().host.buf); - if (MsgBox(0, TStr(message.buf), MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2) != IDYES) - reconnect = false; - } - } - } // Exit the CConn's scope, implicitly destroying it & making it safe to delete the TcpSocket - - // Clean up the old socket, if any - delete sock; sock = 0; - } while (reconnect); -} - - -BOOL CConnThread::getMessage(MSG* msg, HWND hwnd, UINT minMsg, UINT maxMsg) { - while (!PeekMessage(msg, hwnd, minMsg, maxMsg, PM_REMOVE)) { - DWORD result = MsgWaitForMultipleObjects(1, &noMoreThreads.h, FALSE, INFINITE, QS_ALLINPUT); - if (result == WAIT_OBJECT_0) - return FALSE; - else if (result == WAIT_FAILED) - throw rdr::SystemException("CConnThread::getMessage wait failed", GetLastError()); - } - return msg->message != WM_QUIT; -} diff --git a/win/vncviewer/CConnThread.h b/win/vncviewer/CConnThread.h deleted file mode 100644 index 7a8451c1..00000000 --- a/win/vncviewer/CConnThread.h +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -// -=- CConnThread.h - -// CConn-managing Thread implementation. - -#ifndef __RFB_WIN32_CCONN_THREAD_H__ -#define __RFB_WIN32_CCONN_THREAD_H__ - -#include -#include -#include - -namespace rfb { - - namespace win32 { - - class CConnThread : public Thread { - public: - CConnThread(); - CConnThread(const char* hostOrConfig, bool isConfig=false); - CConnThread(network::Socket* sock, bool reverse=false); - ~CConnThread(); - - void run(); - - // Special getMessage call that returns FALSE if message is WM_QUIT, - // OR if there are no more CConnThreads running. - static BOOL getMessage(MSG* msg, HWND hwnd, UINT minMsg, UINT maxMsg); - protected: - CharArray hostOrConfig; - bool isConfig; - network::Socket* sock; - bool reverse; - }; - - }; - -}; - -#endif // __RFB_WIN32_CCONN_THREAD_H__ diff --git a/win/vncviewer/CMakeLists.txt b/win/vncviewer/CMakeLists.txt deleted file mode 100644 index 7870a01e..00000000 --- a/win/vncviewer/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -include_directories(${CMAKE_BINARY_DIR}/win) - -# Disable auto-generated manifests, since we have our own -if(MSVC) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /MANIFEST:NO") -endif() - -add_executable(vncviewer WIN32 - buildTime.cxx - CConn.cxx - CConnOptions.cxx - CConnThread.cxx - ConnectingDialog.cxx - ConnectionDialog.cxx - DesktopWindow.cxx - InfoDialog.cxx - OptionsDialog.cxx - UserPasswdDialog.cxx - ViewerToolBar.cxx - vncviewer.cxx - vncviewer.rc) - -set(VNCVIEWER_LIBRARIES rfb rfb_win32 Xregion network rdr) - -# When building with GnuTLS, librdr depends on ws2_32, so in order to make -# MinGW happy, we need to put ws2_32 in librdr's target_link_libraries string, -# not here. -if(NOT GNUTLS_FOUND) - set(VNCVIEWER_LIBRARIES ${VNCVIEWER_LIBRARIES} ws2_32) -endif() - -target_link_libraries(vncviewer ${VNCVIEWER_LIBRARIES}) - -install(TARGETS vncviewer - RUNTIME DESTINATION . -) diff --git a/win/vncviewer/ConnectingDialog.cxx b/win/vncviewer/ConnectingDialog.cxx deleted file mode 100644 index 7f52e991..00000000 --- a/win/vncviewer/ConnectingDialog.cxx +++ /dev/null @@ -1,161 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * Copyright (C) 2010 D. R. Commander. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -// -=- ConnectingDialog.cxx - -#include -#include -#include -#include -#include -#include -#include - -using namespace rfb; -using namespace rfb::win32; - - -// ConnectingDialog callback -static INT_PTR CALLBACK ConnectingDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { - bool* activePtr = (bool*)GetWindowLongPtr(hwnd, GWLP_USERDATA); - switch (uMsg) { - case WM_INITDIALOG: - SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam); - return TRUE; - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDCANCEL: - if (activePtr) - *activePtr = false; - return TRUE; - } - break; - case WM_DESTROY: - if (activePtr) - *activePtr = false; - return TRUE; - } - return 0; -} - - -// Global map, used by ConnectingDialog::Threads to call back to their owning -// ConnectingDialogs, while coping with the fact that the owner may already have quit. -static std::map dialogs; -static int nextDialogId = 0; -static Mutex dialogsLock; - - -// ConnectingDialog::Thread -// Attempts to connect to the specified host. If the connection succeeds, the -// socket is saved in the owning ConnectingDialog, if still available, and the -// event is signalled. If the connection fails, the Exception text is returned -// to the dialog. If the dialog is already gone, the Exception/socket are discarded. -// NB: This thread class cleans itself up on exit - DO NOT join()! -class ConnectingDialog::Thread : public rfb::Thread { -public: - Thread(int dialogId_, const char* hostAndPort) : dialogId(dialogId_) { - setDeleteAfterRun(); - getHostAndPort(hostAndPort, &host.buf, &port); - } - virtual void run() { - try { - returnSock(new network::TcpSocket(host.buf, port)); - } catch (rdr::Exception& e) { - returnException(e); - } - } - void returnSock(network::Socket* s) { - Lock l(dialogsLock); - if (dialogs.count(dialogId)) { - dialogs[dialogId]->newSocket = s; - SetEvent(dialogs[dialogId]->readyEvent); - } else { - delete s; - } - } - void returnException(const rdr::Exception& e) { - Lock l(dialogsLock); - if (dialogs.count(dialogId)) { - dialogs[dialogId]->errMsg.replaceBuf(strDup(e.str())); - SetEvent(dialogs[dialogId]->readyEvent); - } - }; - CharArray host; - int port; - int dialogId; -}; - - -ConnectingDialog::ConnectingDialog() : dialog(0), newSocket(0), - readyEvent(CreateEvent(0, TRUE, FALSE, 0)), dialogId(0) { -} - -network::Socket* ConnectingDialog::connect(const char* hostAndPort) { - Thread* connectThread = 0; - bool active = true; - errMsg.replaceBuf(0); - newSocket = 0; - - // Get a unique dialog identifier and create the dialog window - { - Lock l(dialogsLock); - dialogId = ++nextDialogId; - dialogs[dialogId] = this; - dialog = CreateDialogParam(GetModuleHandle(0), - MAKEINTRESOURCE(IDD_CONNECTING_DLG), 0, &ConnectingDlgProc, (LONG_PTR)&active); - ShowWindow(dialog, SW_SHOW); - ResetEvent(readyEvent); - } - - // Create and start the connection thread - try { - connectThread = new Thread(dialogId, hostAndPort); - connectThread->start(); - } catch (rdr::Exception& e) { - errMsg.replaceBuf(strDup(e.str())); - active = false; - } - - // Process window messages until the connection thread signals readyEvent, or the dialog is cancelled - while (active && (MsgWaitForMultipleObjects(1, &readyEvent.h, FALSE, INFINITE, QS_ALLINPUT) == WAIT_OBJECT_0 + 1)) { - MSG msg; - while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) - DispatchMessage(&msg); - } - - // Remove this dialog from the table - // NB: If the dialog was cancelled then the thread is still running, and will only - // discover that we're gone when it looks up our unique Id in the dialog table. - { - Lock l(dialogsLock); - dialogs.erase(dialogId); - } - - // Close the dialog window - DestroyWindow(dialog); dialog=0; - - // Throw the exception, if there was one - if (errMsg.buf) - throw rdr::Exception(errMsg.buf); - - // Otherwise, return the socket - // NB: The socket will be null if the dialog was cancelled - return newSocket; -} diff --git a/win/vncviewer/ConnectingDialog.h b/win/vncviewer/ConnectingDialog.h deleted file mode 100644 index c38b3a1b..00000000 --- a/win/vncviewer/ConnectingDialog.h +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -// -=- ConnectingDialog.h - -// ConnectingDialog instances are used to display a status dialog while a -// connection attempt is in progress. The connection attempt is performed -// in a background thread by the ConnectingDialog, to allow the status dialog -// to remain interactive. If the dialog is cancelled then it will close and -// the connection dialog will eventually tidy itself up. - -#ifndef __RFB_WIN32_CONNECTING_DLG_H__ -#define __RFB_WIN32_CONNECTING_DLG_H__ - -#include -#include -#include -#include - -namespace rfb { - - namespace win32 { - - class ConnectingDialog { - public: - ConnectingDialog(); - - // connect - // Show a Connecting dialog and attempt to connect to the specified host - // in the background. - // If the connection succeeds then the Socket is returned. - // If an error occurs, an Exception is thrown. - // If the dialog is cancelled then null is returned. - network::Socket* connect(const char* hostAndPort); - protected: - HWND dialog; - network::Socket* newSocket; - CharArray errMsg; - Handle readyEvent; - int dialogId; - - class Thread; - friend class Thread; - }; - - }; - -}; - -#endif diff --git a/win/vncviewer/ConnectionDialog.cxx b/win/vncviewer/ConnectionDialog.cxx deleted file mode 100644 index e73e8ec1..00000000 --- a/win/vncviewer/ConnectionDialog.cxx +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -#include -#include -#include -#include - -#include - -using namespace rfb; -using namespace rfb::win32; - - -ConnectionDialog::ConnectionDialog(CConn* conn_) : Dialog(GetModuleHandle(0)), conn(conn_) { -} - - -bool ConnectionDialog::showDialog() { - return Dialog::showDialog(MAKEINTRESOURCE(IDD_CONNECTION_DLG)); -} - -void ConnectionDialog::initDialog() { - HWND box = GetDlgItem(handle, IDC_SERVER_EDIT); - - std::list mru = MRU::getEntries(); - std::list::iterator i; - - // Locate the combo-box - // NB: TCharArray converts the supplied char* and assumes ownership! - for (i=mru.begin(); i!=mru.end(); i++) { - SendMessage(box, CB_ADDSTRING, 0, (LPARAM)TCharArray(*i).buf); - } - - // Select the first item in the list - SendMessage(box, CB_SETCURSEL, 0, 0); -} - - -bool ConnectionDialog::onOk() { - delete [] hostname.buf; - hostname.buf = 0; - hostname.buf = getItemString(IDC_SERVER_EDIT); - return hostname.buf[0] != 0; -} - -bool ConnectionDialog::onCommand(int id, int cmd) { - switch (id) { - case IDC_ABOUT: - AboutDialog::instance.showDialog(); - return true; - case IDC_OPTIONS: - conn->showOptionsDialog(); - return true; - }; - return false; -} diff --git a/win/vncviewer/ConnectionDialog.h b/win/vncviewer/ConnectionDialog.h deleted file mode 100644 index f739280c..00000000 --- a/win/vncviewer/ConnectionDialog.h +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -// -=- ConnectionDialog.h - -// Connection dialog for VNC Viewer 4.0 - -#ifndef __RFB_WIN32_CONN_DIALOG_H__ -#define __RFB_WIN32_CONN_DIALOG_H__ - -#include -#include -#include - -namespace rfb { - - namespace win32 { - - class CConn; - - class ConnectionDialog : Dialog { - public: - ConnectionDialog(CConn* view); - virtual bool showDialog(); - virtual void initDialog(); - virtual bool onOk(); - virtual bool onCommand(int id, int cmd); - TCharArray hostname; - protected: - CConn* conn; - }; - - }; - -}; - -#endif diff --git a/win/vncviewer/DesktopWindow.cxx b/win/vncviewer/DesktopWindow.cxx deleted file mode 100644 index fee0a1b0..00000000 --- a/win/vncviewer/DesktopWindow.cxx +++ /dev/null @@ -1,1350 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * Copyright (C) 2010-2011 D. R. Commander. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace rfb; -using namespace rfb::win32; - - -// - Statics & consts - -static LogWriter vlog("DesktopWindow"); - -const int TIMER_BUMPSCROLL = 1; -const int TIMER_POINTER_INTERVAL = 2; -const int TIMER_POINTER_3BUTTON = 3; -const int TIMER_UPDATE = 4; - - -// -// -=- DesktopWindowClass - -// -// Window class used as the basis for all DesktopWindow instances -// - -class DesktopWindowClass { -public: - DesktopWindowClass(); - ~DesktopWindowClass(); - ATOM classAtom; - HINSTANCE instance; -}; - -LRESULT CALLBACK DesktopWindowProc(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam) { - LRESULT result = 0; - if (msg == WM_CREATE) - SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG_PTR)((CREATESTRUCT*)lParam)->lpCreateParams); - else if (msg == WM_DESTROY) - SetWindowLongPtr(wnd, GWLP_USERDATA, 0); - DesktopWindow* _this = (DesktopWindow*) GetWindowLongPtr(wnd, GWLP_USERDATA); - if (!_this) { - vlog.info("null _this in %x, message %u", wnd, msg); - return rfb::win32::SafeDefWindowProc(wnd, msg, wParam, lParam); - } - - try { - result = _this->processMessage(msg, wParam, lParam); - } catch (rfb::UnsupportedPixelFormatException &e) { - MsgBox(0, (TCHAR *) e.str(), MB_OK | MB_ICONINFORMATION); - _this->getCallback()->closeWindow(); - } catch (rdr::Exception& e) { - vlog.error("untrapped: %s", e.str()); - } - - return result; -}; - -static HCURSOR dotCursor = (HCURSOR)LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDC_DOT_CURSOR), IMAGE_CURSOR, 0, 0, LR_SHARED); -static HCURSOR arrowCursor = (HCURSOR)LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED); - -DesktopWindowClass::DesktopWindowClass() : classAtom(0) { - WNDCLASS wndClass; - wndClass.style = 0; - wndClass.lpfnWndProc = DesktopWindowProc; - wndClass.cbClsExtra = 0; - wndClass.cbWndExtra = 0; - wndClass.hInstance = instance = GetModuleHandle(0); - wndClass.hIcon = (HICON)LoadImage(GetModuleHandle(0), MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 0, 0, LR_SHARED); - if (!wndClass.hIcon) - printf("unable to load icon:%ld", GetLastError()); - wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); - wndClass.hbrBackground = NULL; - wndClass.lpszMenuName = 0; - wndClass.lpszClassName = _T("rfb::win32::DesktopWindowClass"); - classAtom = RegisterClass(&wndClass); - if (!classAtom) { - throw rdr::SystemException("unable to register DesktopWindow window class", GetLastError()); - } -} - -DesktopWindowClass::~DesktopWindowClass() { - if (classAtom) { - UnregisterClass((const TCHAR*)classAtom, instance); - } -} - -static DesktopWindowClass baseClass; - -// -// -=- FrameClass - -// -// Window class used for child windows that display pixel data -// - -class FrameClass { -public: - FrameClass(); - ~FrameClass(); - ATOM classAtom; - HINSTANCE instance; -}; - -LRESULT CALLBACK FrameProc(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam) { - LRESULT result = 0; - if (msg == WM_CREATE) - SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG_PTR)((CREATESTRUCT*)lParam)->lpCreateParams); - else if (msg == WM_DESTROY) - SetWindowLongPtr(wnd, GWLP_USERDATA, 0); - DesktopWindow* _this = (DesktopWindow*) GetWindowLongPtr(wnd, GWLP_USERDATA); - if (!_this) { - vlog.info("null _this in %x, message %u", wnd, msg); - return rfb::win32::SafeDefWindowProc(wnd, msg, wParam, lParam); - } - - try { - result = _this->processFrameMessage(msg, wParam, lParam); - } catch (rdr::Exception& e) { - vlog.error("untrapped: %s", e.str()); - } - - return result; -} - -FrameClass::FrameClass() : classAtom(0) { - WNDCLASS wndClass; - wndClass.style = 0; - wndClass.lpfnWndProc = FrameProc; - wndClass.cbClsExtra = 0; - wndClass.cbWndExtra = 0; - wndClass.hInstance = instance = GetModuleHandle(0); - wndClass.hIcon = 0; - wndClass.hCursor = NULL; - wndClass.hbrBackground = NULL; - wndClass.lpszMenuName = 0; - wndClass.lpszClassName = _T("rfb::win32::FrameClass"); - classAtom = RegisterClass(&wndClass); - if (!classAtom) { - throw rdr::SystemException("unable to register Frame window class", GetLastError()); - } -} - -FrameClass::~FrameClass() { - if (classAtom) { - UnregisterClass((const TCHAR*)classAtom, instance); - } -} - -FrameClass frameClass; - - -// -// -=- DesktopWindow instance implementation -// - -DesktopWindow::DesktopWindow(Callback* cb) - : bumpScroll(false), palette_changed(false), fullscreenActive(false), - fullscreenRestore(false), systemCursorVisible(true), trackingMouseLeave(false), - cursorInBuffer(false), cursorVisible(false), cursorAvailable(false), - internalSetCursor(false), cursorImage(0), cursorMask(0), - cursorWidth(0), cursorHeight(0), showToolbar(false), - buffer(0), has_focus(false), autoScaling(false), - window_size(0, 0, 32, 32), client_size(0, 0, 16, 16), handle(0), - frameHandle(0), callback(cb) { - - // Create the window - const char* name = "DesktopWindow"; - handle = CreateWindow((const TCHAR*)baseClass.classAtom, TStr(name), - WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, - 0, 0, 10, 10, 0, 0, baseClass.instance, this); - if (!handle) - throw rdr::SystemException("unable to create WMNotifier window instance", GetLastError()); - vlog.debug("created window \"%s\" (%x)", name, handle); - - // Create the toolbar - tb.create(handle); - vlog.debug("created toolbar window \"%s\" (%x)", "ViewerToolBar", tb.getHandle()); - - // Create the frame window - frameHandle = CreateWindowEx(WS_EX_CLIENTEDGE, (const TCHAR*)frameClass.classAtom, - 0, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, - CW_USEDEFAULT, CW_USEDEFAULT, handle, 0, frameClass.instance, this); - if (!frameHandle) { - throw rdr::SystemException("unable to create rfb frame window instance", GetLastError()); - } - vlog.debug("created window \"%s\" (%x)", "Frame Window", frameHandle); - - // Initialise the CPointer pointer handler - ptr.setHWND(frameHandle); - ptr.setIntervalTimerId(TIMER_POINTER_INTERVAL); - ptr.set3ButtonTimerId(TIMER_POINTER_3BUTTON); - - // Initialise the bumpscroll timer - bumpScrollTimer.setHWND(handle); - bumpScrollTimer.setId(TIMER_BUMPSCROLL); - - // Initialise the update timer - updateTimer.setHWND(handle); - updateTimer.setId(TIMER_UPDATE); - - // Hook the clipboard - clipboard.setNotifier(this); - - // Create the backing buffer - buffer = new win32::ScaledDIBSectionBuffer(frameHandle); - - // Show the window - centerWindow(handle, 0); - ShowWindow(handle, SW_SHOW); -} - -DesktopWindow::~DesktopWindow() { - vlog.debug("~DesktopWindow"); - showSystemCursor(); - if (handle) { - disableLowLevelKeyEvents(handle); - DestroyWindow(handle); - handle = 0; - } - delete buffer; - if (cursorImage) delete [] cursorImage; - if (cursorMask) delete [] cursorMask; - vlog.debug("~DesktopWindow done"); -} - - -void DesktopWindow::setFullscreen(bool fs) { - if (fs && !fullscreenActive) { - fullscreenActive = bumpScroll = true; - - // Un-minimize the window if required - if (GetWindowLong(handle, GWL_STYLE) & WS_MINIMIZE) - ShowWindow(handle, SW_RESTORE); - - // Save the current window position - GetWindowRect(handle, &fullscreenOldRect); - - // Find the size of the virtual display - int cx = GetSystemMetrics(SM_CXVIRTUALSCREEN); - int cy = GetSystemMetrics(SM_CYVIRTUALSCREEN); - int x = GetSystemMetrics(SM_XVIRTUALSCREEN); - int y = GetSystemMetrics(SM_YVIRTUALSCREEN); - - // Hide the toolbar - if (tb.isVisible()) - tb.hide(); - SetWindowLong(frameHandle, GWL_EXSTYLE, 0); - - // Set the window full-screen - DWORD flags = GetWindowLong(handle, GWL_STYLE); - fullscreenOldFlags = flags; - flags = flags & ~(WS_CAPTION | WS_THICKFRAME | WS_MAXIMIZE | WS_MINIMIZE); - vlog.debug("flags=%x", flags); - - SetWindowLong(handle, GWL_STYLE, flags); - SetWindowPos(handle, HWND_TOP, x, y, cx, cy, SWP_FRAMECHANGED); - } else if (!fs && fullscreenActive) { - fullscreenActive = bumpScroll = false; - - // Show the toolbar - if (showToolbar) - tb.show(); - SetWindowLong(frameHandle, GWL_EXSTYLE, WS_EX_CLIENTEDGE); - - // Set the window non-fullscreen - SetWindowLong(handle, GWL_STYLE, fullscreenOldFlags); - - // Set the window position - SetWindowPos(handle, HWND_NOTOPMOST, - fullscreenOldRect.left, fullscreenOldRect.top, - fullscreenOldRect.right - fullscreenOldRect.left, - fullscreenOldRect.bottom - fullscreenOldRect.top, - SWP_FRAMECHANGED); - } - - // Adjust the viewport offset to cope with change in size between FS - // and previous window state. - setViewportOffset(scrolloffset); -} - -void DesktopWindow::setShowToolbar(bool st) -{ - showToolbar = st; - if (fullscreenActive) return; - - RECT r; - GetWindowRect(handle, &r); - bool maximized = GetWindowLong(handle, GWL_STYLE) & WS_MAXIMIZE; - - if (showToolbar && !tb.isVisible()) { - refreshToolbarButtons(); - tb.show(); - if (!maximized) r.bottom += tb.getHeight(); - } else if (!showToolbar && tb.isVisible()) { - tb.hide(); - if (!maximized) r.bottom -= tb.getHeight(); - } - // Resize the chiled windows even if the parent window size - // has not been changed (the main window is maximized) - if (maximized) SendMessage(handle, WM_SIZE, 0, 0); - else SetWindowPos(handle, NULL, 0, 0, r.right-r.left, r.bottom-r.top, SWP_NOMOVE | SWP_NOZORDER); -} - -void DesktopWindow::refreshToolbarButtons() { - int scale = getDesktopScale(); - if (scale <= 10) { - tb.enableButton(ID_ZOOM_IN, true); - tb.enableButton(ID_ZOOM_OUT, false); - } else if (scale >= 200) { - tb.enableButton(ID_ZOOM_IN, false); - tb.enableButton(ID_ZOOM_OUT, true); - } else { - tb.enableButton(ID_ZOOM_IN, true); - tb.enableButton(ID_ZOOM_OUT, true); - } - if (buffer->isScaling() || isAutoScaling()) tb.enableButton(ID_ACTUAL_SIZE, true); - else tb.enableButton(ID_ACTUAL_SIZE, false); - if (isAutoScaling()) tb.pressButton(ID_AUTO_SIZE, true); - else tb.pressButton(ID_AUTO_SIZE, false); -} - -void DesktopWindow::setDisableWinKeys(bool dwk) { - // Enable low-level event hooking, so we get special keys directly - if (dwk) - enableLowLevelKeyEvents(handle); - else - disableLowLevelKeyEvents(handle); -} - - -void DesktopWindow::setMonitor(const char* monitor) { - MonitorInfo mi(monitor); - mi.moveTo(handle); -} - -char* DesktopWindow::getMonitor() const { - MonitorInfo mi(handle); - return strDup(mi.szDevice); -} - - -bool DesktopWindow::setViewportOffset(const Point& tl) { - Point np = Point(__rfbmax(0, __rfbmin(tl.x, buffer->width()-client_size.width())), - __rfbmax(0, __rfbmin(tl.y, buffer->height()-client_size.height()))); - Point delta = np.translate(scrolloffset.negate()); - if (!np.equals(scrolloffset)) { - scrolloffset = np; - ScrollWindowEx(frameHandle, -delta.x, -delta.y, 0, 0, 0, 0, SW_INVALIDATE); - UpdateWindow(frameHandle); - return true; - } - return false; -} - - -bool DesktopWindow::processBumpScroll(const Point& pos) -{ - if (!bumpScroll) return false; - int bumpScrollPixels = 20; - bumpScrollDelta = Point(); - - if (pos.x == client_size.width()-1) - bumpScrollDelta.x = bumpScrollPixels; - else if (pos.x == 0) - bumpScrollDelta.x = -bumpScrollPixels; - if (pos.y == client_size.height()-1) - bumpScrollDelta.y = bumpScrollPixels; - else if (pos.y == 0) - bumpScrollDelta.y = -bumpScrollPixels; - - if (bumpScrollDelta.x || bumpScrollDelta.y) { - if (bumpScrollTimer.isActive()) return true; - if (setViewportOffset(scrolloffset.translate(bumpScrollDelta))) { - bumpScrollTimer.start(25); - return true; - } - } - - bumpScrollTimer.stop(); - return false; -} - - -LRESULT -DesktopWindow::processMessage(UINT msg, WPARAM wParam, LPARAM lParam) { - switch (msg) { - - // -=- Process standard window messages - - case WM_NOTIFY: - if (wParam == ID_TOOLBAR) - tb.processWM_NOTIFY(wParam, lParam); - break; - - case WM_DISPLAYCHANGE: - // Display format has changed - notify callback - callback->displayChanged(); - break; - - // -=- Window position - - // Prevent the window from being resized to be too large if in normal mode. - // If maximized or fullscreen the allow oversized windows. - - case WM_WINDOWPOSCHANGING: - { - WINDOWPOS* wpos = (WINDOWPOS*)lParam; - if ((wpos->flags & SWP_NOSIZE) || isAutoScaling()) - break; - - // Calculate the minimum size of main window - RECT r; - Rect min_size; - int tbMinWidth = 0, tbMinHeight = 0; - if (isToolbarEnabled()) { - tbMinWidth = tb.getTotalWidth(); - tbMinHeight = tb.getHeight(); - SetRect(&r, 0, 0, tbMinWidth, tbMinHeight); - AdjustWindowRect(&r, GetWindowLong(handle, GWL_STYLE), FALSE); - min_size = Rect(r.left, r.top, r.right, r.bottom); - } - - // Work out how big the window should ideally be - DWORD current_style = GetWindowLong(frameHandle, GWL_STYLE); - DWORD style = current_style & ~(WS_VSCROLL | WS_HSCROLL); - DWORD style_ex = GetWindowLong(frameHandle, GWL_EXSTYLE); - - SetRect(&r, 0, 0, buffer->width(), buffer->height()); - AdjustWindowRectEx(&r, style, FALSE, style_ex); - Rect reqd_size = Rect(r.left, r.top, r.right, r.bottom); - if (current_style & WS_VSCROLL) - reqd_size.br.x += GetSystemMetrics(SM_CXVSCROLL); - if (current_style & WS_HSCROLL) - reqd_size.br.y += GetSystemMetrics(SM_CXHSCROLL); - - SetRect(&r, reqd_size.tl.x, reqd_size.tl.y, reqd_size.br.x, reqd_size.br.y); - if (isToolbarEnabled()) - r.bottom += tb.getHeight(); - AdjustWindowRect(&r, GetWindowLong(handle, GWL_STYLE), FALSE); - reqd_size = Rect(r.left, r.top, r.right, r.bottom); - - RECT current; - GetWindowRect(handle, ¤t); - - if (min_size.width() > reqd_size.width()) { - reqd_size.tl.x = min_size.tl.x; - reqd_size.br.x = min_size.br.x; - } - if (min_size.height() > reqd_size.height()) { - reqd_size.tl.y = min_size.tl.y; - reqd_size.br.y = min_size.br.y; - } - - if (!(GetWindowLong(handle, GWL_STYLE) & WS_MAXIMIZE) && !fullscreenActive) { - // Ensure that the window isn't resized too large or too small - if ((wpos->cx < min_size.width()) && isToolbarEnabled()) { - wpos->cx = min_size.width(); - wpos->x = current.left; - } else if ((wpos->cx > reqd_size.width())) { - wpos->cx = reqd_size.width(); - wpos->x = current.left; - } - if ((wpos->cy < min_size.height()) && isToolbarEnabled()) { - wpos->cy = min_size.height(); - wpos->y = current.top; - } else if (wpos->cy > reqd_size.height()) { - wpos->cy = reqd_size.height(); - wpos->y = current.top; - } - } - } - break; - - // Resize child windows and update window size info we have cached. - - case WM_SIZE: - { - Point old_offset = desktopToClient(Point(0, 0)); - RECT r; - - // Resize child windows - GetClientRect(handle, &r); - if (tb.isVisible()) { - MoveWindow(frameHandle, 0, tb.getHeight(), r.right, r.bottom - tb.getHeight(), TRUE); - } else { - MoveWindow(frameHandle, 0, 0, r.right, r.bottom, TRUE); - } - tb.autoSize(); - - // Update the cached sizing information - GetWindowRect(frameHandle, &r); - window_size = Rect(r.left, r.top, r.right, r.bottom); - GetClientRect(frameHandle, &r); - client_size = Rect(r.left, r.top, r.right, r.bottom); - - // Perform the AutoScaling operation - if (isAutoScaling()) { - fitBufferToWindow(false); - } else { - // Determine whether scrollbars are required - calculateScrollBars(); - } - - // Redraw if required - if ((!old_offset.equals(desktopToClient(Point(0, 0)))) || isAutoScaling()) - InvalidateRect(frameHandle, 0, TRUE); - } - break; - - // -=- Bump-scrolling - - case WM_TIMER: - switch (wParam) { - case TIMER_BUMPSCROLL: - if (!setViewportOffset(scrolloffset.translate(bumpScrollDelta))) - bumpScrollTimer.stop(); - break; - case TIMER_POINTER_INTERVAL: - case TIMER_POINTER_3BUTTON: - ptr.handleTimer(callback, wParam); - break; - case TIMER_UPDATE: - updateWindow(); - break; - } - break; - - // -=- Track whether or not the window has focus - - case WM_SETFOCUS: - has_focus = true; - break; - case WM_KILLFOCUS: - has_focus = false; - cursorOutsideBuffer(); - // Restore the keyboard to a consistent state - kbd.releaseAllKeys(callback); - break; - - // -=- If the menu is about to be shown, make sure it's up to date - - case WM_INITMENU: - callback->refreshMenu(true); - break; - - // -=- Handle the extra window menu items - - // Pass system menu messages to the callback and only attempt - // to process them ourselves if the callback returns false. - case WM_SYSCOMMAND: - // Call the supplied callback - if (callback->sysCommand(wParam, lParam)) - break; - - // - Not processed by the callback, so process it as a system message - switch (wParam & 0xfff0) { - - // When restored, ensure that full-screen mode is re-enabled if required. - case SC_RESTORE: - { - if (GetWindowLong(handle, GWL_STYLE) & WS_MINIMIZE) { - rfb::win32::SafeDefWindowProc(handle, msg, wParam, lParam); - setFullscreen(fullscreenRestore); - } - else if (fullscreenActive) - setFullscreen(false); - else - rfb::win32::SafeDefWindowProc(handle, msg, wParam, lParam); - - return 0; - } - - // If we are maximized or minimized then that cancels full-screen mode. - case SC_MINIMIZE: - case SC_MAXIMIZE: - fullscreenRestore = fullscreenActive; - setFullscreen(false); - break; - - } - break; - - // Treat all menu commands as system menu commands - case WM_COMMAND: - SendMessage(handle, WM_SYSCOMMAND, wParam, lParam); - return 0; - - // -=- Handle keyboard input - - case WM_KEYUP: - case WM_KEYDOWN: - // Hook the MenuKey to pop-up the window menu - if (menuKey && (wParam == menuKey)) { - - bool ctrlDown = (GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0; - bool altDown = (GetAsyncKeyState(VK_MENU) & 0x8000) != 0; - bool shiftDown = (GetAsyncKeyState(VK_SHIFT) & 0x8000) != 0; - if (!(ctrlDown || altDown || shiftDown)) { - - // If MenuKey is being released then pop-up the menu - if ((msg == WM_KEYDOWN)) { - // Make sure it's up to date - // - // NOTE: Here we call refreshMenu only to grey out Move and Size - // menu items. Other things will be refreshed once again - // while processing the WM_INITMENU message. - // - callback->refreshMenu(false); - - // Show it under the pointer - POINT pt; - GetCursorPos(&pt); - cursorInBuffer = false; - TrackPopupMenu(GetSystemMenu(handle, FALSE), - TPM_CENTERALIGN | TPM_VCENTERALIGN, pt.x, pt.y, 0, handle, 0); - } - - // Ignore the MenuKey keypress for both press & release events - return 0; - } - } - case WM_SYSKEYDOWN: - case WM_SYSKEYUP: - kbd.keyEvent(callback, wParam, lParam, (msg == WM_KEYDOWN) || (msg == WM_SYSKEYDOWN)); - return 0; - - // -=- Handle mouse wheel scroll events - -#ifdef WM_MOUSEWHEEL - case WM_MOUSEWHEEL: - processMouseMessage(msg, wParam, lParam); - break; -#endif - - // -=- Handle the window closing - - case WM_CLOSE: - vlog.debug("WM_CLOSE %x", handle); - callback->closeWindow(); - break; - - } - - return rfb::win32::SafeDefWindowProc(handle, msg, wParam, lParam); -} - -LRESULT -DesktopWindow::processFrameMessage(UINT msg, WPARAM wParam, LPARAM lParam) { - switch (msg) { - - // -=- Paint the remote frame buffer - - case WM_PAINT: - { - PAINTSTRUCT ps; - HDC paintDC = BeginPaint(frameHandle, &ps); - if (!paintDC) - throw rdr::SystemException("unable to BeginPaint", GetLastError()); - Rect pr = Rect(ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom); - - if (!pr.is_empty()) { - - // Draw using the correct palette - PaletteSelector pSel(paintDC, windowPalette.getHandle()); - - if (buffer->bitmap) { - // Update the bitmap's palette - if (palette_changed) { - palette_changed = false; - buffer->refreshPalette(); - } - - // Get device context - BitmapDC bitmapDC(paintDC, buffer->bitmap); - - // Blit the border if required - Rect bufpos = desktopToClient(buffer->getRect()); - if (!pr.enclosed_by(bufpos)) { - vlog.debug("draw border"); - HBRUSH black = (HBRUSH) GetStockObject(BLACK_BRUSH); - RECT r; - SetRect(&r, 0, 0, bufpos.tl.x, client_size.height()); FillRect(paintDC, &r, black); - SetRect(&r, bufpos.tl.x, 0, bufpos.br.x, bufpos.tl.y); FillRect(paintDC, &r, black); - SetRect(&r, bufpos.br.x, 0, client_size.width(), client_size.height()); FillRect(paintDC, &r, black); - SetRect(&r, bufpos.tl.x, bufpos.br.y, bufpos.br.x, client_size.height()); FillRect(paintDC, &r, black); - } - - // Do the blit - Point buf_pos = clientToDesktop(pr.tl); - - if (!BitBlt(paintDC, pr.tl.x, pr.tl.y, pr.width(), pr.height(), - bitmapDC, buf_pos.x, buf_pos.y, SRCCOPY)) - throw rdr::SystemException("unable to BitBlt to window", GetLastError()); - } - } - - EndPaint(frameHandle, &ps); - } - return 0; - - // -=- Palette management - - case WM_PALETTECHANGED: - vlog.debug("WM_PALETTECHANGED"); - if ((HWND)wParam == frameHandle) { - vlog.debug("ignoring"); - break; - } - case WM_QUERYNEWPALETTE: - vlog.debug("re-selecting palette"); - { - WindowDC wdc(frameHandle); - PaletteSelector pSel(wdc, windowPalette.getHandle()); - if (pSel.isRedrawRequired()) { - InvalidateRect(frameHandle, 0, FALSE); - UpdateWindow(frameHandle); - } - } - return TRUE; - - case WM_VSCROLL: - case WM_HSCROLL: - { - Point delta; - int newpos = (msg == WM_VSCROLL) ? scrolloffset.y : scrolloffset.x; - - switch (LOWORD(wParam)) { - case SB_PAGEUP: newpos -= 50; break; - case SB_PAGEDOWN: newpos += 50; break; - case SB_LINEUP: newpos -= 5; break; - case SB_LINEDOWN: newpos += 5; break; - case SB_THUMBTRACK: - case SB_THUMBPOSITION: newpos = HIWORD(wParam); break; - default: vlog.info("received unknown scroll message"); - }; - - if (msg == WM_HSCROLL) - setViewportOffset(Point(newpos, scrolloffset.y)); - else - setViewportOffset(Point(scrolloffset.x, newpos)); - - SCROLLINFO si; - si.cbSize = sizeof(si); - si.fMask = SIF_POS; - si.nPos = newpos; - SetScrollInfo(frameHandle, (msg == WM_VSCROLL) ? SB_VERT : SB_HORZ, &si, TRUE); - } - break; - - // -=- Cursor shape/visibility handling - - case WM_SETCURSOR: - if (LOWORD(lParam) != HTCLIENT) - break; - SetCursor(cursorInBuffer ? dotCursor : arrowCursor); - return TRUE; - - case WM_MOUSELEAVE: - trackingMouseLeave = false; - cursorOutsideBuffer(); - return 0; - - // -=- Mouse input handling - - case WM_MOUSEMOVE: - case WM_LBUTTONUP: - case WM_MBUTTONUP: - case WM_RBUTTONUP: - case WM_LBUTTONDOWN: - case WM_MBUTTONDOWN: - case WM_RBUTTONDOWN: - processMouseMessage(msg, wParam, lParam); - break; - } - - return rfb::win32::SafeDefWindowProc(frameHandle, msg, wParam, lParam); -} - -void -DesktopWindow::processMouseMessage(UINT msg, WPARAM wParam, LPARAM lParam) -{ - if (!has_focus) { - cursorOutsideBuffer(); - return; - } - - if (!trackingMouseLeave) { - TRACKMOUSEEVENT tme; - tme.cbSize = sizeof(TRACKMOUSEEVENT); - tme.dwFlags = TME_LEAVE; - tme.hwndTrack = frameHandle; - _TrackMouseEvent(&tme); - trackingMouseLeave = true; - } - int mask = 0; - if (LOWORD(wParam) & MK_LBUTTON) mask |= 1; - if (LOWORD(wParam) & MK_MBUTTON) mask |= 2; - if (LOWORD(wParam) & MK_RBUTTON) mask |= 4; - -#ifdef WM_MOUSEWHEEL - if (msg == WM_MOUSEWHEEL) { - int delta = (short)HIWORD(wParam); - int repeats = (abs(delta)+119) / 120; - int wheelMask = (delta > 0) ? 8 : 16; - vlog.debug("repeats %d, mask %d\n",repeats,wheelMask); - for (int i=0; igetRect().contains(p); - if (!cursorInBuffer) { - cursorOutsideBuffer(); - return; - } - - // If we're locally rendering the cursor then redraw it - if (cursorAvailable) { - // - Render the cursor! - if (!p.equals(cursorPos)) { - hideLocalCursor(); - cursorPos = p; - showLocalCursor(); - if (cursorVisible) - hideSystemCursor(); - } - } - - // If we are doing bump-scrolling then try that first... - if (processBumpScroll(clientPos)) - return; - - // Send a pointer event to the server - oldpos = p; - if (buffer->isScaling()) { - p.x /= buffer->getScaleRatioX(); - p.y /= buffer->getScaleRatioY(); - } - ptr.pointerEvent(callback, p, mask); -#ifdef WM_MOUSEWHEEL - } -#endif -} - -void DesktopWindow::updateWindow() -{ - Rect rect; - - updateTimer.stop(); - - rect = damage.get_bounding_rect(); - damage.clear(); - - RECT invalid = {rect.tl.x, rect.tl.y, rect.br.x, rect.br.y}; - InvalidateRect(frameHandle, &invalid, FALSE); -} - -void -DesktopWindow::hideLocalCursor() { - // - Blit the cursor backing store over the cursor - // *** ALWAYS call this BEFORE changing buffer PF!!! - if (cursorVisible) { - cursorVisible = false; - buffer->DIBSectionBuffer::imageRect(cursorBackingRect, cursorBacking.data); - invalidateDesktopRect(cursorBackingRect, false); - } -} - -void -DesktopWindow::showLocalCursor() { - if (cursorAvailable && !cursorVisible && cursorInBuffer) { - if (!buffer->getScaledPixelFormat().equal(cursor.getPF()) || - cursor.getRect().is_empty()) { - vlog.info("attempting to render invalid local cursor"); - cursorAvailable = false; - showSystemCursor(); - return; - } - cursorVisible = true; - - cursorBackingRect = cursor.getRect().translate(cursorPos).translate(cursor.hotspot.negate()); - cursorBackingRect = cursorBackingRect.intersect(buffer->getRect()); - buffer->getImage(cursorBacking.data, cursorBackingRect); - - renderLocalCursor(); - - invalidateDesktopRect(cursorBackingRect, false); - // Since we render the cursor onto the framebuffer, we need to update - // right away to get a responsive cursor. - updateWindow(); - } -} - -void DesktopWindow::cursorOutsideBuffer() -{ - cursorInBuffer = false; - hideLocalCursor(); - showSystemCursor(); -} - -void -DesktopWindow::renderLocalCursor() -{ - Rect r = cursor.getRect(); - r = r.translate(cursorPos).translate(cursor.hotspot.negate()); - buffer->DIBSectionBuffer::maskRect(r, cursor.data, cursor.mask.buf); -} - -void -DesktopWindow::hideSystemCursor() { - if (systemCursorVisible) { - vlog.debug("hide system cursor"); - systemCursorVisible = false; - ShowCursor(FALSE); - } -} - -void -DesktopWindow::showSystemCursor() { - if (!systemCursorVisible) { - vlog.debug("show system cursor"); - systemCursorVisible = true; - ShowCursor(TRUE); - } -} - - -bool -DesktopWindow::invalidateDesktopRect(const Rect& crect, bool scaling) { - Rect rect; - if (buffer->isScaling() && scaling) { - rect = desktopToClient(buffer->calculateScaleBoundary(crect)); - } else rect = desktopToClient(crect); - if (rect.intersect(client_size).is_empty()) return false; - damage.assign_union(rfb::Region(rect)); - if (!updateTimer.isActive()) - updateTimer.start(100); - return true; -} - - -void -DesktopWindow::notifyClipboardChanged(const char* text, int len) { - callback->clientCutText(text, len); -} - - -void -DesktopWindow::setPF(const PixelFormat& pf) { - // If the cursor is the wrong format then clear it - if (!pf.equal(buffer->getScaledPixelFormat())) - setCursor(0, 0, Point(), 0, 0); - - // Update the desktop buffer - buffer->setPF(pf); - - // Redraw the window - InvalidateRect(frameHandle, 0, FALSE); -} - -void -DesktopWindow::setSize(int w, int h) { - vlog.debug("setSize %dx%d", w, h); - - // If the locally-rendered cursor is visible then remove it - hideLocalCursor(); - - // Resize the backing buffer - buffer->setSize(w, h); - - // Calculate the pixel buffer aspect correlation. It's used - // for the autoScaling operation. - aspect_corr = (double)w / h; - - // If the window is not maximised or full-screen then resize it - if (!(GetWindowLong(handle, GWL_STYLE) & WS_MAXIMIZE) && !fullscreenActive) { - // Resize the window to the required size - RECT r = {0, 0, w, h}; - AdjustWindowRectEx(&r, GetWindowLong(frameHandle, GWL_STYLE), FALSE, - GetWindowLong(frameHandle, GWL_EXSTYLE)); - if (isToolbarEnabled()) - r.bottom += tb.getHeight(); - AdjustWindowRect(&r, GetWindowLong(handle, GWL_STYLE), FALSE); - - // Resize about the center of the window, and clip to current monitor - MonitorInfo mi(handle); - resizeWindow(handle, r.right-r.left, r.bottom-r.top); - mi.clipTo(handle); - } else { - // Ensure the screen contents are consistent - InvalidateRect(frameHandle, 0, FALSE); - } - - // Enable/disable scrollbars as appropriate - calculateScrollBars(); -} - -void DesktopWindow::setAutoScaling(bool as) { - autoScaling = as; - if (isToolbarEnabled()) refreshToolbarButtons(); - if (as) fitBufferToWindow(); -} - -void DesktopWindow::setDesktopScale(int scale_) { - if (buffer->getScale() == scale_ || scale_ <= 0) return; - bool state = buffer->isScaling(); - buffer->setScale(scale_); - state ^= buffer->isScaling(); - if (state) convertCursorToBuffer(); - if (isToolbarEnabled()) refreshToolbarButtons(); - if (!(isAutoScaling() || isFullscreen() || (GetWindowLong(handle, GWL_STYLE) & WS_MAXIMIZE))) resizeDesktopWindowToBuffer(); - printScale(); - InvalidateRect(frameHandle, 0, FALSE); -} - -void DesktopWindow::setDesktopScaleFilter(unsigned int scaleFilterID) { - if (scaleFilterID == getDesktopScaleFilterID() || scaleFilterID > scaleFilterMaxNumber) return; - buffer->setScaleFilter(scaleFilterID); - InvalidateRect(frameHandle, 0, FALSE); -} - -void DesktopWindow::convertCursorToBuffer() { - if (memcmp(&(cursor.getPF()), &(buffer->getPF()), sizeof(PixelBuffer)) == 0) return; - internalSetCursor = true; - setCursor(cursorWidth, cursorHeight, cursorHotspot, cursorImage, cursorMask); - internalSetCursor = false; -} - -void DesktopWindow::fitBufferToWindow(bool repaint) { - double scale_ratio; - double resized_aspect_corr = double(client_size.width()) / client_size.height(); - DWORD style = GetWindowLong(frameHandle, GWL_STYLE); - if (style & (WS_VSCROLL | WS_HSCROLL)) { - style &= ~(WS_VSCROLL | WS_HSCROLL); - SetWindowLong(frameHandle, GWL_STYLE, style); - SetWindowPos(frameHandle, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); - // Update the cached client size - RECT r; - GetClientRect(frameHandle, &r); - client_size = Rect(r.left, r.top, r.right, r.bottom); - } - bool state = buffer->isScaling(); - if (resized_aspect_corr > aspect_corr) { - scale_ratio = (double)client_size.height() / buffer->getSrcHeight(); - buffer->setScaleWindowSize(ceil(buffer->getSrcWidth()*scale_ratio), client_size.height()); - } else { - scale_ratio = (double)client_size.width() / buffer->getSrcWidth(); - buffer->setScaleWindowSize(client_size.width(), ceil(buffer->getSrcHeight()*scale_ratio)); - } - state ^= buffer->isScaling(); - if (state) convertCursorToBuffer(); - printScale(); - InvalidateRect(frameHandle, 0, FALSE); -} - -void DesktopWindow::printScale() { - setName(desktopName); -} - -void -DesktopWindow::setCursor(int w, int h, const Point& hotspot, void* data, void* mask) { - hideLocalCursor(); - - cursor.hotspot = hotspot; - - cursor.setSize(w, h); - cursor.setPF(buffer->getScaledPixelFormat()); - - // Convert the current cursor pixel format to bpp32 if scaling mode is on. - // It need because ScaledDIBSection buffer always works with bpp32 pixel data - // in scaling mode. - if (buffer->isScaling()) { - U8 *ptr = (U8*)cursor.data; - U8 *dataPtr = (U8*)data; - U32 pixel = 0; - int bytesPerPixel = buffer->getPixelFormat().bpp / 8; - int pixelCount = w * h; - PixelFormat pf = buffer->getPixelFormat(); - - while (pixelCount--) { - if (bytesPerPixel == 1) { - pixel = *dataPtr++; - } else if (bytesPerPixel == 2) { - int b0 = *dataPtr++; int b1 = *dataPtr++; - pixel = b1 << 8 | b0; - } else if (bytesPerPixel == 4) { - int b0 = *dataPtr++; int b1 = *dataPtr++; - int b2 = *dataPtr++; int b3 = *dataPtr++; - pixel = b3 << 24 | b2 << 16 | b1 << 8 | b0; - } else { - pixel = 0; - } - *ptr++ = (U8)((((pixel >> pf.blueShift ) & pf.blueMax ) * 255 + pf.blueMax /2) / pf.blueMax); - *ptr++ = (U8)((((pixel >> pf.greenShift) & pf.greenMax) * 255 + pf.greenMax/2) / pf.greenMax); - *ptr++ = (U8)((((pixel >> pf.redShift ) & pf.redMax ) * 255 + pf.redMax /2) / pf.redMax); - *ptr++ = (U8)0; - } - } else { - cursor.imageRect(cursor.getRect(), data); - } - memcpy(cursor.mask.buf, mask, cursor.maskLen()); - cursor.crop(); - - cursorBacking.setSize(w, h); - cursorBacking.setPF(buffer->getScaledPixelFormat()); - - cursorAvailable = true; - - showLocalCursor(); - - // Save the cursor parameters - if (!internalSetCursor) { - if (cursorImage) delete [] cursorImage; - if (cursorMask) delete [] cursorMask; - int cursorImageSize = (buffer->getPixelFormat().bpp/8) * w * h; - cursorImage = new U8[cursorImageSize]; - cursorMask = new U8[cursor.maskLen()]; - memcpy(cursorImage, data, cursorImageSize); - memcpy(cursorMask, mask, cursor.maskLen()); - cursorWidth = w; - cursorHeight = h; - cursorHotspot = hotspot; - } -} - -PixelFormat -DesktopWindow::getNativePF() const { - vlog.debug("getNativePF()"); - return WindowDC(handle).getPF(); -} - - -void -DesktopWindow::refreshWindowPalette(int start, int count) { - vlog.debug("refreshWindowPalette(%d, %d)", start, count); - - Colour colours[256]; - if (count > 256) { - vlog.debug("%d palette entries", count); - throw rdr::Exception("too many palette entries"); - } - - // Copy the palette from the DIBSectionBuffer - ColourMap* cm = buffer->getColourMap(); - if (!cm) return; - for (int i=0; ilookup(i, &r, &g, &b); - colours[i].r = r; - colours[i].g = g; - colours[i].b = b; - } - - // Set the window palette - windowPalette.setEntries(start, count, colours); - - // Cause the window to be redrawn - palette_changed = true; - InvalidateRect(handle, 0, FALSE); -} - - -void DesktopWindow::calculateScrollBars() { - // Calculate the required size of window - DWORD current_style = GetWindowLong(frameHandle, GWL_STYLE); - DWORD style = current_style & ~(WS_VSCROLL | WS_HSCROLL); - DWORD style_ex = GetWindowLong(frameHandle, GWL_EXSTYLE); - DWORD old_style; - RECT r; - SetRect(&r, 0, 0, buffer->width(), buffer->height()); - AdjustWindowRectEx(&r, style, FALSE, style_ex); - Rect reqd_size = Rect(r.left, r.top, r.right, r.bottom); - - if (!bumpScroll) { - // We only enable scrollbars if bump-scrolling is not active. - // Effectively, this means if full-screen is not active, - // but I think it's better to make these things explicit. - - // Work out whether scroll bars are required - do { - old_style = style; - - if (!(style & WS_HSCROLL) && (reqd_size.width() > window_size.width())) { - style |= WS_HSCROLL; - reqd_size.br.y += GetSystemMetrics(SM_CXHSCROLL); - } - if (!(style & WS_VSCROLL) && (reqd_size.height() > window_size.height())) { - style |= WS_VSCROLL; - reqd_size.br.x += GetSystemMetrics(SM_CXVSCROLL); - } - } while (style != old_style); - } - - // Tell Windows to update the window style & cached settings - if (style != current_style) { - SetWindowLong(frameHandle, GWL_STYLE, style); - SetWindowPos(frameHandle, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); - } - - // Update the scroll settings - SCROLLINFO si; - if (style & WS_VSCROLL) { - si.cbSize = sizeof(si); - si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; - si.nMin = 0; - si.nMax = buffer->height(); - si.nPage = buffer->height() - (reqd_size.height() - window_size.height()); - maxscrolloffset.y = __rfbmax(0, si.nMax-si.nPage); - scrolloffset.y = __rfbmin(maxscrolloffset.y, scrolloffset.y); - si.nPos = scrolloffset.y; - SetScrollInfo(frameHandle, SB_VERT, &si, TRUE); - } - if (style & WS_HSCROLL) { - si.cbSize = sizeof(si); - si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; - si.nMin = 0; - si.nMax = buffer->width(); - si.nPage = buffer->width() - (reqd_size.width() - window_size.width()); - maxscrolloffset.x = __rfbmax(0, si.nMax-si.nPage); - scrolloffset.x = __rfbmin(maxscrolloffset.x, scrolloffset.x); - si.nPos = scrolloffset.x; - SetScrollInfo(frameHandle, SB_HORZ, &si, TRUE); - } - - // Update the cached client size - GetClientRect(frameHandle, &r); - client_size = Rect(r.left, r.top, r.right, r.bottom); -} - -void DesktopWindow::resizeDesktopWindowToBuffer() { - RECT r; - DWORD style = GetWindowLong(frameHandle, GWL_STYLE) & ~(WS_VSCROLL | WS_HSCROLL); - DWORD style_ex = GetWindowLong(frameHandle, GWL_EXSTYLE); - - // Calculate the required size of the desktop window - SetRect(&r, 0, 0, buffer->width(), buffer->height()); - AdjustWindowRectEx(&r, style, FALSE, style_ex); - if (isToolbarEnabled()) - r.bottom += tb.getHeight(); - AdjustWindowRect(&r, GetWindowLong(handle, GWL_STYLE), FALSE); - - // Set the required size, center the main window and clip to the current monitor - SetWindowPos(handle, 0, 0, 0, r.right-r.left, r.bottom-r.top, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE); - centerWindow(handle, NULL); - MonitorInfo mi(getMonitor()); - mi.clipTo(handle); - - // Enable/disable scrollbars as appropriate - calculateScrollBars(); -} - - -void DesktopWindow::framebufferUpdateEnd() -{ - updateWindow(); -} - - -void -DesktopWindow::setName(const char* name) { - if (name != desktopName) { - strCopy(desktopName, name, sizeof(desktopName)); - } - char *newTitle = new char[strlen(desktopName)+20]; - sprintf(newTitle, "TigerVNC: %.240s @ %i%%", desktopName, getDesktopScale()); - SetWindowText(handle, TStr(newTitle)); - delete [] newTitle; -} - - -void -DesktopWindow::serverCutText(const char* str, rdr::U32 len) { - CharArray t(len+1); - memcpy(t.buf, str, len); - t.buf[len] = 0; - clipboard.setClipText(t.buf); -} - - -void DesktopWindow::fillRect(const Rect& r, Pixel pix) { - Rect img_rect = buffer->isScaling() ? buffer->calculateScaleBoundary(r) : r; - if (cursorBackingRect.overlaps(img_rect)) hideLocalCursor(); - buffer->fillRect(r, pix); - invalidateDesktopRect(r); -} -void DesktopWindow::imageRect(const Rect& r, void* pixels) { - Rect img_rect = buffer->isScaling() ? buffer->calculateScaleBoundary(r) : r; - if (cursorBackingRect.overlaps(img_rect)) hideLocalCursor(); - buffer->imageRect(r, pixels); - invalidateDesktopRect(r); -} -void DesktopWindow::copyRect(const Rect& r, int srcX, int srcY) { - Rect img_rect = buffer->isScaling() ? buffer->calculateScaleBoundary(r) : r; - if (cursorBackingRect.overlaps(img_rect) || - cursorBackingRect.overlaps(Rect(srcX, srcY, srcX+img_rect.width(), srcY+img_rect.height()))) - hideLocalCursor(); - buffer->copyRect(r, Point(r.tl.x-srcX, r.tl.y-srcY)); - invalidateDesktopRect(r); -} - -void DesktopWindow::invertRect(const Rect& r) { - int stride; - rdr::U8* p = buffer->isScaling() ? buffer->getPixelsRW(buffer->calculateScaleBoundary(r), &stride) - : buffer->getPixelsRW(r, &stride); - for (int y = 0; y < r.height(); y++) { - for (int x = 0; x < r.width(); x++) { - switch (buffer->getPF().bpp) { - case 8: ((rdr::U8* )p)[x+y*stride] ^= 0xff; break; - case 16: ((rdr::U16*)p)[x+y*stride] ^= 0xffff; break; - case 32: ((rdr::U32*)p)[x+y*stride] ^= 0xffffffff; break; - } - } - } - invalidateDesktopRect(r); -} diff --git a/win/vncviewer/DesktopWindow.h b/win/vncviewer/DesktopWindow.h deleted file mode 100644 index 4bc7b7a7..00000000 --- a/win/vncviewer/DesktopWindow.h +++ /dev/null @@ -1,294 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -// -=- DesktopWindow.h - -// Each VNC connection instance (CConn) creates a DesktopWindow the -// server initialisation message has been received. The CConn is -// responsible for all RFB-specific and network issues. The -// DesktopWindow is responsible for all GUI management issues. -// -// DesktopWindow provides a FullFramePixelBuffer interface for the -// CConn to render updates into. It also requires a callback object -// to be supplied, which will be notified when various events occur. - -#ifndef __RFB_WIN32_DESKTOP_WINDOW_H__ -#define __RFB_WIN32_DESKTOP_WINDOW_H__ - -#include -#include -#include -#include -#include -#include -#include - - -namespace rfb { - - namespace win32 { - - class DesktopWindow : rfb::win32::Clipboard::Notifier { - public: - class Callback; - - DesktopWindow(Callback* cb_); - ~DesktopWindow(); - - // - Window message handling procedure - LRESULT processMessage(UINT msg, WPARAM wParam, LPARAM lParam); - - // - Window message handling procedure for the framebuffer window - LRESULT processFrameMessage(UINT msg, WPARAM wParam, LPARAM lParam); - - // - Separate message handling procedure for mouse events - // It's called from both processMessage() and processFrameMessage() - void processMouseMessage(UINT msg, WPARAM wParam, LPARAM lParam); - - // - Determine the native pixel format of the window - // This can (and often will) differ from the PixelBuffer format - PixelFormat getNativePF() const; - - // - Get the underlying window handle - // This is used by F8Menu to modify the window's menu - HWND getHandle() const {return handle;} - - // - Get the framebuffer window handle - HWND getFrameHandle() const {return frameHandle;} - - // - Set the window title - void setName(const char* name); - - // - Set the key that causes the system/F8 menu to be displayed - void setMenuKey(rdr::U8 key) { menuKey = key; } - - // - Pointer event handling - void setEmulate3(bool em3) { ptr.enableEmulate3(em3); } - void setPointerEventInterval(int interval) { ptr.enableInterval(interval); } - - // - Set the pixel format, size etc of the underlying PixelBuffer - void setPF(const PixelFormat& pf); - PixelFormat getPF() const { return buffer->getPixelFormat(); } - void setSize(int w, int h); - void setColour(int i, int r, int g, int b) {buffer->setColour(i, r, g, b);} - void setAutoScaling(bool as); - bool isAutoScaling() const { return autoScaling; } - void setDesktopScale(int scale); - int getDesktopScale() const { return buffer->getScale(); } - void setDesktopScaleFilter(unsigned int scaleFilterID); - unsigned int getDesktopScaleFilterID() const { return buffer->getScaleFilterID(); } - void fitBufferToWindow(bool repaint = true); - void printScale(); - - // - Set the cursor to render when the pointer is within the desktop buffer - void setCursor(int w, int h, const Point& hotspot, void* data, void* mask); - void showCursor() { showLocalCursor(); } - void convertCursorToBuffer(); - - // - Set the window fullscreen / determine whether it is fullscreen - void setFullscreen(bool fs); - bool isFullscreen() { return fullscreenActive; } - - // - Set/get the toolbar's state - void setShowToolbar(bool st); - bool isToolbarEnabled() { return showToolbar; } - void refreshToolbarButtons(); - - // - Set whether to disable special Windows keys & pass them straight to server - void setDisableWinKeys(bool dwk); - - // - Set/get which monitor the window should be displayed on - void setMonitor(const char* monitor); - char* getMonitor() const; - - // - Set the local clipboard - void serverCutText(const char* str, rdr::U32 len); - - // - Completion of one FramebufferUpdate - void framebufferUpdateEnd(); - - // - Draw into the desktop buffer & update the window - void fillRect(const Rect& r, Pixel pix); - void imageRect(const Rect& r, void* pixels); - void copyRect(const Rect& r, int srcX, int srcY); - - void invertRect(const Rect& r); - - // - Update the window palette if the display is palette-based. - // Colours are pulled from the desktop buffer's ColourMap. - // Only the specified range of indexes is dealt with. - // After the update, the entire window is redrawn. - void refreshWindowPalette(int start, int count); - - // Clipboard::Notifier interface - void notifyClipboardChanged(const char* text, int len); - - // DesktopWindow Callback interface - class Callback : public InputHandler { - public: - virtual ~Callback() {} - virtual void displayChanged() = 0; - virtual void paintCompleted() = 0; - virtual bool sysCommand(WPARAM wParam, LPARAM lParam) = 0; - virtual void closeWindow() = 0; - virtual void refreshMenu(bool enableSysItems) = 0; - }; - - Callback *getCallback() const { return callback; } - - // Currently accessible so that the CConn can releaseAllKeys & check - // whether Ctrl and Alt are down... - rfb::win32::CKeyboard kbd; - - protected: - // Routines to convert between Desktop and client (window) coordinates - Point desktopToClient(const Point& p) { - Point pos = p; - if (client_size.width() > buffer->width()) - pos.x += (client_size.width() - buffer->width()) / 2; - else if (client_size.width() < buffer->width()) - pos.x -= scrolloffset.x; - if (client_size.height() > buffer->height()) - pos.y += (client_size.height() - buffer->height()) / 2; - else if (client_size.height() < buffer->height()) - pos.y -= scrolloffset.y; - return pos; - } - Rect desktopToClient(const Rect& r) { - return Rect(desktopToClient(r.tl), desktopToClient(r.br)); - } - Point clientToDesktop(const Point& p) { - Point pos = p; - if (client_size.width() > buffer->width()) - pos.x -= (client_size.width() - buffer->width()) / 2; - else if (client_size.width() < buffer->width()) - pos.x += scrolloffset.x; - if (client_size.height() > buffer->height()) - pos.y -= (client_size.height() - buffer->height()) / 2; - else if (client_size.height() < buffer->height()) - pos.y += scrolloffset.y; - return pos; - } - Rect clientToDesktop(const Rect& r) { - return Rect(clientToDesktop(r.tl), clientToDesktop(r.br)); - } - - // Internal routine used by the scrollbars & bump scroller to select - // the portion of the Desktop to display - bool setViewportOffset(const Point& tl); - - // Bump scroll handling. Bump scrolling is used if the window is - // in fullscreen mode and the Desktop is larger than the window - bool processBumpScroll(const Point& cursorPos); - void setBumpScroll(bool on); - bool bumpScroll; - Point bumpScrollDelta; - IntervalTimer bumpScrollTimer; - - // Track modified areas of the framebuffer - void updateWindow(); - - // Locally-rendered VNC cursor - void hideLocalCursor(); - void showLocalCursor(); - void renderLocalCursor(); - - // The system-rendered cursor - void hideSystemCursor(); - void showSystemCursor(); - - // cursorOutsideBuffer() is called whenever we detect that the mouse has - // moved outside the desktop. It restores the system arrow cursor. - void cursorOutsideBuffer(); - - // Returns true if part of the supplied rect is visible, false otherwise - bool invalidateDesktopRect(const Rect& crect, bool scaling=true); - - // Determine whether or not we need to enable/disable scrollbars and set the - // window style accordingly - void calculateScrollBars(); - - // Resizes the main window against the pixel buffer size - void resizeDesktopWindowToBuffer(); - - // Win32-specific input handling - rfb::win32::CPointer ptr; - Point oldpos; - rfb::win32::Clipboard clipboard; - - // Palette handling - LogicalPalette windowPalette; - bool palette_changed; - - // - Full-screen mode - RECT fullscreenOldRect; - DWORD fullscreenOldFlags; - bool fullscreenActive; - bool fullscreenRestore; - - // Damage tracking - rfb::Region damage; - IntervalTimer updateTimer; - - // Cursor handling - Cursor cursor; - bool systemCursorVisible; // Should system-cursor be drawn? - bool trackingMouseLeave; - bool cursorInBuffer; // Is cursor position within server buffer? (ONLY for LocalCursor) - bool cursorVisible; // Is cursor currently rendered? - bool cursorAvailable; // Is cursor available for rendering? - bool internalSetCursor; - Point cursorPos; - ManagedPixelBuffer cursorBacking; - Rect cursorBackingRect; - U8 *cursorImage; - U8 *cursorMask; - int cursorWidth; - int cursorHeight; - Point cursorHotspot; - - // ToolBar handling - ViewerToolBar tb; - bool showToolbar; - - // Remote desktop name - char desktopName[255]; - - // Local window state - win32::ScaledDIBSectionBuffer* buffer; - double aspect_corr; - bool has_focus; - bool autoScaling; - Rect window_size; - Rect client_size; - Point scrolloffset; - Point maxscrolloffset; - HWND handle; - HWND frameHandle; - rdr::U8 menuKey; - - Callback* callback; - }; - - }; - -}; - -#endif // __RFB_WIN32_DESKTOP_WINDOW_H__ - - diff --git a/win/vncviewer/InfoDialog.cxx b/win/vncviewer/InfoDialog.cxx deleted file mode 100644 index 551ccf23..00000000 --- a/win/vncviewer/InfoDialog.cxx +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ -#include -#include -#include -#include -#include -#include -#include - -using namespace rfb; -using namespace rfb::win32; - -static LogWriter vlog("Info"); - - -bool InfoDialog::showDialog(CConn* cc) { - conn = cc; - return Dialog::showDialog(MAKEINTRESOURCE(IDD_CONNECTION_INFO)); -} - -void InfoDialog::initDialog() { - char buf[256]; - - setItemString(IDC_INFO_NAME, TStr(conn->cp.name())); - - setItemString(IDC_INFO_HOST, TCharArray(conn->getSocket()->getPeerAddress()).buf); - - sprintf(buf, "%dx%d", conn->cp.width, conn->cp.height); - setItemString(IDC_INFO_SIZE, TStr(buf)); - - conn->cp.pf().print(buf, 256); - setItemString(IDC_INFO_PF, TStr(buf)); - - conn->getServerDefaultPF().print(buf, 256); - setItemString(IDC_INFO_DEF_PF, TStr(buf)); - - setItemString(IDC_REQUESTED_ENCODING, TStr(encodingName(conn->getOptions().preferredEncoding))); - setItemString(IDC_LAST_ENCODING, TStr(encodingName(conn->lastUsedEncoding()))); - - sprintf(buf, "%d kbits/s", conn->getSocket()->inStream().kbitsPerSecond()); - setItemString(IDC_INFO_LINESPEED, TStr(buf)); - - sprintf(buf, "%d.%d", conn->cp.majorVersion, conn->cp.minorVersion); - setItemString(IDC_INFO_VERSION, TStr(buf)); - - const CSecurity* cSec = conn->csecurity; - setItemString(IDC_INFO_SECURITY, TStr(secTypeName(cSec->getType()))); - setItemString(IDC_INFO_ENCRYPTION, TStr(cSec->description())); -} diff --git a/win/vncviewer/InfoDialog.h b/win/vncviewer/InfoDialog.h deleted file mode 100644 index 752d53c5..00000000 --- a/win/vncviewer/InfoDialog.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -// -=- InfoDialog.h - -// Info dialog for VNC Viewer 4.0 - -#ifndef __RFB_WIN32_INFO_DIALOG_H__ -#define __RFB_WIN32_INFO_DIALOG_H__ - -#include -#include - -namespace rfb { - - namespace win32 { - - class CConn; - - class InfoDialog : Dialog { - public: - InfoDialog() : Dialog(GetModuleHandle(0)), conn(0) {} - virtual bool showDialog(CConn* vw); - virtual void initDialog(); - protected: - CConn* conn; - }; - - }; - -}; - -#endif diff --git a/win/vncviewer/ListenServer.h b/win/vncviewer/ListenServer.h deleted file mode 100644 index d94b58b9..00000000 --- a/win/vncviewer/ListenServer.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -// -=- ListenServer.h - -#ifndef __RFB_WIN32_LISTEN_SERVER_H__ -#define __RFB_WIN32_LISTEN_SERVER_H__ - -#include -#include -#include -#include - - -namespace rfb { - namespace win32 { - - class ListenServer : MsgWindow { - public: - ListenServer(network::SocketListener* l) : MsgWindow(_T("rfb::win32::ListenServer")), sock(l) { - if (WSAAsyncSelect(l->getFd(), getHandle(), WM_USER, FD_ACCEPT) == SOCKET_ERROR) - throw rdr::SystemException("unable to monitor listen socket", WSAGetLastError()); - } - - LRESULT processMessage(UINT msg, WPARAM wParam, LPARAM lParam) { - if (msg == WM_USER) { - network::Socket* newConn = sock->accept(); - new CConnThread(newConn, true); - return 0; - } - return MsgWindow::processMessage(msg, wParam, lParam); - } - protected: - network::SocketListener* sock; - }; - - }; -}; - -#endif diff --git a/win/vncviewer/ListenTrayIcon.h b/win/vncviewer/ListenTrayIcon.h deleted file mode 100644 index 047a1049..00000000 --- a/win/vncviewer/ListenTrayIcon.h +++ /dev/null @@ -1,95 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -// -=- ListenTrayIcon.h - -#ifndef __RFB_WIN32_LISTEN_TRAY_ICON_H__ -#define __RFB_WIN32_LISTEN_TRAY_ICON_H__ - -#include -#include - -namespace rfb { - namespace win32 { - - class ListenTrayIcon : public TrayIcon { - public: - ListenTrayIcon() { - setIcon(IDI_ICON); - setToolTip(_T("VNC Viewer")); - } - virtual LRESULT processMessage(UINT msg, WPARAM wParam, LPARAM lParam) { - switch(msg) { - - case WM_USER: - switch (lParam) { - case WM_LBUTTONDBLCLK: - SendMessage(getHandle(), WM_COMMAND, ID_NEW_CONNECTION, 0); - break; - case WM_RBUTTONUP: - HMENU menu = LoadMenu(GetModuleHandle(0), MAKEINTRESOURCE(IDR_TRAY)); - HMENU trayMenu = GetSubMenu(menu, 0); - - // First item is New Connection, the default - SetMenuDefaultItem(trayMenu, ID_NEW_CONNECTION, FALSE); - - // SetForegroundWindow is required, otherwise Windows ignores the - // TrackPopupMenu because the window isn't the foreground one, on - // some older Windows versions... - SetForegroundWindow(getHandle()); - - // Display the menu - POINT pos; - GetCursorPos(&pos); - TrackPopupMenu(trayMenu, 0, pos.x, pos.y, 0, getHandle(), 0); - break; - } - return 0; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case ID_NEW_CONNECTION: - { - new CConnThread(); - break; - } - case ID_OPTIONS: - OptionsDialog::global.showDialog(0); - break; - case ID_ABOUT: - AboutDialog::instance.showDialog(); - break; - case ID_CLOSE: - SendMessage(getHandle(), WM_CLOSE, 0, 0); - break; - } - return 0; - - case WM_CLOSE: - PostQuitMessage(0); - return 0; - } - - return TrayIcon::processMessage(msg, wParam, lParam); - } - }; - - }; -}; - -#endif // __RFB_WIN32_LISTEN_TRAY_ICON_H__ diff --git a/win/vncviewer/MRU.h b/win/vncviewer/MRU.h deleted file mode 100644 index a0aef814..00000000 --- a/win/vncviewer/MRU.h +++ /dev/null @@ -1,133 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ -#ifndef __VIEWER_MRU_H__ -#define __VIEWER_MRU_H__ - -#include -#include -#include -#include -#include -#include - -namespace rfb { - - namespace win32 { - - namespace MRU { - - static const RegKey RegRoot = HKEY_CURRENT_USER; - static const TCHAR* RegPath = _T("Software\\TigerVNC\\VNCViewer4\\MRU"); - static const int MaxMRUEntries = 256; - static const int MRUEntries = 10; - - static std::list getEntries() { - std::list mru; - - try { - RegKey key; - key.openKey(RegRoot, RegPath); - - CharArray order; - int length; - key.getBinary(_T("Order"), (void**)&order.buf, &length); - - for (int i=0; i ordercodes; - keycode = 0; - bool found = false; - for (int i=0; i0; i--) - order[i] = order[i-1]; - order[0] = keycode; - - TCharArray keyname(rdr::HexOutStream::binToHexStr((char*)&keycode, 1)); - key.setString(keyname.buf, TStr(name)); - key.setBinary(_T("Order"), order, orderlen); - } - - }; - - }; - -}; - -#endif diff --git a/win/vncviewer/OptionsDialog.cxx b/win/vncviewer/OptionsDialog.cxx deleted file mode 100644 index 721b9b4f..00000000 --- a/win/vncviewer/OptionsDialog.cxx +++ /dev/null @@ -1,420 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -using namespace rdr; -using namespace rfb; -using namespace rfb::win32; -using namespace std; - -static LogWriter vlog("Options"); - - -struct OptionsInfo { - CConn* view; - CConnOptions options; -}; - - -OptionsDialog rfb::win32::OptionsDialog::global; - - -class ViewerOptions : public PropSheet { -public: - ViewerOptions(OptionsInfo& info_, std::list pages) - : PropSheet(GetModuleHandle(0), - info_.view ? _T("VNC Viewer Options") : _T("VNC Viewer Defaults"), pages), - changed(false), info(info_) { - } - ~ViewerOptions() { - if (changed) { - if (info.view) - // Apply the settings to the supplied session object - info.view->applyOptions(info.options); - else { - // Commit the settings to the user's registry area - info.options.writeDefaults(); - } - } - } - - void setChanged() {changed = true;} - - bool changed; - OptionsInfo& info; -}; - - -class FormatPage : public PropSheetPage { -public: - FormatPage(OptionsInfo* dlg_) - : PropSheetPage(GetModuleHandle(0), MAKEINTRESOURCE(IDD_FORMAT)), dlg(dlg_) { - } - virtual void initDialog() { - setItemChecked(IDC_ENCODING_AUTO, dlg->options.autoSelect); - setItemChecked(IDC_FORMAT_FULLCOLOUR, dlg->options.fullColour); - if (!dlg->options.fullColour) { - switch (dlg->options.lowColourLevel) { - case 0: setItemChecked(IDC_FORMAT_VERYLOWCOLOUR, true); break; - case 1: setItemChecked(IDC_FORMAT_LOWCOLOUR, true); break; - case 2: setItemChecked(IDC_FORMAT_MEDIUMCOLOUR, true); break; - } - } - switch (dlg->options.preferredEncoding) { - case encodingTight: setItemChecked(IDC_ENCODING_TIGHT, true); break; - case encodingZRLE: setItemChecked(IDC_ENCODING_ZRLE, true); break; - case encodingHextile: setItemChecked(IDC_ENCODING_HEXTILE, true); break; - case encodingRaw: setItemChecked(IDC_ENCODING_RAW, true); break; - } - setItemChecked(IDC_CUSTOM_COMPRESSLEVEL, dlg->options.customCompressLevel); - setItemInt(IDC_COMPRESSLEVEL, dlg->options.compressLevel); - setItemChecked(IDC_ALLOW_JPEG, !dlg->options.noJpeg); - setItemInt(IDC_QUALITYLEVEL, dlg->options.qualityLevel); - onCommand(IDC_ENCODING_AUTO, 0 /* ? */); // Force enableItem status to refresh - onCommand(IDC_CUSTOM_COMPRESSLEVEL, 0 /* ? */); // Force enableItem status to refresh - onCommand(IDC_ALLOW_JPEG, 0 /* ? */); // Force enableItem status to refresh - } - virtual bool onOk() { - dlg->options.autoSelect = isItemChecked(IDC_ENCODING_AUTO); - dlg->options.fullColour = isItemChecked(IDC_FORMAT_FULLCOLOUR); - dlg->options.customCompressLevel = isItemChecked(IDC_CUSTOM_COMPRESSLEVEL); - dlg->options.compressLevel = getItemInt(IDC_COMPRESSLEVEL); - dlg->options.noJpeg = !isItemChecked(IDC_ALLOW_JPEG); - dlg->options.qualityLevel = getItemInt(IDC_QUALITYLEVEL); - if (isItemChecked(IDC_FORMAT_VERYLOWCOLOUR)) - dlg->options.lowColourLevel = 0; - if (isItemChecked(IDC_FORMAT_LOWCOLOUR)) - dlg->options.lowColourLevel = 1; - if (isItemChecked(IDC_FORMAT_MEDIUMCOLOUR)) - dlg->options.lowColourLevel = 2; - dlg->options.preferredEncoding = encodingTight; - if (isItemChecked(IDC_ENCODING_ZRLE)) - dlg->options.preferredEncoding = encodingZRLE; - if (isItemChecked(IDC_ENCODING_HEXTILE)) - dlg->options.preferredEncoding = encodingHextile; - if (isItemChecked(IDC_ENCODING_RAW)) - dlg->options.preferredEncoding = encodingRaw; - ((ViewerOptions*)propSheet)->setChanged(); - return true; - } - virtual bool onCommand(int id, int cmd) { - bool aut = isItemChecked(IDC_ENCODING_AUTO); - bool jpeg = isItemChecked(IDC_ALLOW_JPEG); - bool custom_comp = isItemChecked(IDC_CUSTOM_COMPRESSLEVEL); - if (id == IDC_ENCODING_AUTO) { - enableItem(IDC_ENCODING_TIGHT, !aut); - enableItem(IDC_ENCODING_ZRLE, !aut); - enableItem(IDC_ENCODING_HEXTILE, !aut); - enableItem(IDC_ENCODING_RAW, !aut); - enableItem(IDC_FORMAT_FULLCOLOUR, !aut); - enableItem(IDC_FORMAT_MEDIUMCOLOUR, !aut); - enableItem(IDC_FORMAT_LOWCOLOUR, !aut); - enableItem(IDC_FORMAT_VERYLOWCOLOUR, !aut); - enableItem(IDC_QUALITYLEVEL, !aut && jpeg); - return true; - } - if (id == IDC_CUSTOM_COMPRESSLEVEL) { - enableItem(IDC_COMPRESSLEVEL, custom_comp); - return true; - } - if (id == IDC_ALLOW_JPEG) { - enableItem(IDC_QUALITYLEVEL, !aut && jpeg); - return true; - } - return false; - } -protected: - OptionsInfo* dlg; -}; - -class MiscPage : public PropSheetPage { -public: - MiscPage(OptionsInfo* dlg_) - : PropSheetPage(GetModuleHandle(0), MAKEINTRESOURCE(IDD_MISC)), dlg(dlg_) { - } - virtual void initDialog() { - setItemChecked(IDC_CONN_SHARED, dlg->options.shared); - enableItem(IDC_CONN_SHARED, (!dlg->view) || (dlg->view->state() != CConnection::RFBSTATE_NORMAL)); - setItemChecked(IDC_FULL_SCREEN, dlg->options.fullScreen); - setItemChecked(IDC_LOCAL_CURSOR, dlg->options.useLocalCursor); - setItemChecked(IDC_DESKTOP_RESIZE, dlg->options.useDesktopResize); - enableItem(IDC_PROTOCOL_3_3, (!dlg->view) || (dlg->view->state() != CConnection::RFBSTATE_NORMAL)); - setItemChecked(IDC_PROTOCOL_3_3, dlg->options.protocol3_3); - setItemChecked(IDC_ACCEPT_BELL, dlg->options.acceptBell); - setItemChecked(IDC_AUTO_RECONNECT, dlg->options.autoReconnect); - setItemChecked(IDC_SHOW_TOOLBAR, dlg->options.showToolbar); - char scale_values[10][20] = { - "10","25","50","75","90","100","125","150","200","Auto" - }; - HWND hScaleCombo = GetDlgItem(handle, IDC_COMBO_SCALE); - for (int i = 0; i <= 9; i++) { - SendMessage(hScaleCombo, CB_INSERTSTRING, - (WPARAM)i, (LPARAM)(int FAR*)scale_values[i]); - } - if (dlg->options.autoScaling) { - SetDlgItemText(handle, IDC_COMBO_SCALE, (LPCTSTR) "Auto"); - } else { - SetDlgItemInt(handle, IDC_COMBO_SCALE, dlg->options.scale, FALSE); - } - } - virtual bool onOk() { - dlg->options.shared = isItemChecked(IDC_CONN_SHARED); - dlg->options.fullScreen = isItemChecked(IDC_FULL_SCREEN); - dlg->options.useLocalCursor = isItemChecked(IDC_LOCAL_CURSOR); - dlg->options.useDesktopResize = isItemChecked(IDC_DESKTOP_RESIZE); - dlg->options.protocol3_3 = isItemChecked(IDC_PROTOCOL_3_3); - dlg->options.acceptBell = isItemChecked(IDC_ACCEPT_BELL); - dlg->options.autoReconnect = isItemChecked(IDC_AUTO_RECONNECT); - dlg->options.showToolbar = isItemChecked(IDC_SHOW_TOOLBAR); - int s = GetDlgItemInt(handle, IDC_COMBO_SCALE, NULL, FALSE); - if (s > 0) { - dlg->options.scale = s; - dlg->options.autoScaling = false; - } else { - char scaleStr[20]; - GetDlgItemText(handle, IDC_COMBO_SCALE, (LPTSTR) scaleStr, 20); - if (strcmp(scaleStr, (const char *) "Auto") == 0) { - dlg->options.autoScaling = true; - } - } - ((ViewerOptions*)propSheet)->setChanged(); - return true; - } - virtual bool onCommand(int id, int cmd) { - if (id == IDC_COMBO_SCALE) { - if (cmd == CBN_SELENDOK || cmd == CBN_EDITCHANGE) { - char scaleStr[20]; - if (cmd == CBN_SELENDOK) { - HWND handleComboScale = GetDlgItem(handle, IDC_COMBO_SCALE); - int index = SendMessage(handleComboScale, CB_GETCURSEL, 0, 0); - SendMessage(handleComboScale, CB_GETLBTEXT, (WPARAM)index, (LPARAM)scaleStr); - } else { - GetDlgItemText(handle, IDC_COMBO_SCALE, (LPTSTR) scaleStr, 20); - } - return true; - } - } - return false; - } -protected: - OptionsInfo* dlg; -}; - -class InputsPage : public PropSheetPage { -public: - InputsPage(OptionsInfo* dlg_) - : PropSheetPage(GetModuleHandle(0), MAKEINTRESOURCE(IDD_INPUTS)), dlg(dlg_) { - } - virtual void initDialog() { - setItemChecked(IDC_SEND_POINTER, dlg->options.sendPtrEvents); - setItemChecked(IDC_SEND_KEYS, dlg->options.sendKeyEvents); - setItemChecked(IDC_CLIENT_CUTTEXT, dlg->options.clientCutText); - setItemChecked(IDC_SERVER_CUTTEXT, dlg->options.serverCutText); - setItemChecked(IDC_DISABLE_WINKEYS, dlg->options.disableWinKeys && !osVersion.isPlatformWindows); - enableItem(IDC_DISABLE_WINKEYS, !osVersion.isPlatformWindows); - setItemChecked(IDC_EMULATE3, dlg->options.emulate3); - setItemChecked(IDC_POINTER_INTERVAL, dlg->options.pointerEventInterval != 0); - - // Populate the Menu Key tab - HWND menuKey = GetDlgItem(handle, IDC_MENU_KEY); - SendMessage(menuKey, CB_RESETCONTENT, 0, 0); - SendMessage(menuKey, CB_ADDSTRING, 0, (LPARAM)_T("none")); - if (!dlg->options.menuKey) - SendMessage(menuKey, CB_SETCURSEL, 0, 0); - for (unsigned int i=0; i<12; i++) { - TCHAR buf[4]; - _stprintf(buf, _T("F%d"), i+1); - int index = SendMessage(menuKey, CB_ADDSTRING, 0, (LPARAM)buf); - if (i == (dlg->options.menuKey - VK_F1)) - SendMessage(menuKey, CB_SETCURSEL, index, 0); - } - } - virtual bool onOk() { - dlg->options.sendPtrEvents = isItemChecked(IDC_SEND_POINTER); - dlg->options.sendKeyEvents = isItemChecked(IDC_SEND_KEYS); - dlg->options.clientCutText = isItemChecked(IDC_CLIENT_CUTTEXT); - dlg->options.serverCutText = isItemChecked(IDC_SERVER_CUTTEXT); - dlg->options.disableWinKeys = isItemChecked(IDC_DISABLE_WINKEYS); - dlg->options.emulate3 = isItemChecked(IDC_EMULATE3); - dlg->options.pointerEventInterval = - isItemChecked(IDC_POINTER_INTERVAL) ? 200 : 0; - - HWND mkHwnd = GetDlgItem(handle, IDC_MENU_KEY); - int index = SendMessage(mkHwnd, CB_GETCURSEL, 0, 0); - TCharArray keyName(SendMessage(mkHwnd, CB_GETLBTEXTLEN, index, 0)+1); - SendMessage(mkHwnd, CB_GETLBTEXT, index, (LPARAM)keyName.buf); - if (_tcscmp(keyName.buf, _T("none")) == 0) - dlg->options.setMenuKey(""); - else - dlg->options.setMenuKey(CStr(keyName.buf)); - - ((ViewerOptions*)propSheet)->setChanged(); - return true; - } -protected: - OptionsInfo* dlg; -}; - -class DefaultsPage : public PropSheetPage { -public: - DefaultsPage(OptionsInfo* dlg_) - : PropSheetPage(GetModuleHandle(0), MAKEINTRESOURCE(IDD_DEFAULTS)), dlg(dlg_) { - } - virtual void initDialog() { - enableItem(IDC_LOAD_CONFIG, dlg->options.configFileName.buf); - enableItem(IDC_SAVE_CONFIG, dlg->options.configFileName.buf); - } - virtual bool onCommand(int id, int cmd) { - switch (id) { - case IDC_LOAD_DEFAULTS: - dlg->options = CConnOptions(); - break; - case IDC_SAVE_DEFAULTS: - propSheet->commitPages(); - dlg->options.writeDefaults(); - break; - case IDC_LOAD_CONFIG: - dlg->options.readFromFile(dlg->options.configFileName.buf); - break; - case IDC_SAVE_CONFIG: - propSheet->commitPages(); - dlg->options.writeToFile(dlg->options.configFileName.buf); - MsgBox(handle, _T("Options saved successfully"), - MB_OK | MB_ICONINFORMATION); - return 0; - case IDC_SAVE_CONFIG_AS: - propSheet->commitPages(); - // Get a filename to save to - TCHAR newFilename[4096]; - TCHAR currentDir[4096]; - if (dlg->options.configFileName.buf) - _tcscpy(newFilename, TStr(dlg->options.configFileName.buf)); - else - newFilename[0] = 0; - OPENFILENAME ofn; - memset(&ofn, 0, sizeof(ofn)); -#ifdef OPENFILENAME_SIZE_VERSION_400 - ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; -#else - ofn.lStructSize = sizeof(ofn); -#endif - ofn.hwndOwner = handle; - ofn.lpstrFilter = _T("VNC Connection Options\000*.vnc\000"); - ofn.lpstrFile = newFilename; - currentDir[0] = 0; - GetCurrentDirectory(4096, currentDir); - ofn.lpstrInitialDir = currentDir; - ofn.nMaxFile = 4096; - ofn.lpstrDefExt = _T(".vnc"); - ofn.Flags = OFN_NOREADONLYRETURN | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST; - if (!GetSaveFileName(&ofn)) { - if (CommDlgExtendedError()) - throw rdr::Exception("GetSaveFileName failed"); - return 0; - } - - // Save the Options - dlg->options.writeToFile(CStr(newFilename)); - MsgBox(handle, _T("Options saved successfully"), - MB_OK | MB_ICONINFORMATION); - return 0; - }; - propSheet->reInitPages(); - return true; - } -protected: - OptionsInfo* dlg; -}; - -class SecPage : public SecurityPage { -public: - SecPage(Security *security_, OptionsInfo *dlg_) - : SecurityPage(security_), dlg(dlg_) { - } - - virtual void enableX509Dialogs() { - enableItem(IDC_LOAD_CACERT, true); - enableItem(IDC_LOAD_CRLCERT, true); - } - - virtual void disableX509Dialogs() { - enableItem(IDC_LOAD_CACERT, false); - enableItem(IDC_LOAD_CRLCERT, false); - } - - virtual bool onOk() { - SecurityPage::onOk(); - - dlg->options.secTypes = security->GetEnabledExtSecTypes(); - - if (isItemChecked(IDC_VENCRYPT)) - dlg->options.secTypes.push_front(secTypeVeNCrypt); - - return true; - } - - virtual void loadX509Certs() {} - virtual void loadVncPasswd() {} - -protected: - OptionsInfo* dlg; -}; - -OptionsDialog::OptionsDialog() : visible(false) { -} - -bool OptionsDialog::showDialog(CConn* view, bool capture) { - if (visible) return false; - visible = true; - - // Grab the current properties - OptionsInfo info; - if (view) - info.options = view->getOptions(); - info.view = view; - - // Build a list of pages to display - std::list pages; - FormatPage formatPage(&info); pages.push_back(&formatPage); - InputsPage inputsPage(&info); pages.push_back(&inputsPage); - MiscPage miscPage(&info); pages.push_back(&miscPage); - DefaultsPage defPage(&info); if (view) pages.push_back(&defPage); - SecPage secPage(view->security, &info); pages.push_back(&secPage); - - // Show the property sheet - ViewerOptions dialog(info, pages); - dialog.showPropSheet(view && view->getWindow() ? view->getWindow()->getHandle() : 0, - false, false, capture); - - visible = false; - return dialog.changed; -} diff --git a/win/vncviewer/OptionsDialog.h b/win/vncviewer/OptionsDialog.h deleted file mode 100644 index fcddc71c..00000000 --- a/win/vncviewer/OptionsDialog.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -// -=- OptionsDialog.h - -// Options dialog for VNC Viewer 4.0 - -#ifndef __RFB_WIN32_OPTIONS_DIALOG_H__ -#define __RFB_WIN32_OPTIONS_DIALOG_H__ - -#include - -namespace rfb { - - namespace win32 { - - class CConn; - - class OptionsDialog { - public: - OptionsDialog(); - virtual bool showDialog(CConn* cfg, bool capture=false); - - static OptionsDialog global; - protected: - bool visible; - }; - - }; - -}; - -#endif diff --git a/win/vncviewer/UserPasswdDialog.cxx b/win/vncviewer/UserPasswdDialog.cxx deleted file mode 100644 index 2eea0ea0..00000000 --- a/win/vncviewer/UserPasswdDialog.cxx +++ /dev/null @@ -1,85 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -#include -#include -#include - -using namespace rfb; -using namespace rfb::win32; - - -UserPasswdDialog::UserPasswdDialog() : Dialog(GetModuleHandle(0)), - showUsername(false), showPassword(false) { -} - - -void UserPasswdDialog::setCSecurity(const CSecurity* cs) { - description.replaceBuf(tstrDup(cs->description())); -} - -bool UserPasswdDialog::showDialog() { - return Dialog::showDialog(MAKEINTRESOURCE(IDD_VNC_AUTH_DLG)); -} - -void UserPasswdDialog::initDialog() { - if (username.buf) - setItemString(IDC_USERNAME, username.buf); - if (password.buf) - setItemString(IDC_PASSWORD, password.buf); - if (!showUsername) { - setItemString(IDC_USERNAME, _T("")); - enableItem(IDC_USERNAME, false); - } - if (!showPassword) { - setItemString(IDC_PASSWORD, _T("")); - enableItem(IDC_PASSWORD, false); - } - if (description.buf) { - TCharArray title(128); - GetWindowText(handle, title.buf, 128); - _tcsncat(title.buf, _T(" ["), 128); - _tcsncat(title.buf, description.buf, 128); - _tcsncat(title.buf, _T("]"), 128); - SetWindowText(handle, title.buf); - } -} - -bool UserPasswdDialog::onOk() { - username.replaceBuf(getItemString(IDC_USERNAME)); - password.replaceBuf(getItemString(IDC_PASSWORD)); - return true; -} - - -void UserPasswdDialog::getUserPasswd(char** user, char** passwd) { - showUsername = user != 0; - showPassword = passwd != 0; - if (user && *user) - username.replaceBuf(tstrDup(*user)); - if (passwd && *passwd) - password.replaceBuf(tstrDup(*passwd)); - - if (!showDialog()) - throw rfb::AuthCancelledException(); - - if (user) - *user = strDup(username.buf); - if (passwd) - *passwd = strDup(password.buf); -} diff --git a/win/vncviewer/UserPasswdDialog.h b/win/vncviewer/UserPasswdDialog.h deleted file mode 100644 index bf006f4d..00000000 --- a/win/vncviewer/UserPasswdDialog.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -// -=- UserPasswdDialog.h - -// Username and password dialog for VNC Viewer 4.0 -// Note that the password and username fields are only freed -// when the dialog instance is deleted - it is important to -// ensure that the instance is deleted as early as possible, to -// avoid the password being retained in memory for too long. - -#ifndef __RFB_WIN32_USERPASSWD_DIALOG_H__ -#define __RFB_WIN32_USERPASSWD_DIALOG_H__ - -#include -#include -#include -#include - -namespace rfb { - - namespace win32 { - - class UserPasswdDialog : Dialog, public UserPasswdGetter { - public: - UserPasswdDialog(); - virtual bool showDialog(); - virtual void initDialog(); - virtual bool onOk(); - virtual void getUserPasswd(char** user, char** passwd); - void setCSecurity(const CSecurity* cs); - protected: - TCharArray username; - TPlainPasswd password; - bool showUsername, showPassword; - TCharArray description; - }; - - }; - -}; - -#endif diff --git a/win/vncviewer/ViewerToolBar.cxx b/win/vncviewer/ViewerToolBar.cxx deleted file mode 100644 index 13a64111..00000000 --- a/win/vncviewer/ViewerToolBar.cxx +++ /dev/null @@ -1,104 +0,0 @@ -/* Copyright (C) 2005 TightVNC Team. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -// -=- ViewerToolBar.cxx - -#include -#include - -void ViewerToolBar::create(HWND parentHwnd) { - // Create the toolbar panel - ToolBar::create(ID_TOOLBAR, parentHwnd, WS_CHILD | - TBSTYLE_FLAT | TBSTYLE_TOOLTIPS | CCS_NORESIZE); - addBitmap(4, IDB_TOOLBAR); - - // Create the control buttons - addButton(0, ID_OPTIONS); - addButton(1, ID_INFO); - addButton(0, 0, TBSTATE_ENABLED, TBSTYLE_SEP); - addButton(2, ID_FULLSCREEN); - addButton(3, ID_REQUEST_REFRESH); - addButton(0, 0, TBSTATE_ENABLED, TBSTYLE_SEP); - addButton(4, ID_ZOOM_IN); - addButton(5, ID_ZOOM_OUT); - addButton(6, ID_ACTUAL_SIZE); - addButton(7, ID_AUTO_SIZE); - addButton(0, 0, TBSTATE_ENABLED, TBSTYLE_SEP); - addButton(8, ID_SEND_CAD); - addButton(9, ID_SEND_CTLESC); - addButton(10, ID_CTRL_KEY); - addButton(11, ID_ALT_KEY); - addButton(0, 0, TBSTATE_ENABLED, TBSTYLE_SEP); - addButton(0, 0, TBSTATE_ENABLED, TBSTYLE_SEP); - addButton(13, ID_NEW_CONNECTION); - addButton(14, ID_CONN_SAVE_AS); - - // Resize the toolbar window - autoSize(); -} - -LRESULT ViewerToolBar::processWM_NOTIFY(WPARAM wParam, LPARAM lParam) { - switch (((LPNMHDR)lParam)->code) { - // Process tooltips text - case TTN_NEEDTEXT: - { - LPTOOLTIPTEXT TTStr = (LPTOOLTIPTEXT)lParam; - if (TTStr->hdr.code != TTN_NEEDTEXT) - return 0; - - switch (TTStr->hdr.idFrom) { - case ID_OPTIONS: - TTStr->lpszText = (LPTSTR) "Connection options..."; - break; - case ID_INFO: - TTStr->lpszText = (LPTSTR) "Connection info"; - break; - case ID_FULLSCREEN: - TTStr->lpszText = (LPTSTR) "Full screen"; - break; - case ID_REQUEST_REFRESH: - TTStr->lpszText = (LPTSTR) "Request screen refresh"; - break; - case ID_SEND_CAD: - TTStr->lpszText = (LPTSTR) "Send Ctrl-Alt-Del"; - break; - case ID_SEND_CTLESC: - TTStr->lpszText = (LPTSTR) "Send Ctrl-Esc"; - break; - case ID_CTRL_KEY: - TTStr->lpszText = (LPTSTR) "Send Ctrl key press/release"; - break; - case ID_ALT_KEY: - TTStr->lpszText = (LPTSTR) "Send Alt key press/release"; - break; - case ID_NEW_CONNECTION: - TTStr->lpszText = (LPTSTR) "New connection..."; - break; - case ID_CONN_SAVE_AS: - TTStr->lpszText = (LPTSTR) "Save connection info as..."; - break; - default: - break; - } - } - - default: - break; - } - return 0; -} diff --git a/win/vncviewer/ViewerToolBar.h b/win/vncviewer/ViewerToolBar.h deleted file mode 100644 index 85c1de51..00000000 --- a/win/vncviewer/ViewerToolBar.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (C) 2005 TightVNC Team. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -// -=- ViewerToolBar.h - -// ToolBar for the Vnc Viewer - -#include - -using namespace rfb::win32; - -class ViewerToolBar : public ToolBar { -public: - ViewerToolBar() {} - ~ViewerToolBar() {} - - void create(HWND parentHwnd); - - LRESULT processWM_NOTIFY(WPARAM wParam, LPARAM lParam); -}; diff --git a/win/vncviewer/buildTime.cxx b/win/vncviewer/buildTime.cxx deleted file mode 100644 index 9f37b387..00000000 --- a/win/vncviewer/buildTime.cxx +++ /dev/null @@ -1,18 +0,0 @@ -/* Copyright (C) 2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ -const char* buildTime = "Built on " __DATE__ " at " __TIME__; diff --git a/win/vncviewer/cursor1.cur b/win/vncviewer/cursor1.cur deleted file mode 100644 index 20a713f77078a10c31f4dd70b82878b36cf4d55b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 326 zcmZQzU}9ioP*7k1(o75nj0_B73=9k!KnxUOZ~$UPAOr&_1>qpb|Ns9ZICNnB0NT-k Qgh70u8|Vhufi|II04|+^M*si- diff --git a/win/vncviewer/resource.h b/win/vncviewer/resource.h deleted file mode 100644 index efb977c1..00000000 --- a/win/vncviewer/resource.h +++ /dev/null @@ -1,119 +0,0 @@ -// Used by vncviewer.rc - -#include - -#define IDR_MANIFEST 1 -#define IDI_ICON 101 -#define IDD_VNC_AUTH_DLG 102 -#define IDD_CONNECTING_DLG 103 -#define IDD_CONNECTION_DLG 104 -#define IDC_DOT_CURSOR 105 -#define IDD_ABOUT 107 -#define IDD_FORMAT 108 -#define IDD_MISC 109 -#define IDD_INPUTS 110 -#define IDD_SERVER_KEYS 111 -#define IDR_TRAY 112 -#define IDD_CONNECTION_INFO 113 -#define IDD_DEFAULTS 116 -#define IDB_BITMAP 120 -#define IDB_TOOLBAR 122 -#define IDC_PASSWORD 1000 -#define IDC_CONNECTING_TEXT 1001 -#define IDC_SERVER_EDIT 1002 -#define IDC_USERNAME 1005 -#define IDC_VERSION 1008 -#define IDC_BUILDTIME 1009 -#define IDC_ENCODING_AUTO 1010 -#define IDC_FORMAT_FULLCOLOUR 1011 -#define IDC_ENCODING_ZRLE 1012 -#define IDC_ENCODING_HEXTILE 1013 -#define IDC_CONN_SHARED 1013 -#define IDC_ENCODING_RAW 1014 -#define IDC_FULL_SCREEN 1014 -#define IDC_SEND_POINTER 1015 -#define IDC_SEND_KEYS 1016 -#define IDC_CLIENT_CUTTEXT 1017 -#define IDC_SERVER_CUTTEXT 1018 -#define IDC_LOCAL_CURSOR 1019 -#define IDC_DESKTOP_RESIZE 1020 -#define IDC_COPYRIGHT 1021 -#define IDC_DESCRIPTION 1022 -#define IDC_OPTIONS 1023 -#define IDC_ABOUT 1024 -#define IDC_LIST1 1025 -#define IDC_FTLOCALLIST 1025 -#define IDC_INFO_NAME 1026 -#define IDC_INFO_HOST 1027 -#define IDC_INFO_SIZE 1028 -#define IDC_INFO_PF 1029 -#define IDC_INFO_DEF_PF 1030 -#define IDC_INFO_LINESPEED 1031 -#define IDC_INFO_VERSION 1032 -#define IDC_PROTOCOL_3_3 1034 -#define IDC_ACCEPT_BELL 1035 -#define IDC_FORMAT_VERYLOWCOLOUR 1036 -#define IDC_SHOW_TOOLBAR 1036 -#define IDC_FORMAT_LOWCOLOUR 1037 -#define IDC_FORMAT_MEDIUMCOLOUR 1038 -#define IDC_LOAD_DEFAULTS 1040 -#define IDC_SAVE_DEFAULTS 1041 -#define IDC_LOAD_CONFIG 1042 -#define IDC_EMULATE3 1043 -#define IDC_POINTER_INTERVAL 1044 -#define IDC_SAVE_CONFIG 1045 -#define IDC_INFO_SECURITY 1046 -#define IDC_SAVE_CONFIG_AS 1048 -#define IDC_MENU_KEY 1051 -#define IDC_REQUESTED_ENCODING 1052 -#define IDC_LAST_ENCODING 1053 -#define IDC_INFO_ENCRYPTION 1055 -#define IDC_AUTO_RECONNECT 1056 -#define IDC_DISABLE_WINKEYS 1057 -#define IDC_QUALITYLEVEL 1058 -#define IDC_SEND_SYSKEYS 1059 -#define IDC_PROGRESS 1064 -#define IDC_CONFIRM_YESTOALL 1079 -#define IDC_CONFIRM_TEXT 1080 -#define IDC_EDIT2 1082 -#define IDC_TYPE 1088 -#define IDC_ENCODING_TIGHT 1089 -#define IDC_CUSTOM_COMPRESSLEVEL 1091 -#define IDC_COMPRESSLEVEL 1093 -#define IDC_ALLOW_JPEG 1095 -#define IDC_FTLOCALRELOAD 1096 -#define IDC_STATIC_SCALE 1097 -#define IDC_COMBO_SCALE 1098 -#define IDC_STATIC_PERCENT 1099 -#define IDC_LOAD_CACERT 1100 -#define IDC_LOAD_CRLCERT 1101 -#define ID_TOOLBAR 4002 -#define ID_CLOSE 4003 -#define ID_OPTIONS 4004 -#define ID_NEW_CONNECTION 4005 -#define ID_ABOUT 4006 -#define ID_FULLSCREEN 4007 -#define ID_SEND_CAD 4008 -#define ID_INFO 4009 -#define ID_REQUEST_REFRESH 4010 -#define ID_CTRL_KEY 4011 -#define ID_ALT_KEY 4012 -#define ID_SEND_MENU_KEY 4013 -#define ID_SEND_CTLESC 4014 -#define ID_CONN_SAVE_AS 4015 -#define ID_ZOOM_IN 4017 -#define ID_ZOOM_OUT 4018 -#define ID_ACTUAL_SIZE 4019 -#define ID_AUTO_SIZE 4020 -#define IDM_SHOW_TOOLBAR 4027 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 134 -#define _APS_NEXT_COMMAND_VALUE 40028 -#define _APS_NEXT_CONTROL_VALUE 1102 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/win/vncviewer/toolbar.bmp b/win/vncviewer/toolbar.bmp deleted file mode 100644 index 1473fa3733a4566771d1d82ff99b2dba107fe9c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2166 zcmc&#J#X7E5WS)X#3qB{$=M8OamNDr18qS-Q{lft8Ai^Y%ud#pZi1$EE08IBm;59R z0-R3lyCY@G36ixJStp6)y?ghSuitJBsodiJQJ&rrU8$PL8&O)1FXOu>!bRRkg*zVU z@$nH_7J^aNrugb@IyQK6(!j62vxmYySi_~v(t)vBVnOhC;qT88{#}6K!ly;CT0p(RpIgB5h(F-R@yAIAR_tm2Fwz^e z0p0<;F%NqrDGyI3Xzk&sE zUGQC9`%Cd9X|vmH@D6-aU$V@JH~u znw4A>nou@}!;|bz+U*aAg9m=K*>hb1zavxojN6tb^g!?<;ukO=_`<)p78XYQ6~7($ z!-mwq^8bSDqXNoRQ7pvg&E0Oks}bzG-A;5ppU$V(dv@1u&wg`dLYD_)eABdAe@FZ= z|2~u`zDD_f5>F)l+XfW~|3cR(ejnqX_``h(0E6#L`6k}^3^GUl6Ms*}6V)E3=m%Xy z{#Npb3?%-ckL?FKnLFaQQvRHa2+q*|&+_l?rqj8^JLzl=nQ8r*8p?&vo7#9uR!jH5 zU)vHA@r#A#zeiL+9>h=h0xtL+B=i>eJx20r{%Gp}_ci`f|5AoHg9KzUe*|CaU;DQ} z14{loG&YbW_z269za$?&^iQ5ge7np$>`48;!gYe?HJJ?SCwRaKaB= z$Yk#sJ_ZZ83qB}xpdR_>;vuK`rxkFl`xo`E^DpAVhzQ&m23Gtachq*LZ@{0}fq$kh z@m5!mBE{D^2K+Str30`oeJ|SvE&Y$v=>N0%uUlTi3x33s;uAC4C1)G)X=3#|Ht0Vq Y3rCNF`KQlG%ltdpk;(g}0PfB8e{NA&00000 diff --git a/win/vncviewer/vncviewer.bmp b/win/vncviewer/vncviewer.bmp deleted file mode 100644 index f02897a1483429f391447ba4d936a6e71bd32db7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2852 zcmZvdy^`a`5rBK}Ltp{vbSsjjz{M?;OXYIt$nlgj22N0lM2VO>RT))sz*m^}SOpW% zN_;v7cM_A`+ll=Q4)6p%ML^(y{$@a*eo6#CHi+r&>FMqn{N=Bo))GH|&P4vm-Jh-~ zDMfMrpM}WB=mdWGu_AoM+F9_+t$6Rn|J%!t|N2&>(O`gq#({@HL<=;)jW%GxfrmlF z2sEI9KgNOs55sld2C2b-1qU7m5pKmbpuvCz2Ob836lg$$0SgX13?h7GXh4Gj3l2OC zqJ=P}fp8hH;K0K$FRf{i8Vp!);9;1TtsA5U0~Q>380M6i2C2b-1qU96IbF6vYA|5I zfrnvErE8EH3|MgBVVKkG8>9vU794mOVhQxnAT=1U;K0Kmmi1d{AgtU#xEy#G#5MvA zXfR;Gfrnu(n{JRA3|MgBVVFy58l(mT794mO=5jNMwHgdqaNuE>TfsF*4F)VY@G#76 z;v1v}0~Q>37-9?Ap+RaeV8MZhK|JgC(trj77950Ym|Lr9kQxkFaNuE>+fFw~4F)VY z@G#6RX&R&k0~Q>380L1h4N`*v3l2OCb1SNdnVF@9upS@deJs*ISb)ut=1vwXxT z8f_A+x<#*6%u%b&Gse4h70yT2rdrmD55||sTJ4v?+cM0B$1t|Zv5j6fpM>nGv z(+@>5se9FisJ|~CC3}$k@3+#9vWPQbv!5-}UVX_+FK^4ohu4yPEye4HH@9*hHKXrY zPxZ+`t%K%QXuc34E53es{Qg$h8TefEKhvWRB-Ly&Qr|#>Xe*W(@O5MOETruu0(q)AN&;2meqz#R8cqY_n|iFMU`qQ zIC|)zUCW-%!oJ1}-SKOSPO20AoG?Z%AsMkQk}?^YZ`#Ryi1xi5yZ-!iPWq%G7bkVj z#^jtLld%qKEyrJKm(}^*xn~ac#vOf`9nQu0QHU?b!8(ic_(a%M+;3}H3Y~Np>fX}$ zHJ&D@;sYpvHis^XYZa=%`TYV8M&XsH`N>GQBFzgKW zG`nTHkRE~~3}(%psq!08pwz;9xXzFqXmD(tltp2J@6 z)=SdEOskC$TR7punK+-S6Dv7~y-BUU(<@=BHzCPqSCy8UJuJADdv^ZTga%-n=ti|?ZRSMRLfdasH4AK-JCdjJ3c diff --git a/win/vncviewer/vncviewer.cxx b/win/vncviewer/vncviewer.cxx deleted file mode 100644 index 1c68808a..00000000 --- a/win/vncviewer/vncviewer.cxx +++ /dev/null @@ -1,310 +0,0 @@ -/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved. - * - * This 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 software 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 software; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - -// -=- VNC Viewer for Win32 - -#include -#ifdef WIN32 -#define strcasecmp _stricmp -#endif -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef _DIALOG_CAPTURE -#include -#endif - -using namespace rfb; -using namespace rfb::win32; -using namespace rdr; -using namespace network; - -static LogWriter vlog("main"); - -TStr rfb::win32::AppName("VNC Viewer"); - - -#ifdef _DIALOG_CAPTURE -BoolParameter captureDialogs("CaptureDialogs", "", false); -#endif - -// -// -=- Listener -// Class to handle listening on a particular port for incoming connections -// from servers, and spawning of clients -// - -static BoolParameter acceptIncoming("Listen", "Accept incoming connections from VNC servers.", false); - - -// -// -=- AboutDialog global values -// - -const WORD rfb::win32::AboutDialog::DialogId = IDD_ABOUT; -const WORD rfb::win32::AboutDialog::Copyright = IDC_COPYRIGHT; -const WORD rfb::win32::AboutDialog::Version = IDC_VERSION; -const WORD rfb::win32::AboutDialog::BuildTime = IDC_BUILDTIME; -const WORD rfb::win32::AboutDialog::Description = IDC_DESCRIPTION; - - -// -// -=- processParams -// Read in the command-line parameters and interpret them. -// - -void -programInfo() { - win32::FileVersionInfo inf; - _tprintf(_T("%s - %s, Version %s\n"), - inf.getVerString(_T("ProductName")), - inf.getVerString(_T("FileDescription")), - inf.getVerString(_T("FileVersion"))); - printf("%s\n", buildTime); - _tprintf(_T("%s\n\n"), inf.getVerString(_T("LegalCopyright"))); -} - -void -programUsage() { - printf("usage: vncviewer [:]\n"); - printf("Command-line options:\n"); - printf(" -help - Provide usage information.\n"); - printf(" -config - Load connection settings from VNC Viewer 3.3 settings file\n"); - printf(" -console - Run with a console window visible.\n"); - printf(" = - Set the named configuration parameter.\n"); - printf(" (Parameter values specified on the command-line override those specified by other configuration methods.)\n"); - printf("\nLog names:\n"); - LogWriter::listLogWriters(); - printf("\nLog destinations:\n"); - Logger::listLoggers(); - printf("\nParameters:\n"); - Configuration::listParams(ConfViewer); - printf("Press Enter/Return key to continue\n"); - getchar(); - exit(1); -} - - -bool print_usage = false; -bool close_console = true; -std::list hosts; -std::list configFiles; - -void -processParams(int argc, char* argv[]) { - - Configuration::enableViewerParams(); - - for (int i=1; i=, or - - if (Configuration::setParam(argv[i], true)) - continue; - // Try to process -