Browse Source

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
tags/v1.1.90
DRC 12 years ago
parent
commit
3591fa5b96
52 changed files with 55 additions and 9707 deletions
  1. 55
    63
      CMakeLists.txt
  2. 0
    4
      unix/CMakeLists.txt
  3. 0
    42
      unix/vncviewer/AboutDialog.h
  4. 0
    1038
      unix/vncviewer/CConn.cxx
  5. 0
    141
      unix/vncviewer/CConn.h
  6. 0
    13
      unix/vncviewer/CMakeLists.txt
  7. 0
    580
      unix/vncviewer/DesktopWindow.cxx
  8. 0
    142
      unix/vncviewer/DesktopWindow.h
  9. 0
    60
      unix/vncviewer/InfoDialog.h
  10. 0
    314
      unix/vncviewer/OptionsDialog.h
  11. 0
    72
      unix/vncviewer/PasswdDialog.h
  12. 0
    91
      unix/vncviewer/ServerDialog.h
  13. 0
    18
      unix/vncviewer/buildtime.c
  14. 0
    271
      unix/vncviewer/gettext.h
  15. 0
    49
      unix/vncviewer/parameters.h
  16. 0
    423
      unix/vncviewer/vncviewer.cxx
  17. 0
    224
      unix/vncviewer/vncviewer.man
  18. 0
    4
      win/CMakeLists.txt
  19. 0
    863
      win/vncviewer/CConn.cxx
  20. 0
    169
      win/vncviewer/CConn.h
  21. 0
    507
      win/vncviewer/CConnOptions.cxx
  22. 0
    104
      win/vncviewer/CConnOptions.h
  23. 0
    197
      win/vncviewer/CConnThread.cxx
  24. 0
    57
      win/vncviewer/CConnThread.h
  25. 0
    36
      win/vncviewer/CMakeLists.txt
  26. 0
    161
      win/vncviewer/ConnectingDialog.cxx
  27. 0
    65
      win/vncviewer/ConnectingDialog.h
  28. 0
    72
      win/vncviewer/ConnectionDialog.cxx
  29. 0
    52
      win/vncviewer/ConnectionDialog.h
  30. 0
    1350
      win/vncviewer/DesktopWindow.cxx
  31. 0
    294
      win/vncviewer/DesktopWindow.h
  32. 0
    65
      win/vncviewer/InfoDialog.cxx
  33. 0
    48
      win/vncviewer/InfoDialog.h
  34. 0
    55
      win/vncviewer/ListenServer.h
  35. 0
    95
      win/vncviewer/ListenTrayIcon.h
  36. 0
    133
      win/vncviewer/MRU.h
  37. 0
    420
      win/vncviewer/OptionsDialog.cxx
  38. 0
    48
      win/vncviewer/OptionsDialog.h
  39. 0
    85
      win/vncviewer/UserPasswdDialog.cxx
  40. 0
    58
      win/vncviewer/UserPasswdDialog.h
  41. 0
    104
      win/vncviewer/ViewerToolBar.cxx
  42. 0
    35
      win/vncviewer/ViewerToolBar.h
  43. 0
    18
      win/vncviewer/buildTime.cxx
  44. BIN
      win/vncviewer/cursor1.cur
  45. 0
    119
      win/vncviewer/resource.h
  46. BIN
      win/vncviewer/toolbar.bmp
  47. BIN
      win/vncviewer/vncviewer.bmp
  48. 0
    310
      win/vncviewer/vncviewer.cxx
  49. 0
    22
      win/vncviewer/vncviewer.exe.manifest
  50. 0
    22
      win/vncviewer/vncviewer.exe.manifest64
  51. BIN
      win/vncviewer/vncviewer.ico
  52. 0
    594
      win/vncviewer/vncviewer.rc

+ 55
- 63
CMakeLists.txt View File

@@ -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 <FL/Fl_Widget.H>\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 <FL/Fl_Widget.H>\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 <FL/Fl.H>\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 <FL/Fl.H>\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 <FL/Enumerations.H>\nint main(int c, char** v) { return FL_Volume_Down; }" HAVE_FLTK_MEDIAKEYS)
# FLTK STR #2638
check_cxx_source_compiles("#include <FL/Enumerations.H>\nint main(int c, char** v) { return FL_Volume_Down; }" HAVE_FLTK_MEDIAKEYS)

# FLTK STR #2641
check_cxx_source_compiles("#include <FL/Enumerations.H>\nint main(int c, char** v) { return FL_FULLSCREEN; }" HAVE_FLTK_FULLSCREEN)
# FLTK STR #2641
check_cxx_source_compiles("#include <FL/Enumerations.H>\nint main(int c, char** v) { return FL_FULLSCREEN; }" HAVE_FLTK_FULLSCREEN)

# FLTK STR #2660
check_cxx_source_compiles("#include <FL/Fl_Window.H>\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 <FL/Fl_Window.H>\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)


+ 0
- 4
unix/CMakeLists.txt View File

@@ -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)

+ 0
- 42
unix/vncviewer/AboutDialog.h View File

@@ -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

+ 0
- 1038
unix/vncviewer/CConn.cxx
File diff suppressed because it is too large
View File


+ 0
- 141
unix/vncviewer/CConn.h View File

@@ -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 <rfb/CConnection.h>
#include <rfb/Exception.h>
#include <rfb/UserPasswdGetter.h>
#include <rfb/UserMsgBox.h>
#include <rdr/FdInStream.h>
#include <list>

#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<rfb::Rect> 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

+ 0
- 13
unix/vncviewer/CMakeLists.txt View File

@@ -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})

