From 981c45efc609cd59b8bceb60c5dfd39a4a23f678 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 23 Mar 2009 16:58:53 +0000 Subject: [PATCH] Implement basic support for SetDesktopSize. No real support for RandR 1.2 yet. git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@3714 3789f03b-4d11-0410-bbf8-ca57d06f2519 --- unix/xserver/hw/vnc/XserverDesktop.cc | 74 +++++++++++++++++++++++++++ unix/xserver/hw/vnc/XserverDesktop.h | 4 ++ 2 files changed, 78 insertions(+) diff --git a/unix/xserver/hw/vnc/XserverDesktop.cc b/unix/xserver/hw/vnc/XserverDesktop.cc index cb57a6d1..9554ed8d 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.cc +++ b/unix/xserver/hw/vnc/XserverDesktop.cc @@ -68,6 +68,9 @@ extern char *display; extern void CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master); #endif +#ifdef RANDR +#include "randrstr.h" +#endif #undef public #undef class } @@ -828,6 +831,77 @@ void XserverDesktop::clientCutText(const char* str, int len) vncClientCutText(str, len); } +#ifdef RANDR +unsigned int XserverDesktop::setScreenLayout(int fb_width, int fb_height, + const rfb::ScreenSet& layout) +{ + int i; + Bool ret; + RRScreenSizePtr pSize; + RROutputPtr output; + RRModePtr mode; + + // Make sure all RandR tables are properly populated + ret = RRGetInfo(pScreen); + if (!ret) + return resultNoResources; + + // Register a new size, or get a reference to the existing one + pSize = RRRegisterSize(pScreen, fb_width, fb_height, + pScreen->mmWidth, pScreen->mmHeight); + if (!pSize) + return resultNoResources; + ret = RRRegisterRate(pScreen, pSize, 60); + if (!ret) + return resultNoResources; + + // Go via RandR to set the resolution in order for X11 notifications + // to be sent out properly. We currently only do RandR 1.0, but Xorg + // has dropped support for that API. So we have to emulate it via the + // same method ProcRRSetScreenConfig() uses. + // + // FIXME: This will cause setPixelBuffer() to be called, resulting in + // an unnecessary ExtendedDesktopSize to be sent. + + // We'll just reconfigure the first output + output = RRFirstOutput(pScreen); + if (!output) { + vlog.error("setScreenLayout: Could not get first output"); + return resultNoResources; + } + + // Find first mode with matching size + mode = NULL; + for (i = 0;i < output->numModes;i++) { + if ((output->modes[i]->mode.width == fb_width) && + (output->modes[i]->mode.height == fb_height)) { + mode = output->modes[i]; + break; + } + } + if (!mode) + return resultNoResources; + + // Adjust screen size + ret = RRScreenSizeSet(pScreen, fb_width, fb_height, + pScreen->mmWidth, pScreen->mmHeight); + if (!ret) + return resultNoResources; + + // And then the CRTC + ret = RRCrtcSet(output->crtc, mode, 0, 0, RR_Rotate_0, 1, &output); + if (!ret) + return resultNoResources; + + // RandR 1.0 doesn't carry any screen layout information, so we need + // to update that manually. This results in another unnecessary + // ExtendedDesktopSize. + server->setScreenLayout(layout); + + return resultSuccess; +} +#endif // RANDR + void XserverDesktop::grabRegion(const rfb::Region& region) { if (directFbptr) return; diff --git a/unix/xserver/hw/vnc/XserverDesktop.h b/unix/xserver/hw/vnc/XserverDesktop.h index 50b7d935..8eecb6b3 100644 --- a/unix/xserver/hw/vnc/XserverDesktop.h +++ b/unix/xserver/hw/vnc/XserverDesktop.h @@ -104,6 +104,10 @@ public: virtual void keyEvent(rdr::U32 key, bool down); virtual void clientCutText(const char* str, int len); virtual rfb::Point getFbSize() { return rfb::Point(width(), height()); } +#ifdef RANDR + virtual unsigned int setScreenLayout(int fb_width, int fb_height, + const rfb::ScreenSet& layout); +#endif // rfb::PixelBuffer callbacks virtual void grabRegion(const rfb::Region& r); -- 2.39.5