]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/cursor.cpp
don't save the initial selection if it's invalid in CBN_DROPDOWN (refixes #8474 witho...
[wxWidgets.git] / src / gtk / cursor.cpp
index 63a0340630007c2e79928c0fc44a74566a7b4f7b..3e2a20c6320ecd7962dbb6003a6dc98d5bdc4c9d 100644 (file)
 #include "wx/cursor.h"
 
 #ifndef WX_PRECOMP
+    #include "wx/window.h"
     #include "wx/app.h"
-    #include "wx/utils.h"
     #include "wx/image.h"
-    #include "wx/colour.h"
     #include "wx/bitmap.h"
+    #include "wx/log.h"
 #endif // WX_PRECOMP
 
 #include <gtk/gtk.h>
@@ -57,7 +57,7 @@ wxCursor::wxCursor()
 {
 }
 
-wxCursor::wxCursor( int cursorId )
+void wxCursor::InitFromStock( wxStockCursor cursorId )
 {
     m_refData = new wxCursorRefData();
 
@@ -123,9 +123,49 @@ wxCursor::wxCursor( int cursorId )
     M_CURSORDATA->m_cursor = gdk_cursor_new( gdk_cur );
 }
 
+
+// used in the following two ctors
 extern GtkWidget *wxGetRootWindow();
 
-wxCursor::wxCursor(const char bits[], int width, int  height,
+wxCursor::wxCursor(const wxString& cursor_file,
+                   wxBitmapType type,
+                   int hotSpotX, int hotSpotY)
+{
+    /* TODO: test this code! */
+
+    // Must be an XBM file
+    if (type != wxBITMAP_TYPE_XPM) {
+        wxLogError("Invalid cursor bitmap type '%d'", type);
+        return;
+    }
+
+    // load the XPM
+    GdkBitmap *mask = NULL;
+    GdkBitmap *data = gdk_pixmap_create_from_xpm( wxGetRootWindow()->window,
+                                                  &mask, NULL, cursor_file.mb_str() );
+    if (!data)
+        return;
+
+    // check given hotspot
+    gint w, h;
+    gdk_drawable_get_size( data, &w, &h );
+    if (hotSpotX < 0 || hotSpotX >= w)
+        hotSpotX = 0;
+    if (hotSpotY < 0 || hotSpotY >= h)
+        hotSpotY = 0;
+
+    // create the real cursor
+    m_refData = new wxCursorRefData;
+    M_CURSORDATA->m_cursor =
+        gdk_cursor_new_from_pixmap( data, mask,
+                                    wxBLACK->GetColor(), wxWHITE->GetColor(),
+                                    hotSpotX, hotSpotY );
+
+    g_object_unref (data);
+    g_object_unref (mask);
+}
+
+wxCursor::wxCursor(const char bits[], int width, int height,
                    int hotSpotX, int hotSpotY,
                    const char maskBits[], const wxColour *fg, const wxColour *bg)
 {
@@ -345,19 +385,31 @@ const wxCursor wxBusyCursor::GetBusyCursor()
     return wxCursor(wxCURSOR_WATCH);
 }
 
+static void InternalIdle(const wxWindowList& list, GdkDisplay*& display)
+{
+    wxWindowList::const_iterator i = list.begin();
+    for (size_t n = list.size(); n--; ++i)
+    {
+        wxWindow* win = *i;
+        if (display == NULL && win->m_widget && win->m_widget->window)
+            display = gdk_drawable_get_display(win->m_widget->window);
+        win->OnInternalIdle();
+        InternalIdle(win->GetChildren(), display);
+    }
+}
+
 void wxEndBusyCursor()
 {
     if (--gs_busyCount > 0)
         return;
 
-    wxSetCursor( gs_savedCursor );
+    g_globalCursor = gs_savedCursor;
     gs_savedCursor = wxNullCursor;
-
-    if (wxTheApp)
-        wxTheApp->ProcessIdle();
+    GdkDisplay* unused = NULL;
+    InternalIdle(wxTopLevelWindows, unused);
 }
 
-void wxBeginBusyCursor( const wxCursor *WXUNUSED(cursor) )
+void wxBeginBusyCursor(const wxCursor* cursor)
 {
     if (gs_busyCount++ > 0)
         return;
@@ -366,13 +418,11 @@ void wxBeginBusyCursor( const wxCursor *WXUNUSED(cursor) )
                   wxT("forgot to call wxEndBusyCursor, will leak memory") );
 
     gs_savedCursor = g_globalCursor;
-
-    wxSetCursor( wxCursor(wxCURSOR_WATCH) );
-
-    if (wxTheApp)
-        wxTheApp->ProcessIdle();
-
-    gdk_flush();
+    g_globalCursor = *cursor;
+    GdkDisplay* display = NULL;
+    InternalIdle(wxTopLevelWindows, display);
+    if (display)
+        gdk_display_flush(display);
 }
 
 bool wxIsBusy()