aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--x0vncserver/CPUMonitor.cxx2
-rw-r--r--x0vncserver/Image.cxx2
-rw-r--r--x0vncserver/Makefile.in2
-rw-r--r--x0vncserver/PollingManager.cxx127
-rw-r--r--x0vncserver/PollingManager.h55
-rw-r--r--x0vncserver/x0vncserver.cxx103
6 files changed, 198 insertions, 93 deletions
diff --git a/x0vncserver/CPUMonitor.cxx b/x0vncserver/CPUMonitor.cxx
index e5298bcf..9a7bb016 100644
--- a/x0vncserver/CPUMonitor.cxx
+++ b/x0vncserver/CPUMonitor.cxx
@@ -20,7 +20,7 @@
// CPUMonitor.cxx
//
-#include "CPUMonitor.h"
+#include <x0vncserver/CPUMonitor.h>
CPUMonitor::CPUMonitor(int optimalLevel, int updatePeriod)
{
diff --git a/x0vncserver/Image.cxx b/x0vncserver/Image.cxx
index 880fa5f9..b310619d 100644
--- a/x0vncserver/Image.cxx
+++ b/x0vncserver/Image.cxx
@@ -28,7 +28,7 @@
#include <sys/shm.h>
#endif
-#include "Image.h"
+#include <x0vncserver/Image.h>
//
// ImageCleanup is used to delete Image instances automatically on
diff --git a/x0vncserver/Makefile.in b/x0vncserver/Makefile.in
index 57d6f22e..cca17e0d 100644
--- a/x0vncserver/Makefile.in
+++ b/x0vncserver/Makefile.in
@@ -1,5 +1,5 @@
-SRCS = Image.cxx CPUMonitor.cxx x0vncserver.cxx
+SRCS = Image.cxx CPUMonitor.cxx PollingManager.cxx x0vncserver.cxx
OBJS = $(SRCS:.cxx=.o)
diff --git a/x0vncserver/PollingManager.cxx b/x0vncserver/PollingManager.cxx
new file mode 100644
index 00000000..50c116e0
--- /dev/null
+++ b/x0vncserver/PollingManager.cxx
@@ -0,0 +1,127 @@
+/* Copyright (C) 2004-2005 Constantin Kaplinsky. 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
+ * (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ */
+//
+// PollingManager.cxx
+//
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/time.h>
+#include <X11/Xlib.h>
+#include <rfb/VNCServer.h>
+
+#include <x0vncserver/Image.h>
+#include <x0vncserver/PollingManager.h>
+
+const int PollingManager::m_pollingOrder[32] = {
+ 0, 16, 8, 24, 4, 20, 12, 28,
+ 10, 26, 18, 2, 22, 6, 30, 14,
+ 1, 17, 9, 25, 7, 23, 15, 31,
+ 19, 3, 27, 11, 29, 13, 5, 21
+};
+
+//
+// Constructor. Note that dpy and image should remain valid during
+// object lifetime, while factory is used only in the constructor
+// itself.
+//
+
+PollingManager::PollingManager(Display *dpy, Image *image,
+ ImageFactory *factory)
+ : m_dpy(dpy), m_server(0), m_image(image), m_pollingStep(0)
+{
+ // Create two additional images used in the polling algorithm.
+ // FIXME: verify that these images use the same pixel format as in m_image.
+ m_rowImage = factory->newImage(m_dpy, m_image->xim->width, 1);
+ m_tileImage = factory->newImage(m_dpy, 32, 32);
+}
+
+void PollingManager::setVNCServer(VNCServer* s)
+{
+ m_server = s;
+}
+
+//
+// DEBUG: a version of poll() measuring time spent in the function.
+//
+
+void PollingManager::pollDebug()
+{
+ struct timeval timeSaved, timeNow;
+ struct timezone tz;
+ timeSaved.tv_sec = 0;
+ timeSaved.tv_usec = 0;
+ gettimeofday(&timeSaved, &tz);
+
+ poll();
+
+ gettimeofday(&timeNow, &tz);
+ int diff = (int)((timeNow.tv_usec - timeSaved.tv_usec + 500) / 1000 +
+ (timeNow.tv_sec - timeSaved.tv_sec) * 1000);
+ if (diff != 0)
+ fprintf(stderr, "DEBUG: poll(): %4d ms\n", diff);
+}
+
+//
+// Search for changed rectangles on the screen.
+//
+
+void PollingManager::poll()
+{
+ if (!m_server)
+ return;
+
+ int nTilesChanged = 0;
+ int scanLine = m_pollingOrder[m_pollingStep++ % 32];
+ int bytesPerPixel = m_image->xim->bits_per_pixel / 8;
+ int bytesPerLine = m_image->xim->bytes_per_line;
+ int w = m_image->xim->width, h = m_image->xim->height;
+ Rect rect;
+
+ for (int y = 0; y * 32 < h; y++) {
+ int tile_h = (h - y * 32 >= 32) ? 32 : h - y * 32;
+ if (scanLine >= tile_h)
+ continue;
+ int scan_y = y * 32 + scanLine;
+ m_rowImage->get(DefaultRootWindow(m_dpy), 0, scan_y);
+ char *ptr_old = m_image->xim->data + scan_y * bytesPerLine;
+ char *ptr_new = m_rowImage->xim->data;
+ for (int x = 0; x * 32 < w; x++) {
+ int tile_w = (w - x * 32 >= 32) ? 32 : w - x * 32;
+ int nBytes = tile_w * bytesPerPixel;
+ if (memcmp(ptr_old, ptr_new, nBytes)) {
+ if (tile_w == 32 && tile_h == 32) {
+ m_tileImage->get(DefaultRootWindow(m_dpy), x * 32, y * 32);
+ } else {
+ m_tileImage->get(DefaultRootWindow(m_dpy), x * 32, y * 32,
+ tile_w, tile_h);
+ }
+ m_image->updateRect(m_tileImage, x * 32, y * 32);
+ rect.setXYWH(x * 32, y * 32, tile_w, tile_h);
+ m_server->add_changed(rect);
+ nTilesChanged++;
+ }
+ ptr_old += nBytes;
+ ptr_new += nBytes;
+ }
+ }
+
+ if (nTilesChanged)
+ m_server->tryUpdate();
+}
+
diff --git a/x0vncserver/PollingManager.h b/x0vncserver/PollingManager.h
new file mode 100644
index 00000000..aba7ac10
--- /dev/null
+++ b/x0vncserver/PollingManager.h
@@ -0,0 +1,55 @@
+/* Copyright (C) 2004-2005 Constantin Kaplinsky. 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
+ * (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this software; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ */
+
+//
+// PollingManager.h
+//
+
+#ifndef __POLLINGMANAGER_H__
+#define __POLLINGMANAGER_H__
+
+#include <X11/Xlib.h>
+#include <rfb/VNCServer.h>
+
+#include <x0vncserver/Image.h>
+
+using namespace rfb;
+
+class PollingManager {
+
+public:
+
+ PollingManager(Display *dpy, Image *image, ImageFactory *factory);
+
+ void setVNCServer(VNCServer* s);
+ void pollDebug();
+ void poll();
+
+protected:
+
+ Display* m_dpy;
+ VNCServer* m_server;
+ Image* m_image;
+ Image* m_rowImage;
+ Image* m_tileImage;
+ unsigned int m_pollingStep;
+ static const int m_pollingOrder[];
+
+};
+
+#endif // __POLLINGMANAGER_H__
diff --git a/x0vncserver/x0vncserver.cxx b/x0vncserver/x0vncserver.cxx
index f429553a..f799de3a 100644
--- a/x0vncserver/x0vncserver.cxx
+++ b/x0vncserver/x0vncserver.cxx
@@ -34,9 +34,6 @@
#include <network/TcpSocket.h>
-#include "Image.h"
-#include "CPUMonitor.h"
-
#include <signal.h>
#include <X11/X.h>
#include <X11/Xlib.h>
@@ -45,10 +42,11 @@
#include <X11/extensions/XTest.h>
#endif
-#include <rfb/Encoder.h>
+#include <x0vncserver/Image.h>
+#include <x0vncserver/PollingManager.h>
+#include <x0vncserver/CPUMonitor.h>
using namespace rfb;
-using namespace rdr;
using namespace network;
LogWriter vlog("main");
@@ -80,7 +78,7 @@ class XDesktop : public SDesktop, public rfb::ColourMap
public:
XDesktop(Display* dpy_)
: dpy(dpy_), pb(0), server(0), oldButtonMask(0), haveXtest(false),
- maxButtons(0), pollingStep(0)
+ maxButtons(0)
{
#ifdef HAVE_XTEST
int xtestEventBase;
@@ -110,14 +108,12 @@ public:
int dpyWidth = DisplayWidth(dpy, DefaultScreen(dpy));
int dpyHeight = DisplayHeight(dpy, DefaultScreen(dpy));
- // FIXME: verify that all three images use the same pixel format.
ImageFactory factory((bool)useShm, (bool)useOverlay);
image = factory.newImage(dpy, dpyWidth, dpyHeight);
- rowImage = factory.newImage(dpy, dpyWidth, 1);
- tileImage = factory.newImage(dpy, 32, 32);
-
image->get(DefaultRootWindow(dpy));
+ pollmgr = new PollingManager(dpy, image, &factory);
+
pf.bpp = image->xim->bits_per_pixel;
pf.depth = image->xim->depth;
pf.bigEndian = (image->xim->byte_order == MSBFirst);
@@ -134,13 +130,19 @@ public:
}
virtual ~XDesktop() {
delete pb;
+ delete pollmgr;
}
void setVNCServer(VNCServer* s) {
server = s;
+ pollmgr->setVNCServer(s);
server->setPixelBuffer(pb);
}
+ inline void poll() {
+ pollmgr->poll();
+ }
+
// -=- SDesktop interface
virtual void pointerEvent(const Point& pos, rdr::U8 buttonMask) {
@@ -192,95 +194,16 @@ public:
*b = xc.blue;
}
- //
- // DEBUG: a version of poll() measuring time spent in the function.
- //
-
- virtual void pollDebug()
- {
- struct timeval timeSaved, timeNow;
- struct timezone tz;
- timeSaved.tv_sec = 0;
- timeSaved.tv_usec = 0;
- gettimeofday(&timeSaved, &tz);
-
- poll();
-
- gettimeofday(&timeNow, &tz);
- int diff = (int)((timeNow.tv_usec - timeSaved.tv_usec + 500) / 1000 +
- (timeNow.tv_sec - timeSaved.tv_sec) * 1000);
- if (diff != 0)
- fprintf(stderr, "DEBUG: poll(): %4d ms\n", diff);
- }
-
- //
- // Search for changed rectangles on the screen.
- //
-
- virtual void poll()
- {
- if (server == NULL)
- return;
-
- int nTilesChanged = 0;
- int scanLine = XDesktop::pollingOrder[pollingStep++ % 32];
- int bytesPerPixel = image->xim->bits_per_pixel / 8;
- int bytesPerLine = image->xim->bytes_per_line;
- int w = image->xim->width, h = image->xim->height;
- Rect rect;
-
- for (int y = 0; y * 32 < h; y++) {
- int tile_h = (h - y * 32 >= 32) ? 32 : h - y * 32;
- if (scanLine >= tile_h)
- continue;
- int scan_y = y * 32 + scanLine;
- rowImage->get(DefaultRootWindow(dpy), 0, scan_y);
- char *ptr_old = image->xim->data + scan_y * bytesPerLine;
- char *ptr_new = rowImage->xim->data;
- for (int x = 0; x * 32 < w; x++) {
- int tile_w = (w - x * 32 >= 32) ? 32 : w - x * 32;
- int nBytes = tile_w * bytesPerPixel;
- if (memcmp(ptr_old, ptr_new, nBytes)) {
- if (tile_w == 32 && tile_h == 32) {
- tileImage->get(DefaultRootWindow(dpy), x * 32, y * 32);
- } else {
- tileImage->get(DefaultRootWindow(dpy), x * 32, y * 32,
- tile_w, tile_h);
- }
- image->updateRect(tileImage, x * 32, y * 32);
- rect.setXYWH(x * 32, y * 32, tile_w, tile_h);
- server->add_changed(rect);
- nTilesChanged++;
- }
- ptr_old += nBytes;
- ptr_new += nBytes;
- }
- }
-
- if (nTilesChanged)
- server->tryUpdate();
- }
-
protected:
Display* dpy;
PixelFormat pf;
PixelBuffer* pb;
VNCServer* server;
Image* image;
- Image* rowImage;
- Image* tileImage;
+ PollingManager* pollmgr;
int oldButtonMask;
bool haveXtest;
int maxButtons;
- unsigned int pollingStep;
- static const int pollingOrder[];
-};
-
-const int XDesktop::pollingOrder[32] = {
- 0, 16, 8, 24, 4, 20, 12, 28,
- 10, 26, 18, 2, 22, 6, 30, 14,
- 1, 17, 9, 25, 7, 23, 15, 31,
- 19, 3, 27, 11, 29, 13, 5, 21
};