From: Pierre Ossman Date: Wed, 8 Jun 2011 17:02:36 +0000 (+0000) Subject: Add support for cursors to the new viewer. X-Git-Tag: v1.1.90~308 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=835b4ef7cdf7df1f91aa0d337a5a4537011d4742;p=tigervnc.git 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 94b05b91..33606267 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -194,6 +194,9 @@ if(BUILD_NEW_VNCVIEWER) 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 @@ if(BUILD_NEW_VNCVIEWER) # FLTK STR #2641 check_cxx_source_compiles("#include \nint main(int c, char** v) { return FL_FULLSCREEN; }" HAVE_FLTK_FULLSCREEN) + # FLTK STR #2660 + check_cxx_source_compiles("#include \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 91dff67c..bce755fe 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 3a6c038d..a4392a35 100644 --- a/vncviewer/CConn.cxx +++ b/vncviewer/CConn.cxx @@ -391,7 +391,7 @@ void CConn::copyRect(const rfb::Rect& r, int sx, int sy) 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 8350a42f..52725ed2 100644 --- a/vncviewer/DesktopWindow.cxx +++ b/vncviewer/DesktopWindow.cxx @@ -109,14 +109,6 @@ const rfb::PixelFormat &DesktopWindow::getPreferredPF() } -// 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::resizeFramebuffer(int new_w, int new_h) } +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 ec7b05b7..2be07680 100644 --- a/vncviewer/DesktopWindow.h +++ b/vncviewer/DesktopWindow.h @@ -43,10 +43,6 @@ public: // 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 @@ public: 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 95d883ca..474ae14d 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 @@ enum { ID_EXIT, ID_FULLSCREEN, ID_CTRL, ID_ALT, ID_MENUKEY, ID_CTRLALTDEL, 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 @@ Viewport::~Viewport() 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::updateWindow() } +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 @@ int Viewport::handle(int event) 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 293eb93b..b8f1a789 100644 --- a/vncviewer/Viewport.h +++ b/vncviewer/Viewport.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -78,6 +79,9 @@ public: 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 @@ private: int menuKeyCode; Fl_Menu_Button *contextMenu; + + Fl_RGB_Image *cursor; + rfb::Point cursorHotspot; }; #endif