]> source.dussan.org Git - tigervnc.git/commitdiff
Implement basic support for SetDesktopSize.
authorPierre Ossman <ossman@cendio.se>
Mon, 23 Mar 2009 16:58:53 +0000 (16:58 +0000)
committerPierre Ossman <ossman@cendio.se>
Mon, 23 Mar 2009 16:58:53 +0000 (16:58 +0000)
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
unix/xserver/hw/vnc/XserverDesktop.h

index cb57a6d1cb8128665f06defef54a5b2bc63f0e8f..9554ed8d578b6e2e40922b3f38d7f50e7154e060 100644 (file)
@@ -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;
index 50b7d935292a9ba1fee34a96bea6c286d5d13854..8eecb6b392b8f3596d586bb1392ddaea0f503e87 100644 (file)
@@ -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);