123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 |
- /* Copyright (C) 2002-2004 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/wait.h>
- #include <unistd.h>
- #include <errno.h>
- #include <signal.h>
- #include <rfb/Logger_stdio.h>
- #include <rfb/LogWriter.h>
- #include <network/TcpSocket.h>
- #include "TXWindow.h"
- #include "CConn.h"
-
- #include <intl/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;
-
- 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 rfbauth("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);
-
- BoolParameter listenMode("listen", "Listen for connections from VNC servers",
- false);
- StringParameter geometry("geometry", "X geometry specification", "");
- StringParameter displayname("display", "The X display", "");
-
- 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",
- 6);
-
- 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);
- }
-
- int main(int argc, char** argv)
- {
- setlocale(LC_ALL, "");
- bindtextdomain(PACKAGE, LOCALEDIR);
- textdomain(PACKAGE);
-
- snprintf(aboutText, sizeof(aboutText),
- _("TightVNC viewer for X version 4.0 - built %s\n"
- "Copyright (C) 2002-2004 RealVNC Ltd.\n"
- "Copyright (C) 2000-2004 Constantin Kaplinsky.\n"
- "Copyright (C) 2004 Peter Astrand, Cendio AB\n"
- "See http://www.tightvnc.com for information on TightVNC."),
- buildtime);
- fprintf(stderr,"\n%s\n", aboutText);
-
- rfb::initStdIOLoggers();
- rfb::LogWriter::setLogParams("*:stderr:30");
-
- signal(SIGHUP, CleanupSignalHandler);
- signal(SIGINT, CleanupSignalHandler);
- signal(SIGTERM, CleanupSignalHandler);
-
- programName = argv[0];
- char* vncServerName = 0;
- Display* dpy;
-
- 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();
- }
-
- if (vncServerName)
- usage();
- vncServerName = argv[i];
- }
-
- if (!::autoSelect.hasBeenSet()) {
- // Default to AutoSelect=0 if -PreferredEncoding or -FullColor is used
- ::autoSelect.setParam(!::preferredEncoding.hasBeenSet()
- && !::fullColour.hasBeenSet()
- && !::fullColourAlias.hasBeenSet());
- }
- if (!::customCompressLevel.hasBeenSet()) {
- // Default to CustomCompressLevel=1 if CompressLevel is used.
- ::customCompressLevel.setParam(::compressLevel.hasBeenSet());
- }
-
- try {
- TcpSocket::initTcpSockets();
-
- Socket* sock = 0;
-
- if (listenMode) {
- int port = 5500;
- if (vncServerName && isdigit(vncServerName[0]))
- port = atoi(vncServerName);
-
- TcpListener listener(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);
-
- // X events are processed whenever reading from the socket would block.
-
- while (true) {
- cc.getInStream()->check(1);
- cc.processMsg();
- }
-
- } catch (rdr::Exception &e) {
- vlog.error(e.str());
- }
-
- return 0;
- }
|