Revision: 4935 http://tigervnc.svn.sourceforge.net/tigervnc/?rev=4935&view=rev Author: ossman_ Date: 2012-07-13 11:22:55 +0000 (Fri, 13 Jul 2012) Log Message: ----------- Implement client side multi-head support. Requires a FLTK patched to support fullscreen over multiple monitors. Will properly report screen configuration to the server, provided the server supports it.
Modified Paths: -------------- trunk/CMakeLists.txt trunk/config.h.in trunk/vncviewer/DesktopWindow.cxx trunk/vncviewer/DesktopWindow.h trunk/vncviewer/OptionsDialog.cxx trunk/vncviewer/OptionsDialog.h trunk/vncviewer/Viewport.cxx trunk/vncviewer/parameters.cxx trunk/vncviewer/parameters.h Modified: trunk/CMakeLists.txt =================================================================== --- trunk/CMakeLists.txt 2012-07-13 11:18:55 UTC (rev 4934) +++ trunk/CMakeLists.txt 2012-07-13 11:22:55 UTC (rev 4935) @@ -289,6 +289,9 @@ # FLTK STR #2816 check_cxx_source_compiles("#include <FL/Fl_Window.H>\nint main(int c, char** v) { Fl_Window::default_icons(0, 0); return 0; }" HAVE_FLTK_ICONS) + # FLTK STR #2860 + check_cxx_source_compiles("#include <FL/Fl_Window.H>\nint main(int c, char** v) { void (Fl_Window::*foo)(int,int,int,int) = &Fl_Window::fullscreen_screens; return 0; }" HAVE_FLTK_FULLSCREEN_SCREENS) + set(CMAKE_REQUIRED_INCLUDES) set(CMAKE_REQUIRED_LIBRARIES) endif() Modified: trunk/config.h.in =================================================================== --- trunk/config.h.in 2012-07-13 11:18:55 UTC (rev 4934) +++ trunk/config.h.in 2012-07-13 11:22:55 UTC (rev 4935) @@ -19,6 +19,7 @@ #cmakedefine HAVE_FLTK_CLIPBOARD #cmakedefine HAVE_FLTK_MEDIAKEYS #cmakedefine HAVE_FLTK_FULLSCREEN +#cmakedefine HAVE_FLTK_FULLSCREEN_SCREENS #cmakedefine HAVE_FLTK_CURSOR #cmakedefine HAVE_FLTK_ICONS #cmakedefine HAVE_ACTIVE_DESKTOP_H Modified: trunk/vncviewer/DesktopWindow.cxx =================================================================== --- trunk/vncviewer/DesktopWindow.cxx 2012-07-13 11:18:55 UTC (rev 4934) +++ trunk/vncviewer/DesktopWindow.cxx 2012-07-13 11:22:55 UTC (rev 4935) @@ -76,7 +76,7 @@ #ifdef HAVE_FLTK_FULLSCREEN if (fullScreen) - fullscreen(); + fullscreen_on(); else #endif { @@ -295,6 +295,54 @@ } +void DesktopWindow::fullscreen_on() +{ +#ifdef HAVE_FLTK_FULLSCREEN +#ifdef HAVE_FLTK_FULLSCREEN_SCREENS + if (not fullScreenAllMonitors) + fullscreen_screens(-1, -1, -1, -1); + else { + int top, bottom, left, right; + int top_y, bottom_y, left_x, right_x; + + int sx, sy, sw, sh; + + top = bottom = left = right = 0; + + Fl::screen_xywh(sx, sy, sw, sh, 0); + top_y = sy; + bottom_y = sy + sh; + left_x = sx; + right_x = sx + sw; + + for (int i = 1;i < Fl::screen_count();i++) { + Fl::screen_xywh(sx, sy, sw, sh, i); + if (sy < top_y) { + top = i; + top_y = sy; + } + if ((sy + sh) > bottom_y) { + bottom = i; + bottom_y = sy + sh; + } + if (sx < left_x) { + left = i; + left_x = sx; + } + if ((sx + sw) > right_x) { + right = i; + right_x = sx + sw; + } + } + + fullscreen_screens(top, bottom, left, right); + } +#endif // HAVE_FLTK_FULLSCREEN_SCREENS + + fullscreen(); +#endif // HAVE_FLTK_FULLSCREEN +} + void DesktopWindow::grabKeyboard() { // Grabbing the keyboard is fairly safe as FLTK reroutes events to the @@ -394,6 +442,7 @@ { int width, height; ScreenSet layout; + ScreenSet::iterator iter; if (firstUpdate) { if (sscanf(desktopSize.getValueStr(), "%dx%d", &width, &height) != 2) @@ -403,38 +452,104 @@ height = h(); } - layout = cc->cp.screenLayout; +#ifdef HAVE_FLTK_FULLSCREEN + if (!fullscreen_active()) { +#endif + // In windowed mode we just report a single virtual screen that + // covers the entire framebuffer. - if (layout.num_screens() == 0) - layout.add_screen(rfb::Screen()); - else if (layout.num_screens() != 1) { - ScreenSet::iterator iter; + layout = cc->cp.screenLayout; - while (true) { - iter = layout.begin(); - ++iter; + // Not sure why we have no screens, but adding a new one should be + // safe as there is nothing to conflict with... + if (layout.num_screens() == 0) + layout.add_screen(rfb::Screen()); + else if (layout.num_screens() != 1) { + // More than one screen. Remove all but the first (which we + // assume is the "primary"). - if (iter == layout.end()) - break; + while (true) { + iter = layout.begin(); + ++iter; - layout.remove_screen(iter->id); + if (iter == layout.end()) + break; + + layout.remove_screen(iter->id); + } } + + // Resize the remaining single screen to the complete framebuffer + layout.begin()->dimensions.tl.x = 0; + layout.begin()->dimensions.tl.y = 0; + layout.begin()->dimensions.br.x = width; + layout.begin()->dimensions.br.y = height; +#ifdef HAVE_FLTK_FULLSCREEN + } else { + int i; + rdr::U32 id; + int sx, sy, sw, sh; + + // In full screen we report all screens that are fully covered. + + // If we can find a matching screen in the existing set, we use + // that, otherwise we create a brand new screen. + // + // FIXME: We should really track screens better so we can handle + // a resized one. + // + for (i = 0;i < Fl::screen_count();i++) { + Fl::screen_xywh(sx, sy, sw, sh, i); + + // Look for perfectly matching existing screen... + for (iter = cc->cp.screenLayout.begin(); + iter != cc->cp.screenLayout.end(); ++iter) { + if ((iter->dimensions.tl.x == sx) && + (iter->dimensions.tl.y == sy) && + (iter->dimensions.width() == sw) && + (iter->dimensions.height() == sh)) + break; + } + + // Found it? + if (iter != cc->cp.screenLayout.end()) { + layout.add_screen(*iter); + continue; + } + + // Need to add a new one, which means we need to find an unused id + while (true) { + id = rand(); + for (iter = cc->cp.screenLayout.begin(); + iter != cc->cp.screenLayout.end(); ++iter) { + if (iter->id == id) + break; + } + + if (iter == cc->cp.screenLayout.end()) + break; + } + + layout.add_screen(rfb::Screen(id, sx, sy, sw, sh, 0)); + } } +#endif - layout.begin()->dimensions.tl.x = 0; - layout.begin()->dimensions.tl.y = 0; - layout.begin()->dimensions.br.x = width; - layout.begin()->dimensions.br.y = height; - // Do we actually change anything? if ((width == cc->cp.width) && (height == cc->cp.height) && (layout == cc->cp.screenLayout)) return; - vlog.debug("Requesting framebuffer resize from %dx%d to %dx%d", - cc->cp.width, cc->cp.height, width, height); + vlog.debug("Requesting framebuffer resize from %dx%d to %dx%d (%d screens)", + cc->cp.width, cc->cp.height, width, height, layout.num_screens()); + if (!layout.validate(width, height)) { + vlog.error("Invalid screen layout computed for resize request!"); + layout.debug_print(); + return; + } + cc->writer()->writeSetDesktopSize(width, height, layout); } @@ -499,7 +614,7 @@ self->ungrabKeyboard(); if (fullScreen && !self->fullscreen_active()) - self->fullscreen(); + self->fullscreen_on(); else if (!fullScreen && self->fullscreen_active()) self->fullscreen_off(); #endif Modified: trunk/vncviewer/DesktopWindow.h =================================================================== --- trunk/vncviewer/DesktopWindow.h 2012-07-13 11:18:55 UTC (rev 4934) +++ trunk/vncviewer/DesktopWindow.h 2012-07-13 11:22:55 UTC (rev 4935) @@ -78,6 +78,8 @@ int handle(int event); + void fullscreen_on(); + private: static int fltkHandle(int event, Fl_Window *win); Modified: trunk/vncviewer/OptionsDialog.cxx =================================================================== --- trunk/vncviewer/OptionsDialog.cxx 2012-07-13 11:18:55 UTC (rev 4934) +++ trunk/vncviewer/OptionsDialog.cxx 2012-07-13 11:22:55 UTC (rev 4935) @@ -288,6 +288,9 @@ remoteResizeCheckbox->value(remoteResize); #ifdef HAVE_FLTK_FULLSCREEN fullScreenCheckbox->value(fullScreen); +#ifdef HAVE_FLTK_FULLSCREEN_SCREENS + fullScreenAllMonitorsCheckbox->value(fullScreenAllMonitors); +#endif // HAVE_FLTK_FULLSCREEN_SCREENS #endif // HAVE_FLTK_FULLSCREEN handleDesktopSize(desktopSizeCheckbox, this); @@ -393,6 +396,9 @@ remoteResize.setParam(remoteResizeCheckbox->value()); #ifdef HAVE_FLTK_FULLSCREEN fullScreen.setParam(fullScreenCheckbox->value()); +#ifdef HAVE_FLTK_FULLSCREEN_SCREENS + fullScreenAllMonitors.setParam(fullScreenAllMonitorsCheckbox->value()); +#endif // HAVE_FLTK_FULLSCREEN_SCREENS #endif // HAVE_FLTK_FULLSCREEN /* Misc. */ @@ -760,6 +766,16 @@ _("Full-screen mode"))); ty += CHECK_HEIGHT + TIGHT_MARGIN; +#ifdef HAVE_FLTK_FULLSCREEN_SCREENS + + fullScreenAllMonitorsCheckbox = new Fl_Check_Button(LBLRIGHT(tx + INDENT, ty, + CHECK_MIN_WIDTH, + CHECK_HEIGHT, + _("Enable full-screen mode over all monitors"))); + ty += CHECK_HEIGHT + TIGHT_MARGIN; + +#endif // HAVE_FLTK_FULLSCREEN_SCREENS + #endif // HAVE_FLTK_FULLSCREEN group->end(); Modified: trunk/vncviewer/OptionsDialog.h =================================================================== --- trunk/vncviewer/OptionsDialog.h 2012-07-13 11:18:55 UTC (rev 4934) +++ trunk/vncviewer/OptionsDialog.h 2012-07-13 11:22:55 UTC (rev 4935) @@ -114,6 +114,7 @@ Fl_Int_Input *desktopHeightInput; Fl_Check_Button *remoteResizeCheckbox; Fl_Check_Button *fullScreenCheckbox; + Fl_Check_Button *fullScreenAllMonitorsCheckbox; /* Misc. */ Fl_Check_Button *sharedCheckbox; Modified: trunk/vncviewer/Viewport.cxx =================================================================== --- trunk/vncviewer/Viewport.cxx 2012-07-13 11:18:55 UTC (rev 4934) +++ trunk/vncviewer/Viewport.cxx 2012-07-13 11:22:55 UTC (rev 4935) @@ -920,7 +920,7 @@ if (window()->fullscreen_active()) window()->fullscreen_off(); else - window()->fullscreen(); + ((DesktopWindow*)window())->fullscreen_on(); break; #endif case ID_RESIZE: Modified: trunk/vncviewer/parameters.cxx =================================================================== --- trunk/vncviewer/parameters.cxx 2012-07-13 11:18:55 UTC (rev 4934) +++ trunk/vncviewer/parameters.cxx 2012-07-13 11:22:55 UTC (rev 4935) @@ -66,6 +66,11 @@ #ifdef HAVE_FLTK_FULLSCREEN BoolParameter fullScreen("FullScreen", "Full screen mode", false); +#ifdef HAVE_FLTK_FULLSCREEN_SCREENS +BoolParameter fullScreenAllMonitors("FullScreenAllMonitors", + "Enable full screen over all monitors", + true); +#endif // HAVE_FLTK_FULLSCREEN_SCREENS #endif // HAVE_FLTK_FULLSCREEN StringParameter desktopSize("DesktopSize", "Reconfigure desktop size on the server on " Modified: trunk/vncviewer/parameters.h =================================================================== --- trunk/vncviewer/parameters.h 2012-07-13 11:18:55 UTC (rev 4934) +++ trunk/vncviewer/parameters.h 2012-07-13 11:22:55 UTC (rev 4935) @@ -39,6 +39,9 @@ #ifdef HAVE_FLTK_FULLSCREEN extern rfb::BoolParameter fullScreen; +#ifdef HAVE_FLTK_FULLSCREEN_SCREENS +extern rfb::BoolParameter fullScreenAllMonitors; +#endif // HAVE_FLTK_FULLSCREEN_SCREENS #endif // HAVE_FLTK_FULLSCREEN extern rfb::StringParameter desktopSize; extern rfb::BoolParameter remoteResize; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ _______________________________________________ Tigervnc-commits mailing list Tigervnc-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tigervnc-commits