+ 0
- 580
unix/vncviewer/DesktopWindow.cxx View File

@@ -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 <rfb/CMsgWriter.h>
#include <rfb/LogWriter.h>
#include <X11/keysym.h>
#include <X11/Xatom.h>
#include <stdio.h>
#include <string.h>
#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);
}
}
}
}
}

+ 0
- 142
unix/vncviewer/DesktopWindow.h View File

@@ -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 <rfb/Cursor.h>
#include <rfb/Rect.h>
#include <rfb/Region.h>
#include <rfb/Timer.h>
#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

+ 0
- 60
unix/vncviewer/InfoDialog.h View File

@@ -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

+ 0
- 314
unix/vncviewer/OptionsDialog.h View File

@@ -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

+ 0
- 72
unix/vncviewer/PasswdDialog.h View File

@@ -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

+ 0
- 91
unix/vncviewer/ServerDialog.h View File

@@ -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

+ 0
- 18
unix/vncviewer/buildtime.c View File

@@ -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__;

+ 0
- 271
unix/vncviewer/gettext.h View File

@@ -1,271 +0,0 @@
/* Convenience header for conditional use of GNU <libintl.h>.
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 <libintl.h>

/* 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 <locale.h> a NOP. We don't include <libintl.h>
as well because people using "gettext.h" will not include <libintl.h>,
and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
is OK. */
#if defined(__sun)
# include <locale.h>
#endif

/* Many header files from the libstdc++ coming with g++ 3.3 or newer include
<libintl.h>, which chokes if dcgettext is defined as a macro. So include
it now, to make later inclusions of <libintl.h> a NOP. */
#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
# include <cstdlib>
# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H
# include <libintl.h>
# 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 <string.h>

#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \
(((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \
/* || __STDC_VERSION__ >= 199901L */ )

#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
#include <stdlib.h>
#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 */

+ 0
- 49
unix/vncviewer/parameters.h View File

@@ -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 <rfb/Configuration.h>

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

+ 0
- 423
unix/vncviewer/vncviewer.cxx View File

@@ -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 <string.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <locale.h>
#include <os/os.h>
#include <rfb/Logger_stdio.h>
#include <rfb/SecurityClient.h>
#include <rfb/LogWriter.h>
#include <network/TcpSocket.h>
#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 -<param> or off with -<param>=0\n"
"Parameters which take a value can be specified as "
"-<param> <value>\n"
"Other valid forms are <param>=<value> -<param>=<value> "
"--<param>=<value>\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;
}

+ 0
- 224
unix/vncviewer/vncviewer.man View File

@@ -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.

+ 0
- 4
win/CMakeLists.txt View File

@@ -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)

+ 0
- 863
win/vncviewer/CConn.cxx View File

@@ -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 <config.h>
#endif

#include <winsock2.h>
#include <vncviewer/UserPasswdDialog.h>
#include <vncviewer/CConn.h>
#include <vncviewer/CConnThread.h>
#include <vncviewer/resource.h>
#include <rfb/encodings.h>
#include <rfb/Security.h>
#include <rfb/CMsgWriter.h>
#include <rfb/Configuration.h>
#ifdef HAVE_GNUTLS
#include <rfb/CSecurityTLS.h>
#endif
#include <rfb/LogWriter.h>
#include <rfb_win32/AboutDialog.h>

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 <MenuKey> 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;i<count;i++)
window->setColour(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<rfb::Rect>::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);
}


+ 0
- 169
win/vncviewer/CConn.h View File

@@ -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 <network/Socket.h>
#include <rfb/CConnection.h>
#include <rfb/Cursor.h>
#include <rfb/UserMsgBox.h>
#include <rfb/UserPasswdGetter.h>
#include <rfb_win32/Registry.h>
#include <rfb_win32/Handle.h>
#include <vncviewer/InfoDialog.h>
#include <vncviewer/OptionsDialog.h>
#include <vncviewer/CConnOptions.h>
#include <vncviewer/DesktopWindow.h>
#include <list>


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<Rect> debugRects;
CharArray closeReason_;
bool isClosed_;
};

};

};

#endif



+ 0
- 507
win/vncviewer/CConnOptions.cxx View File

@@ -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 <vncviewer/CConnOptions.h>
#include <rfb/Configuration.h>
#include <rfb/encodings.h>
#include <rfb/LogWriter.h>
#include <rfb/ScaleFilters.h>
#include <rfb_win32/MsgBox.h>
#include <rfb_win32/Registry.h>
#include <rfb/SecurityClient.h>
#include <rdr/HexInStream.h>
#include <rdr/HexOutStream.h>
#include <stdlib.h>

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], ']', &section.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<rdr::U32>::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;
}

+ 0
- 104
win/vncviewer/CConnOptions.h View File

@@ -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 <rdr/types.h>
#include <rfb/Password.h>

#include <list>

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<rdr::U32> 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

+ 0
- 197
win/vncviewer/CConnThread.cxx View File

@@ -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 <stdlib.h>
#include <rfb/LogWriter.h>
#include <rfb_win32/MsgBox.h>
#include <network/TcpSocket.h>
#include <vncviewer/CConnThread.h>
#include <vncviewer/CConn.h>
#include <vncviewer/ConnectionDialog.h>
#include <vncviewer/ConnectingDialog.h>
#include <vncviewer/UserPasswdDialog.h>
#include <set>

using namespace rfb;
using namespace win32;

static LogWriter vlog("CConnThread");

static std::set<CConnThread*> 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;
}

+ 0
- 57
win/vncviewer/CConnThread.h View File

@@ -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 <network/Socket.h>
#include <rfb/Threading.h>
#include <rfb/util.h>

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__

