aboutsummaryrefslogtreecommitdiff
path: root/nxcompshad/Updater.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'nxcompshad/Updater.cpp')
-rw-r--r--nxcompshad/Updater.cpp383
1 files changed, 383 insertions, 0 deletions
diff --git a/nxcompshad/Updater.cpp b/nxcompshad/Updater.cpp
new file mode 100644
index 000000000..3f0e6a4da
--- /dev/null
+++ b/nxcompshad/Updater.cpp
@@ -0,0 +1,383 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
+/* */
+/* NXCOMPSHAD, NX protocol compression and NX extensions to this software */
+/* are copyright of NoMachine. Redistribution and use of the present */
+/* software is allowed according to terms specified in the file LICENSE */
+/* which comes in the source distribution. */
+/* */
+/* Check http://www.nomachine.com/licensing.html for applicability. */
+/* */
+/* NX and NoMachine are trademarks of Medialogic S.p.A. */
+/* */
+/* All rights reserved. */
+/* */
+/**************************************************************************/
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+#include <string.h>
+
+#define PANIC
+#define WARNING
+#undef TEST
+#undef DEBUG
+//
+#include <stdio.h>
+//
+#include "Updater.h"
+#include "Logger.h"
+
+Updater::Updater(char *displayName, Display *display)
+{
+ logTrace("Updater::Updater");
+
+ displayName_ = displayName;
+ display_ = display;
+ closeDisplay_ = false;
+ image_ = NULL;
+ updateRegion_ = NULL;
+ buffer_ = NULL;
+}
+
+Updater::~Updater()
+{
+ logTrace("Updater::~Updater");
+
+ if (input_)
+ {
+ int removedEvents = input_ -> removeAllEvents(display_);
+
+ logTest("Updater::~Updater", "Removed events in input queue is [%d].", removedEvents);
+ }
+
+ if (display_)
+ {
+ XDestroyWindow(display_, window_);
+ XFreePixmap(display_, pixmap_);
+
+ if (closeDisplay_)
+ {
+ XCloseDisplay(display_);
+ }
+ }
+
+ if (image_)
+ {
+ image_ -> data = NULL;
+
+ XDestroyImage(image_);
+ }
+
+ if (updateRegion_)
+ {
+ XDestroyRegion(updateRegion_);
+ }
+}
+
+int Updater::init(int width, int height, char *fb, Input *input)
+{
+ logTrace("Updater::init");
+
+ if (fb == NULL || input == NULL || width <= 0 || height <= 0)
+ {
+ logError("Updater::init", ESET(EINVAL));
+
+ return -1;
+ }
+
+ width_ = width;
+ height_ = height;
+ buffer_ = fb;
+ input_ = input;
+/*
+ if (display_ == NULL)
+ {
+ display_ = XOpenDisplay(displayName_);
+
+ closeDisplay_ = true;
+
+ if (display_ == NULL)
+ {
+ logError("Updater::init", ESET(ENOMSG));
+
+ return -1;
+ }
+ }
+*/
+ depth_ = DefaultDepth(display_, DefaultScreen(display_));
+
+ if (depth_ == 8) bpl_ = width_;
+ else if (depth_ == 16) bpl_ = width_ * 2;
+ else bpl_ = width_ * 4;
+
+ logTest("Updater::init", "Server geometry [%d, %d] depth [%d] bpl [%d].", width_, height_, depth_, bpl_);
+
+/* int bitmap_pad = 8;
+
+ image_ = XCreateImage(display_, DefaultVisual(display_, DefaultScreen(display_)), depth_, ZPixmap, 0,
+ buffer_, width_, height_, bitmap_pad, 0);
+
+ if (image_ == NULL)
+ {
+ logError("Updater::init", ESET(ENOMSG));
+
+ logTest("Updater::init", "Failed to create default image.");
+
+ return -1;
+ }
+
+ pixmap_ = XCreatePixmap(display_, DefaultRootWindow(display_), width_, height_, depth_);
+
+ unsigned int mask = CWBackPixmap | CWBorderPixel | CWEventMask;
+
+ XSetWindowAttributes attributes;
+
+ attributes.background_pixmap = pixmap_;
+ attributes.border_pixel = WhitePixel(display_, DefaultScreen(display_));
+ attributes.event_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask;
+
+ window_ = XCreateWindow(display_, DefaultRootWindow(display_),
+ 0, 0, width_, height_, 0, depth_, InputOutput,
+ DefaultVisual(display_, DefaultScreen(display_)), mask, &attributes);
+
+ if (window_ == None)
+ {
+ logError("Updater::init", ESET(ENOMSG));
+
+ return -1;
+ }
+
+ XSizeHints *size_hints;
+
+ if ((size_hints = XAllocSizeHints()) == NULL)
+ {
+ logError("Updater::init", ESET(ENOMEM));
+
+ return -1;
+ }
+
+ size_hints -> flags = PMinSize | PMaxSize;
+ size_hints -> min_width = width_;
+ size_hints -> max_width = width_;
+ size_hints -> min_height = height_;
+ size_hints -> max_height = height_;
+
+ XSetWMNormalHints(display_, window_, size_hints);
+
+ XFree(size_hints);
+
+ Atom deleteWMatom = XInternAtom(display_, "WM_DELETE_WINDOW", 1);
+
+ XSetWMProtocols(display_, window_, &deleteWMatom, 1);
+
+ XMapWindow(display_, window_);*/
+
+ updateRegion_ = XCreateRegion();
+
+ logTest("Updater::init", "updateRegion_[%p]", updateRegion_);
+ return 1;
+}
+
+void Updater::addRegion(Region region)
+{
+ //
+ // FIXME: Is this too paranoid ?
+ //
+
+ if (updateRegion_ == NULL)
+ {
+ logError("Updater::addRegion", ESET(EINVAL));
+
+ return;
+ }
+
+ XUnionRegion(region, updateRegion_, updateRegion_);
+}
+
+void Updater::update()
+{
+ logTrace("Updater::update");
+
+ if (updateRegion_ == NULL)
+ {
+ logError("Updater::update", ESET(EINVAL));
+
+ return;
+ }
+
+ logTest("Updater::update", "Number of rectangles [%ld].", updateRegion_ -> numRects);
+
+/* for (; updateRegion_ -> numRects > 0; updateRegion_ -> numRects--)
+ {
+ int n = updateRegion_ -> numRects - 1;
+
+ int x = updateRegion_ -> rects[n].x1;
+ int y = updateRegion_ -> rects[n].y1;
+ unsigned int width = updateRegion_ -> rects[n].x2 - updateRegion_ -> rects[n].x1;
+ unsigned int height = updateRegion_ -> rects[n].y2 - updateRegion_ -> rects[n].y1;
+
+ logDebug("Updater::update", "Sending rectangle: [%d, %d, %d, %d].", x, y, width, height);
+
+ //
+ // We need to update the extents.
+ //
+
+ int bitmap_pad;
+
+ if (depth_ == 32 || depth_ == 24)
+ {
+ bitmap_pad = 32;
+ }
+ else if (depth_ == 16)
+ {
+ if ((width & 1) == 0)
+ {
+ bitmap_pad = 32;
+ }
+ else
+ {
+ bitmap_pad = 16;
+ }
+ }
+ else if ((width & 3) == 0)
+ {
+ bitmap_pad = 32;
+ }
+ else if ((width & 1) == 0)
+ {
+ bitmap_pad = 16;
+ }
+ else
+ {
+ bitmap_pad = 8;
+ }*/
+
+/* image_ -> bitmap_pad = bitmap_pad;*/
+
+ /* NXShadowCorrectColor(x, y, width, height);*/
+
+/* XPutImage(display_, pixmap_, DefaultGC(display_, DefaultScreen(display_)),
+ image_, x, y, x, y, width, height);
+
+ XClearArea(display_, window_, x, y, width, height, 0);
+ }*/
+
+ //
+ // Should we reduces the box vector ?
+ //
+ // BOX *box = Xrealloc(updateRegion_ -> rects,
+ // updateRegion_ -> numRects == 0 ? sizeof(BOX) :
+ // updateRegion_ -> numRects * sizeof(BOX));
+ //
+ // if (box)
+ // {
+ // updateRegion_ -> rects = box;
+ // updateRegion_ -> size = 1;
+ // }
+ //
+
+ if (updateRegion_ -> numRects == 0)
+ {
+ updateRegion_ -> extents.x1 = 0;
+ updateRegion_ -> extents.y1 = 0;
+ updateRegion_ -> extents.x2 = 0;
+ updateRegion_ -> extents.y2 = 0;
+ }
+ else
+ {
+ //
+ // FIXME: We have to update the region extents.
+ //
+
+ logTest("Updater::update", "Region extents has not been updated.");
+ }
+}
+
+void Updater::handleInput()
+{
+ logTrace("Updater::handleInput");
+
+ XEvent *event = new XEvent;
+
+ if (event == NULL)
+ {
+ logError("Updater::handleInput", ESET(ENOMEM));
+
+ return;
+ }
+
+ while (XCheckIfEvent(display_, event, anyEventPredicate, NULL))
+ {
+ switch (event -> type)
+ {
+ /* case ClientMessage:
+ {
+ Atom wmProtocols = XInternAtom(display_, "WM_PROTOCOLS", 0);
+ Atom wmDeleteWindow = XInternAtom(display_, "WM_DELETE_WINDOW", 0);
+
+ if (event -> xclient.message_type == wmProtocols &&
+ (Atom)event -> xclient.data.l[0] == wmDeleteWindow)
+ {
+ logTest("Updater::handleInput", "Got client message of type WM_PROTOCOLS and value WM_DELETE_WINDOW,"
+ " throwing exception UpdaterClosing.");
+
+ delete event;
+
+ throw UpdaterClosing();
+ }
+ else
+ {
+ logTest("Updater::handleInput", "Unexpected client message type [%ld] format [%d] first value [%ld]",
+ event -> xclient.message_type, event -> xclient.format, event -> xclient.data.l[0]);
+ }
+
+ break;
+ }*/
+ case KeyPress:
+ case KeyRelease:
+ case ButtonPress:
+ case ButtonRelease:
+ case MotionNotify:
+ {
+ input_ -> pushEvent(display_, event);
+
+ event = new XEvent;
+
+ if (event == NULL)
+ {
+ logError("Updater::handleInput", ESET(ENOMEM));
+
+ return;
+ }
+
+ break;
+ }
+ default:
+ {
+ logTest("Updater::handleInput", "Handling unexpected event [%d].", event -> type);
+
+ break;
+ }
+ }
+ }
+
+ delete event;
+}
+
+void Updater::newRegion()
+{
+ if (updateRegion_ != NULL)
+ {
+ XDestroyRegion(updateRegion_);
+ }
+
+ updateRegion_ = XCreateRegion();
+
+ logTest("Updater::newRegion", "updateRegion_ [%p].", updateRegion_);
+}
+//
+// Private functions.
+//