X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f8855e47254a28f5141524b3aaaac03c2944e997..1722a3f626f7b29b42a22fc6329ce12fb5e8ed90:/src/gtk/cursor.cpp diff --git a/src/gtk/cursor.cpp b/src/gtk/cursor.cpp index cac9e5aaba..a323e44d69 100644 --- a/src/gtk/cursor.cpp +++ b/src/gtk/cursor.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: cursor.cpp +// Name: src/gtk/cursor.cpp // Purpose: // Author: Robert Roebling // Id: $Id$ @@ -11,18 +11,15 @@ #include "wx/wxprec.h" #include "wx/cursor.h" -#include "wx/utils.h" -#include "wx/app.h" -#include -#include - -//----------------------------------------------------------------------------- -// idle system -//----------------------------------------------------------------------------- +#ifndef WX_PRECOMP + #include "wx/app.h" + #include "wx/utils.h" + #include "wx/image.h" + #include "wx/colour.h" +#endif // WX_PRECOMP -extern void wxapp_install_idle_handler(); -extern bool g_isIdle; +#include //----------------------------------------------------------------------------- // wxCursor @@ -33,7 +30,7 @@ class wxCursorRefData: public wxObjectRefData public: wxCursorRefData(); - ~wxCursorRefData(); + virtual ~wxCursorRefData(); GdkCursor *m_cursor; }; @@ -45,7 +42,7 @@ wxCursorRefData::wxCursorRefData() wxCursorRefData::~wxCursorRefData() { - if (m_cursor) gdk_cursor_destroy( m_cursor ); + if (m_cursor) gdk_cursor_unref( m_cursor ); } //----------------------------------------------------------------------------- @@ -90,7 +87,7 @@ wxCursor::wxCursor( int cursorId ) case wxCURSOR_ARROWWAIT: case wxCURSOR_WAIT: case wxCURSOR_WATCH: gdk_cur = GDK_WATCH; break; - case wxCURSOR_SIZING: gdk_cur = GDK_SIZING; break; + case wxCURSOR_SIZING: gdk_cur = GDK_FLEUR; break; case wxCURSOR_SPRAYCAN: gdk_cur = GDK_SPRAYCAN; break; case wxCURSOR_IBEAM: gdk_cur = GDK_XTERM; break; case wxCURSOR_PENCIL: gdk_cur = GDK_PENCIL; break; @@ -128,7 +125,7 @@ extern GtkWidget *wxGetRootWindow(); wxCursor::wxCursor(const char bits[], int width, int height, int hotSpotX, int hotSpotY, - const char maskBits[], wxColour *fg, wxColour *bg) + const char maskBits[], const wxColour *fg, const wxColour *bg) { if (!maskBits) maskBits = bits; @@ -149,12 +146,30 @@ wxCursor::wxCursor(const char bits[], int width, int height, data, mask, fg->GetColor(), bg->GetColor(), hotSpotX, hotSpotY ); - gdk_bitmap_unref( data ); - gdk_bitmap_unref( mask ); + g_object_unref (data); + g_object_unref (mask); } #if wxUSE_IMAGE +static void GetHotSpot(const wxImage& image, int& x, int& y) +{ + if (image.HasOption(wxIMAGE_OPTION_CUR_HOTSPOT_X)) + x = image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X); + else + x = 0; + + if (image.HasOption(wxIMAGE_OPTION_CUR_HOTSPOT_Y)) + y = image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_Y); + else + y = 0; + + if (x < 0 || x >= image.GetWidth()) + x = 0; + if (y < 0 || y >= image.GetHeight()) + y = 0; +} + wxCursor::wxCursor( const wxImage & image ) { unsigned char * rgbBits = image.GetData(); @@ -163,6 +178,58 @@ wxCursor::wxCursor( const wxImage & image ) bool bHasMask = image.HasMask(); int imagebitcount = (w*h)/8; +#ifdef __WXGTK24__ + if (!gtk_check_version(2,4,0)) + { + if ( gdk_display_supports_cursor_color(gdk_display_get_default()) ) + { + unsigned char rMask = 0, + gMask = 0, + bMask = 0; + if (bHasMask) + { + rMask = image.GetMaskRed(); + gMask = image.GetMaskGreen(); + bMask = image.GetMaskBlue(); + } + + GdkPixbuf *pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, w, h); + unsigned char *alpha = image.HasAlpha() ? image.GetAlpha() : NULL; + unsigned char *out = gdk_pixbuf_get_pixels(pixbuf); + int rowpad = gdk_pixbuf_get_rowstride(pixbuf) - 4 * w; + for ( int y = 0; y < h; y++, out += rowpad ) + { + for ( int x = 0; x < w; x++, out += 4, rgbBits += 3 ) + { + out[0] = rgbBits[0]; + out[1] = rgbBits[1]; + out[2] = rgbBits[2]; + if (bHasMask && + out[0] == rMask && out[1] == gMask && out[2] == bMask) + out[3] = 0; + else + out[3] = alpha ? *alpha : 255; + if ( alpha ) + ++alpha; + } + } + + int hotSpotX, hotSpotY; + GetHotSpot(image, hotSpotX, hotSpotY); + + m_refData = new wxCursorRefData; + M_CURSORDATA->m_cursor = gdk_cursor_new_from_pixbuf + ( + gdk_display_get_default(), + pixbuf, + hotSpotX, hotSpotY + ); + g_object_unref (pixbuf); + return; + } + } +#endif // GTK+ 2.4+ + unsigned char * bits = new unsigned char [imagebitcount]; unsigned char * maskBits = new unsigned char [imagebitcount]; @@ -269,23 +336,8 @@ wxCursor::wxCursor( const wxImage & image ) bg = tmp; } - int hotSpotX; - int hotSpotY; - - if (image.HasOption(wxIMAGE_OPTION_CUR_HOTSPOT_X)) - hotSpotX = image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X); - else - hotSpotX = 0; - - if (image.HasOption(wxIMAGE_OPTION_CUR_HOTSPOT_Y)) - hotSpotY = image.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_Y); - else - hotSpotY = 0; - - if (hotSpotX < 0 || hotSpotX >= w) - hotSpotX = 0; - if (hotSpotY < 0 || hotSpotY >= h) - hotSpotY = 0; + int hotSpotX, hotSpotY; + GetHotSpot(image, hotSpotX, hotSpotY); GdkBitmap *data = gdk_bitmap_create_from_data(wxGetRootWindow()->window, (gchar *) bits, w, h); @@ -301,8 +353,8 @@ wxCursor::wxCursor( const wxImage & image ) hotSpotX, hotSpotY ); - gdk_bitmap_unref( data ); - gdk_bitmap_unref( mask ); + g_object_unref (data); + g_object_unref (mask); delete [] bits; delete [] maskBits; } @@ -313,17 +365,7 @@ wxCursor::~wxCursor() { } -bool wxCursor::operator == ( const wxCursor& cursor ) const -{ - return m_refData == cursor.m_refData; -} - -bool wxCursor::operator != ( const wxCursor& cursor ) const -{ - return m_refData != cursor.m_refData; -} - -bool wxCursor::Ok() const +bool wxCursor::IsOk() const { return (m_refData != NULL); } @@ -337,7 +379,9 @@ GdkCursor *wxCursor::GetCursor() const // busy cursor routines //----------------------------------------------------------------------------- -extern wxCursor g_globalCursor; +/* Current cursor, in order to hang on to + * cursor handle when setting the cursor globally */ +wxCursor g_globalCursor; static wxCursor gs_savedCursor; static int gs_busyCount = 0; @@ -364,7 +408,7 @@ void wxEndBusyCursor() wxTheApp->ProcessIdle(); } -void wxBeginBusyCursor( wxCursor *WXUNUSED(cursor) ) +void wxBeginBusyCursor( const wxCursor *WXUNUSED(cursor) ) { if (gs_busyCount++ > 0) return; @@ -389,8 +433,6 @@ bool wxIsBusy() void wxSetCursor( const wxCursor& cursor ) { - if (g_isIdle) - wxapp_install_idle_handler(); - g_globalCursor = cursor; + wxTheApp->WakeUpIdle(); }