+ 0
- 36
win/vncviewer/CMakeLists.txt View File

@@ -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 .
)

+ 0
- 161
win/vncviewer/ConnectingDialog.cxx View File

@@ -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 <stdlib.h>
#include <vncviewer/ConnectingDialog.h>
#include <vncviewer/resource.h>
#include <network/TcpSocket.h>
#include <rfb/Threading.h>
#include <rfb/Hostname.h>
#include <map>

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<int, ConnectingDialog*> 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;
}

+ 0
- 65
win/vncviewer/ConnectingDialog.h View File

@@ -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 <windows.h>
#include <network/Socket.h>
#include <rfb/util.h>
#include <rfb_win32/Handle.h>

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

+ 0
- 72
win/vncviewer/ConnectionDialog.cxx View File

@@ -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 <vncviewer/ConnectionDialog.h>
#include <vncviewer/CConn.h>
#include <vncviewer/resource.h>
#include <rfb_win32/AboutDialog.h>

#include <tchar.h>

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<char*> mru = MRU::getEntries();
std::list<char*>::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;
}

+ 0
- 52
win/vncviewer/ConnectionDialog.h View File

@@ -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 <rfb_win32/Dialog.h>
#include <vncviewer/MRU.h>
#include <rfb/util.h>

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

+ 0
- 1350
win/vncviewer/DesktopWindow.cxx
File diff suppressed because it is too large
View File


+ 0
- 294
win/vncviewer/DesktopWindow.h View File

@@ -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 <rfb/Cursor.h>
#include <rfb_win32/CKeyboard.h>
#include <rfb_win32/CPointer.h>
#include <rfb_win32/Clipboard.h>
#include <rfb_win32/ScaledDIBSectionBuffer.h>
#include <rfb_win32/LogicalPalette.h>
#include <vncviewer/ViewerToolBar.h>


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__



+ 0
- 65
win/vncviewer/InfoDialog.cxx View File

@@ -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 <vncviewer/InfoDialog.h>
#include <vncviewer/resource.h>
#include <vncviewer/CConn.h>
#include <rfb/Security.h>
#include <rfb/encodings.h>
#include <rfb/CSecurity.h>
#include <rfb/LogWriter.h>

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()));
}

+ 0
- 48
win/vncviewer/InfoDialog.h View File

@@ -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 <rfb_win32/Dialog.h>
#include <rfb/util.h>

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

+ 0
- 55
win/vncviewer/ListenServer.h View File

@@ -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 <winsock2.h>
#include <network/Socket.h>
#include <rfb_win32/MsgWindow.h>
#include <vncviewer/CConnThread.h>


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

+ 0
- 95
win/vncviewer/ListenTrayIcon.h View File

@@ -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 <rfb_win32/TrayIcon.h>
#include <rfb_win32/AboutDialog.h>

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__

+ 0
- 133
win/vncviewer/MRU.h View File

@@ -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 <windows.h>
#include <list>
#include <set>
#include <rfb_win32/Registry.h>
#include <rfb/util.h>
#include <rdr/HexOutStream.h>

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<char*> getEntries() {
std::list<char*> 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<length; i++) {
TCharArray keyname(rdr::HexOutStream::binToHexStr(&order.buf[i], 1));
try {
TCharArray entry(key.getString(keyname.buf));
mru.push_back(strDup(entry.buf));
} catch (rdr::Exception) {
}
}
} catch (rdr::Exception) {
}

return mru;
}

static void addToMRU(const char* name) {
RegKey key;
key.createKey(RegRoot, RegPath);

BYTE keycode;
CharArray old_order;
char order[MaxMRUEntries];
int orderlen;
try {
key.getBinary(_T("Order"), (void**)&old_order.buf, &orderlen);
if (orderlen)
memcpy(order, old_order.buf, orderlen);

std::set<int> ordercodes;
keycode = 0;
bool found = false;
for (int i=0; i<orderlen; i++) {
TCharArray keyname(rdr::HexOutStream::binToHexStr(&order[i], 1));
try {
TCharArray hostname(key.getString(keyname.buf));
if (stricmp(name, CStr(hostname.buf)) == 0) {
keycode = order[i];
found = true;
break;
}
} catch (rdr::Exception) {
}
ordercodes.insert(order[i]);
}

if (!found) {
if (orderlen <= MRUEntries) {
while (ordercodes.find(keycode) != ordercodes.end()) keycode++;
} else {
keycode = order[orderlen-1];
orderlen--;
}
}

} catch (rdr::Exception) {
keycode = 0;
orderlen = 0;
}

orderlen++;
int i, j=orderlen-1;
for (i=0; i<orderlen-1; i++) {
if (order[i] == keycode) {
j = i;
orderlen--;
break;
}
}
for (i=j; i>0; 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

+ 0
- 420
win/vncviewer/OptionsDialog.cxx View File

@@ -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 <vncviewer/OptionsDialog.h>
#include <vncviewer/CConn.h>
#include <vncviewer/resource.h>
#include <rfb_win32/Registry.h>
#include <rfb_win32/MsgBox.h>
#include <rfb_win32/OSVersion.h>
#include <rfb_win32/SecurityPage.h>
#include <rfb/encodings.h>
#include <rfb/CConnection.h>
#include <commdlg.h>
#include <rfb/LogWriter.h>
#include <rfb/Security.h>

#include <list>

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<PropSheetPage*> 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<PropSheetPage*> 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;
}

+ 0
- 48
win/vncviewer/OptionsDialog.h View File

@@ -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 <rfb_win32/Dialog.h>

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

+ 0
- 85
win/vncviewer/UserPasswdDialog.cxx View File

@@ -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 <vncviewer/UserPasswdDialog.h>
#include <vncviewer/resource.h>
#include <rfb/Exception.h>

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);
}

