diff options
-rw-r--r-- | x0vncserver/CPUMonitor.cxx | 2 | ||||
-rw-r--r-- | x0vncserver/Image.cxx | 2 | ||||
-rw-r--r-- | x0vncserver/Makefile.in | 2 | ||||
-rw-r--r-- | x0vncserver/PollingManager.cxx | 127 | ||||
-rw-r--r-- | x0vncserver/PollingManager.h | 55 | ||||
-rw-r--r-- | x0vncserver/x0vncserver.cxx | 103 |
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 }; |