X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/bc797f4cc8ffe36277ba8b7dd4b57e63a96bfcb5..d3e780ecdf69233c872d51216eedbc64a1b6db25:/src/x11/cursor.cpp diff --git a/src/x11/cursor.cpp b/src/x11/cursor.cpp index cb0e61f34f..fe53a0a5e9 100644 --- a/src/x11/cursor.cpp +++ b/src/x11/cursor.cpp @@ -9,7 +9,7 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "cursor.h" #endif @@ -19,421 +19,215 @@ #include "wx/app.h" #include "wx/utils.h" -#ifdef __VMS__ -#pragma message disable nosimpint -#endif +#include "wx/x11/private.h" + +#if !wxUSE_NANOX #include -#ifdef __VMS__ -#pragma message enable nosimpint #endif -#include "wx/x11/private.h" +//----------------------------------------------------------------------------- +// wxCursor +//----------------------------------------------------------------------------- + +class wxCursorRefData: public wxObjectRefData +{ +public: + + wxCursorRefData(); + ~wxCursorRefData(); -IMPLEMENT_DYNAMIC_CLASS(wxCursor, wxBitmap) -IMPLEMENT_DYNAMIC_CLASS(wxXCursor, wxObject) + WXCursor m_cursor; + WXDisplay *m_display; +}; wxCursorRefData::wxCursorRefData() { - m_width = 32; m_height = 32; - m_cursorId = wxCURSOR_NONE; + m_cursor = NULL; + m_display = NULL; } wxCursorRefData::~wxCursorRefData() { - wxNode* node = m_cursors.First(); - while (node) - { - wxXCursor* c = (wxXCursor*) node->Data(); - // TODO: how to delete cursor? - // XDestroyCursor((Display*) c->m_display, (Cursor) c->m_cursor); // ?? - delete c; - node = node->Next(); - } + if (m_cursor) + XFreeCursor( (Display*) m_display, (Cursor) m_cursor ); } +//----------------------------------------------------------------------------- + +#define M_CURSORDATA ((wxCursorRefData *)m_refData) + +IMPLEMENT_DYNAMIC_CLASS(wxCursor,wxObject) + wxCursor::wxCursor() { + } -wxCursor::wxCursor(const char bits[], int width, int height, - int hotSpotX, int hotSpotY, const char maskBits[]) +wxCursor::wxCursor( int cursorId ) { - m_refData = new wxCursorRefData; - - Display *dpy = (Display*) wxGetDisplay(); - int screen_num = DefaultScreen (dpy); - - Pixmap pixmap = XCreatePixmapFromBitmapData (dpy, - RootWindow (dpy, DefaultScreen(dpy)), - (char*) bits, width, height, - 1 , 0 , 1); - - Pixmap mask_pixmap = None; - if (maskBits != NULL) + m_refData = new wxCursorRefData(); + +#if wxUSE_NANOX + // TODO Create some standard cursors from bitmaps. + + +#else + // !wxUSE_NANOX + + M_CURSORDATA->m_display = wxGlobalDisplay(); + wxASSERT_MSG( M_CURSORDATA->m_display, wxT("No display") ); + + int x_cur = XC_left_ptr; + switch (cursorId) { - mask_pixmap = XCreatePixmapFromBitmapData (dpy, - RootWindow (dpy, DefaultScreen(dpy)), - (char*) maskBits, width, height, - 1 , 0 , 1); + case wxCURSOR_DEFAULT: x_cur = XC_left_ptr; break; + case wxCURSOR_HAND: x_cur = XC_hand1; break; + case wxCURSOR_CROSS: x_cur = XC_crosshair; break; + case wxCURSOR_SIZEWE: x_cur = XC_sb_h_double_arrow; break; + case wxCURSOR_SIZENS: x_cur = XC_sb_v_double_arrow; break; + case wxCURSOR_ARROWWAIT: + case wxCURSOR_WAIT: + case wxCURSOR_WATCH: x_cur = XC_watch; break; + case wxCURSOR_SIZING: x_cur = XC_sizing; break; + case wxCURSOR_SPRAYCAN: x_cur = XC_spraycan; break; + case wxCURSOR_IBEAM: x_cur = XC_xterm; break; + case wxCURSOR_PENCIL: x_cur = XC_pencil; break; + case wxCURSOR_NO_ENTRY: x_cur = XC_pirate; break; + case wxCURSOR_SIZENWSE: + case wxCURSOR_SIZENESW: x_cur = XC_fleur; break; + case wxCURSOR_QUESTION_ARROW: x_cur = XC_question_arrow; break; + case wxCURSOR_PAINT_BRUSH: x_cur = XC_spraycan; break; + case wxCURSOR_MAGNIFIER: x_cur = XC_plus; break; + case wxCURSOR_CHAR: x_cur = XC_xterm; break; + case wxCURSOR_LEFT_BUTTON: x_cur = XC_leftbutton; break; + case wxCURSOR_MIDDLE_BUTTON: x_cur = XC_middlebutton; break; + case wxCURSOR_RIGHT_BUTTON: x_cur = XC_rightbutton; break; + case wxCURSOR_BULLSEYE: x_cur = XC_target; break; + + case wxCURSOR_POINT_LEFT: x_cur = XC_sb_left_arrow; break; + case wxCURSOR_POINT_RIGHT: x_cur = XC_sb_right_arrow; break; +/* + case wxCURSOR_DOUBLE_ARROW: x_cur = XC_double_arrow; break; + case wxCURSOR_CROSS_REVERSE: x_cur = XC_cross_reverse; break; + case wxCURSOR_BASED_ARROW_UP: x_cur = XC_based_arrow_up; break; + case wxCURSOR_BASED_ARROW_DOWN: x_cur = XC_based_arrow_down; break; +*/ + default: + wxFAIL_MSG(wxT("unsupported cursor type")); + // will use the standard one } - XColor foreground_color; - XColor background_color; - foreground_color.pixel = BlackPixel(dpy, screen_num); - background_color.pixel = WhitePixel(dpy, screen_num); - Colormap cmap = (Colormap) wxTheApp->GetMainColormap((WXDisplay*) dpy); - XQueryColor(dpy, cmap, &foreground_color); - XQueryColor(dpy, cmap, &background_color); - - Cursor cursor = XCreatePixmapCursor (dpy, - pixmap, - mask_pixmap, - &foreground_color, - &background_color, - hotSpotX , - hotSpotY); - - XFreePixmap( dpy, pixmap ); - if (mask_pixmap != None) - { - XFreePixmap( dpy, mask_pixmap ); - } + M_CURSORDATA->m_cursor = (WXCursor) XCreateFontCursor( (Display*) M_CURSORDATA->m_display, x_cur ); +#endif +} - if (cursor) - { - wxXCursor *c = new wxXCursor; +wxCursor::wxCursor(const char bits[], int width, int height, + int hotSpotX, int hotSpotY, + const char maskBits[], wxColour *fg, wxColour *bg) +{ + wxFAIL_MSG( wxT("wxCursor creation from bits not yet implemented") ); +} - c->m_cursor = (WXCursor) cursor; - c->m_display = (WXDisplay*) dpy; - M_CURSORDATA->m_cursors.Append(c); - M_CURSORDATA->m_ok = TRUE; - } - else - { - M_CURSORDATA->m_ok = TRUE; - } + +wxCursor::wxCursor( const wxCursor &cursor ) +{ + Ref( cursor ); } -wxCursor::wxCursor(const wxString& name, long flags, int hotSpotX, int hotSpotY) +#if wxUSE_IMAGE +wxCursor::wxCursor( const wxImage & image ) { - // Must be an XBM file - if (flags != wxBITMAP_TYPE_XBM) - return; + wxFAIL_MSG( wxT("wxCursor creation from wxImage not yet implemented") ); +} +#endif - m_refData = new wxCursorRefData; +wxCursor::~wxCursor() +{ +} - int hotX = -1, hotY = -1; - unsigned int w, h; - Pixmap pixmap; +wxCursor& wxCursor::operator = ( const wxCursor& cursor ) +{ + if (*this == cursor) + return (*this); - Display *dpy = (Display*) wxGetDisplay(); - int screen_num = DefaultScreen (dpy); + Ref( cursor ); - int value = XReadBitmapFile (dpy, RootWindow (dpy, DefaultScreen (dpy)), - (char*) (const char*) name, &w, &h, &pixmap, &hotX, &hotY); + return *this; +} - M_BITMAPDATA->m_width = w; - M_BITMAPDATA->m_height = h; - M_BITMAPDATA->m_depth = 1; +bool wxCursor::operator == ( const wxCursor& cursor ) const +{ + return m_refData == cursor.m_refData; +} - if ((value == BitmapFileInvalid) || - (value == BitmapOpenFailed) || - (value == BitmapNoMemory)) - { - } - else - { - XColor foreground_color; - XColor background_color; - foreground_color.pixel = BlackPixel(dpy, screen_num); - background_color.pixel = WhitePixel(dpy, screen_num); - Colormap cmap = (Colormap) wxTheApp->GetMainColormap((WXDisplay*) dpy); - XQueryColor(dpy, cmap, &foreground_color); - XQueryColor(dpy, cmap, &background_color); - - // TODO: how do we determine whether hotX, hotY were read correctly? - if (hotX < 0 || hotY < 0) - { - hotX = hotSpotX; - hotY = hotSpotY; - } - if (hotX < 0 || hotY < 0) - { - hotX = 0; - hotY = 0; - } - - Pixmap mask_pixmap = None; - Cursor cursor = XCreatePixmapCursor (dpy, - pixmap, - mask_pixmap, - &foreground_color, - &background_color, - hotX, - hotY); - - XFreePixmap( dpy, pixmap ); - if (cursor) - { - wxXCursor *c = new wxXCursor; - - c->m_cursor = (WXCursor) cursor; - c->m_display = (WXDisplay*) dpy; - M_CURSORDATA->m_cursors.Append(c); - M_CURSORDATA->m_ok = TRUE; - } - } +bool wxCursor::operator != ( const wxCursor& cursor ) const +{ + return m_refData != cursor.m_refData; +} +bool wxCursor::Ok() const +{ + return (m_refData != NULL); } -// Cursors by stock number -wxCursor::wxCursor(wxStockCursor id) +WXCursor wxCursor::GetCursor() const { - m_refData = new wxCursorRefData; - M_CURSORDATA->m_cursorId = id; - M_CURSORDATA->m_ok = TRUE; + return M_CURSORDATA->m_cursor; +} - WXDisplay* display = wxGetDisplay(); - if (!display) - return; +//----------------------------------------------------------------------------- +// busy cursor routines +//----------------------------------------------------------------------------- - WXCursor cursor = GetXCursor(display); - if (cursor) - { - wxXCursor* c = new wxXCursor; - c->m_cursor = cursor; - c->m_display = wxGetDisplay(); - M_CURSORDATA->m_cursors.Append(c); - M_CURSORDATA->m_ok = TRUE; - } -} +/* extern */ wxCursor g_globalCursor; -wxCursor::~wxCursor() +static wxCursor gs_savedCursor; +static int gs_busyCount = 0; + +const wxCursor &wxBusyCursor::GetStoredCursor() { + return gs_savedCursor; } -// Motif-specific: create/get a cursor for the current display -WXCursor wxCursor::GetXCursor(WXDisplay* display) +const wxCursor wxBusyCursor::GetBusyCursor() { - if (!M_CURSORDATA) - return (WXCursor) 0; - wxNode* node = M_CURSORDATA->m_cursors.First(); - while (node) - { - wxXCursor* c = (wxXCursor*) node->Data(); - if (c->m_display == display) - return c->m_cursor; - node = node->Next(); - } + return wxCursor(wxCURSOR_WATCH); +} - // No cursor for this display, so let's see if we're an id-type cursor. +void wxEndBusyCursor() +{ + if (--gs_busyCount > 0) + return; - if (M_CURSORDATA->m_cursorId != wxCURSOR_NONE) - { - WXCursor cursor = MakeCursor(display, M_CURSORDATA->m_cursorId); - if (cursor) - { - wxXCursor* c = new wxXCursor; - c->m_cursor = cursor; - c->m_display = display; - M_CURSORDATA->m_cursors.Append(c); - return cursor; - } - else - return (WXCursor) 0; - } + wxSetCursor( gs_savedCursor ); + gs_savedCursor = wxNullCursor; - // Not an id-type cursor, so we don't know how to create it. - return (WXCursor) 0; + if (wxTheApp) + wxTheApp->ProcessIdle(); } -// Make a cursor from standard id -WXCursor wxCursor::MakeCursor(WXDisplay* display, wxStockCursor id) +void wxBeginBusyCursor( wxCursor *WXUNUSED(cursor) ) { - Display* dpy = (Display*) display; - Cursor cursor = (Cursor) 0; + if (gs_busyCount++ > 0) + return; - switch (id) - { - case wxCURSOR_WAIT: - { - cursor = XCreateFontCursor (dpy, XC_watch); - break; - } - case wxCURSOR_CROSS: - { - cursor = XCreateFontCursor (dpy, XC_crosshair); - break; - } - case wxCURSOR_CHAR: - { - // Nothing - break; - } - case wxCURSOR_HAND: - { - cursor = XCreateFontCursor (dpy, XC_hand1); - break; - } - case wxCURSOR_BULLSEYE: - { - cursor = XCreateFontCursor (dpy, XC_target); - break; - } - case wxCURSOR_PENCIL: - { - cursor = XCreateFontCursor (dpy, XC_pencil); - break; - } - case wxCURSOR_MAGNIFIER: - { - cursor = XCreateFontCursor (dpy, XC_sizing); - break; - } - case wxCURSOR_IBEAM: - { - cursor = XCreateFontCursor (dpy, XC_xterm); - break; - } - case wxCURSOR_NO_ENTRY: - { - cursor = XCreateFontCursor (dpy, XC_pirate); - break; - } - case wxCURSOR_LEFT_BUTTON: - { - cursor = XCreateFontCursor (dpy, XC_leftbutton); - break; - } - case wxCURSOR_RIGHT_BUTTON: - { - cursor = XCreateFontCursor (dpy, XC_rightbutton); - break; - } - case wxCURSOR_MIDDLE_BUTTON: - { - cursor = XCreateFontCursor (dpy, XC_middlebutton); - break; - } - case wxCURSOR_QUESTION_ARROW: - { - cursor = XCreateFontCursor (dpy, XC_question_arrow); - break; - } - case wxCURSOR_SIZING: - { - cursor = XCreateFontCursor (dpy, XC_sizing); - break; - } - case wxCURSOR_WATCH: - { - cursor = XCreateFontCursor (dpy, XC_watch); - break; - } - case wxCURSOR_SPRAYCAN: - { - cursor = XCreateFontCursor (dpy, XC_spraycan); - break; - } - case wxCURSOR_PAINT_BRUSH: - { - cursor = XCreateFontCursor (dpy, XC_spraycan); - break; - } - case wxCURSOR_SIZENWSE: - case wxCURSOR_SIZENESW: - { - // Not available in X - cursor = XCreateFontCursor (dpy, XC_crosshair); - break; - } - case wxCURSOR_SIZEWE: - { - cursor = XCreateFontCursor (dpy, XC_sb_h_double_arrow); - break; - } - case wxCURSOR_SIZENS: - { - cursor = XCreateFontCursor (dpy, XC_sb_v_double_arrow); - break; - } - case wxCURSOR_POINT_LEFT: - { - cursor = XCreateFontCursor (dpy, XC_sb_left_arrow); - break; - } - case wxCURSOR_POINT_RIGHT: - { - cursor = XCreateFontCursor (dpy, XC_sb_right_arrow); - break; - } - // (JD Huggins) added more stock cursors for X - // X-only cursors BEGIN - case wxCURSOR_CROSS_REVERSE: - { - cursor = XCreateFontCursor(dpy, XC_cross_reverse); - break; - } - case wxCURSOR_DOUBLE_ARROW: - { - cursor = XCreateFontCursor(dpy, XC_double_arrow); - break; - } - case wxCURSOR_BASED_ARROW_UP: - { - cursor = XCreateFontCursor(dpy, XC_based_arrow_up); - break; - } - case wxCURSOR_BASED_ARROW_DOWN: - { - cursor = XCreateFontCursor(dpy, XC_based_arrow_down); - break; - } - default: - case wxCURSOR_ARROW: - { - cursor = XCreateFontCursor (dpy, XC_top_left_arrow); - break; - } - case wxCURSOR_BLANK: - { - GC gc; - XGCValues gcv; - Pixmap empty_pixmap; - XColor blank_color; - - empty_pixmap = XCreatePixmap (dpy, RootWindow (dpy, DefaultScreen (dpy)), - 16, 16, 1); - gcv.function = GXxor; - gc = XCreateGC (dpy, - empty_pixmap, - GCFunction, - &gcv); - XCopyArea (dpy, - empty_pixmap, - empty_pixmap, - gc, - 0, 0, - 16, 16, - 0, 0); - XFreeGC (dpy, gc); - cursor = XCreatePixmapCursor (dpy, - empty_pixmap, - empty_pixmap, - &blank_color, - &blank_color, - 8, 8); - - break; - } - } - return (WXCursor) cursor; + wxASSERT_MSG( !gs_savedCursor.Ok(), + wxT("forgot to call wxEndBusyCursor, will leak memory") ); + + gs_savedCursor = g_globalCursor; + + wxSetCursor( wxCursor(wxCURSOR_WATCH) ); + + if (wxTheApp) + wxTheApp->ProcessIdle(); } -// Global cursor setting -void wxSetCursor(const wxCursor& WXUNUSED(cursor)) +bool wxIsBusy() { - // Nothing to do for Motif (no global cursor) + return gs_busyCount > 0; } - +void wxSetCursor( const wxCursor& cursor ) +{ + g_globalCursor = cursor; +}