From c9c2d1fba45e6fa3f3ae38f01be520f64fb57cec Mon Sep 17 00:00:00 2001 From: Tobias Taschner Date: Thu, 23 Jan 2020 21:06:40 +0100 Subject: [PATCH] Remove unused carbon files These files where no longer referenced by any build system and where probably left overs from before carbon was removed. --- include/wx/osx/carbon/private/overlay.h | 57 - src/osx/carbon/colordlg.cpp | 79 -- src/osx/carbon/icon.cpp | 604 ---------- src/osx/carbon/main.cpp | 11 - src/osx/carbon/overlay.cpp | 182 --- src/osx/carbon/thread.cpp | 1347 ----------------------- 6 files changed, 2280 deletions(-) delete mode 100644 include/wx/osx/carbon/private/overlay.h delete mode 100644 src/osx/carbon/colordlg.cpp delete mode 100644 src/osx/carbon/icon.cpp delete mode 100644 src/osx/carbon/main.cpp delete mode 100644 src/osx/carbon/overlay.cpp delete mode 100644 src/osx/carbon/thread.cpp diff --git a/include/wx/osx/carbon/private/overlay.h b/include/wx/osx/carbon/private/overlay.h deleted file mode 100644 index f5ebe1d83e..0000000000 --- a/include/wx/osx/carbon/private/overlay.h +++ /dev/null @@ -1,57 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: wx/osx/carbon/private/overlay.h -// Purpose: wxOverlayImpl declaration -// Author: Stefan Csomor -// Modified by: -// Created: 2006-10-20 -// Copyright: (c) wxWidgets team -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#ifndef _WX_MAC_CARBON_PRIVATE_OVERLAY_H_ -#define _WX_MAC_CARBON_PRIVATE_OVERLAY_H_ - -#include "wx/osx/private.h" -#include "wx/toplevel.h" -#include "wx/graphics.h" - -class wxOverlayImpl -{ -public: - wxOverlayImpl() ; - ~wxOverlayImpl() ; - - - // clears the overlay without restoring the former state - // to be done eg when the window content has been changed and repainted - void Reset(); - - // returns true if it has been setup - bool IsOk(); - - void Init( wxDC* dc, int x , int y , int width , int height ); - - void BeginDrawing( wxDC* dc); - - void EndDrawing( wxDC* dc); - - void Clear( wxDC* dc); - -private: - OSStatus CreateOverlayWindow(); - - void MacGetBounds( Rect *bounds ); - - WindowRef m_overlayWindow; - WindowRef m_overlayParentWindow; - CGContextRef m_overlayContext ; - // we store the window in case we would have to issue a Refresh() - wxWindow* m_window ; - - int m_x ; - int m_y ; - int m_width ; - int m_height ; -} ; - -#endif // _WX_MAC_CARBON_PRIVATE_OVERLAY_H_ diff --git a/src/osx/carbon/colordlg.cpp b/src/osx/carbon/colordlg.cpp deleted file mode 100644 index a5f5fd3a7a..0000000000 --- a/src/osx/carbon/colordlg.cpp +++ /dev/null @@ -1,79 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: src/osx/carbon/colordlg.cpp -// Purpose: wxColourDialog class. NOTE: you can use the generic class -// if you wish, instead of implementing this. -// Author: Stefan Csomor -// Modified by: -// Created: 1998-01-01 -// Copyright: (c) Stefan Csomor -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#include "wx/wxprec.h" - -#include "wx/colordlg.h" -#include "wx/fontdlg.h" -#include "wx/modalhook.h" - - -#if !USE_NATIVE_FONT_DIALOG_FOR_MACOSX && wxUSE_COLOURDLG - -wxIMPLEMENT_DYNAMIC_CLASS(wxColourDialog, wxDialog); - -#include "wx/osx/private.h" - -/* - * wxColourDialog - */ - -wxColourDialog::wxColourDialog() -{ - m_dialogParent = NULL; -} - -wxColourDialog::wxColourDialog(wxWindow *parent, const wxColourData *data) -{ - Create(parent, data); -} - -bool wxColourDialog::Create(wxWindow *parent, const wxColourData *data) -{ - m_dialogParent = parent; - - if (data) - m_colourData = *data; - return true; -} - -int wxColourDialog::ShowModal() -{ - WX_HOOK_MODAL_DIALOG(); - - RGBColor currentColor ; - - m_colourData.m_dataColour.GetRGBColor( ¤tColor ); - NColorPickerInfo info; - OSStatus err ; - memset(&info, 0, sizeof(info)) ; - // TODO : use parent to determine better position and then kAtSpecifiedOrigin - info.placeWhere = kCenterOnMainScreen ; - info.flags = kColorPickerDialogIsMoveable | kColorPickerDialogIsModal ; - info.theColor.color.rgb.red = currentColor.red ; - info.theColor.color.rgb.green = currentColor.green ; - info.theColor.color.rgb.blue = currentColor.blue ; - wxDialog::OSXBeginModalDialog(); - err = NPickColor(&info); - wxDialog::OSXEndModalDialog(); - if ((err == noErr) && info.newColorChosen) - { - currentColor.red = info.theColor.color.rgb.red ; - currentColor.green = info.theColor.color.rgb.green ; - currentColor.blue = info.theColor.color.rgb.blue ; - m_colourData.m_dataColour = currentColor; - - return wxID_OK; - } - return wxID_CANCEL; -} - -#endif diff --git a/src/osx/carbon/icon.cpp b/src/osx/carbon/icon.cpp deleted file mode 100644 index f1ad130e40..0000000000 --- a/src/osx/carbon/icon.cpp +++ /dev/null @@ -1,604 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: src/osx/carbon/icon.cpp -// Purpose: wxIcon class -// Author: Stefan Csomor -// Modified by: -// Created: 1998-01-01 -// Copyright: (c) Stefan Csomor -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#include "wx/wxprec.h" - -#if wxOSX_USE_COCOA_OR_CARBON - -#include "wx/icon.h" - -#ifndef WX_PRECOMP - #include "wx/image.h" -#endif - -#include "wx/osx/private.h" - -wxIMPLEMENT_DYNAMIC_CLASS(wxIcon, wxGDIObject); - -#define M_ICONDATA ((wxIconRefData *)m_refData) - -#define wxOSX_ICON_USE_NSIMAGE wxOSX_BITMAP_NATIVE_ACCESS - -#if wxOSX_ICON_USE_NSIMAGE - -// implementation based on NSImage - -class WXDLLEXPORT wxIconRefData : public wxGDIRefData -{ -public: - wxIconRefData() { Init(); } - wxIconRefData( WX_NSImage image, int desiredWidth, int desiredHeight ); - wxIconRefData( WXHICON iconref, int desiredWidth, int desiredHeight ); - - virtual ~wxIconRefData() { Free(); } - - virtual bool IsOk() const wxOVERRIDE { return m_nsImage != NULL; } - virtual void Free(); - - int GetWidth() const { return (int) wxOSXGetImageSize(m_nsImage).width; } - int GetHeight() const { return (int) wxOSXGetImageSize(m_nsImage).height; } - - WX_NSImage GetImage() const; - -private: - void Init(); - void Create( NSImage* icon, int desiredWidth, int desiredHeight ); - NSImage* m_nsImage; - - // We can (easily) copy m_iconRef so we don't implement the copy ctor. - wxDECLARE_NO_COPY_CLASS(wxIconRefData); -}; - - -wxIconRefData::wxIconRefData( NSImage* icon, int desiredWidth, int desiredHeight ) -{ - Init(); - - Create(icon, desiredWidth, desiredHeight); -} - -wxIconRefData::wxIconRefData( WXHICON iconref, int desiredWidth, int desiredHeight ) -{ - Init(); - - Create(wxOSXGetNSImageFromIconRef(iconref), desiredWidth, desiredHeight); - ReleaseIconRef(iconref); -} - -void wxIconRefData::Create( NSImage* icon, int WXUNUSED(desiredWidth), int WXUNUSED(desiredHeight) ) -{ - if ( icon ) - { - m_nsImage = icon; - wxMacCocoaRetain(icon); - } -} - -void wxIconRefData::Init() -{ - m_nsImage = NULL; -} - -void wxIconRefData::Free() -{ - if ( m_nsImage ) - { - wxMacCocoaRelease(m_nsImage); - } -} - -WX_NSImage wxIconRefData::GetImage() const -{ - wxASSERT( IsOk() ); - - return m_nsImage; -} - -#else // !wxOSX_ICON_USE_NSIMAGE - -// implementation based on IconRef - -class WXDLLEXPORT wxIconRefData : public wxGDIRefData -{ -public: - wxIconRefData() { Init(); } - wxIconRefData( WXHICON iconref, int desiredWidth, int desiredHeight ); - virtual ~wxIconRefData() { Free(); } - - virtual bool IsOk() const wxOVERRIDE { return m_iconRef != NULL; } - virtual void Free(); - - void SetWidth( int width ) { m_width = width; } - void SetHeight( int height ) { m_height = height; } - - int GetWidth() const { return m_width; } - int GetHeight() const { return m_height; } - - WXHICON GetHICON() const { return (WXHICON) m_iconRef; } - - WX_NSImage GetImage() const; - -private: - void Init(); - - IconRef m_iconRef; - - mutable NSImage* m_nsImage; - - int m_width; - int m_height; - - // We can (easily) copy m_iconRef so we don't implement the copy ctor. - wxDECLARE_NO_COPY_CLASS(wxIconRefData); -}; - -wxIconRefData::wxIconRefData( WXHICON icon, int desiredWidth, int desiredHeight ) -{ - Init(); - m_iconRef = (IconRef)( icon ) ; - - // Standard sizes - SetWidth( desiredWidth == -1 ? 32 : desiredWidth ) ; - SetHeight( desiredHeight == -1 ? 32 : desiredHeight ) ; -} - -void wxIconRefData::Init() -{ - m_iconRef = NULL ; - m_nsImage = NULL; - - m_width = - m_height = 0; -} - -void wxIconRefData::Free() -{ - if ( m_iconRef ) - { - ReleaseIconRef( m_iconRef ) ; - m_iconRef = NULL ; - } - - if ( m_nsImage ) - { - wxMacCocoaRelease(m_nsImage); - } -} - -WX_NSImage wxIconRefData::GetImage() const -{ - wxASSERT( IsOk() ); - - if ( m_nsImage == 0 ) - { - m_nsImage = wxOSXGetNSImageFromIconRef(m_iconRef); - CFRetain(m_nsImage); - } - - return m_nsImage; -} - -#endif - -// -// -// - -wxIcon::wxIcon() -{ -} - -wxIcon::wxIcon( const char bits[], int width, int height ) -{ - wxBitmap bmp( bits, width, height ) ; - CopyFromBitmap( bmp ) ; -} - -wxIcon::wxIcon(const char* const* bits) -{ - wxBitmap bmp( bits ) ; - CopyFromBitmap( bmp ) ; -} - -wxIcon::wxIcon( - const wxString& icon_file, wxBitmapType flags, - int desiredWidth, int desiredHeight ) -{ - LoadFile( icon_file, flags, desiredWidth, desiredHeight ); -} - -#if wxOSX_USE_ICONREF -wxIcon::wxIcon(WXHICON icon, const wxSize& size) - : wxGDIObject() -{ - // as the icon owns that ref, we have to acquire it as well - if (icon) - AcquireIconRef( (IconRef) icon ) ; - - m_refData = new wxIconRefData( icon, size.x, size.y ) ; -} - -WXHICON wxIcon::GetHICON() const -{ - wxASSERT( IsOk() ) ; - - return (WXHICON) ((wxIconRefData*)m_refData)->GetHICON() ; -} -#endif - -wxIcon::~wxIcon() -{ -} - -wxGDIRefData *wxIcon::CreateGDIRefData() const -{ - return new wxIconRefData; -} - -wxGDIRefData * -wxIcon::CloneGDIRefData(const wxGDIRefData * WXUNUSED(data)) const -{ - wxFAIL_MSG( wxS("Cloning icons is not implemented in wxCarbon.") ); - - return new wxIconRefData; -} - -int wxIcon::GetWidth() const -{ - wxCHECK_MSG( IsOk(), -1, wxT("invalid icon") ); - - return M_ICONDATA->GetWidth(); -} - -int wxIcon::GetHeight() const -{ - wxCHECK_MSG( IsOk(), -1, wxT("invalid icon") ); - - return M_ICONDATA->GetHeight(); -} - -int wxIcon::GetDepth() const -{ - return 32; -} - -WX_NSImage wxIcon::GetImage() const -{ - wxCHECK_MSG( IsOk(), NULL, wxT("invalid icon") ); - - return M_ICONDATA->GetImage() ; -} - -#if WXWIN_COMPATIBILITY_3_0 -void wxIcon::SetDepth( int WXUNUSED(depth) ) -{ -} - -void wxIcon::SetWidth( int WXUNUSED(width) ) -{ -} - -void wxIcon::SetHeight( int WXUNUSED(height) ) -{ -} -#endif - -// Load an icon based on resource name or filel name -// Return true on success, false otherwise -bool wxIcon::LoadFile( - const wxString& filename, wxBitmapType type, - int desiredWidth, int desiredHeight ) -{ - if( type == wxBITMAP_TYPE_ICON_RESOURCE ) - { - if( LoadIconFromSystemResource( filename, desiredWidth, desiredHeight ) ) - return true; - else - return LoadIconFromBundleResource( filename, desiredWidth, desiredHeight ); - } - else if( type == wxBITMAP_TYPE_ICON ) - { - return LoadIconFromFile( filename, desiredWidth, desiredHeight ); - } - else - { - return LoadIconAsBitmap( filename, type, desiredWidth, desiredHeight ); - } -} - -// Load a well known system icon by its wxWidgets identifier -// Returns true on success, false otherwise -bool wxIcon::LoadIconFromSystemResource(const wxString& resourceName, int desiredWidth, int desiredHeight) -{ - UnRef(); - - OSType theId = 0 ; - - if ( resourceName == wxT("wxICON_INFORMATION") ) - { - theId = kAlertNoteIcon ; - } - else if ( resourceName == wxT("wxICON_QUESTION") ) - { - theId = kAlertCautionIcon ; - } - else if ( resourceName == wxT("wxICON_WARNING") ) - { - theId = kAlertCautionIcon ; - } - else if ( resourceName == wxT("wxICON_ERROR") ) - { - theId = kAlertStopIcon ; - } - else if ( resourceName == wxT("wxICON_FOLDER") ) - { - theId = kGenericFolderIcon ; - } - else if ( resourceName == wxT("wxICON_FOLDER_OPEN") ) - { - theId = kOpenFolderIcon ; - } - else if ( resourceName == wxT("wxICON_NORMAL_FILE") ) - { - theId = kGenericDocumentIcon ; - } - else if ( resourceName == wxT("wxICON_EXECUTABLE_FILE") ) - { - theId = kGenericApplicationIcon ; - } - else if ( resourceName == wxT("wxICON_CDROM") ) - { - theId = kGenericCDROMIcon ; - } - else if ( resourceName == wxT("wxICON_FLOPPY") ) - { - theId = kGenericFloppyIcon ; - } - else if ( resourceName == wxT("wxICON_HARDDISK") ) - { - theId = kGenericHardDiskIcon ; - } - else if ( resourceName == wxT("wxICON_REMOVABLE") ) - { - theId = kGenericRemovableMediaIcon ; - } - else if ( resourceName == wxT("wxICON_DELETE") ) - { - theId = kToolbarDeleteIcon ; - } - else if ( resourceName == wxT("wxICON_GO_BACK") ) - { - theId = kBackwardArrowIcon ; - } - else if ( resourceName == wxT("wxICON_GO_FORWARD") ) - { - theId = kForwardArrowIcon ; - } - else if ( resourceName == wxT("wxICON_GO_HOME") ) - { - theId = kToolbarHomeIcon ; - } - else if ( resourceName == wxT("wxICON_HELP_SETTINGS") ) - { - theId = kGenericFontIcon ; - } - else if ( resourceName == wxT("wxICON_HELP_PAGE") ) - { - theId = kGenericDocumentIcon ; - } - else if ( resourceName == wxT( "wxICON_PRINT" ) ) - { - theId = kPrintMonitorFolderIcon; - } - else if ( resourceName == wxT( "wxICON_HELP_FOLDER" ) ) - { - theId = kHelpFolderIcon; - } - - if ( theId != 0 ) - { - IconRef iconRef = NULL ; - __Verify_noErr(GetIconRef( kOnSystemDisk, kSystemIconsCreator, theId, &iconRef )) ; - if ( iconRef ) - m_refData = new wxIconRefData( (WXHICON) iconRef, desiredWidth, desiredHeight ) ; - } - - return IsOk(); -} - -// Load an icon of type 'icns' by resource by name -// The resource must exist in one of the currently accessible bundles -// (usually this means the application bundle for the current application) -// Return true on success, false otherwise -bool wxIcon::LoadIconFromBundleResource(const wxString& resourceName, int desiredWidth, int desiredHeight) -{ - UnRef(); - -#if wxOSX_USE_ICONREF - IconRef iconRef = NULL ; - - // first look in the resource fork - if ( iconRef == NULL ) - { - Str255 theName ; - - wxMacStringToPascal( resourceName , theName ) ; - Handle resHandle = GetNamedResource( 'icns' , theName ) ; - if ( resHandle != 0L ) - { - IconFamilyHandle iconFamily = (IconFamilyHandle) resHandle ; - OSStatus err = GetIconRefFromIconFamilyPtr( *iconFamily, GetHandleSize((Handle) iconFamily), &iconRef ); - - if ( err != noErr ) - { - wxFAIL_MSG("Error when constructing icon ref"); - } - - ReleaseResource( resHandle ) ; - } - } - if ( iconRef == NULL ) - { - wxCFStringRef name(resourceName); - FSRef iconFSRef; - - wxCFRef iconURL(CFBundleCopyResourceURL(CFBundleGetMainBundle(), name, CFSTR("icns"), NULL)); - - if (CFURLGetFSRef(iconURL, &iconFSRef)) - { - // Get a handle on the icon family - IconFamilyHandle iconFamily; - OSStatus err = ReadIconFromFSRef( &iconFSRef, &iconFamily ); - - if ( err == noErr ) - { - err = GetIconRefFromIconFamilyPtr( *iconFamily, GetHandleSize((Handle) iconFamily), &iconRef ); - } - ReleaseResource( (Handle) iconFamily ); - } - } - - if ( iconRef ) - { - m_refData = new wxIconRefData( (WXHICON) iconRef, desiredWidth, desiredHeight ); - return true; - } -#endif - return false; -} - -// Load an icon from an icon file using the underlying OS X API -// The icon file must be in a format understood by the OS -// Return true for success, false otherwise -bool wxIcon::LoadIconFromFile(const wxString& filename, int desiredWidth, int desiredHeight) -{ - UnRef(); - - bool result = false; - -#if wxOSX_USE_ICONREF - OSStatus err; - // Get a file system reference - FSRef fsRef; - err = FSPathMakeRef( (const wxUint8*)filename.utf8_str().data(), &fsRef, NULL ); - - if( err != noErr ) - return false; - - // Get a handle on the icon family - IconFamilyHandle iconFamily; - err = ReadIconFromFSRef( &fsRef, &iconFamily ); - - if( err != noErr ) - return false; - - // Get the icon reference itself - IconRef iconRef; - err = GetIconRefFromIconFamilyPtr( *iconFamily, GetHandleSize((Handle) iconFamily), &iconRef ); - - if( err == noErr ) - { - // If everything is OK, assign m_refData - m_refData = new wxIconRefData( (WXHICON) iconRef, desiredWidth, desiredHeight ); - result = true; - } - - // Release the iconFamily before returning - ReleaseResource( (Handle) iconFamily ); -#endif - return result; -} - -// Load an icon from a file using functionality from wxWidgets -// A suitable bitmap handler (or image handler) must be available -// Return true on success, false otherwise -bool wxIcon::LoadIconAsBitmap(const wxString& filename, wxBitmapType type, int desiredWidth, int desiredHeight) -{ - UnRef(); - - wxBitmapHandler *handler = wxBitmap::FindHandler( type ); - - if ( handler ) - { - wxBitmap bmp ; - if ( handler->LoadFile( &bmp , filename, type, desiredWidth, desiredHeight )) - { - CopyFromBitmap( bmp ) ; - return true ; - } - } - -#if wxUSE_IMAGE - else - { - wxImage loadimage( filename, type ); - if (loadimage.IsOk()) - { - if ( desiredWidth == -1 ) - desiredWidth = loadimage.GetWidth() ; - if ( desiredHeight == -1 ) - desiredHeight = loadimage.GetHeight() ; - if ( desiredWidth != loadimage.GetWidth() || desiredHeight != loadimage.GetHeight() ) - loadimage.Rescale( desiredWidth , desiredHeight ) ; - - wxBitmap bmp( loadimage ); - CopyFromBitmap( bmp ) ; - - return true; - } - } -#endif - - return false; -} - - -void wxIcon::CopyFromBitmap( const wxBitmap& bmp ) -{ - UnRef() ; - -#if wxOSX_ICON_USE_NSIMAGE - m_refData = new wxIconRefData( bmp.GetImage() , bmp.GetWidth(), bmp.GetHeight() ) ; -#else - // as the bitmap owns that ref, we have to acquire it as well - - int w = bmp.GetWidth() ; - int h = bmp.GetHeight() ; - int sz = wxMax( w , h ) ; - - if ( sz == 24 || sz == 64 ) - { - wxBitmap scaleBmp( bmp.ConvertToImage().Scale( w * 2 , h * 2 ) ) ; - m_refData = new wxIconRefData( (WXHICON) scaleBmp.CreateIconRef(), bmp.GetWidth(), bmp.GetHeight() ) ; - } - else - { - m_refData = new wxIconRefData( (WXHICON) bmp.CreateIconRef() , bmp.GetWidth(), bmp.GetHeight() ) ; - } -#endif -} - -wxIMPLEMENT_DYNAMIC_CLASS(wxICONResourceHandler, wxBitmapHandler); - -bool wxICONResourceHandler::LoadFile( - wxBitmap *bitmap, const wxString& name, wxBitmapType WXUNUSED(flags), - int desiredWidth, int desiredHeight ) -{ - wxIcon icon ; - if ( icon.LoadFile( name , wxBITMAP_TYPE_ICON_RESOURCE , desiredWidth , desiredHeight ) ) - { - bitmap->CopyFromIcon( icon ) ; - return bitmap->IsOk() ; - } - return false; -} - -#endif - diff --git a/src/osx/carbon/main.cpp b/src/osx/carbon/main.cpp deleted file mode 100644 index 9615657900..0000000000 --- a/src/osx/carbon/main.cpp +++ /dev/null @@ -1,11 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: src/osx/carbon/main.cpp -// Purpose: Entry point -// Author: Stefan Csomor -// Modified by: -// Created: 1998-01-01 -// Copyright: (c) Stefan Csomor -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -// We don't put main() in the library any more. GD. diff --git a/src/osx/carbon/overlay.cpp b/src/osx/carbon/overlay.cpp deleted file mode 100644 index 9273fa81dc..0000000000 --- a/src/osx/carbon/overlay.cpp +++ /dev/null @@ -1,182 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: src/osx/carbon/overlay.cpp -// Purpose: common wxOverlay code -// Author: Stefan Csomor -// Modified by: -// Created: 2006-10-20 -// Copyright: (c) wxWidgets team -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -// ============================================================================ -// declarations -// ============================================================================ - -// ---------------------------------------------------------------------------- -// headers -// ---------------------------------------------------------------------------- - -// For compilers that support precompilation, includes "wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -#include "wx/overlay.h" - -#ifndef WX_PRECOMP - #include "wx/dcclient.h" -#endif - -#include "wx/private/overlay.h" - -#ifdef wxHAS_NATIVE_OVERLAY - -// ============================================================================ -// implementation -// ============================================================================ - -wxOverlayImpl::wxOverlayImpl() -{ - m_window = NULL ; - m_overlayContext = NULL ; - m_overlayWindow = NULL ; -} - -wxOverlayImpl::~wxOverlayImpl() -{ - Reset(); -} - -bool wxOverlayImpl::IsOk() -{ - return m_overlayWindow != NULL ; -} - -void wxOverlayImpl::MacGetBounds( Rect *bounds ) -{ - int x, y; - x=y=0; - m_window->MacWindowToRootWindow( &x , &y ) ; - wxNonOwnedWindow* tlw = m_window->MacGetTopLevelWindow(); - tlw->GetNonOwnedPeer()->WindowToScreen( &x, &y ); - - bounds->top = y+m_y; - bounds->left = x+m_x; - bounds->bottom = y+m_y+m_height; - bounds->right = x+m_x+m_width; -} - -OSStatus wxOverlayImpl::CreateOverlayWindow() -{ - OSStatus err; - - WindowAttributes overlayAttributes = kWindowIgnoreClicksAttribute; - - if ( m_window ) - { - m_overlayParentWindow =(WindowRef) m_window->MacGetTopLevelWindowRef(); - - Rect bounds ; - MacGetBounds(&bounds); - err = CreateNewWindow( kOverlayWindowClass, overlayAttributes, &bounds, &m_overlayWindow ); - if ( err == noErr ) - { - SetWindowGroup( m_overlayWindow, GetWindowGroup(m_overlayParentWindow)); // Put them in the same group so that their window layers are consistent - } - } - else - { - m_overlayParentWindow = NULL ; - CGRect cgbounds ; - cgbounds = CGDisplayBounds(CGMainDisplayID()); - Rect bounds; - bounds.top = (short)cgbounds.origin.y; - bounds.left = (short)cgbounds.origin.x; - bounds.bottom = (short)(bounds.top + cgbounds.size.height); - bounds.right = (short)(bounds.left + cgbounds.size.width); - err = CreateNewWindow( kOverlayWindowClass, overlayAttributes, &bounds, &m_overlayWindow ); - } - ShowWindow(m_overlayWindow); - return err; -} - -void wxOverlayImpl::Init( wxDC* dc, int x , int y , int width , int height ) -{ - wxASSERT_MSG( !IsOk() , _("You cannot Init an overlay twice") ); - - m_window = dc->GetWindow(); - m_x = x ; - m_y = y ; - if ( dc->IsKindOf( CLASSINFO( wxClientDC ) )) - { - wxPoint origin = m_window->GetClientAreaOrigin(); - m_x += origin.x; - m_y += origin.y; - } - m_width = width ; - m_height = height ; - - OSStatus err = CreateOverlayWindow(); - wxASSERT_MSG( err == noErr , _("Couldn't create the overlay window") ); -#ifndef __LP64__ - err = QDBeginCGContext(GetWindowPort(m_overlayWindow), &m_overlayContext); -#endif - CGContextTranslateCTM( m_overlayContext, 0, m_height ); - CGContextScaleCTM( m_overlayContext, 1, -1 ); - CGContextTranslateCTM( m_overlayContext, -m_x , -m_y ); - wxASSERT_MSG( err == noErr , _("Couldn't init the context on the overlay window") ); -} - -void wxOverlayImpl::BeginDrawing( wxDC* dc) -{ - wxDCImpl *impl = dc->GetImpl(); - wxGCDCImpl *win_impl = wxDynamicCast(impl,wxGCDCImpl); - if (win_impl) - { - win_impl->SetGraphicsContext( wxGraphicsContext::CreateFromNative( m_overlayContext ) ); - dc->SetClippingRegion( m_x , m_y , m_width , m_height ) ; - } -} - -void wxOverlayImpl::EndDrawing( wxDC* dc) -{ - wxDCImpl *impl = dc->GetImpl(); - wxGCDCImpl *win_impl = wxDynamicCast(impl,wxGCDCImpl); - if (win_impl) - win_impl->SetGraphicsContext(NULL); - - CGContextFlush( m_overlayContext ); -} - -void wxOverlayImpl::Clear(wxDC* WXUNUSED(dc)) -{ - wxASSERT_MSG( IsOk() , _("You cannot Clear an overlay that is not inited") ); - CGRect box = CGRectMake( m_x - 1, m_y - 1 , m_width + 2 , m_height + 2 ); - CGContextClearRect( m_overlayContext, box ); -} - -void wxOverlayImpl::Reset() -{ - if ( m_overlayContext ) - { -#ifndef __LP64__ - OSStatus err = QDEndCGContext(GetWindowPort(m_overlayWindow), &m_overlayContext); - if ( err != noErr ) - { - wxFAIL_MSG("Couldn't end the context on the overlay window"); - } -#endif - m_overlayContext = NULL ; - } - - // todo : don't dispose, only hide and reposition on next run - if (m_overlayWindow) - { - DisposeWindow(m_overlayWindow); - m_overlayWindow = NULL ; - } -} - -#endif // wxHAS_NATIVE_OVERLAY diff --git a/src/osx/carbon/thread.cpp b/src/osx/carbon/thread.cpp deleted file mode 100644 index d2ea457e14..0000000000 --- a/src/osx/carbon/thread.cpp +++ /dev/null @@ -1,1347 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: src/osx/carbon/thread.cpp -// Purpose: wxThread Implementation -// Author: Original from Wolfram Gloger/Guilhem Lavaux/Vadim Zeitlin -// Modified by: Aj Lavin, Stefan Csomor -// Created: 04/22/98 -// Copyright: (c) Wolfram Gloger (1996, 1997); Guilhem Lavaux (1998), -// Vadim Zeitlin (1999), Stefan Csomor (2000) -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#include "wx/wxprec.h" - -#if defined(__BORLANDC__) - #pragma hdrstop -#endif - -#ifndef WX_PRECOMP - #include "wx/wx.h" - #include "wx/module.h" -#endif - -#if wxUSE_THREADS - -#include "wx/thread.h" - -#if wxOSX_USE_COCOA_OR_CARBON -#include -#else -#include -#endif - -#include "wx/osx/uma.h" - -// the possible states of the thread: -// ("=>" shows all possible transitions from this state) -enum wxThreadState -{ - STATE_NEW, // didn't start execution yet (=> RUNNING) - STATE_RUNNING, // thread is running (=> PAUSED, CANCELED) - STATE_PAUSED, // thread is temporarily suspended (=> RUNNING) - STATE_CANCELED, // thread should terminate a.s.a.p. (=> EXITED) - STATE_EXITED // thread is terminating -}; - -// ---------------------------------------------------------------------------- -// globals -// ---------------------------------------------------------------------------- - -// the task ID of the main thread -wxThreadIdType wxThread::ms_idMainThread = kInvalidID; - -// this is the Per-Task Storage for the pointer to the appropriate wxThread -TaskStorageIndex gs_tlsForWXThread = 0; - -// if it's false, some secondary thread is holding the GUI lock -static bool gs_bGuiOwnedByMainThread = true; - -// critical section which controls access to all GUI functions: any secondary -// thread (i.e. except the main one) must enter this crit section before doing -// any GUI calls -static wxCriticalSection *gs_critsectGui = NULL; - -// critical section which protects gs_nWaitingForGui variable -static wxCriticalSection *gs_critsectWaitingForGui = NULL; - -// number of threads waiting for GUI in wxMutexGuiEnter() -static size_t gs_nWaitingForGui = 0; - -// overall number of threads, needed for determining -// the sleep value of the main event loop -size_t g_numberOfThreads = 0; - - -#if wxUSE_GUI -MPCriticalRegionID gs_guiCritical = kInvalidID; -#endif - -// ============================================================================ -// MacOS implementation of thread classes -// ============================================================================ - -/* - Notes : - - The implementation is very close to the phtreads implementation, the reason for - using MPServices is the fact that these are also available under OS 9. Thus allowing - for one common API for all current builds. - - As soon as wxThreads are on a 64 bit address space, the TLS must be extended - to use two indices one for each 32 bit part as the MP implementation is limited - to longs. - - I have three implementations for mutexes : - version A based on a binary semaphore, problem - not reentrant, version B based - on a critical region, allows for reentrancy, performance implications not - yet tested, and third a plain pthreads implementation - - The same for condition internal, one implementation by Aj Lavin and the other one - copied from the thrimpl.cpp which I assume has been more broadly tested, I've just - replaced the interlock increment with the appropriate PPC calls -*/ - -// ---------------------------------------------------------------------------- -// wxCriticalSection -// ---------------------------------------------------------------------------- - -wxCriticalSection::wxCriticalSection( wxCriticalSectionType WXUNUSED(critSecType) ) -{ - MPCreateCriticalRegion( (MPCriticalRegionID*) &m_critRegion ); -} - -wxCriticalSection::~wxCriticalSection() -{ - MPDeleteCriticalRegion( (MPCriticalRegionID) m_critRegion ); -} - -void wxCriticalSection::Enter() -{ - MPEnterCriticalRegion( (MPCriticalRegionID) m_critRegion, kDurationForever ); -} - -bool wxCriticalSection::TryEnter() -{ - return MPEnterCriticalRegion( (MPCriticalRegionID) m_critRegion, kDurationImmediate ) == noErr; -} - -void wxCriticalSection::Leave() -{ - MPExitCriticalRegion( (MPCriticalRegionID) m_critRegion ); -} - -// ---------------------------------------------------------------------------- -// wxMutex implementation -// ---------------------------------------------------------------------------- - -#define wxUSE_MAC_SEMAPHORE_MUTEX 0 -#define wxUSE_MAC_CRITICAL_REGION_MUTEX 1 -#define wxUSE_MAC_PTHREADS_MUTEX 0 - -#if wxUSE_MAC_CRITICAL_REGION_MUTEX - -class wxMutexInternal -{ -public: - wxMutexInternal( wxMutexType mutexType ); - virtual ~wxMutexInternal(); - - bool IsOk() const { return m_isOk; } - - wxMutexError Lock() { return Lock(kDurationForever); } - wxMutexError Lock(unsigned long ms); - wxMutexError TryLock(); - wxMutexError Unlock(); - -private: - MPCriticalRegionID m_critRegion; - bool m_isOk ; -}; - -wxMutexInternal::wxMutexInternal( wxMutexType WXUNUSED(mutexType) ) -{ - m_isOk = false; - m_critRegion = kInvalidID; - - __Verify_noErr(MPCreateCriticalRegion( &m_critRegion )); - m_isOk = ( m_critRegion != kInvalidID ); - if ( !IsOk() ) - { - wxFAIL_MSG( wxT("Error when creating mutex") ); - } -} - -wxMutexInternal::~wxMutexInternal() -{ - if ( m_critRegion != kInvalidID ) - MPDeleteCriticalRegion( m_critRegion ); - - MPYield(); -} - -wxMutexError wxMutexInternal::Lock(unsigned long ms) -{ - wxCHECK_MSG( m_isOk , wxMUTEX_MISC_ERROR , wxT("Invalid Mutex") ); - - OSStatus err = MPEnterCriticalRegion( m_critRegion, ms ); - switch ( err ) - { - case noErr: - break; - - case kMPTimeoutErr: - wxASSERT_MSG( ms != kDurationForever, wxT("unexpected timeout") ); - return wxMUTEX_TIMEOUT; - - default: - wxLogSysError(wxT("Could not lock mutex")); - return wxMUTEX_MISC_ERROR; - } - - return wxMUTEX_NO_ERROR; -} - -wxMutexError wxMutexInternal::TryLock() -{ - wxCHECK_MSG( m_isOk , wxMUTEX_MISC_ERROR , wxT("Invalid Mutex") ) ; - - OSStatus err = MPEnterCriticalRegion( m_critRegion, kDurationImmediate); - if (err != noErr) - { - if ( err == kMPTimeoutErr) - return wxMUTEX_BUSY; - - wxLogSysError( wxT("Could not try lock mutex") ); - return wxMUTEX_MISC_ERROR; - } - - return wxMUTEX_NO_ERROR; -} - -wxMutexError wxMutexInternal::Unlock() -{ - wxCHECK_MSG( m_isOk , wxMUTEX_MISC_ERROR , wxT("Invalid Mutex") ) ; - - OSStatus err = MPExitCriticalRegion( m_critRegion ); - MPYield() ; - - if (err != noErr) - { - wxLogSysError( wxT("Could not unlock mutex") ); - - return wxMUTEX_MISC_ERROR; - } - - return wxMUTEX_NO_ERROR; -} - -#endif - -// -------------------------------------------------------------------------- -// wxSemaphore -// -------------------------------------------------------------------------- - -class wxSemaphoreInternal -{ -public: - wxSemaphoreInternal( int initialcount, int maxcount ); - virtual ~wxSemaphoreInternal(); - - bool IsOk() const - { return m_isOk; } - - wxSemaError Post(); - wxSemaError WaitTimeout( unsigned long milliseconds ); - - wxSemaError Wait() - { return WaitTimeout( kDurationForever); } - - wxSemaError TryWait() - { - wxSemaError err = WaitTimeout( kDurationImmediate ); - if (err == wxSEMA_TIMEOUT) - err = wxSEMA_BUSY; - - return err; - } - -private: - MPSemaphoreID m_semaphore; - bool m_isOk; -}; - -wxSemaphoreInternal::wxSemaphoreInternal( int initialcount, int maxcount) -{ - m_isOk = false; - m_semaphore = kInvalidID; - if ( maxcount == 0 ) - // make it practically infinite - maxcount = INT_MAX; - - __Verify_noErr(MPCreateSemaphore( maxcount, initialcount, &m_semaphore )); - m_isOk = ( m_semaphore != kInvalidID ); - - if ( !IsOk() ) - { - wxFAIL_MSG( wxT("Error when creating semaphore") ); - } -} - -wxSemaphoreInternal::~wxSemaphoreInternal() -{ - if (m_semaphore != kInvalidID) - MPDeleteSemaphore( m_semaphore ); - - MPYield(); -} - -wxSemaError wxSemaphoreInternal::WaitTimeout( unsigned long milliseconds ) -{ - OSStatus err = MPWaitOnSemaphore( m_semaphore, milliseconds ); - if (err != noErr) - { - if (err == kMPTimeoutErr) - return wxSEMA_TIMEOUT; - - return wxSEMA_MISC_ERROR; - } - - return wxSEMA_NO_ERROR; -} - -wxSemaError wxSemaphoreInternal::Post() -{ - OSStatus err = MPSignalSemaphore( m_semaphore ); - MPYield(); - if (err != noErr) - return wxSEMA_MISC_ERROR; - - return wxSEMA_NO_ERROR; -} - -// ---------------------------------------------------------------------------- -// wxCondition implementation -// ---------------------------------------------------------------------------- - -class wxConditionInternal -{ -public: - wxConditionInternal( wxMutex& mutex ); - - bool IsOk() const - { return m_mutex.IsOk() && m_semaphore.IsOk(); } - - wxCondError Wait(); - wxCondError WaitTimeout( unsigned long milliseconds ); - - wxCondError Signal(); - wxCondError Broadcast(); - -private: - // the number of threads currently waiting for this condition - SInt32 m_numWaiters; - - // the critical section protecting m_numWaiters - wxCriticalSection m_csWaiters; - - wxMutex& m_mutex; - wxSemaphore m_semaphore; - - wxDECLARE_NO_COPY_CLASS(wxConditionInternal); -}; - -wxConditionInternal::wxConditionInternal( wxMutex& mutex ) - : m_mutex(mutex) -{ - // another thread can't access it until we return from ctor, so no need to - // protect access to m_numWaiters here - m_numWaiters = 0; -} - -wxCondError wxConditionInternal::Wait() -{ - // increment the number of waiters - IncrementAtomic( &m_numWaiters ); - - m_mutex.Unlock(); - - // a potential race condition can occur here - // - // after a thread increments nwaiters, and unlocks the mutex and before the - // semaphore.Wait() is called, if another thread can cause a signal to be - // generated - // - // this race condition is handled by using a semaphore and incrementing the - // semaphore only if 'nwaiters' is greater that zero since the semaphore, - // can 'remember' signals the race condition will not occur - - // wait ( if necessary ) and decrement semaphore - wxSemaError err = m_semaphore.Wait(); - m_mutex.Lock(); - - return err == wxSEMA_NO_ERROR ? wxCOND_NO_ERROR : wxCOND_MISC_ERROR; -} - -wxCondError wxConditionInternal::WaitTimeout( unsigned long milliseconds ) -{ - IncrementAtomic( &m_numWaiters ); - - m_mutex.Unlock(); - - // a race condition can occur at this point in the code - // - // please see the comments in Wait(), for details - - wxSemaError err = m_semaphore.WaitTimeout(milliseconds); - - if ( err == wxSEMA_TIMEOUT ) - { - // another potential race condition exists here it is caused when a - // 'waiting' thread timesout, and returns from WaitForSingleObject, but - // has not yet decremented 'nwaiters'. - // - // at this point if another thread calls signal() then the semaphore - // will be incremented, but the waiting thread will miss it. - // - // to handle this particular case, the waiting thread calls - // WaitForSingleObject again with a timeout of 0, after locking - // 'nwaiters_mutex'. this call does not block because of the zero - // timeout, but will allow the waiting thread to catch the missed - // signals. - wxCriticalSectionLocker lock(m_csWaiters); - - err = m_semaphore.WaitTimeout(0); - - if ( err != wxSEMA_NO_ERROR ) - { - m_numWaiters--; - } - } - - m_mutex.Lock(); - - return err == wxSEMA_NO_ERROR ? wxCOND_NO_ERROR : wxCOND_MISC_ERROR; -} - -wxCondError wxConditionInternal::Signal() -{ - wxCriticalSectionLocker lock(m_csWaiters); - - if ( m_numWaiters > 0 ) - { - // increment the semaphore by 1 - if ( m_semaphore.Post() != wxSEMA_NO_ERROR ) - return wxCOND_MISC_ERROR; - - m_numWaiters--; - } - - return wxCOND_NO_ERROR; -} - -wxCondError wxConditionInternal::Broadcast() -{ - wxCriticalSectionLocker lock(m_csWaiters); - - while ( m_numWaiters > 0 ) - { - if ( m_semaphore.Post() != wxSEMA_NO_ERROR ) - return wxCOND_MISC_ERROR; - - m_numWaiters--; - } - - return wxCOND_NO_ERROR; -} - -// ---------------------------------------------------------------------------- -// wxCriticalSection implementation -// ---------------------------------------------------------------------------- - -// XXX currently implemented as mutex in headers. Change to critical section. - -// ---------------------------------------------------------------------------- -// wxThread implementation -// ---------------------------------------------------------------------------- - -// wxThreadInternal class -// ---------------------- - -class wxThreadInternal -{ -public: - wxThreadInternal() - { - m_tid = kInvalidID; - m_state = STATE_NEW; - m_prio = wxPRIORITY_DEFAULT; - m_notifyQueueId = kInvalidID; - m_exitcode = 0; - m_cancelled = false ; - - // set to true only when the thread starts waiting on m_semSuspend - m_isPaused = false; - - // defaults for joinable threads - m_shouldBeJoined = true; - m_isDetached = false; - } - - virtual ~wxThreadInternal() - { - if ( m_notifyQueueId) - { - MPDeleteQueue( m_notifyQueueId ); - m_notifyQueueId = kInvalidID ; - } - } - - // thread function - static OSStatus MacThreadStart(void* arg); - - // create a new (suspended) thread (for the given thread object) - bool Create(wxThread *thread, unsigned int stackSize); - - // thread actions - - // start the thread - wxThreadError Run(); - - // unblock the thread allowing it to run - void SignalRun() { m_semRun.Post(); } - - // ask the thread to terminate - void Wait(); - - // go to sleep until Resume() is called - void Pause(); - - // resume the thread - void Resume(); - - // accessors - // priority - int GetPriority() const - { return m_prio; } - void SetPriority(int prio); - - // state - wxThreadState GetState() const - { return m_state; } - void SetState(wxThreadState state) - { m_state = state; } - - // Get the ID of this thread's underlying MP Services task. - MPTaskID GetId() const - { return m_tid; } - - void SetCancelFlag() - { m_cancelled = true; } - - bool WasCancelled() const - { return m_cancelled; } - - // exit code - void SetExitCode(wxThread::ExitCode exitcode) - { m_exitcode = exitcode; } - wxThread::ExitCode GetExitCode() const - { return m_exitcode; } - - // the pause flag - void SetReallyPaused(bool paused) - { m_isPaused = paused; } - bool IsReallyPaused() const - { return m_isPaused; } - - // tell the thread that it is a detached one - void Detach() - { - wxCriticalSectionLocker lock(m_csJoinFlag); - - m_shouldBeJoined = false; - m_isDetached = true; - } - -private: - // the thread we're associated with - wxThread * m_thread; - - MPTaskID m_tid; // thread id - MPQueueID m_notifyQueueId; // its notification queue - - wxThreadState m_state; // see wxThreadState enum - int m_prio; // in wxWidgets units: from 0 to 100 - - // this flag is set when the thread should terminate - bool m_cancelled; - - // this flag is set when the thread is blocking on m_semSuspend - bool m_isPaused; - - // the thread exit code - only used for joinable (!detached) threads and - // is only valid after the thread termination - wxThread::ExitCode m_exitcode; - - // many threads may call Wait(), but only one of them should call - // pthread_join(), so we have to keep track of this - wxCriticalSection m_csJoinFlag; - bool m_shouldBeJoined; - bool m_isDetached; - - // this semaphore is posted by Run() and the threads Entry() is not - // called before it is done - wxSemaphore m_semRun; - - // this one is signaled when the thread should resume after having been - // Pause()d - wxSemaphore m_semSuspend; -}; - -OSStatus wxThreadInternal::MacThreadStart(void *parameter) -{ - wxThread* thread = (wxThread*) parameter ; - wxThreadInternal *pthread = thread->m_internal; - - // add to TLS so that This() will work - __Verify_noErr(MPSetTaskStorageValue( gs_tlsForWXThread , (TaskStorageValue) thread )) ; - - // have to declare this before pthread_cleanup_push() which defines a - // block! - bool dontRunAtAll; - - // wait for the semaphore to be posted from Run() - pthread->m_semRun.Wait(); - - // test whether we should run the run at all - may be it was deleted - // before it started to Run()? - { - wxCriticalSectionLocker lock(thread->m_critsect); - - dontRunAtAll = pthread->GetState() == STATE_NEW && - pthread->WasCancelled(); - } - - if ( !dontRunAtAll ) - { - pthread->m_exitcode = thread->CallEntry(); - - { - wxCriticalSectionLocker lock(thread->m_critsect); - pthread->SetState( STATE_EXITED ); - } - } - - if ( dontRunAtAll ) - { - if ( pthread->m_isDetached ) - delete thread; - - return -1; - } - else - { - // on Mac for the running code, - // the correct thread termination is to return - - // terminate the thread - thread->Exit( pthread->m_exitcode ); - - return (OSStatus) NULL; // pthread->m_exitcode; - } -} - -bool wxThreadInternal::Create( wxThread *thread, unsigned int stackSize ) -{ - wxASSERT_MSG( m_state == STATE_NEW && !m_tid, - wxT("Create()ing thread twice?") ); - - if ( thread->IsDetached() ) - Detach(); - - OSStatus err = noErr; - m_thread = thread; - - if ( m_notifyQueueId == kInvalidID ) - { - OSStatus err = MPCreateQueue( &m_notifyQueueId ); - if (err != noErr) - { - wxLogSysError( wxT("Can't create the thread event queue") ); - - return false; - } - } - - m_state = STATE_NEW; - - err = MPCreateTask( - MacThreadStart, (void*)m_thread, stackSize, - m_notifyQueueId, &m_exitcode, 0, 0, &m_tid ); - - if (err != noErr) - { - wxLogSysError( wxT("Can't create thread") ); - - return false; - } - - if ( m_prio != wxPRIORITY_DEFAULT ) - SetPriority( m_prio ); - - return true; -} - -void wxThreadInternal::SetPriority( int priority ) -{ - m_prio = priority; - - if (m_tid) - { - // Mac priorities range from 1 to 10,000, with a default of 100. - // wxWidgets priorities range from 0 to 100 with a default of 50. - // We can map wxWidgets to Mac priorities easily by assuming - // the former uses a logarithmic scale. - const unsigned int macPriority = (int)( exp( priority / 25.0 * log( 10.0)) + 0.5); - - MPSetTaskWeight( m_tid, macPriority ); - } -} - -wxThreadError wxThreadInternal::Run() -{ - wxCHECK_MSG( GetState() == STATE_NEW, wxTHREAD_RUNNING, - wxT("thread may only be started once after Create()") ); - - SetState( STATE_RUNNING ); - - // wake up threads waiting for our start - SignalRun(); - - return wxTHREAD_NO_ERROR; -} - -void wxThreadInternal::Wait() -{ - wxCHECK_RET( !m_isDetached, wxT("can't wait for a detached thread") ); - - // if the thread we're waiting for is waiting for the GUI mutex, we will - // deadlock so make sure we release it temporarily - if ( wxThread::IsMain() ) - { - // give the thread we're waiting for chance to do the GUI call - // it might be in, we don't do this conditionally as the to be waited on - // thread might have to acquire the mutex later but before terminating - if ( wxGuiOwnedByMainThread() ) - wxMutexGuiLeave(); - } - - { - wxCriticalSectionLocker lock(m_csJoinFlag); - - if ( m_shouldBeJoined ) - { - void *param1, *param2, *rc; - - OSStatus err = MPWaitOnQueue( - m_notifyQueueId, - ¶m1, - ¶m2, - &rc, - kDurationForever ); - if (err != noErr) - { - wxLogSysError( wxT( "Cannot wait for thread termination.")); - rc = (void*) -1; - } - - // actually param1 would be the address of m_exitcode - // but we don't need this here - m_exitcode = rc; - - m_shouldBeJoined = false; - } - } -} - -void wxThreadInternal::Pause() -{ - // the state is set from the thread which pauses us first, this function - // is called later so the state should have been already set - wxCHECK_RET( m_state == STATE_PAUSED, - wxT("thread must first be paused with wxThread::Pause().") ); - - // wait until the semaphore is Post()ed from Resume() - m_semSuspend.Wait(); -} - -void wxThreadInternal::Resume() -{ - wxCHECK_RET( m_state == STATE_PAUSED, - wxT("can't resume thread which is not suspended.") ); - - // the thread might be not actually paused yet - if there were no call to - // TestDestroy() since the last call to Pause() for example - if ( IsReallyPaused() ) - { - // wake up Pause() - m_semSuspend.Post(); - - // reset the flag - SetReallyPaused( false ); - } - - SetState( STATE_RUNNING ); -} - -// static functions -// ---------------- - -wxThread *wxThread::This() -{ - wxThread* thr = (wxThread*) MPGetTaskStorageValue( gs_tlsForWXThread ) ; - - return thr; -} - -#ifdef Yield -#undef Yield -#endif - -void wxThread::Yield() -{ - CFRunLoopRunInMode( kCFRunLoopDefaultMode , 0 , true ) ; - - MPYield(); -} - -void wxThread::Sleep( unsigned long milliseconds ) -{ - AbsoluteTime wakeup = AddDurationToAbsolute( milliseconds, UpTime() ); - MPDelayUntil( &wakeup ); -} - -int wxThread::GetCPUCount() -{ - return MPProcessors(); -} - -unsigned long wxThread::GetCurrentId() -{ - return (unsigned long)MPCurrentTaskID(); -} - -bool wxThread::SetConcurrency( size_t WXUNUSED(level) ) -{ - // Cannot be set in MacOS. - return false; -} - -wxThread::wxThread( wxThreadKind kind ) -{ - g_numberOfThreads++; - m_internal = new wxThreadInternal(); - - m_isDetached = (kind == wxTHREAD_DETACHED); -} - -wxThread::~wxThread() -{ - wxASSERT_MSG( g_numberOfThreads>0 , wxT("More threads deleted than created.") ) ; - - g_numberOfThreads--; - - m_critsect.Enter(); - - // check that the thread either exited or couldn't be created - if ( m_internal->GetState() != STATE_EXITED && - m_internal->GetState() != STATE_NEW ) - { - wxLogDebug( - wxT("The thread %ld is being destroyed although it is still running! The application may crash."), - GetId() ); - } - - m_critsect.Leave(); - - wxDELETE( m_internal ) ; -} - -wxThreadError wxThread::Create( unsigned int stackSize ) -{ - wxCriticalSectionLocker lock(m_critsect); - - if ( !m_internal->Create(this, stackSize) ) - { - m_internal->SetState( STATE_EXITED ); - return wxTHREAD_NO_RESOURCE; - } - - return wxTHREAD_NO_ERROR; -} - -wxThreadError wxThread::Run() -{ - wxCriticalSectionLocker lock(m_critsect); - - // Create the thread if it wasn't created yet with an explicit - // Create() call: - if ( m_internal->GetId() == kInvalidID ) - { - if ( !m_internal->Create(this, stackSize) ) - { - m_internal->SetState( STATE_EXITED ); - return wxTHREAD_NO_RESOURCE; - } - } - - wxCHECK_MSG( m_internal->GetId(), wxTHREAD_MISC_ERROR, - wxT("must call wxThread::Create() first") ); - - return m_internal->Run(); -} - -// ----------------------------------------------------------------------------- -// pause/resume -// ----------------------------------------------------------------------------- - -wxThreadError wxThread::Pause() -{ - wxCHECK_MSG( This() != this, wxTHREAD_MISC_ERROR, - wxT("a thread can't pause itself") ); - - wxCriticalSectionLocker lock(m_critsect); - - if ( m_internal->GetState() != STATE_RUNNING ) - { - wxLogDebug( wxT("Can't pause thread which is not running.") ); - - return wxTHREAD_NOT_RUNNING; - } - - // just set a flag, the thread will be really paused only during the next - // call to TestDestroy() - m_internal->SetState( STATE_PAUSED ); - - return wxTHREAD_NO_ERROR; -} - -wxThreadError wxThread::Resume() -{ - wxCHECK_MSG( This() != this, wxTHREAD_MISC_ERROR, - wxT("a thread can't resume itself") ); - - wxCriticalSectionLocker lock(m_critsect); - - wxThreadState state = m_internal->GetState(); - - switch ( state ) - { - case STATE_PAUSED: - m_internal->Resume(); - return wxTHREAD_NO_ERROR; - - case STATE_EXITED: - return wxTHREAD_NO_ERROR; - - default: - wxLogDebug( wxT("Attempt to resume a thread which is not paused.") ); - - return wxTHREAD_MISC_ERROR; - } -} - -// ----------------------------------------------------------------------------- -// exiting thread -// ----------------------------------------------------------------------------- - -wxThread::ExitCode wxThread::Wait(wxThreadWait WXUNUSED(waitMode)) -{ - wxCHECK_MSG( This() != this, (ExitCode)-1, - wxT("a thread can't wait for itself") ); - - wxCHECK_MSG( !m_isDetached, (ExitCode)-1, - wxT("can't wait for detached thread") ); - - m_internal->Wait(); - - return m_internal->GetExitCode(); -} - -wxThreadError wxThread::Delete(ExitCode *rc, wxThreadWait WXUNUSED(waitMode)) -{ - wxCHECK_MSG( This() != this, wxTHREAD_MISC_ERROR, - wxT("a thread can't delete itself") ); - - bool isDetached = m_isDetached; - - m_critsect.Enter(); - wxThreadState state = m_internal->GetState(); - - // ask the thread to stop - m_internal->SetCancelFlag(); - - m_critsect.Leave(); - - switch ( state ) - { - case STATE_NEW: - // we need to wake up the thread so that PthreadStart() will - // terminate - right now it's blocking on run semaphore in - // PthreadStart() - m_internal->SignalRun(); - - // fall through - - case STATE_EXITED: - // nothing to do - break; - - case STATE_PAUSED: - // resume the thread first - m_internal->Resume(); - - // fall through - - default: - if ( !isDetached ) - { - // wait until the thread stops - m_internal->Wait(); - - if ( rc ) - { - // return the exit code of the thread - *rc = m_internal->GetExitCode(); - } - } - } - - return wxTHREAD_NO_ERROR; -} - -wxThreadError wxThread::Kill() -{ - wxCHECK_MSG( This() != this, wxTHREAD_MISC_ERROR, - wxT("a thread can't kill itself") ); - - switch ( m_internal->GetState() ) - { - case STATE_NEW: - case STATE_EXITED: - return wxTHREAD_NOT_RUNNING; - - case STATE_PAUSED: - // resume the thread first - Resume(); - - // fall through - - default: - OSStatus err = MPTerminateTask( m_internal->GetId() , -1 ) ; - if (err != noErr) - { - wxLogError( wxT("Failed to terminate a thread.") ); - - return wxTHREAD_MISC_ERROR; - } - - if ( m_isDetached ) - { - delete this ; - } - else - { - // this should be retrieved by Wait actually - m_internal->SetExitCode( (void*)-1 ); - } - - return wxTHREAD_NO_ERROR; - } -} - -void wxThread::Exit( ExitCode status ) -{ - wxASSERT_MSG( This() == this, - wxT("wxThread::Exit() can only be called in the context of the same thread") ); - - // don't enter m_critsect before calling OnExit() because the user code - // might deadlock if, for example, it signals a condition in OnExit() (a - // common case) while the main thread calls any of functions entering - // m_critsect on us (almost all of them do) - OnExit(); - - MPTaskID threadid = m_internal->GetId(); - - if ( IsDetached() ) - { - delete this; - } - else // joinable - { - // update the status of the joinable thread - wxCriticalSectionLocker lock( m_critsect ); - m_internal->SetState( STATE_EXITED ); - } - - MPTerminateTask( threadid, (long)status ); -} - -// also test whether we were paused -bool wxThread::TestDestroy() -{ - wxASSERT_MSG( This() == this, - wxT("wxThread::TestDestroy() can only be called in the context of the same thread") ); - - m_critsect.Enter(); - - if ( m_internal->GetState() == STATE_PAUSED ) - { - m_internal->SetReallyPaused( true ); - - // leave the crit section or the other threads will stop too if they attempt - // to call any of (seemingly harmless) IsXXX() functions while we sleep - m_critsect.Leave(); - - m_internal->Pause(); - } - else - { - // thread wasn't requested to pause, nothing to do - m_critsect.Leave(); - } - - return m_internal->WasCancelled(); -} - -// ----------------------------------------------------------------------------- -// priority setting -// ----------------------------------------------------------------------------- - -void wxThread::SetPriority(unsigned int prio) -{ - wxCHECK_RET( wxPRIORITY_MIN <= prio && prio <= wxPRIORITY_MAX, - wxT("invalid thread priority") ); - - wxCriticalSectionLocker lock(m_critsect); - - switch ( m_internal->GetState() ) - { - case STATE_RUNNING: - case STATE_PAUSED: - case STATE_NEW: - // thread not yet started, priority will be set when it is - m_internal->SetPriority( prio ); - break; - - case STATE_EXITED: - default: - wxFAIL_MSG( wxT("impossible to set thread priority in this state") ); - } -} - -unsigned int wxThread::GetPriority() const -{ - wxCriticalSectionLocker lock(const_cast(m_critsect)); - - return m_internal->GetPriority(); -} - -unsigned long wxThread::GetId() const -{ - wxCriticalSectionLocker lock(const_cast(m_critsect)); - - return (unsigned long)m_internal->GetId(); -} - -// ----------------------------------------------------------------------------- -// state tests -// ----------------------------------------------------------------------------- - -bool wxThread::IsRunning() const -{ - wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect); - - return m_internal->GetState() == STATE_RUNNING; -} - -bool wxThread::IsAlive() const -{ - wxCriticalSectionLocker lock((wxCriticalSection&)m_critsect); - - switch ( m_internal->GetState() ) - { - case STATE_RUNNING: - case STATE_PAUSED: - return true; - - default: - return false; - } -} - -bool wxThread::IsPaused() const -{ - wxCriticalSectionLocker lock((wxCriticalSection&)m_critsect); - - return (m_internal->GetState() == STATE_PAUSED); -} - -// ---------------------------------------------------------------------------- -// Automatic initialization for thread module -// ---------------------------------------------------------------------------- - -class wxThreadModule : public wxModule -{ -public: - virtual bool OnInit() wxOVERRIDE; - virtual void OnExit() wxOVERRIDE; - -private: - wxDECLARE_DYNAMIC_CLASS(wxThreadModule); -}; - -wxIMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule); - -bool wxThreadModule::OnInit() -{ - bool hasThreadManager = -#ifdef __LP64__ - true ; // TODO VERIFY IN NEXT BUILD -#else - MPLibraryIsLoaded(); -#endif - - if ( !hasThreadManager ) - { - wxLogError( wxT("MP thread support is not available on this system" ) ) ; - - return false; - } - - // main thread's This() is NULL - __Verify_noErr(MPAllocateTaskStorageIndex( &gs_tlsForWXThread )) ; - __Verify_noErr(MPSetTaskStorageValue( gs_tlsForWXThread, 0 )) ; - - wxThread::ms_idMainThread = wxThread::GetCurrentId(); - gs_critsectWaitingForGui = new wxCriticalSection(); - - gs_critsectGui = new wxCriticalSection(); - gs_critsectGui->Enter(); - - return true; -} - -void wxThreadModule::OnExit() -{ - if ( gs_critsectGui ) - { - if ( !wxGuiOwnedByMainThread() ) - { - gs_critsectGui->Enter(); - gs_bGuiOwnedByMainThread = true; - } - - gs_critsectGui->Leave(); - wxDELETE(gs_critsectGui); - } - - wxDELETE(gs_critsectWaitingForGui); -} - -// ---------------------------------------------------------------------------- -// GUI Serialization copied from MSW implementation -// ---------------------------------------------------------------------------- - -void wxMutexGuiEnterImpl() -{ - // this would dead lock everything... - wxASSERT_MSG( !wxThread::IsMain(), - wxT("main thread doesn't want to block in wxMutexGuiEnter()!") ); - - // the order in which we enter the critical sections here is crucial!! - - // set the flag telling to the main thread that we want to do some GUI - { - wxCriticalSectionLocker enter(*gs_critsectWaitingForGui); - - gs_nWaitingForGui++; - } - - wxWakeUpMainThread(); - - // now we may block here because the main thread will soon let us in - // (during the next iteration of OnIdle()) - gs_critsectGui->Enter(); -} - -void wxMutexGuiLeaveImpl() -{ - wxCriticalSectionLocker enter(*gs_critsectWaitingForGui); - - if ( wxThread::IsMain() ) - { - gs_bGuiOwnedByMainThread = false; - } - else - { - // decrement the number of threads waiting for GUI access now - wxASSERT_MSG( gs_nWaitingForGui > 0, - wxT("calling wxMutexGuiLeave() without entering it first?") ); - - gs_nWaitingForGui--; - - wxWakeUpMainThread(); - } - - gs_critsectGui->Leave(); -} - -void WXDLLIMPEXP_BASE wxMutexGuiLeaveOrEnter() -{ - wxASSERT_MSG( wxThread::IsMain(), - wxT("only main thread may call wxMutexGuiLeaveOrEnter()!") ); - - if ( !gs_critsectWaitingForGui ) - return; - - wxCriticalSectionLocker enter(*gs_critsectWaitingForGui); - - if ( gs_nWaitingForGui == 0 ) - { - // no threads are waiting for GUI - so we may acquire the lock without - // any danger (but only if we don't already have it) - if ( !wxGuiOwnedByMainThread() ) - { - gs_critsectGui->Enter(); - - gs_bGuiOwnedByMainThread = true; - } - //else: already have it, nothing to do - } - else - { - // some threads are waiting, release the GUI lock if we have it - if ( wxGuiOwnedByMainThread() ) - wxMutexGuiLeave(); - //else: some other worker thread is doing GUI - } -} - -bool WXDLLIMPEXP_BASE wxGuiOwnedByMainThread() -{ - return gs_bGuiOwnedByMainThread; -} - -// wake up the main thread -void WXDLLEXPORT wxWakeUpMainThread() -{ - wxMacWakeUp(); -} - -// ---------------------------------------------------------------------------- -// include common implementation code -// ---------------------------------------------------------------------------- - -#include "wx/thrimpl.cpp" - -#endif // wxUSE_THREADS