+ 0
- 58
win/vncviewer/UserPasswdDialog.h View File

@@ -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 <rfb_win32/Dialog.h>
#include <rfb_win32/TCharArray.h>
#include <rfb/CSecurity.h>
#include <rfb/UserPasswdGetter.h>

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

+ 0
- 104
win/vncviewer/ViewerToolBar.cxx View File

@@ -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 <vncviewer/ViewerToolBar.h>
#include <vncviewer/resource.h>

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;
}

+ 0
- 35
win/vncviewer/ViewerToolBar.h View File

@@ -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 <rfb_win32/ToolBar.h>

using namespace rfb::win32;

class ViewerToolBar : public ToolBar {
public:
ViewerToolBar() {}
~ViewerToolBar() {}

void create(HWND parentHwnd);

LRESULT processWM_NOTIFY(WPARAM wParam, LPARAM lParam);
};

+ 0
- 18
win/vncviewer/buildTime.cxx View File

@@ -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__;

BIN
win/vncviewer/cursor1.cur View File


+ 0
- 119
win/vncviewer/resource.h View File

@@ -1,119 +0,0 @@
// Used by vncviewer.rc

#include <rfb_win32/resource.h>

#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

BIN
win/vncviewer/toolbar.bmp View File


BIN
win/vncviewer/vncviewer.bmp View File


+ 0
- 310
win/vncviewer/vncviewer.cxx View File

@@ -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 <string.h>
#ifdef WIN32
#define strcasecmp _stricmp
#endif
#include <list>

#include <vncviewer/ListenServer.h>
#include <vncviewer/resource.h>
#include <vncviewer/CConn.h>
#include <vncviewer/CConnThread.h>
#include <vncviewer/OptionsDialog.h>
#include <vncviewer/ListenTrayIcon.h>
#include <network/TcpSocket.h>
#include <os/os.h>
#include <rfb/Logger_stdio.h>
#include <rfb/Logger_file.h>
#include <rfb/LogWriter.h>
#include <rfb/Exception.h>
#include <rfb_win32/RegConfig.h>
#include <rfb_win32/MsgBox.h>

