diff -urN vnc-4.0-unixsrc.orig/configure.in vnc-4.0-unixsrc/configure.in --- vnc-4.0-unixsrc.orig/configure.in 2003-07-31 11:57:20.000000000 -0400 +++ vnc-4.0-unixsrc/configure.in 2006-06-12 02:52:02.121538927 -0400 @@ -78,6 +78,11 @@ SOCKLEN_T_DEFINE='-DVNC_SOCKLEN_T=int') AC_SUBST(SOCKLEN_T_DEFINE) +AC_CHECK_LIB(Xinerama, XineramaIsActive, + [ AC_DEFINE(HAVE_XINERAMA, 1, [Define if you have Xinerama support]) + X_PRE_LIBS="$X_PRE_LIBS -lXinerama" + ],, $X_PRE_LIBS $X_LIBS -lX11 -lXext $X_EXTRA_LIBS) + BOILERPLATE=boilerplate.mk if (sh -c "make --version" 2>/dev/null | grep GNU 2>&1 >/dev/null); then diff -urN vnc-4.0-unixsrc.orig/vncviewer/CConn.cxx vnc-4.0-unixsrc/vncviewer/CConn.cxx --- vnc-4.0-unixsrc.orig/vncviewer/CConn.cxx 2004-04-26 12:39:08.000000000 -0400 +++ vnc-4.0-unixsrc/vncviewer/CConn.cxx 2006-06-12 02:52:02.121538927 -0400 @@ -37,6 +37,10 @@ #include "PasswdDialog.h" #include "parameters.h" +#ifdef HAVE_XINERAMA +# include +#endif + using namespace rfb; static rfb::LogWriter vlog("CConn"); @@ -49,7 +53,7 @@ StringParameter windowName("name", "The X window name", ""); CConn::CConn(Display* dpy_, int argc_, char** argv_, network::Socket* sock_, - char* vncServerName) + char* vncServerName, int xineramascreen) : dpy(dpy_), argc(argc_), argv(argv_), serverHost(0), serverPort(0), sock(sock_), viewport(0), desktop(0), desktopEventHandler(0), @@ -62,7 +66,7 @@ { CharArray menuKeyStr(menuKey.getData()); menuKeysym = XStringToKeysym(menuKeyStr.buf); - + xineramaScreen = xineramascreen; setShared(shared); addSecType(secTypeNone); addSecType(secTypeVncAuth); @@ -566,7 +570,9 @@ if (fullScreen) { XGrabKeyboard(dpy, desktop->win(), True, GrabModeAsync, GrabModeAsync, CurrentTime); + desktop->setGrabKeyboard(true); } else { + desktop->setGrabKeyboard(false); XUngrabKeyboard(dpy, CurrentTime); } if (oldViewport) delete oldViewport; @@ -576,6 +582,22 @@ { viewport->setMaxSize(cp.width, cp.height); if (fullScreen) { +#ifdef HAVE_XINERAMA + int number; + XineramaScreenInfo* info = XineramaQueryScreens (dpy, &number); + // Find requested Xinerama screen + for (int i = 0; (info != NULL) && (i < number); i++) { + // Setup window to match found Xinerama screen + if (info[i].screen_number == xineramaScreen) { + viewport->setUSPosition(info[i].x_org, info[i].y_org); + viewport->resize(info[i].width, info[i].height); + XFree(info); + return; + } + } + XFree(info); +#endif + // No Xinerama screen found, or none requested, fill default display viewport->resize(DisplayWidth(dpy,DefaultScreen(dpy)), DisplayHeight(dpy,DefaultScreen(dpy))); } else { diff -urN vnc-4.0-unixsrc.orig/vncviewer/CConn.h vnc-4.0-unixsrc/vncviewer/CConn.h --- vnc-4.0-unixsrc.orig/vncviewer/CConn.h 2004-04-14 07:50:12.000000000 -0400 +++ vnc-4.0-unixsrc/vncviewer/CConn.h 2006-06-12 02:52:36.529538927 -0400 @@ -48,7 +48,7 @@ public: CConn(Display* dpy_, int argc_, char** argv_, network::Socket* sock_, - char* vncServerName); + char* vncServerName, int xineramascreen=-1); ~CConn(); // TXDeleteWindowCallback methods @@ -118,6 +118,7 @@ bool fullScreen; bool ctrlDown; bool altDown; + int xineramaScreen; KeySym menuKeysym; TXMenu menu; TXEventHandler* menuEventHandler; diff -urN vnc-4.0-unixsrc.orig/vncviewer/DesktopWindow.cxx vnc-4.0-unixsrc/vncviewer/DesktopWindow.cxx --- vnc-4.0-unixsrc.orig/vncviewer/DesktopWindow.cxx 2004-04-30 06:24:35.000000000 -0400 +++ vnc-4.0-unixsrc/vncviewer/DesktopWindow.cxx 2006-06-12 02:52:02.125538927 -0400 @@ -74,6 +74,7 @@ lastButtonMask(0) { setEventHandler(this); + grabkeys = false; gc = XCreateGC(dpy, win(), 0, 0); addEventMask(ExposureMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask | KeyPressMask | KeyReleaseMask | @@ -425,6 +426,11 @@ XConvertSelection(dpy, xaCLIPBOARD, xaTIMESTAMP, xaSELECTION_TIME, win(), ev->xcrossing.time); } + // Grab keyboard + if (grabkeys) { + XGrabKeyboard(dpy, win(), True, GrabModeAsync, GrabModeAsync, + CurrentTime); + } break; case LeaveNotify: @@ -436,6 +442,7 @@ 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++) { @@ -444,6 +451,10 @@ downKeysym[i] = 0; } } + // Release keyboard + if (grabkeys) { + XUngrabKeyboard (dpy, CurrentTime); + } break; } } diff -urN vnc-4.0-unixsrc.orig/vncviewer/DesktopWindow.h vnc-4.0-unixsrc/vncviewer/DesktopWindow.h --- vnc-4.0-unixsrc.orig/vncviewer/DesktopWindow.h 2004-03-18 12:25:26.000000000 -0500 +++ vnc-4.0-unixsrc/vncviewer/DesktopWindow.h 2006-06-12 02:52:02.125538927 -0400 @@ -52,6 +52,11 @@ // resetLocalCursor() stops the rendering of the local cursor void resetLocalCursor(); + + // If set, the keyboard focus will be grabbed/released when the pointer + // enters/leaves the window. The window manager will take car of the + // keyboard focus is unset. + void setGrabKeyboard(bool grab) {grabkeys = grab;} // Methods forwarded from CConn void setColourMapEntries(int firstColour, int nColours, rdr::U16* rgbs); @@ -117,6 +122,7 @@ bool gettingInitialSelectionTime; bool newServerCutText; char* serverCutText_; + bool grabkeys; Timer setColourMapEntriesTimer; TXViewport* viewport; diff -urN vnc-4.0-unixsrc.orig/vncviewer/vncviewer.cxx vnc-4.0-unixsrc/vncviewer/vncviewer.cxx --- vnc-4.0-unixsrc.orig/vncviewer/vncviewer.cxx 2006-06-12 02:51:31.000000000 -0400 +++ vnc-4.0-unixsrc/vncviewer/vncviewer.cxx 2006-06-12 02:52:02.125538927 -0400 @@ -97,6 +97,12 @@ /* Support for tunnelling */ StringParameter via("via", "Gateway to tunnel via", ""); +#ifdef HAVE_XINERAMA +IntParameter xineramaScreen("XineramaScreen", "Xineramascreen used in fullscreen", -1); +#else +static int xineramaScreen=-1; +#endif + char aboutText[256]; char* programName; extern char buildtime[]; @@ -297,7 +303,7 @@ TXWindow::init(dpy, "Vncviewer"); xloginIconifier.iconify(dpy); - CConn cc(dpy, argc, argv, sock, vncServerName); + CConn cc(dpy, argc, argv, sock, vncServerName, xineramaScreen); // X events are processed whenever reading from the socket would block.