After searching around a bit I couldn't find any support for mouse wheels
in the Win32 VNC viewer, so I decided to implement it myself.

My solution is a bit of a hack but it does work when connecting from a
Win32 client to an X server.  It is not compatible with the Win32 server.

The attached patch translates wheel movements into buttons 4 and 5, this is
compatible with the way most X applications seem to want the wheel to
work.

See http://koala.ilog.fr/colas/mouse-wheel-scroll/ for ways to persuade
various applications to work with the wheel.

-- 
Mike Crowe <[EMAIL PROTECTED]>
diff -w -u -p --recursive -N vnc_winsrc/vncviewer/ClientConnection.cpp 
vnc_winsrc.mac/vncviewer/ClientConnection.cpp
--- vnc_winsrc/vncviewer/ClientConnection.cpp   Mon Mar 19 14:58:32 2001
+++ vnc_winsrc.mac/vncviewer/ClientConnection.cpp       Sun Apr 21 17:57:52 2002
@@ -862,6 +862,8 @@ LRESULT CALLBACK ClientConnection::WndPr
        case WM_MBUTTONUP:
        case WM_RBUTTONDOWN:
        case WM_RBUTTONUP:
+       case WM_XBUTTONDOWN:
+       case WM_XBUTTONUP:
        case WM_MOUSEMOVE:
                {
                        if (!_this->m_running) return 0;
@@ -877,6 +879,9 @@ LRESULT CALLBACK ClientConnection::WndPr
                        return 0;
                }
 
+       case WM_MOUSEWHEEL:
+               _this->ProcessWheelEvent(LOWORD(lParam), HIWORD(lParam), wParam);
+               break;
        case WM_KEYDOWN:
        case WM_KEYUP:
        case WM_SYSKEYDOWN:
@@ -1263,6 +1268,42 @@ LRESULT CALLBACK ClientConnection::WndPr
 
 #pragma warning(default : 4101)
 
+void 
+ClientConnection::ProcessWheelEvent(int x, int y, WPARAM wParam)
+{
+    static int wheel_value = 0;
+    int wheel_delta = GET_WHEEL_DELTA_WPARAM(wParam);
+    if (wheel_delta)
+    {
+       int standard_button_mask = BuildMouseButtonFlags(wParam);
+
+       wheel_value += wheel_delta;
+       while (abs(wheel_value) >= WHEEL_DELTA)
+       {
+           int button_mask;
+           if (wheel_value > 0)
+           {
+               button_mask = standard_button_mask | rfbButton4Mask;
+               wheel_value -= WHEEL_DELTA;
+           }
+           else
+           {
+               button_mask = standard_button_mask | rfbButton5Mask;
+               wheel_value += WHEEL_DELTA;
+           }
+
+           // Press the button
+           SendPointerEvent((x + m_hScrollPos) * m_opts.m_scale_den / 
+m_opts.m_scale_num, 
+                    (y + m_vScrollPos) * m_opts.m_scale_den / m_opts.m_scale_num, 
+button_mask);
+
+           // And release it.
+           SendPointerEvent((x + m_hScrollPos) * m_opts.m_scale_den / 
+m_opts.m_scale_num, 
+                    (y + m_vScrollPos) * m_opts.m_scale_den / m_opts.m_scale_num, 
+standard_button_mask);
+       }
+    }
+}
+
+
 // ProcessPointerEvent handles the delicate case of emulating 3 buttons
 // on a two button mouse, then passes events off to SubProcessPointerEvent.
 void
@@ -1376,23 +1417,35 @@ ClientConnection::ProcessPointerEvent(in
          }
 }
 
