Migrating to new directory structure adopted from the RealVNC's source tree. More changes will follow.
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@591 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/win/rfb_win32/CPointer.cxx b/win/rfb_win32/CPointer.cxx
new file mode 100644
index 0000000..3d0d934
--- /dev/null
+++ b/win/rfb_win32/CPointer.cxx
@@ -0,0 +1,186 @@
+/* Copyright (C) 2002-2005 RealVNC Ltd. 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.
+ */
+
+#include <windows.h>
+#include <rfb/LogWriter.h>
+#include <rfb_win32/CPointer.h>
+
+using namespace rfb;
+using namespace win32;
+
+static LogWriter vlog("CPointer");
+
+
+CPointer::CPointer() : currButtonMask(0), intervalQueued(false), threeEmulating(false) {
+}
+
+CPointer::~CPointer() {
+ intervalTimer.stop();
+ threeTimer.stop();
+}
+
+
+void CPointer::pointerEvent(InputHandler* writer, const Point& pos, int buttonMask) {
+ //
+ // - Duplicate Event Filtering
+ //
+
+ bool maskChanged = buttonMask != currButtonMask;
+ bool posChanged = !pos.equals(currPos);
+ if (!(posChanged || maskChanged))
+ return;
+
+ // Pass on the event to the event-interval handler
+ threePointerEvent(writer, pos, buttonMask);
+
+ // Save the position and mask
+ currPos = pos;
+ currButtonMask = buttonMask;
+}
+
+
+inline abs(int x) {return x>0 ? x : 0;}
+
+int emulate3Mask(int buttonMask) {
+ // - Release left & right and press middle
+ vlog.debug("emulate3: active");
+ buttonMask &= ~5;
+ buttonMask |= 2;
+ return buttonMask;
+}
+
+void CPointer::threePointerEvent(InputHandler* writer, const Point& pos, int buttonMask) {
+ //
+ // - 3-Button Mouse Emulation
+ //
+
+ if (emulate3) {
+
+ bool leftChanged = (buttonMask & 1) != (currButtonMask & 1);
+ bool rightChanged = (buttonMask & 4) != (currButtonMask & 4);
+
+ if (leftChanged || rightChanged) {
+ // - One of left or right have changed
+
+ if ((buttonMask & 5) == 1 || (buttonMask & 5) == 4) {
+ // - One is up, one is down. Start a timer, so that if it
+ // expires then we know we should actually send this event
+ vlog.debug("emulate3: start timer");
+ threeTimer.start(100);
+ threePos = pos;
+ threeMask = buttonMask;
+ return;
+
+ } else if (threeTimer.isActive()) {
+ // - Both are up or both are down, and we were timing for an emulation event
+ // Stop the timer and flush the stored event
+ vlog.debug("emulate3: stop timer (state)");
+ threeTimer.stop();
+ if (threeEmulating == ((buttonMask & 5) == 5))
+ intervalPointerEvent(writer, threePos, threeMask);
+ else
+ threeEmulating = ((buttonMask & 5) == 5);
+ }
+
+ } else {
+
+ if (threeTimer.isActive()) {
+ // - We are timing for an emulation event
+
+ if (abs(threePos.x - pos.x) <= 4 || abs(threePos.y - pos.y) <= 4) {
+ // If the mouse has moved too far since the button-change event then flush
+ vlog.debug("emulate3: stop timer (moved)");
+ threeTimer.stop();
+ intervalPointerEvent(writer, threePos, threeMask);
+
+ } else {
+ // Otherwise, we ignore the new event
+ return;
+ }
+ }
+
+ }
+
+ // - If neither left nor right are down, stop emulating
+ if ((buttonMask & 5) == 0)
+ threeEmulating = false;
+
+ // - If emulating, release left & right and press middle
+ if (threeEmulating)
+ buttonMask = emulate3Mask(buttonMask);
+
+ }
+
+ // - Let the event pass through to the next stage of processing
+ intervalPointerEvent(writer, pos, buttonMask);
+}
+
+void CPointer::intervalPointerEvent(InputHandler* writer, const Point& pos, int buttonMask) {
+ //
+ // - Pointer Event Interval
+ //
+ vlog.write(101, "ptrEvent: %d,%d (%lx)", pos.x, pos.y, buttonMask);
+
+ // Send the event immediately if we haven't sent one for a while
+ bool sendNow = !intervalTimer.isActive();
+
+ if (intervalMask != buttonMask) {
+ // If the buttons have changed then flush queued events and send now
+ sendNow = true;
+ if (intervalQueued)
+ writer->pointerEvent(intervalPos, intervalMask);
+ intervalQueued = false;
+ }
+
+ if (!sendNow) {
+ // If we're not sending now then just queue the event
+ intervalQueued = true;
+ intervalPos = pos;
+ intervalMask = buttonMask;
+ } else {
+ // Start the interval timer if required, and send the event
+ intervalQueued = false;
+ intervalMask = buttonMask;
+ if (pointerEventInterval)
+ intervalTimer.start(pointerEventInterval);
+ writer->pointerEvent(pos, buttonMask);
+ }
+}
+
+void CPointer::handleTimer(InputHandler* writer, int timerId) {
+ if (timerId == intervalTimer.getId()) {
+ // Pointer interval has expired - send any queued events
+ if (intervalQueued) {
+ writer->pointerEvent(intervalPos, intervalMask);
+ intervalQueued = false;
+ } else {
+ intervalTimer.stop();
+ }
+
+ } else if (timerId = threeTimer.getId()) {
+ // 3-Button emulation timer has expired - send what we've got
+ vlog.debug("emulate3: timeout");
+ threeTimer.stop();
+
+ // If emulating, release left & right and press middle
+ if (threeEmulating)
+ threeMask = emulate3Mask(threeMask);
+
+ intervalPointerEvent(writer, threePos, threeMask);
+ }
+}