Add support for cursors to the new viewer.
git-svn-id: svn://svn.code.sf.net/p/tigervnc/code/trunk@4472 3789f03b-4d11-0410-bbf8-ca57d06f2519
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 94b05b9..3360626 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -194,6 +194,9 @@
if(X11_Xfixes_FOUND)
set(FLTK_LIBRARIES ${FLTK_LIBRARIES} ${X11_Xfixes_LIB})
endif()
+ if(X11_Xcursor_FOUND)
+ set(FLTK_LIBRARIES ${FLTK_LIBRARIES} ${X11_Xcursor_LIB})
+ endif()
set(CMAKE_REQUIRED_INCLUDES ${FLTK_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${FLTK_LIBRARIES})
@@ -210,6 +213,9 @@
# FLTK STR #2641
check_cxx_source_compiles("#include <FL/Enumerations.H>\nint main(int c, char** v) { return FL_FULLSCREEN; }" HAVE_FLTK_FULLSCREEN)
+ # FLTK STR #2660
+ check_cxx_source_compiles("#include <FL/Fl_Window.H>\nint main(int c, char** v) { void (Fl_Window::*foo)(const Fl_RGB_Image*,int,int) = &Fl_Window::cursor; return 0; }" HAVE_FLTK_CURSOR)
+
set(CMAKE_REQUIRED_INCLUDES)
set(CMAKE_REQUIRED_LIBRARIES)
endif()
diff --git a/config.h.cmake.in b/config.h.cmake.in
index 91dff67..bce755f 100644
--- a/config.h.cmake.in
+++ b/config.h.cmake.in
@@ -15,6 +15,7 @@
#cmakedefine HAVE_FLTK_CLIPBOARD
#cmakedefine HAVE_FLTK_MEDIAKEYS
#cmakedefine HAVE_FLTK_FULLSCREEN
+#cmakedefine HAVE_FLTK_CURSOR
#cmakedefine ENABLE_NLS 1
/* MS Visual Studio 2008 and newer doesn't know ssize_t */
diff --git a/vncviewer/CConn.cxx b/vncviewer/CConn.cxx
index 3a6c038..a4392a3 100644
--- a/vncviewer/CConn.cxx
+++ b/vncviewer/CConn.cxx
@@ -391,7 +391,7 @@
void CConn::setCursor(int width, int height, const Point& hotspot,
void* data, void* mask)
{
-// desktop->setCursor(width, height, hotspot, data, mask);
+ desktop->setCursor(width, height, hotspot, data, mask);
}
////////////////////// Internal methods //////////////////////
diff --git a/vncviewer/DesktopWindow.cxx b/vncviewer/DesktopWindow.cxx
index 8350a42..52725ed 100644
--- a/vncviewer/DesktopWindow.cxx
+++ b/vncviewer/DesktopWindow.cxx
@@ -109,14 +109,6 @@
}
-// Cursor stuff
-
-void DesktopWindow::setCursor(int width, int height, const Point& hotspot,
- void* data, void* mask)
-{
-}
-
-
void DesktopWindow::setName(const char *name)
{
CharArray windowNameStr;
@@ -185,6 +177,13 @@
}
+void DesktopWindow::setCursor(int width, int height, const Point& hotspot,
+ void* data, void* mask)
+{
+ viewport->setCursor(width, height, hotspot, data, mask);
+}
+
+
void DesktopWindow::resize(int x, int y, int w, int h)
{
Fl_Window::resize(x, y, w, h);
diff --git a/vncviewer/DesktopWindow.h b/vncviewer/DesktopWindow.h
index ec7b05b..2be0768 100644
--- a/vncviewer/DesktopWindow.h
+++ b/vncviewer/DesktopWindow.h
@@ -43,10 +43,6 @@
// Most efficient format (from DesktopWindow's point of view)
const rfb::PixelFormat &getPreferredPF();
- // setCursor() sets the shape of the local cursor
- void setCursor(int width, int height, const rfb::Point& hotspot,
- void* data, void* mask);
-
// Flush updates to screen
void updateWindow();
@@ -67,6 +63,9 @@
void resizeFramebuffer(int new_w, int new_h);
+ void setCursor(int width, int height, const rfb::Point& hotspot,
+ void* data, void* mask);
+
// Fl_Window callback methods
void resize(int x, int y, int w, int h);
diff --git a/vncviewer/Viewport.cxx b/vncviewer/Viewport.cxx
index 95d883c..474ae14 100644
--- a/vncviewer/Viewport.cxx
+++ b/vncviewer/Viewport.cxx
@@ -47,6 +47,7 @@
#include "keysym2ucs.h"
using namespace rfb;
+using namespace rdr;
extern void exit_vncviewer();
extern void about_vncviewer();
@@ -60,7 +61,7 @@
Viewport::Viewport(int w, int h, const rfb::PixelFormat& serverPF, CConn* cc_)
: Fl_Widget(0, 0, w, h), cc(cc_), frameBuffer(NULL), pixelTrans(NULL),
- lastPointerPos(0, 0), lastButtonMask(0)
+ lastPointerPos(0, 0), lastButtonMask(0), cursor(NULL)
{
// FLTK STR #2599 must be fixed for proper dead keys support
#ifdef HAVE_FLTK_DEAD_KEYS
@@ -115,6 +116,11 @@
if (pixelTrans)
delete pixelTrans;
+ if (cursor) {
+ delete [] cursor->array;
+ delete cursor;
+ }
+
// FLTK automatically deletes all child widgets, so we shouldn't touch
// them ourselves here
}
@@ -173,6 +179,49 @@
}
+void Viewport::setCursor(int width, int height, const Point& hotspot,
+ void* data, void* mask)
+{
+#ifdef HAVE_FLTK_CURSOR
+ U8 *buffer = new U8[width*height*4];
+ U8 *i, *o, *m;
+ int m_width;
+
+ const PixelFormat &pf = frameBuffer->getPF();
+
+ i = (U8*)data;
+ o = buffer;
+ m = (U8*)mask;
+ m_width = (width+7)/8;
+ for (int y = 0;y < height;y++) {
+ for (int x = 0;x < width;x++) {
+ pf.rgbFromBuffer(o, i, 1, &colourMap);
+
+ if (m[(m_width*y)+(x/8)] & 0x80>>(x%8))
+ o[3] = 255;
+ else
+ o[3] = 0;
+
+ o += 4;
+ i += pf.bpp/8;
+ }
+ }
+
+ if (cursor) {
+ delete [] cursor->array;
+ delete cursor;
+ }
+
+ cursor = new Fl_RGB_Image(buffer, width, height, 4);
+
+ cursorHotspot = hotspot;
+
+ if (Fl::belowmouse() == this)
+ window()->cursor(cursor, cursorHotspot.x, cursorHotspot.y);
+#endif
+}
+
+
void Viewport::draw()
{
int X, Y, W, H;
@@ -263,7 +312,17 @@
case FL_ENTER:
// Yes, we would like some pointer events please!
+#ifdef HAVE_FLTK_CURSOR
+ window()->cursor(cursor, cursorHotspot.x, cursorHotspot.y);
+#endif
return 1;
+
+ case FL_LEAVE:
+#ifdef HAVE_FLTK_CURSOR
+ window()->cursor(FL_CURSOR_DEFAULT);
+#endif
+ return 1;
+
case FL_PUSH:
case FL_RELEASE:
case FL_DRAG:
diff --git a/vncviewer/Viewport.h b/vncviewer/Viewport.h
index 293eb93..b8f1a78 100644
--- a/vncviewer/Viewport.h
+++ b/vncviewer/Viewport.h
@@ -25,6 +25,7 @@
#include <FL/Fl.H>
#include <FL/Fl_Widget.H>
#include <FL/Fl_Menu_Button.H>
+#include <FL/Fl_RGB_Image.H>
#include <rfb/Rect.h>
#include <rfb/Region.h>
@@ -78,6 +79,9 @@
damageRect(r);
}
+ void setCursor(int width, int height, const rfb::Point& hotspot,
+ void* data, void* mask);
+
// Fl_Widget callback methods
void draw();
@@ -130,6 +134,9 @@
int menuKeyCode;
Fl_Menu_Button *contextMenu;
+
+ Fl_RGB_Image *cursor;
+ rfb::Point cursorHotspot;
};
#endif