#ifdef _DIALOG_CAPTURE
#include <extra/LoadBMP.h>
#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 <options> <hostname>[:<display>]\n");
printf("Command-line options:\n");
printf(" -help - Provide usage information.\n");
printf(" -config <file> - Load connection settings from VNC Viewer 3.3 settings file\n");
printf(" -console - Run with a console window visible.\n");
printf(" <setting>=<value> - 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<char*> hosts;
std::list<char*> configFiles;

void
processParams(int argc, char* argv[]) {

Configuration::enableViewerParams();

for (int i=1; i<argc; i++) {
try {

if (strcasecmp(argv[i], "-console") == 0) {
close_console = false;

} else if (((strcasecmp(argv[i], "-config") == 0) ||
(strcasecmp(argv[i], "/config") == 0)) && (i < argc-1)) {
configFiles.push_back(strDup(argv[i+1]));
i++;

} else if ((strcasecmp(argv[i], "-help") == 0) ||
(strcasecmp(argv[i], "--help") == 0) ||
(strcasecmp(argv[i], "-h") == 0) ||
(strcasecmp(argv[i], "/?") == 0)) {
print_usage = true;
close_console = false;
break;

} else {
// Try to process <option>=<value>, or -<bool>
if (Configuration::setParam(argv[i], true))
continue;
// Try to process -<option> <value>
if ((argv[i][0] == '-') && (i+1 < argc)) {
if (Configuration::setParam(&argv[i][1], argv[i+1], true)) {
i++;
continue;
}
}
// If it's -<option> then it's not recognised - error
// If it's <host> then add it to the list to connect to.
if ((argv[i][0] == '-') || (argv[i][0] == '/')) {
const char* fmt = "The option %s was not recognized. Use -help to see VNC Viewer usage";
CharArray tmp(strlen(argv[i])+strlen(fmt)+1);
sprintf(tmp.buf, fmt, argv[i]);
MsgBox(0, TStr(tmp.buf), MB_ICONSTOP | MB_OK);
exit(1);
} else if (strContains(argv[i], '\\')) {
configFiles.push_back(strDup(argv[i]));
} else {
hosts.push_back(strDup(argv[i]));
}
}

} catch (rdr::Exception& e) {
vlog.error(e.str());
}
}
}


//
// -=- main
//

int WINAPI WinMain(HINSTANCE inst, HINSTANCE prevInst, char* cmdLine, int cmdShow) {
try {

// - Initialise the available loggers
initStdIOLoggers();
initFileLogger("C:\\temp\\vncviewer4.log");

// - By default, just log errors to stderr
logParams.setDefault("*:stderr:0");

// - Process the command-line
int argc = __argc;
char** argv = __argv;
processParams(argc, argv);

// - By default the console will be closed
if (close_console) {
if (!FreeConsole())
vlog.info("unable to close console:%u", GetLastError());
} else {
AllocConsole();
freopen("CONIN$","rb",stdin);
freopen("CONOUT$","wb",stdout);
freopen("CONOUT$","wb",stderr);
setbuf(stderr, 0);
}

#ifdef _DIALOG_CAPTURE
if (captureDialogs) {
CConn::userConfigKey.openKey(HKEY_CURRENT_USER, _T("Software\\TigerVNC\\VNCViewer4"));
OptionsDialog::global.showDialog(0, true);
return 0;
}
#endif

// - If no clients are specified, bring up a connection dialog
if (configFiles.empty() && hosts.empty() && !acceptIncoming && !print_usage)
hosts.push_back(0);

programInfo();

// 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 directory: can't obtain home directory path");
else {
int result = CreateDirectory(homeDir, NULL);
if (result <= 0 && GetLastError() != ERROR_ALREADY_EXISTS)
vlog.error("Could not create vnc directory: %u", GetLastError());
delete [] homeDir;
}

// - Connect to the clients
if (!configFiles.empty() || !hosts.empty() || acceptIncoming) {
// - Configure the registry configuration reader
win32::RegConfigThread config;
config.start(HKEY_CURRENT_USER, _T("Software\\TigerVNC\\VNCViewer4"));

// - Tell the rest of VNC Viewer where to write config data to
CConn::userConfigKey.createKey(HKEY_CURRENT_USER, _T("Software\\TigerVNC\\VNCViewer4"));

if (acceptIncoming) {
int port = 5500;

// Listening viewer
if (hosts.size() > 1)
programUsage();
if (!hosts.empty())
port = atoi(hosts.front());

// Show the tray icon & menu
ListenTrayIcon tray;

// Listen for reverse connections
network::TcpListener sock(NULL, port);
ListenServer listener(&sock);

// Run the view manager
// Also processes the tray icon if necessary
MSG msg;
while (GetMessage(&msg, NULL, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} else {
// Read each config file in turn
while (!configFiles.empty()) {
char* filename = configFiles.front();
new CConnThread(filename, true);
strFree(filename);
configFiles.pop_front();
}

// Connect to each client in turn
while (!hosts.empty()) {
char* hostinfo = hosts.front();
new CConnThread(hostinfo);
strFree(hostinfo);
hosts.pop_front();
}

// Run the view manager
MSG msg;
while (CConnThread::getMessage(&msg, NULL, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}

vlog.debug("quitting viewer");
}

}

// - If necessary, print the program's usage info
if (print_usage)
programUsage();

if (!close_console) {
printf("Press Enter/Return key to continue\n");
getchar();
}

} catch (rdr::Exception& e) {
MsgBox(0, TStr(e.str()), MB_ICONSTOP | MB_OK);
}

return 0;
}

+ 0
- 22
win/vncviewer/vncviewer.exe.manifest View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="4.0.0.26"
processorArchitecture="X86"
name="TigerVNC.vncviewer.exe"
type="win32"
/>
<description>.NET control deployment tool</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="X86"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>

+ 0
- 22
win/vncviewer/vncviewer.exe.manifest64 View File

@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="4.0.0.26"
processorArchitecture="AMD64"
name="TigerVNC.vncviewer.exe"
type="win32"
/>
<description>.NET control deployment tool</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="AMD64"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>

BIN
win/vncviewer/vncviewer.ico View File


+ 0
- 594
win/vncviewer/vncviewer.rc View File

@@ -1,594 +0,0 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#include "resdefs.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "windows.h"

#ifndef IDC_STATIC
#define IDC_STATIC -1
#endif

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// English (U.K.) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
#pragma code_page(1252)
#endif //_WIN32

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END

2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""windows.h""\r\n"
"\0"
END

3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END

#endif // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// Icon
//

// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON ICON DISCARDABLE "vncviewer.ico"

#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//

VS_VERSION_INFO VERSIONINFO
FILEVERSION __RCVERSION
PRODUCTVERSION __RCVERSION
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080904b0"
BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "TigerVNC Project\0"
#ifdef WIN64
VALUE "FileDescription", "TigerVNC Viewer for Win64\0"
VALUE "ProductName", "TigerVNC Viewer for Win64\0"
#else
VALUE "FileDescription", "TigerVNC Viewer for Win32\0"
VALUE "ProductName", "TigerVNC Viewer for Win32\0"
#endif
VALUE "FileVersion", __RCVERSIONSTR
VALUE "InternalName", "free4/vncviewer/win\0"
VALUE "LegalCopyright", "Copyright (C) 1999-2011 TigerVNC Team and many others (see README.txt)\0"
VALUE "LegalTrademarks", "TigerVNC\0"
VALUE "OriginalFilename", "vncviewer.exe\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductVersion", __VERSIONSTR
VALUE "SpecialBuild", "\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x809, 1200
END
END

#endif // !_MAC


/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

IDD_VNC_AUTH_DLG DIALOG DISCARDABLE 0, 0, 241, 46
STYLE DS_SETFOREGROUND | DS_CENTER | WS_POPUP | WS_CAPTION
CAPTION "VNC Viewer : Authentication"
FONT 8, "MS Sans Serif"
BEGIN
EDITTEXT IDC_USERNAME,85,6,100,14,ES_AUTOHSCROLL
EDITTEXT IDC_PASSWORD,85,25,100,15,ES_PASSWORD | ES_AUTOHSCROLL |
ES_WANTRETURN
DEFPUSHBUTTON "OK",IDOK,190,6,45,14
PUSHBUTTON "Cancel",IDCANCEL,190,25,45,15
CONTROL 120,IDI_ICON,"Static",SS_BITMAP,7,6,21,20
LTEXT "Username:",IDC_STATIC,45,6,35,14
LTEXT "Password:",IDC_STATIC,45,25,35,15
END

IDD_CONNECTING_DLG DIALOG DISCARDABLE 0, 0, 185, 47
STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_CENTER | WS_POPUP | WS_CAPTION
CAPTION "VNC Viewer : Connecting"
FONT 8, "MS Sans Serif"
BEGIN
PUSHBUTTON "Cancel",IDCANCEL,128,26,50,14
CTEXT "Attempting to connect to host...",IDC_CONNECTING_TEXT,7,
7,171,14,SS_CENTERIMAGE
END

IDD_CONNECTION_DLG DIALOG DISCARDABLE 0, 0, 224, 66
STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_CENTER | WS_POPUP | WS_CAPTION |
WS_SYSMENU
CAPTION "VNC Viewer : Connection Details"
FONT 8, "MS Sans Serif"
BEGIN
COMBOBOX IDC_SERVER_EDIT,85,15,105,234,CBS_DROPDOWN |
CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "&About...",IDC_ABOUT,5,45,50,14
PUSHBUTTON "&Options...",IDC_OPTIONS,60,45,50,14
DEFPUSHBUTTON "OK",IDOK,115,45,50,14
PUSHBUTTON "Cancel",IDCANCEL,170,45,48,14
CONTROL 120,IDI_ICON,"Static",SS_BITMAP | SS_REALSIZEIMAGE,5,6,
20,20
RTEXT "Server:",IDC_STATIC,43,15,37,13,SS_CENTERIMAGE
END

IDD_ABOUT DIALOG DISCARDABLE 0, 0, 300, 92
STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_CENTER | WS_POPUP | WS_CAPTION |
WS_SYSMENU
CAPTION "About TigerVNC Viewer for Windows"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,245,70,47,15
CONTROL 120,IDC_STATIC,"Static",SS_BITMAP | SS_REALSIZEIMAGE,7,
10,33,31
LTEXT ">appname<",IDC_DESCRIPTION,46,10,119,15
LTEXT ">version<",IDC_VERSION,165,10,77,15
LTEXT ">buildtime<",IDC_BUILDTIME,46,25,196,15
LTEXT ">copyright<",IDC_COPYRIGHT,46,40,250,15
LTEXT "Visit www.tigervnc.org for more information on TigerVNC.",
IDC_STATIC,46,55,196,15
END

IDD_FORMAT DIALOG DISCARDABLE 0, 0, 201, 161
STYLE DS_MODALFRAME | DS_CONTROL | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Colour && Encoding"
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "&Auto select",IDC_ENCODING_AUTO,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,7,7,88,13
GROUPBOX "Preferred encoding",IDC_STATIC,7,20,83,75
CONTROL "Tight",IDC_ENCODING_TIGHT,"Button",BS_AUTORADIOBUTTON |
WS_GROUP,10,30,75,14
CONTROL "ZRLE",IDC_ENCODING_ZRLE,"Button",BS_AUTORADIOBUTTON,10,
45,75,14
CONTROL "Hextile",IDC_ENCODING_HEXTILE,"Button",
BS_AUTORADIOBUTTON,10,60,75,16
CONTROL "Raw",IDC_ENCODING_RAW,"Button",BS_AUTORADIOBUTTON,10,75,
75,15
GROUPBOX "Color level",IDC_STATIC,95,20,99,75
CONTROL "&Full (all available colors)",IDC_FORMAT_FULLCOLOUR,
"Button",BS_AUTORADIOBUTTON | WS_GROUP,100,30,90,15
CONTROL "&Medium (256 colors)",IDC_FORMAT_MEDIUMCOLOUR,"Button",
BS_AUTORADIOBUTTON,100,45,90,14
CONTROL "&Low (64 colors)",IDC_FORMAT_LOWCOLOUR,"Button",
BS_AUTORADIOBUTTON,100,60,90,16
CONTROL "&Very low (8 colors)",IDC_FORMAT_VERYLOWCOLOUR,"Button",
BS_AUTORADIOBUTTON,100,75,90,15
CONTROL "Custom compression level:",IDC_CUSTOM_COMPRESSLEVEL,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,100,99,10
EDITTEXT IDC_COMPRESSLEVEL,25,111,15,12,ES_AUTOHSCROLL |
ES_NUMBER
LTEXT "level (1=fast, 9=best)",IDC_STATIC,44,114,81,9,NOT
WS_GROUP
CONTROL "Allow JPEG compression:",IDC_ALLOW_JPEG,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,10,126,96,10
EDITTEXT IDC_QUALITYLEVEL,25,137,15,12,ES_AUTOHSCROLL | ES_NUMBER
LTEXT "quality (1=poor, 9=best)",IDC_STATIC,44,140,81,9
END

IDD_MISC DIALOG DISCARDABLE 0, 0, 216, 138
STYLE DS_MODALFRAME | DS_CONTROL | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Misc"
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "Shared connection (do not disconnect other viewers)",
IDC_CONN_SHARED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,
10,202,15
CONTROL "Full-screen mode",IDC_FULL_SCREEN,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,7,25,99,15
CONTROL "Render cursor locally",IDC_LOCAL_CURSOR,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,7,40,99,15
CONTROL "Allow dynamic desktop resizing",IDC_DESKTOP_RESIZE,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,55,112,15
CONTROL "Only use protocol version 3.3",IDC_PROTOCOL_3_3,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,7,70,111,15
CONTROL "Beep when requested to by the server",IDC_ACCEPT_BELL,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,85,202,15
CONTROL "Offer to automatically reconnect",IDC_AUTO_RECONNECT,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,100,202,15
CONTROL "Show toolbar",IDC_SHOW_TOOLBAR,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,106,25,103,15
COMBOBOX IDC_COMBO_SCALE,138,40,42,134,CBS_DROPDOWN | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
LTEXT "Scale by:",IDC_STATIC_SCALE,106,40,32,15,SS_CENTERIMAGE
LTEXT "%",IDC_STATIC_PERCENT,185,40,24,15,SS_CENTERIMAGE
END

IDD_INPUTS DIALOG DISCARDABLE 0, 0, 186, 162
STYLE DS_MODALFRAME | DS_CONTROL | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Inputs"
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "Send pointer events to server",IDC_SEND_POINTER,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,7,10,172,15
CONTROL "Send keyboard events to server",IDC_SEND_KEYS,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,7,25,172,15
CONTROL "Send clipboard changes to server",IDC_CLIENT_CUTTEXT,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,40,172,15
CONTROL "Accept clipboard changes from server",
IDC_SERVER_CUTTEXT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
7,55,172,15
CONTROL "Enable 3-button mouse emulation",IDC_EMULATE3,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,7,70,172,15
CONTROL "Rate-limit mouse move events",IDC_POINTER_INTERVAL,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,86,172,14
LTEXT "Menu key",IDC_STATIC,7,100,98,15,SS_CENTERIMAGE
COMBOBOX IDC_MENU_KEY,105,100,74,105,CBS_DROPDOWNLIST | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
CONTROL "Pass special keys directly to server",
IDC_DISABLE_WINKEYS,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,7,115,172,15
END

IDD_CONNECTION_INFO DIALOG DISCARDABLE 0, 0, 239, 199
STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_CENTER | WS_POPUP | WS_CAPTION |
WS_SYSMENU
CAPTION "VNC Connection Info"
FONT 8, "MS Sans Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,182,178,50,14
LTEXT "Desktop Name:",IDC_STATIC,7,10,73,15
LTEXT "Host:",IDC_STATIC,7,25,73,15
LTEXT "Size:",IDC_STATIC,7,40,73,15
LTEXT "Pixel Format:",IDC_STATIC,7,55,73,15
LTEXT "Server Default:",IDC_STATIC,7,70,73,15
LTEXT "Line Speed Estimate:",IDC_STATIC,7,115,73,15
LTEXT "Protocol Version:",IDC_STATIC,7,130,73,15
LTEXT "",IDC_INFO_NAME,80,10,152,15
LTEXT "",IDC_INFO_HOST,80,25,152,15
LTEXT "",IDC_INFO_SIZE,80,40,152,15
LTEXT "",IDC_INFO_PF,80,55,152,15
LTEXT "",IDC_INFO_DEF_PF,80,70,152,15
LTEXT "",IDC_INFO_LINESPEED,80,115,152,15
LTEXT "",IDC_INFO_VERSION,80,130,152,15
LTEXT "Security Method:",IDC_STATIC,7,145,73,15
LTEXT "",IDC_INFO_SECURITY,80,145,152,15
LTEXT "Requested Encoding:",IDC_STATIC,7,85,73,15
LTEXT "Last Used Encoding:",IDC_STATIC,7,100,73,15
LTEXT "",IDC_REQUESTED_ENCODING,80,86,152,15
LTEXT "",IDC_LAST_ENCODING,80,100,152,15
LTEXT "Static",IDC_INFO_ENCRYPTION,80,160,152,15
LTEXT "Encryption:",IDC_STATIC,7,160,73,15
END

IDD_DEFAULTS DIALOG DISCARDABLE 0, 0, 217, 87
STYLE DS_MODALFRAME | DS_CONTROL | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Load / Save"
FONT 8, "MS Sans Serif"
BEGIN
PUSHBUTTON "&Reload",IDC_LOAD_CONFIG,15,20,85,15
PUSHBUTTON "&Save",IDC_SAVE_CONFIG,15,40,85,15
PUSHBUTTON "Save &As ...",IDC_SAVE_CONFIG_AS,15,60,85,15
PUSHBUTTON "R&eload",IDC_LOAD_DEFAULTS,120,20,85,15
PUSHBUTTON "S&ave",IDC_SAVE_DEFAULTS,120,40,85,15
GROUPBOX "Configuration File",IDC_STATIC,7,7,100,74
GROUPBOX "Defaults",IDC_STATIC,113,7,97,53
END


IDD_SECURITY DIALOG DISCARDABLE 0, 0, 200, 200
STYLE DS_MODALFRAME | DS_CONTROL | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Security"
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "Extended encryption and authentication methods (VeNCrypt)",
IDC_VENCRYPT, "Button", BS_AUTOCHECKBOX | WS_TABSTOP,
7,10,200,15
GROUPBOX "Session encryption", IDC_STATIC, 7,25,120,60
CONTROL "None", IDC_ENC_NONE, "Button", BS_AUTOCHECKBOX | WS_TABSTOP,
10,35,50,15
CONTROL "Anonymous TLS", IDC_ENC_TLS, "Button",
BS_AUTOCHECKBOX | WS_TABSTOP, 10,50,80,15
CONTROL "TLS with X.509 certificates", IDC_ENC_X509, "Button",
BS_AUTOCHECKBOX | WS_TABSTOP, 10,65,110,15
GROUPBOX "X.509 certificates", IDC_STATIC, 7,90,170,30
PUSHBUTTON "Load CA certificate", IDC_LOAD_CACERT, 10,100,80,15
PUSHBUTTON "Load CRL certificate", IDC_LOAD_CRLCERT, 90,100,80,15
GROUPBOX "Authentication", IDC_STATIC, 7,125,100,60
CONTROL "None", IDC_AUTH_NONE, "Button", BS_AUTOCHECKBOX | WS_TABSTOP,
10,135,50,15
CONTROL "Standard VNC", IDC_AUTH_VNC, "Button",
BS_AUTOCHECKBOX | WS_TABSTOP, 10,150,80,15
CONTROL "Plaintext", IDC_AUTH_PLAIN, "Button",
BS_AUTOCHECKBOX | WS_TABSTOP, 10,165,70,15
END

/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_VNC_AUTH_DLG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 235
VERTGUIDE, 45
VERTGUIDE, 80
VERTGUIDE, 85
VERTGUIDE, 185
VERTGUIDE, 190
TOPMARGIN, 6
BOTTOMMARGIN, 40
HORZGUIDE, 20
HORZGUIDE, 25
HORZGUIDE, 40
END

IDD_CONNECTING_DLG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 178
TOPMARGIN, 7
BOTTOMMARGIN, 40
HORZGUIDE, 21
HORZGUIDE, 26
END

IDD_CONNECTION_DLG, DIALOG
BEGIN
LEFTMARGIN, 5
RIGHTMARGIN, 218
VERTGUIDE, 30
VERTGUIDE, 43
VERTGUIDE, 55
VERTGUIDE, 60
VERTGUIDE, 80
VERTGUIDE, 85
VERTGUIDE, 110
VERTGUIDE, 115
VERTGUIDE, 165
VERTGUIDE, 170
VERTGUIDE, 190
TOPMARGIN, 6
BOTTOMMARGIN, 59
HORZGUIDE, 19
HORZGUIDE, 24
HORZGUIDE, 36
HORZGUIDE, 45
END

IDD_ABOUT, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 242
VERTGUIDE, 46
VERTGUIDE, 165
VERTGUIDE, 195
TOPMARGIN, 7
BOTTOMMARGIN, 85
HORZGUIDE, 10
HORZGUIDE, 25
HORZGUIDE, 40
HORZGUIDE, 55
HORZGUIDE, 70
END

IDD_FORMAT, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 194
VERTGUIDE, 10
VERTGUIDE, 85
VERTGUIDE, 90
VERTGUIDE, 95
VERTGUIDE, 100
VERTGUIDE, 105
VERTGUIDE, 190
TOPMARGIN, 7
BOTTOMMARGIN, 154
HORZGUIDE, 10
HORZGUIDE, 20
HORZGUIDE, 25
HORZGUIDE, 35
HORZGUIDE, 49
HORZGUIDE, 65
HORZGUIDE, 80
HORZGUIDE, 85
END

IDD_MISC, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 209
VERTGUIDE, 106
VERTGUIDE, 138
VERTGUIDE, 180
VERTGUIDE, 185
TOPMARGIN, 7
BOTTOMMARGIN, 131
HORZGUIDE, 10
HORZGUIDE, 25
HORZGUIDE, 40
HORZGUIDE, 55
HORZGUIDE, 70
HORZGUIDE, 85
HORZGUIDE, 100
HORZGUIDE, 115
HORZGUIDE, 130
END

IDD_INPUTS, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 179
VERTGUIDE, 105
TOPMARGIN, 7
BOTTOMMARGIN, 155
HORZGUIDE, 10
HORZGUIDE, 25
HORZGUIDE, 40
HORZGUIDE, 55
HORZGUIDE, 70
HORZGUIDE, 85
HORZGUIDE, 100
HORZGUIDE, 115
HORZGUIDE, 130
HORZGUIDE, 145
END

IDD_CONNECTION_INFO, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 232
VERTGUIDE, 80
TOPMARGIN, 7
BOTTOMMARGIN, 192
HORZGUIDE, 10
HORZGUIDE, 25
HORZGUIDE, 40
HORZGUIDE, 55
HORZGUIDE, 70
HORZGUIDE, 85
HORZGUIDE, 100
HORZGUIDE, 115
HORZGUIDE, 130
HORZGUIDE, 145
HORZGUIDE, 160
HORZGUIDE, 175
END

IDD_DEFAULTS, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 210
VERTGUIDE, 15
VERTGUIDE, 100
VERTGUIDE, 107
VERTGUIDE, 113
VERTGUIDE, 120
VERTGUIDE, 205
TOPMARGIN, 7
BOTTOMMARGIN, 80
HORZGUIDE, 20
HORZGUIDE, 35
HORZGUIDE, 40
HORZGUIDE, 55
HORZGUIDE, 60
HORZGUIDE, 75
END
END
#endif // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// Cursor
//

IDC_DOT_CURSOR CURSOR DISCARDABLE "cursor1.cur"

/////////////////////////////////////////////////////////////////////////////
//
// Dialog Info
//

IDD_CONNECTION_DLG DLGINIT
BEGIN
IDC_SERVER_EDIT, 0x403, 16, 0,
0x796d, 0x616d, 0x6863, 0x6e69, 0x2e65, 0x726f, 0x3a67, 0x0031,
0
END


/////////////////////////////////////////////////////////////////////////////
//
// Menu
//

IDR_TRAY MENU DISCARDABLE
BEGIN
POPUP "Tray Menu"
BEGIN
MENUITEM "&New Connection...", ID_NEW_CONNECTION
MENUITEM SEPARATOR
MENUITEM "Default &Options...", ID_OPTIONS
MENUITEM SEPARATOR
MENUITEM "&Close Daemon", ID_CLOSE
MENUITEM "&About...", ID_ABOUT
END
END


/////////////////////////////////////////////////////////////////////////////
//
// 24
//

#ifdef WIN64
IDR_MANIFEST 24 DISCARDABLE "vncviewer.exe.manifest64"
#else
IDR_MANIFEST 24 DISCARDABLE "vncviewer.exe.manifest"
#endif

/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//

IDB_BITMAP BITMAP DISCARDABLE "vncviewer.bmp"
IDB_TOOLBAR BITMAP DISCARDABLE "toolbar.bmp"
#endif // English (U.K.) resources
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//


/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED


Loading…
Cancel
Save