aboutsummaryrefslogtreecommitdiffstats
path: root/vncviewer/DesktopWindow.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vncviewer/DesktopWindow.cxx')
-rw-r--r--vncviewer/DesktopWindow.cxx186
1 files changed, 186 insertions, 0 deletions
diff --git a/vncviewer/DesktopWindow.cxx b/vncviewer/DesktopWindow.cxx
new file mode 100644
index 00000000..28f6c09a
--- /dev/null
+++ b/vncviewer/DesktopWindow.cxx
@@ -0,0 +1,186 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
+ * Copyright 2011 Pierre Ossman <ossman@cendio.se> for Cendio AB
+ *
+ * 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.
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <FL/fl_draw.H>
+
+#include <rfb/CMsgWriter.h>
+#include <rfb/LogWriter.h>
+
+#include "DesktopWindow.h"
+#include "CConn.h"
+#include "i18n.h"
+#include "parameters.h"
+
+using namespace rfb;
+
+extern void exit_vncviewer();
+
+static rfb::LogWriter vlog("DesktopWindow");
+
+DesktopWindow::DesktopWindow(int w, int h, const char *name,
+ const rfb::PixelFormat& serverPF,
+ CConn* cc_)
+ : Fl_Window(w, h), cc(cc_), frameBuffer(NULL), pixelTrans(NULL)
+{
+ callback(handleClose, this);
+
+ setName(name);
+
+ frameBuffer = new ManagedPixelBuffer(getPreferredPF(), w, h);
+ assert(frameBuffer);
+
+ setServerPF(serverPF);
+
+ show();
+}
+
+
+DesktopWindow::~DesktopWindow()
+{
+ delete frameBuffer;
+
+ if (pixelTrans)
+ delete pixelTrans;
+}
+
+
+void DesktopWindow::setServerPF(const rfb::PixelFormat& pf)
+{
+ if (pixelTrans)
+ delete pixelTrans;
+ pixelTrans = NULL;
+
+ if (pf.equal(getPreferredPF()))
+ return;
+
+ pixelTrans = new PixelTransformer();
+ pixelTrans->init(pf, &colourMap, getPreferredPF());
+}
+
+
+const rfb::PixelFormat &DesktopWindow::getPreferredPF()
+{
+ static PixelFormat prefPF(32, 24, false, true, 255, 255, 255, 0, 8, 16);
+
+ return prefPF;
+}
+
+
+// Cursor stuff
+
+void DesktopWindow::setCursor(int width, int height, const Point& hotspot,
+ void* data, void* mask)
+{
+}
+
+
+void DesktopWindow::setName(const char *name)
+{
+ CharArray windowNameStr;
+ windowNameStr.replaceBuf(new char[256]);
+
+ snprintf(windowNameStr.buf, 256, _("TigerVNC: %.240s"), name);
+
+ copy_label(windowNameStr.buf);
+}
+
+// setColourMapEntries() changes some of the entries in the colourmap.
+// Unfortunately these messages are often sent one at a time, so we delay the
+// settings taking effect by 100ms. This is because recalculating the internal
+// translation table can be expensive.
+void DesktopWindow::setColourMapEntries(int firstColour, int nColours,
+ rdr::U16* rgbs)
+{
+ for (int i = 0; i < nColours; i++)
+ colourMap.set(firstColour+i, rgbs[i*3], rgbs[i*3+1], rgbs[i*3+2]);
+
+ if (!Fl::has_timeout(handleColourMap, this))
+ Fl::add_timeout(0.100, handleColourMap, this);
+}
+
+
+// Copy the areas of the framebuffer that have been changed (damaged)
+// to the displayed window.
+
+void DesktopWindow::updateWindow()
+{
+ Rect r;
+
+ Fl::remove_timeout(handleUpdateTimeout, this);
+
+ r = damage.get_bounding_rect();
+ Fl_Window::damage(FL_DAMAGE_USER1, r.tl.x, r.tl.y, r.width(), r.height());
+
+ damage.clear();
+}
+
+
+void DesktopWindow::draw()
+{
+ int X, Y, W, H;
+
+ int pixel_bytes, stride_bytes;
+ const uchar *buf_start;
+
+ // Check what actually needs updating
+ fl_clip_box(0, 0, w(), h(), X, Y, W, H);
+ if ((W == 0) || (H == 0))
+ return;
+
+ pixel_bytes = frameBuffer->getPF().bpp/8;
+ stride_bytes = pixel_bytes * frameBuffer->getStride();
+ buf_start = frameBuffer->data +
+ pixel_bytes * X +
+ stride_bytes * Y;
+
+ // FIXME: Check how efficient this thing really is
+ fl_draw_image(buf_start, X, Y, W, H, pixel_bytes, stride_bytes);
+}
+
+
+void DesktopWindow::handleUpdateTimeout(void *data)
+{
+ DesktopWindow *self = (DesktopWindow *)data;
+
+ assert(self);
+
+ self->updateWindow();
+}
+
+
+void DesktopWindow::handleColourMap(void *data)
+{
+ DesktopWindow *self = (DesktopWindow *)data;
+
+ assert(self);
+
+ if (self->pixelTrans != NULL)
+ self->pixelTrans->setColourMapEntries(0, 0);
+
+ self->Fl_Window::damage(FL_DAMAGE_ALL);
+}
+
+void DesktopWindow::handleClose(Fl_Widget *wnd, void *data)
+{
+ exit_vncviewer();
+}