git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/branches/merge-with-vnc-4.1.1@545 3789f03b-4d11-0410-bbf8-ca57d06f2519tags/v0.0.90
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved. | |||
* | |||
/* 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 |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved. | |||
* | |||
/* 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 | |||
@@ -29,6 +29,7 @@ | |||
#include <rfb/Hostname.h> | |||
#include <rfb/LogWriter.h> | |||
#include <rfb/util.h> | |||
#include <rfb/Password.h> | |||
#include <network/TcpSocket.h> | |||
#include "TXViewport.h" | |||
@@ -49,7 +50,7 @@ StringParameter menuKey("MenuKey", "The key which brings up the popup menu", | |||
StringParameter windowName("name", "The X window name", ""); | |||
CConn::CConn(Display* dpy_, int argc_, char** argv_, network::Socket* sock_, | |||
char* vncServerName) | |||
char* vncServerName, bool reverse) | |||
: dpy(dpy_), argc(argc_), | |||
argv(argv_), serverHost(0), serverPort(0), sock(sock_), viewport(0), | |||
desktop(0), desktopEventHandler(0), | |||
@@ -58,7 +59,8 @@ CConn::CConn(Display* dpy_, int argc_, char** argv_, network::Socket* sock_, | |||
autoSelect(::autoSelect), shared(::shared), formatChange(false), | |||
encodingChange(false), sameMachine(false), fullScreen(::fullScreen), | |||
ctrlDown(false), altDown(false), | |||
menuKeysym(0), menu(dpy, this), options(dpy, this), about(dpy), info(dpy) | |||
menuKeysym(0), menu(dpy, this), options(dpy, this), about(dpy), info(dpy), | |||
reverseConnection(reverse) | |||
{ | |||
CharArray menuKeyStr(menuKey.getData()); | |||
menuKeysym = XStringToKeysym(menuKeyStr.buf); | |||
@@ -160,19 +162,32 @@ void CConn::handleEvent(TXWindow* w, XEvent* ev) | |||
void CConn::blockCallback() { | |||
fd_set rfds; | |||
do { | |||
TXWindow::handleXEvents(dpy); | |||
struct timeval tv; | |||
struct timeval* tvp; | |||
if (Timer::getTimeout(&tv)) | |||
struct timeval* tvp = 0; | |||
// Process any incoming X events | |||
TXWindow::handleXEvents(dpy); | |||
// Process expired timers and get the time until the next one | |||
int timeoutMs = Timer::checkTimeouts(); | |||
if (timeoutMs) { | |||
tv.tv_sec = timeoutMs / 1000; | |||
tv.tv_usec = (timeoutMs % 1000) * 1000; | |||
tvp = &tv; | |||
else | |||
tvp = 0; | |||
} | |||
// If there are X requests pending then poll, don't wait! | |||
if (XPending(dpy)) { | |||
tv.tv_usec = tv.tv_sec = 0; | |||
tvp = &tv; | |||
} | |||
// Wait for X events, VNC traffic, or the next timer expiry | |||
FD_ZERO(&rfds); | |||
FD_SET(ConnectionNumber(dpy), &rfds); | |||
FD_SET(sock->getFd(), &rfds); | |||
int n = select(FD_SETSIZE, &rfds, 0, 0, tvp); | |||
if (n < 0) throw rdr::SystemException("select",errno); | |||
Timer::callTimers(); | |||
} while (!(FD_ISSET(sock->getFd(), &rfds))); | |||
} | |||
@@ -180,20 +195,18 @@ void CConn::blockCallback() { | |||
// getPasswd() is called by the CSecurity object when it needs us to read a | |||
// password from the user. | |||
bool CConn::getUserPasswd(char** user, char** password) | |||
void CConn::getUserPasswd(char** user, char** password) | |||
{ | |||
CharArray passwordFileStr(passwordFile.getData()); | |||
if (!user && passwordFileStr.buf[0]) { | |||
FILE* fp = fopen(passwordFileStr.buf, "r"); | |||
if (!fp) return false; | |||
char data[256]; | |||
int datalen = fread(data, 1, 256, fp); | |||
if (!fp) throw rfb::Exception("Opening password file failed"); | |||
ObfuscatedPasswd obfPwd(256); | |||
obfPwd.length = fread(obfPwd.buf, 1, obfPwd.length, fp); | |||
fclose(fp); | |||
if (datalen != 8) return false; | |||
vncAuthUnobfuscatePasswd(data); | |||
*password = strDup(data); | |||
memset(data, 0, strlen(data)); | |||
return true; | |||
PlainPasswd passwd(obfPwd); | |||
*password = passwd.takeBuf(); | |||
return; | |||
} | |||
const char* secType = secTypeName(getCurrentCSecurity()->getType()); | |||
@@ -202,11 +215,10 @@ bool CConn::getUserPasswd(char** user, char** password) | |||
CharArray title(titleLen); | |||
snprintf(title.buf, titleLen, "%s [%s]", titlePrefix, secType); | |||
PasswdDialog dlg(dpy, title.buf, !user); | |||
if (!dlg.show()) return false; | |||
if (!dlg.show()) throw rfb::Exception("Authentication cancelled"); | |||
if (user) | |||
*user = strDup(dlg.userEntry.getText()); | |||
*password = strDup(dlg.passwdEntry.getText()); | |||
return true; | |||
} | |||
@@ -324,9 +336,9 @@ void CConn::imageRect(const rfb::Rect& r, void* p) { | |||
void CConn::copyRect(const rfb::Rect& r, int sx, int sy) { | |||
desktop->copyRect(r,sx,sy); | |||
} | |||
void CConn::setCursor(const Point& hotspot, const Point& size, | |||
void CConn::setCursor(int width, int height, const Point& hotspot, | |||
void* data, void* mask) { | |||
desktop->setCursor(hotspot, size, data, mask); | |||
desktop->setCursor(width, height, hotspot, data, mask); | |||
} | |||
@@ -444,26 +456,26 @@ void CConn::menuSelect(long id, TXMenu* m) { | |||
case ID_F8: | |||
menu.unmap(); | |||
if (!viewOnly) { | |||
writer()->writeKeyEvent(menuKeysym, true); | |||
writer()->writeKeyEvent(menuKeysym, false); | |||
writer()->keyEvent(menuKeysym, true); | |||
writer()->keyEvent(menuKeysym, false); | |||
} | |||
break; | |||
case ID_CTRLALTDEL: | |||
menu.unmap(); | |||
if (!viewOnly) { | |||
writer()->writeKeyEvent(XK_Control_L, true); | |||
writer()->writeKeyEvent(XK_Alt_L, true); | |||
writer()->writeKeyEvent(XK_Delete, true); | |||
writer()->writeKeyEvent(XK_Delete, false); | |||
writer()->writeKeyEvent(XK_Alt_L, false); | |||
writer()->writeKeyEvent(XK_Control_L, false); | |||
writer()->keyEvent(XK_Control_L, true); | |||
writer()->keyEvent(XK_Alt_L, true); | |||
writer()->keyEvent(XK_Delete, true); | |||
writer()->keyEvent(XK_Delete, false); | |||
writer()->keyEvent(XK_Alt_L, false); | |||
writer()->keyEvent(XK_Control_L, false); | |||
} | |||
break; | |||
case ID_CTRL: | |||
menu.unmap(); | |||
if (!viewOnly) { | |||
ctrlDown = !ctrlDown; | |||
writer()->writeKeyEvent(XK_Control_L, ctrlDown); | |||
writer()->keyEvent(XK_Control_L, ctrlDown); | |||
menu.check(ID_CTRL, ctrlDown); | |||
} | |||
break; | |||
@@ -471,7 +483,7 @@ void CConn::menuSelect(long id, TXMenu* m) { | |||
menu.unmap(); | |||
if (!viewOnly) { | |||
altDown = !altDown; | |||
writer()->writeKeyEvent(XK_Alt_L, altDown); | |||
writer()->keyEvent(XK_Alt_L, altDown); | |||
menu.check(ID_ALT, altDown); | |||
} | |||
break; |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved. | |||
* | |||
/* 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 | |||
@@ -48,7 +48,7 @@ class CConn : public rfb::CConnection, public rfb::UserPasswdGetter, | |||
public: | |||
CConn(Display* dpy_, int argc_, char** argv_, network::Socket* sock_, | |||
char* vncServerName); | |||
char* vncServerName, bool reverse=false); | |||
~CConn(); | |||
// TXDeleteWindowCallback methods | |||
@@ -58,7 +58,7 @@ public: | |||
void blockCallback(); | |||
// UserPasswdGetter methods | |||
virtual bool getUserPasswd(char** user, char** password); | |||
virtual void getUserPasswd(char** user, char** password); | |||
// TXMenuCallback methods | |||
void menuSelect(long id, TXMenu* m); | |||
@@ -69,7 +69,7 @@ public: | |||
// TXEventHandler callback method | |||
virtual void handleEvent(TXWindow* w, XEvent* ev); | |||
// CConnection callback methods | |||
rfb::CSecurity* getCSecurity(int secType); | |||
void serverInit(); | |||
@@ -83,7 +83,7 @@ public: | |||
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(const rfb::Point& hotspot, const rfb::Point& size, | |||
void setCursor(int width, int height, const rfb::Point& hotspot, | |||
void* data, void* mask); | |||
private: | |||
@@ -124,6 +124,7 @@ private: | |||
OptionsDialog options; | |||
AboutDialog about; | |||
InfoDialog info; | |||
bool reverseConnection; | |||
}; | |||
#endif |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved. | |||
* | |||
/* 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 | |||
@@ -70,7 +70,7 @@ DesktopWindow::DesktopWindow(Display* dpy, int w, int h, | |||
newSelection(0), gettingInitialSelectionTime(true), | |||
newServerCutText(false), serverCutText_(0), | |||
setColourMapEntriesTimer(this), viewport(0), | |||
pointerEventTimer(this), lastPointerX(0), lastPointerY(0), | |||
pointerEventTimer(this), | |||
lastButtonMask(0) | |||
{ | |||
setEventHandler(this); | |||
@@ -125,14 +125,14 @@ void DesktopWindow::createXCursors() | |||
localXCursor = 0; | |||
} | |||
void DesktopWindow::setCursor(const Point& hotspot, const Point& size, | |||
void DesktopWindow::setCursor(int width, int height, const Point& hotspot, | |||
void* data, void* mask) | |||
{ | |||
if (!useLocalCursor) return; | |||
hideLocalCursor(); | |||
int mask_len = ((size.x+7)/8) * size.y; | |||
int mask_len = ((width+7)/8) * height; | |||
int i; | |||
for (i = 0; i < mask_len; i++) | |||
@@ -151,11 +151,11 @@ void DesktopWindow::setCursor(const Point& hotspot, const Point& size, | |||
cursor.hotspot = hotspot; | |||
cursor.setSize(size.x, size.y); | |||
cursor.setSize(width, height); | |||
cursor.setPF(getPF()); | |||
cursor.imageRect(cursor.getRect(), data); | |||
cursorBacking.setSize(size.x, size.y); | |||
cursorBacking.setSize(width, height); | |||
cursorBacking.setPF(getPF()); | |||
delete [] cursor.mask.buf; | |||
@@ -250,8 +250,8 @@ void DesktopWindow::setColourMapEntries(int firstColour, int nColours, | |||
rdr::U16* rgbs) | |||
{ | |||
im->setColourMapEntries(firstColour, nColours, rgbs); | |||
if (!setColourMapEntriesTimer.isSet()) | |||
setColourMapEntriesTimer.reset(100); | |||
if (!setColourMapEntriesTimer.isStarted()) | |||
setColourMapEntriesTimer.start(100); | |||
} | |||
void DesktopWindow::serverCutText(const char* str, int len) | |||
@@ -311,41 +311,39 @@ void DesktopWindow::resize(int w, int h) | |||
} | |||
void DesktopWindow::timerCallback(Timer* timer) | |||
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()->writePointerEvent(lastPointerX, lastPointerY, | |||
lastButtonMask); | |||
cc->writer()->pointerEvent(lastPointerPos, lastButtonMask); | |||
} | |||
} | |||
return false; | |||
} | |||
void DesktopWindow::handlePointerEvent(int x, int y, int buttonMask) | |||
void DesktopWindow::handlePointerEvent(const Point& pos, int buttonMask) | |||
{ | |||
if (!viewOnly) { | |||
if (pointerEventInterval == 0 || buttonMask != lastButtonMask) { | |||
cc->writer()->writePointerEvent(x, y, buttonMask); | |||
cc->writer()->pointerEvent(pos, buttonMask); | |||
} else { | |||
if (!pointerEventTimer.isSet()) | |||
pointerEventTimer.reset(pointerEventInterval); | |||
if (!pointerEventTimer.isStarted()) | |||
pointerEventTimer.start(pointerEventInterval); | |||
} | |||
lastPointerX = x; | |||
lastPointerY = y; | |||
lastPointerPos = pos; | |||
lastButtonMask = buttonMask; | |||
} | |||
// - If local cursor rendering is enabled then use it | |||
if (cursorAvailable) { | |||
// - Render the cursor! | |||
Point p(x, y); | |||
if (!p.equals(cursorPos)) { | |||
if (!pos.equals(cursorPos)) { | |||
hideLocalCursor(); | |||
if (im->getRect().contains(p)) { | |||
cursorPos = p; | |||
if (im->getRect().contains(pos)) { | |||
cursorPos = pos; | |||
showLocalCursor(); | |||
} | |||
} | |||
@@ -367,18 +365,18 @@ void DesktopWindow::handleEvent(TXWindow* w, XEvent* ev) | |||
case MotionNotify: | |||
while (XCheckTypedWindowEvent(dpy, win(), MotionNotify, ev)); | |||
if (viewport && viewport->bumpScrollEvent(&ev->xmotion)) break; | |||
handlePointerEvent(ev->xmotion.x, ev->xmotion.y, | |||
handlePointerEvent(Point(ev->xmotion.x, ev->xmotion.y), | |||
(ev->xmotion.state & 0x1f00) >> 8); | |||
break; | |||
case ButtonPress: | |||
handlePointerEvent(ev->xbutton.x, ev->xbutton.y, | |||
handlePointerEvent(Point(ev->xbutton.x, ev->xbutton.y), | |||
(((ev->xbutton.state & 0x1f00) >> 8) | | |||
(1 << (ev->xbutton.button-1)))); | |||
break; | |||
case ButtonRelease: | |||
handlePointerEvent(ev->xbutton.x, ev->xbutton.y, | |||
handlePointerEvent(Point(ev->xbutton.x, ev->xbutton.y), | |||
(((ev->xbutton.state & 0x1f00) >> 8) & | |||
~(1 << (ev->xbutton.button-1)))); | |||
break; | |||
@@ -397,20 +395,20 @@ void DesktopWindow::handleEvent(TXWindow* w, XEvent* ev) | |||
} | |||
if (fakeShiftPress) | |||
cc->writer()->writeKeyEvent(XK_Shift_L, true); | |||
cc->writer()->keyEvent(XK_Shift_L, true); | |||
downKeysym[ev->xkey.keycode] = ks; | |||
cc->writer()->writeKeyEvent(ks, true); | |||
cc->writer()->keyEvent(ks, true); | |||
if (fakeShiftPress) | |||
cc->writer()->writeKeyEvent(XK_Shift_L, false); | |||
cc->writer()->keyEvent(XK_Shift_L, false); | |||
break; | |||
} | |||
case KeyRelease: | |||
if (!viewOnly) { | |||
if (downKeysym[ev->xkey.keycode]) { | |||
cc->writer()->writeKeyEvent(downKeysym[ev->xkey.keycode], false); | |||
cc->writer()->keyEvent(downKeysym[ev->xkey.keycode], false); | |||
downKeysym[ev->xkey.keycode] = 0; | |||
} | |||
} | |||
@@ -440,7 +438,7 @@ void DesktopWindow::handleEvent(TXWindow* w, XEvent* ev) | |||
// LeaveNotify is near enough... | |||
for (int i = 8; i < 256; i++) { | |||
if (downKeysym[i]) { | |||
cc->writer()->writeKeyEvent(downKeysym[i], false); | |||
cc->writer()->keyEvent(downKeysym[i], false); | |||
downKeysym[i] = 0; | |||
} | |||
} | |||
@@ -545,7 +543,7 @@ void DesktopWindow::selectionNotify(XSelectionEvent* ev, Atom type, int format, | |||
if (str) { | |||
if (!viewOnly) { | |||
vlog.debug("sending cut buffer to server"); | |||
cc->writer()->writeClientCutText(str, len); | |||
cc->writer()->clientCutText(str, len); | |||
} | |||
XFree(str); | |||
return; | |||
@@ -565,7 +563,7 @@ void DesktopWindow::selectionNotify(XSelectionEvent* ev, Atom type, int format, | |||
vlog.debug("sending %s selection to server", | |||
ev->selection == XA_PRIMARY ? "primary" : | |||
ev->selection == xaCLIPBOARD ? "clipboard" : "unknown" ); | |||
cc->writer()->writeClientCutText((char*)data, nitems); | |||
cc->writer()->clientCutText((char*)data, nitems); | |||
} | |||
} | |||
} |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved. | |||
* | |||
/* 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 | |||
@@ -24,15 +24,15 @@ | |||
#include <rfb/Cursor.h> | |||
#include <rfb/Rect.h> | |||
#include <rfb/Timer.h> | |||
#include "TXWindow.h" | |||
#include "TXViewport.h" | |||
#include "TXImage.h" | |||
#include "Timer.h" | |||
class CConn; | |||
class DesktopWindow : public TXWindow, public TXEventHandler, | |||
public TimerCallback { | |||
public rfb::Timer::Callback { | |||
public: | |||
DesktopWindow(Display* dpy, int w, int h, | |||
@@ -47,7 +47,7 @@ public: | |||
void setPF(const rfb::PixelFormat& pf) { im->setPF(pf); } | |||
// setCursor() sets the shape of the local cursor | |||
void setCursor(const rfb::Point& hotspot, const rfb::Point& size, | |||
void setCursor(int width, int height, const rfb::Point& hotspot, | |||
void* data, void* mask); | |||
// resetLocalCursor() stops the rendering of the local cursor | |||
@@ -97,8 +97,8 @@ private: | |||
void createXCursors(); | |||
void hideLocalCursor(); | |||
void showLocalCursor(); | |||
void timerCallback(Timer* timer); | |||
void handlePointerEvent(int x, int y, int buttonMask); | |||
bool handleTimeout(rfb::Timer* timer); | |||
void handlePointerEvent(const rfb::Point& pos, int buttonMask); | |||
CConn* cc; | |||
TXImage* im; | |||
@@ -118,10 +118,11 @@ private: | |||
bool newServerCutText; | |||
char* serverCutText_; | |||
Timer setColourMapEntriesTimer; | |||
rfb::Timer setColourMapEntriesTimer; | |||
TXViewport* viewport; | |||
Timer pointerEventTimer; | |||
int lastPointerX, lastPointerY, lastButtonMask; | |||
rfb::Timer pointerEventTimer; | |||
rfb::Point lastPointerPos; | |||
int lastButtonMask; | |||
rdr::U32 downKeysym[256]; | |||
}; | |||
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. | |||
* | |||
/* 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 |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. | |||
* | |||
/* 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 |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. | |||
* | |||
/* 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 |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. | |||
* | |||
/* 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 |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. | |||
* | |||
/* 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 |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved. | |||
* | |||
/* 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 |
@@ -1,5 +1,5 @@ | |||
/* Copyright (C) 2002-2004 RealVNC Ltd. All Rights Reserved. | |||
* | |||
/* 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 | |||
@@ -25,6 +25,7 @@ | |||
#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> | |||
@@ -33,6 +34,7 @@ | |||
#include <rfb/LogWriter.h> | |||
#include <network/TcpSocket.h> | |||
#include "TXWindow.h" | |||
#include "TXMsgBox.h" | |||
#include "CConn.h" | |||
#include <intl/gettext.h> | |||
@@ -265,12 +267,12 @@ int main(int argc, char** argv) | |||
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-2005 Peter Astrand, Cendio AB\n" | |||
"See http://www.tightvnc.com for information on TightVNC."), | |||
buildtime); | |||
_("TightVNC viewer for X version 1.5 - built %s\n" | |||
"Copyright (C) 2002-2005 RealVNC Ltd.\n" | |||
"Copyright (C) 2000-2004 Constantin Kaplinsky\n" | |||
"Copyright (C) 2004-2005 Peter Astrand, Cendio AB\n" | |||
"See http://www.tightvnc.com for information on TightVNC."), | |||
buildtime); | |||
fprintf(stderr,"\n%s\n", aboutText); | |||
bind_textdomain_codeset(PACKAGE, "iso-8859-1"); | |||
@@ -284,7 +286,7 @@ int main(int argc, char** argv) | |||
programName = argv[0]; | |||
char* vncServerName = 0; | |||
Display* dpy; | |||
Display* dpy = 0; | |||
for (int i = 1; i < argc; i++) { | |||
if (Configuration::setParam(argv[i])) | |||
@@ -303,6 +305,17 @@ int main(int argc, char** argv) | |||
vncServerName = argv[i]; | |||
} | |||
// Create .vnc in the user's home directory if it doesn't already exist | |||
char* homeDir = getenv("HOME"); | |||
if (homeDir) { | |||
CharArray vncDir(strlen(homeDir)+6); | |||
sprintf(vncDir.buf, "%s/.vnc", homeDir); | |||
int result = mkdir(vncDir.buf, 0755); | |||
if (result == -1 && errno != EEXIST) | |||
vlog.error("Could not create .vnc directory: %s.", strerror(errno)); | |||
} else | |||
vlog.error("Could not create .vnc directory: environment variable $HOME not set."); | |||
if (!::autoSelect.hasBeenSet()) { | |||
// Default to AutoSelect=0 if -PreferredEncoding or -FullColor is used | |||
::autoSelect.setParam(!::preferredEncoding.hasBeenSet() | |||
@@ -315,8 +328,6 @@ int main(int argc, char** argv) | |||
} | |||
try { | |||
TcpSocket::initTcpSockets(); | |||
/* Tunnelling support. */ | |||
if (strlen (via.getValueStr ()) > 0) { | |||
char *gatewayHost = ""; | |||
@@ -361,7 +372,7 @@ int main(int argc, char** argv) | |||
TXWindow::init(dpy, "Vncviewer"); | |||
xloginIconifier.iconify(dpy); | |||
CConn cc(dpy, argc, argv, sock, vncServerName); | |||
CConn cc(dpy, argc, argv, sock, vncServerName, listenMode); | |||
// X events are processed whenever reading from the socket would block. | |||
@@ -370,8 +381,15 @@ int main(int argc, char** argv) | |||
cc.processMsg(); | |||
} | |||
} catch (rdr::Exception &e) { | |||
} 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; |
@@ -1,4 +1,4 @@ | |||
.TH vncviewer 1 "30 December 2004" "TightVNC" "Virtual Network Computing" | |||
.TH vncviewer 1 "05 May 2004" "TightVNC" "Virtual Network Computing" | |||
.SH NAME | |||
vncviewer \- VNC viewer for X | |||
.SH SYNOPSIS | |||
@@ -196,9 +196,10 @@ host, the port number on the remote host, and the gateway machine | |||
respectively. | |||
.SH SEE ALSO | |||
.BR Xvnc (1) | |||
.BR Xvnc (1), | |||
.BR vncpasswd (1), | |||
.BR vncconfig (1), | |||
.BR vncserver (1), | |||
.BR vncserver (1) | |||
.br | |||
http://www.tightvnc.com | |||