-// SubProcessPointerEvent takes windows positions and flags and converts 
-// them into VNC ones.
-
-inline void 
-ClientConnection::SubProcessPointerEvent(int x, int y, DWORD keyflags) 
+inline int 
+ClientConnection::BuildMouseButtonFlags(DWORD keyflags) const
 {
   int mask;
   
-  if (m_opts.m_SwapMouse) {
-               mask = ( ((keyflags & MK_LBUTTON) ? rfbButton1Mask : 0) |
+    if (m_opts.m_SwapMouse)
+    {
+       mask = (((keyflags & MK_LBUTTON)  ? rfbButton2Mask : 0) |
                        ((keyflags & MK_MBUTTON) ? rfbButton3Mask : 0) |
-                       ((keyflags & MK_RBUTTON) ? rfbButton2Mask : 0)  );
+               ((keyflags & MK_RBUTTON)  ? rfbButton1Mask : 0) |
+               ((keyflags & MK_XBUTTON1) ? rfbButton6Mask : 0) |
+               ((keyflags & MK_XBUTTON2) ? rfbButton7Mask : 0));
        } else {
                mask = ( ((keyflags & MK_LBUTTON) ? rfbButton1Mask : 0) |
                        ((keyflags & MK_MBUTTON) ? rfbButton2Mask : 0) |
-                       ((keyflags & MK_RBUTTON) ? rfbButton3Mask : 0)  );
+               ((keyflags & MK_RBUTTON) ? rfbButton3Mask : 0) |
+               ((keyflags & MK_XBUTTON1) ? rfbButton6Mask : 0) |
+               ((keyflags & MK_XBUTTON2) ? rfbButton7Mask : 0));
        }
+    return mask;
+}
+
+// SubProcessPointerEvent takes windows positions and flags and converts 
+// them into VNC ones.
+
+inline void 
+ClientConnection::SubProcessPointerEvent(int x, int y, DWORD keyflags) 
+{
+  int mask = BuildMouseButtonFlags(keyflags);
        
        try {
                SendPointerEvent((x + m_hScrollPos) * m_opts.m_scale_den / 
m_opts.m_scale_num, 
diff -w -u -p --recursive -N vnc_winsrc/vncviewer/ClientConnection.h 
vnc_winsrc.mac/vncviewer/ClientConnection.h
--- vnc_winsrc/vncviewer/ClientConnection.h     Mon Mar 19 14:58:32 2001
+++ vnc_winsrc.mac/vncviewer/ClientConnection.h Sun Apr 21 17:44:40 2002
@@ -91,6 +91,7 @@ private:
        void SubProcessPointerEvent(int x, int y, DWORD keyflags);
        void SendPointerEvent(int x, int y, int buttonMask);
     void ProcessKeyEvent(int virtkey, DWORD keyData);
+       void ProcessWheelEvent(int x, int y, WPARAM wparam);
        void SendKeyEvent(CARD32 key, bool down);
        
        void ReadScreenUpdate();
@@ -134,6 +135,8 @@ private:
        void ReadExact(char *buf, int bytes);
        void ReadString(char *buf, int length);
        void WriteExact(char *buf, int bytes);
+
+       int BuildMouseButtonFlags(DWORD keyflags) const;
 
        // This is what controls the thread
        void * run_undetached(void* arg);
diff -w -u -p --recursive -N vnc_winsrc/vncviewer/rfbproto.h 
vnc_winsrc.mac/vncviewer/rfbproto.h
--- vnc_winsrc/vncviewer/rfbproto.h     Mon Mar 19 14:58:36 2001
+++ vnc_winsrc.mac/vncviewer/rfbproto.h Sun Apr 21 17:12:00 2002
@@ -678,6 +678,10 @@ typedef struct {
 #define rfbButton1Mask 1
 #define rfbButton2Mask 2
 #define rfbButton3Mask 4
+#define rfbButton4Mask 8
+#define rfbButton5Mask 16
+#define rfbButton6Mask 32
+#define rfbButton7Mask 64
 
 #define sz_rfbPointerEventMsg 6
 
diff -w -u -p --recursive -N vnc_winsrc/vncviewer/stdhdrs.h 
vnc_winsrc.mac/vncviewer/stdhdrs.h
--- vnc_winsrc/vncviewer/stdhdrs.h      Mon Mar 19 14:58:36 2001
+++ vnc_winsrc.mac/vncviewer/stdhdrs.h  Sun Apr 21 17:55:06 2002
@@ -24,6 +24,7 @@
 
 #define VC_EXTRALEAN
 
+#define _WIN32_WINNT 0x0500
 #include <winsock2.h>
 #include <stdio.h>
 #include <process.h>
---------------------------------------------------------------------
To unsubscribe, mail [EMAIL PROTECTED] with the line:
'unsubscribe vnc-list' in the message BODY
See also: http://www.uk.research.att.com/vnc/intouch.html
---------------------------------------------------------------------

Reply via email to