--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.9">
+<dict>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleIdentifier</key>
+ <string>org.wxwindows.IDENTIFIER</string>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>EXECUTABLE</string>
+ <key>CFBundleIconFile</key>
+ <string>wxmac.icns</string>
+ <key>CFBundleName</key>
+ <string>EXECUTABLE</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>VERSION</string>
+ <key>CFBundleShortVersionString</key>
+ <string>VERSION</string>
+ <key>CFBundleGetInfoString</key>
+ <string>EXECUTABLE version VERSION, (c) 2002 wxWindows</string>
+ <key>CFBundleLongVersionString</key>
+ <string>VERSION, (c) 2002 wxWindows</string>
+ <key>NSHumanReadableCopyright</key>
+ <string>Copyright 2002 wxWindows</string>
+ <key>LSRequiresCarbon</key>
+ <true/>
+ <key>CSResourcesFileMapped</key>
+ <true/>
+</dict>
+</plist>
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: accel.cpp
+// Purpose: wxAcceleratorTable
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "accel.h"
+#endif
+
+#include "wx/setup.h"
+#include "wx/accel.h"
+#include "wx/string.h"
+
+#if !USE_SHARED_LIBRARIES
+IMPLEMENT_DYNAMIC_CLASS(wxAcceleratorTable, wxObject)
+#endif
+
+// ----------------------------------------------------------------------------
+// wxAccelList: a list of wxAcceleratorEntries
+// ----------------------------------------------------------------------------
+
+WX_DECLARE_LIST(wxAcceleratorEntry, wxAccelList);
+#include "wx/listimpl.cpp"
+WX_DEFINE_LIST(wxAccelList);
+
+// ----------------------------------------------------------------------------
+// wxAccelRefData: the data used by wxAcceleratorTable
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxAcceleratorRefData: public wxObjectRefData
+{
+ friend class WXDLLEXPORT wxAcceleratorTable;
+public:
+ wxAcceleratorRefData();
+ ~wxAcceleratorRefData();
+
+ wxAccelList m_accels;
+};
+
+#define M_ACCELDATA ((wxAcceleratorRefData *)m_refData)
+
+wxAcceleratorRefData::wxAcceleratorRefData()
+ : m_accels()
+{
+}
+
+wxAcceleratorRefData::~wxAcceleratorRefData()
+{
+ m_accels.DeleteContents( TRUE );
+}
+
+wxAcceleratorTable::wxAcceleratorTable()
+{
+ m_refData = NULL;
+}
+
+wxAcceleratorTable::~wxAcceleratorTable()
+{
+}
+
+// Create from an array
+wxAcceleratorTable::wxAcceleratorTable(int n, const wxAcceleratorEntry entries[])
+{
+ m_refData = new wxAcceleratorRefData;
+
+ for (int i = 0; i < n; i++)
+ {
+ int flag = entries[i].GetFlags();
+ int keycode = entries[i].GetKeyCode();
+ int command = entries[i].GetCommand();
+ if ((keycode >= (int)'a') && (keycode <= (int)'z')) keycode = (int)toupper( (char)keycode );
+ M_ACCELDATA->m_accels.Append( new wxAcceleratorEntry( flag, keycode, command ) );
+ }
+}
+
+bool wxAcceleratorTable::Ok() const
+{
+ return (m_refData != NULL);
+}
+
+int wxAcceleratorTable::GetCommand( wxKeyEvent &event )
+{
+ if (!Ok()) return -1;
+
+ wxAccelList::Node *node = M_ACCELDATA->m_accels.GetFirst();
+ while (node)
+ {
+ wxAcceleratorEntry *entry = (wxAcceleratorEntry*)node->GetData();
+ if ((event.m_keyCode == entry->GetKeyCode()) &&
+ (((entry->GetFlags() & wxACCEL_CTRL) == 0) || event.ControlDown()) &&
+ (((entry->GetFlags() & wxACCEL_SHIFT) == 0) || event.ShiftDown()) &&
+ (((entry->GetFlags() & wxACCEL_ALT) == 0) || event.AltDown() || event.MetaDown()))
+ {
+ return entry->GetCommand();
+ }
+ node = node->GetNext();
+ }
+
+ return -1;
+}
+
+
--- /dev/null
+// NOT NEEDED ANYMORE
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: app.cpp
+// Purpose: wxApp
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "app.h"
+#endif
+
+#include "wx/defs.h"
+
+#include "wx/window.h"
+#include "wx/frame.h"
+#include "wx/button.h"
+#include "wx/app.h"
+#include "wx/utils.h"
+#include "wx/gdicmn.h"
+#include "wx/pen.h"
+#include "wx/brush.h"
+#include "wx/cursor.h"
+#include "wx/intl.h"
+#include "wx/icon.h"
+#include "wx/palette.h"
+#include "wx/dc.h"
+#include "wx/dialog.h"
+#include "wx/msgdlg.h"
+#include "wx/log.h"
+#include "wx/module.h"
+#include "wx/memory.h"
+#include "wx/tooltip.h"
+#include "wx/textctrl.h"
+#include "wx/menu.h"
+#include "wx/docview.h"
+#include "wx/filename.h"
+
+#include <string.h>
+
+// mac
+
+#ifndef __DARWIN__
+ #if __option(profile)
+ #include <profiler.h>
+ #endif
+#endif
+
+#include "apprsrc.h"
+
+#include "wx/mac/uma.h"
+#include "wx/mac/macnotfy.h"
+
+#ifdef __DARWIN__
+# include <CoreServices/CoreServices.h>
+# if defined(WXMAKINGDLL_CORE)
+# include <mach-o/dyld.h>
+# endif
+#else
+# include <Sound.h>
+# include <Threads.h>
+# include <ToolUtils.h>
+# include <DiskInit.h>
+# include <Devices.h>
+#endif
+
+extern wxList wxPendingDelete;
+extern wxList *wxWinMacWindowList;
+extern wxList *wxWinMacControlList;
+#if wxUSE_THREADS
+extern size_t g_numberOfThreads;
+#endif // wxUSE_THREADS
+
+// statics for implementation
+
+static bool s_inYield = FALSE;
+
+#if TARGET_CARBON
+static bool s_inReceiveEvent = FALSE ;
+static EventTime sleepTime = kEventDurationNoWait ;
+#else
+static long sleepTime = 0 ;
+#endif
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
+BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
+ EVT_IDLE(wxApp::OnIdle)
+ EVT_END_SESSION(wxApp::OnEndSession)
+ EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession)
+END_EVENT_TABLE()
+#endif
+
+
+const short kMacMinHeap = (29 * 1024) ;
+// platform specific static variables
+
+const short kwxMacMenuBarResource = 1 ;
+const short kwxMacAppleMenuId = 1 ;
+
+WXHRGN wxApp::s_macCursorRgn = NULL;
+wxWindow* wxApp::s_captureWindow = NULL ;
+int wxApp::s_lastMouseDown = 0 ;
+long wxApp::sm_lastMessageTime = 0;
+long wxApp::s_lastModifiers = 0 ;
+
+
+bool wxApp::s_macSupportPCMenuShortcuts = true ;
+long wxApp::s_macAboutMenuItemId = wxID_ABOUT ;
+long wxApp::s_macPreferencesMenuItemId = wxID_PREFERENCES ;
+long wxApp::s_macExitMenuItemId = wxID_EXIT ;
+wxString wxApp::s_macHelpMenuTitleName = wxT("&Help") ;
+
+// Normally we're not a plugin
+bool wxApp::sm_isEmbedded = false;
+//----------------------------------------------------------------------
+// Core Apple Event Support
+//----------------------------------------------------------------------
+
+pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
+pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
+pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
+pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
+pascal OSErr AEHandleRApp( const AppleEvent *event , AppleEvent *reply , long refcon ) ;
+
+pascal OSErr AEHandleODoc( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
+{
+ return wxTheApp->MacHandleAEODoc( (AppleEvent*) event , reply) ;
+}
+
+pascal OSErr AEHandleOApp( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
+{
+ return wxTheApp->MacHandleAEOApp( (AppleEvent*) event , reply ) ;
+}
+
+pascal OSErr AEHandlePDoc( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
+{
+ return wxTheApp->MacHandleAEPDoc( (AppleEvent*) event , reply ) ;
+}
+
+pascal OSErr AEHandleQuit( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
+{
+ return wxTheApp->MacHandleAEQuit( (AppleEvent*) event , reply) ;
+}
+
+pascal OSErr AEHandleRApp( const AppleEvent *event , AppleEvent *reply , long WXUNUSED(refcon) )
+{
+ return wxTheApp->MacHandleAERApp( (AppleEvent*) event , reply) ;
+}
+
+// AEODoc Calls MacOpenFile on each of the files passed
+
+short wxApp::MacHandleAEODoc(const WXEVENTREF event, WXEVENTREF WXUNUSED(reply))
+{
+ AEDescList docList;
+ AEKeyword keywd;
+ DescType returnedType;
+ Size actualSize;
+ long itemsInList;
+ FSSpec theSpec;
+ OSErr err;
+ short i;
+ err = AEGetParamDesc((AppleEvent *)event, keyDirectObject, typeAEList,&docList);
+ if (err != noErr)
+ return err;
+
+ err = AECountItems(&docList, &itemsInList);
+ if (err != noErr)
+ return err;
+
+ ProcessSerialNumber PSN ;
+ PSN.highLongOfPSN = 0 ;
+ PSN.lowLongOfPSN = kCurrentProcess ;
+ SetFrontProcess( &PSN ) ;
+
+ for (i = 1; i <= itemsInList; i++) {
+ AEGetNthPtr(&docList, i, typeFSS, &keywd, &returnedType,
+ (Ptr) & theSpec, sizeof(theSpec), &actualSize);
+ wxString fName = wxMacFSSpec2MacFilename(&theSpec);
+ MacOpenFile(fName);
+ }
+ return noErr;
+}
+
+// AEPDoc Calls MacPrintFile on each of the files passed
+
+short wxApp::MacHandleAEPDoc(const WXEVENTREF event , WXEVENTREF WXUNUSED(reply))
+{
+ AEDescList docList;
+ AEKeyword keywd;
+ DescType returnedType;
+ Size actualSize;
+ long itemsInList;
+ FSSpec theSpec;
+ OSErr err;
+ short i;
+ err = AEGetParamDesc((AppleEvent *)event, keyDirectObject, typeAEList,&docList);
+ if (err != noErr)
+ return err;
+
+ err = AECountItems(&docList, &itemsInList);
+ if (err != noErr)
+ return err;
+
+ ProcessSerialNumber PSN ;
+ PSN.highLongOfPSN = 0 ;
+ PSN.lowLongOfPSN = kCurrentProcess ;
+ SetFrontProcess( &PSN ) ;
+
+ for (i = 1; i <= itemsInList; i++) {
+ AEGetNthPtr(&docList, i, typeFSS, &keywd, &returnedType,
+ (Ptr) & theSpec, sizeof(theSpec), &actualSize);
+ wxString fName = wxMacFSSpec2MacFilename(&theSpec);
+ MacPrintFile(fName);
+ }
+ return noErr;
+}
+
+// AEOApp calls MacNewFile
+
+short wxApp::MacHandleAEOApp(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply))
+{
+ MacNewFile() ;
+ return noErr ;
+}
+
+// AEQuit attempts to quit the application
+
+short wxApp::MacHandleAEQuit(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply))
+{
+ wxWindow* win = GetTopWindow() ;
+ if ( win )
+ {
+ wxCommandEvent exitEvent(wxEVT_COMMAND_MENU_SELECTED, s_macExitMenuItemId);
+ if (!win->ProcessEvent(exitEvent))
+ win->Close(TRUE ) ;
+ }
+ else
+ {
+ ExitMainLoop() ;
+ }
+ return noErr ;
+}
+
+// AEROApp calls MacReopenApp
+
+short wxApp::MacHandleAERApp(const WXEVENTREF WXUNUSED(event) , WXEVENTREF WXUNUSED(reply))
+{
+ MacReopenApp() ;
+ return noErr ;
+}
+
+
+//----------------------------------------------------------------------
+// Support Routines linking the Mac...File Calls to the Document Manager
+//----------------------------------------------------------------------
+
+void wxApp::MacOpenFile(const wxString & fileName )
+{
+ wxDocManager* dm = wxDocManager::GetDocumentManager() ;
+ if ( dm )
+ dm->CreateDocument(fileName , wxDOC_SILENT ) ;
+}
+
+void wxApp::MacPrintFile(const wxString & fileName )
+{
+ wxDocManager* dm = wxDocManager::GetDocumentManager() ;
+ if ( dm )
+ {
+ wxDocument *doc = dm->CreateDocument(fileName , wxDOC_SILENT ) ;
+ if ( doc )
+ {
+ wxView* view = doc->GetFirstView() ;
+ if( view )
+ {
+ wxPrintout *printout = view->OnCreatePrintout();
+ if (printout)
+ {
+ wxPrinter printer;
+ printer.Print(view->GetFrame(), printout, TRUE);
+ delete printout;
+ }
+ }
+ if (doc->Close())
+ {
+ doc->DeleteAllViews();
+ dm->RemoveDocument(doc) ;
+ }
+ }
+ }
+}
+
+void wxApp::MacNewFile()
+{
+}
+
+void wxApp::MacReopenApp()
+{
+ // eventually check for open docs, if none, call MacNewFile
+}
+
+//----------------------------------------------------------------------
+// Carbon Event Handler
+//----------------------------------------------------------------------
+
+#if TARGET_CARBON
+
+ static const EventTypeSpec eventList[] =
+ {
+ { kEventClassCommand, kEventProcessCommand } ,
+ { kEventClassCommand, kEventCommandUpdateStatus } ,
+
+ { kEventClassMenu, kEventMenuOpening },
+ { kEventClassMenu, kEventMenuClosed },
+ { kEventClassMenu, kEventMenuTargetItem },
+
+ { kEventClassApplication , kEventAppActivated } ,
+ { kEventClassApplication , kEventAppDeactivated } ,
+ // handling the quit event is not recommended by apple
+ // rather using the quit apple event - which we do
+
+ { kEventClassAppleEvent , kEventAppleEvent } ,
+
+ { kEventClassMouse , kEventMouseDown } ,
+ { kEventClassMouse , kEventMouseMoved } ,
+ { kEventClassMouse , kEventMouseUp } ,
+ { kEventClassMouse , kEventMouseDragged } ,
+ { 'WXMC' , 'WXMC' }
+ } ;
+
+static pascal OSStatus
+MenuEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
+{
+ wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar();
+
+ if ( mbar )
+ {
+ wxFrame* win = mbar->GetFrame();
+ if ( win )
+ {
+
+ // VZ: we could find the menu from its handle here by examining all
+ // the menus in the menu bar recursively but knowing that neither
+ // wxMSW nor wxGTK do it why bother...
+ #if 0
+ MenuRef menuRef;
+
+ GetEventParameter(event,
+ kEventParamDirectObject,
+ typeMenuRef, NULL,
+ sizeof(menuRef), NULL,
+ &menuRef);
+ #endif // 0
+
+ wxEventType type=0;
+ MenuCommand cmd=0;
+ switch (GetEventKind(event))
+ {
+ case kEventMenuOpening:
+ type = wxEVT_MENU_OPEN;
+ break;
+ case kEventMenuClosed:
+ type = wxEVT_MENU_CLOSE;
+ break;
+ case kEventMenuTargetItem:
+ type = wxEVT_MENU_HIGHLIGHT;
+ GetEventParameter(event, kEventParamMenuCommand,
+ typeMenuCommand, NULL,
+ sizeof(cmd), NULL, &cmd);
+ if (cmd == 0) return eventNotHandledErr;
+ break;
+ default:
+ wxFAIL_MSG(wxT("Unexpected menu event kind"));
+ break;
+ }
+
+ wxMenuEvent wxevent(type, cmd);
+ wxevent.SetEventObject(win);
+
+ (void)win->GetEventHandler()->ProcessEvent(wxevent);
+ }
+ }
+
+ return eventNotHandledErr;
+}
+
+// due to the rather low-level event API of wxWindows, we cannot use RunApplicationEventLoop
+// but have to use ReceiveNextEvent dealing with events manually, therefore we also have
+// deal with clicks in the menu bar explicitely
+
+pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) ;
+
+static pascal OSStatus MouseEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
+{
+ OSStatus result = eventNotHandledErr ;
+
+ Point point ;
+ UInt32 modifiers = 0;
+ EventMouseButton button = 0 ;
+ UInt32 click = 0 ;
+
+ GetEventParameter( event, kEventParamMouseLocation, typeQDPoint, NULL,
+ sizeof( Point ), NULL, &point );
+ GetEventParameter( event, kEventParamKeyModifiers, typeUInt32, NULL,
+ sizeof( UInt32 ), NULL, &modifiers );
+ GetEventParameter( event, kEventParamMouseButton, typeMouseButton, NULL,
+ sizeof( EventMouseButton ), NULL, &button );
+ GetEventParameter( event, kEventParamClickCount, typeUInt32, NULL,
+ sizeof( UInt32 ), NULL, &click );
+
+ if ( button == 0 || GetEventKind( event ) == kEventMouseUp )
+ modifiers += btnState ;
+
+
+ switch( GetEventKind(event) )
+ {
+ case kEventMouseDown :
+ {
+ WindowRef window ;
+
+ short windowPart = ::FindWindow(point, &window);
+
+ if ( windowPart == inMenuBar )
+ {
+ MenuSelect( point ) ;
+ result = noErr ;
+ }
+ }
+ break ;
+ case kEventMouseDragged :
+ case kEventMouseUp :
+ {
+ if ( wxTheApp->s_captureWindow )
+ wxMacWindowEventHandler( handler , event , (void*) wxTheApp->s_captureWindow->MacGetTopLevelWindow() ) ;
+ }
+ break ;
+ case kEventMouseMoved :
+ {
+ wxTheApp->MacHandleMouseMovedEvent( point.h , point.v , modifiers , EventTimeToTicks( GetEventTime( event ) ) ) ;
+ result = noErr ;
+ break ;
+ }
+ break ;
+ }
+
+ return result ;
+}
+
+static pascal OSStatus CommandEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
+{
+ OSStatus result = eventNotHandledErr ;
+
+ HICommand command ;
+
+ GetEventParameter( event, kEventParamDirectObject, typeHICommand, NULL,
+ sizeof( HICommand ), NULL, &command );
+
+ MenuCommand id = command.commandID ;
+ if ( id == kHICommandPreferences )
+ id = wxApp::s_macPreferencesMenuItemId ;
+
+ wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ;
+ wxMenu* menu = NULL ;
+ wxMenuItem* item = NULL ;
+
+ if ( mbar )
+ {
+ item = mbar->FindItem( id , &menu ) ;
+ // it is not 100 % sure that an menu of id 0 is really ours, safety check
+ if ( id == 0 && menu != NULL && menu->GetHMenu() != command.menu.menuRef )
+ {
+ item = NULL ;
+ menu = NULL ;
+ }
+ }
+
+ if ( item == NULL || menu == NULL || mbar == NULL )
+ return result ;
+
+ switch( GetEventKind( event ) )
+ {
+ case kEventProcessCommand :
+ {
+ if (item->IsCheckable())
+ {
+ item->Check( !item->IsChecked() ) ;
+ }
+
+ menu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ;
+ result = noErr ;
+ }
+ break ;
+ case kEventCommandUpdateStatus:
+ // eventually trigger an updateui round
+ result = noErr ;
+ break ;
+ default :
+ break ;
+ }
+
+ return result ;
+}
+
+static pascal OSStatus ApplicationEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
+{
+ OSStatus result = eventNotHandledErr ;
+ switch ( GetEventKind( event ) )
+ {
+ case kEventAppActivated :
+ {
+ if ( wxTheApp )
+ wxTheApp->MacResume( true ) ;
+ result = noErr ;
+ }
+ break ;
+ case kEventAppDeactivated :
+ {
+ if ( wxTheApp )
+ wxTheApp->MacSuspend( true ) ;
+ result = noErr ;
+ }
+ break ;
+ default :
+ break ;
+ }
+ return result ;
+}
+
+pascal OSStatus wxAppEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
+{
+ OSStatus result = eventNotHandledErr ;
+ switch( GetEventClass( event ) )
+ {
+ case kEventClassCommand :
+ result = CommandEventHandler( handler , event , data ) ;
+ break ;
+ case kEventClassApplication :
+ result = ApplicationEventHandler( handler , event , data ) ;
+ break ;
+ case kEventClassMenu :
+ result = MenuEventHandler( handler , event , data ) ;
+ break ;
+ case kEventClassMouse :
+ result = MouseEventHandler( handler , event , data ) ;
+ break ;
+ case kEventClassAppleEvent :
+ {
+ EventRecord rec ;
+ wxMacConvertEventToRecord( event , &rec ) ;
+ result = AEProcessAppleEvent( &rec ) ;
+ }
+ break ;
+ default :
+ break ;
+ }
+
+ return result ;
+}
+
+DEFINE_ONE_SHOT_HANDLER_GETTER( wxAppEventHandler )
+
+#endif
+
+#if defined(WXMAKINGDLL_CORE) && !defined(__DARWIN__)
+// we know it's there ;-)
+WXIMPORT char std::__throws_bad_alloc ;
+#endif
+
+bool wxApp::Initialize(int& argc, wxChar **argv)
+{
+ int error = 0 ;
+
+ // Mac-specific
+
+ UMAInitToolbox( 4, sm_isEmbedded ) ;
+ SetEventMask( everyEvent ) ;
+ UMAShowWatchCursor() ;
+
+#if defined(WXMAKINGDLL_CORE) && defined(__DARWIN__)
+ // open shared library resources from here since we don't have
+ // __wxinitialize in Mach-O shared libraries
+ wxStAppResource::OpenSharedLibraryResource(NULL);
+#endif
+
+#ifndef __DARWIN__
+ // test the minimal configuration necessary
+
+# if !TARGET_CARBON
+ long theSystem ;
+ long theMachine;
+
+ if (Gestalt(gestaltMachineType, &theMachine) != noErr)
+ {
+ error = kMacSTRWrongMachine;
+ }
+ else if (theMachine < gestaltMacPlus)
+ {
+ error = kMacSTRWrongMachine;
+ }
+ else if (Gestalt(gestaltSystemVersion, &theSystem) != noErr )
+ {
+ error = kMacSTROldSystem ;
+ }
+ else if ( theSystem < 0x0860 )
+ {
+ error = kMacSTROldSystem ;
+ }
+ else if ((long)GetApplLimit() - (long)ApplicationZone() < kMacMinHeap)
+ {
+ error = kMacSTRSmallSize;
+ }
+# endif
+ /*
+ else
+ {
+ if ( !UMAHasAppearance() )
+ {
+ error = kMacSTRNoPre8Yet ;
+ }
+ }
+ */
+#endif
+
+ // if we encountered any problems so far, give the error code and exit immediately
+
+ if ( error )
+ {
+ wxStAppResource resload ;
+ short itemHit;
+ Str255 message;
+
+ GetIndString(message, 128, error);
+ UMAShowArrowCursor() ;
+ ParamText("\pFatal Error", message, (ConstStr255Param)"\p", (ConstStr255Param)"\p");
+ itemHit = Alert(128, nil);
+ return FALSE ;
+ }
+
+#ifndef __DARWIN__
+# if __option(profile)
+ ProfilerInit( collectDetailed, bestTimeBase , 40000 , 50 ) ;
+# endif
+#endif
+
+#ifndef __DARWIN__
+ // now avoid exceptions thrown for new (bad_alloc)
+ // FIXME CS for some changes outside wxMac does not compile anymore
+#if 0
+ std::__throws_bad_alloc = 0 ;
+#endif
+
+#endif
+
+ s_macCursorRgn = ::NewRgn() ;
+
+ // Mac OS X passes a process serial number command line argument when
+ // the application is launched from the Finder. This argument must be
+ // removed from the command line arguments before being handled by the
+ // application (otherwise applications would need to handle it)
+ if ( argc > 1 )
+ {
+ static const wxChar *ARG_PSN = _T("-psn_");
+ if ( wxStrncmp(argv[1], ARG_PSN, wxStrlen(ARG_PSN)) == 0 )
+ {
+ // remove this argument
+ --argc;
+ memmove(argv + 1, argv + 2, argc * sizeof(char *));
+ }
+ }
+
+ if ( !wxAppBase::Initialize(argc, argv) )
+ return false;
+
+#if wxUSE_INTL
+ wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding());
+#endif
+
+
+ wxWinMacWindowList = new wxList(wxKEY_INTEGER);
+ wxWinMacControlList = new wxList(wxKEY_INTEGER);
+
+ wxMacCreateNotifierTable() ;
+
+ UMAShowArrowCursor() ;
+
+ return true;
+}
+
+bool wxApp::OnInitGui()
+{
+ if( !wxAppBase::OnInitGui() )
+ return false ;
+
+#if TARGET_CARBON
+ InstallStandardEventHandler( GetApplicationEventTarget() ) ;
+
+ if (!sm_isEmbedded)
+ {
+ InstallApplicationEventHandler(
+ GetwxAppEventHandlerUPP(),
+ GetEventTypeCount(eventList), eventList, wxTheApp, (EventHandlerRef *)&(wxTheApp->m_macEventHandler));
+ }
+#endif
+
+ if (!sm_isEmbedded)
+ {
+#if defined(UNIVERSAL_INTERFACES_VERSION) && (UNIVERSAL_INTERFACES_VERSION >= 0x0340)
+ AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments ,
+ NewAEEventHandlerUPP(AEHandleODoc) ,
+ 0 , FALSE ) ;
+ AEInstallEventHandler( kCoreEventClass , kAEOpenApplication ,
+ NewAEEventHandlerUPP(AEHandleOApp) ,
+ 0 , FALSE ) ;
+ AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments ,
+ NewAEEventHandlerUPP(AEHandlePDoc) ,
+ 0 , FALSE ) ;
+ AEInstallEventHandler( kCoreEventClass , kAEReopenApplication ,
+ NewAEEventHandlerUPP(AEHandleRApp) ,
+ 0 , FALSE ) ;
+ AEInstallEventHandler( kCoreEventClass , kAEQuitApplication ,
+ NewAEEventHandlerUPP(AEHandleQuit) ,
+ 0 , FALSE ) ;
+#else
+ AEInstallEventHandler( kCoreEventClass , kAEOpenDocuments ,
+ NewAEEventHandlerProc(AEHandleODoc) ,
+ 0 , FALSE ) ;
+ AEInstallEventHandler( kCoreEventClass , kAEOpenApplication ,
+ NewAEEventHandlerProc(AEHandleOApp) ,
+ 0 , FALSE ) ;
+ AEInstallEventHandler( kCoreEventClass , kAEPrintDocuments ,
+ NewAEEventHandlerProc(AEHandlePDoc) ,
+ 0 , FALSE ) ;
+ AEInstallEventHandler( kCoreEventClass , kAEReopenApplication ,
+ NewAEEventHandlerProc(AEHandleRApp) ,
+ 0 , FALSE ) ;
+ AEInstallEventHandler( kCoreEventClass , kAEQuitApplication ,
+ NewAEEventHandlerProc(AEHandleQuit) ,
+ 0 , FALSE ) ;
+#endif
+ }
+
+ return TRUE ;
+}
+
+void wxApp::CleanUp()
+{
+ wxToolTip::RemoveToolTips() ;
+
+ // One last chance for pending objects to be cleaned up
+ wxTheApp->DeletePendingObjects();
+
+ wxMacDestroyNotifierTable() ;
+
+ delete wxWinMacWindowList ;
+ wxWinMacWindowList = NULL;
+
+ delete wxWinMacControlList ;
+ wxWinMacControlList = NULL;
+
+#ifndef __DARWIN__
+# if __option(profile)
+ ProfilerDump( (StringPtr)"\papp.prof" ) ;
+ ProfilerTerm() ;
+# endif
+#endif
+
+#if defined(WXMAKINGDLL_CORE) && defined(__DARWIN__)
+ // close shared library resources from here since we don't have
+ // __wxterminate in Mach-O shared libraries
+ wxStAppResource::CloseSharedLibraryResource();
+#endif
+
+ UMACleanupToolbox() ;
+ if (s_macCursorRgn) {
+ ::DisposeRgn((RgnHandle)s_macCursorRgn);
+ }
+
+ #if 0
+ TerminateAE() ;
+ #endif
+
+ wxAppBase::CleanUp();
+}
+
+//----------------------------------------------------------------------
+// misc initialization stuff
+//----------------------------------------------------------------------
+
+// extern variable for shared library resource id
+// need to be able to find it with NSLookupAndBindSymbol
+short gSharedLibraryResource = kResFileNotOpened ;
+
+#if defined(WXMAKINGDLL_CORE) && defined(__DARWIN__)
+CFBundleRef gSharedLibraryBundle = NULL;
+#endif /* WXMAKINGDLL_CORE && __DARWIN__ */
+
+wxStAppResource::wxStAppResource()
+{
+ m_currentRefNum = CurResFile() ;
+ if ( gSharedLibraryResource != kResFileNotOpened )
+ {
+ UseResFile( gSharedLibraryResource ) ;
+ }
+}
+
+wxStAppResource::~wxStAppResource()
+{
+ if ( m_currentRefNum != kResFileNotOpened )
+ {
+ UseResFile( m_currentRefNum ) ;
+ }
+}
+
+void wxStAppResource::OpenSharedLibraryResource(const void *initBlock)
+{
+ gSharedLibraryResource = kResFileNotOpened;
+
+#ifdef WXMAKINGDLL_CORE
+ if ( initBlock != NULL ) {
+ const CFragInitBlock *theInitBlock = (const CFragInitBlock *)initBlock;
+ FSSpec *fileSpec = NULL;
+
+ if (theInitBlock->fragLocator.where == kDataForkCFragLocator) {
+ fileSpec = theInitBlock->fragLocator.u.onDisk.fileSpec;
+ }
+ else if (theInitBlock->fragLocator.where == kResourceCFragLocator) {
+ fileSpec = theInitBlock->fragLocator.u.inSegs.fileSpec;
+ }
+
+ if (fileSpec != NULL) {
+ gSharedLibraryResource = FSpOpenResFile(fileSpec, fsRdPerm);
+ }
+ }
+ else {
+#ifdef __DARWIN__
+ // Open the shared library resource file if it is not yet open
+ NSSymbol theSymbol;
+ NSModule theModule;
+ const char *theLibPath;
+
+ gSharedLibraryBundle = CFBundleGetBundleWithIdentifier(CFSTR("com.wxwindows.wxWindows"));
+ if (gSharedLibraryBundle != NULL) {
+ // wxWindows has been bundled into a framework
+ // load the framework resources
+
+ gSharedLibraryResource = CFBundleOpenBundleResourceMap(gSharedLibraryBundle);
+ }
+ else {
+ // wxWindows is a simple dynamic shared library
+ // load the resources from the data fork of a separate resource file
+ wxString theResPath;
+ wxString theName;
+ FSRef theResRef;
+ OSErr theErr = noErr;
+
+ // get the library path
+ theSymbol = NSLookupAndBindSymbol("_gSharedLibraryResource");
+ theModule = NSModuleForSymbol(theSymbol);
+ theLibPath = NSLibraryNameForModule(theModule);
+
+ // if we call wxLogDebug from here then, as wxTheApp hasn't been
+ // created yet when we're called from wxApp::Initialize(), wxLog
+ // is going to create a default stderr-based log target instead of
+ // the expected normal GUI one -- don't do it, if we really want
+ // to see this message just use fprintf() here
+#if 0
+ wxLogDebug( wxT("wxMac library installation name is '%s'"),
+ theLibPath );
+#endif
+
+ // allocate copy to replace .dylib.* extension with .rsrc
+ if (theLibPath != NULL) {
+#if wxUSE_UNICODE
+ theResPath = wxString(theLibPath, wxConvLocal);
+#else
+ theResPath = wxString(theLibPath);
+#endif
+ // replace '_core' with '' in case of multi-lib build
+ theResPath.Replace(wxT("_core"), wxEmptyString);
+ // replace ".dylib" shared library extension with ".rsrc"
+ theResPath.Replace(wxT(".dylib"), wxT(".rsrc"));
+ // Find the begining of the filename
+ theName = theResPath.AfterLast('/');
+
+#if 0
+ wxLogDebug( wxT("wxMac resources file name is '%s'"),
+ theResPath.mb_str() );
+#endif
+
+ theErr = FSPathMakeRef((UInt8 *) theResPath.mb_str(), &theResRef, false);
+ if (theErr != noErr) {
+ // try in current directory (using name only)
+ theErr = FSPathMakeRef((UInt8 *) theName.mb_str(), &theResRef, false);
+ }
+
+ // open the resource file
+ if (theErr == noErr) {
+ theErr = FSOpenResourceFile( &theResRef, 0, NULL, fsRdPerm,
+ &gSharedLibraryResource);
+ }
+ if (theErr != noErr) {
+#ifdef __WXDEBUG__
+ wxLogDebug( wxT("unable to open wxMac resource file '%s'\n"),
+ theResPath.mb_str() );
+#endif // __WXDEBUG__
+ }
+
+ }
+ }
+#endif /* __DARWIN__ */
+ }
+#endif /* WXMAKINGDLL_CORE */
+}
+
+void wxStAppResource::CloseSharedLibraryResource()
+{
+#ifdef WXMAKINGDLL_CORE
+ // Close the shared library resource file
+ if (gSharedLibraryResource != kResFileNotOpened) {
+#ifdef __DARWIN__
+ if (gSharedLibraryBundle != NULL) {
+ CFBundleCloseBundleResourceMap(gSharedLibraryBundle,
+ gSharedLibraryResource);
+ gSharedLibraryBundle = NULL;
+ }
+ else
+#endif /* __DARWIN__ */
+ {
+ CloseResFile(gSharedLibraryResource);
+ }
+ gSharedLibraryResource = kResFileNotOpened;
+ }
+#endif /* WXMAKINGDLL_CORE */
+}
+
+#if defined(WXMAKINGDLL_CORE) && !defined(__DARWIN__)
+
+// for shared libraries we have to manually get the correct resource
+// ref num upon initializing and releasing when terminating, therefore
+// the __wxinitialize and __wxterminate must be used
+
+extern "C" {
+ void __sinit(void); /* (generated by linker) */
+ pascal OSErr __initialize(const CFragInitBlock *theInitBlock);
+ pascal void __terminate(void);
+}
+
+pascal OSErr __wxinitialize(const CFragInitBlock *theInitBlock)
+{
+ wxStAppResource::OpenSharedLibraryResource( theInitBlock ) ;
+ return __initialize( theInitBlock ) ;
+}
+
+pascal void __wxterminate(void)
+{
+ wxStAppResource::CloseSharedLibraryResource() ;
+ __terminate() ;
+}
+
+#endif /* WXMAKINGDLL_CORE && !__DARWIN__ */
+
+#if TARGET_CARBON
+
+bool wxMacConvertEventToRecord( EventRef event , EventRecord *rec)
+{
+ bool converted = ConvertEventRefToEventRecord( event,rec) ;
+ OSStatus err = noErr ;
+ if ( !converted )
+ {
+ switch( GetEventClass( event ) )
+ {
+ case kEventClassKeyboard :
+ {
+ converted = true ;
+ switch( GetEventKind(event) )
+ {
+ case kEventRawKeyDown :
+ rec->what = keyDown ;
+ break ;
+ case kEventRawKeyRepeat :
+ rec->what = autoKey ;
+ break ;
+ case kEventRawKeyUp :
+ rec->what = keyUp ;
+ break ;
+ case kEventRawKeyModifiersChanged :
+ rec->what = nullEvent ;
+ break ;
+ default :
+ converted = false ;
+ break ;
+ }
+ if ( converted )
+ {
+ UInt32 keyCode ;
+ unsigned char charCode ;
+ UInt32 modifiers ;
+ GetMouse( &rec->where) ;
+
+ err = GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL, 4, NULL, &modifiers);
+ err = GetEventParameter(event, kEventParamKeyCode, typeUInt32, NULL, 4, NULL, &keyCode);
+ err = GetEventParameter(event, kEventParamKeyMacCharCodes, typeChar, NULL, 1, NULL, &charCode);
+ rec->modifiers = modifiers ;
+ rec->message = (keyCode << 8 ) + charCode ;
+ }
+ }
+ break ;
+ case kEventClassTextInput :
+ {
+ switch( GetEventKind( event ) )
+ {
+ case kEventTextInputUnicodeForKeyEvent :
+ {
+ EventRef rawEvent ;
+ err = GetEventParameter( event , kEventParamTextInputSendKeyboardEvent ,typeEventRef,NULL,sizeof(rawEvent),NULL,&rawEvent ) ;
+ converted = true ;
+ {
+ UInt32 keyCode ;
+ unsigned char charCode ;
+ UInt32 modifiers ;
+ GetMouse( &rec->where) ;
+ rec->what = keyDown ;
+ err = GetEventParameter(rawEvent, kEventParamKeyModifiers, typeUInt32, NULL, 4, NULL, &modifiers);
+ err = GetEventParameter(rawEvent, kEventParamKeyCode, typeUInt32, NULL, 4, NULL, &keyCode);
+ err = GetEventParameter(rawEvent, kEventParamKeyMacCharCodes, typeChar, NULL, 1, NULL, &charCode);
+ rec->modifiers = modifiers ;
+ rec->message = (keyCode << 8 ) + charCode ;
+ }
+ }
+ break ;
+ default :
+ break ;
+ }
+ }
+ break ;
+ }
+ }
+
+ return converted ;
+}
+
+/*
+pascal OSStatus wxMacApplicationEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
+{
+ OSStatus result = eventNotHandledErr ;
+
+ EventRecord rec ;
+ switch ( GetEventClass( event ) )
+ {
+ case kEventClassKeyboard :
+ if ( wxMacConvertEventToRecord( event , &rec ) )
+ {
+ wxTheApp->MacHandleModifierEvents( &rec ) ;
+ wxTheApp->MacHandleOneEvent( &rec ) ;
+ result = noErr ;
+ }
+ break ;
+ case kEventClassTextInput :
+ if ( wxMacConvertEventToRecord( event , &rec ) )
+ {
+ wxTheApp->MacHandleModifierEvents( &rec ) ;
+ wxTheApp->MacHandleOneEvent( &rec ) ;
+ result = noErr ;
+ }
+ break ;
+ default :
+ break ;
+ }
+ return result ;
+}
+*/
+#endif
+
+wxApp::wxApp()
+{
+ m_printMode = wxPRINT_WINDOWS;
+ m_auto3D = TRUE;
+
+ m_macCurrentEvent = NULL ;
+#if TARGET_CARBON
+ m_macCurrentEventHandlerCallRef = NULL ;
+#endif
+}
+
+int wxApp::MainLoop()
+{
+ m_keepGoing = TRUE;
+
+ while (m_keepGoing)
+ {
+ MacDoOneEvent() ;
+ }
+
+ return 0;
+}
+
+void wxApp::ExitMainLoop()
+{
+ m_keepGoing = FALSE;
+}
+
+// Is a message/event pending?
+bool wxApp::Pending()
+{
+#if TARGET_CARBON
+ // without the receive event (with pull param = false ) nothing is ever reported
+ EventRef theEvent;
+ ReceiveNextEvent (0, NULL, kEventDurationNoWait, false, &theEvent);
+ return GetNumEventsInQueue( GetMainEventQueue() ) > 0 ;
+#else
+ EventRecord event ;
+
+ return EventAvail( everyEvent , &event ) ;
+#endif
+}
+
+// Dispatch a message.
+bool wxApp::Dispatch()
+{
+ MacDoOneEvent() ;
+
+ return true;
+}
+
+void wxApp::OnIdle(wxIdleEvent& event)
+{
+ wxAppBase::OnIdle(event);
+
+ // If they are pending events, we must process them: pending events are
+ // either events to the threads other than main or events posted with
+ // wxPostEvent() functions
+ wxMacProcessNotifierAndPendingEvents();
+
+ if(!wxMenuBar::MacGetInstalledMenuBar() && wxMenuBar::MacGetCommonMenuBar())
+ wxMenuBar::MacGetCommonMenuBar()->MacInstallMenuBar();
+}
+
+void wxApp::WakeUpIdle()
+{
+ wxMacWakeUp() ;
+}
+
+void wxApp::Exit()
+{
+ wxApp::CleanUp();
+ ::ExitToShell() ;
+}
+
+void wxApp::OnEndSession(wxCloseEvent& WXUNUSED(event))
+{
+ if (GetTopWindow())
+ GetTopWindow()->Close(TRUE);
+}
+
+// Default behaviour: close the application with prompts. The
+// user can veto the close, and therefore the end session.
+void wxApp::OnQueryEndSession(wxCloseEvent& event)
+{
+ if (GetTopWindow())
+ {
+ if (!GetTopWindow()->Close(!event.CanVeto()))
+ event.Veto(TRUE);
+ }
+}
+
+extern "C" void wxCYield() ;
+void wxCYield()
+{
+ wxYield() ;
+}
+
+// Yield to other processes
+
+bool wxApp::Yield(bool onlyIfNeeded)
+{
+ if (s_inYield)
+ {
+ if ( !onlyIfNeeded )
+ {
+ wxFAIL_MSG( wxT("wxYield called recursively" ) );
+ }
+
+ return FALSE;
+ }
+
+ s_inYield = TRUE;
+
+#if wxUSE_THREADS
+ YieldToAnyThread() ;
+#endif
+ // by definition yield should handle all non-processed events
+#if TARGET_CARBON
+ EventRef theEvent;
+
+ OSStatus status = noErr ;
+ do
+ {
+ s_inReceiveEvent = true ;
+ status = ReceiveNextEvent(0, NULL,kEventDurationNoWait,true,&theEvent) ;
+ s_inReceiveEvent = false ;
+
+ if ( status == eventLoopTimedOutErr )
+ {
+ // make sure next time the event loop will trigger idle events
+ sleepTime = kEventDurationNoWait ;
+ }
+ else if ( status == eventLoopQuitErr )
+ {
+ // according to QA1061 this may also occur when a WakeUp Process
+ // is executed
+ }
+ else
+ {
+ MacHandleOneEvent( theEvent ) ;
+ ReleaseEvent(theEvent);
+ }
+ } while( status == noErr ) ;
+#else
+ EventRecord event ;
+
+ // having a larger value here leads to large performance slowdowns
+ // so we cannot give background apps more processor time here
+ // we do so however having a large sleep value in the main event loop
+ sleepTime = 0 ;
+
+ while ( !IsExiting() && WaitNextEvent(everyEvent, &event,sleepTime, (RgnHandle) wxApp::s_macCursorRgn))
+ {
+ MacHandleModifierEvents( &event ) ;
+ MacHandleOneEvent( &event );
+ if ( event.what != kHighLevelEvent )
+ SetRectRgn( (RgnHandle) wxApp::s_macCursorRgn , event.where.h , event.where.v , event.where.h + 1 , event.where.v + 1 ) ;
+ }
+ MacHandleModifierEvents( &event ) ;
+#endif
+
+ wxMacProcessNotifierAndPendingEvents() ;
+ s_inYield = FALSE;
+
+ return TRUE;
+}
+
+// platform specifics
+
+void wxApp::MacSuspend( bool convertClipboard )
+{
+#if !TARGET_CARBON
+ // we have to deactive the top level windows manually
+
+ wxWindowListNode* node = wxTopLevelWindows.GetFirst();
+ while (node)
+ {
+ wxTopLevelWindow* win = (wxTopLevelWindow*) node->Data();
+#if TARGET_CARBON
+#if 0 // having problems right now with that
+ if (!win->HasFlag(wxSTAY_ON_TOP))
+#endif
+#endif
+ win->MacActivate( ((EventRecord*) MacGetCurrentEvent())->when , false ) ;
+
+ node = node->GetNext();
+ }
+
+ ::HideFloatingWindows() ;
+#endif
+ s_lastMouseDown = 0 ;
+
+ if( convertClipboard )
+ {
+ MacConvertPrivateToPublicScrap() ;
+ }
+}
+
+extern wxList wxModalDialogs;
+
+void wxApp::MacResume( bool convertClipboard )
+{
+ s_lastMouseDown = 0 ;
+ if( convertClipboard )
+ {
+ MacConvertPublicToPrivateScrap() ;
+ }
+
+#if !TARGET_CARBON
+ ::ShowFloatingWindows() ;
+ // raise modal dialogs in case a non modal window was selected to activate the app
+
+ wxNode* node = wxModalDialogs.GetFirst();
+ while (node)
+ {
+ wxDialog* dialog = (wxDialog *) node->GetData();
+ dialog->Raise();
+
+ node = node->GetNext();
+ }
+#endif
+}
+
+void wxApp::MacConvertPrivateToPublicScrap()
+{
+}
+
+void wxApp::MacConvertPublicToPrivateScrap()
+{
+}
+
+void wxApp::MacDoOneEvent()
+{
+#if TARGET_CARBON
+ EventRef theEvent;
+
+ s_inReceiveEvent = true ;
+ OSStatus status = ReceiveNextEvent(0, NULL,sleepTime,true,&theEvent) ;
+ s_inReceiveEvent = false ;
+ if ( status == eventLoopTimedOutErr )
+ {
+ if ( wxTheApp->ProcessIdle() )
+ sleepTime = kEventDurationNoWait ;
+ else
+ {
+#if wxUSE_THREADS
+ if (g_numberOfThreads)
+ {
+ sleepTime = kEventDurationNoWait;
+ }
+ else
+#endif // wxUSE_THREADS
+ {
+ sleepTime = kEventDurationSecond;
+ }
+ }
+ }
+ else if ( status == eventLoopQuitErr )
+ {
+ // according to QA1061 this may also occur when a WakeUp Process
+ // is executed
+ }
+ else
+ {
+ MacHandleOneEvent( theEvent ) ;
+ ReleaseEvent(theEvent);
+ sleepTime = kEventDurationNoWait ;
+ }
+#else
+ EventRecord event ;
+
+ EventMask eventMask = everyEvent ;
+
+ if (WaitNextEvent(eventMask, &event, sleepTime, (RgnHandle) s_macCursorRgn))
+ {
+ MacHandleModifierEvents( &event ) ;
+ MacHandleOneEvent( &event );
+ }
+ else
+ {
+ MacHandleModifierEvents( &event ) ;
+ // idlers
+ WindowPtr window = ::FrontWindow() ;
+ if ( window )
+ ::IdleControls( window ) ;
+
+ if ( wxTheApp->ProcessIdle() )
+ sleepTime = kEventDurationNoWait;
+ else
+ {
+#if wxUSE_THREADS
+ if (g_numberOfThreads)
+ {
+ sleepTime = kEventDurationNoWait;
+ }
+ else
+#endif // wxUSE_THREADS
+ {
+ sleepTime = kEventDurationSecond;
+ }
+ }
+ }
+ if ( event.what != kHighLevelEvent )
+ SetRectRgn( (RgnHandle) s_macCursorRgn , event.where.h , event.where.v , event.where.h + 1 , event.where.v + 1 ) ;
+#endif
+ // repeaters
+
+ DeletePendingObjects() ;
+ wxMacProcessNotifierAndPendingEvents() ;
+}
+
+/*virtual*/ void wxApp::MacHandleUnhandledEvent( WXEVENTREF evr )
+{
+ // Override to process unhandled events as you please
+}
+
+void wxApp::MacHandleOneEvent( WXEVENTREF evr )
+{
+#if TARGET_CARBON
+ EventTargetRef theTarget;
+ theTarget = GetEventDispatcherTarget();
+ m_macCurrentEvent = evr ;
+ OSStatus status = SendEventToEventTarget ((EventRef) evr , theTarget);
+ if(status == eventNotHandledErr)
+ {
+ MacHandleUnhandledEvent(evr);
+ }
+#else
+ EventRecord* ev = (EventRecord*) evr ;
+ m_macCurrentEvent = ev ;
+
+ wxApp::sm_lastMessageTime = ev->when ;
+
+ switch (ev->what)
+ {
+ case mouseDown:
+ MacHandleMouseDownEvent( ev ) ;
+ if ( ev->modifiers & controlKey )
+ s_lastMouseDown = 2;
+ else
+ s_lastMouseDown = 1;
+ break;
+ case mouseUp:
+ if ( s_lastMouseDown == 2 )
+ {
+ ev->modifiers |= controlKey ;
+ }
+ else
+ {
+ ev->modifiers &= ~controlKey ;
+ }
+ MacHandleMouseUpEvent( ev ) ;
+ s_lastMouseDown = 0;
+ break;
+ case activateEvt:
+ MacHandleActivateEvent( ev ) ;
+ break;
+ case updateEvt:
+ // In embedded mode we first let the UnhandledEvent function
+ // try to handle the update event. If we handle it ourselves
+ // first and then pass it on, the host's windows won't update.
+ MacHandleUnhandledEvent(ev);
+ MacHandleUpdateEvent( ev ) ;
+ break;
+ case keyDown:
+ case autoKey:
+ MacHandleKeyDownEvent( ev ) ;
+ break;
+ case keyUp:
+ MacHandleKeyUpEvent( ev ) ;
+ break;
+ case diskEvt:
+ MacHandleDiskEvent( ev ) ;
+ break;
+ case osEvt:
+ MacHandleOSEvent( ev ) ;
+ break;
+ case kHighLevelEvent:
+ MacHandleHighLevelEvent( ev ) ;
+ break;
+ default:
+ break;
+ }
+#endif
+ wxMacProcessNotifierAndPendingEvents() ;
+}
+
+#if !TARGET_CARBON
+bool s_macIsInModalLoop = false ;
+
+void wxApp::MacHandleModifierEvents( WXEVENTREF evr )
+{
+ EventRecord* ev = (EventRecord*) evr ;
+ if ( ev->modifiers != s_lastModifiers && wxWindow::FindFocus() != NULL )
+ {
+ wxKeyEvent event(wxEVT_KEY_DOWN);
+
+ event.m_shiftDown = ev->modifiers & shiftKey;
+ event.m_controlDown = ev->modifiers & controlKey;
+ event.m_altDown = ev->modifiers & optionKey;
+ event.m_metaDown = ev->modifiers & cmdKey;
+
+ event.m_x = ev->where.h;
+ event.m_y = ev->where.v;
+ event.m_timeStamp = ev->when;
+ wxWindow* focus = wxWindow::FindFocus() ;
+ event.SetEventObject(focus);
+
+ if ( (ev->modifiers ^ s_lastModifiers ) & controlKey )
+ {
+ event.m_keyCode = WXK_CONTROL ;
+ event.SetEventType( ( ev->modifiers & controlKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
+ focus->GetEventHandler()->ProcessEvent( event ) ;
+ }
+ if ( (ev->modifiers ^ s_lastModifiers ) & shiftKey )
+ {
+ event.m_keyCode = WXK_SHIFT ;
+ event.SetEventType( ( ev->modifiers & shiftKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
+ focus->GetEventHandler()->ProcessEvent( event ) ;
+ }
+ if ( (ev->modifiers ^ s_lastModifiers ) & optionKey )
+ {
+ event.m_keyCode = WXK_ALT ;
+ event.SetEventType( ( ev->modifiers & optionKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
+ focus->GetEventHandler()->ProcessEvent( event ) ;
+ }
+ if ( ( ev->modifiers ^ s_lastModifiers ) & cmdKey )
+ {
+ event.m_keyCode = WXK_COMMAND ;
+ event.SetEventType( ( ev->modifiers & cmdKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
+ focus->GetEventHandler()->ProcessEvent( event ) ;
+ }
+ s_lastModifiers = ev->modifiers ;
+ }
+}
+
+void wxApp::MacHandleHighLevelEvent( WXEVENTREF evr )
+{
+ // we must avoid reentrancy problems when processing high level events eg printing
+ bool former = s_inYield ;
+ s_inYield = TRUE ;
+ EventRecord* ev = (EventRecord*) evr ;
+ ::AEProcessAppleEvent( ev ) ;
+ s_inYield = former ;
+}
+
+void wxApp::MacHandleMouseDownEvent( WXEVENTREF evr )
+{
+ EventRecord* ev = (EventRecord*) evr ;
+ wxToolTip::RemoveToolTips() ;
+
+ WindowRef window;
+ WindowRef frontWindow = ::FrontNonFloatingWindow() ;
+ WindowAttributes frontWindowAttributes = NULL ;
+ if ( frontWindow )
+ ::GetWindowAttributes( frontWindow , &frontWindowAttributes ) ;
+
+ short windowPart = ::FindWindow(ev->where, &window);
+ wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ;
+ if ( wxPendingDelete.Member(win) )
+ return ;
+
+ BitMap screenBits;
+ GetQDGlobalsScreenBits( &screenBits );
+
+ switch (windowPart)
+ {
+ case inMenuBar :
+ if ( s_macIsInModalLoop )
+ {
+ SysBeep ( 30 ) ;
+ }
+ else
+ {
+ UInt32 menuresult = MenuSelect(ev->where) ;
+ MacHandleMenuSelect( HiWord( menuresult ) , LoWord( menuresult ) );
+ s_lastMouseDown = 0;
+ }
+ break ;
+ case inSysWindow :
+ SystemClick( ev , window ) ;
+ s_lastMouseDown = 0;
+ break ;
+ case inDrag :
+ if ( window != frontWindow && s_macIsInModalLoop && !(ev->modifiers & cmdKey ) )
+ {
+ SysBeep ( 30 ) ;
+ }
+ else
+ {
+ DragWindow(window, ev->where, &screenBits.bounds);
+ if (win)
+ {
+ GrafPtr port ;
+ GetPort( &port ) ;
+ Point pt = { 0, 0 } ;
+ SetPortWindowPort(window) ;
+ LocalToGlobal( &pt ) ;
+ SetPort( port ) ;
+ win->SetSize( pt.h , pt.v , -1 ,
+ -1 , wxSIZE_USE_EXISTING);
+ }
+ s_lastMouseDown = 0;
+ }
+ break ;
+ case inGoAway:
+ if (TrackGoAway(window, ev->where))
+ {
+ if ( win )
+ win->Close() ;
+ }
+ s_lastMouseDown = 0;
+ break;
+ case inGrow:
+ {
+ Rect newContentRect ;
+ Rect constraintRect ;
+ constraintRect.top = win->GetMinHeight() ;
+ if ( constraintRect.top == -1 )
+ constraintRect.top = 0 ;
+ constraintRect.left = win->GetMinWidth() ;
+ if ( constraintRect.left == -1 )
+ constraintRect.left = 0 ;
+ constraintRect.right = win->GetMaxWidth() ;
+ if ( constraintRect.right == -1 )
+ constraintRect.right = 32000 ;
+ constraintRect.bottom = win->GetMaxHeight() ;
+ if ( constraintRect.bottom == -1 )
+ constraintRect.bottom = 32000 ;
+
+ Boolean growResult = ResizeWindow( window , ev->where ,
+ &constraintRect , &newContentRect ) ;
+ if ( growResult )
+ {
+ win->SetSize( newContentRect.left , newContentRect.top ,
+ newContentRect.right - newContentRect.left ,
+ newContentRect.bottom - newContentRect.top, wxSIZE_USE_EXISTING);
+ }
+ s_lastMouseDown = 0;
+ }
+ break;
+ case inZoomIn:
+ case inZoomOut:
+ if (TrackBox(window, ev->where, windowPart))
+ {
+ // TODO setup size event
+ ZoomWindow( window , windowPart , false ) ;
+ if (win)
+ {
+ Rect tempRect ;
+ GrafPtr port ;
+ GetPort( &port ) ;
+ Point pt = { 0, 0 } ;
+ SetPortWindowPort(window) ;
+ LocalToGlobal( &pt ) ;
+ SetPort( port ) ;
+
+ GetWindowPortBounds(window, &tempRect ) ;
+ win->SetSize( pt.h , pt.v , tempRect.right-tempRect.left ,
+ tempRect.bottom-tempRect.top, wxSIZE_USE_EXISTING);
+ }
+ }
+ s_lastMouseDown = 0;
+ break;
+ case inCollapseBox :
+ // TODO setup size event
+ s_lastMouseDown = 0;
+ break ;
+
+ case inContent :
+ {
+ GrafPtr port ;
+ GetPort( &port ) ;
+ SetPortWindowPort(window) ;
+ SetPort( port ) ;
+ }
+ if ( window != frontWindow && wxTheApp->s_captureWindow == NULL )
+ {
+ if ( s_macIsInModalLoop )
+ {
+ SysBeep ( 30 ) ;
+ }
+ else if ( UMAIsWindowFloating( window ) )
+ {
+ if ( win )
+ win->MacMouseDown( ev , windowPart ) ;
+ }
+ else
+ {
+ // Activate window first
+ ::SelectWindow( window ) ;
+
+ // Send event later
+ if ( win )
+ win->MacMouseDown( ev , windowPart ) ;
+ }
+ }
+ else
+ {
+ if ( win )
+ win->MacMouseDown( ev , windowPart ) ;
+ }
+ break ;
+ default:
+ break;
+ }
+}
+
+void wxApp::MacHandleMouseUpEvent( WXEVENTREF evr )
+{
+ EventRecord* ev = (EventRecord*) evr ;
+ WindowRef window;
+
+ short windowPart = inNoWindow ;
+ if ( wxTheApp->s_captureWindow )
+ {
+ window = (WindowRef) s_captureWindow->MacGetRootWindow() ;
+ windowPart = inContent ;
+ }
+ else
+ {
+ windowPart = ::FindWindow(ev->where, &window) ;
+ }
+
+ switch (windowPart)
+ {
+ case inMenuBar :
+ break ;
+ case inSysWindow :
+ break ;
+ default:
+ {
+ wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ;
+ if ( win )
+ win->MacMouseUp( ev , windowPart ) ;
+ }
+ break;
+ }
+}
+
+#endif
+
+long wxMacTranslateKey(unsigned char key, unsigned char code) ;
+long wxMacTranslateKey(unsigned char key, unsigned char code)
+{
+ long retval = key ;
+ switch (key)
+ {
+ case kHomeCharCode :
+ retval = WXK_HOME;
+ break;
+ case kEnterCharCode :
+ retval = WXK_RETURN;
+ break;
+ case kEndCharCode :
+ retval = WXK_END;
+ break;
+ case kHelpCharCode :
+ retval = WXK_HELP;
+ break;
+ case kBackspaceCharCode :
+ retval = WXK_BACK;
+ break;
+ case kTabCharCode :
+ retval = WXK_TAB;
+ break;
+ case kPageUpCharCode :
+ retval = WXK_PAGEUP;
+ break;
+ case kPageDownCharCode :
+ retval = WXK_PAGEDOWN;
+ break;
+ case kReturnCharCode :
+ retval = WXK_RETURN;
+ break;
+ case kFunctionKeyCharCode :
+ {
+ switch( code )
+ {
+ case 0x7a :
+ retval = WXK_F1 ;
+ break;
+ case 0x78 :
+ retval = WXK_F2 ;
+ break;
+ case 0x63 :
+ retval = WXK_F3 ;
+ break;
+ case 0x76 :
+ retval = WXK_F4 ;
+ break;
+ case 0x60 :
+ retval = WXK_F5 ;
+ break;
+ case 0x61 :
+ retval = WXK_F6 ;
+ break;
+ case 0x62:
+ retval = WXK_F7 ;
+ break;
+ case 0x64 :
+ retval = WXK_F8 ;
+ break;
+ case 0x65 :
+ retval = WXK_F9 ;
+ break;
+ case 0x6D :
+ retval = WXK_F10 ;
+ break;
+ case 0x67 :
+ retval = WXK_F11 ;
+ break;
+ case 0x6F :
+ retval = WXK_F12 ;
+ break;
+ case 0x69 :
+ retval = WXK_F13 ;
+ break;
+ case 0x6B :
+ retval = WXK_F14 ;
+ break;
+ case 0x71 :
+ retval = WXK_F15 ;
+ break;
+ }
+ }
+ break ;
+ case kEscapeCharCode :
+ retval = WXK_ESCAPE ;
+ break ;
+ case kLeftArrowCharCode :
+ retval = WXK_LEFT ;
+ break ;
+ case kRightArrowCharCode :
+ retval = WXK_RIGHT ;
+ break ;
+ case kUpArrowCharCode :
+ retval = WXK_UP ;
+ break ;
+ case kDownArrowCharCode :
+ retval = WXK_DOWN ;
+ break ;
+ case kDeleteCharCode :
+ retval = WXK_DELETE ;
+ default:
+ break ;
+ } // end switch
+
+ return retval;
+}
+
+int wxKeyCodeToMacModifier(wxKeyCode key)
+{
+ switch (key)
+ {
+ case WXK_START:
+ case WXK_MENU:
+ return cmdKey;
+
+ case WXK_SHIFT:
+ return shiftKey;
+
+ case WXK_CAPITAL:
+ return alphaLock;
+
+ case WXK_ALT:
+ return optionKey;
+
+ case WXK_CONTROL:
+ return controlKey;
+
+ default:
+ return 0;
+ }
+}
+
+bool wxGetKeyState(wxKeyCode key) //virtual key code if < 10.2.x, else see below
+{
+//#ifdef __DARWIN__
+// wxHIDKeyboard keyboard;
+// return keyboard.IsActive(key);
+//#else
+// TODO: Have it use HID Manager on OSX...
+//if OS X > 10.2 (i.e. 10.2.x)
+//a known apple bug prevents the system from determining led
+//states with GetKeys... can only determine caps lock led
+ return !!(GetCurrentKeyModifiers() & wxKeyCodeToMacModifier(key));
+//else
+// KeyMapByteArray keymap;
+// GetKeys((BigEndianLong*)keymap);
+// return !!(BitTst(keymap, (sizeof(KeyMapByteArray)*8) - iKey));
+//#endif
+}
+
+#if !TARGET_CARBON
+void wxApp::MacHandleKeyDownEvent( WXEVENTREF evr )
+{
+ EventRecord* ev = (EventRecord*) evr ;
+ wxToolTip::RemoveToolTips() ;
+
+ UInt32 menuresult = UMAMenuEvent(ev) ;
+ if ( HiWord( menuresult ) )
+ {
+ if ( !s_macIsInModalLoop )
+ MacHandleMenuSelect( HiWord( menuresult ) , LoWord( menuresult ) ) ;
+ }
+ else
+ {
+ wxWindow* focus = wxWindow::FindFocus() ;
+
+ if ( MacSendKeyDownEvent( focus , ev->message , ev->modifiers , ev->when , ev->where.h , ev->where.v ) == false )
+ {
+#if 0
+ // we must handle control keys the other way round, otherwise text content is updated too late
+ // has not been handled -> perform default
+ wxControl* control = wxDynamicCast( focus , wxControl ) ;
+ if ( control && control->GetMacControl() != NULL )
+ {
+ short keycode ;
+ short keychar ;
+ keychar = short(ev->message & charCodeMask);
+ keycode = short(ev->message & keyCodeMask) >> 8 ;
+ ::HandleControlKey( (ControlHandle) control->GetMacControl() , keycode , keychar , ev->modifiers ) ;
+ }
+#endif
+ }
+ }
+}
+
+void wxApp::MacHandleKeyUpEvent( WXEVENTREF evr )
+{
+ EventRecord* ev = (EventRecord*) evr ;
+ wxToolTip::RemoveToolTips() ;
+
+ UInt32 menuresult = UMAMenuEvent(ev) ;
+ if ( HiWord( menuresult ) )
+ {
+ }
+ else
+ {
+ MacSendKeyUpEvent( wxWindow::FindFocus() , ev->message , ev->modifiers , ev->when , ev->where.h , ev->where.v ) ;
+ }
+}
+
+#endif
+
+bool wxApp::MacSendKeyDownEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey )
+{
+ if ( !focus )
+ return false ;
+
+ short keycode ;
+ short keychar ;
+ keychar = short(keymessage & charCodeMask);
+ keycode = short(keymessage & keyCodeMask) >> 8 ;
+
+ if ( modifiers & ( controlKey|shiftKey|optionKey ) )
+ {
+ // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier
+ // and look at the character after
+ UInt32 state = 0;
+ UInt32 keyInfo = KeyTranslate((Ptr)GetScriptManagerVariable(smKCHRCache), ( modifiers & (~(controlKey|shiftKey|optionKey))) | keycode, &state);
+ keychar = short(keyInfo & charCodeMask);
+ keycode = short(keyInfo & keyCodeMask) >> 8 ;
+ }
+ long keyval = wxMacTranslateKey(keychar, keycode) ;
+ long realkeyval = keyval ;
+ if ( keyval == keychar )
+ {
+ // we are not on a special character combo -> pass the real os event-value to EVT_CHAR, but not to EVT_KEY (make upper first)
+ realkeyval = short(keymessage & charCodeMask) ;
+ keyval = wxToupper( keyval ) ;
+ }
+
+ wxKeyEvent event(wxEVT_KEY_DOWN);
+ bool handled = false ;
+ event.m_shiftDown = modifiers & shiftKey;
+ event.m_controlDown = modifiers & controlKey;
+ event.m_altDown = modifiers & optionKey;
+ event.m_metaDown = modifiers & cmdKey;
+ event.m_keyCode = keyval ;
+
+ event.m_x = wherex;
+ event.m_y = wherey;
+ event.m_timeStamp = when;
+ event.SetEventObject(focus);
+ handled = focus->GetEventHandler()->ProcessEvent( event ) ;
+ if ( handled && event.GetSkipped() )
+ handled = false ;
+ if ( !handled )
+ {
+#if wxUSE_ACCEL
+ if (!handled)
+ {
+ wxWindow *ancestor = focus;
+ while (ancestor)
+ {
+ int command = ancestor->GetAcceleratorTable()->GetCommand( event );
+ if (command != -1)
+ {
+ wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command );
+ handled = ancestor->GetEventHandler()->ProcessEvent( command_event );
+ break;
+ }
+ if (ancestor->IsTopLevel())
+ break;
+ ancestor = ancestor->GetParent();
+ }
+ }
+#endif // wxUSE_ACCEL
+ }
+ if (!handled)
+ {
+ event.Skip( FALSE ) ;
+ event.SetEventType( wxEVT_CHAR ) ;
+ // raw value again
+ event.m_keyCode = realkeyval ;
+
+ handled = focus->GetEventHandler()->ProcessEvent( event ) ;
+ if ( handled && event.GetSkipped() )
+ handled = false ;
+ }
+ if ( !handled &&
+ (keyval == WXK_TAB) &&
+// CS: copied the change below from wxGTK
+// VZ: testing for wxTE_PROCESS_TAB shouldn't be done here the control may
+// have this style, yet choose not to process this particular TAB in which
+// case TAB must still work as a navigational character
+#if 0
+ (!focus->HasFlag(wxTE_PROCESS_TAB)) &&
+#endif
+ (focus->GetParent()) &&
+ (focus->GetParent()->HasFlag( wxTAB_TRAVERSAL)) )
+ {
+ wxNavigationKeyEvent new_event;
+ new_event.SetEventObject( focus );
+ new_event.SetDirection( !event.ShiftDown() );
+ /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
+ new_event.SetWindowChange( event.ControlDown() );
+ new_event.SetCurrentFocus( focus );
+ handled = focus->GetEventHandler()->ProcessEvent( new_event );
+ if ( handled && new_event.GetSkipped() )
+ handled = false ;
+ }
+ // backdoor handler for default return and command escape
+ if ( !handled && (!focus->IsKindOf(CLASSINFO(wxControl) ) || !focus->MacCanFocus() ) )
+ {
+ // if window is not having a focus still testing for default enter or cancel
+ // TODO add the UMA version for ActiveNonFloatingWindow
+ wxWindow* focus = wxFindWinFromMacWindow( FrontWindow() ) ;
+ if ( focus )
+ {
+ if ( keyval == WXK_RETURN )
+ {
+ wxButton *def = wxDynamicCast(focus->GetDefaultItem(),
+ wxButton);
+ if ( def && def->IsEnabled() )
+ {
+ wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() );
+ event.SetEventObject(def);
+ def->Command(event);
+ return true ;
+ }
+ }
+ /* generate wxID_CANCEL if command-. or <esc> has been pressed (typically in dialogs) */
+ else if (keyval == WXK_ESCAPE || (keyval == '.' && modifiers & cmdKey ) )
+ {
+ wxCommandEvent new_event(wxEVT_COMMAND_BUTTON_CLICKED,wxID_CANCEL);
+ new_event.SetEventObject( focus );
+ handled = focus->GetEventHandler()->ProcessEvent( new_event );
+ }
+ }
+ }
+ return handled ;
+}
+
+bool wxApp::MacSendKeyUpEvent( wxWindow* focus , long keymessage , long modifiers , long when , short wherex , short wherey )
+{
+ if ( !focus )
+ return false ;
+
+ short keycode ;
+ short keychar ;
+ keychar = short(keymessage & charCodeMask);
+ keycode = short(keymessage & keyCodeMask) >> 8 ;
+ if ( modifiers & ( controlKey|shiftKey|optionKey ) )
+ {
+ // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier
+ // and look at the character after
+ UInt32 state = 0;
+ UInt32 keyInfo = KeyTranslate((Ptr)GetScriptManagerVariable(smKCHRCache), ( modifiers & (~(controlKey|shiftKey|optionKey))) | keycode, &state);
+ keychar = short(keyInfo & charCodeMask);
+ keycode = short(keyInfo & keyCodeMask) >> 8 ;
+ }
+ long keyval = wxMacTranslateKey(keychar, keycode) ;
+
+ if ( keyval == keychar )
+ {
+ keyval = wxToupper( keyval ) ;
+ }
+ bool handled = false ;
+
+ wxKeyEvent event(wxEVT_KEY_UP);
+ event.m_shiftDown = modifiers & shiftKey;
+ event.m_controlDown = modifiers & controlKey;
+ event.m_altDown = modifiers & optionKey;
+ event.m_metaDown = modifiers & cmdKey;
+ event.m_keyCode = keyval ;
+
+ event.m_x = wherex;
+ event.m_y = wherey;
+ event.m_timeStamp = when;
+ event.SetEventObject(focus);
+ handled = focus->GetEventHandler()->ProcessEvent( event ) ;
+
+ return handled ;
+}
+
+#if !TARGET_CARBON
+void wxApp::MacHandleActivateEvent( WXEVENTREF evr )
+{
+ EventRecord* ev = (EventRecord*) evr ;
+ WindowRef window = (WindowRef) ev->message ;
+ if ( window )
+ {
+ bool activate = (ev->modifiers & activeFlag ) ;
+ WindowClass wclass ;
+ ::GetWindowClass ( window , &wclass ) ;
+ if ( wclass == kFloatingWindowClass )
+ {
+ // if it is a floater we activate/deactivate the front non-floating window instead
+ window = ::FrontNonFloatingWindow() ;
+ }
+ wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ;
+ if ( win )
+ win->MacActivate( ev->when , activate ) ;
+ }
+}
+
+void wxApp::MacHandleUpdateEvent( WXEVENTREF evr )
+{
+ EventRecord* ev = (EventRecord*) evr ;
+ WindowRef window = (WindowRef) ev->message ;
+ wxTopLevelWindowMac * win = wxFindWinFromMacWindow( window ) ;
+ if ( win )
+ {
+ if ( !wxPendingDelete.Member(win) )
+ win->MacUpdate( ev->when ) ;
+ }
+ else
+ {
+ // since there is no way of telling this foreign window to update itself
+ // we have to invalidate the update region otherwise we keep getting the same
+ // event over and over again
+ BeginUpdate( window ) ;
+ EndUpdate( window ) ;
+ }
+}
+
+void wxApp::MacHandleDiskEvent( WXEVENTREF evr )
+{
+ EventRecord* ev = (EventRecord*) evr ;
+ if ( HiWord( ev->message ) != noErr )
+ {
+ OSErr err ;
+ Point point ;
+ SetPt( &point , 100 , 100 ) ;
+
+ err = DIBadMount( point , ev->message ) ;
+ wxASSERT( err == noErr ) ;
+ }
+}
+
+void wxApp::MacHandleOSEvent( WXEVENTREF evr )
+{
+ EventRecord* ev = (EventRecord*) evr ;
+ switch( ( ev->message & osEvtMessageMask ) >> 24 )
+ {
+ case suspendResumeMessage :
+ {
+ bool isResuming = ev->message & resumeFlag ;
+ bool convertClipboard = ev->message & convertClipboardFlag ;
+
+ bool doesActivate = UMAGetProcessModeDoesActivateOnFGSwitch() ;
+ if ( isResuming )
+ {
+ WindowRef oldFrontWindow = NULL ;
+ WindowRef newFrontWindow = NULL ;
+
+ // in case we don't take care of activating ourselves, we have to synchronize
+ // our idea of the active window with the process manager's - which it already activated
+
+ if ( !doesActivate )
+ oldFrontWindow = ::FrontNonFloatingWindow() ;
+
+ MacResume( convertClipboard ) ;
+
+ newFrontWindow = ::FrontNonFloatingWindow() ;
+
+ if ( oldFrontWindow )
+ {
+ wxTopLevelWindowMac* win = wxFindWinFromMacWindow( oldFrontWindow ) ;
+ if ( win )
+ win->MacActivate( ev->when , false ) ;
+ }
+ if ( newFrontWindow )
+ {
+ wxTopLevelWindowMac* win = wxFindWinFromMacWindow( newFrontWindow ) ;
+ if ( win )
+ win->MacActivate( ev->when , true ) ;
+ }
+ }
+ else
+ {
+ MacSuspend( convertClipboard ) ;
+ }
+ }
+ break ;
+ case mouseMovedMessage :
+ {
+ WindowRef window;
+
+ wxWindow* currentMouseWindow = NULL ;
+
+ if (s_captureWindow )
+ {
+ currentMouseWindow = s_captureWindow ;
+ }
+ else
+ {
+ wxWindow::MacGetWindowFromPoint( wxPoint( ev->where.h , ev->where.v ) ,
+ ¤tMouseWindow ) ;
+ }
+
+ if ( currentMouseWindow != wxWindow::s_lastMouseWindow )
+ {
+ wxMouseEvent event ;
+
+ bool isDown = !(ev->modifiers & btnState) ; // 1 is for up
+ bool controlDown = ev->modifiers & controlKey ; // for simulating right mouse
+
+ event.m_leftDown = isDown && !controlDown;
+ event.m_middleDown = FALSE;
+ event.m_rightDown = isDown && controlDown;
+ event.m_shiftDown = ev->modifiers & shiftKey;
+ event.m_controlDown = ev->modifiers & controlKey;
+ event.m_altDown = ev->modifiers & optionKey;
+ event.m_metaDown = ev->modifiers & cmdKey;
+ event.m_x = ev->where.h;
+ event.m_y = ev->where.v;
+ event.m_timeStamp = ev->when;
+ event.SetEventObject(this);
+
+ if ( wxWindow::s_lastMouseWindow )
+ {
+ wxMouseEvent eventleave(event);
+ eventleave.SetEventType( wxEVT_LEAVE_WINDOW );
+ wxWindow::s_lastMouseWindow->ScreenToClient( &eventleave.m_x, &eventleave.m_y );
+ eventleave.SetEventObject( wxWindow::s_lastMouseWindow ) ;
+
+ wxWindow::s_lastMouseWindow->GetEventHandler()->ProcessEvent(eventleave);
+ }
+ if ( currentMouseWindow )
+ {
+ wxMouseEvent evententer(event);
+ evententer.SetEventType( wxEVT_ENTER_WINDOW );
+ currentMouseWindow->ScreenToClient( &evententer.m_x, &evententer.m_y );
+ evententer.SetEventObject( currentMouseWindow ) ;
+ currentMouseWindow->GetEventHandler()->ProcessEvent(evententer);
+ }
+ wxWindow::s_lastMouseWindow = currentMouseWindow ;
+ }
+
+ short windowPart = inNoWindow ;
+
+ if ( s_captureWindow )
+ {
+ window = (WindowRef) s_captureWindow->MacGetRootWindow() ;
+ windowPart = inContent ;
+ }
+ else
+ {
+ windowPart = ::FindWindow(ev->where, &window);
+ }
+
+ switch (windowPart)
+ {
+ case inContent :
+ {
+ wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ;
+ if ( win )
+ win->MacMouseMoved( ev , windowPart ) ;
+ else
+ {
+ if ( wxIsBusy() )
+ {
+ }
+ else
+ UMAShowArrowCursor();
+ }
+ }
+ break;
+ default :
+ {
+ if ( wxIsBusy() )
+ {
+ }
+ else
+ UMAShowArrowCursor();
+ }
+ break ;
+ }
+ }
+ break ;
+
+ }
+}
+#else
+
+void wxApp::MacHandleMouseMovedEvent(wxInt32 x , wxInt32 y ,wxUint32 modifiers , long timestamp)
+{
+ WindowRef window;
+
+ wxWindow* currentMouseWindow = NULL ;
+
+ if (s_captureWindow )
+ {
+ currentMouseWindow = s_captureWindow ;
+ }
+ else
+ {
+ wxWindow::MacGetWindowFromPoint( wxPoint( x, y ) , ¤tMouseWindow ) ;
+ }
+
+ if ( currentMouseWindow != wxWindow::s_lastMouseWindow )
+ {
+ wxMouseEvent event ;
+
+ bool isDown = !(modifiers & btnState) ; // 1 is for up
+ bool controlDown = modifiers & controlKey ; // for simulating right mouse
+
+ event.m_leftDown = isDown && !controlDown;
+
+ event.m_middleDown = FALSE;
+ event.m_rightDown = isDown && controlDown;
+
+ event.m_shiftDown = modifiers & shiftKey;
+ event.m_controlDown = modifiers & controlKey;
+ event.m_altDown = modifiers & optionKey;
+ event.m_metaDown = modifiers & cmdKey;
+
+ event.m_x = x;
+ event.m_y = y;
+ event.m_timeStamp = timestamp;
+
+ if ( wxWindow::s_lastMouseWindow )
+ {
+ wxMouseEvent eventleave(event);
+ eventleave.SetEventType( wxEVT_LEAVE_WINDOW );
+ wxWindow::s_lastMouseWindow->ScreenToClient( &eventleave.m_x, &eventleave.m_y );
+ eventleave.SetEventObject( wxWindow::s_lastMouseWindow ) ;
+
+#if wxUSE_TOOLTIPS
+ wxToolTip::RelayEvent( wxWindow::s_lastMouseWindow , eventleave);
+#endif // wxUSE_TOOLTIPS
+ wxWindow::s_lastMouseWindow->GetEventHandler()->ProcessEvent(eventleave);
+ }
+ if ( currentMouseWindow )
+ {
+ wxMouseEvent evententer(event);
+ evententer.SetEventType( wxEVT_ENTER_WINDOW );
+ currentMouseWindow->ScreenToClient( &evententer.m_x, &evententer.m_y );
+ evententer.SetEventObject( currentMouseWindow ) ;
+#if wxUSE_TOOLTIPS
+ wxToolTip::RelayEvent( currentMouseWindow , evententer);
+#endif // wxUSE_TOOLTIPS
+ currentMouseWindow->GetEventHandler()->ProcessEvent(evententer);
+ }
+ wxWindow::s_lastMouseWindow = currentMouseWindow ;
+ }
+
+ short windowPart = inNoWindow ;
+
+ if ( s_captureWindow )
+ {
+ window = (WindowRef) s_captureWindow->MacGetRootWindow() ;
+ windowPart = inContent ;
+ }
+ else
+ {
+ Point pt= { y , x } ;
+ windowPart = ::FindWindow(pt , &window);
+ }
+
+ switch (windowPart)
+ {
+ case inContent :
+ {
+ wxTopLevelWindowMac* win = wxFindWinFromMacWindow( window ) ;
+ if ( win )
+ win->MacFireMouseEvent( nullEvent , x , y , modifiers , timestamp ) ;
+ else
+ {
+ if ( wxIsBusy() )
+ {
+ }
+ else
+ UMAShowArrowCursor();
+ }
+ }
+ break;
+ default :
+ {
+ if ( wxIsBusy() )
+ {
+ }
+ else
+ UMAShowArrowCursor();
+ }
+ break ;
+ }
+}
+#endif
+
+void wxApp::MacHandleMenuCommand( wxUint32 id )
+{
+ wxMenuBar* mbar = wxMenuBar::MacGetInstalledMenuBar() ;
+ wxFrame* frame = mbar->GetFrame();
+ wxCHECK_RET( mbar != NULL && frame != NULL, wxT("error in menu item callback") );
+ if ( frame )
+ {
+ frame->ProcessCommand(id);
+ }
+}
+
+#if !TARGET_CARBON
+void wxApp::MacHandleMenuSelect( int macMenuId , int macMenuItemNum )
+{
+ if (macMenuId == 0)
+ return; // no menu item selected
+
+ if (macMenuId == kwxMacAppleMenuId && macMenuItemNum > 1)
+ {
+ #if ! TARGET_CARBON
+ Str255 deskAccessoryName ;
+ GrafPtr savedPort ;
+
+ GetMenuItemText(GetMenuHandle(kwxMacAppleMenuId), macMenuItemNum, deskAccessoryName);
+ GetPort(&savedPort);
+ OpenDeskAcc(deskAccessoryName);
+ SetPort(savedPort);
+ #endif
+ }
+ else
+ {
+ MenuCommand id ;
+ GetMenuItemCommandID( GetMenuHandle(macMenuId) , macMenuItemNum , &id ) ;
+ MacHandleMenuCommand( id ) ;
+ }
+ HiliteMenu(0);
+}
+#endif
--- /dev/null
+#define kMacSTRWrongMachine 1
+#define kMacSTRSmallSize 2
+#define kMacSTRNoMemory 3
+#define kMacSTROldSystem 4
+#define kMacSTRGenericAbout 5
+#define kMacSTRNoPre8Yet 6
--- /dev/null
+#ifdef __UNIX__
+# include <Carbon.r>
+#else
+# include <Types.r>
+#endif
+#include "apprsrc.h"
+
+resource 'STR#' ( 128 , "Simple Alert Messages" )
+{
+ {
+ "This application needs at least a MacPlus" ,
+ "This application needs more memory" ,
+ "This application is out of memory" ,
+ "This application needs at least System 8.6" ,
+ "About this wxWindows Application" ,
+ "This application needs Appearance extension (built in with System 8) - this restriction will be relieved in the final release"
+ }
+} ;
+
+resource 'MENU' (1, preload)
+{
+ 1, textMenuProc, 0b11111111111111111111111111111110 , enabled, apple ,
+ {
+ "AboutÉ" , noicon, nokey,nomark,plain ,
+ "-" , noicon, nokey,nomark,plain
+ }
+} ;
+
+resource 'MBAR' (1,preload)
+{
+ { 1 } ;
+} ;
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: bitmap.cpp
+// Purpose: wxBitmap
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "bitmap.h"
+#endif
+
+#include "wx/defs.h"
+
+#include "wx/bitmap.h"
+#include "wx/icon.h"
+#include "wx/log.h"
+#include "wx/image.h"
+#include "wx/xpmdecod.h"
+
+#include "wx/rawbmp.h"
+
+IMPLEMENT_DYNAMIC_CLASS(wxBitmap, wxGDIObject)
+IMPLEMENT_DYNAMIC_CLASS(wxMask, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxBitmapHandler, wxObject )
+
+#ifdef __DARWIN__
+ #include <ApplicationServices/ApplicationServices.h>
+#else
+ #include <PictUtils.h>
+#endif
+
+#include "wx/mac/uma.h"
+
+CTabHandle wxMacCreateColorTable( int numColors )
+{
+ CTabHandle newColors; /* Handle to the new color table */
+
+ /* Allocate memory for the color table */
+ newColors = (CTabHandle)NewHandleClear( sizeof (ColorTable) +
+ sizeof (ColorSpec) * (numColors - 1) );
+ if (newColors != nil)
+ {
+ /* Initialize the fields */
+ (**newColors).ctSeed = GetCTSeed();
+ (**newColors).ctFlags = 0;
+ (**newColors).ctSize = numColors - 1;
+ /* Initialize the table of colors */
+ }
+ return newColors ;
+}
+
+void wxMacDestroyColorTable( CTabHandle colors )
+{
+ DisposeHandle( (Handle) colors ) ;
+}
+
+void wxMacSetColorTableEntry( CTabHandle newColors , int index , int red , int green , int blue )
+{
+ (**newColors).ctTable[index].value = index;
+ (**newColors).ctTable[index].rgb.red = red ; // someRedValue;
+ (**newColors).ctTable[index].rgb.green = green ; // someGreenValue;
+ (**newColors).ctTable[index].rgb.blue = blue ; // someBlueValue;
+}
+
+GWorldPtr wxMacCreateGWorld( int width , int height , int depth )
+{
+ OSErr err = noErr ;
+ GWorldPtr port ;
+ Rect rect = { 0 , 0 , height , width } ;
+
+ if ( depth < 0 )
+ {
+ depth = wxDisplayDepth() ;
+ }
+
+ err = NewGWorld( &port , depth , &rect , NULL , NULL , 0 ) ;
+ if ( err == noErr )
+ {
+ return port ;
+ }
+ return NULL ;
+}
+
+void wxMacDestroyGWorld( GWorldPtr gw )
+{
+ if ( gw )
+ DisposeGWorld( gw ) ;
+}
+
+#define kDefaultRes 0x00480000 /* Default resolution is 72 DPI; Fixed type */
+
+OSErr SetupCIconHandlePixMap( CIconHandle icon , short depth , Rect *bounds , CTabHandle colors )
+{
+ CTabHandle newColors; /* Color table used for the off-screen PixMap */
+ Ptr offBaseAddr; /* Pointer to the off-screen pixel image */
+ OSErr error; /* Returns error code */
+ short bytesPerRow; /* Number of bytes per row in the PixMap */
+
+
+ error = noErr;
+ newColors = nil;
+ offBaseAddr = nil;
+
+ bytesPerRow = ((depth * (bounds->right - bounds->left) + 31) / 32) * 4;
+
+ /* Clone the clut if indexed color; allocate a dummy clut if direct color*/
+ if (depth <= 8)
+ {
+ newColors = colors;
+ error = HandToHand((Handle *) &newColors);
+ }
+ else
+ {
+ newColors = (CTabHandle) NewHandle(sizeof(ColorTable) -
+ sizeof(CSpecArray));
+ error = MemError();
+ }
+ if (error == noErr)
+ {
+ /* Allocate pixel image; long integer multiplication avoids overflow */
+ (**icon).iconData = NewHandle((unsigned long) bytesPerRow * (bounds->bottom -
+ bounds->top));
+ if ((**icon).iconData != nil)
+ {
+ /* Initialize fields common to indexed and direct PixMaps */
+ (**icon).iconPMap.baseAddr = 0; /* Point to image */
+ (**icon).iconPMap.rowBytes = bytesPerRow | /* MSB set for PixMap */
+ 0x8000;
+ (**icon).iconPMap.bounds = *bounds; /* Use given bounds */
+ (**icon).iconPMap.pmVersion = 0; /* No special stuff */
+ (**icon).iconPMap.packType = 0; /* Default PICT pack */
+ (**icon).iconPMap.packSize = 0; /* Always zero in mem */
+ (**icon).iconPMap.hRes = kDefaultRes; /* 72 DPI default res */
+ (**icon).iconPMap.vRes = kDefaultRes; /* 72 DPI default res */
+ (**icon).iconPMap.pixelSize = depth; /* Set # bits/pixel */
+
+ /* Initialize fields specific to indexed and direct PixMaps */
+ if (depth <= 8)
+ {
+ /* PixMap is indexed */
+ (**icon).iconPMap.pixelType = 0; /* Indicates indexed */
+ (**icon).iconPMap.cmpCount = 1; /* Have 1 component */
+ (**icon).iconPMap.cmpSize = depth; /* Component size=depth */
+ (**icon).iconPMap.pmTable = newColors; /* Handle to CLUT */
+ }
+ else
+ {
+ /* PixMap is direct */
+ (**icon).iconPMap.pixelType = RGBDirect; /* Indicates direct */
+ (**icon).iconPMap.cmpCount = 3; /* Have 3 components */
+ if (depth == 16)
+ (**icon).iconPMap.cmpSize = 5; /* 5 bits/component */
+ else
+ (**icon).iconPMap.cmpSize = 8; /* 8 bits/component */
+ (**newColors).ctSeed = 3 * (**icon).iconPMap.cmpSize;
+ (**newColors).ctFlags = 0;
+ (**newColors).ctSize = 0;
+ (**icon).iconPMap.pmTable = newColors;
+ }
+ }
+ else
+ error = MemError();
+ }
+ else
+ newColors = nil;
+
+ /* If no errors occured, return a handle to the new off-screen PixMap */
+ if (error != noErr)
+ {
+ if (newColors != nil)
+ DisposeCTable(newColors);
+ }
+
+ /* Return the error code */
+ return error;
+}
+
+CIconHandle wxMacCreateCIcon(GWorldPtr image , GWorldPtr mask , short dstDepth , short iconSize )
+{
+ GWorldPtr saveWorld;
+ GDHandle saveHandle;
+
+ GetGWorld(&saveWorld,&saveHandle); // save Graphics env state
+ SetGWorld(image,nil);
+
+ Rect frame = { 0 , 0 , iconSize , iconSize } ;
+ Rect imageBounds = frame ;
+ GetPortBounds( image , &imageBounds ) ;
+
+ int bwSize = iconSize / 8 * iconSize ;
+ CIconHandle icon = (CIconHandle) NewHandleClear( sizeof ( CIcon ) + 2 * bwSize) ;
+ HLock((Handle)icon) ;
+ SetupCIconHandlePixMap( icon , dstDepth , &frame,GetCTable(dstDepth)) ;
+ HLock( (**icon).iconData ) ;
+ (**icon).iconPMap.baseAddr = *(**icon).iconData ;
+
+ LockPixels(GetGWorldPixMap(image));
+
+ CopyBits(GetPortBitMapForCopyBits(image),
+ (BitMapPtr)&((**icon).iconPMap),
+ &imageBounds,
+ &imageBounds,
+ srcCopy | ditherCopy, nil);
+
+
+ UnlockPixels(GetGWorldPixMap(image));
+ HUnlock( (**icon).iconData ) ;
+
+ (**icon).iconMask.rowBytes = iconSize / 8 ;
+ (**icon).iconMask.bounds = frame ;
+
+ (**icon).iconBMap.rowBytes = iconSize / 8 ;
+ (**icon).iconBMap.bounds = frame ;
+ (**icon).iconMask.baseAddr = (char*) &(**icon).iconMaskData ;
+ (**icon).iconBMap.baseAddr = (char*) &(**icon).iconMaskData + bwSize ;
+
+ if ( mask )
+ {
+ Rect r ;
+ GetPortBounds( image , &r ) ;
+ LockPixels(GetGWorldPixMap(mask) ) ;
+ CopyBits(GetPortBitMapForCopyBits(mask) ,
+ &(**icon).iconBMap , &r , &r, srcCopy , nil ) ;
+ CopyBits(GetPortBitMapForCopyBits(mask) ,
+ &(**icon).iconMask , &r , &r, srcCopy , nil ) ;
+ UnlockPixels(GetGWorldPixMap( mask ) ) ;
+ }
+ else
+ {
+ Rect r ;
+ GetPortBounds( image , &r ) ;
+ LockPixels(GetGWorldPixMap(image));
+ CopyBits(GetPortBitMapForCopyBits(image) ,
+ &(**icon).iconBMap , &r , &r, srcCopy , nil ) ;
+ CopyBits(GetPortBitMapForCopyBits(image) ,
+ &(**icon).iconMask , &r , &r, srcCopy , nil ) ;
+ UnlockPixels(GetGWorldPixMap(image));
+ }
+
+ (**icon).iconMask.baseAddr = NULL ;
+ (**icon).iconBMap.baseAddr = NULL ;
+ (**icon).iconPMap.baseAddr = NULL ;
+ HUnlock((Handle)icon) ;
+ SetGWorld(saveWorld,saveHandle);
+
+ return icon;
+}
+
+PicHandle wxMacCreatePict(GWorldPtr wp, GWorldPtr mask)
+{
+ CGrafPtr origPort ;
+ GDHandle origDev ;
+
+ PicHandle pict;
+
+ RGBColor white = { 0xffff ,0xffff , 0xffff } ;
+ RGBColor black = { 0x0000 ,0x0000 , 0x0000 } ;
+
+ GetGWorld( &origPort , &origDev ) ;
+
+ RgnHandle clipRgn = NULL ;
+
+ if ( mask )
+ {
+ clipRgn = NewRgn() ;
+ LockPixels( GetGWorldPixMap( mask ) ) ;
+ BitMapToRegion( clipRgn , (BitMap*) *GetGWorldPixMap( mask ) ) ;
+ UnlockPixels( GetGWorldPixMap( mask ) ) ;
+ }
+
+ SetGWorld( wp , NULL ) ;
+ Rect portRect ;
+ if ( clipRgn )
+ GetRegionBounds( clipRgn , &portRect ) ;
+ else
+ GetPortBounds( wp , &portRect ) ;
+ pict = OpenPicture(&portRect);
+ if(pict)
+ {
+ RGBForeColor( &black ) ;
+ RGBBackColor( &white ) ;
+
+ if ( clipRgn )
+ SetClip( clipRgn ) ;
+
+ LockPixels( GetGWorldPixMap( wp ) ) ;
+ CopyBits(GetPortBitMapForCopyBits(wp),
+ GetPortBitMapForCopyBits(wp),
+ &portRect,
+ &portRect,
+ srcCopy,clipRgn);
+ UnlockPixels( GetGWorldPixMap( wp ) ) ;
+ ClosePicture();
+ }
+ SetGWorld( origPort , origDev ) ;
+ if ( clipRgn )
+ DisposeRgn( clipRgn ) ;
+ return pict;
+}
+
+void wxMacCreateBitmapButton( ControlButtonContentInfo*info , const wxBitmap& bitmap , int forceType )
+{
+ memset( info , 0 , sizeof(ControlButtonContentInfo) ) ;
+ if ( bitmap.Ok() )
+ {
+ wxBitmapRefData * bmap = (wxBitmapRefData*) ( bitmap.GetRefData()) ;
+ if ( bmap == NULL )
+ return ;
+
+ if ( bmap->m_bitmapType == kMacBitmapTypePict )
+ {
+ info->contentType = kControlContentPictHandle ;
+ info->u.picture = MAC_WXHMETAFILE(bmap->m_hPict) ;
+ }
+ else if ( bmap->m_bitmapType == kMacBitmapTypeGrafWorld )
+ {
+ if ( (forceType == kControlContentCIconHandle || ( bmap->m_width == bmap->m_height && forceType != kControlContentPictHandle ) ) && ((bmap->m_width & 0x3) == 0) )
+ {
+ info->contentType = kControlContentCIconHandle ;
+ if ( bitmap.GetMask() )
+ {
+ info->u.cIconHandle = wxMacCreateCIcon( MAC_WXHBITMAP(bmap->m_hBitmap) , MAC_WXHBITMAP(bitmap.GetMask()->GetMaskBitmap()) ,
+ 8 , bmap->m_width ) ;
+ }
+ else
+ {
+ info->u.cIconHandle = wxMacCreateCIcon( MAC_WXHBITMAP(bmap->m_hBitmap) , NULL ,
+ 8 , bmap->m_width ) ;
+ }
+ }
+ else
+ {
+ info->contentType = kControlContentPictHandle ;
+ if ( bitmap.GetMask() )
+ {
+ info->u.picture = wxMacCreatePict( MAC_WXHBITMAP(bmap->m_hBitmap) , MAC_WXHBITMAP(bitmap.GetMask()->GetMaskBitmap() ) ) ;
+ }
+ else
+ {
+ info->u.picture = wxMacCreatePict( MAC_WXHBITMAP(bmap->m_hBitmap) , NULL ) ;
+ }
+ }
+ }
+ else if ( bmap->m_bitmapType == kMacBitmapTypeIcon )
+ {
+ info->contentType = kControlContentCIconHandle ;
+ info->u.cIconHandle = MAC_WXHICON(bmap->m_hIcon) ;
+ }
+ }
+}
+
+wxBitmapRefData::wxBitmapRefData()
+ : m_width(0)
+ , m_height(0)
+ , m_depth(0)
+ , m_ok(FALSE)
+ , m_numColors(0)
+ , m_quality(0)
+{
+ m_bitmapMask = NULL;
+ m_hBitmap = NULL ;
+ m_hPict = NULL ;
+ m_hIcon = NULL ;
+ m_bitmapType = kMacBitmapTypeUnknownType ;
+ m_hasAlpha = false;
+}
+
+// TODO move this to a public function of Bitmap Ref
+static void DisposeBitmapRefData(wxBitmapRefData *data)
+{
+ if ( !data )
+ return ;
+
+ switch (data->m_bitmapType)
+ {
+ case kMacBitmapTypePict :
+ {
+ if ( data->m_hPict )
+ {
+ KillPicture( MAC_WXHMETAFILE( data->m_hPict ) ) ;
+ data->m_hPict = NULL ;
+ }
+ }
+ break ;
+ case kMacBitmapTypeGrafWorld :
+ {
+ if ( data->m_hBitmap )
+ {
+ wxMacDestroyGWorld( MAC_WXHBITMAP(data->m_hBitmap) ) ;
+ data->m_hBitmap = NULL ;
+ }
+ }
+ break ;
+ case kMacBitmapTypeIcon :
+ if ( data->m_hIcon )
+ {
+ DisposeCIcon( MAC_WXHICON(data->m_hIcon) ) ;
+ data->m_hIcon = NULL ;
+ }
+
+ default :
+ // unkown type ?
+ break ;
+ }
+
+ if (data->m_bitmapMask)
+ {
+ delete data->m_bitmapMask;
+ data->m_bitmapMask = NULL;
+ }
+}
+
+wxBitmapRefData::~wxBitmapRefData()
+{
+ DisposeBitmapRefData( this ) ;
+}
+
+bool wxBitmap::CopyFromIcon(const wxIcon& icon)
+{
+ Ref(icon) ;
+ return true;
+}
+
+wxBitmap::wxBitmap()
+{
+ m_refData = NULL;
+}
+
+wxBitmap::~wxBitmap()
+{
+}
+
+wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits)
+{
+ m_refData = new wxBitmapRefData;
+
+ M_BITMAPDATA->m_width = the_width ;
+ M_BITMAPDATA->m_height = the_height ;
+ M_BITMAPDATA->m_depth = no_bits ;
+ M_BITMAPDATA->m_numColors = 0;
+ if ( no_bits == 1 )
+ {
+ M_BITMAPDATA->m_bitmapType = kMacBitmapTypeGrafWorld ;
+ M_BITMAPDATA->m_hBitmap = wxMacCreateGWorld( the_width , the_height , no_bits ) ;
+ M_BITMAPDATA->m_ok = (MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap) != NULL ) ;
+
+ CGrafPtr origPort ;
+ GDHandle origDevice ;
+
+ GetGWorld( &origPort , &origDevice ) ;
+ SetGWorld( MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap) , NULL ) ;
+ LockPixels( GetGWorldPixMap( MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap) ) ) ;
+
+ // bits is a char array
+
+ unsigned char* linestart = (unsigned char*) bits ;
+ int linesize = ( the_width / (sizeof(unsigned char) * 8)) ;
+ if ( the_width % (sizeof(unsigned char) * 8) ) {
+ linesize += sizeof(unsigned char);
+ }
+
+ RGBColor colors[2] = {
+ { 0xFFFF , 0xFFFF , 0xFFFF } ,
+ { 0, 0 , 0 }
+ } ;
+
+ for ( int y = 0 ; y < the_height ; ++y , linestart += linesize )
+ {
+ for ( int x = 0 ; x < the_width ; ++x )
+ {
+ int index = x / 8 ;
+ int bit = x % 8 ;
+ int mask = 1 << bit ;
+ if ( linestart[index] & mask )
+ {
+ SetCPixel( x , y , &colors[1] ) ;
+ }
+ else
+ {
+ SetCPixel( x , y , &colors[0] ) ;
+ }
+ }
+ }
+ UnlockPixels( GetGWorldPixMap( MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap) ) ) ;
+
+ SetGWorld( origPort , origDevice ) ;
+ }
+ else
+ {
+ wxFAIL_MSG(wxT("multicolor BITMAPs not yet implemented"));
+ }
+}
+
+wxBitmap::wxBitmap(int w, int h, int d)
+{
+ (void)Create(w, h, d);
+}
+
+wxBitmap::wxBitmap(void *data, wxBitmapType type, int width, int height, int depth)
+{
+ (void) Create(data, type, width, height, depth);
+}
+
+wxBitmap::wxBitmap(const wxString& filename, wxBitmapType type)
+{
+ LoadFile(filename, type);
+}
+
+bool wxBitmap::CreateFromXpm(const char **bits)
+{
+ wxCHECK_MSG( bits != NULL, FALSE, wxT("invalid bitmap data") )
+ wxXPMDecoder decoder;
+ wxImage img = decoder.ReadData(bits);
+ wxCHECK_MSG( img.Ok(), FALSE, wxT("invalid bitmap data") )
+ *this = wxBitmap(img);
+ return TRUE;
+}
+
+wxBitmap::wxBitmap(const char **bits)
+{
+ (void) CreateFromXpm(bits);
+}
+
+wxBitmap::wxBitmap(char **bits)
+{
+ (void) CreateFromXpm((const char **)bits);
+}
+
+wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const
+{
+ wxCHECK_MSG( Ok() &&
+ (rect.x >= 0) && (rect.y >= 0) &&
+ (rect.x+rect.width <= GetWidth()) &&
+ (rect.y+rect.height <= GetHeight()),
+ wxNullBitmap, wxT("invalid bitmap or bitmap region") );
+
+
+ wxBitmap ret( rect.width, rect.height, GetDepth() );
+ wxASSERT_MSG( ret.Ok(), wxT("GetSubBitmap error") );
+
+ GWorldPtr origPort;
+ GDHandle origDevice;
+
+ GetGWorld( &origPort, &origDevice );
+
+ // Update the subbitmaps reference data
+ wxBitmapRefData *ref = (wxBitmapRefData *)ret.GetRefData();
+
+ ref->m_numColors = M_BITMAPDATA->m_numColors;
+#if wxUSE_PALETTE
+ ref->m_bitmapPalette = M_BITMAPDATA->m_bitmapPalette;
+#endif // wxUSE_PALETTE
+ ref->m_bitmapType = M_BITMAPDATA->m_bitmapType;
+
+ // Copy sub region of this bitmap
+ if(M_BITMAPDATA->m_bitmapType == kMacBitmapTypePict)
+ {
+ printf("GetSubBitmap: Copy a region of a Pict structure - TODO\n");
+ }
+ else if(M_BITMAPDATA->m_bitmapType == kMacBitmapTypeGrafWorld)
+ {
+ // Copy mask
+ if(GetMask())
+ {
+ GWorldPtr submask, mask;
+ RGBColor color;
+
+ mask = (GWorldPtr) GetMask()->GetMaskBitmap();
+ submask = wxMacCreateGWorld(rect.width, rect.height, GetMask()->GetDepth() );
+ LockPixels(GetGWorldPixMap(mask));
+ LockPixels(GetGWorldPixMap(submask));
+
+ for(int yy = 0; yy < rect.height; yy++)
+ {
+ for(int xx = 0; xx < rect.width; xx++)
+ {
+ SetGWorld(mask, NULL);
+ GetCPixel(rect.x + xx, rect.y + yy, &color);
+ SetGWorld(submask, NULL);
+ SetCPixel(xx,yy, &color);
+ }
+ }
+ UnlockPixels(GetGWorldPixMap(mask));
+ UnlockPixels(GetGWorldPixMap(submask));
+ ref->m_bitmapMask = new wxMask;
+ ref->m_bitmapMask->SetMaskBitmap(submask);
+ }
+
+ // Copy bitmap
+ if(GetHBITMAP())
+ {
+ GWorldPtr subbitmap, bitmap;
+ RGBColor color;
+
+ bitmap = (GWorldPtr) GetHBITMAP();
+ subbitmap = (GWorldPtr) ref->m_hBitmap ;
+ LockPixels(GetGWorldPixMap(bitmap));
+ LockPixels(GetGWorldPixMap(subbitmap));
+
+ for(int yy = 0; yy < rect.height; yy++)
+ {
+ for(int xx = 0; xx < rect.width; xx++)
+ {
+ SetGWorld(bitmap, NULL);
+ GetCPixel(rect.x + xx, rect.y + yy, &color);
+ SetGWorld(subbitmap, NULL);
+ SetCPixel(xx, yy, &color);
+ }
+ }
+ UnlockPixels(GetGWorldPixMap(bitmap));
+ UnlockPixels(GetGWorldPixMap(subbitmap));
+ }
+ }
+ SetGWorld( origPort, origDevice );
+
+ return ret;
+}
+
+bool wxBitmap::Create(int w, int h, int d)
+{
+ UnRef();
+
+ m_refData = new wxBitmapRefData;
+
+ M_BITMAPDATA->m_width = w;
+ M_BITMAPDATA->m_height = h;
+ M_BITMAPDATA->m_depth = d;
+
+ M_BITMAPDATA->m_bitmapType = kMacBitmapTypeGrafWorld ;
+ M_BITMAPDATA->m_hBitmap = wxMacCreateGWorld( w , h , d ) ;
+ M_BITMAPDATA->m_ok = ( M_BITMAPDATA->m_hBitmap != NULL ) ;
+ return M_BITMAPDATA->m_ok;
+}
+
+int wxBitmap::GetBitmapType() const
+{
+ wxCHECK_MSG( Ok(), kMacBitmapTypeUnknownType, wxT("invalid bitmap") );
+
+ return M_BITMAPDATA->m_bitmapType;
+}
+
+void wxBitmap::SetHBITMAP(WXHBITMAP bmp)
+{
+ if (!M_BITMAPDATA)
+ m_refData = new wxBitmapRefData;
+ else
+ DisposeBitmapRefData( M_BITMAPDATA ) ;
+
+ M_BITMAPDATA->m_bitmapType = kMacBitmapTypeGrafWorld ;
+ M_BITMAPDATA->m_hBitmap = bmp ;
+ M_BITMAPDATA->m_ok = ( M_BITMAPDATA->m_hBitmap != NULL ) ;
+}
+
+void wxBitmap::SetHICON(WXHICON ico)
+{
+ if (!M_BITMAPDATA)
+ m_refData = new wxBitmapRefData;
+ else
+ DisposeBitmapRefData( M_BITMAPDATA ) ;
+
+ M_BITMAPDATA->m_bitmapType = kMacBitmapTypeIcon ;
+ M_BITMAPDATA->m_hIcon = ico ;
+ M_BITMAPDATA->m_ok = ( M_BITMAPDATA->m_hIcon != NULL ) ;
+}
+
+void wxBitmap::SetPict(WXHMETAFILE pict)
+{
+ if (!M_BITMAPDATA)
+ m_refData = new wxBitmapRefData;
+ else
+ DisposeBitmapRefData( M_BITMAPDATA ) ;
+
+ M_BITMAPDATA->m_bitmapType = kMacBitmapTypePict ;
+ M_BITMAPDATA->m_hPict = pict ;
+ M_BITMAPDATA->m_ok = ( M_BITMAPDATA->m_hPict != NULL ) ;
+}
+
+bool wxBitmap::LoadFile(const wxString& filename, wxBitmapType type)
+{
+ UnRef();
+
+ wxBitmapHandler *handler = FindHandler(type);
+
+ if ( handler )
+ {
+ m_refData = new wxBitmapRefData;
+
+ return handler->LoadFile(this, filename, type, -1, -1);
+ }
+ else
+ {
+ wxImage loadimage(filename, type);
+ if (loadimage.Ok()) {
+ *this = loadimage;
+ return true;
+ }
+ }
+ wxLogWarning(wxT("no bitmap handler for type %d defined."), type);
+ return false;
+}
+
+bool wxBitmap::Create(void *data, wxBitmapType type, int width, int height, int depth)
+{
+ UnRef();
+
+ m_refData = new wxBitmapRefData;
+
+ wxBitmapHandler *handler = FindHandler(type);
+
+ if ( handler == NULL ) {
+ wxLogWarning(wxT("no bitmap handler for type %d defined."), type);
+
+ return FALSE;
+ }
+
+ return handler->Create(this, data, type, width, height, depth);
+}
+
+wxBitmap::wxBitmap(const wxImage& image, int depth)
+{
+ wxCHECK_RET( image.Ok(), wxT("invalid image") )
+ wxCHECK_RET( depth == -1, wxT("invalid bitmap depth") )
+
+ m_refData = new wxBitmapRefData();
+
+ // width and height of the device-dependent bitmap
+ int width = image.GetWidth();
+ int height = image.GetHeight();
+
+ // Create picture
+
+ Create( width , height , 32 ) ;
+
+ CGrafPtr origPort ;
+ GDHandle origDevice ;
+
+ PixMapHandle pixMap = GetGWorldPixMap((GWorldPtr)GetHBITMAP()) ;
+ LockPixels( pixMap );
+
+ GetGWorld( &origPort , &origDevice ) ;
+ SetGWorld( (GWorldPtr) GetHBITMAP() , NULL ) ;
+
+ // Render image
+ register unsigned char* data = image.GetData();
+ char* destinationBase = GetPixBaseAddr( pixMap );
+ register unsigned char* destination = (unsigned char*) destinationBase ;
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
+ {
+ *destination++ = 0 ;
+ *destination++ = *data++ ;
+ *destination++ = *data++ ;
+ *destination++ = *data++ ;
+ }
+ destinationBase += ((**pixMap).rowBytes & 0x7fff);
+ destination = (unsigned char*) destinationBase ;
+ }
+ if ( image.HasAlpha() )
+ {
+ unsigned char *alpha = image.GetAlpha();
+
+ wxColour maskcolor(image.GetMaskRed(), image.GetMaskGreen(), image.GetMaskBlue());
+ RGBColor color ;
+ wxBitmap maskBitmap ;
+
+ maskBitmap.Create( width, height, 24);
+ LockPixels( GetGWorldPixMap( (GWorldPtr) maskBitmap.GetHBITMAP()) );
+ SetGWorld( (GWorldPtr) maskBitmap.GetHBITMAP(), NULL);
+
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
+ {
+ memset( &color , 255 - *alpha , sizeof( color ) );
+ SetCPixel(x,y, &color);
+
+ alpha += 1 ;
+ }
+ } // for height
+ SetGWorld( (GWorldPtr) GetHBITMAP(), NULL);
+ SetMask(new wxMask( maskBitmap ));
+ UnlockPixels( GetGWorldPixMap( (GWorldPtr) maskBitmap.GetHBITMAP()) );
+ }
+ else if ( image.HasMask() )
+ {
+ data = image.GetData();
+
+ wxColour maskcolor(image.GetMaskRed(), image.GetMaskGreen(), image.GetMaskBlue());
+ RGBColor white = { 0xffff, 0xffff, 0xffff };
+ RGBColor black = { 0 , 0 , 0 };
+ wxBitmap maskBitmap ;
+
+ maskBitmap.Create( width, height, 1);
+ LockPixels( GetGWorldPixMap( (GWorldPtr) maskBitmap.GetHBITMAP()) );
+ SetGWorld( (GWorldPtr) maskBitmap.GetHBITMAP(), NULL);
+
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
+ {
+ if ( data[0] == image.GetMaskRed() && data[1] == image.GetMaskGreen() && data[2] == image.GetMaskBlue() )
+ {
+ SetCPixel(x,y, &white);
+ }
+ else {
+ SetCPixel(x,y, &black);
+ }
+ data += 3 ;
+ }
+ } // for height
+ SetGWorld( (GWorldPtr) GetHBITMAP(), NULL);
+ SetMask(new wxMask( maskBitmap ));
+ UnlockPixels( GetGWorldPixMap( (GWorldPtr) maskBitmap.GetHBITMAP()) );
+ }
+
+ UnlockPixels( GetGWorldPixMap( (GWorldPtr) GetHBITMAP()) );
+ SetGWorld( origPort, origDevice );
+}
+
+wxImage wxBitmap::ConvertToImage() const
+{
+ wxImage image;
+
+ wxCHECK_MSG( Ok(), wxNullImage, wxT("invalid bitmap") );
+
+ // create an wxImage object
+ int width = GetWidth();
+ int height = GetHeight();
+ image.Create( width, height );
+
+ unsigned char *data = image.GetData();
+
+ wxCHECK_MSG( data, wxNullImage, wxT("Could not allocate data for image") );
+
+ GWorldPtr origPort;
+ GDHandle origDevice;
+ RgnHandle maskRgn = NULL ;
+ GWorldPtr tempPort = NULL ;
+ int index;
+ RGBColor color;
+ // background color set to RGB(16,16,16) in consistent with wxGTK
+ unsigned char mask_r=16, mask_g=16, mask_b=16;
+ SInt16 r,g,b;
+ wxMask *mask = GetMask();
+
+ GetGWorld( &origPort, &origDevice );
+ if ( GetBitmapType() != kMacBitmapTypeGrafWorld )
+ {
+ tempPort = wxMacCreateGWorld( width , height , -1) ;
+ }
+ else
+ {
+ tempPort = (GWorldPtr) GetHBITMAP() ;
+ }
+ LockPixels(GetGWorldPixMap(tempPort));
+ SetGWorld( tempPort, NULL);
+ if ( GetBitmapType() == kMacBitmapTypePict || GetBitmapType() == kMacBitmapTypeIcon )
+ {
+ Rect bitmaprect = { 0 , 0 , height, width };
+ if ( GetBitmapType() == kMacBitmapTypeIcon )
+ {
+ ::PlotCIconHandle( &bitmaprect , atNone , ttNone , MAC_WXHICON(GetHICON()) ) ;
+ maskRgn = NewRgn() ;
+ BitMapToRegion( maskRgn , &(**(MAC_WXHICON(GetHICON()))).iconMask ) ;
+ }
+ else
+ ::DrawPicture( (PicHandle) GetPict(), &bitmaprect ) ;
+ }
+ // Copy data into image
+ index = 0;
+ for (int yy = 0; yy < height; yy++)
+ {
+ for (int xx = 0; xx < width; xx++)
+ {
+ GetCPixel(xx,yy, &color);
+ r = ((color.red ) >> 8);
+ g = ((color.green ) >> 8);
+ b = ((color.blue ) >> 8);
+ data[index ] = r;
+ data[index + 1] = g;
+ data[index + 2] = b;
+ if ( maskRgn )
+ {
+ Point pt ;
+ pt.h = xx ;
+ pt.v = yy ;
+ if ( !PtInRgn( pt , maskRgn ) )
+ {
+ data[index ] = mask_r;
+ data[index + 1] = mask_g;
+ data[index + 2] = mask_b;
+ }
+ }
+ else
+ {
+ if (mask)
+ {
+ if (mask->PointMasked(xx,yy))
+ {
+ data[index ] = mask_r;
+ data[index + 1] = mask_g;
+ data[index + 2] = mask_b;
+ }
+ }
+ }
+ index += 3;
+ }
+ }
+ if (mask || maskRgn )
+ {
+ image.SetMaskColour( mask_r, mask_g, mask_b );
+ image.SetMask( true );
+ }
+
+ // Free resources
+ UnlockPixels(GetGWorldPixMap( tempPort ));
+ SetGWorld(origPort, origDevice);
+ if ( GetBitmapType() != kMacBitmapTypeGrafWorld )
+ {
+ wxMacDestroyGWorld( tempPort ) ;
+ }
+ if ( maskRgn )
+ {
+ DisposeRgn( maskRgn ) ;
+ }
+
+ return image;
+}
+
+
+bool wxBitmap::SaveFile(const wxString& filename, wxBitmapType type,
+ const wxPalette *palette) const
+{
+ wxBitmapHandler *handler = FindHandler(type);
+
+ if ( handler )
+ {
+ return handler->SaveFile(this, filename, type, palette);
+ }
+ else
+ {
+ wxImage image = ConvertToImage();
+
+ return image.SaveFile(filename, type);
+ }
+
+ wxLogWarning(wxT("no bitmap handler for type %d defined."), type);
+ return false;
+}
+
+bool wxBitmap::Ok() const
+{
+ return (M_BITMAPDATA && M_BITMAPDATA->m_ok);
+}
+
+int wxBitmap::GetHeight() const
+{
+ wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
+
+ return M_BITMAPDATA->m_height;
+}
+
+int wxBitmap::GetWidth() const
+{
+ wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
+
+ return M_BITMAPDATA->m_width;
+}
+
+int wxBitmap::GetDepth() const
+{
+ wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
+
+ return M_BITMAPDATA->m_depth;
+}
+
+int wxBitmap::GetQuality() const
+{
+ wxCHECK_MSG( Ok(), -1, wxT("invalid bitmap") );
+
+ return M_BITMAPDATA->m_quality;
+}
+
+wxMask *wxBitmap::GetMask() const
+{
+ wxCHECK_MSG( Ok(), (wxMask *) NULL, wxT("invalid bitmap") );
+
+ return M_BITMAPDATA->m_bitmapMask;
+}
+
+void wxBitmap::SetWidth(int w)
+{
+ if (!M_BITMAPDATA)
+ m_refData = new wxBitmapRefData;
+
+ M_BITMAPDATA->m_width = w;
+}
+
+void wxBitmap::SetHeight(int h)
+{
+ if (!M_BITMAPDATA)
+ m_refData = new wxBitmapRefData;
+
+ M_BITMAPDATA->m_height = h;
+}
+
+void wxBitmap::SetDepth(int d)
+{
+ if (!M_BITMAPDATA)
+ m_refData = new wxBitmapRefData;
+
+ M_BITMAPDATA->m_depth = d;
+}
+
+void wxBitmap::SetQuality(int q)
+{
+ if (!M_BITMAPDATA)
+ m_refData = new wxBitmapRefData;
+
+ M_BITMAPDATA->m_quality = q;
+}
+
+void wxBitmap::SetOk(bool isOk)
+{
+ if (!M_BITMAPDATA)
+ m_refData = new wxBitmapRefData;
+
+ M_BITMAPDATA->m_ok = isOk;
+}
+
+#if wxUSE_PALETTE
+wxPalette *wxBitmap::GetPalette() const
+{
+ wxCHECK_MSG( Ok(), NULL, wxT("Invalid bitmap GetPalette()") );
+
+ return &M_BITMAPDATA->m_bitmapPalette;
+}
+
+void wxBitmap::SetPalette(const wxPalette& palette)
+{
+ if (!M_BITMAPDATA)
+ m_refData = new wxBitmapRefData;
+
+ M_BITMAPDATA->m_bitmapPalette = palette ;
+}
+#endif // wxUSE_PALETTE
+
+void wxBitmap::SetMask(wxMask *mask)
+{
+ if (!M_BITMAPDATA)
+ m_refData = new wxBitmapRefData;
+
+ // Remove existing mask if there is one.
+ delete M_BITMAPDATA->m_bitmapMask;
+
+ M_BITMAPDATA->m_bitmapMask = mask ;
+}
+
+WXHBITMAP wxBitmap::GetHBITMAP() const
+{
+ wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") );
+
+ return MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap);
+}
+
+WXHMETAFILE wxBitmap::GetPict( bool *created ) const
+{
+ wxCHECK_MSG( Ok(), NULL, wxT("invalid bitmap") );
+
+ PicHandle picture = NULL ; // This is the returned picture
+ if ( created )
+ (*created) = false ;
+ // If bitmap already in Pict format return pointer
+ if(M_BITMAPDATA->m_bitmapType == kMacBitmapTypePict) {
+ return M_BITMAPDATA->m_hPict;
+ }
+ else if(M_BITMAPDATA->m_bitmapType != kMacBitmapTypeGrafWorld) {
+ // Invalid bitmap
+ return NULL;
+ }
+ else
+ {
+ if ( GetMask() )
+ {
+ picture = wxMacCreatePict( MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap) , MAC_WXHBITMAP(GetMask()->GetMaskBitmap() ) ) ;
+ }
+ else
+ {
+ picture = wxMacCreatePict( MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap) , NULL ) ;
+ }
+ if ( created && picture )
+ (*created) = true ;
+ }
+ return picture ;
+}
+
+/*
+ * wxMask
+ */
+
+wxMask::wxMask()
+ : m_maskBitmap(NULL)
+{
+}
+
+// Construct a mask from a bitmap and a colour indicating
+// the transparent area
+wxMask::wxMask(const wxBitmap& bitmap, const wxColour& colour)
+ : m_maskBitmap(NULL)
+{
+ Create(bitmap, colour);
+}
+
+// Construct a mask from a bitmap and a palette index indicating
+// the transparent area
+wxMask::wxMask(const wxBitmap& bitmap, int paletteIndex)
+ : m_maskBitmap(NULL)
+{
+ Create(bitmap, paletteIndex);
+}
+
+// Construct a mask from a mono bitmap (copies the bitmap).
+wxMask::wxMask(const wxBitmap& bitmap)
+ : m_maskBitmap(NULL)
+{
+ Create(bitmap);
+}
+
+wxMask::~wxMask()
+{
+ if ( m_maskBitmap )
+ {
+ wxMacDestroyGWorld( (GWorldPtr) m_maskBitmap ) ;
+ m_maskBitmap = NULL ;
+ }
+}
+
+// Create a mask from a mono bitmap (copies the bitmap).
+bool wxMask::Create(const wxBitmap& bitmap)
+{
+ if ( m_maskBitmap )
+ {
+ wxMacDestroyGWorld( (GWorldPtr) m_maskBitmap ) ;
+ m_maskBitmap = NULL ;
+ }
+ wxCHECK_MSG( bitmap.GetBitmapType() == kMacBitmapTypeGrafWorld, false,
+ wxT("Cannot create mask from this bitmap type (TODO)"));
+ // other types would require a temporary bitmap. not yet implemented
+
+ wxCHECK_MSG( bitmap.Ok(), false, wxT("Invalid bitmap"));
+
+ m_depth = bitmap.GetDepth() ;
+ m_maskBitmap = wxMacCreateGWorld(bitmap.GetWidth(), bitmap.GetHeight(), bitmap.GetDepth() );
+ Rect rect = { 0,0, bitmap.GetHeight(), bitmap.GetWidth() };
+
+ LockPixels( GetGWorldPixMap( (GWorldPtr) m_maskBitmap) );
+ LockPixels( GetGWorldPixMap( (GWorldPtr) bitmap.GetHBITMAP()) );
+ CopyBits(GetPortBitMapForCopyBits( (GWorldPtr) bitmap.GetHBITMAP()),
+ GetPortBitMapForCopyBits( (GWorldPtr) m_maskBitmap),
+ &rect, &rect, srcCopy, 0);
+ UnlockPixels( GetGWorldPixMap( (GWorldPtr) m_maskBitmap) );
+ UnlockPixels( GetGWorldPixMap( (GWorldPtr) bitmap.GetHBITMAP()) );
+
+ return FALSE;
+}
+
+// Create a mask from a bitmap and a palette index indicating
+// the transparent area
+bool wxMask::Create(const wxBitmap& bitmap, int paletteIndex)
+{
+ // TODO
+ wxCHECK_MSG( 0, false, wxT("wxMask::Create not yet implemented"));
+ return FALSE;
+}
+
+// Create a mask from a bitmap and a colour indicating
+// the transparent area
+bool wxMask::Create(const wxBitmap& bitmap, const wxColour& colour)
+{
+ if ( m_maskBitmap )
+ {
+ wxMacDestroyGWorld( (GWorldPtr) m_maskBitmap ) ;
+ m_maskBitmap = NULL ;
+ }
+ wxCHECK_MSG( bitmap.GetBitmapType() == kMacBitmapTypeGrafWorld, false,
+ wxT("Cannot create mask from this bitmap type (TODO)"));
+ // other types would require a temporary bitmap. not yet implemented
+
+ wxCHECK_MSG( bitmap.Ok(), false, wxT("Illigal bitmap"));
+
+ m_maskBitmap = wxMacCreateGWorld( bitmap.GetWidth() , bitmap.GetHeight() , 1 );
+ m_depth = 1 ;
+ LockPixels( GetGWorldPixMap( (GWorldPtr) m_maskBitmap ) );
+ LockPixels( GetGWorldPixMap( (GWorldPtr) bitmap.GetHBITMAP() ) );
+ RGBColor maskColor = MAC_WXCOLORREF(colour.GetPixel());
+
+ // this is not very efficient, but I can't think
+ // of a better way of doing it
+ CGrafPtr origPort ;
+ GDHandle origDevice ;
+ RGBColor col;
+ RGBColor colors[2] = {
+ { 0xFFFF, 0xFFFF, 0xFFFF },
+ { 0, 0, 0 }};
+
+ GetGWorld( &origPort , &origDevice ) ;
+ for (int w = 0; w < bitmap.GetWidth(); w++)
+ {
+ for (int h = 0; h < bitmap.GetHeight(); h++)
+ {
+ SetGWorld( (GWorldPtr) bitmap.GetHBITMAP(), NULL ) ;
+ GetCPixel( w , h , &col ) ;
+ SetGWorld( (GWorldPtr) m_maskBitmap , NULL ) ;
+ if (col.red == maskColor.red && col.green == maskColor.green && col.blue == maskColor.blue)
+ {
+ SetCPixel( w , h , &colors[0] ) ;
+ }
+ else
+ {
+ SetCPixel( w , h , &colors[1] ) ;
+ }
+ }
+ }
+ UnlockPixels( GetGWorldPixMap( (CGrafPtr) m_maskBitmap ) ) ;
+ UnlockPixels( GetGWorldPixMap( (GWorldPtr) bitmap.GetHBITMAP() ) ) ;
+ SetGWorld( origPort , origDevice ) ;
+
+ return TRUE;
+}
+
+bool wxMask::PointMasked(int x, int y)
+{
+ GWorldPtr origPort;
+ GDHandle origDevice;
+ RGBColor color;
+ bool masked = true;
+
+ GetGWorld( &origPort, &origDevice);
+
+ //Set port to mask and see if it masked (1) or not ( 0 )
+ SetGWorld( (GWorldPtr) m_maskBitmap, NULL);
+ LockPixels(GetGWorldPixMap( (GWorldPtr) m_maskBitmap));
+ GetCPixel(x,y, &color);
+ masked = !(color.red == 0 && color.green == 0 && color.blue == 0);
+ UnlockPixels(GetGWorldPixMap( (GWorldPtr) m_maskBitmap));
+
+ SetGWorld( origPort, origDevice);
+
+ return masked;
+}
+
+/*
+ * wxBitmapHandler
+ */
+
+wxBitmapHandler::~wxBitmapHandler()
+{
+}
+
+bool wxBitmapHandler::Create(wxBitmap *bitmap, void *data, long type, int width, int height, int depth)
+{
+ return FALSE;
+}
+
+bool wxBitmapHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
+ int desiredWidth, int desiredHeight)
+{
+ return FALSE;
+}
+
+bool wxBitmapHandler::SaveFile(const wxBitmap *bitmap, const wxString& name, int type, const wxPalette *palette)
+{
+ return FALSE;
+}
+
+/*
+ * Standard handlers
+ */
+
+class WXDLLEXPORT wxPICTResourceHandler: public wxBitmapHandler
+{
+ DECLARE_DYNAMIC_CLASS(wxPICTResourceHandler)
+public:
+ inline wxPICTResourceHandler()
+ {
+ m_name = wxT("Macintosh Pict resource");
+ m_extension = wxEmptyString;
+ m_type = wxBITMAP_TYPE_PICT_RESOURCE;
+ };
+
+ virtual bool LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
+ int desiredWidth, int desiredHeight);
+};
+IMPLEMENT_DYNAMIC_CLASS(wxPICTResourceHandler, wxBitmapHandler)
+
+bool wxPICTResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
+ int desiredWidth, int desiredHeight)
+{
+ Str255 theName ;
+ wxMacStringToPascal( name , theName ) ;
+
+ PicHandle thePict = (PicHandle ) GetNamedResource( 'PICT' , theName ) ;
+ if ( thePict )
+ {
+ PictInfo theInfo ;
+
+ GetPictInfo( thePict , &theInfo , 0 , 0 , systemMethod , 0 ) ;
+ DetachResource( (Handle) thePict ) ;
+ M_BITMAPHANDLERDATA->m_bitmapType = kMacBitmapTypePict ;
+ M_BITMAPHANDLERDATA->m_hPict = thePict ;
+ M_BITMAPHANDLERDATA->m_width = theInfo.sourceRect.right - theInfo.sourceRect.left ;
+ M_BITMAPHANDLERDATA->m_height = theInfo.sourceRect.bottom - theInfo.sourceRect.top ;
+
+ M_BITMAPHANDLERDATA->m_depth = theInfo.depth ;
+ M_BITMAPHANDLERDATA->m_ok = true ;
+ M_BITMAPHANDLERDATA->m_numColors = theInfo.uniqueColors ;
+// M_BITMAPHANDLERDATA->m_bitmapPalette;
+// M_BITMAPHANDLERDATA->m_quality;
+ return TRUE ;
+ }
+ return FALSE ;
+}
+
+void wxBitmap::InitStandardHandlers()
+{
+ AddHandler(new wxPICTResourceHandler) ;
+ AddHandler(new wxICONResourceHandler) ;
+}
+
+// ----------------------------------------------------------------------------
+// raw bitmap access support
+// ----------------------------------------------------------------------------
+
+void *wxBitmap::GetRawData(wxPixelDataBase& data, int bpp)
+{
+ if ( !Ok() )
+ {
+ // no bitmap, no data (raw or otherwise)
+ return NULL;
+ }
+
+ if ( M_BITMAPDATA->m_bitmapType != kMacBitmapTypeGrafWorld )
+ {
+ wxFAIL_MSG( _T("GetRawData() only supported for GWorlds") );
+
+ return NULL;
+ }
+
+ GWorldPtr gworld = MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap);
+ PixMapHandle hPixMap = GetGWorldPixMap(gworld);
+ wxCHECK_MSG( hPixMap && *hPixMap, NULL,
+ _T("GetRawData(): failed to get PixMap from GWorld?") );
+
+ wxCHECK_MSG( (*hPixMap)->pixelSize == bpp, NULL,
+ _T("GetRawData(): pixel format mismatch") );
+
+ if ( !LockPixels(hPixMap) )
+ {
+ wxFAIL_MSG( _T("failed to lock PixMap in GetRawData()") );
+
+ return NULL;
+ }
+
+ data.m_width = GetWidth();
+ data.m_height = GetHeight();
+ data.m_stride = (*hPixMap)->rowBytes & 0x7fff;
+
+ M_BITMAPDATA->m_hasAlpha = false;
+
+ return GetPixBaseAddr(hPixMap);
+}
+
+void wxBitmap::UngetRawData(wxPixelDataBase& dataBase)
+{
+ if ( !Ok() )
+ return;
+
+ if ( M_BITMAPDATA->m_hasAlpha )
+ {
+ wxAlphaPixelData& data = (wxAlphaPixelData&)dataBase;
+
+ int w = data.GetWidth(),
+ h = data.GetHeight();
+
+ wxBitmap bmpMask(GetWidth(), GetHeight(), 32);
+ wxAlphaPixelData dataMask(bmpMask, data.GetOrigin(), wxSize(w, h));
+ wxAlphaPixelData::Iterator pMask(dataMask),
+ p(data);
+ for ( int y = 0; y < h; y++ )
+ {
+ wxAlphaPixelData::Iterator rowStartMask = pMask,
+ rowStart = p;
+
+ for ( int x = 0; x < w; x++ )
+ {
+ const wxAlphaPixelData::Iterator::ChannelType
+ alpha = p.Alpha();
+
+ pMask.Red() = alpha;
+ pMask.Green() = alpha;
+ pMask.Blue() = alpha;
+
+ ++p;
+ ++pMask;
+ }
+
+ p = rowStart;
+ p.OffsetY(data, 1);
+
+ pMask = rowStartMask;
+ pMask.OffsetY(dataMask, 1);
+ }
+
+ SetMask(new wxMask(bmpMask));
+ }
+
+ GWorldPtr gworld = MAC_WXHBITMAP(M_BITMAPDATA->m_hBitmap);
+ PixMapHandle hPixMap = GetGWorldPixMap(gworld);
+ if ( hPixMap )
+ {
+ UnlockPixels(hPixMap);
+ }
+}
+
+void wxBitmap::UseAlpha()
+{
+ // remember that we are using alpha channel, we'll need to create a proper
+ // mask in UngetRawData()
+ M_BITMAPDATA->m_hasAlpha = true;
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: bmpbuttn.cpp
+// Purpose: wxBitmapButton
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "bmpbuttn.h"
+#endif
+
+#include "wx/window.h"
+#include "wx/bmpbuttn.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxBitmapButton, wxButton)
+#endif
+
+#include "wx/mac/uma.h"
+#include "wx/bitmap.h"
+
+bool wxBitmapButton::Create(wxWindow *parent, wxWindowID id, const wxBitmap& bitmap,
+ const wxPoint& pos,
+ const wxSize& size, long style,
+ const wxValidator& validator,
+ const wxString& name)
+{
+ // since bitmapbuttonbase is subclass of button calling wxBitmapButtonBase::Create
+ // essentially creates an additional button
+ if ( !wxControl::Create(parent, id, pos, size,
+ style, validator, name) )
+ return false;
+
+ m_bmpNormal = bitmap;
+
+ if (style & wxBU_AUTODRAW)
+ {
+ m_marginX = wxDEFAULT_BUTTON_MARGIN;
+ m_marginY = wxDEFAULT_BUTTON_MARGIN;
+ }
+ else
+ {
+ m_marginX = 0;
+ m_marginY = 0;
+ }
+
+ int width = size.x;
+ int height = size.y;
+
+ if ( bitmap.Ok() )
+ {
+ wxSize newSize = DoGetBestSize();
+ if ( width == -1 )
+ width = newSize.x;
+ if ( height == -1 )
+ height = newSize.y;
+ }
+
+ Rect bounds ;
+ Str255 title ;
+ m_bmpNormal = bitmap;
+ wxBitmapRefData * bmap = NULL ;
+
+ if ( m_bmpNormal.Ok() )
+ bmap = (wxBitmapRefData*) ( m_bmpNormal.GetRefData()) ;
+
+ MacPreControlCreate( parent , id , wxEmptyString , pos , wxSize( width , height ) ,style, validator , name , &bounds , title ) ;
+
+ m_macControl = ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , title , false , 0 ,
+ kControlBehaviorOffsetContents +
+ ( bmap && bmap->m_bitmapType == kMacBitmapTypeIcon ?
+ kControlContentCIconHandle : kControlContentPictHandle ) , 0,
+ (( style & wxBU_AUTODRAW ) ? kControlBevelButtonSmallBevelProc : kControlBevelButtonNormalBevelProc ), (long) this ) ;
+ wxASSERT_MSG( (ControlHandle) m_macControl != NULL , wxT("No valid mac control") ) ;
+
+ ControlButtonContentInfo info ;
+ wxMacCreateBitmapButton( &info , m_bmpNormal ) ;
+ if ( info.contentType != kControlNoContent )
+ {
+ ::SetControlData( (ControlHandle) m_macControl , kControlButtonPart , kControlBevelButtonContentTag , sizeof(info) , (char*) &info ) ;
+ }
+ MacPostControlCreate() ;
+
+ return TRUE;
+}
+
+void wxBitmapButton::SetBitmapLabel(const wxBitmap& bitmap)
+{
+ m_bmpNormal = bitmap;
+
+ ControlButtonContentInfo info ;
+ wxMacCreateBitmapButton( &info , m_bmpNormal ) ;
+ if ( info.contentType != kControlNoContent )
+ {
+ ::SetControlData( (ControlHandle) m_macControl , kControlButtonPart , kControlBevelButtonContentTag , sizeof(info) , (char*) &info ) ;
+ }
+}
+
+
+wxSize wxBitmapButton::DoGetBestSize() const
+{
+ wxSize best;
+ if (m_bmpNormal.Ok())
+ {
+ best.x = m_bmpNormal.GetWidth() + 2*m_marginX;
+ best.y = m_bmpNormal.GetHeight() + 2*m_marginY;
+ }
+ return best;
+}
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: brush.cpp
+// Purpose: wxBrush
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "brush.h"
+#endif
+
+#include "wx/setup.h"
+#include "wx/utils.h"
+#include "wx/brush.h"
+
+#include "wx/mac/private.h"
+
+#if !USE_SHARED_LIBRARIES
+IMPLEMENT_DYNAMIC_CLASS(wxBrush, wxGDIObject)
+#endif
+
+class WXDLLEXPORT wxBrushRefData: public wxGDIRefData
+{
+ friend class WXDLLEXPORT wxBrush;
+public:
+ wxBrushRefData();
+ wxBrushRefData(const wxBrushRefData& data);
+ ~wxBrushRefData();
+
+protected:
+ wxMacBrushKind m_macBrushKind ;
+ int m_style;
+ wxBitmap m_stipple ;
+ wxColour m_colour;
+
+ ThemeBrush m_macThemeBrush ;
+
+ ThemeBackgroundKind m_macThemeBackground ;
+ Rect m_macThemeBackgroundExtent ;
+};
+
+#define M_BRUSHDATA ((wxBrushRefData *)m_refData)
+
+wxBrushRefData::wxBrushRefData()
+ : m_style(wxSOLID)
+{
+ m_macBrushKind = kwxMacBrushColour ;
+}
+
+wxBrushRefData::wxBrushRefData(const wxBrushRefData& data)
+ : wxGDIRefData()
+ , m_style(data.m_style)
+{
+ m_stipple = data.m_stipple;
+ m_colour = data.m_colour;
+ m_macBrushKind = data.m_macBrushKind ;
+ m_macThemeBrush = data.m_macThemeBrush ;
+ m_macThemeBackground = data.m_macThemeBackground ;
+ m_macThemeBackgroundExtent = data.m_macThemeBackgroundExtent ;
+}
+
+wxBrushRefData::~wxBrushRefData()
+{
+}
+
+// Brushes
+wxBrush::wxBrush()
+{
+}
+
+wxBrush::~wxBrush()
+{
+}
+
+wxBrush::wxBrush(const wxColour& col, int Style)
+{
+ m_refData = new wxBrushRefData;
+
+ M_BRUSHDATA->m_colour = col;
+ M_BRUSHDATA->m_style = Style;
+
+ RealizeResource();
+}
+
+wxBrush::wxBrush(const wxBitmap& stipple)
+{
+ m_refData = new wxBrushRefData;
+
+ M_BRUSHDATA->m_colour = *wxBLACK;
+ M_BRUSHDATA->m_stipple = stipple;
+
+ if (M_BRUSHDATA->m_stipple.GetMask())
+ M_BRUSHDATA->m_style = wxSTIPPLE_MASK_OPAQUE;
+ else
+ M_BRUSHDATA->m_style = wxSTIPPLE;
+
+ RealizeResource();
+}
+
+wxBrush::wxBrush(ThemeBrush macThemeBrush )
+{
+ m_refData = new wxBrushRefData;
+
+ M_BRUSHDATA->m_macBrushKind = kwxMacBrushTheme;
+ M_BRUSHDATA->m_macThemeBrush = macThemeBrush;
+
+ RealizeResource();
+}
+void wxBrush::Unshare()
+{
+ // Don't change shared data
+ if (!m_refData)
+ {
+ m_refData = new wxBrushRefData();
+ }
+ else
+ {
+ wxBrushRefData* ref = new wxBrushRefData(*(wxBrushRefData*)m_refData);
+ UnRef();
+ m_refData = ref;
+ }
+}
+
+void wxBrush::SetColour(const wxColour& col)
+{
+ Unshare();
+ M_BRUSHDATA->m_macBrushKind = kwxMacBrushColour;
+ M_BRUSHDATA->m_colour = col;
+
+ RealizeResource();
+}
+
+void wxBrush::SetColour(unsigned char r, unsigned char g, unsigned char b)
+{
+ Unshare();
+
+ M_BRUSHDATA->m_macBrushKind = kwxMacBrushColour;
+ M_BRUSHDATA->m_colour.Set(r, g, b);
+
+ RealizeResource();
+}
+
+void wxBrush::SetStyle(int Style)
+{
+ Unshare();
+
+ M_BRUSHDATA->m_macBrushKind = kwxMacBrushColour;
+ M_BRUSHDATA->m_style = Style;
+
+ RealizeResource();
+}
+
+void wxBrush::SetStipple(const wxBitmap& Stipple)
+{
+ Unshare();
+
+ M_BRUSHDATA->m_macBrushKind = kwxMacBrushColour;
+ M_BRUSHDATA->m_stipple = Stipple;
+
+ RealizeResource();
+}
+
+void wxBrush::SetMacTheme(ThemeBrush macThemeBrush)
+{
+ Unshare();
+
+ M_BRUSHDATA->m_macBrushKind = kwxMacBrushTheme;
+ M_BRUSHDATA->m_macThemeBrush = macThemeBrush;
+
+ RealizeResource();
+}
+
+void wxBrush::SetMacThemeBackground(unsigned long macThemeBackground, const WXRECTPTR extent)
+{
+ Unshare();
+
+ M_BRUSHDATA->m_macBrushKind = kwxMacBrushThemeBackground;
+ M_BRUSHDATA->m_macThemeBackground = macThemeBackground;
+ M_BRUSHDATA->m_macThemeBackgroundExtent = *(Rect*)extent ;
+ RealizeResource();
+}
+
+bool wxBrush::RealizeResource()
+{
+ return TRUE;
+}
+
+unsigned long wxBrush::GetMacThemeBackground( WXRECTPTR extent) const
+{
+ if ( M_BRUSHDATA && M_BRUSHDATA->m_macBrushKind == kwxMacBrushThemeBackground )
+ {
+ if ( extent )
+ *(Rect*)extent = M_BRUSHDATA->m_macThemeBackgroundExtent ;
+ return M_BRUSHDATA->m_macThemeBackground ;
+ }
+ else
+ {
+ return 0 ;
+ }
+}
+
+short wxBrush::GetMacTheme() const
+{
+ return (M_BRUSHDATA ? ( M_BRUSHDATA->m_macBrushKind == kwxMacBrushTheme ? M_BRUSHDATA->m_macThemeBrush : kThemeBrushBlack) : kThemeBrushBlack);
+}
+
+wxColour& wxBrush::GetColour() const
+{
+ return (M_BRUSHDATA ? M_BRUSHDATA->m_colour : wxNullColour);
+}
+
+int wxBrush::GetStyle() const
+{
+ return (M_BRUSHDATA ? M_BRUSHDATA->m_style : 0);
+}
+
+wxBitmap *wxBrush::GetStipple() const
+{
+ return (M_BRUSHDATA ? & M_BRUSHDATA->m_stipple : 0);
+}
+
+wxMacBrushKind wxBrush::MacGetBrushKind() const
+{
+ return (M_BRUSHDATA ? M_BRUSHDATA->m_macBrushKind : kwxMacBrushColour);
+}
\ No newline at end of file
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: button.cpp
+// Purpose: wxButton
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "button.h"
+#endif
+
+#include "wx/defs.h"
+
+#include "wx/button.h"
+#include "wx/panel.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxButton, wxControl)
+#endif
+
+#include "wx/mac/uma.h"
+// Button
+
+static const int kMacOSXHorizontalBorder = 2 ;
+static const int kMacOSXVerticalBorder = 4 ;
+
+bool wxButton::Create(wxWindow *parent, wxWindowID id, const wxString& label,
+ const wxPoint& pos,
+ const wxSize& size, long style,
+ const wxValidator& validator,
+ const wxString& name)
+{
+ if ( !wxButtonBase::Create(parent, id, pos, size, style, validator, name) )
+ return false;
+
+ Rect bounds ;
+ Str255 title ;
+
+ if ( UMAHasAquaLayout() )
+ {
+ m_macHorizontalBorder = kMacOSXHorizontalBorder;
+ m_macVerticalBorder = kMacOSXVerticalBorder;
+ }
+
+ MacPreControlCreate( parent , id , label , pos , size ,style, validator , name , &bounds , title ) ;
+
+ m_macControl = ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , title , false , 0 , 0 , 1,
+ kControlPushButtonProc , (long) this ) ;
+ wxASSERT_MSG( (ControlHandle) m_macControl != NULL , wxT("No valid mac control") ) ;
+
+ MacPostControlCreate() ;
+
+ return TRUE;
+}
+
+void wxButton::SetDefault()
+{
+ wxWindow *parent = GetParent();
+ wxButton *btnOldDefault = NULL;
+ if ( parent )
+ {
+ btnOldDefault = wxDynamicCast(parent->GetDefaultItem(),
+ wxButton);
+ parent->SetDefaultItem(this);
+ }
+
+ Boolean inData;
+ if ( btnOldDefault && btnOldDefault->m_macControl )
+ {
+ inData = 0;
+ ::SetControlData( (ControlHandle) btnOldDefault->m_macControl , kControlButtonPart ,
+ kControlPushButtonDefaultTag , sizeof( Boolean ) , (char*)(&inData) ) ;
+ }
+ if ( (ControlHandle) m_macControl )
+ {
+ inData = 1;
+ ::SetControlData( (ControlHandle) m_macControl , kControlButtonPart ,
+ kControlPushButtonDefaultTag , sizeof( Boolean ) , (char*)(&inData) ) ;
+ }
+}
+
+wxSize wxButton::DoGetBestSize() const
+{
+ wxSize sz = GetDefaultSize() ;
+
+ int wBtn = m_label.Length() * 8 + 12 + 2 * kMacOSXHorizontalBorder ;
+
+ if (wBtn > sz.x) sz.x = wBtn;
+
+ return sz ;
+}
+
+wxSize wxButton::GetDefaultSize()
+{
+ int wBtn = 70 ;
+ int hBtn = 20 ;
+
+ if ( UMAHasAquaLayout() )
+ {
+ wBtn += 2 * kMacOSXHorizontalBorder ;
+ hBtn += 2 * kMacOSXVerticalBorder ;
+ }
+
+ return wxSize(wBtn, hBtn);
+}
+
+void wxButton::Command (wxCommandEvent & event)
+{
+ if ( (ControlHandle) m_macControl )
+ {
+ HiliteControl( (ControlHandle) m_macControl , kControlButtonPart ) ;
+ unsigned long finalTicks ;
+ Delay( 8 , &finalTicks ) ;
+ HiliteControl( (ControlHandle) m_macControl , 0 ) ;
+ }
+ ProcessCommand (event);
+}
+
+void wxButton::MacHandleControlClick( WXWidget WXUNUSED(control) , wxInt16 controlpart , bool WXUNUSED(mouseStillDown) )
+{
+ if ( controlpart != kControlNoPart )
+ {
+ wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, m_windowId );
+ event.SetEventObject(this);
+ ProcessCommand(event);
+ }
+}
+
--- /dev/null
+// carbon for 9
+data 'carb' (0) {
+ $"0000" /* .. */
+};
+
+// the plist resource should only be included in the application
+// since it contains the bundle information and should not be duplicated
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: checkbox.cpp
+// Purpose: wxCheckBox
+// Author: Stefan Csomor
+// Modified by:
+// Created: 04/01/98
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "checkbox.h"
+#endif
+
+#include "wx/defs.h"
+
+#include "wx/checkbox.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxCheckBox, wxControl)
+IMPLEMENT_DYNAMIC_CLASS(wxBitmapCheckBox, wxCheckBox)
+#endif
+
+#include "wx/mac/uma.h"
+
+// Single check box item
+bool wxCheckBox::Create(wxWindow *parent, wxWindowID id, const wxString& label,
+ const wxPoint& pos,
+ const wxSize& size, long style,
+ const wxValidator& validator,
+ const wxString& name)
+{
+ if ( !wxCheckBoxBase::Create(parent, id, pos, size, style, validator, name) )
+ return false;
+
+ Rect bounds ;
+ Str255 title ;
+
+ MacPreControlCreate( parent , id , label , pos , size ,style, validator , name , &bounds , title ) ;
+
+ SInt16 maxValue = 1 /* kControlCheckboxCheckedValue */;
+ if (style & wxCHK_3STATE)
+ {
+ maxValue = 2 /* kControlCheckboxMixedValue */;
+ }
+
+ m_macControl = ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , title , false , 0 , 0 , maxValue,
+ kControlCheckBoxProc , (long) this ) ;
+
+ MacPostControlCreate() ;
+
+ return TRUE;
+}
+
+void wxCheckBox::SetValue(bool val)
+{
+ if (val)
+ {
+ Set3StateValue(wxCHK_CHECKED);
+ }
+ else
+ {
+ Set3StateValue(wxCHK_UNCHECKED);
+ }
+}
+
+bool wxCheckBox::GetValue() const
+{
+ return (DoGet3StateValue() != 0);
+}
+
+void wxCheckBox::Command (wxCommandEvent & event)
+{
+ int state = event.GetInt();
+
+ wxCHECK_RET( (state == wxCHK_UNCHECKED) || (state == wxCHK_CHECKED)
+ || (state == wxCHK_UNDETERMINED),
+ wxT("event.GetInt() returned an invalid checkbox state") );
+
+ Set3StateValue((wxCheckBoxState) state);
+
+ ProcessCommand(event);
+}
+
+wxCheckBoxState wxCheckBox::DoGet3StateValue() const
+{
+ return (wxCheckBoxState) ::GetControl32BitValue( (ControlHandle) m_macControl );
+}
+
+void wxCheckBox::DoSet3StateValue(wxCheckBoxState val)
+{
+ ::SetControl32BitValue( (ControlHandle) m_macControl , (int) val) ;
+ MacRedrawControl() ;
+}
+
+void wxCheckBox::MacHandleControlClick( WXWidget WXUNUSED(control), wxInt16 WXUNUSED(controlpart) , bool WXUNUSED(mouseStillDown) )
+{
+ wxCommandEvent event(wxEVT_COMMAND_CHECKBOX_CLICKED, m_windowId );
+ wxCheckBoxState state = Get3StateValue();
+
+ if (state == wxCHK_UNCHECKED)
+ {
+ state = wxCHK_CHECKED;
+ }
+ else if (state == wxCHK_CHECKED)
+ {
+ // If the style flag to allow the user setting the undetermined state
+ // is set, then set the state to undetermined. Otherwise set state to
+ // unchecked.
+ if ( Is3rdStateAllowedForUser() )
+ {
+ state = wxCHK_UNDETERMINED;
+ }
+ else
+ {
+ state = wxCHK_UNCHECKED;
+ }
+ }
+ else if (state == wxCHK_UNDETERMINED)
+ {
+ state = wxCHK_UNCHECKED;
+ }
+ Set3StateValue(state);
+
+ event.SetInt(state);
+ event.SetEventObject(this);
+ ProcessCommand(event);
+}
+
+// Bitmap checkbox
+bool wxBitmapCheckBox::Create(wxWindow *parent, wxWindowID id,
+ const wxBitmap *label,
+ const wxPoint& pos,
+ const wxSize& size, long style,
+ const wxValidator& validator,
+ const wxString& name)
+{
+ SetName(name);
+ SetValidator(validator);
+ m_windowStyle = style;
+
+ if (parent) parent->AddChild(this);
+
+ if ( id == -1 )
+ m_windowId = NewControlId();
+ else
+ m_windowId = id;
+
+ // TODO: Create the bitmap checkbox
+
+ return FALSE;
+}
+
+void wxBitmapCheckBox::SetLabel(const wxBitmap *bitmap)
+{
+ // TODO
+ wxFAIL_MSG(wxT("wxBitmapCheckBox::SetLabel() not yet implemented"));
+}
+
+void wxBitmapCheckBox::SetSize(int x, int y, int width, int height, int sizeFlags)
+{
+ wxControl::SetSize( x , y , width , height , sizeFlags ) ;
+}
+
+void wxBitmapCheckBox::SetValue(bool val)
+{
+ // TODO
+ wxFAIL_MSG(wxT("wxBitmapCheckBox::SetValue() not yet implemented"));
+}
+
+bool wxBitmapCheckBox::GetValue() const
+{
+ // TODO
+ wxFAIL_MSG(wxT("wxBitmapCheckBox::GetValue() not yet implemented"));
+ return FALSE;
+}
+
+
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Name: checklst.cpp
+// Purpose: implementation of wxCheckListBox class
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// headers & declarations
+// ============================================================================
+
+#ifdef __GNUG__
+#pragma implementation "checklst.h"
+#endif
+
+#include "wx/defs.h"
+
+#if wxUSE_CHECKLISTBOX
+
+#include "wx/checklst.h"
+#include "wx/arrstr.h"
+
+#include "wx/mac/uma.h"
+#include <Appearance.h>
+
+// ============================================================================
+// implementation of wxCheckListBox
+// ============================================================================
+
+IMPLEMENT_DYNAMIC_CLASS(wxCheckListBox, wxListBox)
+
+const short kwxMacListWithVerticalScrollbar = 128 ;
+const short kwxMacListItemHeight = 14 ;
+const short kwxMacListCheckboxWidth = 14 ;
+
+#if PRAGMA_STRUCT_ALIGN
+ #pragma options align=mac68k
+#elif PRAGMA_STRUCT_PACKPUSH
+ #pragma pack(push, 2)
+#elif PRAGMA_STRUCT_PACK
+ #pragma pack(2)
+#endif
+
+typedef struct {
+ unsigned short instruction;
+ void (*function)();
+} ldefRec, *ldefPtr, **ldefHandle;
+
+#if PRAGMA_STRUCT_ALIGN
+ #pragma options align=reset
+#elif PRAGMA_STRUCT_PACKPUSH
+ #pragma pack(pop)
+#elif PRAGMA_STRUCT_PACK
+ #pragma pack()
+#endif
+
+extern "C"
+{
+static pascal void wxMacCheckListDefinition( short message, Boolean isSelected, Rect *drawRect,
+ Cell cell, short dataOffset, short dataLength,
+ ListHandle listHandle ) ;
+}
+
+static pascal void wxMacCheckListDefinition( short message, Boolean isSelected, Rect *drawRect,
+ Cell cell, short dataOffset, short dataLength,
+ ListHandle listHandle )
+{
+ wxCheckListBox* list;
+ list = (wxCheckListBox*) GetControlReference( (ControlHandle) GetListRefCon(listHandle) );
+ if ( list == NULL )
+ return ;
+
+ GrafPtr savePort;
+ GrafPtr grafPtr;
+ RgnHandle savedClipRegion;
+ SInt32 savedPenMode;
+ GetPort(&savePort);
+ SetPort((**listHandle).port);
+ grafPtr = (**listHandle).port ;
+ // typecast our refCon
+
+ // Calculate the cell rect.
+
+ switch( message ) {
+ case lInitMsg:
+ break;
+
+ case lCloseMsg:
+ break;
+
+ case lDrawMsg:
+ {
+ const wxString text = list->m_stringArray[cell.v] ;
+ int checked = list->m_checks[cell.v] ;
+
+ // Save the current clip region, and set the clip region to the area we are about
+ // to draw.
+
+ savedClipRegion = NewRgn();
+ GetClip( savedClipRegion );
+
+ ClipRect( drawRect );
+ EraseRect( drawRect );
+
+ const wxFont& font = list->GetFont();
+ if ( font.Ok() )
+ {
+ ::TextFont( font.GetMacFontNum() ) ;
+ ::TextSize( font.GetMacFontSize()) ;
+ ::TextFace( font.GetMacFontStyle() ) ;
+ }
+
+ ThemeButtonDrawInfo info ;
+ info.state = kThemeStateActive ;
+ info.value = checked ? kThemeButtonOn : kThemeButtonOff ;
+ info.adornment = kThemeAdornmentNone ;
+ Rect checkRect = *drawRect ;
+
+
+ checkRect.left +=0 ;
+ checkRect.top +=0 ;
+ checkRect.right = checkRect.left + list->m_checkBoxWidth ;
+ checkRect.bottom = checkRect.top + list->m_checkBoxHeight ;
+ DrawThemeButton(&checkRect,kThemeCheckBox,
+ &info,NULL,NULL, NULL,0);
+
+ MoveTo(drawRect->left + 2 + list->m_checkBoxWidth+2, drawRect->top + list->m_TextBaseLineOffset );
+
+ DrawText(text, 0 , text.Length());
+ // If the cell is hilited, do the hilite now. Paint the cell contents with the
+ // appropriate QuickDraw transform mode.
+
+ if( isSelected ) {
+ savedPenMode = GetPortPenMode( (CGrafPtr) grafPtr );
+ SetPortPenMode( (CGrafPtr) grafPtr, hilitetransfermode );
+ PaintRect( drawRect );
+ SetPortPenMode( (CGrafPtr) grafPtr, savedPenMode );
+ }
+
+ // Restore the saved clip region.
+
+ SetClip( savedClipRegion );
+ DisposeRgn( savedClipRegion );
+ }
+ break;
+ case lHiliteMsg:
+
+ // Hilite or unhilite the cell. Paint the cell contents with the
+ // appropriate QuickDraw transform mode.
+
+ GetPort( &grafPtr );
+ savedPenMode = GetPortPenMode( (CGrafPtr) grafPtr );
+ SetPortPenMode( (CGrafPtr) grafPtr, hilitetransfermode );
+ PaintRect( drawRect );
+ SetPortPenMode( (CGrafPtr) grafPtr, savedPenMode );
+ break;
+ default :
+ break ;
+ }
+ SetPort(savePort);
+}
+
+extern "C" void MacDrawStringCell(Rect *cellRect, Cell lCell, ListHandle theList, long refCon) ;
+
+static ListDefUPP macCheckListDefUPP = NULL ;
+
+// ----------------------------------------------------------------------------
+// creation
+// ----------------------------------------------------------------------------
+
+void wxCheckListBox::Init()
+{
+}
+
+bool wxCheckListBox::Create(wxWindow *parent,
+ wxWindowID id,
+ const wxPoint &pos,
+ const wxSize &size,
+ const wxArrayString& choices,
+ long style,
+ const wxValidator& validator,
+ const wxString &name)
+{
+ wxCArrayString chs(choices);
+
+ return Create(parent, id, pos, size, chs.GetCount(), chs.GetStrings(),
+ style, validator, name);
+}
+
+bool wxCheckListBox::Create(wxWindow *parent,
+ wxWindowID id,
+ const wxPoint &pos,
+ const wxSize &size,
+ int n,
+ const wxString choices[],
+ long style,
+ const wxValidator& validator,
+ const wxString &name)
+{
+ if ( !wxCheckListBoxBase::Create(parent, id, pos, size,
+ n, choices, style, validator, name) )
+ return false;
+
+ m_noItems = 0 ; // this will be increased by our append command
+ m_selected = 0;
+
+ m_checkBoxWidth = 12;
+ m_checkBoxHeight= 10;
+
+ long h = m_checkBoxHeight ;
+#if TARGET_CARBON
+ GetThemeMetric(kThemeMetricCheckBoxWidth,(long *)&m_checkBoxWidth);
+ GetThemeMetric(kThemeMetricCheckBoxHeight,&h);
+#endif
+
+ const wxFont& font = GetFont();
+
+ FontInfo finfo;
+ FetchFontInfo(font.GetMacFontNum(),font.GetMacFontSize(),font.GetMacFontStyle(),&finfo);
+
+ m_TextBaseLineOffset= finfo.leading+finfo.ascent;
+ m_checkBoxHeight= finfo.leading+finfo.ascent+finfo.descent;
+
+ if (m_checkBoxHeight<h)
+ {
+ m_TextBaseLineOffset+= (h-m_checkBoxHeight)/2;
+ m_checkBoxHeight= h;
+ }
+
+ Rect bounds ;
+ Str255 title ;
+
+ MacPreControlCreate( parent , id , wxEmptyString , pos , size ,style, validator , name , &bounds , title ) ;
+
+ ListDefSpec listDef;
+ listDef.defType = kListDefUserProcType;
+ if ( macCheckListDefUPP == NULL )
+ {
+ macCheckListDefUPP = NewListDefUPP( wxMacCheckListDefinition );
+ }
+ listDef.u.userProc = macCheckListDefUPP ;
+
+#if TARGET_CARBON
+ Size asize;
+
+
+ CreateListBoxControl( MAC_WXHWND(parent->MacGetRootWindow()), &bounds, false, 0, 1, false, true,
+ m_checkBoxHeight+2, 14, false, &listDef, (ControlRef *)&m_macControl );
+
+ GetControlData( (ControlHandle) m_macControl, kControlNoPart, kControlListBoxListHandleTag,
+ sizeof(ListHandle), (Ptr) &m_macList, &asize);
+
+ SetControlReference( (ControlHandle) m_macControl, (long) this);
+ SetControlVisibility( (ControlHandle) m_macControl, false, false);
+
+#else
+
+ long result ;
+
+ wxStAppResource resload ;
+ m_macControl = ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , title , false ,
+ kwxMacListWithVerticalScrollbar , 0 , 0,
+ kControlListBoxProc , (long) this ) ;
+ ::GetControlData( (ControlHandle) m_macControl , kControlNoPart , kControlListBoxListHandleTag ,
+ sizeof( ListHandle ) , (char*) &m_macList , &result ) ;
+
+ HLock( (Handle) m_macList ) ;
+ ldefHandle ldef ;
+ ldef = (ldefHandle) NewHandle( sizeof(ldefRec) ) ;
+ if ( (**(ListHandle)m_macList).listDefProc != NULL )
+ {
+ (**ldef).instruction = 0x4EF9; /* JMP instruction */
+ (**ldef).function = (void(*)()) listDef.u.userProc;
+ (**(ListHandle)m_macList).listDefProc = (Handle) ldef ;
+ }
+
+ Point pt = (**(ListHandle)m_macList).cellSize ;
+ pt.v = 14 ;
+ LCellSize( pt , (ListHandle)m_macList ) ;
+ LAddColumn( 1 , 0 , (ListHandle)m_macList ) ;
+#endif
+ OptionBits options = 0;
+ if ( style & wxLB_MULTIPLE )
+ {
+ options += lNoExtend ;
+ }
+ else if ( style & wxLB_EXTENDED )
+ {
+ options += lExtendDrag ;
+ }
+ else
+ {
+ options = (OptionBits) lOnlyOne ;
+ }
+ SetListSelectionFlags((ListHandle)m_macList, options);
+
+ MacPostControlCreate() ;
+
+ for ( int i = 0 ; i < n ; i++ )
+ {
+ Append( choices[i] ) ;
+ }
+
+ LSetDrawingMode( true , (ListHandle) m_macList ) ;
+
+ return TRUE;
+}
+
+// ----------------------------------------------------------------------------
+// wxCheckListBox functions
+// ----------------------------------------------------------------------------
+
+bool wxCheckListBox::IsChecked(size_t item) const
+{
+ wxCHECK_MSG( item < m_checks.GetCount(), FALSE,
+ _T("invalid index in wxCheckListBox::IsChecked") );
+
+ return m_checks[item] != 0;
+}
+
+void wxCheckListBox::Check(size_t item, bool check)
+{
+ wxCHECK_RET( item < m_checks.GetCount(),
+ _T("invalid index in wxCheckListBox::Check") );
+
+ // intermediate var is needed to avoid compiler warning with VC++
+ bool isChecked = m_checks[item] != 0;
+ if ( check != isChecked )
+ {
+ m_checks[item] = check;
+
+ MacRedrawControl() ;
+ }
+}
+
+// ----------------------------------------------------------------------------
+// methods forwarded to wxListBox
+// ----------------------------------------------------------------------------
+
+void wxCheckListBox::Delete(int n)
+{
+ wxCHECK_RET( n < GetCount(), _T("invalid index in wxListBox::Delete") );
+
+ wxListBox::Delete(n);
+
+ m_checks.RemoveAt(n);
+}
+
+int wxCheckListBox::DoAppend(const wxString& item)
+{
+ LSetDrawingMode( false , (ListHandle) m_macList ) ;
+ int pos = wxListBox::DoAppend(item);
+
+ // the item is initially unchecked
+ m_checks.Insert(FALSE, pos);
+ LSetDrawingMode( true , (ListHandle) m_macList ) ;
+
+ return pos;
+}
+
+void wxCheckListBox::DoInsertItems(const wxArrayString& items, int pos)
+{
+ wxListBox::DoInsertItems(items, pos);
+
+ size_t count = items.GetCount();
+ for ( size_t n = 0; n < count; n++ )
+ {
+ m_checks.Insert(FALSE, pos + n);
+ }
+}
+
+void wxCheckListBox::DoSetItems(const wxArrayString& items, void **clientData)
+{
+ // call it first as it does DoClear()
+ wxListBox::DoSetItems(items, clientData);
+
+ size_t count = items.GetCount();
+ for ( size_t n = 0; n < count; n++ )
+ {
+ m_checks.Add(FALSE);
+ }
+}
+
+void wxCheckListBox::DoClear()
+{
+ m_checks.Empty();
+}
+
+BEGIN_EVENT_TABLE(wxCheckListBox, wxListBox)
+ EVT_CHAR(wxCheckListBox::OnChar)
+ EVT_LEFT_DOWN(wxCheckListBox::OnLeftClick)
+END_EVENT_TABLE()
+
+// this will only work as soon as
+
+void wxCheckListBox::OnChar(wxKeyEvent& event)
+{
+ if ( event.GetKeyCode() == WXK_SPACE )
+ {
+ int index = GetSelection() ;
+ if ( index >= 0 )
+ {
+ Check(index, !IsChecked(index) ) ;
+ wxCommandEvent event(wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, GetId());
+ event.SetInt(index);
+ event.SetEventObject(this);
+ GetEventHandler()->ProcessEvent(event);
+ }
+ }
+ else
+ event.Skip();
+}
+
+void wxCheckListBox::OnLeftClick(wxMouseEvent& event)
+{
+ // clicking on the item selects it, clicking on the checkmark toggles
+ if ( event.GetX() <= 20 /*check width*/ ) {
+ int lineheight ;
+ int topcell ;
+#if TARGET_CARBON
+ Point pt ;
+ GetListCellSize( (ListHandle)m_macList , &pt ) ;
+ lineheight = pt.v ;
+ ListBounds visible ;
+ GetListVisibleCells( (ListHandle)m_macList , &visible ) ;
+ topcell = visible.top ;
+#else
+ lineheight = (**(ListHandle)m_macList).cellSize.v ;
+ topcell = (**(ListHandle)m_macList).visible.top ;
+#endif
+ size_t nItem = ((size_t)event.GetY()) / lineheight + topcell ;
+
+ if ( nItem < (size_t)m_noItems )
+ {
+ Check(nItem, !IsChecked(nItem) ) ;
+ wxCommandEvent event(wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, GetId());
+ event.SetInt(nItem);
+ event.SetEventObject(this);
+ GetEventHandler()->ProcessEvent(event);
+ }
+ //else: it's not an error, just click outside of client zone
+ }
+ else {
+ // implement default behaviour: clicking on the item selects it
+ event.Skip();
+ }
+}
+
+#endif // wxUSE_CHECKLISTBOX
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: choice.cpp
+// Purpose: wxChoice
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "choice.h"
+#endif
+
+#include "wx/defs.h"
+#include "wx/choice.h"
+#include "wx/menu.h"
+#include "wx/mac/uma.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxChoice, wxControl)
+#endif
+
+extern MenuHandle NewUniqueMenu() ;
+
+wxChoice::~wxChoice()
+{
+ if ( HasClientObjectData() )
+ {
+ size_t i, max = GetCount();
+
+ for ( i = 0; i < max; ++i )
+ delete GetClientObject(i);
+ }
+
+ // DeleteMenu( m_macPopUpMenuId ) ;
+ // DisposeMenu( m_macPopUpMenuHandle ) ;
+}
+
+bool wxChoice::Create(wxWindow *parent, wxWindowID id,
+ const wxPoint& pos,
+ const wxSize& size,
+ const wxArrayString& choices,
+ long style,
+ const wxValidator& validator,
+ const wxString& name)
+{
+ wxCArrayString chs(choices);
+
+ return Create(parent, id, pos, size, chs.GetCount(), chs.GetStrings(),
+ style, validator, name);
+}
+
+bool wxChoice::Create(wxWindow *parent, wxWindowID id,
+ const wxPoint& pos,
+ const wxSize& size,
+ int n, const wxString choices[],
+ long style,
+ const wxValidator& validator,
+ const wxString& name)
+{
+ if ( !wxChoiceBase::Create(parent, id, pos, size, style, validator, name) )
+ return false;
+
+ Rect bounds ;
+ Str255 title ;
+
+ MacPreControlCreate( parent , id , wxEmptyString , pos , size ,style, validator , name , &bounds , title ) ;
+ m_macControl = ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , title , false , 0 , -12345 , 0 ,
+ kControlPopupButtonProc + kControlPopupFixedWidthVariant , (long) this ) ;
+
+ m_macPopUpMenuHandle = NewUniqueMenu() ;
+ SetControlData( (ControlHandle) m_macControl , kControlNoPart , kControlPopupButtonMenuHandleTag , sizeof( MenuHandle ) , (char*) &m_macPopUpMenuHandle) ;
+ SetControl32BitMinimum( (ControlHandle) m_macControl , 0 ) ;
+ SetControl32BitMaximum( (ControlHandle) m_macControl , 0) ;
+ if ( n > 0 )
+ SetControl32BitValue( (ControlHandle) m_macControl , 1 ) ;
+ MacPostControlCreate() ;
+ // TODO wxCB_SORT
+ for ( int i = 0; i < n; i++ )
+ {
+ Append(choices[i]);
+ }
+ return TRUE;
+}
+
+// ----------------------------------------------------------------------------
+// adding/deleting items to/from the list
+// ----------------------------------------------------------------------------
+int wxChoice::DoAppend(const wxString& item)
+{
+ UMAAppendMenuItem(MAC_WXHMENU( m_macPopUpMenuHandle ) , item, m_font.GetEncoding() );
+ m_strings.Add( item ) ;
+ m_datas.Add( NULL ) ;
+ int index = m_strings.GetCount() - 1 ;
+ DoSetItemClientData( index , NULL ) ;
+ SetControl32BitMaximum( (ControlHandle) m_macControl , GetCount()) ;
+ return index ;
+}
+
+int wxChoice::DoInsert(const wxString& item, int pos)
+{
+ wxCHECK_MSG(!(GetWindowStyle() & wxCB_SORT), -1, wxT("can't insert into sorted list"));
+ wxCHECK_MSG((pos>=0) && (pos<=GetCount()), -1, wxT("invalid index"));
+
+ if (pos == GetCount())
+ return DoAppend(item);
+
+ UMAAppendMenuItem(MAC_WXHMENU( m_macPopUpMenuHandle ) , item, m_font.GetEncoding() );
+ m_strings.Insert( item, pos ) ;
+ m_datas.Insert( NULL, pos ) ;
+ DoSetItemClientData( pos , NULL ) ;
+ SetControl32BitMaximum( (ControlHandle) m_macControl , pos) ;
+ return pos ;
+}
+
+void wxChoice::Delete(int n)
+{
+ wxCHECK_RET( n < GetCount(), wxT("invalid item index in wxChoice::Delete") );
+ if ( HasClientObjectData() )
+ {
+ delete GetClientObject(n);
+ }
+ ::DeleteMenuItem( MAC_WXHMENU(m_macPopUpMenuHandle) , n + 1) ;
+ m_strings.RemoveAt( n ) ;
+ m_datas.RemoveAt( n ) ;
+ SetControl32BitMaximum( (ControlHandle) m_macControl , GetCount()) ;
+}
+
+void wxChoice::Clear()
+{
+ FreeData();
+ for ( int i = 0 ; i < GetCount() ; i++ )
+ {
+ ::DeleteMenuItem( MAC_WXHMENU(m_macPopUpMenuHandle) , 1 ) ;
+ }
+ m_strings.Empty() ;
+ m_datas.Empty() ;
+ SetControl32BitMaximum( (ControlHandle) m_macControl , 0 ) ;
+}
+
+void wxChoice::FreeData()
+{
+ if ( HasClientObjectData() )
+ {
+ size_t count = GetCount();
+ for ( size_t n = 0; n < count; n++ )
+ {
+ delete GetClientObject(n);
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+// selection
+// ----------------------------------------------------------------------------
+int wxChoice::GetSelection() const
+{
+ return GetControl32BitValue( (ControlHandle) m_macControl ) -1 ;
+}
+
+void wxChoice::SetSelection(int n)
+{
+ SetControl32BitValue( (ControlHandle) m_macControl , n + 1 ) ;
+}
+
+// ----------------------------------------------------------------------------
+// string list functions
+// ----------------------------------------------------------------------------
+
+int wxChoice::GetCount() const
+{
+ return m_strings.GetCount() ;
+}
+
+int wxChoice::FindString(const wxString& s) const
+{
+ for( int i = 0 ; i < GetCount() ; i++ )
+ {
+ if ( GetString( i ).IsSameAs(s, FALSE) )
+ return i ;
+ }
+ return wxNOT_FOUND ;
+}
+
+void wxChoice::SetString(int n, const wxString& s)
+{
+ wxFAIL_MSG(wxT("wxChoice::SetString() not yet implemented"));
+#if 0 // should do this, but no Insert() so far
+ Delete(n);
+ Insert(n + 1, s);
+#endif
+}
+
+wxString wxChoice::GetString(int n) const
+{
+ wxCHECK_MSG( n >= 0 && (size_t)n < m_strings.GetCount(), _T(""),
+ _T("wxChoice::GetString(): invalid index") );
+
+ return m_strings[n] ;
+}
+
+// ----------------------------------------------------------------------------
+// client data
+// ----------------------------------------------------------------------------
+void wxChoice::DoSetItemClientData( int n, void* clientData )
+{
+ wxCHECK_RET( n >= 0 && (size_t)n < m_datas.GetCount(),
+ wxT("invalid index in wxChoice::SetClientData") );
+
+ m_datas[n] = (char*) clientData ;
+}
+
+void *wxChoice::DoGetItemClientData(int n) const
+{
+ wxCHECK_MSG( n >= 0 && (size_t)n < m_datas.GetCount(), NULL,
+ wxT("invalid index in wxChoice::GetClientData") );
+ return (void *)m_datas[n];
+}
+
+void wxChoice::DoSetItemClientObject( int n, wxClientData* clientData )
+{
+ DoSetItemClientData(n, clientData);
+}
+
+wxClientData* wxChoice::DoGetItemClientObject( int n ) const
+{
+ return (wxClientData *)DoGetItemClientData(n);
+}
+
+void wxChoice::MacHandleControlClick( WXWidget control , wxInt16 controlpart , bool WXUNUSED(mouseStillDown))
+{
+ wxCommandEvent event(wxEVT_COMMAND_CHOICE_SELECTED, m_windowId );
+ int n = GetSelection();
+ // actually n should be made sure by the os to be a valid selection, but ...
+ if ( n > -1 )
+ {
+ event.SetInt( n );
+ event.SetString(GetStringSelection());
+ event.SetEventObject(this);
+ if ( HasClientObjectData() )
+ event.SetClientObject( GetClientObject(n) );
+ else if ( HasClientUntypedData() )
+ event.SetClientData( GetClientData(n) );
+ ProcessCommand(event);
+ }
+}
+
+wxSize wxChoice::DoGetBestSize() const
+{
+ int lbWidth = GetCount() > 0 ? 20 : 100; // some defaults
+ int lbHeight = 20;
+ int wLine;
+#if TARGET_CARBON
+ long metric ;
+ GetThemeMetric(kThemeMetricPopupButtonHeight , &metric );
+ lbHeight = metric ;
+#endif
+ {
+ wxMacPortStateHelper st( UMAGetWindowPort( (WindowRef) MacGetRootWindow() ) ) ;
+ if ( m_font.Ok() )
+ {
+ ::TextFont( m_font.GetMacFontNum() ) ;
+ ::TextSize( m_font.GetMacFontSize() ) ;
+ ::TextFace( m_font.GetMacFontStyle() ) ;
+ }
+ else
+ {
+ ::TextFont( kFontIDMonaco ) ;
+ ::TextSize( 9 );
+ ::TextFace( 0 ) ;
+ }
+ // Find the widest line
+ for(int i = 0; i < GetCount(); i++) {
+ wxString str(GetString(i));
+ #if wxUSE_UNICODE
+ Point bounds={0,0} ;
+ SInt16 baseline ;
+ ::GetThemeTextDimensions( wxMacCFStringHolder( str , m_font.GetEncoding() ) ,
+ kThemeCurrentPortFont,
+ kThemeStateActive,
+ false,
+ &bounds,
+ &baseline );
+ wLine = bounds.h ;
+ #else
+ wLine = ::TextWidth( str.c_str() , 0 , str.Length() ) ;
+ #endif
+ lbWidth = wxMax(lbWidth, wLine);
+ }
+ // Add room for the popup arrow
+ lbWidth += 2 * lbHeight ;
+ // And just a bit more
+ int cx = ::TextWidth( "X" , 0 , 1 ) ;
+ lbWidth += cx ;
+
+ }
+ return wxSize(lbWidth, lbHeight);
+}
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: clipbrd.cpp
+// Purpose: Clipboard functionality
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "clipbrd.h"
+#endif
+
+#include "wx/app.h"
+#include "wx/frame.h"
+#include "wx/bitmap.h"
+#include "wx/utils.h"
+#include "wx/metafile.h"
+#include "wx/clipbrd.h"
+#include "wx/intl.h"
+#include "wx/log.h"
+
+#ifndef __DARWIN__
+#include <Scrap.h>
+#endif
+#include "wx/mac/uma.h"
+
+#define wxUSE_DATAOBJ 1
+
+#include <string.h>
+
+// the trace mask we use with wxLogTrace() - call
+// wxLog::AddTraceMask(TRACE_CLIPBOARD) to enable the trace messages from here
+// (there will be a *lot* of them!)
+static const wxChar *TRACE_CLIPBOARD = _T("clipboard");
+
+void *wxGetClipboardData(wxDataFormat dataFormat, long *len)
+{
+#if !TARGET_CARBON
+ OSErr err = noErr ;
+#else
+ OSStatus err = noErr ;
+#endif
+ void * data = NULL ;
+ Size byteCount;
+
+ switch (dataFormat.GetType())
+ {
+ case wxDF_OEMTEXT:
+ dataFormat = wxDF_TEXT;
+ // fall through
+
+ case wxDF_TEXT:
+ break;
+ case wxDF_UNICODETEXT:
+ break;
+ case wxDF_BITMAP :
+ case wxDF_METAFILE :
+ break ;
+ default:
+ {
+ wxLogError(_("Unsupported clipboard format."));
+ return NULL;
+ }
+ }
+
+#if TARGET_CARBON
+ ScrapRef scrapRef;
+
+ err = GetCurrentScrap( &scrapRef );
+ if ( err != noTypeErr && err != memFullErr )
+ {
+ ScrapFlavorFlags flavorFlags;
+
+ if (( err = GetScrapFlavorFlags( scrapRef, dataFormat.GetFormatId(), &flavorFlags )) == noErr)
+ {
+ if (( err = GetScrapFlavorSize( scrapRef, dataFormat.GetFormatId(), &byteCount )) == noErr)
+ {
+ Size allocSize = byteCount ;
+ if ( dataFormat.GetType() == wxDF_TEXT )
+ allocSize += 1 ;
+ else if ( dataFormat.GetType() == wxDF_UNICODETEXT )
+ allocSize += 2 ;
+
+ data = new char[ allocSize ] ;
+
+ if (( err = GetScrapFlavorData( scrapRef, dataFormat.GetFormatId(), &byteCount , data )) == noErr )
+ {
+ *len = allocSize ;
+ if ( dataFormat.GetType() == wxDF_TEXT )
+ ((char*)data)[byteCount] = 0 ;
+ if ( dataFormat.GetType() == wxDF_UNICODETEXT )
+ ((wxChar*)data)[byteCount/2] = 0 ;
+ }
+ else
+ {
+ delete[] ((char *)data) ;
+ data = NULL ;
+ }
+ }
+ }
+ }
+
+#else
+ long offset ;
+ Handle datahandle = NewHandle(0) ;
+ HLock( datahandle ) ;
+ GetScrap( datahandle , dataFormat.GetFormatId() , &offset ) ;
+ HUnlock( datahandle ) ;
+ if ( GetHandleSize( datahandle ) > 0 )
+ {
+ byteCount = GetHandleSize( datahandle ) ;
+ Size allocSize = byteCount ;
+ if ( dataFormat.GetType() == wxDF_TEXT )
+ allocSize += 1 ;
+ else if ( dataFormat.GetType() == wxDF_UNICODETEXT )
+ allocSize += 2 ;
+
+ data = new char[ allocSize ] ;
+
+ memcpy( (char*) data , (char*) *datahandle , byteCount ) ;
+ if ( dataFormat.GetType() == wxDF_TEXT )
+ ((char*)data)[byteCount] = 0 ;
+ if ( dataFormat.GetType() == wxDF_UNICODETEXT )
+ ((wxChar*)data)[byteCount/2] = 0 ;
+ *len = byteCount ;
+ }
+ DisposeHandle( datahandle ) ;
+#endif
+ if ( err )
+ {
+ wxLogSysError(_("Failed to get clipboard data."));
+
+ return NULL ;
+ }
+
+ if ( dataFormat.GetType() == wxDF_TEXT )
+ {
+ wxMacConvertNewlines10To13( (char*) data ) ;
+ }
+
+ return data;
+}
+
+
+/*
+ * Generalized clipboard implementation by Matthew Flatt
+ */
+
+IMPLEMENT_DYNAMIC_CLASS(wxClipboard, wxObject)
+
+wxClipboard::wxClipboard()
+{
+ m_open = false ;
+ m_data = NULL ;
+}
+
+wxClipboard::~wxClipboard()
+{
+ if (m_data)
+ {
+ delete m_data;
+ m_data = (wxDataObject*) NULL;
+ }
+}
+
+void wxClipboard::Clear()
+{
+ if (m_data)
+ {
+ delete m_data;
+ m_data = (wxDataObject*) NULL;
+ }
+#if TARGET_CARBON
+ OSStatus err ;
+ err = ClearCurrentScrap( );
+#else
+ OSErr err ;
+ err = ZeroScrap( );
+#endif
+ if ( err )
+ {
+ wxLogSysError(_("Failed to empty the clipboard."));
+ }
+}
+
+bool wxClipboard::Flush()
+{
+ return FALSE;
+}
+
+bool wxClipboard::Open()
+{
+ wxCHECK_MSG( !m_open, FALSE, wxT("clipboard already open") );
+ m_open = true ;
+ return true ;
+}
+
+bool wxClipboard::IsOpened() const
+{
+ return m_open;
+}
+
+bool wxClipboard::SetData( wxDataObject *data )
+{
+ wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") );
+
+ wxCHECK_MSG( data, FALSE, wxT("data is invalid") );
+
+ Clear();
+ // as we can only store one wxDataObject, this is the same in this
+ // implementation
+ return AddData( data );
+}
+
+bool wxClipboard::AddData( wxDataObject *data )
+{
+ wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") );
+
+ wxCHECK_MSG( data, FALSE, wxT("data is invalid") );
+
+ /* we can only store one wxDataObject */
+ Clear();
+
+ m_data = data;
+
+ /* get formats from wxDataObjects */
+ wxDataFormat *array = new wxDataFormat[ m_data->GetFormatCount() ];
+ m_data->GetAllFormats( array );
+
+ for (size_t i = 0; i < m_data->GetFormatCount(); i++)
+ {
+ wxLogTrace( TRACE_CLIPBOARD,
+ wxT("wxClipboard now supports atom %s"),
+ array[i].GetId().c_str() );
+
+#if !TARGET_CARBON
+ OSErr err = noErr ;
+#else
+ OSStatus err = noErr ;
+#endif
+ size_t sz = data->GetDataSize( array[i] ) ;
+ void* buf = malloc( sz + 1 ) ;
+ if ( buf )
+ {
+ data->GetDataHere( array[i] , buf ) ;
+ OSType mactype = 0 ;
+ switch ( array[i].GetType() )
+ {
+ case wxDF_TEXT:
+ case wxDF_OEMTEXT:
+ mactype = kScrapFlavorTypeText ;
+ break ;
+ #if wxUSE_UNICODE
+ case wxDF_UNICODETEXT :
+ mactype = kScrapFlavorTypeUnicode ;
+ break ;
+ #endif
+ #if wxUSE_DRAG_AND_DROP
+ case wxDF_METAFILE:
+ mactype = kScrapFlavorTypePicture ;
+ break ;
+ #endif
+ case wxDF_BITMAP:
+ case wxDF_DIB:
+ mactype = kScrapFlavorTypePicture ;
+ break ;
+ default:
+ break ;
+ }
+ UMAPutScrap( sz , mactype , buf ) ;
+ free( buf ) ;
+ }
+ }
+
+ delete[] array;
+
+ return true ;
+}
+
+void wxClipboard::Close()
+{
+ wxCHECK_RET( m_open, wxT("clipboard not open") );
+
+ m_open = false ;
+
+ // Get rid of cached object. If this is not done copying from another application will
+ // only work once
+ if (m_data)
+ {
+ delete m_data;
+ m_data = (wxDataObject*) NULL;
+ }
+
+}
+
+bool wxClipboard::IsSupported( const wxDataFormat &dataFormat )
+{
+ if ( m_data )
+ {
+ return m_data->IsSupported( dataFormat ) ;
+ }
+#if TARGET_CARBON
+ OSStatus err = noErr;
+ ScrapRef scrapRef;
+
+ err = GetCurrentScrap( &scrapRef );
+ if ( err != noTypeErr && err != memFullErr )
+ {
+ ScrapFlavorFlags flavorFlags;
+ Size byteCount;
+
+ if (( err = GetScrapFlavorFlags( scrapRef, dataFormat.GetFormatId(), &flavorFlags )) == noErr)
+ {
+ if (( err = GetScrapFlavorSize( scrapRef, dataFormat.GetFormatId(), &byteCount )) == noErr)
+ {
+ return TRUE ;
+ }
+ }
+ }
+ return FALSE;
+
+#else
+ long offset ;
+ Handle datahandle = NewHandle(0) ;
+ HLock( datahandle ) ;
+ GetScrap( datahandle , dataFormat.GetFormatId() , &offset ) ;
+ HUnlock( datahandle ) ;
+ bool hasData = GetHandleSize( datahandle ) > 0 ;
+ DisposeHandle( datahandle ) ;
+ return hasData ;
+#endif
+}
+
+bool wxClipboard::GetData( wxDataObject& data )
+{
+ wxCHECK_MSG( m_open, FALSE, wxT("clipboard not open") );
+
+ size_t formatcount = data.GetFormatCount() + 1 ;
+ wxDataFormat *array = new wxDataFormat[ formatcount ];
+ array[0] = data.GetPreferredFormat();
+ data.GetAllFormats( &array[1] );
+
+ bool transferred = false ;
+
+ if ( m_data )
+ {
+ for (size_t i = 0; !transferred && i < formatcount ; i++)
+ {
+ wxDataFormat format = array[i] ;
+ if ( m_data->IsSupported( format ) )
+ {
+ int size = m_data->GetDataSize( format );
+ transferred = true ;
+
+ if (size == 0)
+ {
+ data.SetData(format , 0 , 0 ) ;
+ }
+ else
+ {
+ char *d = new char[size];
+ m_data->GetDataHere( format , (void*) d );
+ data.SetData( format , size , d ) ;
+ delete[] d ;
+ }
+ }
+ }
+ }
+ /* get formats from wxDataObjects */
+ if ( !transferred )
+ {
+ for (size_t i = 0; !transferred && i < formatcount ; i++)
+ {
+ wxDataFormat format = array[i] ;
+
+ switch ( format.GetType() )
+ {
+ case wxDF_TEXT :
+ case wxDF_OEMTEXT :
+ case wxDF_BITMAP :
+ case wxDF_METAFILE :
+ {
+ long len ;
+ char* s = (char*)wxGetClipboardData(format, &len );
+ if ( s )
+ {
+ data.SetData( format , len , s ) ;
+ delete [] s;
+
+ transferred = true ;
+ }
+ }
+ break ;
+
+ default :
+ break ;
+ }
+ }
+ }
+
+ delete[] array ;
+ return transferred ;
+}
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: 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
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "colordlg.h"
+#endif
+
+#include "wx/mac/colordlg.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxColourDialog, wxDialog)
+#endif
+
+#include "wx/mac/private.h"
+#ifndef __DARWIN__
+#include <ColorPicker.h>
+#endif
+
+/*
+ * wxColourDialog
+ */
+
+wxColourDialog::wxColourDialog()
+{
+ m_dialogParent = NULL;
+}
+
+wxColourDialog::wxColourDialog(wxWindow *parent, wxColourData *data)
+{
+ Create(parent, data);
+}
+
+bool wxColourDialog::Create(wxWindow *parent, wxColourData *data)
+{
+ m_dialogParent = parent;
+
+ if (data)
+ m_colourData = *data;
+ return TRUE;
+}
+
+int wxColourDialog::ShowModal()
+{
+ Point where ;
+ RGBColor currentColor = *((RGBColor*)m_colourData.m_dataColour.GetPixel()) , newColor ;
+
+ where.h = where.v = -1;
+
+ if (GetColor( where, "\pSelect a new palette color.", ¤tColor, &newColor ))
+ {
+ m_colourData.m_dataColour.Set( (WXCOLORREF*) &newColor ) ;
+ return wxID_OK;
+ }
+ else
+ {
+ return wxID_CANCEL;
+ }
+
+ return wxID_CANCEL;
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: colour.cpp
+// Purpose: wxColour class
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "colour.h"
+#endif
+
+#include "wx/gdicmn.h"
+#include "wx/colour.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxColour, wxObject)
+#endif
+
+// Colour
+
+#include "wx/mac/private.h"
+
+static void wxComposeRGBColor( WXCOLORREF* color , int red, int blue, int green ) ;
+static void wxComposeRGBColor( WXCOLORREF* color , int red, int blue, int green )
+{
+ RGBColor* col = (RGBColor*) color ;
+ col->red = (red << 8) + red;
+ col->blue = (blue << 8) + blue;
+ col->green = (green << 8) + green;
+}
+
+void wxColour::Init()
+{
+ m_isInit = false;
+ m_red =
+ m_blue =
+ m_green = 0;
+
+ wxComposeRGBColor( &m_pixel , m_red , m_blue , m_green ) ;
+}
+
+wxColour::wxColour (const wxColour& col)
+ : wxObject()
+{
+ m_red = col.m_red;
+ m_green = col.m_green;
+ m_blue = col.m_blue;
+ m_isInit = col.m_isInit;
+
+ memcpy( &m_pixel , &col.m_pixel , 6 ) ;
+}
+
+wxColour::wxColour (const wxColour* col)
+{
+ m_red = col->m_red;
+ m_green = col->m_green;
+ m_blue = col->m_blue;
+ m_isInit = col->m_isInit;
+
+ memcpy( &m_pixel , &col->m_pixel , 6 ) ;
+}
+
+wxColour& wxColour::operator =(const wxColour& col)
+{
+ m_red = col.m_red;
+ m_green = col.m_green;
+ m_blue = col.m_blue;
+ m_isInit = col.m_isInit;
+
+ memcpy( &m_pixel , &col.m_pixel , 6 ) ;
+
+ return *this;
+}
+
+void wxColour::InitFromName(const wxString& name)
+{
+ if ( wxTheColourDatabase )
+ {
+ wxColour col = wxTheColourDatabase->Find(name);
+ if ( col.Ok() )
+ {
+ *this = col;
+ return;
+ }
+ }
+
+ // leave invalid
+ Init();
+}
+
+wxColour::~wxColour ()
+{
+}
+
+void wxColour::Set (unsigned char r, unsigned char g, unsigned char b)
+{
+ m_red = r;
+ m_green = g;
+ m_blue = b;
+ m_isInit = true;
+
+ wxComposeRGBColor( &m_pixel , m_red , m_blue , m_green ) ;
+}
+
+void wxColour::Set( const WXCOLORREF* color )
+{
+ RGBColor* col = (RGBColor*) color ;
+ memcpy( &m_pixel , color , 6 ) ;
+ m_red = col->red>>8 ;
+ m_blue = col->blue>>8 ;
+ m_green = col->green>>8 ;
+}
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: combobox.cpp
+// Purpose: wxComboBox class
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "combobox.h"
+#endif
+
+#include "wx/combobox.h"
+#include "wx/button.h"
+#include "wx/menu.h"
+#include "wx/mac/uma.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxComboBox, wxControl)
+#endif
+
+// composite combobox implementation by Dan "Bud" Keith bud@otsys.com
+
+
+static int nextPopUpMenuId = 1000 ;
+MenuHandle NewUniqueMenu()
+{
+ MenuHandle handle = NewMenu( nextPopUpMenuId , "\pMenu" ) ;
+ nextPopUpMenuId++ ;
+ return handle ;
+}
+
+
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+// the margin between the text control and the choice
+static const wxCoord MARGIN = 2;
+static const int POPUPWIDTH = 18;
+static const int POPUPHEIGHT = 23;
+
+
+// ----------------------------------------------------------------------------
+// wxComboBoxText: text control forwards events to combobox
+// ----------------------------------------------------------------------------
+
+class wxComboBoxText : public wxTextCtrl
+{
+public:
+ wxComboBoxText( wxComboBox * cb )
+ : wxTextCtrl( cb , 1 )
+ {
+ m_cb = cb;
+ }
+
+protected:
+ void OnChar( wxKeyEvent& event )
+ {
+ if ( event.GetKeyCode() == WXK_RETURN )
+ {
+ wxString value = GetValue();
+
+ if ( m_cb->GetCount() == 0 )
+ {
+ // make Enter generate "selected" event if there is only one item
+ // in the combobox - without it, it's impossible to select it at
+ // all!
+ wxCommandEvent event( wxEVT_COMMAND_COMBOBOX_SELECTED, m_cb->GetId() );
+ event.SetInt( 0 );
+ event.SetString( value );
+ event.SetEventObject( m_cb );
+ m_cb->GetEventHandler()->ProcessEvent( event );
+ }
+ else
+ {
+ // add the item to the list if it's not there yet
+ if ( m_cb->FindString(value) == wxNOT_FOUND )
+ {
+ m_cb->Append(value);
+ m_cb->SetStringSelection(value);
+
+ // and generate the selected event for it
+ wxCommandEvent event( wxEVT_COMMAND_COMBOBOX_SELECTED, m_cb->GetId() );
+ event.SetInt( m_cb->GetCount() - 1 );
+ event.SetString( value );
+ event.SetEventObject( m_cb );
+ m_cb->GetEventHandler()->ProcessEvent( event );
+ }
+
+ // This will invoke the dialog default action, such
+ // as the clicking the default button.
+
+ wxWindow *parent = GetParent();
+ while( parent && !parent->IsTopLevel() && parent->GetDefaultItem() == NULL ) {
+ parent = parent->GetParent() ;
+ }
+ if ( parent && parent->GetDefaultItem() )
+ {
+ wxButton *def = wxDynamicCast(parent->GetDefaultItem(),
+ wxButton);
+ if ( def && def->IsEnabled() )
+ {
+ wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() );
+ event.SetEventObject(def);
+ def->Command(event);
+ return ;
+ }
+ }
+
+ return;
+ }
+ }
+
+ event.Skip();
+ }
+
+private:
+ wxComboBox *m_cb;
+
+ DECLARE_EVENT_TABLE()
+};
+
+BEGIN_EVENT_TABLE(wxComboBoxText, wxTextCtrl)
+ EVT_CHAR( wxComboBoxText::OnChar)
+END_EVENT_TABLE()
+
+class wxComboBoxChoice : public wxChoice
+{
+public:
+ wxComboBoxChoice(wxComboBox *cb, int style)
+ : wxChoice( cb , 1 )
+ {
+ m_cb = cb;
+ }
+
+protected:
+ void OnChoice( wxCommandEvent& e )
+ {
+ wxString s = e.GetString();
+
+ m_cb->DelegateChoice( s );
+ wxCommandEvent event2(wxEVT_COMMAND_COMBOBOX_SELECTED, m_cb->GetId() );
+ event2.SetInt(m_cb->GetSelection());
+ event2.SetEventObject(m_cb);
+ event2.SetString(m_cb->GetStringSelection());
+ m_cb->ProcessCommand(event2);
+ }
+
+private:
+ wxComboBox *m_cb;
+
+ DECLARE_EVENT_TABLE()
+};
+
+BEGIN_EVENT_TABLE(wxComboBoxChoice, wxChoice)
+ EVT_CHOICE(-1, wxComboBoxChoice::OnChoice)
+END_EVENT_TABLE()
+
+wxComboBox::~wxComboBox()
+{
+ // delete client objects
+ FreeData();
+
+ // delete the controls now, don't leave them alive even though they would
+ // still be eventually deleted by our parent - but it will be too late, the
+ // user code expects them to be gone now
+ if (m_text != NULL) {
+ delete m_text;
+ m_text = NULL;
+ }
+ if (m_choice != NULL) {
+ delete m_choice;
+ m_choice = NULL;
+ }
+}
+
+
+// ----------------------------------------------------------------------------
+// geometry
+// ----------------------------------------------------------------------------
+
+wxSize wxComboBox::DoGetBestSize() const
+{
+ wxSize size = m_choice->GetBestSize();
+
+ if ( m_text != NULL )
+ {
+ wxSize sizeText = m_text->GetBestSize();
+
+ size.x = POPUPWIDTH + sizeText.x + MARGIN;
+ }
+
+ return size;
+}
+
+void wxComboBox::DoMoveWindow(int x, int y, int width, int height) {
+ height = POPUPHEIGHT;
+
+ wxControl::DoMoveWindow(x, y, width, height);
+
+ if ( m_text == NULL )
+ {
+ m_choice->SetSize(0, 0 , width, -1);
+ }
+ else
+ {
+ wxCoord wText = width - POPUPWIDTH - MARGIN;
+ m_text->SetSize(0, 0, wText, height);
+ m_choice->SetSize(0 + wText + MARGIN, 0, POPUPWIDTH, -1);
+ }
+}
+
+
+
+// ----------------------------------------------------------------------------
+// operations forwarded to the subcontrols
+// ----------------------------------------------------------------------------
+
+bool wxComboBox::Enable(bool enable)
+{
+ if ( !wxControl::Enable(enable) )
+ return FALSE;
+
+ return TRUE;
+}
+
+bool wxComboBox::Show(bool show)
+{
+ if ( !wxControl::Show(show) )
+ return FALSE;
+
+ return TRUE;
+}
+
+void wxComboBox::SetFocus()
+{
+ if ( m_text != NULL) {
+ m_text->SetFocus();
+ }
+}
+
+
+void wxComboBox::DelegateTextChanged( const wxString& value )
+{
+ SetStringSelection( value );
+}
+
+
+void wxComboBox::DelegateChoice( const wxString& value )
+{
+ SetStringSelection( value );
+}
+
+
+bool wxComboBox::Create(wxWindow *parent, wxWindowID id,
+ const wxString& value,
+ const wxPoint& pos,
+ const wxSize& size,
+ const wxArrayString& choices,
+ long style,
+ const wxValidator& validator,
+ const wxString& name)
+{
+ wxCArrayString chs( choices );
+
+ return Create( parent, id, value, pos, size, chs.GetCount(),
+ chs.GetStrings(), style, validator, name );
+}
+
+
+bool wxComboBox::Create(wxWindow *parent, wxWindowID id,
+ const wxString& value,
+ const wxPoint& pos,
+ const wxSize& size,
+ int n, const wxString choices[],
+ long style,
+ const wxValidator& validator,
+ const wxString& name)
+{
+ if ( !wxControl::Create(parent, id, wxDefaultPosition, wxDefaultSize, style ,
+ wxDefaultValidator, name) )
+ {
+ return FALSE;
+ }
+
+ m_choice = new wxComboBoxChoice(this, style );
+
+ wxSize csize = size;
+ if ( style & wxCB_READONLY )
+ {
+ m_text = NULL;
+ }
+ else
+ {
+ m_text = new wxComboBoxText(this);
+ if ( size.y == -1 ) {
+ csize.y = m_text->GetSize().y ;
+ }
+ }
+
+ DoSetSize(pos.x, pos.y, csize.x, csize.y);
+
+ for ( int i = 0 ; i < n ; i++ )
+ {
+ m_choice->DoAppend( choices[ i ] );
+ }
+
+ return TRUE;
+}
+
+wxString wxComboBox::GetValue() const
+{
+ wxString result;
+
+ if ( m_text == NULL )
+ {
+ result = m_choice->GetString( m_choice->GetSelection() );
+ }
+ else
+ {
+ result = m_text->GetValue();
+ }
+
+ return result;
+}
+
+void wxComboBox::SetValue(const wxString& value)
+{
+ int s = FindString (value);
+ if (s == wxNOT_FOUND && !HasFlag(wxCB_READONLY) )
+ {
+ m_choice->Append(value) ;
+ }
+ SetStringSelection( value ) ;
+}
+
+// Clipboard operations
+void wxComboBox::Copy()
+{
+ if ( m_text != NULL )
+ {
+ m_text->Copy();
+ }
+}
+
+void wxComboBox::Cut()
+{
+ if ( m_text != NULL )
+ {
+ m_text->Cut();
+ }
+}
+
+void wxComboBox::Paste()
+{
+ if ( m_text != NULL )
+ {
+ m_text->Paste();
+ }
+}
+
+void wxComboBox::SetEditable(bool editable)
+{
+ if ( ( m_text == NULL ) && editable )
+ {
+ m_text = new wxComboBoxText( this );
+ }
+ else if ( ( m_text != NULL ) && !editable )
+ {
+ delete m_text;
+ m_text = NULL;
+ }
+
+ int currentX, currentY;
+ GetPosition( ¤tX, ¤tY );
+
+ int currentW, currentH;
+ GetSize( ¤tW, ¤tH );
+
+ DoMoveWindow( currentX, currentY, currentW, currentH );
+}
+
+void wxComboBox::SetInsertionPoint(long pos)
+{
+ // TODO
+}
+
+void wxComboBox::SetInsertionPointEnd()
+{
+ // TODO
+}
+
+long wxComboBox::GetInsertionPoint() const
+{
+ // TODO
+ return 0;
+}
+
+long wxComboBox::GetLastPosition() const
+{
+ // TODO
+ return 0;
+}
+
+void wxComboBox::Replace(long from, long to, const wxString& value)
+{
+ // TODO
+}
+
+void wxComboBox::Remove(long from, long to)
+{
+ // TODO
+}
+
+void wxComboBox::SetSelection(long from, long to)
+{
+ // TODO
+}
+
+int wxComboBox::DoAppend(const wxString& item)
+{
+ return m_choice->DoAppend( item ) ;
+}
+
+int wxComboBox::DoInsert(const wxString& item, int pos)
+{
+ return m_choice->DoInsert( item , pos ) ;
+}
+
+void wxComboBox::DoSetItemClientData(int n, void* clientData)
+{
+ return m_choice->DoSetItemClientData( n , clientData ) ;
+}
+
+void* wxComboBox::DoGetItemClientData(int n) const
+{
+ return m_choice->DoGetItemClientData( n ) ;
+}
+
+void wxComboBox::DoSetItemClientObject(int n, wxClientData* clientData)
+{
+ return m_choice->DoSetItemClientObject( n , clientData ) ;
+}
+
+wxClientData* wxComboBox::DoGetItemClientObject(int n) const
+{
+ return m_choice->DoGetItemClientObject( n ) ;
+}
+
+void wxComboBox::FreeData()
+{
+ if ( HasClientObjectData() )
+ {
+ size_t count = GetCount();
+ for ( size_t n = 0; n < count; n++ )
+ {
+ SetClientObject( n, NULL );
+ }
+ }
+}
+
+void wxComboBox::Delete(int n)
+{
+ // force client object deletion
+ if( HasClientObjectData() )
+ SetClientObject( n, NULL );
+ m_choice->Delete( n );
+}
+
+void wxComboBox::Clear()
+{
+ FreeData();
+ m_choice->Clear();
+}
+
+int wxComboBox::GetSelection() const
+{
+ return m_choice->GetSelection();
+}
+
+void wxComboBox::SetSelection(int n)
+{
+ m_choice->SetSelection( n );
+
+ if ( m_text != NULL )
+ {
+ m_text->SetValue( GetString( n ) );
+ }
+}
+
+int wxComboBox::FindString(const wxString& s) const
+{
+ return m_choice->FindString( s );
+}
+
+wxString wxComboBox::GetString(int n) const
+{
+ return m_choice->GetString( n );
+}
+
+wxString wxComboBox::GetStringSelection() const
+{
+ int sel = GetSelection ();
+ if (sel > -1)
+ return wxString(this->GetString (sel));
+ else
+ return wxEmptyString;
+}
+
+bool wxComboBox::SetStringSelection(const wxString& sel)
+{
+ int s = FindString (sel);
+ if (s > -1)
+ {
+ SetSelection (s);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+void wxComboBox::SetString(int n, const wxString& s)
+{
+ m_choice->SetString( n , s ) ;
+}
+
+
+void wxComboBox::MacHandleControlClick( WXWidget WXUNUSED(control) , wxInt16 WXUNUSED(controlpart) , bool WXUNUSED(mouseStillDown))
+{
+ wxCommandEvent event(wxEVT_COMMAND_COMBOBOX_SELECTED, m_windowId );
+ event.SetInt(GetSelection());
+ event.SetEventObject(this);
+ event.SetString(GetStringSelection());
+ ProcessCommand(event);
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: control.cpp
+// Purpose: wxControl class
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "control.h"
+#endif
+
+#include "wx/defs.h"
+
+#include "wx/control.h"
+#include "wx/panel.h"
+#include "wx/app.h"
+#include "wx/dc.h"
+#include "wx/dcclient.h"
+#include "wx/notebook.h"
+#include "wx/tabctrl.h"
+#include "wx/radiobox.h"
+#include "wx/spinbutt.h"
+#include "wx/scrolbar.h"
+#include "wx/button.h"
+#include "wx/dialog.h"
+#include "wx/statbox.h"
+#include "wx/sizer.h"
+#include "wx/stattext.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_ABSTRACT_CLASS(wxControl, wxWindow)
+
+BEGIN_EVENT_TABLE(wxControl, wxWindow)
+ EVT_MOUSE_EVENTS( wxControl::OnMouseEvent )
+ EVT_PAINT( wxControl::OnPaint )
+END_EVENT_TABLE()
+#endif
+
+#include "wx/mac/uma.h"
+#include "wx/mac/private.h"
+
+// Item members
+
+
+#if PRAGMA_STRUCT_ALIGN
+ #pragma options align=mac68k
+#elif PRAGMA_STRUCT_PACKPUSH
+ #pragma pack(push, 2)
+#elif PRAGMA_STRUCT_PACK
+ #pragma pack(2)
+#endif
+
+typedef struct {
+ unsigned short instruction;
+ void (*function)();
+} cdefRec, *cdefPtr, **cdefHandle;
+
+#if PRAGMA_STRUCT_ALIGN
+ #pragma options align=reset
+#elif PRAGMA_STRUCT_PACKPUSH
+ #pragma pack(pop)
+#elif PRAGMA_STRUCT_PACK
+ #pragma pack()
+#endif
+
+ControlActionUPP wxMacLiveScrollbarActionUPP = NULL ;
+wxControl *wxFindControlFromMacControl(ControlHandle inControl ) ;
+
+pascal void wxMacLiveScrollbarActionProc( ControlHandle control , ControlPartCode partCode ) ;
+pascal void wxMacLiveScrollbarActionProc( ControlHandle control , ControlPartCode partCode )
+{
+ if ( partCode != 0)
+ {
+ wxControl* wx = (wxControl*) GetControlReference( control ) ;
+ if ( wx )
+ {
+ wx->MacHandleControlClick( control , partCode , true /* stillDown */ ) ;
+ }
+ }
+}
+
+ControlColorUPP wxMacSetupControlBackgroundUPP = NULL ;
+ControlDefUPP wxMacControlActionUPP = NULL ;
+
+pascal SInt32 wxMacControlDefinition(SInt16 varCode, ControlRef theControl, ControlDefProcMessage message, SInt32 param)
+{
+
+ wxControl* wx = (wxControl*) wxFindControlFromMacControl( theControl ) ;
+ if ( wx != NULL && wx->IsKindOf( CLASSINFO( wxControl ) ) )
+ {
+ if( message == drawCntl )
+ {
+ wxMacWindowClipper clip( wx ) ;
+ return InvokeControlDefUPP( varCode , theControl , message , param , (ControlDefUPP) wx->MacGetControlAction() ) ;
+ }
+ else
+ return InvokeControlDefUPP( varCode , theControl , message , param , (ControlDefUPP) wx->MacGetControlAction() ) ;
+ }
+ return NULL ;
+}
+
+pascal OSStatus wxMacSetupControlBackground( ControlRef iControl , SInt16 iMessage , SInt16 iDepth , Boolean iIsColor )
+{
+ OSStatus status = noErr ;
+ switch( iMessage )
+ {
+ case kControlMsgSetUpBackground :
+ {
+ wxControl* wx = (wxControl*) GetControlReference( iControl ) ;
+ if ( wx != NULL && wx->IsKindOf( CLASSINFO( wxControl ) ) )
+ {
+ wxDC::MacSetupBackgroundForCurrentPort( wx->MacGetBackgroundBrush() ) ;
+#if TARGET_CARBON
+ // under classic this would lead to partial redraws
+ RgnHandle clip = NewRgn() ;
+ int x = 0 , y = 0;
+
+ wx->MacWindowToRootWindow( &x,&y ) ;
+ CopyRgn( (RgnHandle) wx->MacGetVisibleRegion(false).GetWXHRGN() , clip ) ;
+ OffsetRgn( clip , x , y ) ;
+ SetClip( clip ) ;
+ DisposeRgn( clip ) ;
+#endif
+ }
+ else
+ {
+ status = paramErr ;
+ }
+ }
+ break ;
+ default :
+ status = paramErr ;
+ break ;
+ }
+ return status ;
+}
+
+wxControl::wxControl()
+{
+ m_macControl = NULL ;
+ m_macControlAction = NULL ;
+ m_macHorizontalBorder = 0 ; // additional pixels around the real control
+ m_macVerticalBorder = 0 ;
+ m_backgroundColour = *wxWHITE;
+ m_foregroundColour = *wxBLACK;
+
+ if ( wxMacLiveScrollbarActionUPP == NULL )
+ {
+#if defined(UNIVERSAL_INTERFACES_VERSION) && (UNIVERSAL_INTERFACES_VERSION >= 0x0340)
+ wxMacLiveScrollbarActionUPP = NewControlActionUPP( wxMacLiveScrollbarActionProc );
+#else
+ wxMacLiveScrollbarActionUPP = NewControlActionProc( wxMacLiveScrollbarActionProc ) ;
+#endif
+ }
+}
+
+bool wxControl::Create(wxWindow *parent, wxWindowID id,
+ const wxPoint& pos,
+ const wxSize& size, long style,
+ const wxValidator& validator,
+ const wxString& name)
+{
+ m_macControl = NULL ;
+ m_macHorizontalBorder = 0 ; // additional pixels around the real control
+ m_macVerticalBorder = 0 ;
+
+ bool rval = wxWindow::Create(parent, id, pos, size, style, name);
+ if ( parent )
+ {
+ m_backgroundColour = parent->GetBackgroundColour() ;
+ m_foregroundColour = parent->GetForegroundColour() ;
+ }
+ if (rval) {
+#if wxUSE_VALIDATORS
+ SetValidator(validator);
+#endif
+ }
+ return rval;
+}
+
+wxControl::~wxControl()
+{
+ m_isBeingDeleted = TRUE;
+ wxRemoveMacControlAssociation( this ) ;
+ // If we delete an item, we should initialize the parent panel,
+ // because it could now be invalid.
+ wxWindow *parent = GetParent() ;
+ if ( parent )
+ {
+ if (parent->GetDefaultItem() == (wxButton*) this)
+ parent->SetDefaultItem(NULL);
+ }
+ if ( (ControlHandle) m_macControl )
+ {
+ // in case the callback might be called during destruction
+ ::SetControlColorProc( (ControlHandle) m_macControl , NULL ) ;
+ ::DisposeControl( (ControlHandle) m_macControl ) ;
+ m_macControl = NULL ;
+ }
+}
+
+void wxControl::SetLabel(const wxString& title)
+{
+ m_label = wxStripMenuCodes(title) ;
+
+ if ( m_macControl )
+ {
+ UMASetControlTitle( (ControlHandle) m_macControl , m_label , m_font.GetEncoding() ) ;
+ }
+ Refresh() ;
+}
+
+wxSize wxControl::DoGetBestSize() const
+{
+ if ( (ControlHandle) m_macControl == NULL )
+ return wxWindow::DoGetBestSize() ;
+
+ Rect bestsize = { 0 , 0 , 0 , 0 } ;
+ short baselineoffset ;
+ int bestWidth, bestHeight ;
+ ::GetBestControlRect( (ControlHandle) m_macControl , &bestsize , &baselineoffset ) ;
+
+ if ( EmptyRect( &bestsize ) )
+ {
+ baselineoffset = 0;
+ bestsize.left = bestsize.top = 0 ;
+ bestsize.right = 16 ;
+ bestsize.bottom = 16 ;
+ if ( IsKindOf( CLASSINFO( wxScrollBar ) ) )
+ {
+ bestsize.bottom = 16 ;
+ }
+ else if ( IsKindOf( CLASSINFO( wxSpinButton ) ) )
+ {
+ bestsize.bottom = 24 ;
+ }
+ }
+
+ bestWidth = bestsize.right - bestsize.left ;
+
+ bestWidth += 2 * m_macHorizontalBorder ;
+
+ bestHeight = bestsize.bottom - bestsize.top ;
+ if ( bestHeight < 10 )
+ bestHeight = 13 ;
+
+ bestHeight += 2 * m_macVerticalBorder;
+
+
+ return wxSize(bestWidth, bestHeight);
+}
+
+bool wxControl::ProcessCommand (wxCommandEvent & event)
+{
+ // Tries:
+ // 1) OnCommand, starting at this window and working up parent hierarchy
+ // 2) OnCommand then calls ProcessEvent to search the event tables.
+ return GetEventHandler()->ProcessEvent(event);
+}
+
+// ------------------------
+wxList *wxWinMacControlList = NULL;
+wxControl *wxFindControlFromMacControl(ControlHandle inControl )
+{
+ wxNode *node = wxWinMacControlList->Find((long)inControl);
+ if (!node)
+ return NULL;
+ return (wxControl *)node->GetData();
+}
+
+void wxAssociateControlWithMacControl(ControlHandle inControl, wxControl *control)
+{
+ // adding NULL WindowRef is (first) surely a result of an error and
+ // (secondly) breaks menu command processing
+ wxCHECK_RET( inControl != (ControlHandle) NULL, wxT("attempt to add a NULL WindowRef to window list") );
+
+ if ( !wxWinMacControlList->Find((long)inControl) )
+ wxWinMacControlList->Append((long)inControl, control);
+}
+
+void wxRemoveMacControlAssociation(wxControl *control)
+{
+ if ( wxWinMacControlList )
+ wxWinMacControlList->DeleteObject(control);
+}
+
+void wxControl::MacPreControlCreate( wxWindow *parent, wxWindowID id, wxString label ,
+ const wxPoint& pos,
+ const wxSize& size, long style,
+ const wxValidator& validator,
+ const wxString& name , WXRECTPTR outBounds , unsigned char* maclabel )
+{
+ m_label = label ;
+
+ // These sizes will be adjusted in MacPostControlCreate
+ m_width = size.x ;
+ m_height = size.y ;
+ m_x = pos.x ;
+ m_y = pos.y ;
+
+ ((Rect*)outBounds)->top = -10;
+ ((Rect*)outBounds)->left = -10;
+ ((Rect*)outBounds)->bottom = 0;
+ ((Rect*)outBounds)->right = 0;
+
+ wxMacStringToPascal( wxStripMenuCodes(label) , maclabel ) ;
+}
+
+void wxControl::MacPostControlCreate()
+{
+ wxASSERT_MSG( (ControlHandle) m_macControl != NULL , wxT("No valid mac control") ) ;
+ DoSetWindowVariant( m_windowVariant ) ;
+ /*
+ if ( IsKindOf( CLASSINFO( wxScrollBar ) ) )
+ {
+ // no font
+ }
+ else if ( !UMAHasAquaLayout() && (IsKindOf( CLASSINFO( wxStaticBox ) ) || IsKindOf( CLASSINFO( wxRadioBox ) ) || IsKindOf( CLASSINFO( wxButton ) ) ) )
+ {
+ ControlFontStyleRec controlstyle ;
+ controlstyle.flags = kControlUseFontMask ;
+ controlstyle.font = kControlFontSmallBoldSystemFont ;
+
+ ::SetControlFontStyle( (ControlHandle) m_macControl , &controlstyle ) ;
+ }
+ else
+ {
+ ControlFontStyleRec controlstyle ;
+ controlstyle.flags = kControlUseFontMask ;
+
+ if (IsKindOf( CLASSINFO( wxButton ) ) )
+ controlstyle.font = kControlFontBigSystemFont ; // eventually kControlFontBigSystemFont ;
+ else
+ controlstyle.font = kControlFontSmallSystemFont ;
+
+ ::SetControlFontStyle( (ControlHandle) m_macControl , &controlstyle ) ;
+ }
+ */
+ ControlHandle container = (ControlHandle) GetParent()->MacGetContainerForEmbedding() ;
+ wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ;
+ ::EmbedControl( (ControlHandle) m_macControl , container ) ;
+ m_macControlIsShown = MacIsReallyShown() ;
+
+ wxAssociateControlWithMacControl( (ControlHandle) m_macControl , this ) ;
+ if ( wxMacSetupControlBackgroundUPP == NULL )
+ {
+ wxMacSetupControlBackgroundUPP = NewControlColorUPP( wxMacSetupControlBackground ) ;
+ }
+ if ( wxMacControlActionUPP == NULL )
+ {
+ wxMacControlActionUPP = NewControlDefUPP( wxMacControlDefinition ) ;
+ }
+ // The following block of code is responsible for crashes when switching
+ // back to windows, which can be seen in the dialogs sample.
+ // It is disabled until a proper solution can be found.
+#if 0
+#if TARGET_CARBON
+/*
+ only working under classic carbon
+ m_macControlAction = *(**(ControlHandle)m_macControl).contrlDefProc ;
+ (**(ControlHandle)m_macControl).contrlDefProc = (Handle) &wxMacControlActionUPP ;
+*/
+#else
+ m_macControlAction = *(**(ControlHandle)m_macControl).contrlDefProc ;
+
+ cdefHandle cdef ;
+ cdef = (cdefHandle) NewHandle( sizeof(cdefRec) ) ;
+ if ( (**(ControlHandle)m_macControl).contrlDefProc != NULL )
+ {
+ (**cdef).instruction = 0x4EF9; /* JMP instruction */
+ (**cdef).function = (void(*)()) wxMacControlActionUPP;
+ (**(ControlHandle)m_macControl).contrlDefProc = (Handle) cdef ;
+ }
+#endif
+#endif
+ SetControlColorProc( (ControlHandle) m_macControl , wxMacSetupControlBackgroundUPP ) ;
+
+ // Adjust the controls size and position
+ wxPoint pos(m_x, m_y);
+ wxSize best_size( DoGetBestSize() );
+ wxSize new_size( m_width, m_height );
+
+ m_x = m_y = m_width = m_height = -1; // Forces SetSize to move/size the control
+
+ if (new_size.x == -1) {
+ new_size.x = best_size.x;
+ }
+ if (new_size.y == -1) {
+ new_size.y = best_size.y;
+ }
+
+ SetSize(pos.x, pos.y, new_size.x, new_size.y);
+
+#if wxUSE_UNICODE
+ UMASetControlTitle( (ControlHandle) m_macControl , wxStripMenuCodes(m_label) , m_font.GetEncoding() ) ;
+#endif
+
+ if ( m_macControlIsShown )
+ UMAShowControl( (ControlHandle) m_macControl ) ;
+
+ SetCursor( *wxSTANDARD_CURSOR ) ;
+
+ Refresh() ;
+}
+
+void wxControl::MacAdjustControlRect()
+{
+ wxASSERT_MSG( (ControlHandle) m_macControl != NULL , wxT("No valid mac control") ) ;
+ if ( m_width == -1 || m_height == -1 )
+ {
+ Rect bestsize = { 0 , 0 , 0 , 0 } ;
+ short baselineoffset ;
+
+ ::GetBestControlRect( (ControlHandle) m_macControl , &bestsize , &baselineoffset ) ;
+
+ if ( EmptyRect( &bestsize ) )
+ {
+ baselineoffset = 0;
+ bestsize.left = bestsize.top = 0 ;
+ bestsize.right = 16 ;
+ bestsize.bottom = 16 ;
+ if ( IsKindOf( CLASSINFO( wxScrollBar ) ) )
+ {
+ bestsize.bottom = 16 ;
+ }
+ else if ( IsKindOf( CLASSINFO( wxSpinButton ) ) )
+ {
+ bestsize.bottom = 24 ;
+ }
+ }
+
+ if ( m_width == -1 )
+ {
+ if ( IsKindOf( CLASSINFO( wxButton ) ) )
+ {
+ m_width = m_label.Length() * 8 + 12 ;
+ if ( m_width < 70 )
+ m_width = 70 ;
+ }
+ else if ( IsKindOf( CLASSINFO( wxStaticText ) ) )
+ {
+ m_width = m_label.Length() * 8 ;
+ }
+ else
+ m_width = bestsize.right - bestsize.left ;
+
+ m_width += 2 * m_macHorizontalBorder + MacGetLeftBorderSize() + MacGetRightBorderSize() ;
+ }
+ if ( m_height == -1 )
+ {
+ m_height = bestsize.bottom - bestsize.top ;
+ if ( m_height < 10 )
+ m_height = 13 ;
+
+ m_height += 2 * m_macVerticalBorder + MacGetTopBorderSize() + MacGetBottomBorderSize() ;
+ }
+ MacUpdateDimensions() ;
+ }
+}
+
+WXWidget wxControl::MacGetContainerForEmbedding()
+{
+ if ( m_macControl )
+ return m_macControl ;
+
+ return wxWindow::MacGetContainerForEmbedding() ;
+}
+
+void wxControl::MacUpdateDimensions()
+{
+ // actually in the current systems this should never be possible, but later reparenting
+ // may become a reality
+
+ if ( (ControlHandle) m_macControl == NULL )
+ return ;
+
+ if ( GetParent() == NULL )
+ return ;
+
+ WindowRef rootwindow = (WindowRef) MacGetRootWindow() ;
+ if ( rootwindow == NULL )
+ return ;
+
+ Rect oldBounds ;
+ GetControlBounds( (ControlHandle) m_macControl , &oldBounds ) ;
+
+ int new_x = m_x + MacGetLeftBorderSize() + m_macHorizontalBorder ;
+ int new_y = m_y + MacGetTopBorderSize() + m_macVerticalBorder ;
+ int new_width = m_width - MacGetLeftBorderSize() - MacGetRightBorderSize() - 2 * m_macHorizontalBorder ;
+ int new_height = m_height - MacGetTopBorderSize() - MacGetBottomBorderSize() - 2 * m_macVerticalBorder ;
+
+ GetParent()->MacWindowToRootWindow( & new_x , & new_y ) ;
+ bool doMove = new_x != oldBounds.left || new_y != oldBounds.top ;
+ bool doResize = ( oldBounds.right - oldBounds.left ) != new_width || (oldBounds.bottom - oldBounds.top ) != new_height ;
+ if ( doMove || doResize )
+ {
+ InvalWindowRect( rootwindow, &oldBounds ) ;
+ if ( doMove )
+ {
+ UMAMoveControl( (ControlHandle) m_macControl , new_x , new_y ) ;
+ }
+ if ( doResize )
+ {
+ UMASizeControl( (ControlHandle) m_macControl , new_width , new_height ) ;
+ }
+ }
+}
+
+void wxControl::MacSuperChangedPosition()
+{
+ MacUpdateDimensions() ;
+ wxWindow::MacSuperChangedPosition() ;
+}
+
+void wxControl::MacSuperEnabled( bool enabled )
+{
+ Refresh(FALSE) ;
+ wxWindow::MacSuperEnabled( enabled ) ;
+}
+
+void wxControl::MacSuperShown( bool show )
+{
+ if ( (ControlHandle) m_macControl )
+ {
+ if ( !show )
+ {
+ if ( m_macControlIsShown )
+ {
+ ::UMAHideControl( (ControlHandle) m_macControl ) ;
+ m_macControlIsShown = false ;
+ }
+ }
+ else
+ {
+ if ( MacIsReallyShown() && !m_macControlIsShown )
+ {
+ ::UMAShowControl( (ControlHandle) m_macControl ) ;
+ m_macControlIsShown = true ;
+ }
+ }
+ }
+
+ wxWindow::MacSuperShown( show ) ;
+}
+
+void wxControl::DoSetSize(int x, int y,
+ int width, int height,
+ int sizeFlags )
+{
+ wxWindow::DoSetSize( x , y ,width , height ,sizeFlags ) ;
+#if 0
+ {
+ Rect meta , control ;
+ GetControlBounds( (ControlHandle) m_macControl , &control ) ;
+ RgnHandle rgn = NewRgn() ;
+ GetControlRegion( (ControlHandle) m_macControl , kControlStructureMetaPart , rgn ) ;
+ GetRegionBounds( rgn , &meta ) ;
+ if ( !EmptyRect( &meta ) )
+ {
+ wxASSERT( meta.left >= control.left - m_macHorizontalBorder ) ;
+ wxASSERT( meta.right <= control.right + m_macHorizontalBorder ) ;
+ wxASSERT( meta.top >= control.top - m_macVerticalBorder ) ;
+ wxASSERT( meta.bottom <= control.bottom + m_macVerticalBorder ) ;
+ }
+ DisposeRgn( rgn ) ;
+ }
+#endif
+ return ;
+}
+
+bool wxControl::Show(bool show)
+{
+ if ( !wxWindow::Show( show ) )
+ return FALSE ;
+
+ if ( (ControlHandle) m_macControl )
+ {
+ if ( !show )
+ {
+ if ( m_macControlIsShown )
+ {
+ ::UMAHideControl( (ControlHandle) m_macControl ) ;
+ m_macControlIsShown = false ;
+ }
+ }
+ else
+ {
+ if ( MacIsReallyShown() && !m_macControlIsShown )
+ {
+ ::UMAShowControl( (ControlHandle) m_macControl ) ;
+ m_macControlIsShown = true ;
+ }
+ }
+ }
+ return TRUE ;
+}
+
+bool wxControl::Enable(bool enable)
+{
+ if ( !wxWindow::Enable(enable) )
+ return FALSE;
+
+ if ( (ControlHandle) m_macControl )
+ {
+ if ( enable )
+ UMAActivateControl( (ControlHandle) m_macControl ) ;
+ else
+ UMADeactivateControl( (ControlHandle) m_macControl ) ;
+ }
+ return TRUE ;
+}
+
+void wxControl::Refresh(bool eraseBack, const wxRect *rect)
+{
+ wxWindow::Refresh( eraseBack , rect ) ;
+}
+
+void wxControl::MacRedrawControl()
+{
+ if ( (ControlHandle) m_macControl && MacGetRootWindow() && m_macControlIsShown )
+ {
+ wxClientDC dc(this) ;
+ wxMacPortSetter helper(&dc) ;
+ wxMacWindowClipper clipper(this) ;
+ wxDC::MacSetupBackgroundForCurrentPort( MacGetBackgroundBrush() ) ;
+ UMADrawControl( (ControlHandle) m_macControl ) ;
+ }
+}
+
+void wxControl::OnPaint(wxPaintEvent& event)
+{
+ if ( (ControlHandle) m_macControl )
+ {
+ wxPaintDC dc(this) ;
+ wxMacPortSetter helper(&dc) ;
+ wxMacWindowClipper clipper(this) ;
+ wxDC::MacSetupBackgroundForCurrentPort( MacGetBackgroundBrush() ) ;
+ UMADrawControl( (ControlHandle) m_macControl ) ;
+ }
+ else
+ {
+ event.Skip() ;
+ }
+}
+void wxControl::OnEraseBackground(wxEraseEvent& event)
+{
+ wxWindow::OnEraseBackground( event ) ;
+}
+
+void wxControl::OnKeyDown( wxKeyEvent &event )
+{
+ if ( (ControlHandle) m_macControl == NULL )
+ return ;
+
+#if TARGET_CARBON
+
+ char charCode ;
+ UInt32 keyCode ;
+ UInt32 modifiers ;
+
+ GetEventParameter( (EventRef) wxTheApp->MacGetCurrentEvent(), kEventParamKeyMacCharCodes, typeChar, NULL,sizeof(char), NULL,&charCode );
+ GetEventParameter( (EventRef) wxTheApp->MacGetCurrentEvent(), kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode );
+ GetEventParameter((EventRef) wxTheApp->MacGetCurrentEvent(), kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);
+
+ ::HandleControlKey( (ControlHandle) m_macControl , keyCode , charCode , modifiers ) ;
+
+#else
+ EventRecord *ev = (EventRecord*) wxTheApp->MacGetCurrentEvent() ;
+ short keycode ;
+ short keychar ;
+ keychar = short(ev->message & charCodeMask);
+ keycode = short(ev->message & keyCodeMask) >> 8 ;
+
+ ::HandleControlKey( (ControlHandle) m_macControl , keycode , keychar , ev->modifiers ) ;
+#endif
+}
+
+void wxControl::OnMouseEvent( wxMouseEvent &event )
+{
+ if ( (ControlHandle) m_macControl == NULL )
+ {
+ event.Skip() ;
+ return ;
+ }
+
+ if (event.GetEventType() == wxEVT_LEFT_DOWN || event.GetEventType() == wxEVT_LEFT_DCLICK )
+ {
+
+ int x = event.m_x ;
+ int y = event.m_y ;
+
+ MacClientToRootWindow( &x , &y ) ;
+
+ ControlHandle control ;
+ Point localwhere ;
+ SInt16 controlpart ;
+
+ localwhere.h = x ;
+ localwhere.v = y ;
+
+ short modifiers = 0;
+
+ if ( !event.m_leftDown && !event.m_rightDown )
+ modifiers |= btnState ;
+
+ if ( event.m_shiftDown )
+ modifiers |= shiftKey ;
+
+ if ( event.m_controlDown )
+ modifiers |= controlKey ;
+
+ if ( event.m_altDown )
+ modifiers |= optionKey ;
+
+ if ( event.m_metaDown )
+ modifiers |= cmdKey ;
+ {
+ control = (ControlHandle) m_macControl ;
+ if ( control && ::IsControlActive( control ) )
+ {
+ {
+ controlpart = ::HandleControlClick( control , localwhere , modifiers , (ControlActionUPP) -1 ) ;
+ wxTheApp->s_lastMouseDown = 0 ;
+ if ( control && controlpart != kControlNoPart )
+ {
+ MacHandleControlClick( control , controlpart , false /* mouse not down anymore */ ) ;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ event.Skip() ;
+ }
+}
+
+bool wxControl::MacCanFocus() const
+{
+ if ( (ControlHandle) m_macControl == NULL )
+ return true ;
+ else
+ return false ;
+}
+
+void wxControl::MacHandleControlClick( WXWidget control , wxInt16 controlpart , bool WXUNUSED( mouseStillDown ) )
+{
+ wxASSERT_MSG( (ControlHandle) m_macControl != NULL , wxT("No valid mac control") ) ;
+}
+
+void wxControl::DoSetWindowVariant( wxWindowVariant variant )
+{
+ if ( m_macControl == NULL )
+ {
+ wxWindow::SetWindowVariant( variant ) ;
+ return ;
+
+ }
+ m_windowVariant = variant ;
+
+ ControlSize size ;
+ ControlFontStyleRec fontStyle;
+ fontStyle.flags = kControlUseFontMask ;
+
+ // we will get that from the settings later
+ // and make this NORMAL later, but first
+ // we have a few calculations that we must fix
+
+ if ( variant == wxWINDOW_VARIANT_DEFAULT )
+ {
+ if ( IsKindOf( CLASSINFO( wxScrollBar ) ) )
+ variant = wxWINDOW_VARIANT_NORMAL ;
+ else
+ variant = wxWINDOW_VARIANT_SMALL ;
+ }
+
+ switch ( variant )
+ {
+ case wxWINDOW_VARIANT_NORMAL :
+ size = kControlSizeNormal;
+ fontStyle.font = kControlFontBigSystemFont;
+ break ;
+ case wxWINDOW_VARIANT_SMALL :
+ size = kControlSizeSmall;
+ fontStyle.font = kControlFontSmallSystemFont;
+ break ;
+ case wxWINDOW_VARIANT_MINI :
+ if (UMAGetSystemVersion() >= 0x1030 )
+ {
+ size = 3 ; // not always defined in the header
+ fontStyle.font = -5 ; // not always defined in the header
+ }
+ else
+ {
+ size = kControlSizeSmall;
+ fontStyle.font = kControlFontSmallSystemFont;
+ }
+ break;
+ break ;
+ case wxWINDOW_VARIANT_LARGE :
+ size = kControlSizeLarge;
+ fontStyle.font = kControlFontBigSystemFont;
+ break ;
+ default:
+ wxFAIL_MSG(_T("unexpected window variant"));
+ break ;
+ }
+ ::SetControlData( (ControlHandle) m_macControl , kControlEntireControl, kControlSizeTag, sizeof( ControlSize ), &size );
+ ::SetControlFontStyle( (ControlHandle) m_macControl , &fontStyle );
+}
--- /dev/null
+#ifdef __UNIX__
+ #include <Carbon.r>
+#else
+ #include <Types.r>
+ #if UNIVERSAL_INTERFACES_VERSION > 0x320
+ #include <ControlDefinitions.r>
+ #endif
+#endif
+
+resource 'ldes' ( 128 )
+{
+ versionZero
+ {
+ 0 ,
+ 0 ,
+ 0 ,
+ 0 ,
+ hasVertScroll ,
+ noHorizScroll ,
+ 0 ,
+ noGrowSpace ,
+ }
+} ;
+
+resource 'ldes' ( 129 )
+{
+ versionZero
+ {
+ 0 ,
+ 0 ,
+ 0 ,
+ 0 ,
+ hasVertScroll ,
+ hasHorizScroll ,
+ 0 ,
+ noGrowSpace ,
+ }
+} ;
+
+data 'CURS' (10) {
+ $"0000 03E0 0630 0808 1004 31C6 2362 2222"
+ $"2362 31C6 1004 0808 0630 03E0 0000 0000"
+ $"0000 03E0 07F0 0FF8 1FFC 3FFE 3FFE 3FFE"
+ $"3FFE 3FFE 1FFC 0FF8 07F0 03E0 0000 0000"
+ $"0007 0008"
+};
+
+data 'CURS' (11) {
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0000 0000 0000 0000 0000 0000 0000 0000"
+ $"0000 0000"
+};
+
+data 'CURS' (12) {
+ $"00F0 0088 0108 0190 0270 0220 0440 0440"
+ $"0880 0880 1100 1E00 1C00 1800 1000 0000"
+ $"00F0 00F8 01F8 01F0 03F0 03E0 07C0 07C0"
+ $"0F80 0F80 1F00 1E00 1C00 1800 1000 0000"
+ $"000E 0003"
+};
+
+data 'CURS' (13) {
+ $"0000 1E00 2100 4080 4080 4080 4080 2180"
+ $"1FC0 00E0 0070 0038 001C 000E 0006 0000"
+ $"3F00 7F80 FFC0 FFC0 FFC0 FFC0 FFC0 7FC0"
+ $"3FE0 1FF0 00F8 007C 003E 001F 000F 0007"
+ $"0004 0004"
+};
+
+data 'CURS' (14) {
+ $"0000 07E0 1FF0 3838 3C0C 6E0E 6706 6386"
+ $"61C6 60E6 7076 303C 1C1C 0FF8 07E0 0000"
+ $"0540 0FF0 3FF8 3C3C 7E0E FF0F 6F86 E7C7"
+ $"63E6 E1F7 70FE 707E 3C3C 1FFC 0FF0 0540"
+ $"0007 0007"
+};
+
+data 'CURS' (15) {
+ $"0000 0380 0380 0380 0380 0380 0380 0FE0"
+ $"1FF0 1FF0 0000 1FF0 1FF0 1550 1550 1550"
+ $"07C0 07C0 07C0 07C0 07C0 07C0 0FE0 1FF0"
+ $"3FF8 3FF8 3FF8 3FF8 3FF8 3FF8 3FF8 3FF8"
+ $"000B 0007"
+};
+
+data 'CURS' (16) {
+ $"00C0 0140 0640 08C0 3180 47FE 8001 8001"
+ $"81FE 8040 01C0 0040 03C0 C080 3F80 0000"
+ $"00C0 01C0 07C0 0FC0 3F80 7FFE FFFF FFFF"
+ $"FFFE FFC0 FFC0 FFC0 FFC0 FF80 3F80 0000"
+ $"0006 000F"
+};
+
+data 'CURS' (17) {
+ $"0100 0280 0260 0310 018C 7FE3 8000 8000"
+ $"7F80 0200 0380 0200 03C0 0107 01F8 0000"
+ $"0100 0380 03E0 03F0 01FC 7FFF FFFF FFFF"
+ $"FFFF 03FF 03FF 03FF 03FF 01FF 01F8 0000"
+ $"0006 0000"
+};
+
+data 'CURS' (18) {
+ $"0000 4078 60FC 71CE 7986 7C06 7E0E 7F1C"
+ $"7FB8 7C30 6C30 4600 0630 0330 0300 0000"
+ $"C078 E0FC F1FE FBFF FFCF FF8F FF1F FFBE"
+ $"FFFC FE78 FF78 EFF8 CFF8 87F8 07F8 0300"
+ $"0001 0001"
+};
+
+data 'CURS' (19) {
+ $"0000 0002 0006 000E 001E 003E 007E 00FE"
+ $"01FE 003E 0036 0062 0060 00C0 00C0 0000"
+ $"0003 0007 000F 001F 003F 007F 00FF 01FF"
+ $"03FF 07FF 007F 00F7 00F3 01E1 01E0 01C0"
+ $"0001 000E"
+};
+
+data 'CURS' (20) {
+ $"0000 0080 01C0 03E0 0080 0080 0080 1FFC"
+ $"1FFC 0080 0080 0080 03E0 01C0 0080 0000"
+ $"0080 01C0 03E0 07F0 0FF8 01C0 3FFE 3FFE"
+ $"3FFE 3FFE 01C0 0FF8 07F0 03E0 01C0 0080"
+ $"0007 0008"
+};
+
+data 'CURS' (21) {
+ $"0000 0080 01C0 03E0 0080 0888 188C 3FFE"
+ $"188C 0888 0080 03E0 01C0 0080 0000 0000"
+ $"0080 01C0 03E0 07F0 0BE8 1DDC 3FFE 7FFF"
+ $"3FFE 1DDC 0BE8 07F0 03E0 01C0 0080 0000"
+ $"0007 0008"
+};
+
+data 'CURS' (22) {
+ $"0000 001E 000E 060E 0712 03A0 01C0 00E0"
+ $"0170 1238 1C18 1C00 1E00 0000 0000 0000"
+ $"007F 003F 0E1F 0F0F 0F97 07E3 03E1 21F0"
+ $"31F8 3A7C 3C3C 3E1C 3F00 3F80 0000 0000"
+ $"0006 0009"
+};
+
+data 'CURS' (23) {
+ $"0000 7800 7000 7060 48E0 05C0 0380 0700"
+ $"0E80 1C48 1838 0038 0078 0000 0000 0000"
+ $"FE00 FC00 F870 F0F0 E9F0 C7E0 87C0 0F84"
+ $"1F8C 3E5C 3C3C 387C 00FC 01FC 0000 0000"
+ $"0006 0006"
+};
+
+data 'CURS' (24) {
+ $"0006 000E 001C 0018 0020 0040 00F8 0004"
+ $"1FF4 200C 2AA8 1FF0 1F80 3800 6000 8000"
+ $"000F 001F 003E 007C 0070 00E0 01FC 3FF6"
+ $"7FF6 7FFE 7FFC 7FF8 3FF0 7FC0 F800 E000"
+ $"000A 0006"
+};
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: cursor.cpp
+// Purpose: wxCursor class
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "cursor.h"
+#endif
+
+#include "wx/defs.h"
+
+#include "wx/app.h"
+#include "wx/cursor.h"
+#include "wx/icon.h"
+#include "wx/image.h"
+#include "wx/xpmdecod.h"
+
+#include "wx/mac/private.h"
+
+#if !USE_SHARED_LIBRARIES
+IMPLEMENT_DYNAMIC_CLASS(wxCursor, wxBitmap)
+#endif
+
+const short kwxCursorBullseye = 10 ;
+const short kwxCursorBlank = 11 ;
+const short kwxCursorPencil = 12 ;
+const short kwxCursorMagnifier = 13 ;
+const short kwxCursorNoEntry = 14 ;
+const short kwxCursorPaintBrush = 15 ;
+const short kwxCursorPointRight = 16 ;
+const short kwxCursorPointLeft = 17 ;
+const short kwxCursorQuestionArrow = 18 ;
+const short kwxCursorRightArrow = 19 ;
+const short kwxCursorSizeNS = 20 ;
+const short kwxCursorSize = 21 ;
+const short kwxCursorSizeNESW = 22 ;
+const short kwxCursorSizeNWSE = 23 ;
+const short kwxCursorRoller = 24 ;
+
+wxCursor gMacCurrentCursor ;
+
+wxCursorRefData::wxCursorRefData()
+{
+ m_width = 16;
+ m_height = 16;
+ m_hCursor = NULL ;
+ m_disposeHandle = false ;
+ m_releaseHandle = false ;
+ m_isColorCursor = false ;
+ m_themeCursor = -1 ;
+}
+
+wxCursorRefData::~wxCursorRefData()
+{
+ if ( m_isColorCursor )
+ {
+ ::DisposeCCursor( (CCrsrHandle) m_hCursor ) ;
+ }
+ else if ( m_disposeHandle )
+ {
+ ::DisposeHandle( (Handle ) m_hCursor ) ;
+ }
+ else if ( m_releaseHandle )
+ {
+ // we don't release the resource since it may already
+ // be in use again
+ }
+}
+
+// Cursors
+wxCursor::wxCursor()
+{
+}
+
+wxCursor::wxCursor(const char WXUNUSED(bits)[], int WXUNUSED(width), int WXUNUSED(height),
+ int WXUNUSED(hotSpotX), int WXUNUSED(hotSpotY), const char WXUNUSED(maskBits)[])
+{
+}
+
+wxCursor::wxCursor( const wxImage &image )
+{
+ CreateFromImage( image ) ;
+}
+
+wxCursor::wxCursor(const char **bits)
+{
+ (void) CreateFromXpm(bits);
+}
+
+wxCursor::wxCursor(char **bits)
+{
+ (void) CreateFromXpm((const char **)bits);
+}
+
+bool wxCursor::CreateFromXpm(const char **bits)
+{
+ wxCHECK_MSG( bits != NULL, FALSE, wxT("invalid cursor data") )
+ wxXPMDecoder decoder;
+ wxImage img = decoder.ReadData(bits);
+ wxCHECK_MSG( img.Ok(), FALSE, wxT("invalid cursor data") )
+ CreateFromImage( img ) ;
+ return TRUE;
+}
+
+short GetCTabIndex( CTabHandle colors , RGBColor *col )
+{
+ short retval = 0 ;
+ unsigned long bestdiff = 0xFFFF ;
+ for ( int i = 0 ; i < (**colors).ctSize ; ++i )
+ {
+ unsigned long diff = abs(col->red - (**colors).ctTable[i].rgb.red ) +
+ abs(col->green - (**colors).ctTable[i].rgb.green ) +
+ abs(col->blue - (**colors).ctTable[i].rgb.blue ) ;
+ if ( diff < bestdiff )
+ {
+ bestdiff = diff ;
+ retval = (**colors).ctTable[i].value ;
+ }
+ }
+ return retval ;
+}
+
+void wxCursor::CreateFromImage(const wxImage & image)
+{
+ m_refData = new wxCursorRefData;
+
+ wxImage image16 = image.Scale(16,16) ;
+ unsigned char * rgbBits = image16.GetData();
+
+
+ int w = image16.GetWidth() ;
+ int h = image16.GetHeight() ;
+ bool bHasMask = image16.HasMask() ;
+
+ int hotSpotX = image16.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X);
+ int hotSpotY = image16.GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_Y);
+ if (hotSpotX < 0 || hotSpotX >= w)
+ hotSpotX = 0;
+ if (hotSpotY < 0 || hotSpotY >= h)
+ hotSpotY = 0;
+
+#if 0
+ // monochrome implementation
+ M_CURSORDATA->m_hCursor = NewHandle( sizeof( Cursor ) ) ;
+ M_CURSORDATA->m_disposeHandle = true ;
+ HLock( (Handle) M_CURSORDATA->m_hCursor ) ;
+ CursPtr cp = *(CursHandle)M_CURSORDATA->m_hCursor ;
+ memset( cp->data , 0 , sizeof( Bits16 ) ) ;
+ memset( cp->mask , 0 , sizeof( Bits16 ) ) ;
+
+ unsigned char mr = image16.GetMaskRed() ;
+ unsigned char mg = image16.GetMaskGreen() ;
+ unsigned char mb = image16.GetMaskBlue() ;
+ for ( int y = 0 ; y < h ; ++y )
+ {
+ short rowbits = 0 ;
+ short maskbits = 0 ;
+
+ for ( int x = 0 ; x < w ; ++x )
+ {
+ long pos = (y * w + x) * 3;
+
+ unsigned char r = rgbBits[pos] ;
+ unsigned char g = rgbBits[pos+1] ;
+ unsigned char b = rgbBits[pos+2] ;
+ if ( bHasMask && r==mr && g==mg && b==mb )
+ {
+ // masked area, does not appear anywhere
+ }
+ else
+ {
+ if ( (int)r + (int)g + (int)b < 0x0200 )
+ {
+ rowbits |= ( 1 << (15-x) ) ;
+ }
+ maskbits |= ( 1 << (15-x) ) ;
+ }
+ }
+ cp->data[y] = rowbits ;
+ cp->mask[y] = maskbits ;
+ }
+ if ( !bHasMask )
+ {
+ memcpy( cp->mask , cp->data , sizeof( Bits16) ) ;
+ }
+ cp->hotSpot.h = hotSpotX ;
+ cp->hotSpot.v = hotSpotY ;
+ HUnlock( (Handle) M_CURSORDATA->m_hCursor ) ;
+#else
+ PixMapHandle pm = (PixMapHandle) NewHandleClear( sizeof (PixMap)) ;
+ short extent = 16 ;
+ short bytesPerPixel = 1 ;
+ short depth = 8 ;
+ Rect bounds = { 0 , 0 , extent , extent } ;
+ CCrsrHandle ch = (CCrsrHandle) NewHandleClear ( sizeof( CCrsr ) ) ;
+ CTabHandle newColors = GetCTable( 8 ) ;
+ HandToHand((Handle *) &newColors);
+ // set the values to the indices
+ for ( int i = 0 ; i < (**newColors).ctSize ; ++i )
+ {
+ (**newColors).ctTable[i].value = i ;
+ }
+ HLock( (Handle) ch) ;
+ (**ch).crsrType = 0x8001 ; // color cursors
+ (**ch).crsrMap = pm ;
+ short bytesPerRow = bytesPerPixel * extent ;
+
+ (**pm).baseAddr = 0;
+ (**pm).rowBytes = bytesPerRow | 0x8000;
+ (**pm).bounds = bounds;
+ (**pm).pmVersion = 0;
+ (**pm).packType = 0;
+ (**pm).packSize = 0;
+ (**pm).hRes = 0x00480000; /* 72 DPI default res */
+ (**pm).vRes = 0x00480000; /* 72 DPI default res */
+ (**pm).pixelSize = depth;
+ (**pm).pixelType = 0;
+ (**pm).cmpCount = 1;
+ (**pm).cmpSize = depth;
+ (**pm).pmTable = newColors;
+
+ (**ch).crsrData = NewHandleClear( extent * bytesPerRow ) ;
+ (**ch).crsrXData = NULL ;
+ (**ch).crsrXValid = 0;
+ (**ch).crsrXHandle = NULL;
+
+ (**ch).crsrHotSpot.h = hotSpotX ;
+ (**ch).crsrHotSpot.v = hotSpotY ;
+ (**ch).crsrXTable = NULL ;
+ (**ch).crsrID = GetCTSeed() ;
+
+ memset( (**ch).crsr1Data , 0 , sizeof( Bits16 ) ) ;
+ memset( (**ch).crsrMask , 0 , sizeof( Bits16 ) ) ;
+
+ unsigned char mr = image16.GetMaskRed() ;
+ unsigned char mg = image16.GetMaskGreen() ;
+ unsigned char mb = image16.GetMaskBlue() ;
+ for ( int y = 0 ; y < h ; ++y )
+ {
+ short rowbits = 0 ;
+ short maskbits = 0 ;
+
+ for ( int x = 0 ; x < w ; ++x )
+ {
+ long pos = (y * w + x) * 3;
+
+ unsigned char r = rgbBits[pos] ;
+ unsigned char g = rgbBits[pos+1] ;
+ unsigned char b = rgbBits[pos+2] ;
+ RGBColor col = { 0xFFFF ,0xFFFF, 0xFFFF } ;
+
+ if ( bHasMask && r==mr && g==mg && b==mb )
+ {
+ // masked area, does not appear anywhere
+ }
+ else
+ {
+ if ( (int)r + (int)g + (int)b < 0x0200 )
+ {
+ rowbits |= ( 1 << (15-x) ) ;
+ }
+ maskbits |= ( 1 << (15-x) ) ;
+
+ col = *((RGBColor*) wxColor( r , g , b ).GetPixel()) ;
+ }
+ *((*(**ch).crsrData) + y * bytesPerRow + x) =
+ GetCTabIndex( newColors , &col) ;
+ }
+ (**ch).crsr1Data[y] = rowbits ;
+ (**ch).crsrMask[y] = maskbits ;
+ }
+ if ( !bHasMask )
+ {
+ memcpy( (**ch).crsrMask , (**ch).crsr1Data , sizeof( Bits16) ) ;
+ }
+
+ HUnlock((Handle) ch) ;
+ M_CURSORDATA->m_hCursor = ch ;
+ M_CURSORDATA->m_isColorCursor = true ;
+#endif
+}
+
+wxCursor::wxCursor(const wxString& cursor_file, long flags, int hotSpotX, int hotSpotY)
+{
+ m_refData = new wxCursorRefData;
+ if ( flags == wxBITMAP_TYPE_MACCURSOR_RESOURCE )
+ {
+ Str255 theName ;
+ wxMacStringToPascal( cursor_file , theName ) ;
+
+ wxStAppResource resload ;
+ Handle resHandle = ::GetNamedResource( 'crsr' , theName ) ;
+ if ( resHandle )
+ {
+ short theId = -1 ;
+ OSType theType ;
+ GetResInfo( resHandle , &theId , &theType , theName ) ;
+ ReleaseResource( resHandle ) ;
+ M_CURSORDATA->m_hCursor = GetCCursor( theId ) ;
+ if ( M_CURSORDATA->m_hCursor )
+ M_CURSORDATA->m_isColorCursor = true ;
+ }
+ else
+ {
+ Handle resHandle = ::GetNamedResource( 'CURS' , theName ) ;
+ if ( resHandle )
+ {
+ short theId = -1 ;
+ OSType theType ;
+ GetResInfo( resHandle , &theId , &theType , theName ) ;
+ ReleaseResource( resHandle ) ;
+ M_CURSORDATA->m_hCursor = GetCursor( theId ) ;
+ if ( M_CURSORDATA->m_hCursor )
+ M_CURSORDATA->m_releaseHandle = true ;
+ }
+ }
+ }
+ else
+ {
+ wxImage image ;
+ image.LoadFile( cursor_file , flags ) ;
+ if( image.Ok() )
+ {
+ image.SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_X,hotSpotX ) ;
+ image.SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_Y,hotSpotY ) ;
+ delete m_refData ;
+ CreateFromImage(image) ;
+ }
+ }
+}
+
+// Cursors by stock number
+wxCursor::wxCursor(int cursor_type)
+{
+ m_refData = new wxCursorRefData;
+
+ switch (cursor_type)
+ {
+ case wxCURSOR_COPY_ARROW:
+ M_CURSORDATA->m_themeCursor = kThemeCopyArrowCursor ;
+ break;
+ case wxCURSOR_WAIT:
+ M_CURSORDATA->m_themeCursor = kThemeWatchCursor ;
+ break;
+ case wxCURSOR_IBEAM:
+ M_CURSORDATA->m_themeCursor = kThemeIBeamCursor ;
+ break;
+ case wxCURSOR_CROSS:
+ M_CURSORDATA->m_themeCursor = kThemeCrossCursor;
+ break;
+ case wxCURSOR_SIZENWSE:
+ {
+ wxStAppResource resload ;
+ M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorSizeNWSE);
+ }
+ break;
+ case wxCURSOR_SIZENESW:
+ {
+ wxStAppResource resload ;
+ M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorSizeNESW);
+ }
+ break;
+ case wxCURSOR_SIZEWE:
+ {
+ M_CURSORDATA->m_themeCursor = kThemeResizeLeftRightCursor;
+ }
+ break;
+ case wxCURSOR_SIZENS:
+ {
+ wxStAppResource resload ;
+ M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorSizeNS);
+ }
+ break;
+ case wxCURSOR_SIZING:
+ {
+ wxStAppResource resload ;
+ M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorSize);
+ }
+ break;
+ case wxCURSOR_HAND:
+ {
+ M_CURSORDATA->m_themeCursor = kThemePointingHandCursor;
+ }
+ break;
+ case wxCURSOR_BULLSEYE:
+ {
+ wxStAppResource resload ;
+ M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorBullseye);
+ }
+ break;
+ case wxCURSOR_PENCIL:
+ {
+ wxStAppResource resload ;
+ M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorPencil);
+ }
+ break;
+ case wxCURSOR_MAGNIFIER:
+ {
+ wxStAppResource resload ;
+ M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorMagnifier);
+ }
+ break;
+ case wxCURSOR_NO_ENTRY:
+ {
+ wxStAppResource resload ;
+ M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorNoEntry);
+ }
+ break;
+ case wxCURSOR_WATCH:
+ {
+ M_CURSORDATA->m_themeCursor = kThemeWatchCursor;
+ break;
+ }
+ case wxCURSOR_PAINT_BRUSH:
+ {
+ wxStAppResource resload ;
+ M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorPaintBrush);
+ break;
+ }
+ case wxCURSOR_POINT_LEFT:
+ {
+ wxStAppResource resload ;
+ M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorPointLeft);
+ break;
+ }
+ case wxCURSOR_POINT_RIGHT:
+ {
+ wxStAppResource resload ;
+ M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorPointRight);
+ break;
+ }
+ case wxCURSOR_QUESTION_ARROW:
+ {
+ wxStAppResource resload ;
+ M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorQuestionArrow);
+ break;
+ }
+ case wxCURSOR_BLANK:
+ {
+ wxStAppResource resload ;
+ M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorBlank);
+ break;
+ }
+ case wxCURSOR_RIGHT_ARROW:
+ {
+ wxStAppResource resload ;
+ M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorRightArrow);
+ break;
+ }
+ case wxCURSOR_SPRAYCAN:
+ {
+ wxStAppResource resload ;
+ M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorRoller);
+ break;
+ }
+ case wxCURSOR_CHAR:
+ case wxCURSOR_ARROW:
+ case wxCURSOR_LEFT_BUTTON:
+ case wxCURSOR_RIGHT_BUTTON:
+ case wxCURSOR_MIDDLE_BUTTON:
+ default:
+ M_CURSORDATA->m_themeCursor = kThemeArrowCursor ;
+ break;
+ }
+ if ( M_CURSORDATA->m_themeCursor == -1 )
+ M_CURSORDATA->m_releaseHandle = true ;
+}
+
+void wxCursor::MacInstall() const
+{
+ gMacCurrentCursor = *this ;
+ if ( m_refData && M_CURSORDATA->m_themeCursor != -1 )
+ {
+ SetThemeCursor( M_CURSORDATA->m_themeCursor ) ;
+ }
+ else if ( m_refData && M_CURSORDATA->m_hCursor )
+ {
+ if ( M_CURSORDATA->m_isColorCursor )
+ ::SetCCursor( (CCrsrHandle) M_CURSORDATA->m_hCursor ) ;
+ else
+ ::SetCursor( * (CursHandle) M_CURSORDATA->m_hCursor ) ;
+ }
+ else
+ {
+ SetThemeCursor( kThemeArrowCursor ) ;
+ }
+}
+
+wxCursor::~wxCursor()
+{
+}
+
+// Global cursor setting
+void wxSetCursor(const wxCursor& cursor)
+{
+ cursor.MacInstall() ;
+}
+
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: mac/data.cpp
+// Purpose: Various global Mac-specific data
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#include "wx/event.h"
+
+#if wxUSE_SHARED_LIBRARY
+///// Event tables (also must be in one, statically-linked file for shared libraries)
+
+// This is the base, wxEvtHandler 'bootstrap' code which is expanded manually here
+const wxEventTable *wxEvtHandler::GetEventTable() const { return &wxEvtHandler::sm_eventTable; }
+
+const wxEventTable wxEvtHandler::sm_eventTable =
+ { NULL, &wxEvtHandler::sm_eventTableEntries[0] };
+
+const wxEventTableEntry wxEvtHandler::sm_eventTableEntries[] = { { 0, 0, 0, NULL } };
+#endif
+
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Name: mac/dataobj.cpp
+// Purpose: implementation of wxDataObject class
+// Author: Stefan Csomor
+// Modified by:
+// Created: 10/21/99
+// RCS-ID: $Id$
+// Copyright: (c) 1999 Stefan Csomor
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#ifdef __GNUG__
+ #pragma implementation "dataobj.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifndef WX_PRECOMP
+#include "wx/intl.h"
+#endif
+#include "wx/defs.h"
+
+#include "wx/log.h"
+#include "wx/dataobj.h"
+#include "wx/mstream.h"
+#include "wx/image.h"
+#include "wx/mac/private.h"
+#include <Scrap.h>
+
+// ----------------------------------------------------------------------------
+// functions
+// ----------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------
+// wxDataFormat
+// ----------------------------------------------------------------------------
+
+wxDataFormat::wxDataFormat()
+{
+ m_type = wxDF_INVALID;
+ m_format = 0;
+}
+
+wxDataFormat::wxDataFormat( wxDataFormatId vType )
+{
+ SetType(vType);
+}
+
+wxDataFormat::wxDataFormat( const wxChar* zId)
+{
+ SetId(zId);
+}
+
+wxDataFormat::wxDataFormat( const wxString& rId)
+{
+ SetId(rId);
+}
+
+wxDataFormat::wxDataFormat( NativeFormat vFormat)
+{
+ SetId(vFormat);
+}
+
+void wxDataFormat::SetType( wxDataFormatId Type )
+{
+ m_type = Type;
+
+ if (m_type == wxDF_TEXT )
+ m_format = kScrapFlavorTypeText;
+ else if (m_type == wxDF_UNICODETEXT )
+ m_format = kScrapFlavorTypeUnicode ;
+ else if (m_type == wxDF_BITMAP || m_type == wxDF_METAFILE )
+ m_format = kScrapFlavorTypePicture;
+ else if (m_type == wxDF_FILENAME)
+ m_format = kDragFlavorTypeHFS ;
+ else
+ {
+ wxFAIL_MSG( wxT("invalid dataformat") );
+
+ // this is '????' but it can't be used in the code because ??' is
+ // parsed as a trigraph!
+ m_format = 0x3f3f3f3f;
+ }
+}
+
+wxString wxDataFormat::GetId() const
+{
+ // note that m_format is not a pointer to string, it *is* itself a 4
+ // character string
+ char text[5] ;
+ strncpy( text , (char*) &m_format , 4 ) ;
+ text[4] = 0 ;
+
+ return wxString::FromAscii( text ) ;
+}
+
+void wxDataFormat::SetId( NativeFormat format )
+{
+ m_format = format;
+
+ if (m_format == kScrapFlavorTypeText)
+ m_type = wxDF_TEXT;
+ else if (m_format == kScrapFlavorTypeUnicode )
+ m_type = wxDF_UNICODETEXT;
+ else if (m_format == kScrapFlavorTypePicture)
+ m_type = wxDF_BITMAP;
+ else if (m_format == kDragFlavorTypeHFS )
+ m_type = wxDF_FILENAME;
+ else
+ m_type = wxDF_PRIVATE;
+}
+
+void wxDataFormat::SetId( const wxChar* zId )
+{
+ m_type = wxDF_PRIVATE;
+ m_format = 0;// TODO: get the format gdk_atom_intern( wxMBSTRINGCAST tmp.mbc_str(), FALSE );
+}
+
+//-------------------------------------------------------------------------
+// wxDataObject
+//-------------------------------------------------------------------------
+
+wxDataObject::wxDataObject()
+{
+}
+
+bool wxDataObject::IsSupportedFormat(
+ const wxDataFormat& rFormat
+, Direction vDir
+) const
+{
+ size_t nFormatCount = GetFormatCount(vDir);
+
+ if (nFormatCount == 1)
+ {
+ return rFormat == GetPreferredFormat();
+ }
+ else
+ {
+ wxDataFormat* pFormats = new wxDataFormat[nFormatCount];
+ GetAllFormats( pFormats
+ ,vDir
+ );
+
+ size_t n;
+
+ for (n = 0; n < nFormatCount; n++)
+ {
+ if (pFormats[n] == rFormat)
+ break;
+ }
+
+ delete [] pFormats;
+
+ // found?
+ return n < nFormatCount;
+ }
+}
+
+// ----------------------------------------------------------------------------
+// wxFileDataObject
+// ----------------------------------------------------------------------------
+
+bool wxFileDataObject::GetDataHere(
+ void* pBuf
+) const
+{
+ wxString sFilenames;
+
+ for (size_t i = 0; i < m_filenames.GetCount(); i++)
+ {
+ sFilenames += m_filenames[i];
+ sFilenames += (wxChar)0;
+ }
+
+ memcpy(pBuf, sFilenames.mbc_str(), sFilenames.Len() + 1);
+ return TRUE;
+}
+
+size_t wxFileDataObject::GetDataSize() const
+{
+ size_t nRes = 0;
+
+ for (size_t i = 0; i < m_filenames.GetCount(); i++)
+ {
+ nRes += m_filenames[i].Len();
+ nRes += 1;
+ }
+
+ return nRes + 1;
+}
+
+bool wxFileDataObject::SetData(
+ size_t WXUNUSED(nSize)
+, const void* pBuf
+)
+{
+ m_filenames.Empty();
+
+ AddFile(wxString::FromAscii((char*)pBuf));
+
+ return TRUE;
+}
+
+void wxFileDataObject::AddFile(
+ const wxString& rFilename
+)
+{
+ m_filenames.Add(rFilename);
+}
+
+// ----------------------------------------------------------------------------
+// wxBitmapDataObject
+// ----------------------------------------------------------------------------
+
+wxBitmapDataObject::wxBitmapDataObject()
+{
+ Init();
+}
+
+wxBitmapDataObject::wxBitmapDataObject(
+ const wxBitmap& rBitmap
+)
+: wxBitmapDataObjectBase(rBitmap)
+{
+ Init();
+ if ( m_bitmap.Ok() )
+ {
+ m_pictHandle = m_bitmap.GetPict( &m_pictCreated ) ;
+ }
+}
+
+wxBitmapDataObject::~wxBitmapDataObject()
+{
+ Clear();
+}
+
+void wxBitmapDataObject::SetBitmap(
+ const wxBitmap& rBitmap
+)
+{
+ Clear();
+ wxBitmapDataObjectBase::SetBitmap(rBitmap);
+ if ( m_bitmap.Ok() )
+ {
+ m_pictHandle = m_bitmap.GetPict( &m_pictCreated ) ;
+ }
+}
+
+void wxBitmapDataObject::Init()
+{
+ m_pictHandle = NULL ;
+ m_pictCreated = false ;
+}
+
+void wxBitmapDataObject::Clear()
+{
+ if ( m_pictCreated && m_pictHandle )
+ {
+ KillPicture( (PicHandle) m_pictHandle ) ;
+ }
+ m_pictHandle = NULL ;
+}
+
+bool wxBitmapDataObject::GetDataHere(
+ void* pBuf
+) const
+{
+ if (!m_pictHandle)
+ {
+ wxFAIL_MSG(wxT("attempt to copy empty bitmap failed"));
+ return FALSE;
+ }
+ memcpy(pBuf, *(Handle)m_pictHandle, GetHandleSize((Handle)m_pictHandle));
+ return TRUE;
+}
+
+size_t wxBitmapDataObject::GetDataSize() const
+{
+ return GetHandleSize((Handle)m_pictHandle) ;
+}
+
+bool wxBitmapDataObject::SetData(
+ size_t nSize
+, const void* pBuf
+)
+{
+ Clear();
+ PicHandle picHandle = (PicHandle) NewHandle( nSize ) ;
+ memcpy( *picHandle , pBuf , nSize ) ;
+ m_pictHandle = picHandle ;
+ m_pictCreated = false ;
+ Rect frame = (**picHandle).picFrame ;
+
+ m_bitmap.SetPict( picHandle ) ;
+ m_bitmap.SetWidth( frame.right - frame.left ) ;
+ m_bitmap.SetHeight( frame.bottom - frame.top ) ;
+ return m_bitmap.Ok();
+}
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: dc.cpp
+// Purpose: wxDC class
+// Author: Stefan Csomor
+// Modified by:
+// Created: 01/02/97
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "dc.h"
+#endif
+
+#include "wx/dc.h"
+#include "wx/app.h"
+#include "wx/mac/uma.h"
+#include "wx/dcmemory.h"
+#include "wx/dcprint.h"
+#include "wx/region.h"
+#include "wx/image.h"
+#include "wx/log.h"
+
+#if __MSL__ >= 0x6000
+#include "math.h"
+using namespace std ;
+#endif
+
+#include "wx/mac/private.h"
+#include <ATSUnicode.h>
+#include <TextCommon.h>
+#include <TextEncodingConverter.h>
+#include <FixMath.h>
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject)
+#endif
+
+//-----------------------------------------------------------------------------
+// constants
+//-----------------------------------------------------------------------------
+
+#define mm2inches 0.0393700787402
+#define inches2mm 25.4
+#define mm2twips 56.6929133859
+#define twips2mm 0.0176388888889
+#define mm2pt 2.83464566929
+#define pt2mm 0.352777777778
+#if !defined( __DARWIN__ ) || defined(__MWERKS__)
+#ifndef M_PI
+const double M_PI = 3.14159265358979 ;
+#endif
+#endif
+const double RAD2DEG = 180.0 / M_PI;
+const short kEmulatedMode = -1 ;
+const short kUnsupportedMode = -2 ;
+
+extern TECObjectRef s_TECNativeCToUnicode ;
+
+// set to 0 if problems arise
+#define wxMAC_EXPERIMENTAL_DC 1
+
+wxMacPortSetter::wxMacPortSetter( const wxDC* dc ) :
+ m_ph( (GrafPtr) dc->m_macPort )
+{
+ wxASSERT( dc->Ok() ) ;
+ m_dc = dc ;
+ dc->MacSetupPort(&m_ph) ;
+}
+wxMacPortSetter::~wxMacPortSetter()
+{
+ m_dc->MacCleanupPort(&m_ph) ;
+}
+
+#if wxMAC_EXPERIMENTAL_DC
+class wxMacFastPortSetter
+{
+public :
+ wxMacFastPortSetter( const wxDC *dc )
+ {
+ wxASSERT( dc->Ok() ) ;
+ GetPort( &m_oldPort ) ;
+ SetPort( (GrafPtr) dc->m_macPort ) ;
+ m_clipRgn = NewRgn() ;
+ GetClip( m_clipRgn ) ;
+ m_dc = dc ;
+ dc->MacSetupPort( NULL ) ;
+ }
+ ~wxMacFastPortSetter()
+ {
+ SetPort( (GrafPtr) m_dc->m_macPort ) ;
+ SetClip( m_clipRgn ) ;
+ SetPort( m_oldPort ) ;
+ m_dc->MacCleanupPort( NULL ) ;
+ DisposeRgn( m_clipRgn ) ;
+ }
+private :
+ RgnHandle m_clipRgn ;
+ GrafPtr m_oldPort ;
+ const wxDC* m_dc ;
+} ;
+
+#else
+typedef wxMacPortSetter wxMacFastPortSetter ;
+#endif
+
+#if 0
+
+// start moving to a dual implementation for QD and CGContextRef
+
+class wxMacGraphicsContext
+{
+public :
+ void DrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask ) = 0 ;
+ void SetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord height ) = 0 ;
+ void SetClippingRegion( const wxRegion ®ion ) = 0 ;
+ void DestroyClippingRegion() = 0 ;
+ void SetTextForeground( const wxColour &col ) = 0 ;
+ void SetTextBackground( const wxColour &col ) = 0 ;
+ void SetLogicalScale( double x , double y ) = 0 ;
+ void SetUserScale( double x , double y ) = 0;
+} ;
+
+class wxMacQuickDrawContext : public wxMacGraphicsContext
+{
+public :
+} ;
+
+#endif
+
+wxMacWindowClipper::wxMacWindowClipper( const wxWindow* win )
+{
+ m_formerClip = NewRgn() ;
+ m_newClip = NewRgn() ;
+ GetClip( m_formerClip ) ;
+
+ if ( win )
+ {
+#if 0
+ // this clipping area was set to the parent window's drawing area, lead to problems
+ // with MacOSX controls drawing outside their wx' rectangle
+ RgnHandle insidergn = NewRgn() ;
+ int x = 0 , y = 0;
+ wxWindow *parent = win->GetParent() ;
+ parent->MacWindowToRootWindow( &x,&y ) ;
+ wxSize size = parent->GetSize() ;
+ SetRectRgn( insidergn , parent->MacGetLeftBorderSize() , parent->MacGetTopBorderSize() ,
+ size.x - parent->MacGetRightBorderSize(),
+ size.y - parent->MacGetBottomBorderSize()) ;
+ CopyRgn( (RgnHandle) parent->MacGetVisibleRegion(false).GetWXHRGN() , m_newClip ) ;
+ SectRgn( m_newClip , insidergn , m_newClip ) ;
+ OffsetRgn( m_newClip , x , y ) ;
+ SetClip( m_newClip ) ;
+ DisposeRgn( insidergn ) ;
+#else
+ int x = 0 , y = 0;
+ win->MacWindowToRootWindow( &x,&y ) ;
+ CopyRgn( (RgnHandle) ((wxWindow*)win)->MacGetVisibleRegion().GetWXHRGN() , m_newClip ) ;
+ OffsetRgn( m_newClip , x , y ) ;
+ SetClip( m_newClip ) ;
+#endif
+ }
+}
+
+wxMacWindowClipper::~wxMacWindowClipper()
+{
+ SetClip( m_formerClip ) ;
+ DisposeRgn( m_newClip ) ;
+ DisposeRgn( m_formerClip ) ;
+}
+
+//-----------------------------------------------------------------------------
+// Local functions
+//-----------------------------------------------------------------------------
+static inline double dmin(double a, double b) { return a < b ? a : b; }
+static inline double dmax(double a, double b) { return a > b ? a : b; }
+static inline double DegToRad(double deg) { return (deg * M_PI) / 180.0; }
+
+//-----------------------------------------------------------------------------
+// wxDC
+//-----------------------------------------------------------------------------
+// this function emulates all wx colour manipulations, used to verify the implementation
+// by setting the mode in the blitting functions to kEmulatedMode
+void wxMacCalculateColour( int logical_func , const RGBColor &srcColor , RGBColor &dstColor ) ;
+
+void wxMacCalculateColour( int logical_func , const RGBColor &srcColor , RGBColor &dstColor )
+{
+ switch ( logical_func )
+ {
+ case wxAND: // src AND dst
+ dstColor.red = dstColor.red & srcColor.red ;
+ dstColor.green = dstColor.green & srcColor.green ;
+ dstColor.blue = dstColor.blue & srcColor.blue ;
+ break ;
+ case wxAND_INVERT: // (NOT src) AND dst
+ dstColor.red = dstColor.red & ~srcColor.red ;
+ dstColor.green = dstColor.green & ~srcColor.green ;
+ dstColor.blue = dstColor.blue & ~srcColor.blue ;
+ break ;
+ case wxAND_REVERSE:// src AND (NOT dst)
+ dstColor.red = ~dstColor.red & srcColor.red ;
+ dstColor.green = ~dstColor.green & srcColor.green ;
+ dstColor.blue = ~dstColor.blue & srcColor.blue ;
+ break ;
+ case wxCLEAR: // 0
+ dstColor.red = 0 ;
+ dstColor.green = 0 ;
+ dstColor.blue = 0 ;
+ break ;
+ case wxCOPY: // src
+ dstColor.red = srcColor.red ;
+ dstColor.green = srcColor.green ;
+ dstColor.blue = srcColor.blue ;
+ break ;
+ case wxEQUIV: // (NOT src) XOR dst
+ dstColor.red = dstColor.red ^ ~srcColor.red ;
+ dstColor.green = dstColor.green ^ ~srcColor.green ;
+ dstColor.blue = dstColor.blue ^ ~srcColor.blue ;
+ break ;
+ case wxINVERT: // NOT dst
+ dstColor.red = ~dstColor.red ;
+ dstColor.green = ~dstColor.green ;
+ dstColor.blue = ~dstColor.blue ;
+ break ;
+ case wxNAND: // (NOT src) OR (NOT dst)
+ dstColor.red = ~dstColor.red | ~srcColor.red ;
+ dstColor.green = ~dstColor.green | ~srcColor.green ;
+ dstColor.blue = ~dstColor.blue | ~srcColor.blue ;
+ break ;
+ case wxNOR: // (NOT src) AND (NOT dst)
+ dstColor.red = ~dstColor.red & ~srcColor.red ;
+ dstColor.green = ~dstColor.green & ~srcColor.green ;
+ dstColor.blue = ~dstColor.blue & ~srcColor.blue ;
+ break ;
+ case wxNO_OP: // dst
+ break ;
+ case wxOR: // src OR dst
+ dstColor.red = dstColor.red | srcColor.red ;
+ dstColor.green = dstColor.green | srcColor.green ;
+ dstColor.blue = dstColor.blue | srcColor.blue ;
+ break ;
+ case wxOR_INVERT: // (NOT src) OR dst
+ dstColor.red = dstColor.red | ~srcColor.red ;
+ dstColor.green = dstColor.green | ~srcColor.green ;
+ dstColor.blue = dstColor.blue | ~srcColor.blue ;
+ break ;
+ case wxOR_REVERSE: // src OR (NOT dst)
+ dstColor.red = ~dstColor.red | srcColor.red ;
+ dstColor.green = ~dstColor.green | srcColor.green ;
+ dstColor.blue = ~dstColor.blue | srcColor.blue ;
+ break ;
+ case wxSET: // 1
+ dstColor.red = 0xFFFF ;
+ dstColor.green = 0xFFFF ;
+ dstColor.blue = 0xFFFF ;
+ break ;
+ case wxSRC_INVERT: // (NOT src)
+ dstColor.red = ~srcColor.red ;
+ dstColor.green = ~srcColor.green ;
+ dstColor.blue = ~srcColor.blue ;
+ break ;
+ case wxXOR: // src XOR dst
+ dstColor.red = dstColor.red ^ srcColor.red ;
+ dstColor.green = dstColor.green ^ srcColor.green ;
+ dstColor.blue = dstColor.blue ^ srcColor.blue ;
+ break ;
+ }
+}
+
+wxDC::wxDC()
+{
+ m_ok = FALSE;
+ m_colour = TRUE;
+ m_mm_to_pix_x = mm2pt;
+ m_mm_to_pix_y = mm2pt;
+ m_internalDeviceOriginX = 0;
+ m_internalDeviceOriginY = 0;
+ m_externalDeviceOriginX = 0;
+ m_externalDeviceOriginY = 0;
+ m_logicalScaleX = 1.0;
+ m_logicalScaleY = 1.0;
+ m_userScaleX = 1.0;
+ m_userScaleY = 1.0;
+ m_scaleX = 1.0;
+ m_scaleY = 1.0;
+ m_needComputeScaleX = FALSE;
+ m_needComputeScaleY = FALSE;
+ m_macPort = NULL ;
+ m_macMask = NULL ;
+ m_ok = FALSE ;
+ m_macFontInstalled = false ;
+ m_macBrushInstalled = false ;
+ m_macPenInstalled = false ;
+ m_macLocalOrigin.x = m_macLocalOrigin.y = 0 ;
+ m_macBoundaryClipRgn = NewRgn() ;
+ m_macCurrentClipRgn = NewRgn() ;
+ SetRectRgn( (RgnHandle) m_macBoundaryClipRgn , -32000 , -32000 , 32000 , 32000 ) ;
+ SetRectRgn( (RgnHandle) m_macCurrentClipRgn , -32000 , -32000 , 32000 , 32000 ) ;
+ m_pen = *wxBLACK_PEN;
+ m_font = *wxNORMAL_FONT;
+ m_brush = *wxWHITE_BRUSH;
+#ifdef __WXDEBUG__
+ // needed to debug possible errors with two active drawing methods at the same time on
+ // the same DC
+ m_macCurrentPortStateHelper = NULL ;
+#endif
+ m_macATSUIStyle = NULL ;
+ m_macAliasWasEnabled = false;
+ m_macForegroundPixMap = NULL ;
+ m_macBackgroundPixMap = NULL ;
+}
+
+wxDC::~wxDC(void)
+{
+ DisposeRgn( (RgnHandle) m_macBoundaryClipRgn ) ;
+ DisposeRgn( (RgnHandle) m_macCurrentClipRgn ) ;
+}
+
+void wxDC::MacSetupPort(wxMacPortStateHelper* help) const
+{
+#ifdef __WXDEBUG__
+ wxASSERT( m_macCurrentPortStateHelper == NULL ) ;
+ m_macCurrentPortStateHelper = help ;
+#endif
+ SetClip( (RgnHandle) m_macCurrentClipRgn);
+#if ! wxMAC_EXPERIMENTAL_DC
+ m_macFontInstalled = false ;
+ m_macBrushInstalled = false ;
+ m_macPenInstalled = false ;
+#endif
+}
+void wxDC::MacCleanupPort(wxMacPortStateHelper* help) const
+{
+#ifdef __WXDEBUG__
+ wxASSERT( m_macCurrentPortStateHelper == help ) ;
+ m_macCurrentPortStateHelper = NULL ;
+#endif
+ if( m_macATSUIStyle )
+ {
+ ::ATSUDisposeStyle((ATSUStyle)m_macATSUIStyle);
+ m_macATSUIStyle = NULL ;
+ }
+ if ( m_macAliasWasEnabled )
+ {
+ SetAntiAliasedTextEnabled(m_macFormerAliasState, m_macFormerAliasSize);
+ m_macAliasWasEnabled = false ;
+ }
+ if ( m_macForegroundPixMap )
+ {
+ Pattern blackColor ;
+ ::PenPat(GetQDGlobalsBlack(&blackColor));
+ DisposePixPat( (PixPatHandle) m_macForegroundPixMap ) ;
+ m_macForegroundPixMap = NULL ;
+ }
+ if ( m_macBackgroundPixMap )
+ {
+ Pattern whiteColor ;
+ ::BackPat(GetQDGlobalsWhite(&whiteColor));
+ DisposePixPat( (PixPatHandle) m_macBackgroundPixMap ) ;
+ m_macBackgroundPixMap = NULL ;
+ }
+}
+
+void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask )
+{
+ wxCHECK_RET( Ok(), wxT("invalid window dc") );
+ wxCHECK_RET( bmp.Ok(), wxT("invalid bitmap") );
+ wxMacFastPortSetter helper(this) ;
+ wxCoord xx = XLOG2DEVMAC(x);
+ wxCoord yy = YLOG2DEVMAC(y);
+ wxCoord w = bmp.GetWidth();
+ wxCoord h = bmp.GetHeight();
+ wxCoord ww = XLOG2DEVREL(w);
+ wxCoord hh = YLOG2DEVREL(h);
+ // Set up drawing mode
+ short mode = (m_logicalFunction == wxCOPY ? srcCopy :
+ //m_logicalFunction == wxCLEAR ? WHITENESS :
+ //m_logicalFunction == wxSET ? BLACKNESS :
+ m_logicalFunction == wxINVERT ? hilite :
+ //m_logicalFunction == wxAND ? MERGECOPY :
+ m_logicalFunction == wxOR ? srcOr :
+ m_logicalFunction == wxSRC_INVERT ? notSrcCopy :
+ m_logicalFunction == wxXOR ? srcXor :
+ m_logicalFunction == wxOR_REVERSE ? notSrcOr :
+ //m_logicalFunction == wxAND_REVERSE ? SRCERASE :
+ //m_logicalFunction == wxSRC_OR ? srcOr :
+ //m_logicalFunction == wxSRC_AND ? SRCAND :
+ srcCopy );
+ if ( bmp.GetBitmapType() == kMacBitmapTypePict ) {
+ Rect bitmaprect = { 0 , 0 , hh, ww };
+ ::OffsetRect( &bitmaprect, xx, yy ) ;
+ ::DrawPicture( (PicHandle) bmp.GetPict(), &bitmaprect ) ;
+ }
+ else if ( bmp.GetBitmapType() == kMacBitmapTypeGrafWorld )
+ {
+ GWorldPtr bmapworld = MAC_WXHBITMAP( bmp.GetHBITMAP() );
+ PixMapHandle bmappixels ;
+ // Set foreground and background colours (for bitmaps depth = 1)
+ if(bmp.GetDepth() == 1)
+ {
+ RGBColor fore = MAC_WXCOLORREF(m_textForegroundColour.GetPixel());
+ RGBColor back = MAC_WXCOLORREF(m_textBackgroundColour.GetPixel());
+ RGBForeColor(&fore);
+ RGBBackColor(&back);
+ }
+ else
+ {
+ RGBColor white = { 0xFFFF, 0xFFFF,0xFFFF} ;
+ RGBColor black = { 0,0,0} ;
+ RGBForeColor( &black ) ;
+ RGBBackColor( &white ) ;
+ }
+ bmappixels = GetGWorldPixMap( bmapworld ) ;
+ wxCHECK_RET(LockPixels(bmappixels),
+ wxT("DoDrawBitmap: Unable to lock pixels"));
+ Rect source = { 0, 0, h, w };
+ Rect dest = { yy, xx, yy + hh, xx + ww };
+ if ( useMask && bmp.GetMask() )
+ {
+ if( LockPixels(GetGWorldPixMap(MAC_WXHBITMAP(bmp.GetMask()->GetMaskBitmap()))))
+ {
+ CopyDeepMask
+ (
+ GetPortBitMapForCopyBits(bmapworld),
+ GetPortBitMapForCopyBits(MAC_WXHBITMAP(bmp.GetMask()->GetMaskBitmap())),
+ GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort) ),
+ &source, &source, &dest, mode, NULL
+ );
+ UnlockPixels(GetGWorldPixMap(MAC_WXHBITMAP(bmp.GetMask()->GetMaskBitmap())));
+ }
+ }
+ else {
+ CopyBits( GetPortBitMapForCopyBits( bmapworld ),
+ GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort) ),
+ &source, &dest, mode, NULL ) ;
+ }
+ UnlockPixels( bmappixels ) ;
+ }
+ else if ( bmp.GetBitmapType() == kMacBitmapTypeIcon )
+ {
+ Rect bitmaprect = { 0 , 0 , bmp.GetHeight(), bmp.GetWidth() } ;
+ OffsetRect( &bitmaprect, xx, yy ) ;
+ PlotCIconHandle( &bitmaprect , atNone , ttNone , MAC_WXHICON(bmp.GetHICON()) ) ;
+ }
+ m_macPenInstalled = false ;
+ m_macBrushInstalled = false ;
+ m_macFontInstalled = false ;
+}
+
+void wxDC::DoDrawIcon( const wxIcon &icon, wxCoord x, wxCoord y )
+{
+ wxCHECK_RET(Ok(), wxT("Invalid dc wxDC::DoDrawIcon"));
+ wxCHECK_RET(icon.Ok(), wxT("Invalid icon wxDC::DoDrawIcon"));
+ DoDrawBitmap( icon , x , y , icon.GetMask() != NULL ) ;
+}
+
+void wxDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord height )
+{
+ wxCHECK_RET(Ok(), wxT("wxDC::DoSetClippingRegion Invalid DC"));
+ wxCoord xx, yy, ww, hh;
+ xx = XLOG2DEVMAC(x);
+ yy = YLOG2DEVMAC(y);
+ ww = XLOG2DEVREL(width);
+ hh = YLOG2DEVREL(height);
+ SetRectRgn( (RgnHandle) m_macCurrentClipRgn , xx , yy , xx + ww , yy + hh ) ;
+ SectRgn( (RgnHandle) m_macCurrentClipRgn , (RgnHandle) m_macBoundaryClipRgn , (RgnHandle) m_macCurrentClipRgn ) ;
+ if( m_clipping )
+ {
+ m_clipX1 = wxMax( m_clipX1 , xx );
+ m_clipY1 = wxMax( m_clipY1 , yy );
+ m_clipX2 = wxMin( m_clipX2, (xx + ww));
+ m_clipY2 = wxMin( m_clipY2, (yy + hh));
+ }
+ else
+ {
+ m_clipping = TRUE;
+ m_clipX1 = xx;
+ m_clipY1 = yy;
+ m_clipX2 = xx + ww;
+ m_clipY2 = yy + hh;
+ }
+}
+
+void wxDC::DoSetClippingRegionAsRegion( const wxRegion ®ion )
+{
+ wxCHECK_RET( Ok(), wxT("invalid window dc") ) ;
+ if (region.Empty())
+ {
+ DestroyClippingRegion();
+ return;
+ }
+ wxMacFastPortSetter helper(this) ;
+ wxCoord x, y, w, h;
+ region.GetBox( x, y, w, h );
+ wxCoord xx, yy, ww, hh;
+ xx = XLOG2DEVMAC(x);
+ yy = YLOG2DEVMAC(y);
+ ww = XLOG2DEVREL(w);
+ hh = YLOG2DEVREL(h);
+ // if we have a scaling that we cannot map onto native regions
+ // we must use the box
+ if ( ww != w || hh != h )
+ {
+ wxDC::DoSetClippingRegion( x, y, w, h );
+ }
+ else
+ {
+ CopyRgn( (RgnHandle) region.GetWXHRGN() , (RgnHandle) m_macCurrentClipRgn ) ;
+ if ( xx != x || yy != y )
+ {
+ OffsetRgn( (RgnHandle) m_macCurrentClipRgn , xx - x , yy - y ) ;
+ }
+ SectRgn( (RgnHandle) m_macCurrentClipRgn , (RgnHandle) m_macBoundaryClipRgn , (RgnHandle) m_macCurrentClipRgn ) ;
+ if( m_clipping )
+ {
+ m_clipX1 = wxMax( m_clipX1 , xx );
+ m_clipY1 = wxMax( m_clipY1 , yy );
+ m_clipX2 = wxMin( m_clipX2, (xx + ww));
+ m_clipY2 = wxMin( m_clipY2, (yy + hh));
+ }
+ else
+ {
+ m_clipping = TRUE;
+ m_clipX1 = xx;
+ m_clipY1 = yy;
+ m_clipX2 = xx + ww;
+ m_clipY2 = yy + hh;
+ }
+ }
+}
+
+void wxDC::DestroyClippingRegion()
+{
+ wxMacFastPortSetter helper(this) ;
+ CopyRgn( (RgnHandle) m_macBoundaryClipRgn , (RgnHandle) m_macCurrentClipRgn ) ;
+ m_clipping = FALSE;
+}
+
+void wxDC::DoGetSizeMM( int* width, int* height ) const
+{
+ int w = 0;
+ int h = 0;
+ GetSize( &w, &h );
+ *width = long( double(w) / (m_scaleX*m_mm_to_pix_x) );
+ *height = long( double(h) / (m_scaleY*m_mm_to_pix_y) );
+}
+
+void wxDC::SetTextForeground( const wxColour &col )
+{
+ wxCHECK_RET(Ok(), wxT("Invalid DC"));
+ m_textForegroundColour = col;
+ m_macFontInstalled = false ;
+}
+
+void wxDC::SetTextBackground( const wxColour &col )
+{
+ wxCHECK_RET(Ok(), wxT("Invalid DC"));
+ m_textBackgroundColour = col;
+ m_macFontInstalled = false ;
+}
+
+void wxDC::SetMapMode( int mode )
+{
+ switch (mode)
+ {
+ case wxMM_TWIPS:
+ SetLogicalScale( twips2mm*m_mm_to_pix_x, twips2mm*m_mm_to_pix_y );
+ break;
+ case wxMM_POINTS:
+ SetLogicalScale( pt2mm*m_mm_to_pix_x, pt2mm*m_mm_to_pix_y );
+ break;
+ case wxMM_METRIC:
+ SetLogicalScale( m_mm_to_pix_x, m_mm_to_pix_y );
+ break;
+ case wxMM_LOMETRIC:
+ SetLogicalScale( m_mm_to_pix_x/10.0, m_mm_to_pix_y/10.0 );
+ break;
+ default:
+ case wxMM_TEXT:
+ SetLogicalScale( 1.0, 1.0 );
+ break;
+ }
+ if (mode != wxMM_TEXT)
+ {
+ m_needComputeScaleX = TRUE;
+ m_needComputeScaleY = TRUE;
+ }
+}
+
+void wxDC::SetUserScale( double x, double y )
+{
+ // allow negative ? -> no
+ m_userScaleX = x;
+ m_userScaleY = y;
+ ComputeScaleAndOrigin();
+}
+
+void wxDC::SetLogicalScale( double x, double y )
+{
+ // allow negative ?
+ m_logicalScaleX = x;
+ m_logicalScaleY = y;
+ ComputeScaleAndOrigin();
+}
+
+void wxDC::SetLogicalOrigin( wxCoord x, wxCoord y )
+{
+ m_logicalOriginX = x * m_signX; // is this still correct ?
+ m_logicalOriginY = y * m_signY;
+ ComputeScaleAndOrigin();
+}
+
+void wxDC::SetDeviceOrigin( wxCoord x, wxCoord y )
+{
+ m_externalDeviceOriginX = x;
+ m_externalDeviceOriginY = y;
+ ComputeScaleAndOrigin();
+}
+
+#if 0
+void wxDC::SetInternalDeviceOrigin( long x, long y )
+{
+ m_internalDeviceOriginX = x;
+ m_internalDeviceOriginY = y;
+ ComputeScaleAndOrigin();
+}
+void wxDC::GetInternalDeviceOrigin( long *x, long *y )
+{
+ if (x) *x = m_internalDeviceOriginX;
+ if (y) *y = m_internalDeviceOriginY;
+}
+#endif
+
+void wxDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp )
+{
+ m_signX = (xLeftRight ? 1 : -1);
+ m_signY = (yBottomUp ? -1 : 1);
+ ComputeScaleAndOrigin();
+}
+
+wxSize wxDC::GetPPI() const
+{
+ return wxSize(72, 72);
+}
+
+int wxDC::GetDepth() const
+{
+ if ( IsPortColor( (CGrafPtr) m_macPort ) )
+ {
+ return ( (**GetPortPixMap( (CGrafPtr) m_macPort)).pixelSize ) ;
+ }
+ return 1 ;
+}
+
+void wxDC::ComputeScaleAndOrigin()
+{
+ // CMB: copy scale to see if it changes
+ double origScaleX = m_scaleX;
+ double origScaleY = m_scaleY;
+ m_scaleX = m_logicalScaleX * m_userScaleX;
+ m_scaleY = m_logicalScaleY * m_userScaleY;
+ m_deviceOriginX = m_internalDeviceOriginX + m_externalDeviceOriginX;
+ m_deviceOriginY = m_internalDeviceOriginY + m_externalDeviceOriginY;
+ // CMB: if scale has changed call SetPen to recalulate the line width
+ if (m_scaleX != origScaleX || m_scaleY != origScaleY)
+ {
+ // this is a bit artificial, but we need to force wxDC to think
+ // the pen has changed
+ wxPen* pen = & GetPen();
+ wxPen tempPen;
+ m_pen = tempPen;
+ SetPen(* pen);
+ }
+}
+
+void wxDC::SetPalette( const wxPalette& palette )
+{
+}
+
+void wxDC::SetBackgroundMode( int mode )
+{
+ m_backgroundMode = mode ;
+}
+
+void wxDC::SetFont( const wxFont &font )
+{
+ m_font = font;
+ m_macFontInstalled = false ;
+}
+
+void wxDC::SetPen( const wxPen &pen )
+{
+ if ( m_pen == pen )
+ return ;
+ m_pen = pen;
+ m_macPenInstalled = false ;
+}
+
+void wxDC::SetBrush( const wxBrush &brush )
+{
+ if (m_brush == brush)
+ return;
+ m_brush = brush;
+ m_macBrushInstalled = false ;
+}
+
+void wxDC::SetBackground( const wxBrush &brush )
+{
+ if (m_backgroundBrush == brush)
+ return;
+ m_backgroundBrush = brush;
+ if (!m_backgroundBrush.Ok())
+ return;
+ m_macBrushInstalled = false ;
+}
+
+void wxDC::SetLogicalFunction( int function )
+{
+ if (m_logicalFunction == function)
+ return;
+ m_logicalFunction = function ;
+ m_macFontInstalled = false ;
+ m_macBrushInstalled = false ;
+ m_macPenInstalled = false ;
+}
+
+extern bool wxDoFloodFill(wxDC *dc, wxCoord x, wxCoord y,
+ const wxColour & col, int style);
+
+bool wxDC::DoFloodFill(wxCoord x, wxCoord y,
+ const wxColour& col, int style)
+{
+ return wxDoFloodFill(this, x, y, col, style);
+}
+
+bool wxDC::DoGetPixel( wxCoord x, wxCoord y, wxColour *col ) const
+{
+ wxCHECK_MSG( Ok(), false, wxT("wxDC::DoGetPixel Invalid DC") );
+ wxMacFastPortSetter helper(this) ;
+ RGBColor colour;
+ GetCPixel( XLOG2DEVMAC(x), YLOG2DEVMAC(y), &colour );
+ // Convert from Mac colour to wx
+ col->Set( colour.red >> 8,
+ colour.green >> 8,
+ colour.blue >> 8);
+ return true ;
+}
+
+void wxDC::DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2 )
+{
+ wxCHECK_RET(Ok(), wxT("Invalid DC"));
+ wxMacFastPortSetter helper(this) ;
+ if (m_pen.GetStyle() != wxTRANSPARENT)
+ {
+ MacInstallPen() ;
+ wxCoord offset = ( (m_pen.GetWidth() == 0 ? 1 :
+ m_pen.GetWidth() ) * (wxCoord)m_scaleX - 1) / 2;
+ wxCoord xx1 = XLOG2DEVMAC(x1) - offset;
+ wxCoord yy1 = YLOG2DEVMAC(y1) - offset;
+ wxCoord xx2 = XLOG2DEVMAC(x2) - offset;
+ wxCoord yy2 = YLOG2DEVMAC(y2) - offset;
+ if ((m_pen.GetCap() == wxCAP_ROUND) &&
+ (m_pen.GetWidth() <= 1))
+ {
+ // Implement LAST_NOT for MAC at least for
+ // orthogonal lines. RR.
+ if (xx1 == xx2)
+ {
+ if (yy1 < yy2)
+ yy2--;
+ if (yy1 > yy2)
+ yy2++;
+ }
+ if (yy1 == yy2)
+ {
+ if (xx1 < xx2)
+ xx2--;
+ if (xx1 > xx2)
+ xx2++;
+ }
+ }
+ ::MoveTo(xx1, yy1);
+ ::LineTo(xx2, yy2);
+ }
+}
+
+void wxDC::DoCrossHair( wxCoord x, wxCoord y )
+{
+ wxCHECK_RET( Ok(), wxT("wxDC::DoCrossHair Invalid window dc") );
+ wxMacFastPortSetter helper(this) ;
+ if (m_pen.GetStyle() != wxTRANSPARENT)
+ {
+ int w = 0;
+ int h = 0;
+ GetSize( &w, &h );
+ wxCoord xx = XLOG2DEVMAC(x);
+ wxCoord yy = YLOG2DEVMAC(y);
+ MacInstallPen();
+ ::MoveTo( XLOG2DEVMAC(0), yy );
+ ::LineTo( XLOG2DEVMAC(w), yy );
+ ::MoveTo( xx, YLOG2DEVMAC(0) );
+ ::LineTo( xx, YLOG2DEVMAC(h) );
+ CalcBoundingBox(x, y);
+ CalcBoundingBox(x+w, y+h);
+ }
+}
+
+/*
+* To draw arcs properly the angles need to be converted from the WX style:
+* Angles start on the +ve X axis and go anti-clockwise (As you would draw on
+* a normal axis on paper).
+* TO
+* the Mac style:
+* Angles start on the +ve y axis and go clockwise.
+*/
+
+static double wxConvertWXangleToMACangle(double angle)
+{
+ double newAngle = 90 - angle ;
+ if ( newAngle < 0 )
+ newAngle += 360 ;
+ return newAngle ;
+}
+
+void wxDC::DoDrawArc( wxCoord x1, wxCoord y1,
+ wxCoord x2, wxCoord y2,
+ wxCoord xc, wxCoord yc )
+{
+ wxCHECK_RET(Ok(), wxT("wxDC::DoDrawArc Invalid DC"));
+ wxMacFastPortSetter helper(this) ;
+ wxCoord xx1 = XLOG2DEVMAC(x1);
+ wxCoord yy1 = YLOG2DEVMAC(y1);
+ wxCoord xx2 = XLOG2DEVMAC(x2);
+ wxCoord yy2 = YLOG2DEVMAC(y2);
+ wxCoord xxc = XLOG2DEVMAC(xc);
+ wxCoord yyc = YLOG2DEVMAC(yc);
+ double dx = xx1 - xxc;
+ double dy = yy1 - yyc;
+ double radius = sqrt((double)(dx*dx+dy*dy));
+ wxCoord rad = (wxCoord)radius;
+ double radius1, radius2;
+ if (xx1 == xx2 && yy1 == yy2)
+ {
+ radius1 = 0.0;
+ radius2 = 360.0;
+ }
+ else if (radius == 0.0)
+ {
+ radius1 = radius2 = 0.0;
+ }
+ else
+ {
+ radius1 = (xx1 - xxc == 0) ?
+ (yy1 - yyc < 0) ? 90.0 : -90.0 :
+ -atan2(double(yy1-yyc), double(xx1-xxc)) * RAD2DEG;
+ radius2 = (xx2 - xxc == 0) ?
+ (yy2 - yyc < 0) ? 90.0 : -90.0 :
+ -atan2(double(yy2-yyc), double(xx2-xxc)) * RAD2DEG;
+ }
+ wxCoord alpha2 = wxCoord(radius2 - radius1);
+ wxCoord alpha1 = wxCoord(wxConvertWXangleToMACangle(radius1));
+ if( (xx1 > xx2) || (yy1 > yy2) ) {
+ alpha2 *= -1;
+ }
+ Rect r = { yyc - rad, xxc - rad, yyc + rad, xxc + rad };
+ if(m_brush.GetStyle() != wxTRANSPARENT) {
+ MacInstallBrush();
+ PaintArc(&r, alpha1, alpha2);
+ }
+ if(m_pen.GetStyle() != wxTRANSPARENT) {
+ MacInstallPen();
+ FrameArc(&r, alpha1, alpha2);
+ }
+}
+
+void wxDC::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord w, wxCoord h,
+ double sa, double ea )
+{
+ wxCHECK_RET(Ok(), wxT("wxDC::DoDrawEllepticArc Invalid DC"));
+ wxMacFastPortSetter helper(this) ;
+ Rect r;
+ double angle = sa - ea; // Order important Mac in opposite direction to wx
+ // we have to make sure that the filling is always counter-clockwise
+ if ( angle > 0 )
+ angle -= 360 ;
+ wxCoord xx = XLOG2DEVMAC(x);
+ wxCoord yy = YLOG2DEVMAC(y);
+ wxCoord ww = m_signX * XLOG2DEVREL(w);
+ wxCoord hh = m_signY * YLOG2DEVREL(h);
+ // handle -ve width and/or height
+ if (ww < 0) { ww = -ww; xx = xx - ww; }
+ if (hh < 0) { hh = -hh; yy = yy - hh; }
+ sa = wxConvertWXangleToMACangle(sa);
+ r.top = yy;
+ r.left = xx;
+ r.bottom = yy + hh;
+ r.right = xx + ww;
+ if(m_brush.GetStyle() != wxTRANSPARENT) {
+ MacInstallBrush();
+ PaintArc(&r, (short)sa, (short)angle);
+ }
+ if(m_pen.GetStyle() != wxTRANSPARENT) {
+ MacInstallPen();
+ FrameArc(&r, (short)sa, (short)angle);
+ }
+}
+
+void wxDC::DoDrawPoint( wxCoord x, wxCoord y )
+{
+ wxCHECK_RET(Ok(), wxT("Invalid DC"));
+ wxMacFastPortSetter helper(this) ;
+ if (m_pen.GetStyle() != wxTRANSPARENT)
+ {
+ wxCoord xx1 = XLOG2DEVMAC(x);
+ wxCoord yy1 = YLOG2DEVMAC(y);
+ RGBColor pencolor = MAC_WXCOLORREF( m_pen.GetColour().GetPixel());
+ ::SetCPixel( xx1,yy1,&pencolor) ;
+ CalcBoundingBox(x, y);
+ }
+}
+
+void wxDC::DoDrawLines(int n, wxPoint points[],
+ wxCoord xoffset, wxCoord yoffset)
+{
+ wxCHECK_RET(Ok(), wxT("Invalid DC"));
+ wxMacFastPortSetter helper(this) ;
+ if (m_pen.GetStyle() == wxTRANSPARENT)
+ return;
+ MacInstallPen() ;
+ wxCoord offset = ( (m_pen.GetWidth() == 0 ? 1 :
+ m_pen.GetWidth() ) * (wxCoord)m_scaleX - 1) / 2 ;
+ wxCoord x1, x2 , y1 , y2 ;
+ x1 = XLOG2DEVMAC(points[0].x + xoffset);
+ y1 = YLOG2DEVMAC(points[0].y + yoffset);
+ ::MoveTo(x1 - offset, y1 - offset );
+ for (int i = 0; i < n-1; i++)
+ {
+ x2 = XLOG2DEVMAC(points[i+1].x + xoffset);
+ y2 = YLOG2DEVMAC(points[i+1].y + yoffset);
+ ::LineTo( x2 - offset, y2 - offset );
+ }
+}
+
+void wxDC::DoDrawPolygon(int n, wxPoint points[],
+ wxCoord xoffset, wxCoord yoffset,
+ int fillStyle )
+{
+ wxCHECK_RET(Ok(), wxT("Invalid DC"));
+ wxMacFastPortSetter helper(this) ;
+ wxCoord x1, x2 , y1 , y2 ;
+ if ( m_brush.GetStyle() == wxTRANSPARENT && m_pen.GetStyle() == wxTRANSPARENT )
+ return ;
+ PolyHandle polygon = OpenPoly();
+ x2 = x1 = XLOG2DEVMAC(points[0].x + xoffset);
+ y2 = y1 = YLOG2DEVMAC(points[0].y + yoffset);
+ ::MoveTo(x1,y1);
+ for (int i = 1; i < n; i++)
+ {
+ x2 = XLOG2DEVMAC(points[i].x + xoffset);
+ y2 = YLOG2DEVMAC(points[i].y + yoffset);
+ ::LineTo(x2, y2);
+ }
+ // close the polyline if necessary
+ if ( x1 != x2 || y1 != y2 )
+ {
+ ::LineTo(x1,y1 ) ;
+ }
+ ClosePoly();
+ if (m_brush.GetStyle() != wxTRANSPARENT)
+ {
+ MacInstallBrush();
+ ::PaintPoly( polygon );
+ }
+ if (m_pen.GetStyle() != wxTRANSPARENT)
+ {
+ MacInstallPen() ;
+ ::FramePoly( polygon ) ;
+ }
+ KillPoly( polygon );
+}
+
+void wxDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
+{
+ wxCHECK_RET(Ok(), wxT("Invalid DC"));
+ wxMacFastPortSetter helper(this) ;
+ wxCoord xx = XLOG2DEVMAC(x);
+ wxCoord yy = YLOG2DEVMAC(y);
+ wxCoord ww = m_signX * XLOG2DEVREL(width);
+ wxCoord hh = m_signY * YLOG2DEVREL(height);
+ // CMB: draw nothing if transformed w or h is 0
+ if (ww == 0 || hh == 0)
+ return;
+ // CMB: handle -ve width and/or height
+ if (ww < 0)
+ {
+ ww = -ww;
+ xx = xx - ww;
+ }
+ if (hh < 0)
+ {
+ hh = -hh;
+ yy = yy - hh;
+ }
+ Rect rect = { yy , xx , yy + hh , xx + ww } ;
+ if (m_brush.GetStyle() != wxTRANSPARENT)
+ {
+ MacInstallBrush() ;
+ ::PaintRect( &rect ) ;
+ }
+ if (m_pen.GetStyle() != wxTRANSPARENT)
+ {
+ MacInstallPen() ;
+ ::FrameRect( &rect ) ;
+ }
+}
+
+void wxDC::DoDrawRoundedRectangle(wxCoord x, wxCoord y,
+ wxCoord width, wxCoord height,
+ double radius)
+{
+ wxCHECK_RET(Ok(), wxT("Invalid DC"));
+ wxMacFastPortSetter helper(this) ;
+ if (radius < 0.0)
+ radius = - radius * ((width < height) ? width : height);
+ wxCoord xx = XLOG2DEVMAC(x);
+ wxCoord yy = YLOG2DEVMAC(y);
+ wxCoord ww = m_signX * XLOG2DEVREL(width);
+ wxCoord hh = m_signY * YLOG2DEVREL(height);
+ // CMB: draw nothing if transformed w or h is 0
+ if (ww == 0 || hh == 0)
+ return;
+ // CMB: handle -ve width and/or height
+ if (ww < 0)
+ {
+ ww = -ww;
+ xx = xx - ww;
+ }
+ if (hh < 0)
+ {
+ hh = -hh;
+ yy = yy - hh;
+ }
+ Rect rect = { yy , xx , yy + hh , xx + ww } ;
+ if (m_brush.GetStyle() != wxTRANSPARENT)
+ {
+ MacInstallBrush() ;
+ ::PaintRoundRect( &rect , int(radius * 2) , int(radius * 2) ) ;
+ }
+ if (m_pen.GetStyle() != wxTRANSPARENT)
+ {
+ MacInstallPen() ;
+ ::FrameRoundRect( &rect , int(radius * 2) , int(radius * 2) ) ;
+ }
+}
+
+void wxDC::DoDrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
+{
+ wxCHECK_RET(Ok(), wxT("Invalid DC"));
+ wxMacFastPortSetter helper(this) ;
+ wxCoord xx = XLOG2DEVMAC(x);
+ wxCoord yy = YLOG2DEVMAC(y);
+ wxCoord ww = m_signX * XLOG2DEVREL(width);
+ wxCoord hh = m_signY * YLOG2DEVREL(height);
+ // CMB: draw nothing if transformed w or h is 0
+ if (ww == 0 || hh == 0)
+ return;
+ // CMB: handle -ve width and/or height
+ if (ww < 0)
+ {
+ ww = -ww;
+ xx = xx - ww;
+ }
+ if (hh < 0)
+ {
+ hh = -hh;
+ yy = yy - hh;
+ }
+ Rect rect = { yy , xx , yy + hh , xx + ww } ;
+ if (m_brush.GetStyle() != wxTRANSPARENT)
+ {
+ MacInstallBrush() ;
+ ::PaintOval( &rect ) ;
+ }
+ if (m_pen.GetStyle() != wxTRANSPARENT)
+ {
+ MacInstallPen() ;
+ ::FrameOval( &rect ) ;
+ }
+}
+
+bool wxDC::CanDrawBitmap(void) const
+{
+ return true ;
+}
+
+bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
+ wxDC *source, wxCoord xsrc, wxCoord ysrc, int logical_func , bool useMask,
+ wxCoord xsrcMask, wxCoord ysrcMask )
+{
+ wxCHECK_MSG(Ok(), false, wxT("wxDC::DoBlit Illegal dc"));
+ wxCHECK_MSG(source->Ok(), false, wxT("wxDC::DoBlit Illegal source DC"));
+ if ( logical_func == wxNO_OP )
+ return TRUE ;
+ if (xsrcMask == -1 && ysrcMask == -1)
+ {
+ xsrcMask = xsrc; ysrcMask = ysrc;
+ }
+ // correct the parameter in case this dc does not have a mask at all
+ if ( useMask && !source->m_macMask )
+ useMask = false ;
+ Rect srcrect , dstrect ;
+ srcrect.top = source->YLOG2DEVMAC(ysrc) ;
+ srcrect.left = source->XLOG2DEVMAC(xsrc) ;
+ srcrect.right = source->XLOG2DEVMAC(xsrc + width ) ;
+ srcrect.bottom = source->YLOG2DEVMAC(ysrc + height) ;
+ dstrect.top = YLOG2DEVMAC(ydest) ;
+ dstrect.left = XLOG2DEVMAC(xdest) ;
+ dstrect.bottom = YLOG2DEVMAC(ydest + height ) ;
+ dstrect.right = XLOG2DEVMAC(xdest + width ) ;
+ short mode = kUnsupportedMode ;
+ bool invertDestinationFirst = false ;
+ switch ( logical_func )
+ {
+ case wxAND: // src AND dst
+ mode = adMin ; // ok
+ break ;
+ case wxAND_INVERT: // (NOT src) AND dst
+ mode = notSrcOr ; // ok
+ break ;
+ case wxAND_REVERSE:// src AND (NOT dst)
+ invertDestinationFirst = true ;
+ mode = srcOr ;
+ break ;
+ case wxCLEAR: // 0
+ mode = kEmulatedMode ;
+ break ;
+ case wxCOPY: // src
+ mode = srcCopy ; // ok
+ break ;
+ case wxEQUIV: // (NOT src) XOR dst
+ mode = srcXor ; // ok
+ break ;
+ case wxINVERT: // NOT dst
+ mode = kEmulatedMode ; //or hilite ;
+ break ;
+ case wxNAND: // (NOT src) OR (NOT dst)
+ invertDestinationFirst = true ;
+ mode = srcBic ;
+ break ;
+ case wxNOR: // (NOT src) AND (NOT dst)
+ invertDestinationFirst = true ;
+ mode = notSrcOr ;
+ break ;
+ case wxNO_OP: // dst
+ mode = kEmulatedMode ; // this has already been handled upon entry
+ break ;
+ case wxOR: // src OR dst
+ mode = notSrcBic ;
+ break ;
+ case wxOR_INVERT: // (NOT src) OR dst
+ mode = srcBic ;
+ break ;
+ case wxOR_REVERSE: // src OR (NOT dst)
+ invertDestinationFirst = true ;
+ mode = notSrcBic ;
+ break ;
+ case wxSET: // 1
+ mode = kEmulatedMode ;
+ break ;
+ case wxSRC_INVERT: // (NOT src)
+ mode = notSrcCopy ; // ok
+ break ;
+ case wxXOR: // src XOR dst
+ mode = notSrcXor ; // ok
+ break ;
+ default :
+ break ;
+ }
+ if ( mode == kUnsupportedMode )
+ {
+ wxFAIL_MSG(wxT("unsupported blitting mode" ));
+ return FALSE ;
+ }
+ CGrafPtr sourcePort = (CGrafPtr) source->m_macPort ;
+ PixMapHandle bmappixels = GetGWorldPixMap( sourcePort ) ;
+ if ( LockPixels(bmappixels) )
+ {
+ wxMacFastPortSetter helper(this) ;
+ if ( source->GetDepth() == 1 )
+ {
+ RGBForeColor( &MAC_WXCOLORREF(m_textForegroundColour.GetPixel()) ) ;
+ RGBBackColor( &MAC_WXCOLORREF(m_textBackgroundColour.GetPixel()) ) ;
+ }
+ else
+ {
+ // the modes need this, otherwise we'll end up having really nice colors...
+ RGBColor white = { 0xFFFF, 0xFFFF,0xFFFF} ;
+ RGBColor black = { 0,0,0} ;
+ RGBForeColor( &black ) ;
+ RGBBackColor( &white ) ;
+ }
+ if ( useMask && source->m_macMask )
+ {
+ if ( mode == srcCopy )
+ {
+ if ( LockPixels( GetGWorldPixMap( MAC_WXHBITMAP(source->m_macMask) ) ) )
+ {
+ CopyMask( GetPortBitMapForCopyBits( sourcePort ) ,
+ GetPortBitMapForCopyBits( MAC_WXHBITMAP(source->m_macMask) ) ,
+ GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort) ) ,
+ &srcrect, &srcrect , &dstrect ) ;
+ UnlockPixels( GetGWorldPixMap( MAC_WXHBITMAP(source->m_macMask) ) ) ;
+ }
+ }
+ else
+ {
+ RgnHandle clipRgn = NewRgn() ;
+ LockPixels( GetGWorldPixMap( MAC_WXHBITMAP(source->m_macMask) ) ) ;
+ BitMapToRegion( clipRgn , (BitMap*) *GetGWorldPixMap( MAC_WXHBITMAP(source->m_macMask) ) ) ;
+ UnlockPixels( GetGWorldPixMap( MAC_WXHBITMAP(source->m_macMask) ) ) ;
+ OffsetRgn( clipRgn , -srcrect.left + dstrect.left, -srcrect.top + dstrect.top ) ;
+ if ( mode == kEmulatedMode )
+ {
+ Pattern pat ;
+ ::PenPat(GetQDGlobalsBlack(&pat));
+ if ( logical_func == wxSET )
+ {
+ RGBColor col= { 0xFFFF, 0xFFFF, 0xFFFF } ;
+ ::RGBForeColor( &col ) ;
+ ::PaintRgn( clipRgn ) ;
+ }
+ else if ( logical_func == wxCLEAR )
+ {
+ RGBColor col= { 0x0000, 0x0000, 0x0000 } ;
+ ::RGBForeColor( &col ) ;
+ ::PaintRgn( clipRgn ) ;
+ }
+ else if ( logical_func == wxINVERT )
+ {
+ MacInvertRgn( clipRgn ) ;
+ }
+ else
+ {
+ for ( int y = 0 ; y < srcrect.right - srcrect.left ; ++y )
+ {
+ for ( int x = 0 ; x < srcrect.bottom - srcrect.top ; ++x )
+ {
+ Point dstPoint = { dstrect.top + y , dstrect.left + x } ;
+ Point srcPoint = { srcrect.top + y , srcrect.left + x } ;
+ if ( PtInRgn( dstPoint , clipRgn ) )
+ {
+ RGBColor srcColor ;
+ RGBColor dstColor ;
+ SetPort( (GrafPtr) sourcePort ) ;
+ GetCPixel( srcPoint.h , srcPoint.v , &srcColor) ;
+ SetPort( (GrafPtr) m_macPort ) ;
+ GetCPixel( dstPoint.h , dstPoint.v , &dstColor ) ;
+ wxMacCalculateColour( logical_func , srcColor , dstColor ) ;
+ SetCPixel( dstPoint.h , dstPoint.v , &dstColor ) ;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if ( invertDestinationFirst )
+ {
+ MacInvertRgn( clipRgn ) ;
+ }
+ CopyBits( GetPortBitMapForCopyBits( sourcePort ) ,
+ GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort) ) ,
+ &srcrect, &dstrect, mode, clipRgn ) ;
+ }
+ DisposeRgn( clipRgn ) ;
+ }
+ }
+ else
+ {
+ RgnHandle clipRgn = NewRgn() ;
+ SetRectRgn( clipRgn , dstrect.left , dstrect.top , dstrect.right , dstrect.bottom ) ;
+ if ( mode == kEmulatedMode )
+ {
+ Pattern pat ;
+ ::PenPat(GetQDGlobalsBlack(&pat));
+ if ( logical_func == wxSET )
+ {
+ RGBColor col= { 0xFFFF, 0xFFFF, 0xFFFF } ;
+ ::RGBForeColor( &col ) ;
+ ::PaintRgn( clipRgn ) ;
+ }
+ else if ( logical_func == wxCLEAR )
+ {
+ RGBColor col= { 0x0000, 0x0000, 0x0000 } ;
+ ::RGBForeColor( &col ) ;
+ ::PaintRgn( clipRgn ) ;
+ }
+ else if ( logical_func == wxINVERT )
+ {
+ MacInvertRgn( clipRgn ) ;
+ }
+ else
+ {
+ for ( int y = 0 ; y < srcrect.right - srcrect.left ; ++y )
+ {
+ for ( int x = 0 ; x < srcrect.bottom - srcrect.top ; ++x )
+ {
+ Point dstPoint = { dstrect.top + y , dstrect.left + x } ;
+ Point srcPoint = { srcrect.top + y , srcrect.left + x } ;
+ {
+ RGBColor srcColor ;
+ RGBColor dstColor ;
+ SetPort( (GrafPtr) sourcePort ) ;
+ GetCPixel( srcPoint.h , srcPoint.v , &srcColor) ;
+ SetPort( (GrafPtr) m_macPort ) ;
+ GetCPixel( dstPoint.h , dstPoint.v , &dstColor ) ;
+ wxMacCalculateColour( logical_func , srcColor , dstColor ) ;
+ SetCPixel( dstPoint.h , dstPoint.v , &dstColor ) ;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if ( invertDestinationFirst )
+ {
+ MacInvertRgn( clipRgn ) ;
+ }
+ CopyBits( GetPortBitMapForCopyBits( sourcePort ) ,
+ GetPortBitMapForCopyBits( MAC_WXHBITMAP(m_macPort) ) ,
+ &srcrect, &dstrect, mode, NULL ) ;
+ }
+ DisposeRgn( clipRgn ) ;
+ }
+ UnlockPixels( bmappixels ) ;
+ }
+ m_macPenInstalled = false ;
+ m_macBrushInstalled = false ;
+ m_macFontInstalled = false ;
+ return TRUE;
+}
+
+#ifndef FixedToInt
+// as macro in FixMath.h for 10.3
+inline Fixed IntToFixed( int inInt )
+{
+ return (((SInt32) inInt) << 16);
+}
+
+inline int FixedToInt( Fixed inFixed )
+{
+ return (((SInt32) inFixed) >> 16);
+}
+#endif
+
+void wxDC::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y,
+ double angle)
+{
+ wxCHECK_RET( Ok(), wxT("wxDC::DoDrawRotatedText Invalid window dc") );
+
+ if (angle == 0.0 )
+ {
+ DrawText(str, x, y);
+ return;
+ }
+
+ if ( str.Length() == 0 )
+ return ;
+
+ wxMacFastPortSetter helper(this) ;
+ MacInstallFont() ;
+
+ if ( 0 )
+ {
+ m_macFormerAliasState = IsAntiAliasedTextEnabled(&m_macFormerAliasSize);
+ SetAntiAliasedTextEnabled(true, SInt16(m_scaleY * m_font.GetMacFontSize()));
+ m_macAliasWasEnabled = true ;
+ }
+ OSStatus status = noErr ;
+ ATSUTextLayout atsuLayout ;
+ UniCharCount chars = str.Length() ;
+#if wxUSE_UNICODE
+ status = ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr) (const wxChar*) str , 0 , str.Length() , str.Length() , 1 ,
+ &chars , (ATSUStyle*) &m_macATSUIStyle , &atsuLayout ) ;
+#else
+ wxWCharBuffer wchar = str.wc_str( wxConvLocal ) ;
+ int wlen = wxWcslen( wchar.data() ) ;
+ status = ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr) wchar.data() , 0 , wlen , wlen , 1 ,
+ &chars , (ATSUStyle*) &m_macATSUIStyle , &atsuLayout ) ;
+#endif
+ wxASSERT_MSG( status == noErr , wxT("couldn't create the layout of the rotated text") );
+ int iAngle = int( angle );
+ int drawX = XLOG2DEVMAC(x) ;
+ int drawY = YLOG2DEVMAC(y) ;
+
+ ATSUTextMeasurement textBefore ;
+ ATSUTextMeasurement textAfter ;
+ ATSUTextMeasurement ascent ;
+ ATSUTextMeasurement descent ;
+
+
+ if ( abs(iAngle) > 0 )
+ {
+ Fixed atsuAngle = IntToFixed( iAngle ) ;
+ ATSUAttributeTag atsuTags[] =
+ {
+ kATSULineRotationTag ,
+ } ;
+ ByteCount atsuSizes[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] =
+ {
+ sizeof( Fixed ) ,
+ } ;
+ ATSUAttributeValuePtr atsuValues[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] =
+ {
+ &atsuAngle ,
+ } ;
+ status = ::ATSUSetLayoutControls(atsuLayout , sizeof(atsuTags)/sizeof(ATSUAttributeTag),
+ atsuTags, atsuSizes, atsuValues ) ;
+ }
+ status = ::ATSUMeasureText( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd,
+ &textBefore , &textAfter, &ascent , &descent );
+
+ drawX += (int)(sin(angle/RAD2DEG) * FixedToInt(ascent));
+ drawY += (int)(cos(angle/RAD2DEG) * FixedToInt(ascent));
+ status = ::ATSUDrawText( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd,
+ IntToFixed(drawX) , IntToFixed(drawY) );
+ wxASSERT_MSG( status == noErr , wxT("couldn't draw the rotated text") );
+ Rect rect ;
+ status = ::ATSUMeasureTextImage( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd,
+ IntToFixed(drawX) , IntToFixed(drawY) , &rect );
+ wxASSERT_MSG( status == noErr , wxT("couldn't measure the rotated text") );
+ OffsetRect( &rect , -m_macLocalOrigin.x , -m_macLocalOrigin.y ) ;
+ CalcBoundingBox(XDEV2LOG(rect.left), YDEV2LOG(rect.top) );
+ CalcBoundingBox(XDEV2LOG(rect.right), YDEV2LOG(rect.bottom) );
+ ::ATSUDisposeTextLayout(atsuLayout);
+}
+
+void wxDC::DoDrawText(const wxString& strtext, wxCoord x, wxCoord y)
+{
+ wxCHECK_RET(Ok(), wxT("wxDC::DoDrawText Invalid DC"));
+
+ wxMacFastPortSetter helper(this) ;
+ long xx = XLOG2DEVMAC(x);
+ long yy = YLOG2DEVMAC(y);
+#if TARGET_CARBON
+ bool useDrawThemeText = ( DrawThemeTextBox != (void*) kUnresolvedCFragSymbolAddress ) ;
+ if ( UMAGetSystemVersion() < 0x1000 || IsKindOf(CLASSINFO( wxPrinterDC ) ) || m_font.GetNoAntiAliasing() )
+ useDrawThemeText = false ;
+#endif
+ MacInstallFont() ;
+ if ( 0 )
+ {
+ m_macFormerAliasState = IsAntiAliasedTextEnabled(&m_macFormerAliasSize);
+ SetAntiAliasedTextEnabled(true, 8);
+ m_macAliasWasEnabled = true ;
+ }
+ FontInfo fi ;
+ ::GetFontInfo( &fi ) ;
+#if TARGET_CARBON
+ if ( !useDrawThemeText )
+#endif
+ yy += fi.ascent ;
+ ::MoveTo( xx , yy );
+ if ( m_backgroundMode == wxTRANSPARENT )
+ {
+ ::TextMode( srcOr) ;
+ }
+ else
+ {
+ ::TextMode( srcCopy ) ;
+ }
+ int length = strtext.Length() ;
+
+ int laststop = 0 ;
+ int i = 0 ;
+ int line = 0 ;
+ {
+#if 0 // we don't have to do all that here
+ while( i < length )
+ {
+ if( strtext[i] == 13 || strtext[i] == 10)
+ {
+ wxString linetext = strtext.Mid( laststop , i - laststop ) ;
+#if TARGET_CARBON
+ if ( useDrawThemeText )
+ {
+ Rect frame = { yy + line*(fi.descent + fi.ascent + fi.leading) ,xx , yy + (line+1)*(fi.descent + fi.ascent + fi.leading) , xx + 10000 } ;
+ wxMacCFStringHolder mString( linetext , m_font.GetEncoding() ) ;
+ if ( m_backgroundMode != wxTRANSPARENT )
+ {
+ Point bounds={0,0} ;
+ Rect background = frame ;
+ SInt16 baseline ;
+ ::GetThemeTextDimensions( mString,
+ kThemeCurrentPortFont,
+ kThemeStateActive,
+ false,
+ &bounds,
+ &baseline );
+ background.right = background.left + bounds.h ;
+ background.bottom = background.top + bounds.v ;
+ ::EraseRect( &background ) ;
+ }
+ ::DrawThemeTextBox( mString,
+ kThemeCurrentPortFont,
+ kThemeStateActive,
+ false,
+ &frame,
+ teJustLeft,
+ nil );
+ line++ ;
+ }
+ else
+#endif
+ {
+ wxCharBuffer text = linetext.mb_str(wxConvLocal) ;
+ ::DrawText( text , 0 , strlen(text) ) ;
+ if ( m_backgroundMode != wxTRANSPARENT )
+ {
+ Point bounds={0,0} ;
+ Rect background = frame ;
+ SInt16 baseline ;
+ ::GetThemeTextDimensions( mString,
+ kThemeCurrentPortFont,
+ kThemeStateActive,
+ false,
+ &bounds,
+ &baseline );
+ background.right = background.left + bounds.h ;
+ background.bottom = background.top + bounds.v ;
+ ::EraseRect( &background ) ;
+ }
+ line++ ;
+ ::MoveTo( xx , yy + line*(fi.descent + fi.ascent + fi.leading) );
+ }
+ laststop = i+1 ;
+ }
+ i++ ;
+ }
+ wxString linetext = strtext.Mid( laststop , i - laststop ) ;
+#endif // 0
+ wxString linetext = strtext ;
+#if TARGET_CARBON
+ if ( useDrawThemeText )
+ {
+ Rect frame = { yy + line*(fi.descent + fi.ascent + fi.leading) ,xx , yy + (line+1)*(fi.descent + fi.ascent + fi.leading) , xx + 10000 } ;
+ wxMacCFStringHolder mString( linetext , m_font.GetEncoding()) ;
+
+ if ( m_backgroundMode != wxTRANSPARENT )
+ {
+ Point bounds={0,0} ;
+ Rect background = frame ;
+ SInt16 baseline ;
+ ::GetThemeTextDimensions( mString,
+ kThemeCurrentPortFont,
+ kThemeStateActive,
+ false,
+ &bounds,
+ &baseline );
+ background.right = background.left + bounds.h ;
+ background.bottom = background.top + bounds.v ;
+ ::EraseRect( &background ) ;
+ }
+ ::DrawThemeTextBox( mString,
+ kThemeCurrentPortFont,
+ kThemeStateActive,
+ false,
+ &frame,
+ teJustLeft,
+ nil );
+ }
+ else
+#endif
+ {
+ wxCharBuffer text = linetext.mb_str(wxConvLocal) ;
+ if ( m_backgroundMode != wxTRANSPARENT )
+ {
+ Rect frame = { yy - fi.ascent + line*(fi.descent + fi.ascent + fi.leading) ,xx , yy - fi.ascent + (line+1)*(fi.descent + fi.ascent + fi.leading) , xx + 10000 } ;
+ short width = ::TextWidth( text , 0 , strlen(text) ) ;
+ frame.right = frame.left + width ;
+
+ ::EraseRect( &frame ) ;
+ }
+ ::DrawText( text , 0 , strlen(text) ) ;
+ }
+ }
+ ::TextMode( srcOr ) ;
+}
+
+bool wxDC::CanGetTextExtent() const
+{
+ wxCHECK_MSG(Ok(), false, wxT("Invalid DC"));
+ return true ;
+}
+
+void wxDC::DoGetTextExtent( const wxString &strtext, wxCoord *width, wxCoord *height,
+ wxCoord *descent, wxCoord *externalLeading ,
+ wxFont *theFont ) const
+{
+ wxCHECK_RET(Ok(), wxT("Invalid DC"));
+ wxMacFastPortSetter helper(this) ;
+ wxFont formerFont = m_font ;
+ if ( theFont )
+ {
+ // work around the constness
+ *((wxFont*)(&m_font)) = *theFont ;
+ }
+ MacInstallFont() ;
+ FontInfo fi ;
+ ::GetFontInfo( &fi ) ;
+#if TARGET_CARBON
+ bool useGetThemeText = ( GetThemeTextDimensions != (void*) kUnresolvedCFragSymbolAddress ) ;
+ if ( UMAGetSystemVersion() < 0x1000 || IsKindOf(CLASSINFO( wxPrinterDC ) ) || ((wxFont*)&m_font)->GetNoAntiAliasing() )
+ useGetThemeText = false ;
+#endif
+ if ( height )
+ *height = YDEV2LOGREL( fi.descent + fi.ascent ) ;
+ if ( descent )
+ *descent =YDEV2LOGREL( fi.descent );
+ if ( externalLeading )
+ *externalLeading = YDEV2LOGREL( fi.leading ) ;
+ int length = strtext.Length() ;
+
+ int laststop = 0 ;
+ int i = 0 ;
+ int curwidth = 0 ;
+ if ( width )
+ {
+ *width = 0 ;
+#if 0 // apparently we don't have to do all that
+ while( i < length )
+ {
+ if( strtext[i] == 13 || strtext[i] == 10)
+ {
+ wxString linetext = strtext.Mid( laststop , i - laststop ) ;
+ if ( height )
+ *height += YDEV2LOGREL( fi.descent + fi.ascent + fi.leading ) ;
+#if TARGET_CARBON
+ if ( useGetThemeText )
+ {
+ Point bounds={0,0} ;
+ SInt16 baseline ;
+ wxMacCFStringHolder mString( linetext , m_font.GetEncoding() ) ;
+ ::GetThemeTextDimensions( mString,
+ kThemeCurrentPortFont,
+ kThemeStateActive,
+ false,
+ &bounds,
+ &baseline );
+ curwidth = bounds.h ;
+ }
+ else
+#endif
+ {
+ wxCharBuffer text = linetext.mb_str(wxConvLocal) ;
+ curwidth = ::TextWidth( text , 0 , strlen(text) ) ;
+ }
+ if ( curwidth > *width )
+ *width = XDEV2LOGREL( curwidth ) ;
+ laststop = i+1 ;
+ }
+ i++ ;
+ }
+
+ wxString linetext = strtext.Mid( laststop , i - laststop ) ;
+#endif // 0
+ wxString linetext = strtext ;
+#if TARGET_CARBON
+ if ( useGetThemeText )
+ {
+ Point bounds={0,0} ;
+ SInt16 baseline ;
+ wxMacCFStringHolder mString( linetext , m_font.GetEncoding() ) ;
+ ::GetThemeTextDimensions( mString,
+ kThemeCurrentPortFont,
+ kThemeStateActive,
+ false,
+ &bounds,
+ &baseline );
+ curwidth = bounds.h ;
+ }
+ else
+#endif
+ {
+ wxCharBuffer text = linetext.mb_str(wxConvLocal) ;
+ curwidth = ::TextWidth( text , 0 , strlen(text) ) ;
+ }
+ if ( curwidth > *width )
+ *width = XDEV2LOGREL( curwidth ) ;
+ }
+ if ( theFont )
+ {
+ // work around the constness
+ *((wxFont*)(&m_font)) = formerFont ;
+ m_macFontInstalled = false ;
+ }
+}
+
+
+bool wxDC::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths) const
+{
+ wxCHECK_MSG(Ok(), false, wxT("Invalid DC"));
+
+ widths.Empty();
+ widths.Add(0, text.Length());
+
+ if (text.Length() == 0)
+ return false;
+
+ wxMacFastPortSetter helper(this) ;
+ MacInstallFont() ;
+#if TARGET_CARBON
+ bool useGetThemeText = ( GetThemeTextDimensions != (void*) kUnresolvedCFragSymbolAddress ) ;
+ if ( UMAGetSystemVersion() < 0x1000 || IsKindOf(CLASSINFO( wxPrinterDC ) ) || ((wxFont*)&m_font)->GetNoAntiAliasing() )
+ useGetThemeText = false ;
+
+ if ( useGetThemeText )
+ {
+ // If anybody knows how to do this more efficiently yet still handle
+ // the fractional glyph widths that may be present when using AA
+ // fonts, please change it. Currently it is measuring from the
+ // begining of the string for each succeding substring, which is much
+ // slower than this should be.
+ for (size_t i=0; i<text.Length(); i++)
+ {
+ wxString str(text.Left(i+1));
+ Point bounds = {0,0};
+ SInt16 baseline ;
+ wxMacCFStringHolder mString(str, m_font.GetEncoding());
+ ::GetThemeTextDimensions( mString,
+ kThemeCurrentPortFont,
+ kThemeStateActive,
+ false,
+ &bounds,
+ &baseline );
+ widths[i] = XDEV2LOGREL(bounds.h);
+ }
+ }
+ else
+#endif
+ {
+ wxCharBuffer buff = text.mb_str(wxConvLocal);
+ size_t len = strlen(buff);
+ short* measurements = new short[len+1];
+ MeasureText(len, buff.data(), measurements);
+
+ // Copy to widths, starting at measurements[1]
+ // NOTE: this doesn't take into account any multi-byte characters
+ // in buff, it probabkly should...
+ for (size_t i=0; i<text.Length(); i++)
+ widths[i] = XDEV2LOGREL(measurements[i+1]);
+
+ delete [] measurements;
+ }
+
+ return true;
+}
+
+
+
+wxCoord wxDC::GetCharWidth(void) const
+{
+ wxCHECK_MSG(Ok(), 1, wxT("Invalid DC"));
+ wxMacFastPortSetter helper(this) ;
+ MacInstallFont() ;
+ int width = 0 ;
+#if TARGET_CARBON
+ bool useGetThemeText = ( GetThemeTextDimensions != (void*) kUnresolvedCFragSymbolAddress ) ;
+ if ( UMAGetSystemVersion() < 0x1000 || ((wxFont*)&m_font)->GetNoAntiAliasing() )
+ useGetThemeText = false ;
+#endif
+ char text[] = "g" ;
+#if TARGET_CARBON
+ if ( useGetThemeText )
+ {
+ Point bounds={0,0} ;
+ SInt16 baseline ;
+ CFStringRef mString = CFStringCreateWithBytes( NULL , (UInt8*) text , 1 , CFStringGetSystemEncoding(), false ) ;
+ ::GetThemeTextDimensions( mString,
+ kThemeCurrentPortFont,
+ kThemeStateActive,
+ false,
+ &bounds,
+ &baseline );
+ CFRelease( mString ) ;
+ width = bounds.h ;
+ }
+ else
+#endif
+ {
+ width = ::TextWidth( text , 0 , 1 ) ;
+ }
+ return YDEV2LOGREL(width) ;
+}
+
+wxCoord wxDC::GetCharHeight(void) const
+{
+ wxCHECK_MSG(Ok(), 1, wxT("Invalid DC"));
+ wxMacFastPortSetter helper(this) ;
+ MacInstallFont() ;
+ FontInfo fi ;
+ ::GetFontInfo( &fi ) ;
+ return YDEV2LOGREL( fi.descent + fi.ascent );
+}
+
+void wxDC::Clear(void)
+{
+ wxCHECK_RET(Ok(), wxT("Invalid DC"));
+ wxMacFastPortSetter helper(this) ;
+ Rect rect = { -31000 , -31000 , 31000 , 31000 } ;
+ if (m_backgroundBrush.GetStyle() != wxTRANSPARENT)
+ {
+ ::PenNormal() ;
+ //MacInstallBrush() ;
+ MacSetupBackgroundForCurrentPort( m_backgroundBrush ) ;
+ ::EraseRect( &rect ) ;
+ }
+}
+
+void wxDC::MacInstallFont() const
+{
+ wxCHECK_RET(Ok(), wxT("Invalid DC"));
+ // if ( m_macFontInstalled )
+ // return ;
+ Pattern blackColor ;
+ MacSetupBackgroundForCurrentPort(m_backgroundBrush) ;
+ if ( m_font.Ok() )
+ {
+ ::TextFont( m_font.GetMacFontNum() ) ;
+ ::TextSize( (short)(m_scaleY * m_font.GetMacFontSize()) ) ;
+ ::TextFace( m_font.GetMacFontStyle() ) ;
+ m_macFontInstalled = true ;
+ m_macBrushInstalled = false ;
+ m_macPenInstalled = false ;
+ RGBColor forecolor = MAC_WXCOLORREF( m_textForegroundColour.GetPixel());
+ RGBColor backcolor = MAC_WXCOLORREF( m_textBackgroundColour.GetPixel());
+ ::RGBForeColor( &forecolor );
+ ::RGBBackColor( &backcolor );
+ }
+ else
+ {
+ FontFamilyID fontId ;
+ Str255 fontName ;
+ SInt16 fontSize ;
+ Style fontStyle ;
+ GetThemeFont(kThemeSmallSystemFont , GetApplicationScript() , fontName , &fontSize , &fontStyle ) ;
+ GetFNum( fontName, &fontId );
+ ::TextFont( fontId ) ;
+ ::TextSize( short(m_scaleY * fontSize) ) ;
+ ::TextFace( fontStyle ) ;
+ // todo reset after spacing changes - or store the current spacing somewhere
+ m_macFontInstalled = true ;
+ m_macBrushInstalled = false ;
+ m_macPenInstalled = false ;
+ RGBColor forecolor = MAC_WXCOLORREF( m_textForegroundColour.GetPixel());
+ RGBColor backcolor = MAC_WXCOLORREF( m_textBackgroundColour.GetPixel());
+ ::RGBForeColor( &forecolor );
+ ::RGBBackColor( &backcolor );
+ }
+ short mode = patCopy ;
+ // todo :
+ switch( m_logicalFunction )
+ {
+ case wxCOPY: // src
+ mode = patCopy ;
+ break ;
+ case wxINVERT: // NOT dst
+ ::PenPat(GetQDGlobalsBlack(&blackColor));
+ mode = patXor ;
+ break ;
+ case wxXOR: // src XOR dst
+ mode = patXor ;
+ break ;
+ case wxOR_REVERSE: // src OR (NOT dst)
+ mode = notPatOr ;
+ break ;
+ case wxSRC_INVERT: // (NOT src)
+ mode = notPatCopy ;
+ break ;
+ case wxAND: // src AND dst
+ mode = adMin ;
+ break ;
+ // unsupported TODO
+ case wxCLEAR: // 0
+ case wxAND_REVERSE:// src AND (NOT dst)
+ case wxAND_INVERT: // (NOT src) AND dst
+ case wxNO_OP: // dst
+ case wxNOR: // (NOT src) AND (NOT dst)
+ case wxEQUIV: // (NOT src) XOR dst
+ case wxOR_INVERT: // (NOT src) OR dst
+ case wxNAND: // (NOT src) OR (NOT dst)
+ case wxOR: // src OR dst
+ case wxSET: // 1
+ // case wxSRC_OR: // source _bitmap_ OR destination
+ // case wxSRC_AND: // source _bitmap_ AND destination
+ break ;
+ }
+ ::PenMode( mode ) ;
+ OSStatus status = noErr ;
+ Fixed atsuSize = IntToFixed( int(m_scaleY * m_font.GetMacFontSize()) ) ;
+ Style qdStyle = m_font.GetMacFontStyle() ;
+ ATSUFontID atsuFont = m_font.GetMacATSUFontID() ;
+ status = ::ATSUCreateStyle((ATSUStyle *)&m_macATSUIStyle) ;
+ wxASSERT_MSG( status == noErr , wxT("couldn't create ATSU style") ) ;
+ ATSUAttributeTag atsuTags[] =
+ {
+ kATSUFontTag ,
+ kATSUSizeTag ,
+ // kATSUColorTag ,
+ // kATSUBaselineClassTag ,
+ kATSUVerticalCharacterTag,
+ kATSUQDBoldfaceTag ,
+ kATSUQDItalicTag ,
+ kATSUQDUnderlineTag ,
+ kATSUQDCondensedTag ,
+ kATSUQDExtendedTag ,
+ } ;
+ ByteCount atsuSizes[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] =
+ {
+ sizeof( ATSUFontID ) ,
+ sizeof( Fixed ) ,
+ // sizeof( RGBColor ) ,
+ // sizeof( BslnBaselineClass ) ,
+ sizeof( ATSUVerticalCharacterType),
+ sizeof( Boolean ) ,
+ sizeof( Boolean ) ,
+ sizeof( Boolean ) ,
+ sizeof( Boolean ) ,
+ sizeof( Boolean ) ,
+ } ;
+ Boolean kTrue = true ;
+ Boolean kFalse = false ;
+ //BslnBaselineClass kBaselineDefault = kBSLNHangingBaseline ;
+ ATSUVerticalCharacterType kHorizontal = kATSUStronglyHorizontal;
+ ATSUAttributeValuePtr atsuValues[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] =
+ {
+ &atsuFont ,
+ &atsuSize ,
+ // &MAC_WXCOLORREF( m_textForegroundColour.GetPixel() ) ,
+ // &kBaselineDefault ,
+ &kHorizontal,
+ (qdStyle & bold) ? &kTrue : &kFalse ,
+ (qdStyle & italic) ? &kTrue : &kFalse ,
+ (qdStyle & underline) ? &kTrue : &kFalse ,
+ (qdStyle & condense) ? &kTrue : &kFalse ,
+ (qdStyle & extend) ? &kTrue : &kFalse ,
+ } ;
+ status = ::ATSUSetAttributes((ATSUStyle)m_macATSUIStyle, sizeof(atsuTags)/sizeof(ATSUAttributeTag) ,
+ atsuTags, atsuSizes, atsuValues);
+ wxASSERT_MSG( status == noErr , wxT("couldn't set create ATSU style") ) ;
+}
+
+Pattern gPatterns[] =
+{ // hatch patterns
+ { { 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF } } ,
+ { { 0x01 , 0x02 , 0x04 , 0x08 , 0x10 , 0x20 , 0x40 , 0x80 } } ,
+ { { 0x80 , 0x40 , 0x20 , 0x10 , 0x08 , 0x04 , 0x02 , 0x01 } } ,
+ { { 0x10 , 0x10 , 0x10 , 0xFF , 0x10 , 0x10 , 0x10 , 0x10 } } ,
+ { { 0x00 , 0x00 , 0x00 , 0xFF , 0x00 , 0x00 , 0x00 , 0x00 } } ,
+ { { 0x10 , 0x10 , 0x10 , 0x10 , 0x10 , 0x10 , 0x10 , 0x10 } } ,
+ { { 0x81 , 0x42 , 0x24 , 0x18 , 0x18 , 0x24 , 0x42 , 0x81 } } ,
+ // dash patterns
+ { { 0xCC , 0x99 , 0x33 , 0x66 , 0xCC , 0x99 , 0x33 , 0x66 } } , // DOT
+ { { 0xFE , 0xFD , 0xFB , 0xF7 , 0xEF , 0xDF , 0xBF , 0x7F } } , // LONG_DASH
+ { { 0xEE , 0xDD , 0xBB , 0x77 , 0xEE , 0xDD , 0xBB , 0x77 } } , // SHORT_DASH
+ { { 0xDE , 0xBD , 0x7B , 0xF6 , 0xED , 0xDB , 0xB7 , 0x6F } } , // DOT_DASH
+} ;
+
+static void wxMacGetPattern(int penStyle, Pattern *pattern)
+{
+ int index = 0; // solid pattern by default
+ switch(penStyle)
+ {
+ // hatches
+ case wxBDIAGONAL_HATCH: index = 1; break;
+ case wxFDIAGONAL_HATCH: index = 2; break;
+ case wxCROSS_HATCH: index = 3; break;
+ case wxHORIZONTAL_HATCH: index = 4; break;
+ case wxVERTICAL_HATCH: index = 5; break;
+ case wxCROSSDIAG_HATCH: index = 6; break;
+ // dashes
+ case wxDOT: index = 7; break;
+ case wxLONG_DASH: index = 8; break;
+ case wxSHORT_DASH: index = 9; break;
+ case wxDOT_DASH: index = 10; break;
+ }
+ *pattern = gPatterns[index];
+}
+
+void wxDC::MacInstallPen() const
+{
+ wxCHECK_RET(Ok(), wxT("Invalid DC"));
+ //Pattern blackColor;
+ // if ( m_macPenInstalled )
+ // return ;
+ RGBColor forecolor = MAC_WXCOLORREF( m_pen.GetColour().GetPixel());
+ RGBColor backcolor = MAC_WXCOLORREF( m_backgroundBrush.GetColour().GetPixel());
+ ::RGBForeColor( &forecolor );
+ ::RGBBackColor( &backcolor );
+ ::PenNormal() ;
+ int penWidth = (int) (m_pen.GetWidth() * m_scaleX) ; ;
+ // null means only one pixel, at whatever resolution
+ if ( penWidth == 0 )
+ penWidth = 1 ;
+ ::PenSize(penWidth, penWidth);
+
+ int penStyle = m_pen.GetStyle();
+ Pattern pat;
+ if (penStyle == wxUSER_DASH)
+ {
+ // FIXME: there should be exactly 8 items in the dash
+ wxDash* dash ;
+ int number = m_pen.GetDashes(&dash) ;
+ int index = 0;
+ for ( int i = 0 ; i < 8 ; ++i )
+ {
+ pat.pat[i] = dash[index] ;
+ if (index < number - 1)
+ index++;
+ }
+ }
+ else
+ {
+ wxMacGetPattern(penStyle, &pat);
+ }
+ ::PenPat(&pat);
+
+ short mode = patCopy ;
+ // todo :
+ switch( m_logicalFunction )
+ {
+ case wxCOPY: // only foreground color, leave background (thus not patCopy)
+ mode = patOr ;
+ break ;
+ case wxINVERT: // NOT dst
+ // ::PenPat(GetQDGlobalsBlack(&blackColor));
+ mode = patXor ;
+ break ;
+ case wxXOR: // src XOR dst
+ mode = patXor ;
+ break ;
+ case wxOR_REVERSE: // src OR (NOT dst)
+ mode = notPatOr ;
+ break ;
+ case wxSRC_INVERT: // (NOT src)
+ mode = notPatCopy ;
+ break ;
+ case wxAND: // src AND dst
+ mode = adMin ;
+ break ;
+ // unsupported TODO
+ case wxCLEAR: // 0
+ case wxAND_REVERSE:// src AND (NOT dst)
+ case wxAND_INVERT: // (NOT src) AND dst
+ case wxNO_OP: // dst
+ case wxNOR: // (NOT src) AND (NOT dst)
+ case wxEQUIV: // (NOT src) XOR dst
+ case wxOR_INVERT: // (NOT src) OR dst
+ case wxNAND: // (NOT src) OR (NOT dst)
+ case wxOR: // src OR dst
+ case wxSET: // 1
+ // case wxSRC_OR: // source _bitmap_ OR destination
+ // case wxSRC_AND: // source _bitmap_ AND destination
+ break ;
+ }
+ ::PenMode( mode ) ;
+ m_macPenInstalled = true ;
+ m_macBrushInstalled = false ;
+ m_macFontInstalled = false ;
+}
+
+void wxDC::MacSetupBackgroundForCurrentPort(const wxBrush& background )
+{
+ Pattern whiteColor ;
+ switch( background.MacGetBrushKind() )
+ {
+ case kwxMacBrushTheme :
+ {
+ ::SetThemeBackground( background.GetMacTheme() , wxDisplayDepth() , true ) ;
+ break ;
+ }
+ case kwxMacBrushThemeBackground :
+ {
+ Rect extent ;
+ ThemeBackgroundKind bg = background.GetMacThemeBackground( &extent ) ;
+ ::ApplyThemeBackground( bg , &extent ,kThemeStateActive , wxDisplayDepth() , true ) ;
+ break ;
+ }
+ case kwxMacBrushColour :
+ {
+ ::RGBBackColor( &MAC_WXCOLORREF( background.GetColour().GetPixel()) );
+ int brushStyle = background.GetStyle();
+ if (brushStyle == wxSOLID)
+ ::BackPat(GetQDGlobalsWhite(&whiteColor));
+ else if (IS_HATCH(brushStyle))
+ {
+ Pattern pat ;
+ wxMacGetPattern(brushStyle, &pat);
+ ::BackPat(&pat);
+ }
+ else
+ {
+ ::BackPat(GetQDGlobalsWhite(&whiteColor));
+ }
+ break ;
+ }
+ }
+}
+
+void wxDC::MacInstallBrush() const
+{
+ wxCHECK_RET(Ok(), wxT("Invalid DC"));
+ Pattern blackColor ;
+ // if ( m_macBrushInstalled )
+ // return ;
+ // foreground
+ bool backgroundTransparent = (GetBackgroundMode() == wxTRANSPARENT) ;
+ ::RGBForeColor( &MAC_WXCOLORREF( m_brush.GetColour().GetPixel()) );
+ ::RGBBackColor( &MAC_WXCOLORREF( m_backgroundBrush.GetColour().GetPixel()) );
+ int brushStyle = m_brush.GetStyle();
+ if (brushStyle == wxSOLID)
+ {
+ ::PenPat(GetQDGlobalsBlack(&blackColor));
+ }
+ else if (IS_HATCH(brushStyle))
+ {
+ Pattern pat ;
+ wxMacGetPattern(brushStyle, &pat);
+ ::PenPat(&pat);
+ }
+ else if ( m_brush.GetStyle() == wxSTIPPLE || m_brush.GetStyle() == wxSTIPPLE_MASK_OPAQUE )
+ {
+ // we force this in order to be compliant with wxMSW
+ backgroundTransparent = false ;
+ // for these the text fore (and back for MASK_OPAQUE) colors are used
+ wxBitmap* bitmap = m_brush.GetStipple() ;
+ int width = bitmap->GetWidth() ;
+ int height = bitmap->GetHeight() ;
+ GWorldPtr gw = NULL ;
+ if ( m_brush.GetStyle() == wxSTIPPLE )
+ gw = MAC_WXHBITMAP(bitmap->GetHBITMAP()) ;
+ else
+ gw = MAC_WXHBITMAP(bitmap->GetMask()->GetMaskBitmap()) ;
+ PixMapHandle gwpixmaphandle = GetGWorldPixMap( gw ) ;
+ LockPixels( gwpixmaphandle ) ;
+ bool isMonochrome = !IsPortColor( gw ) ;
+ if ( !isMonochrome )
+ {
+ if ( (**gwpixmaphandle).pixelSize == 1 )
+ isMonochrome = true ;
+ }
+ if ( isMonochrome && width == 8 && height == 8 )
+ {
+ ::RGBForeColor( &MAC_WXCOLORREF( m_textForegroundColour.GetPixel()) );
+ ::RGBForeColor( &MAC_WXCOLORREF( m_textBackgroundColour.GetPixel()) );
+ BitMap* gwbitmap = (BitMap*) *gwpixmaphandle ; // since the color depth is 1 it is a BitMap
+ UInt8 *gwbits = (UInt8*) gwbitmap->baseAddr ;
+ int alignment = gwbitmap->rowBytes & 0x7FFF ;
+ Pattern pat ;
+ for ( int i = 0 ; i < 8 ; ++i )
+ {
+ pat.pat[i] = gwbits[i*alignment+0] ;
+ }
+ UnlockPixels( GetGWorldPixMap( gw ) ) ;
+ ::PenPat( &pat ) ;
+ }
+ else
+ {
+ // this will be the code to handle power of 2 patterns, we will have to arrive at a nice
+ // caching scheme before putting this into production
+ Handle image;
+ long imageSize;
+ PixPatHandle pixpat = NewPixPat() ;
+ CopyPixMap(gwpixmaphandle, (**pixpat).patMap);
+ imageSize = GetPixRowBytes((**pixpat).patMap) *
+ ((**(**pixpat).patMap).bounds.bottom -
+ (**(**pixpat).patMap).bounds.top);
+ PtrToHand( (**gwpixmaphandle).baseAddr, &image, imageSize );
+ (**pixpat).patData = image;
+ if ( isMonochrome )
+ {
+ CTabHandle ctable = ((**((**pixpat).patMap)).pmTable) ;
+ ColorSpecPtr ctspec = (ColorSpecPtr) &(**ctable).ctTable ;
+ if ( ctspec[0].rgb.red == 0x0000 )
+ {
+ ctspec[1].rgb = MAC_WXCOLORREF( m_textBackgroundColour.GetPixel()) ;
+ ctspec[0].rgb = MAC_WXCOLORREF( m_textForegroundColour.GetPixel()) ;
+ }
+ else
+ {
+ ctspec[0].rgb = MAC_WXCOLORREF( m_textBackgroundColour.GetPixel()) ;
+ ctspec[1].rgb = MAC_WXCOLORREF( m_textForegroundColour.GetPixel()) ;
+ }
+ ::CTabChanged( ctable ) ;
+ }
+ ::PenPixPat(pixpat);
+ m_macForegroundPixMap = pixpat ;
+ }
+ UnlockPixels( gwpixmaphandle ) ;
+ }
+ else
+ {
+ ::PenPat(GetQDGlobalsBlack(&blackColor));
+ }
+ short mode = patCopy ;
+ switch( m_logicalFunction )
+ {
+ case wxCOPY: // src
+ if ( backgroundTransparent )
+ mode = patOr ;
+ else
+ mode = patCopy ;
+ break ;
+ case wxINVERT: // NOT dst
+ if ( !backgroundTransparent )
+ {
+ ::PenPat(GetQDGlobalsBlack(&blackColor));
+ }
+ mode = patXor ;
+ break ;
+ case wxXOR: // src XOR dst
+ mode = patXor ;
+ break ;
+ case wxOR_REVERSE: // src OR (NOT dst)
+ mode = notPatOr ;
+ break ;
+ case wxSRC_INVERT: // (NOT src)
+ mode = notPatCopy ;
+ break ;
+ case wxAND: // src AND dst
+ mode = adMin ;
+ break ;
+ // unsupported TODO
+ case wxCLEAR: // 0
+ case wxAND_REVERSE:// src AND (NOT dst)
+ case wxAND_INVERT: // (NOT src) AND dst
+ case wxNO_OP: // dst
+ case wxNOR: // (NOT src) AND (NOT dst)
+ case wxEQUIV: // (NOT src) XOR dst
+ case wxOR_INVERT: // (NOT src) OR dst
+ case wxNAND: // (NOT src) OR (NOT dst)
+ case wxOR: // src OR dst
+ case wxSET: // 1
+ // case wxSRC_OR: // source _bitmap_ OR destination
+ // case wxSRC_AND: // source _bitmap_ AND destination
+ break ;
+ }
+ ::PenMode( mode ) ;
+ m_macBrushInstalled = true ;
+ m_macPenInstalled = false ;
+ m_macFontInstalled = false ;
+}
+
+// ---------------------------------------------------------------------------
+// coordinates transformations
+// ---------------------------------------------------------------------------
+
+wxCoord wxDCBase::DeviceToLogicalX(wxCoord x) const
+{
+ return ((wxDC *)this)->XDEV2LOG(x);
+}
+
+wxCoord wxDCBase::DeviceToLogicalY(wxCoord y) const
+{
+ return ((wxDC *)this)->YDEV2LOG(y);
+}
+
+wxCoord wxDCBase::DeviceToLogicalXRel(wxCoord x) const
+{
+ return ((wxDC *)this)->XDEV2LOGREL(x);
+}
+
+wxCoord wxDCBase::DeviceToLogicalYRel(wxCoord y) const
+{
+ return ((wxDC *)this)->YDEV2LOGREL(y);
+}
+
+wxCoord wxDCBase::LogicalToDeviceX(wxCoord x) const
+{
+ return ((wxDC *)this)->XLOG2DEV(x);
+}
+
+wxCoord wxDCBase::LogicalToDeviceY(wxCoord y) const
+{
+ return ((wxDC *)this)->YLOG2DEV(y);
+}
+
+wxCoord wxDCBase::LogicalToDeviceXRel(wxCoord x) const
+{
+ return ((wxDC *)this)->XLOG2DEVREL(x);
+}
+
+wxCoord wxDCBase::LogicalToDeviceYRel(wxCoord y) const
+{
+ return ((wxDC *)this)->YLOG2DEVREL(y);
+}
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: dcclient.cpp
+// Purpose: wxClientDC class
+// Author: Stefan Csomor
+// Modified by:
+// Created: 01/02/97
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "dcclient.h"
+#endif
+
+#include "wx/dcclient.h"
+#include "wx/dcmemory.h"
+#include "wx/region.h"
+#include "wx/window.h"
+#include "wx/toplevel.h"
+#include <math.h>
+#include "wx/mac/private.h"
+
+//-----------------------------------------------------------------------------
+// constants
+//-----------------------------------------------------------------------------
+
+#define RAD2DEG 57.2957795131
+
+//-----------------------------------------------------------------------------
+// wxPaintDC
+//-----------------------------------------------------------------------------
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxWindowDC, wxDC)
+IMPLEMENT_DYNAMIC_CLASS(wxClientDC, wxWindowDC)
+IMPLEMENT_DYNAMIC_CLASS(wxPaintDC, wxWindowDC)
+#endif
+
+/*
+ * wxWindowDC
+ */
+
+#include "wx/mac/uma.h"
+
+wxWindowDC::wxWindowDC()
+{
+ m_window = NULL ;
+}
+
+wxWindowDC::wxWindowDC(wxWindow *window)
+{
+ m_window = window ;
+ wxTopLevelWindowMac* rootwindow = window->MacGetTopLevelWindow() ;
+ WindowRef windowref = (WindowRef) rootwindow->MacGetWindowRef() ;
+
+ int x , y ;
+ x = y = 0 ;
+ window->MacWindowToRootWindow( &x , &y ) ;
+ m_macLocalOrigin.x = x ;
+ m_macLocalOrigin.y = y ;
+ CopyRgn( (RgnHandle) window->MacGetVisibleRegion().GetWXHRGN() , (RgnHandle) m_macBoundaryClipRgn ) ;
+ OffsetRgn( (RgnHandle) m_macBoundaryClipRgn , m_macLocalOrigin.x , m_macLocalOrigin.y ) ;
+ CopyRgn( (RgnHandle) m_macBoundaryClipRgn , (RgnHandle) m_macCurrentClipRgn ) ;
+ m_macPort = UMAGetWindowPort( windowref ) ;
+ m_ok = TRUE ;
+ SetBackground(window->MacGetBackgroundBrush());
+}
+
+wxWindowDC::~wxWindowDC()
+{
+}
+
+void wxWindowDC::DoGetSize( int* width, int* height ) const
+{
+ wxCHECK_RET( m_window, _T("GetSize() doesn't work without window") );
+
+ m_window->GetSize(width, height);
+}
+
+/*
+ * wxClientDC
+ */
+
+wxClientDC::wxClientDC()
+{
+ m_window = NULL ;
+}
+
+wxClientDC::wxClientDC(wxWindow *window)
+{
+ m_window = window ;
+ wxTopLevelWindowMac* rootwindow = window->MacGetTopLevelWindow() ;
+ if (!rootwindow)
+ return;
+ WindowRef windowref = (WindowRef) rootwindow->MacGetWindowRef() ;
+ wxPoint origin = window->GetClientAreaOrigin() ;
+ wxSize size = window->GetClientSize() ;
+ int x , y ;
+ x = origin.x ;
+ y = origin.y ;
+ window->MacWindowToRootWindow( &x , &y ) ;
+ m_macLocalOrigin.x = x ;
+ m_macLocalOrigin.y = y ;
+ SetRectRgn( (RgnHandle) m_macBoundaryClipRgn , origin.x , origin.y , origin.x + size.x , origin.y + size.y ) ;
+ SectRgn( (RgnHandle) m_macBoundaryClipRgn , (RgnHandle) window->MacGetVisibleRegion().GetWXHRGN() , (RgnHandle) m_macBoundaryClipRgn ) ;
+ OffsetRgn( (RgnHandle) m_macBoundaryClipRgn , -origin.x , -origin.y ) ;
+ OffsetRgn( (RgnHandle) m_macBoundaryClipRgn , m_macLocalOrigin.x , m_macLocalOrigin.y ) ;
+ CopyRgn( (RgnHandle) m_macBoundaryClipRgn ,(RgnHandle) m_macCurrentClipRgn ) ;
+ m_macPort = UMAGetWindowPort( windowref ) ;
+
+ m_ok = TRUE ;
+ SetBackground(window->MacGetBackgroundBrush());
+ SetFont( window->GetFont() ) ;
+}
+
+wxClientDC::~wxClientDC()
+{
+}
+
+void wxClientDC::DoGetSize(int *width, int *height) const
+{
+ wxCHECK_RET( m_window, _T("GetSize() doesn't work without window") );
+
+ m_window->GetClientSize( width, height );
+}
+
+
+/*
+ * wxPaintDC
+ */
+
+wxPaintDC::wxPaintDC()
+{
+ m_window = NULL ;
+}
+
+wxPaintDC::wxPaintDC(wxWindow *window)
+{
+ m_window = window ;
+ wxTopLevelWindowMac* rootwindow = window->MacGetTopLevelWindow() ;
+ WindowRef windowref = (WindowRef) rootwindow->MacGetWindowRef() ;
+ wxPoint origin = window->GetClientAreaOrigin() ;
+ wxSize size = window->GetClientSize() ;
+ int x , y ;
+ x = origin.x ;
+ y = origin.y ;
+ window->MacWindowToRootWindow( &x , &y ) ;
+ m_macLocalOrigin.x = x ;
+ m_macLocalOrigin.y = y ;
+ SetRectRgn( (RgnHandle) m_macBoundaryClipRgn , origin.x , origin.y , origin.x + size.x , origin.y + size.y ) ;
+ SectRgn( (RgnHandle) m_macBoundaryClipRgn , (RgnHandle) window->MacGetVisibleRegion().GetWXHRGN() , (RgnHandle) m_macBoundaryClipRgn ) ;
+ OffsetRgn( (RgnHandle) m_macBoundaryClipRgn , -origin.x , -origin.y ) ;
+ SectRgn( (RgnHandle) m_macBoundaryClipRgn , (RgnHandle) window->GetUpdateRegion().GetWXHRGN() , (RgnHandle) m_macBoundaryClipRgn ) ;
+ OffsetRgn( (RgnHandle) m_macBoundaryClipRgn , m_macLocalOrigin.x , m_macLocalOrigin.y ) ;
+ CopyRgn( (RgnHandle) m_macBoundaryClipRgn , (RgnHandle) m_macCurrentClipRgn ) ;
+ m_macPort = UMAGetWindowPort( windowref ) ;
+
+ m_ok = TRUE ;
+ SetBackground(window->MacGetBackgroundBrush());
+ SetFont( window->GetFont() ) ;
+}
+
+wxPaintDC::~wxPaintDC()
+{
+}
+
+void wxPaintDC::DoGetSize(int *width, int *height) const
+{
+ wxCHECK_RET( m_window, _T("GetSize() doesn't work without window") );
+
+ m_window->GetClientSize( width, height );
+}
+
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: dcmemory.cpp
+// Purpose: wxMemoryDC class
+// Author: Stefan Csomor
+// Modified by:
+// Created: 01/02/97
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "dcmemory.h"
+#endif
+
+#include "wx/dcmemory.h"
+#include "wx/mac/private.h"
+
+//-----------------------------------------------------------------------------
+// wxMemoryDC
+//-----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC,wxPaintDC)
+
+wxMemoryDC::wxMemoryDC(void)
+: m_selected()
+{
+ m_ok = TRUE;
+ SetBackground(*wxWHITE_BRUSH);
+ SetBrush(*wxWHITE_BRUSH);
+ SetPen(*wxBLACK_PEN);
+ m_ok = FALSE;
+};
+
+wxMemoryDC::wxMemoryDC( wxDC *WXUNUSED(dc) )
+: m_selected()
+{
+ m_ok = TRUE;
+ SetBackground(*wxWHITE_BRUSH);
+ SetBrush(*wxWHITE_BRUSH);
+ SetPen(*wxBLACK_PEN);
+ m_ok = FALSE;
+};
+
+wxMemoryDC::~wxMemoryDC()
+{
+ if ( m_selected.Ok() )
+ {
+ UnlockPixels( GetGWorldPixMap(MAC_WXHBITMAP(m_selected.GetHBITMAP())) );
+ }
+};
+
+void wxMemoryDC::SelectObject( const wxBitmap& bitmap )
+{
+ if ( m_selected.Ok() )
+ {
+ UnlockPixels( GetGWorldPixMap(MAC_WXHBITMAP(m_selected.GetHBITMAP())) );
+ }
+ m_selected = bitmap;
+ if (m_selected.Ok())
+ {
+ if ( m_selected.GetHBITMAP() )
+ {
+ m_macPort = (GrafPtr) m_selected.GetHBITMAP() ;
+ LockPixels( GetGWorldPixMap( (CGrafPtr) m_macPort ) ) ;
+ wxMask * mask = bitmap.GetMask() ;
+ if ( mask )
+ {
+ m_macMask = mask->GetMaskBitmap() ;
+ }
+ SetRectRgn( (RgnHandle) m_macBoundaryClipRgn , 0 , 0 , m_selected.GetWidth() , m_selected.GetHeight() ) ;
+ CopyRgn( (RgnHandle) m_macBoundaryClipRgn ,(RgnHandle) m_macCurrentClipRgn ) ;
+ m_ok = TRUE ;
+ }
+ else
+ {
+ m_ok = FALSE;
+ }
+ }
+ else
+ {
+ m_ok = FALSE;
+ }
+}
+
+void wxMemoryDC::DoGetSize( int *width, int *height ) const
+{
+ if (m_selected.Ok())
+ {
+ if (width) (*width) = m_selected.GetWidth();
+ if (height) (*height) = m_selected.GetHeight();
+ }
+ else
+ {
+ if (width) (*width) = 0;
+ if (height) (*height) = 0;
+ }
+}
+
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: dcprint.cpp
+// Purpose: wxPrinterDC class
+// Author: Julian Smart
+// Modified by:
+// Created: 01/02/97
+// RCS-ID: $Id$
+// Copyright: (c) Julian Smart
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "dcprint.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#endif
+
+#include "wx/dcprint.h"
+#include "wx/msgdlg.h"
+#include <math.h>
+#include "wx/mac/uma.h"
+#include "wx/mac/private/print.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_CLASS(wxPrinterDC, wxDC)
+#endif
+
+class wxNativePrinterDC
+{
+public :
+ wxNativePrinterDC() {}
+ virtual ~wxNativePrinterDC() {}
+ virtual bool StartDoc( wxPrinterDC* dc , const wxString& message ) = 0;
+ virtual void EndDoc( wxPrinterDC* dc ) = 0;
+ virtual void StartPage( wxPrinterDC* dc ) = 0;
+ virtual void EndPage( wxPrinterDC* dc ) = 0;
+ virtual wxCoord GetMaxX() const = 0 ;
+ virtual wxCoord GetMaxY() const = 0 ;
+ // returns 0 in case of no Error, otherwise platform specific error codes
+ virtual wxUint32 GetStatus() const = 0 ;
+ bool Ok() { return GetStatus() == 0 ; }
+
+ static wxNativePrinterDC* Create(wxPrintData* data) ;
+} ;
+
+#if TARGET_CARBON
+
+class wxMacCarbonPrinterDC : public wxNativePrinterDC
+{
+public :
+ wxMacCarbonPrinterDC( wxPrintData* data ) ;
+ ~wxMacCarbonPrinterDC() ;
+ virtual bool StartDoc( wxPrinterDC* dc , const wxString& message ) ;
+ virtual void EndDoc( wxPrinterDC* dc ) ;
+ virtual void StartPage( wxPrinterDC* dc ) ;
+ virtual void EndPage( wxPrinterDC* dc ) ;
+ virtual wxCoord GetMaxX() const { return m_maxX ; }
+ virtual wxCoord GetMaxY() const { return m_maxY ; }
+ virtual wxUint32 GetStatus() const { return m_err ; }
+private :
+ GrafPtr m_macPrintFormerPort ;
+ wxCoord m_maxX ;
+ wxCoord m_maxY ;
+ OSStatus m_err ;
+} ;
+
+wxMacCarbonPrinterDC::wxMacCarbonPrinterDC( wxPrintData* data )
+{
+ ::GetPort( & m_macPrintFormerPort ) ;
+
+ m_err = noErr ;
+ wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) data->m_nativePrintData ;
+
+ PMRect rPage;
+ m_err = PMGetAdjustedPageRect(native->m_macPageFormat, &rPage);
+ if ( m_err != noErr )
+ return;
+
+ m_maxX = wxCoord(rPage.right - rPage.left) ;
+ m_maxY = wxCoord(rPage.bottom - rPage.top);
+}
+
+wxMacCarbonPrinterDC::~wxMacCarbonPrinterDC()
+{
+ // nothing to release from print data, as wxPrinterDC has all data in its wxPrintData member
+ ::SetPort( m_macPrintFormerPort ) ;
+}
+
+wxNativePrinterDC* wxNativePrinterDC::Create(wxPrintData* data)
+{
+ return new wxMacCarbonPrinterDC(data) ;
+}
+
+bool wxMacCarbonPrinterDC::StartDoc( wxPrinterDC* dc , const wxString& WXUNUSED(message) )
+{
+ if ( m_err )
+ return false ;
+
+ wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) dc->GetPrintData().m_nativePrintData ;
+
+ m_err = PMSessionBeginDocument(native->m_macPrintSession,
+ native->m_macPrintSettings,
+ native->m_macPageFormat);
+ if ( m_err != noErr )
+ return false;
+
+ PMRect rPage;
+ m_err = PMGetAdjustedPageRect(native->m_macPageFormat, &rPage);
+ if ( m_err != noErr )
+ return false;
+
+ m_maxX = (wxCoord)(rPage.right - rPage.left);
+ m_maxY = (wxCoord)(rPage.bottom - rPage.top);
+ return true ;
+}
+
+void wxMacCarbonPrinterDC::EndDoc( wxPrinterDC* dc )
+{
+ if ( m_err )
+ return ;
+
+ wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) dc->GetPrintData().m_nativePrintData ;
+
+ m_err = PMSessionEndDocument(native->m_macPrintSession);
+}
+
+void wxMacCarbonPrinterDC::StartPage( wxPrinterDC* dc )
+{
+ if ( m_err )
+ return ;
+
+ wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) dc->GetPrintData().m_nativePrintData ;
+
+ m_err = PMSessionBeginPage(native->m_macPrintSession,
+ native->m_macPageFormat,
+ nil);
+
+ if ( m_err == noErr )
+ {
+ m_err = PMSessionGetGraphicsContext(native->m_macPrintSession,
+ nil,
+ (void**) &dc->m_macPort );
+ }
+
+ if ( m_err != noErr )
+ {
+ PMSessionEndPage(native->m_macPrintSession);
+ PMSessionEndDocument(native->m_macPrintSession);
+ }
+ else
+ {
+ PMRect rPage;
+
+ m_err = PMGetAdjustedPageRect(native->m_macPageFormat, &rPage);
+ if ( !m_err )
+ {
+ dc->m_macLocalOrigin.x = (int) rPage.left;
+ dc->m_macLocalOrigin.y = (int) rPage.top;
+ }
+ // since this is a non-critical error, we set the flag back
+ m_err = noErr ;
+ }
+}
+
+void wxMacCarbonPrinterDC::EndPage( wxPrinterDC* dc )
+{
+ if ( m_err )
+ return ;
+
+ wxMacCarbonPrintData *native = (wxMacCarbonPrintData*) dc->GetPrintData().m_nativePrintData ;
+
+ m_err = PMSessionEndPage(native->m_macPrintSession);
+ if ( m_err != noErr )
+ {
+ PMSessionEndDocument(native->m_macPrintSession);
+ }
+}
+
+#else
+
+class wxMacClassicPrinterDC : public wxNativePrinterDC
+{
+public :
+ wxMacClassicPrinterDC( wxPrintData* data ) ;
+ ~wxMacClassicPrinterDC() ;
+ virtual bool StartDoc( wxPrinterDC* dc , const wxString& message ) ;
+ virtual void EndDoc( wxPrinterDC* dc ) ;
+ virtual void StartPage( wxPrinterDC* dc ) ;
+ virtual void EndPage( wxPrinterDC* dc ) ;
+ virtual wxCoord GetMaxX() const { return m_maxX ; }
+ virtual wxCoord GetMaxY() const { return m_maxY ; }
+ virtual wxUint32 GetStatus() const { return m_err ; }
+private :
+ GrafPtr m_macPrintFormerPort ;
+ TPPrPort m_macPrintingPort ;
+ OSErr m_err ;
+ long m_maxX ;
+ long m_maxY ;
+} ;
+
+wxNativePrinterDC* wxNativePrinterDC::Create(wxPrintData* data)
+{
+ return new wxMacClassicPrinterDC(data) ;
+}
+
+wxMacClassicPrinterDC::wxMacClassicPrinterDC(wxPrintData* data)
+{
+ ::GetPort( &m_macPrintFormerPort ) ;
+ m_err = noErr ;
+ ::UMAPrOpen() ;
+ m_err = PrError() ;
+ if ( m_err != noErr )
+ return;
+
+ wxMacClassicPrintData *native = (wxMacClassicPrintData*) data->m_nativePrintData ;
+
+ if ( ::PrValidate( native->m_macPrintSettings ) )
+ {
+ // the driver has changed in the mean time, should we pop up a page setup dialog ?
+ if ( !::PrStlDialog( native->m_macPrintSettings ) )
+ {
+ m_err = -1 ;
+ return;
+ }
+ }
+ m_err = PrError() ;
+
+ if ( m_err == noErr )
+ {
+ m_maxX = (**native->m_macPrintSettings).prInfo.rPage.right - (**native->m_macPrintSettings).prInfo.rPage.left ;
+ m_maxY = (**native->m_macPrintSettings).prInfo.rPage.bottom - (**native->m_macPrintSettings).prInfo.rPage.top ;
+ }
+}
+
+wxMacClassicPrinterDC::~wxMacClassicPrinterDC()
+{
+ ::UMAPrClose() ;
+ ::SetPort( LMGetWMgrPort() ) ;
+}
+
+bool wxMacClassicPrinterDC::StartDoc( wxPrinterDC* dc , const wxString& WXUNUSED(message) )
+{
+ if ( m_err )
+ return false ;
+
+ wxMacClassicPrintData *native = (wxMacClassicPrintData*) dc->GetPrintData().m_nativePrintData ;
+ m_macPrintingPort = ::PrOpenDoc( native->m_macPrintSettings , NULL , NULL ) ;
+ m_err = PrError() ;
+ if ( m_err )
+ return false ;
+
+ // sets current port
+ dc->m_macPort = (GrafPtr ) m_macPrintingPort ;
+ m_maxX = (**native->m_macPrintSettings).prInfo.rPage.right - (**native->m_macPrintSettings).prInfo.rPage.left ;
+ m_maxY = (**native->m_macPrintSettings).prInfo.rPage.bottom - (**native->m_macPrintSettings).prInfo.rPage.top ;
+ return true ;
+}
+
+void wxMacClassicPrinterDC::EndDoc( wxPrinterDC* dc )
+{
+ if ( m_err )
+ return ;
+
+ PrCloseDoc( m_macPrintingPort ) ;
+ m_err = PrError() ;
+}
+
+void wxMacClassicPrinterDC::StartPage( wxPrinterDC* dc )
+{
+ if ( m_err )
+ return ;
+
+ wxMacClassicPrintData *native = (wxMacClassicPrintData*) dc->GetPrintData().m_nativePrintData ;
+
+ PrOpenPage( m_macPrintingPort , NULL ) ;
+ dc->m_macLocalOrigin.x = (**native->m_macPrintSettings).rPaper.left ;
+ dc->m_macLocalOrigin.y = (**native->m_macPrintSettings).rPaper.top ;
+ // m_macPrintingPort is now the current port
+ Rect clip = { -32000 , -32000 , 32000 , 32000 } ;
+ ::ClipRect( &clip ) ;
+ m_err = PrError() ;
+ if ( m_err != noErr )
+ ::PrCloseDoc( m_macPrintingPort ) ;
+}
+
+void wxMacClassicPrinterDC::EndPage( wxPrinterDC* dc )
+{
+ if ( m_err )
+ return ;
+
+ PrClosePage( m_macPrintingPort ) ;
+ m_err = PrError() ;
+ if ( m_err != noErr )
+ ::PrCloseDoc( m_macPrintingPort ) ;
+}
+
+#endif
+
+wxPrinterDC::wxPrinterDC(const wxPrintData& printdata)
+{
+ m_ok = FALSE ;
+ m_printData = printdata ;
+ m_printData.ConvertToNative() ;
+ m_nativePrinterDC = wxNativePrinterDC::Create( &m_printData ) ;
+ if ( m_nativePrinterDC )
+ {
+ m_ok = m_nativePrinterDC->Ok() ;
+
+ if ( !m_ok )
+ {
+ wxString message ;
+ message.Printf( wxT("Print Error %u"), m_nativePrinterDC->GetStatus() ) ;
+ wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ;
+ dialog.ShowModal();
+ }
+ }
+}
+
+wxPrinterDC::~wxPrinterDC(void)
+{
+ delete m_nativePrinterDC ;
+}
+
+bool wxPrinterDC::StartDoc( const wxString& message )
+{
+ wxASSERT_MSG( Ok() , wxT("Called wxPrinterDC::StartDoc from an invalid object") ) ;
+
+ if ( !m_ok )
+ return false ;
+
+ if ( m_nativePrinterDC->StartDoc(this, message ) )
+ {
+ // in case we have to do additional things when successful
+ }
+ m_ok = m_nativePrinterDC->Ok() ;
+ if ( !m_ok )
+ {
+ wxString message ;
+ message.Printf( wxT("Print Error %u"), m_nativePrinterDC->GetStatus() ) ;
+ wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ;
+ dialog.ShowModal();
+ }
+
+ return m_ok ;
+}
+
+void wxPrinterDC::EndDoc(void)
+{
+ if ( !m_ok )
+ return ;
+
+ m_nativePrinterDC->EndDoc( this ) ;
+ m_ok = m_nativePrinterDC->Ok() ;
+
+ if ( !m_ok )
+ {
+ wxString message ;
+ message.Printf( wxT("Print Error %u"), m_nativePrinterDC->GetStatus() ) ;
+ wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ;
+ dialog.ShowModal();
+ }
+}
+
+void wxPrinterDC::StartPage(void)
+{
+ if ( !m_ok )
+ return ;
+
+ m_logicalFunction = wxCOPY;
+ // m_textAlignment = wxALIGN_TOP_LEFT;
+ m_backgroundMode = wxTRANSPARENT;
+
+ m_textForegroundColour = *wxBLACK;
+ m_textBackgroundColour = *wxWHITE;
+ m_pen = *wxBLACK_PEN;
+ m_font = *wxNORMAL_FONT;
+ m_brush = *wxTRANSPARENT_BRUSH;
+ m_backgroundBrush = *wxWHITE_BRUSH;
+
+ m_macFontInstalled = false ;
+ m_macBrushInstalled = false ;
+ m_macPenInstalled = false ;
+
+ m_nativePrinterDC->StartPage(this) ;
+ m_ok = m_nativePrinterDC->Ok() ;
+
+}
+
+void wxPrinterDC::EndPage(void)
+{
+ if ( !m_ok )
+ return ;
+
+ m_nativePrinterDC->EndPage(this) ;
+ m_ok = m_nativePrinterDC->Ok() ;
+}
+
+void wxPrinterDC::DoGetSize(int *width, int *height) const
+{
+ wxCHECK_RET( m_ok , _T("GetSize() doesn't work without a valid wxPrinterDC") );
+
+ if ( width )
+ * width = m_nativePrinterDC->GetMaxX() ;
+ if ( height )
+ * height = m_nativePrinterDC->GetMaxY() ;
+}
+
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: dcscreen.cpp
+// Purpose: wxScreenDC class
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "dcscreen.h"
+#endif
+
+#include "wx/dcscreen.h"
+#include "wx/mac/uma.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxScreenDC, wxWindowDC)
+#endif
+
+// Create a DC representing the whole screen
+wxScreenDC::wxScreenDC()
+{
+#if TARGET_CARBON
+ m_macPort = GetQDGlobalsThePort() ;
+ GrafPtr port ;
+ GetPort( &port ) ;
+ SetPort( (GrafPtr) m_macPort ) ;
+ Point pt = { 0,0 } ;
+ LocalToGlobal( &pt ) ;
+ SetPort( port ) ;
+ m_macLocalOrigin.x = -pt.h ;
+ m_macLocalOrigin.y = -pt.v ;
+#else
+ m_macPort = LMGetWMgrPort() ;
+ m_macLocalOrigin.x = 0 ;
+ m_macLocalOrigin.y = 0 ;
+#endif
+ m_ok = TRUE ;
+ BitMap screenBits;
+ GetQDGlobalsScreenBits( &screenBits );
+ m_minX = screenBits.bounds.left ;
+ #if TARGET_CARBON
+ SInt16 height ;
+ GetThemeMenuBarHeight( &height ) ;
+ m_minY = screenBits.bounds.top + height ;
+ #else
+ m_minY = screenBits.bounds.top + LMGetMBarHeight() ;
+ #endif
+ m_maxX = screenBits.bounds.right ;
+ m_maxY = screenBits.bounds.bottom ;
+ MacSetRectRgn( (RgnHandle) m_macBoundaryClipRgn , m_minX , m_minY , m_maxX , m_maxY ) ;
+ OffsetRgn( (RgnHandle) m_macBoundaryClipRgn , m_macLocalOrigin.x , m_macLocalOrigin.y ) ;
+ CopyRgn( (RgnHandle) m_macBoundaryClipRgn , (RgnHandle) m_macCurrentClipRgn ) ;
+}
+
+wxScreenDC::~wxScreenDC()
+{
+ // TODO
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: dialog.cpp
+// Purpose: wxDialog class
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "dialog.h"
+#endif
+
+#include "wx/dialog.h"
+#include "wx/utils.h"
+#include "wx/frame.h"
+#include "wx/app.h"
+#include "wx/settings.h"
+
+#include "wx/mac/uma.h"
+
+// Lists to keep track of windows, so we can disable/enable them
+// for modal dialogs
+wxList wxModalDialogs;
+//wxList wxModelessWindows; // Frames and modeless dialogs
+extern wxList wxPendingDelete;
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxDialog, wxTopLevelWindow)
+
+BEGIN_EVENT_TABLE(wxDialog, wxDialogBase)
+ EVT_BUTTON(wxID_OK, wxDialog::OnOK)
+ EVT_BUTTON(wxID_APPLY, wxDialog::OnApply)
+ EVT_BUTTON(wxID_CANCEL, wxDialog::OnCancel)
+
+ EVT_CHAR_HOOK(wxDialog::OnCharHook)
+
+ EVT_SYS_COLOUR_CHANGED(wxDialog::OnSysColourChanged)
+
+ EVT_CLOSE(wxDialog::OnCloseWindow)
+END_EVENT_TABLE()
+
+#endif
+
+wxDialog::wxDialog()
+{
+ m_isShown = FALSE;
+ SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
+}
+
+bool wxDialog::Create(wxWindow *parent, wxWindowID id,
+ const wxString& title,
+ const wxPoint& pos,
+ const wxSize& size,
+ long style,
+ const wxString& name)
+{
+ SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
+
+
+ if ( !wxTopLevelWindow::Create(parent, id, title, pos, size, style, name) )
+ return FALSE;
+
+ MacCreateRealWindow( title , pos , size , MacRemoveBordersFromStyle(style) & ~(wxYES|wxOK|wxNO|wxCANCEL) , name ) ;
+
+ m_macWindowBackgroundTheme = kThemeBrushDialogBackgroundActive ;
+ SetThemeWindowBackground( (WindowRef) m_macWindow , m_macWindowBackgroundTheme , false ) ;
+
+ return TRUE;
+}
+
+void wxDialog::SetModal(bool flag)
+{
+ if ( flag )
+ {
+ m_windowStyle |= wxDIALOG_MODAL;
+
+ wxModelessWindows.DeleteObject(this);
+#if TARGET_CARBON
+ SetWindowModality( (WindowRef) MacGetWindowRef() , kWindowModalityAppModal , NULL ) ;
+#endif
+ }
+ else
+ {
+ m_windowStyle &= ~wxDIALOG_MODAL;
+
+ wxModelessWindows.Append(this);
+ }
+}
+
+wxDialog::~wxDialog()
+{
+ m_isBeingDeleted = TRUE;
+ Show(FALSE);
+}
+
+// By default, pressing escape cancels the dialog , on mac command-stop does the same thing
+void wxDialog::OnCharHook(wxKeyEvent& event)
+{
+ if (( event.m_keyCode == WXK_ESCAPE ||
+ ( event.m_keyCode == '.' && event.MetaDown() ) )
+ && FindWindow(wxID_CANCEL) )
+ {
+ // Behaviour changed in 2.0: we'll send a Cancel message
+ // to the dialog instead of Close.
+ wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
+ cancelEvent.SetEventObject( this );
+ GetEventHandler()->ProcessEvent(cancelEvent);
+
+ return;
+ }
+ // We didn't process this event.
+ event.Skip();
+}
+
+bool wxDialog::IsModal() const
+{
+ return (GetWindowStyleFlag() & wxDIALOG_MODAL) != 0;
+}
+
+
+bool wxDialog::IsModalShowing() const
+{
+ return wxModalDialogs.Find((wxDialog *)this) != NULL; // const_cast
+}
+
+bool wxDialog::Show(bool show)
+{
+ if ( !wxDialogBase::Show(show) )
+ {
+ // nothing to do
+ return FALSE;
+ }
+
+ if ( show )
+ {
+ // usually will result in TransferDataToWindow() being called
+ InitDialog();
+ }
+
+ if ( IsModal() )
+ {
+ if ( show )
+ {
+ DoShowModal();
+ }
+ else // end of modal dialog
+ {
+ // this will cause IsModalShowing() return FALSE and our local
+ // message loop will terminate
+ wxModalDialogs.DeleteObject(this);
+ }
+ }
+
+ return TRUE;
+}
+
+#if !TARGET_CARBON
+extern bool s_macIsInModalLoop ;
+#endif
+
+void wxDialog::DoShowModal()
+{
+ wxCHECK_RET( !IsModalShowing(), _T("DoShowModal() called twice") );
+
+ wxModalDialogs.Append(this);
+
+#if TARGET_CARBON
+ BeginAppModalStateForWindow( (WindowRef) MacGetWindowRef()) ;
+#else
+ // TODO : test whether parent gets disabled
+ bool formerModal = s_macIsInModalLoop ;
+ s_macIsInModalLoop = true ;
+#endif
+ while ( IsModalShowing() )
+ {
+ wxTheApp->MacDoOneEvent() ;
+ // calls process idle itself
+ }
+
+#if TARGET_CARBON
+ EndAppModalStateForWindow( (WindowRef) MacGetWindowRef() ) ;
+#else
+ // TODO probably reenable the parent window if any
+ s_macIsInModalLoop = formerModal ;
+#endif
+}
+
+
+// Replacement for Show(TRUE) for modal dialogs - returns return code
+int wxDialog::ShowModal()
+{
+ if ( !IsModal() )
+ {
+ SetModal(TRUE);
+ }
+
+ Show(TRUE);
+ return GetReturnCode();
+}
+
+// NB: this function (surprizingly) may be called for both modal and modeless
+// dialogs and should work for both of them
+void wxDialog::EndModal(int retCode)
+{
+ SetReturnCode(retCode);
+ Show(FALSE);
+}
+
+// Standard buttons
+void wxDialog::OnOK(wxCommandEvent& WXUNUSED(event))
+{
+ if ( Validate() && TransferDataFromWindow() )
+ {
+ EndModal(wxID_OK);
+ }
+}
+
+void wxDialog::OnApply(wxCommandEvent& WXUNUSED(event))
+{
+ if (Validate())
+ TransferDataFromWindow();
+ // TODO probably need to disable the Apply button until things change again
+}
+
+void wxDialog::OnCancel(wxCommandEvent& WXUNUSED(event))
+{
+ EndModal(wxID_CANCEL);
+}
+
+void wxDialog::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
+{
+ // We'll send a Cancel message by default,
+ // which may close the dialog.
+ // Check for looping if the Cancel event handler calls Close().
+
+ // Note that if a cancel button and handler aren't present in the dialog,
+ // nothing will happen when you close the dialog via the window manager, or
+ // via Close().
+ // We wouldn't want to destroy the dialog by default, since the dialog may have been
+ // created on the stack.
+ // However, this does mean that calling dialog->Close() won't delete the dialog
+ // unless the handler for wxID_CANCEL does so. So use Destroy() if you want to be
+ // sure to destroy the dialog.
+ // The default OnCancel (above) simply ends a modal dialog, and hides a modeless dialog.
+
+ static wxList closing;
+
+ if ( closing.Member(this) )
+ return;
+
+ closing.Append(this);
+
+ wxCommandEvent cancelEvent(wxEVT_COMMAND_BUTTON_CLICKED, wxID_CANCEL);
+ cancelEvent.SetEventObject( this );
+ GetEventHandler()->ProcessEvent(cancelEvent); // This may close the dialog
+
+ closing.DeleteObject(this);
+}
+
+void wxDialog::OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(event))
+{
+ SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
+ Refresh();
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: dirdlg.cpp
+// Purpose: wxDirDialog
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "dirdlg.h"
+#endif
+
+#include "wx/defs.h"
+#include "wx/utils.h"
+#include "wx/dialog.h"
+#include "wx/dirdlg.h"
+
+#include "wx/cmndata.h"
+
+#include "wx/mac/private.h"
+
+#ifdef __DARWIN__
+ #include <Carbon/Carbon.h>
+#else
+ #include <Navigation.h>
+#endif
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_CLASS(wxDirDialog, wxDialog)
+#endif
+
+wxDirDialog::wxDirDialog(wxWindow *parent,
+ const wxString& message,
+ const wxString& defaultPath,
+ long style,
+ const wxPoint& WXUNUSED(pos),
+ const wxSize& WXUNUSED(size),
+ const wxString& WXUNUSED(name))
+{
+ wxASSERT_MSG( NavServicesAvailable() , wxT("Navigation Services are not running") ) ;
+ m_message = message;
+ m_dialogStyle = style;
+ m_parent = parent;
+ m_path = defaultPath;
+}
+
+int wxDirDialog::ShowModal()
+{
+ NavDialogOptions mNavOptions;
+ NavObjectFilterUPP mNavFilterUPP = NULL;
+ NavPreviewUPP mNavPreviewUPP = NULL ;
+ NavReplyRecord mNavReply;
+ AEDesc* mDefaultLocation = NULL ;
+ bool mSelectDefault = false ;
+
+ ::NavGetDefaultDialogOptions(&mNavOptions);
+
+ mNavFilterUPP = nil;
+ mNavPreviewUPP = nil;
+ mSelectDefault = false;
+ mNavReply.validRecord = false;
+ mNavReply.replacing = false;
+ mNavReply.isStationery = false;
+ mNavReply.translationNeeded = false;
+ mNavReply.selection.descriptorType = typeNull;
+ mNavReply.selection.dataHandle = nil;
+ mNavReply.keyScript = smSystemScript;
+ mNavReply.fileTranslation = nil;
+
+ // Set default location, the location
+ // that's displayed when the dialog
+ // first appears
+
+ if ( mDefaultLocation ) {
+
+ if (mSelectDefault) {
+ mNavOptions.dialogOptionFlags |= kNavSelectDefaultLocation;
+ } else {
+ mNavOptions.dialogOptionFlags &= ~kNavSelectDefaultLocation;
+ }
+ }
+
+ OSErr err = ::NavChooseFolder(
+ mDefaultLocation,
+ &mNavReply,
+ &mNavOptions,
+ NULL,
+ mNavFilterUPP,
+ 0L); // User Data
+
+ if ( (err != noErr) && (err != userCanceledErr) ) {
+ m_path = wxT("") ;
+ return wxID_CANCEL ;
+ }
+
+ if (mNavReply.validRecord) { // User chose a folder
+
+ FSSpec folderInfo;
+ FSSpec outFileSpec ;
+ AEDesc specDesc ;
+
+ OSErr err = ::AECoerceDesc( &mNavReply.selection , typeFSS, &specDesc);
+ if ( err != noErr ) {
+ m_path = wxT("") ;
+ return wxID_CANCEL ;
+ }
+ folderInfo = **(FSSpec**) specDesc.dataHandle;
+ if (specDesc.dataHandle != nil) {
+ ::AEDisposeDesc(&specDesc);
+ }
+
+// mNavReply.GetFileSpec(folderInfo);
+
+ // The FSSpec from NavChooseFolder is NOT the file spec
+ // for the folder. The parID field is actually the DirID
+ // of the folder itself, not the folder's parent, and
+ // the name field is empty. We must call PBGetCatInfo
+ // to get the parent DirID and folder name
+
+ Str255 name;
+ CInfoPBRec thePB; // Directory Info Parameter Block
+ thePB.dirInfo.ioCompletion = nil;
+ thePB.dirInfo.ioVRefNum = folderInfo.vRefNum; // Volume is right
+ thePB.dirInfo.ioDrDirID = folderInfo.parID; // Folder's DirID
+ thePB.dirInfo.ioNamePtr = name;
+ thePB.dirInfo.ioFDirIndex = -1; // Lookup using Volume and DirID
+
+ err = ::PBGetCatInfoSync(&thePB);
+ if ( err != noErr ) {
+ m_path = wxT("") ;
+ return wxID_CANCEL ;
+ }
+ // Create cannonical FSSpec
+ ::FSMakeFSSpec(thePB.dirInfo.ioVRefNum, thePB.dirInfo.ioDrParID,
+ name, &outFileSpec);
+
+ // outFolderDirID = thePB.dirInfo.ioDrDirID;
+ m_path = wxMacFSSpec2MacFilename( &outFileSpec ) ;
+ return wxID_OK ;
+ }
+ return wxID_CANCEL;
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: msw/dir.cpp
+// Purpose: wxDir implementation for Mac
+// Author: Stefan Csomor
+// Modified by:
+// Created: 08.12.99
+// RCS-ID: $Id$
+// Copyright: (c) 1999 Stefan Csomor <csomor@advanced.ch>
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#ifdef __GNUG__
+ #pragma implementation "dir.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+ #include "wx/intl.h"
+ #include "wx/log.h"
+#endif // PCH
+
+#include "wx/dir.h"
+#include "wx/filefn.h" // for wxPathExists()
+
+#ifndef __DARWIN__
+ #include <windows.h>
+#endif
+
+#include "wx/mac/private.h"
+
+#ifdef __DARWIN__
+# include "MoreFilesX.h"
+#else
+# include "MoreFiles.h"
+# include "MoreFilesExtras.h"
+#endif
+
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+#ifndef MAX_PATH
+ #define MAX_PATH 260 // from VC++ headers
+#endif
+
+// ----------------------------------------------------------------------------
+// macros
+// ----------------------------------------------------------------------------
+
+#define M_DIR ((wxDirData *)m_data)
+
+// ----------------------------------------------------------------------------
+// private classes
+// ----------------------------------------------------------------------------
+
+// this class stores everything we need to enumerate the files
+class wxDirData
+{
+public:
+ wxDirData(const wxString& dirname);
+ ~wxDirData();
+
+ void SetFileSpec(const wxString& filespec) { m_filespec = filespec; }
+ void SetFlags(int flags) { m_flags = flags; }
+
+ bool Read(wxString *filename); // reads the next
+ void Rewind() ;
+
+ const wxString& GetName() const { return m_dirname; }
+ bool Ok() const { return m_ok; }
+
+private:
+ CInfoPBRec m_CPB ;
+ wxInt16 m_index ;
+ long m_dirId ;
+ Str255 m_name ;
+ Boolean m_isDir ;
+
+ wxString m_dirname;
+ wxString m_filespec;
+
+ int m_flags;
+ bool m_ok;
+};
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxDirData
+// ----------------------------------------------------------------------------
+
+wxDirData::wxDirData(const wxString& dirname)
+ : m_dirname(dirname)
+{
+ m_ok = false;
+
+ OSErr err;
+
+ // throw away the trailing slashes
+ size_t n = m_dirname.length();
+ wxCHECK_RET( n, _T("empty dir name in wxDir") );
+
+ while ( n > 0 && wxIsPathSeparator(m_dirname[--n]) )
+ ;
+
+ m_dirname.Truncate(n + 1);
+
+#ifdef __DARWIN__
+ FSRef theRef;
+
+ // get the FSRef associated with the POSIX path
+ err = FSPathMakeRef((const UInt8 *) m_dirname.c_str(), &theRef, NULL);
+ FSGetVRefNum(&theRef, &(m_CPB.hFileInfo.ioVRefNum));
+
+ err = FSGetNodeID( &theRef , &m_dirId , &m_isDir ) ;
+#else
+ FSSpec fsspec ;
+
+ wxMacFilename2FSSpec( m_dirname , &fsspec ) ;
+ m_CPB.hFileInfo.ioVRefNum = fsspec.vRefNum ;
+
+ err = FSpGetDirectoryID( &fsspec , &m_dirId , &m_isDir ) ;
+#endif
+ //wxASSERT_MSG( (err == noErr) || (err == nsvErr) , wxT("Error accessing directory " + m_dirname)) ;
+ if ( (err == noErr) || (err == nsvErr))
+ m_ok = true;
+ else
+ wxLogError(wxString(wxT("Error accessing directory ")) + m_dirname);
+
+ m_CPB.hFileInfo.ioNamePtr = m_name ;
+ m_index = 0 ;
+}
+
+wxDirData::~wxDirData()
+{
+}
+
+void wxDirData::Rewind()
+{
+ m_index = 0 ;
+}
+
+bool wxDirData::Read(wxString *filename)
+{
+ if ( !m_isDir )
+ return FALSE ;
+
+ wxString result;
+
+ short err = noErr ;
+
+ while ( err == noErr )
+ {
+ m_index++ ;
+ m_CPB.dirInfo.ioFDirIndex = m_index;
+ m_CPB.dirInfo.ioDrDirID = m_dirId; /* we need to do this every time */
+ err = PBGetCatInfoSync((CInfoPBPtr)&m_CPB);
+ if ( err != noErr )
+ break ;
+
+ // its hidden but we don't want it
+ if ( ( m_CPB.hFileInfo.ioFlFndrInfo.fdFlags & kIsInvisible ) && !(m_flags & wxDIR_HIDDEN) )
+ continue ;
+#ifdef __DARWIN__
+ // under X, names that start with '.' are hidden
+ if ( ( m_name[1] == '.' ) && !(m_flags & wxDIR_HIDDEN) )
+ continue;
+#endif
+#if TARGET_CARBON
+ // under X thats the way the mounting points look like
+ if ( ( m_CPB.dirInfo.ioDrDirID == 0 ) && ( m_flags & wxDIR_DIRS) )
+ break ;
+#endif
+ // we have a directory
+ if ( ( m_CPB.dirInfo.ioFlAttrib & ioDirMask) != 0 && (m_flags & wxDIR_DIRS) )
+ break ;
+
+ // its a file but we don't want it
+ if ( ( m_CPB.dirInfo.ioFlAttrib & ioDirMask) == 0 && !(m_flags & wxDIR_FILES ) )
+ continue ;
+
+ wxString file = wxMacMakeStringFromPascal( m_name ) ;
+ if ( m_filespec.IsEmpty() || m_filespec == wxT("*.*") || m_filespec == wxT("*") )
+ {
+ }
+ else if ( m_filespec.Length() > 1 && m_filespec.Left(1) == wxT("*") )
+ {
+ if ( file.Right( m_filespec.Length() - 1 ).Upper() != m_filespec.Mid(1).Upper() )
+ {
+ continue ;
+ }
+ }
+ else if ( m_filespec.Length() > 1 && m_filespec.Right(1) == wxT("*") )
+ {
+ if ( file.Left( m_filespec.Length() - 1 ).Upper() != m_filespec.Left( m_filespec.Length() - 1 ).Upper() )
+ {
+ continue ;
+ }
+ }
+ else if ( file.Upper() != m_filespec.Upper() )
+ {
+ continue ;
+ }
+
+ break ;
+ }
+ if ( err != noErr )
+ {
+ return FALSE ;
+ }
+
+ *filename = wxMacMakeStringFromPascal( m_name ) ;
+
+ return TRUE;
+}
+
+// ----------------------------------------------------------------------------
+// wxDir helpers
+// ----------------------------------------------------------------------------
+
+/* static */
+bool wxDir::Exists(const wxString& dir)
+{
+ return wxPathExists(dir);
+}
+
+// ----------------------------------------------------------------------------
+// wxDir construction/destruction
+// ----------------------------------------------------------------------------
+
+wxDir::wxDir(const wxString& dirname)
+{
+ m_data = NULL;
+
+ (void)Open(dirname);
+}
+
+bool wxDir::Open(const wxString& dirname)
+{
+ delete M_DIR;
+ m_data = new wxDirData(dirname);
+ if (m_data->Ok())
+ return TRUE;
+ else
+ {
+ delete m_data;
+ m_data = NULL;
+ return FALSE;
+ }
+}
+
+bool wxDir::IsOpened() const
+{
+ return m_data != NULL;
+}
+
+wxString wxDir::GetName() const
+{
+ wxString name;
+ if ( m_data )
+ {
+ name = M_DIR->GetName();
+ if ( !name.empty() && (name.Last() == _T('/')) )
+ {
+ // chop off the last (back)slash
+ name.Truncate(name.length() - 1);
+ }
+ }
+
+ return name;
+}
+
+wxDir::~wxDir()
+{
+ if (M_DIR != NULL) {
+ delete M_DIR;
+ m_data = NULL;
+ }
+}
+
+// ----------------------------------------------------------------------------
+// wxDir enumerating
+// ----------------------------------------------------------------------------
+
+bool wxDir::GetFirst(wxString *filename,
+ const wxString& filespec,
+ int flags) const
+{
+ wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") );
+
+ M_DIR->Rewind();
+
+ M_DIR->SetFileSpec(filespec);
+ M_DIR->SetFlags(flags);
+
+ return GetNext(filename);
+}
+
+bool wxDir::GetNext(wxString *filename) const
+{
+ wxCHECK_MSG( IsOpened(), FALSE, _T("must wxDir::Open() first") );
+
+ wxCHECK_MSG( filename, FALSE, _T("bad pointer in wxDir::GetNext()") );
+
+ return M_DIR->Read(filename);
+}
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: display.cpp
+// Purpose: Mac implementation of wxDisplay class
+// Author: Brian Victor
+// Modified by: Royce Mitchell III & Ryan Norton
+// Created: 06/21/02
+// RCS-ID: $Id$
+// Copyright: (c) wxWindows team
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+ #pragma implementation "display.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#if wxUSE_DISPLAY
+
+#ifndef WX_PRECOMP
+ #include "wx/dynarray.h"
+ #include "wx/log.h"
+ #include "wx/msgdlg.h"
+#endif
+
+#ifdef __DARWIN__
+ #include <Carbon/Carbon.h>
+#else
+ #include <Gestalt.h>
+ #include <Displays.h>
+ #include <Quickdraw.h>
+ #include <Video.h> //for VDSwitchInfoRec
+ #include <FixMath.h>
+#endif
+
+#include "wx/display.h"
+#include "wx/gdicmn.h"
+#include "wx/string.h"
+
+// ----------------------------------------------------------------------------
+// private classes
+// ----------------------------------------------------------------------------
+
+class wxDisplayMacPriv
+{
+public:
+ GDHandle m_hndl;
+};
+
+size_t wxDisplayBase::GetCount()
+{
+ GDHandle hndl;
+ size_t num = 0;
+ hndl = DMGetFirstScreenDevice(true);
+ while(hndl)
+ {
+ num++;
+ hndl = DMGetNextScreenDevice(hndl, true);
+ }
+ return num;
+}
+
+int wxDisplayBase::GetFromPoint(const wxPoint &p)
+{
+ GDHandle hndl;
+ size_t num = 0;
+ hndl = DMGetFirstScreenDevice(true);
+ while(hndl)
+ {
+ Rect screenrect = (*hndl)->gdRect;
+ if (p.x >= screenrect.left &&
+ p.x <= screenrect.right &&
+ p.y >= screenrect.top &&
+ p.y <= screenrect.bottom)
+ {
+ return num;
+ }
+ num++;
+ hndl = DMGetNextScreenDevice(hndl, true);
+ }
+ return -1;
+}
+
+wxDisplay::wxDisplay(size_t index) : wxDisplayBase ( index ),
+ m_priv ( new wxDisplayMacPriv() )
+{
+ GDHandle hndl;
+ hndl = DMGetFirstScreenDevice(true);
+ m_priv->m_hndl = NULL;
+ while(hndl)
+ {
+ if (index == 0)
+ {
+ m_priv->m_hndl = hndl;
+ }
+ index--;
+ hndl = DMGetNextScreenDevice(hndl, true);
+ }
+}
+
+wxRect wxDisplay::GetGeometry() const
+{
+ if (!(m_priv)) return wxRect(0, 0, 0, 0);
+ if (!(m_priv->m_hndl)) return wxRect(0, 0, 0, 0);
+ Rect screenrect = (*(m_priv->m_hndl))->gdRect;
+ return wxRect( screenrect.left, screenrect.top,
+ screenrect.right - screenrect.left, screenrect.bottom - screenrect.top);
+}
+
+int wxDisplay::GetDepth() const
+{
+ if (!(m_priv)) return 0;
+ if (!(m_priv->m_hndl)) return 0;
+
+ // This cryptic looking code is based on Apple's sample code:
+ // http://developer.apple.com/samplecode/Sample_Code/Graphics_2D/GDevVideo/Gen.cp.htm
+
+ //RN - according to the docs
+ //gdPMap is a bitmap-type representation of the GDevice, and all
+ //0x0000FFFF does is get the lower 16 bits of pixelSize. However,
+ //since pixelSize is only 16 bits (a short)...
+ return ((*(*(m_priv->m_hndl))->gdPMap)->pixelSize) & 0x0000FFFF;
+}
+
+wxString wxDisplay::GetName() const
+{
+ // Macs don't name their displays...
+ return wxEmptyString;
+}
+
+struct DMModeIteratorRec
+{
+ wxArrayVideoModes* pModes;
+ const wxVideoMode* pMatchMode;
+};
+
+pascal void DMModeListIteratorProc ( void* pData,
+ DMListIndexType nIndex,
+ DMDisplayModeListEntryPtr pInfo)
+{
+ DMModeIteratorRec* pInfoData = (DMModeIteratorRec*) pData;
+
+ //Note that in testing the refresh rate is always 0 on my ibook - RN
+ int refresh = (int) Fix2Long(pInfo->displayModeResolutionInfo->csRefreshRate);
+
+ for(unsigned long i = 0; i < pInfo->displayModeDepthBlockInfo->depthBlockCount; ++i)
+ {
+#define pDBI pInfo->displayModeDepthBlockInfo->depthVPBlock[i].depthVPBlock
+
+ if (wxVideoMode((int) pInfo->displayModeResolutionInfo->csHorizontalPixels,
+ (int) pInfo->displayModeResolutionInfo->csVerticalLines,
+ (int) pDBI->vpPixelSize,
+ refresh).Matches(*pInfoData->pMatchMode) )
+ {
+ pInfoData->pModes->Add(wxVideoMode((int) pInfo->displayModeResolutionInfo->csHorizontalPixels,
+ (int) pInfo->displayModeResolutionInfo->csVerticalLines,
+ (int) pDBI->vpPixelSize,
+ refresh));
+ }
+#undef pDBI
+ }
+}
+
+struct DMModeInfoRec
+{
+ const wxVideoMode* pMode;
+ VDSwitchInfoRec sMode;
+ bool bMatched;
+};
+
+pascal void DMModeInfoProc ( void* pData,
+ DMListIndexType nIndex,
+ DMDisplayModeListEntryPtr pInfo)
+{
+ DMModeInfoRec* pInfoData = (DMModeInfoRec*) pData;
+ Fixed refresh = Long2Fix(pInfoData->pMode->refresh);
+
+ for(unsigned long i = 0; i < pInfo->displayModeDepthBlockInfo->depthBlockCount; ++i)
+ {
+#define pDBI pInfo->displayModeDepthBlockInfo->depthVPBlock[i].depthVPBlock
+ if (pInfoData->pMode->w == (int&) pInfo->displayModeResolutionInfo->csHorizontalPixels &&
+ pInfoData->pMode->h == (int&) pInfo->displayModeResolutionInfo->csVerticalLines &&
+ pInfoData->pMode->bpp == (int) pDBI->vpPixelSize &&
+ refresh == pInfo->displayModeResolutionInfo->csRefreshRate)
+ {
+ memcpy(&pInfoData->sMode, pInfo->displayModeDepthBlockInfo->depthVPBlock[i].depthSwitchInfo,
+ sizeof(VDSwitchInfoRec));
+ pInfoData->sMode.csMode = pDBI->vpPixelSize;
+ pInfoData->bMatched = true;
+ break;
+ }
+#undef pDBI
+ }
+}
+
+struct DMModeTransRec
+{
+ wxVideoMode Mode;
+ const VDSwitchInfoRec* psMode;
+ bool bMatched;
+};
+
+pascal void DMModeTransProc ( void* pData,
+ DMListIndexType nIndex,
+ DMDisplayModeListEntryPtr pInfo)
+{
+ DMModeTransRec* pInfoData = (DMModeTransRec*) pData;
+
+ for(unsigned long i = 0; i < pInfo->displayModeDepthBlockInfo->depthBlockCount; ++i)
+ {
+#define pDBI pInfo->displayModeDepthBlockInfo->depthVPBlock[i].depthVPBlock
+ if (pInfoData->psMode->csData == pInfo->displayModeDepthBlockInfo->depthVPBlock[i].depthSwitchInfo->csData)
+ {
+ pInfoData->Mode = wxVideoMode((int) pInfo->displayModeResolutionInfo->csHorizontalPixels,
+ (int) pInfo->displayModeResolutionInfo->csVerticalLines,
+ (int) pDBI->vpPixelSize,
+ (int) Fix2Long(pInfo->displayModeResolutionInfo->csRefreshRate) );
+ pInfoData->bMatched = true;
+ break;
+ }
+#undef pDBI
+ }
+}
+
+wxArrayVideoModes
+ wxDisplay::GetModes(const wxVideoMode& mode) const
+{
+
+ wxArrayVideoModes Modes;
+
+ unsigned long dwDMVer;
+ Gestalt(gestaltDisplayMgrVers, (long*) &dwDMVer);
+
+ //Check DM version (for backward compatibility only - 7.5.3+ use 2.0)
+ if (dwDMVer >= 0x020000) //version 2?
+ {
+
+ DMListIndexType nNumModes;
+ DMListType pModes;
+ DMDisplayModeListIteratorUPP uppMLI;
+ DisplayIDType nDisplayID;
+
+ wxASSERT(DMGetDisplayIDByGDevice(m_priv->m_hndl, &nDisplayID, false) == noErr);
+ //Create a new list...
+ wxASSERT_MSG(DMNewDisplayModeList(nDisplayID, NULL, NULL, &nNumModes, &pModes) == noErr, wxT("Could not create a new display mode list") );
+
+ uppMLI = NewDMDisplayModeListIteratorUPP(DMModeListIteratorProc);
+ wxASSERT(uppMLI);
+
+ DMModeIteratorRec sModeInfo;
+ sModeInfo.pModes = &Modes;
+ sModeInfo.pMatchMode = &mode;
+ for (DMListIndexType i = 0; i < nNumModes; ++i)
+ {
+ wxASSERT(DMGetIndexedDisplayModeFromList(pModes, i, NULL,
+ uppMLI, &sModeInfo) == noErr);
+ }
+ DisposeDMDisplayModeListIteratorUPP(uppMLI);
+ wxASSERT(DMDisposeList(pModes) == noErr);
+ }
+ else //DM 1.0, 1.2, 1.x
+ {
+ wxLogSysError(wxString::Format(wxT("Display Manager Version %u Not Supported! Present? %s"),
+ (unsigned int) dwDMVer / 0x10000,
+ (dwDMVer & (1 << gestaltDisplayMgrPresent) ? wxT("Yes") : wxT("No")) )
+ );
+ }
+
+ return Modes;
+}
+
+wxVideoMode wxDisplay::GetCurrentMode() const
+{
+ unsigned long dwDMVer;
+ wxVideoMode RetMode;
+
+ Gestalt(gestaltDisplayMgrVers, (long*) &dwDMVer);
+ //Check DM version (for backward compatibility only - 7.5.3+ use 2.0)
+ if (dwDMVer >= 0x020000) //version 2?
+ {
+ VDSwitchInfoRec sMode; //Note - csMode member also contains the bit depth
+ if (DMGetDisplayMode(m_priv->m_hndl, &sMode) == noErr)
+ {
+ DMListIndexType nNumModes;
+ DMListType pModes;
+ DMDisplayModeListIteratorUPP uppMLI;
+ DisplayIDType nDisplayID;
+
+ wxASSERT(DMGetDisplayIDByGDevice(m_priv->m_hndl, &nDisplayID, false) == noErr);
+ //Create a new list...
+ wxASSERT_MSG(DMNewDisplayModeList(nDisplayID, NULL, NULL, &nNumModes, &pModes) == noErr,
+ wxT("Could not create a new display mode list") );
+
+ uppMLI = NewDMDisplayModeListIteratorUPP(DMModeTransProc);
+ wxASSERT(uppMLI);
+
+ DMModeTransRec sModeInfo;
+ sModeInfo.bMatched = false;
+ sModeInfo.psMode = &sMode;
+ for (DMListIndexType i = 0; i < nNumModes; ++i)
+ {
+ wxASSERT(DMGetIndexedDisplayModeFromList(pModes, i, NULL,
+ uppMLI, &sModeInfo) == noErr);
+
+ if ( sModeInfo.bMatched == true )
+ {
+ RetMode = sModeInfo.Mode;
+ break;
+ }
+ }
+
+ DisposeDMDisplayModeListIteratorUPP(uppMLI);
+ wxASSERT(DMDisposeList(pModes) == noErr);
+ }
+ else //Can't get current mode?
+ {
+ wxLogSysError(wxString::Format(wxT("Couldn't obtain current display mode!!!\ndwDMVer:%u"),
+ (unsigned int) dwDMVer));
+ }
+ }
+ else //DM ver 1
+ {
+ wxLogSysError(wxString::Format(wxT("Display Manager Version %u Not Supported! Present? %s"),
+ (unsigned int) dwDMVer / 0x10000,
+ (dwDMVer & (1 << gestaltDisplayMgrPresent) ? wxT("Yes") : wxT("No")) )
+ );
+ }
+
+ return RetMode;
+}
+
+bool wxDisplay::ChangeMode(const wxVideoMode& mode)
+{
+ unsigned long dwDMVer;
+ Gestalt(gestaltDisplayMgrVers, (long*)&dwDMVer);
+ if (GetCount() == 1 || dwDMVer >= 0x020000)
+ {
+ if (mode == wxDefaultVideoMode)
+ {
+//#ifndef __DARWIN__
+// Handle hDisplayState;
+// if (DMBeginConfigureDisplays(&hDisplayState) != noErr)
+// {
+// wxLogSysError(wxT("Could not lock display for display mode changing!"));
+// return false;
+// }
+// wxASSERT( DMUseScreenPrefs(true, hDisplayState) == noErr);
+// DMEndConfigureDisplays(hDisplayState);
+// return true;
+//#else
+ //hmmmmm....
+ return true;
+//#endif
+ }
+
+ //0 & NULL for params 2 & 3 of DMSetVideoMode signal it to use defaults (current mode)
+ //DM 2.0+ doesn't use params 2 & 3 of DMSetDisplayMode
+ //so we have to use this icky structure
+ VDSwitchInfoRec sMode;
+ memset(&sMode, 0, sizeof(VDSwitchInfoRec) );
+
+ DMListIndexType nNumModes;
+ DMListType pModes;
+ DMDisplayModeListIteratorUPP uppMLI;
+ DisplayIDType nDisplayID;
+
+ wxASSERT(DMGetDisplayIDByGDevice(m_priv->m_hndl, &nDisplayID, false) == noErr);
+ //Create a new list...
+ wxASSERT_MSG(DMNewDisplayModeList(nDisplayID, NULL, NULL, &nNumModes, &pModes) == noErr,
+ wxT("Could not create a new display mode list") );
+
+ uppMLI = NewDMDisplayModeListIteratorUPP(DMModeInfoProc);
+ wxASSERT(uppMLI);
+
+ DMModeInfoRec sModeInfo;
+ sModeInfo.bMatched = false;
+ sModeInfo.pMode = &mode;
+ unsigned int i;
+ for(i = 0; i < nNumModes; ++i)
+ {
+ wxASSERT(DMGetIndexedDisplayModeFromList(pModes, i, NULL,
+ uppMLI, &sModeInfo) == noErr);
+ if (sModeInfo.bMatched == true)
+ {
+ sMode = sModeInfo.sMode;
+ break;
+ }
+ }
+ if(i == nNumModes)
+ return false;
+
+ DisposeDMDisplayModeListIteratorUPP(uppMLI);
+ wxASSERT(DMDisposeList(pModes) == noErr);
+
+ // For the really paranoid -
+ // unsigned long flags;
+ // Boolean bok;
+ // wxASSERT(noErr == DMCheckDisplayMode(m_priv->m_hndl, sMode.csData,
+ // sMode.csMode, &flags, NULL, &bok));
+ // wxASSERT(bok);
+
+ Handle hDisplayState;
+ if (DMBeginConfigureDisplays(&hDisplayState) != noErr)
+ {
+ wxLogSysError(wxT("Could not lock display for display mode changing!"));
+ return false;
+ }
+
+ unsigned long dwBPP = (unsigned long) mode.bpp;
+ if (DMSetDisplayMode(m_priv->m_hndl, sMode.csData,
+ (unsigned long*) &(dwBPP), NULL
+ //(unsigned long) &sMode
+ , hDisplayState
+ ) != noErr)
+ {
+ DMEndConfigureDisplays(hDisplayState);
+ wxMessageBox(wxString::Format(wxT("Could not set the display mode")));
+ return false;
+ }
+ DMEndConfigureDisplays(hDisplayState);
+ }
+ else //DM 1.0, 1.2, 1.x
+ {
+ wxLogSysError(wxString::Format(wxT("Monitor gravitation not supported yet. dwDMVer:%u"),
+ (unsigned int) dwDMVer));
+ return false;
+ }
+
+ return true;
+}
+
+wxDisplay::~wxDisplay()
+{
+ if ( m_priv )
+ {
+ delete m_priv;
+ m_priv = 0;
+ }
+}
+
+#endif // wxUSE_DISPLAY
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Name: dnd.cpp
+// Purpose: wxDropTarget, wxDropSource, wxDataObject implementation
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) 1998 Stefan Csomor
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "dnd.h"
+#endif
+
+#include "wx/defs.h"
+
+#if wxUSE_DRAG_AND_DROP
+
+#include "wx/dnd.h"
+#include "wx/window.h"
+#include "wx/toplevel.h"
+#include "wx/app.h"
+#include "wx/gdicmn.h"
+#include "wx/mac/private.h"
+
+// ----------------------------------------------------------------------------
+// global
+// ----------------------------------------------------------------------------
+
+void wxMacEnsureTrackingHandlersInstalled() ;
+
+typedef struct
+{
+ wxWindow* m_currentTargetWindow ;
+ wxDropTarget* m_currentTarget ;
+ wxDropSource* m_currentSource ;
+} MacTrackingGlobals ;
+
+MacTrackingGlobals gTrackingGlobals ;
+
+//----------------------------------------------------------------------------
+// wxDropTarget
+//----------------------------------------------------------------------------
+
+wxDropTarget::wxDropTarget( wxDataObject *data )
+ : wxDropTargetBase( data )
+{
+ wxMacEnsureTrackingHandlersInstalled() ;
+}
+
+wxDragResult wxDropTarget::OnDragOver( wxCoord WXUNUSED(x),
+ wxCoord WXUNUSED(y),
+ wxDragResult def )
+{
+
+ return CurrentDragHasSupportedFormat() ? def : wxDragNone;
+}
+
+bool wxDropTarget::OnDrop( wxCoord WXUNUSED(x), wxCoord WXUNUSED(y) )
+{
+ if (!m_dataObject)
+ return FALSE;
+
+ return CurrentDragHasSupportedFormat() ;
+}
+
+wxDragResult wxDropTarget::OnData( wxCoord WXUNUSED(x), wxCoord WXUNUSED(y),
+ wxDragResult def )
+{
+ if (!m_dataObject)
+ return wxDragNone;
+
+ if (!CurrentDragHasSupportedFormat())
+ return wxDragNone;
+
+ return GetData() ? def : wxDragNone;
+}
+
+bool wxDropTarget::CurrentDragHasSupportedFormat()
+{
+ bool supported = false ;
+ if ( gTrackingGlobals.m_currentSource != NULL )
+ {
+ wxDataObject* data = gTrackingGlobals.m_currentSource->GetDataObject() ;
+
+ if ( data )
+ {
+ size_t formatcount = data->GetFormatCount() ;
+ wxDataFormat *array = new wxDataFormat[ formatcount ];
+ data->GetAllFormats( array );
+ for (size_t i = 0; !supported && i < formatcount ; i++)
+ {
+ wxDataFormat format = array[i] ;
+ if ( m_dataObject->IsSupported( format ) )
+ {
+ supported = true ;
+ break ;
+ }
+ }
+ delete[] array ;
+ }
+ }
+ if ( !supported )
+ {
+ UInt16 items ;
+ OSErr result;
+ CountDragItems((DragReference)m_currentDrag, &items);
+ for (UInt16 index = 1; index <= items && supported == false ; ++index)
+ {
+ ItemReference theItem;
+ FlavorType theType ;
+ UInt16 flavors = 0 ;
+ GetDragItemReferenceNumber((DragReference)m_currentDrag, index, &theItem);
+ CountDragItemFlavors( (DragReference)m_currentDrag, theItem , &flavors ) ;
+ for ( UInt16 flavor = 1 ; flavor <= flavors ; ++flavor )
+ {
+ result = GetFlavorType((DragReference)m_currentDrag, theItem, flavor , &theType);
+ if ( m_dataObject->IsSupportedFormat( wxDataFormat( theType ) ) )
+ {
+ supported = true ;
+ break ;
+ }
+ }
+ }
+ }
+ return supported ;
+}
+
+bool wxDropTarget::GetData()
+{
+ if (!m_dataObject)
+ return FALSE;
+
+ if ( !CurrentDragHasSupportedFormat() )
+ return FALSE ;
+
+ bool transferred = false ;
+ if ( gTrackingGlobals.m_currentSource != NULL )
+ {
+ wxDataObject* data = gTrackingGlobals.m_currentSource->GetDataObject() ;
+
+ if ( data )
+ {
+ size_t formatcount = data->GetFormatCount() ;
+ wxDataFormat *array = new wxDataFormat[ formatcount ];
+ data->GetAllFormats( array );
+ for (size_t i = 0; !transferred && i < formatcount ; i++)
+ {
+ wxDataFormat format = array[i] ;
+ if ( m_dataObject->IsSupported( format ) )
+ {
+ int size = data->GetDataSize( format );
+ transferred = true ;
+
+ if (size == 0)
+ {
+ m_dataObject->SetData(format , 0 , 0 ) ;
+ }
+ else
+ {
+ char *d = new char[size];
+ data->GetDataHere( format , (void*) d );
+ m_dataObject->SetData( format , size , d ) ;
+ delete[] d ;
+ }
+ }
+ }
+ delete[] array ;
+ }
+ }
+ if ( !transferred )
+ {
+ UInt16 items ;
+ OSErr result;
+ bool firstFileAdded = false ;
+ CountDragItems((DragReference)m_currentDrag, &items);
+ for (UInt16 index = 1; index <= items; ++index)
+ {
+ ItemReference theItem;
+ FlavorType theType ;
+ UInt16 flavors = 0 ;
+ GetDragItemReferenceNumber((DragReference)m_currentDrag, index, &theItem);
+ CountDragItemFlavors( (DragReference)m_currentDrag, theItem , &flavors ) ;
+ for ( UInt16 flavor = 1 ; flavor <= flavors ; ++flavor )
+ {
+ result = GetFlavorType((DragReference)m_currentDrag, theItem, flavor , &theType);
+ wxDataFormat format(theType) ;
+ if ( m_dataObject->IsSupportedFormat( format ) )
+ {
+ FlavorFlags theFlags;
+ result = GetFlavorFlags((DragReference)m_currentDrag, theItem, theType, &theFlags);
+ if (result == noErr)
+ {
+ Size dataSize ;
+ Ptr theData ;
+ GetFlavorDataSize((DragReference)m_currentDrag, theItem, theType, &dataSize);
+ if ( theType == 'TEXT' )
+ {
+ // this increment is only valid for allocating, on the next GetFlavorData
+ // call it is reset again to the original value
+ dataSize++ ;
+ }
+ theData = new char[dataSize];
+ GetFlavorData((DragReference)m_currentDrag, theItem, theType, (void*) theData, &dataSize, 0L);
+ if( theType == 'TEXT' )
+ {
+ theData[dataSize]=0 ;
+ wxString convert( theData , wxConvLocal ) ;
+ m_dataObject->SetData( format, convert.Length() * sizeof(wxChar), (const wxChar*) convert );
+ }
+ else if ( theType == kDragFlavorTypeHFS )
+ {
+ HFSFlavor* theFile = (HFSFlavor*) theData ;
+ wxString name = wxMacFSSpec2MacFilename( &theFile->fileSpec ) ;
+ if ( firstFileAdded )
+ ((wxFileDataObject*)m_dataObject)->AddFile( name ) ;
+ else
+ {
+ ((wxFileDataObject*)m_dataObject)->SetData( 0 , name.c_str() ) ;
+ firstFileAdded = true ;
+ }
+ }
+ else
+ {
+ m_dataObject->SetData( format, dataSize, theData );
+ }
+ delete[] theData;
+ }
+ break ;
+ }
+ }
+ }
+ }
+ return TRUE ;
+}
+
+//-------------------------------------------------------------------------
+// wxDropSource
+//-------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// drag request
+
+wxDropSource::wxDropSource(wxWindow *win,
+ const wxCursor &cursorCopy,
+ const wxCursor &cursorMove,
+ const wxCursor &cursorStop)
+ : wxDropSourceBase(cursorCopy, cursorMove, cursorStop)
+{
+ wxMacEnsureTrackingHandlersInstalled() ;
+ m_window = win;
+}
+
+wxDropSource::wxDropSource(wxDataObject& data,
+ wxWindow *win,
+ const wxCursor &cursorCopy,
+ const wxCursor &cursorMove,
+ const wxCursor &cursorStop)
+ : wxDropSourceBase(cursorCopy, cursorMove, cursorStop)
+{
+ wxMacEnsureTrackingHandlersInstalled() ;
+ SetData( data );
+ m_window = win;
+}
+
+wxDropSource::~wxDropSource()
+{
+}
+
+
+wxDragResult wxDropSource::DoDragDrop(int WXUNUSED(flags))
+{
+ wxASSERT_MSG( m_data, wxT("Drop source: no data") );
+
+ if (!m_data)
+ return (wxDragResult) wxDragNone;
+
+ if (m_data->GetFormatCount() == 0)
+ return (wxDragResult) wxDragNone;
+
+ OSErr result;
+ DragReference theDrag;
+ RgnHandle dragRegion;
+ if ((result = NewDrag(&theDrag)))
+ {
+ return wxDragNone ;
+ }
+ // add data to drag
+ size_t formatCount = m_data->GetFormatCount() ;
+ wxDataFormat *formats = new wxDataFormat[formatCount] ;
+ m_data->GetAllFormats( formats ) ;
+ ItemReference theItem = 1 ;
+ for ( size_t i = 0 ; i < formatCount ; ++i )
+ {
+ size_t dataSize = m_data->GetDataSize( formats[i] ) ;
+ Ptr dataPtr = new char[dataSize] ;
+ m_data->GetDataHere( formats[i] , dataPtr ) ;
+ OSType type = formats[i].GetFormatId() ;
+ if ( type == 'TEXT' )
+ {
+ dataSize-- ;
+ dataPtr[ dataSize ] = 0 ;
+ wxString st( (wxChar*) dataPtr ) ;
+ wxCharBuffer buf = st.mb_str( wxConvLocal) ;
+ AddDragItemFlavor(theDrag, theItem, type , buf.data(), strlen(buf), 0);
+ }
+ else if (type == kDragFlavorTypeHFS )
+ {
+ HFSFlavor theFlavor ;
+ OSErr err = noErr;
+ CInfoPBRec cat;
+
+ wxMacFilename2FSSpec( dataPtr , &theFlavor.fileSpec ) ;
+
+ cat.hFileInfo.ioNamePtr = theFlavor.fileSpec.name;
+ cat.hFileInfo.ioVRefNum = theFlavor.fileSpec.vRefNum;
+ cat.hFileInfo.ioDirID = theFlavor.fileSpec.parID;
+ cat.hFileInfo.ioFDirIndex = 0;
+ err = PBGetCatInfoSync(&cat);
+ if (err == noErr )
+ {
+ theFlavor.fdFlags = cat.hFileInfo.ioFlFndrInfo.fdFlags;
+ if (theFlavor.fileSpec.parID == fsRtParID) {
+ theFlavor.fileCreator = 'MACS';
+ theFlavor.fileType = 'disk';
+ } else if ((cat.hFileInfo.ioFlAttrib & ioDirMask) != 0) {
+ theFlavor.fileCreator = 'MACS';
+ theFlavor.fileType = 'fold';
+ } else {
+ theFlavor.fileCreator = cat.hFileInfo.ioFlFndrInfo.fdCreator;
+ theFlavor.fileType = cat.hFileInfo.ioFlFndrInfo.fdType;
+ }
+ AddDragItemFlavor(theDrag, theItem, type , &theFlavor, sizeof(theFlavor), 0);
+ }
+ }
+ else
+ {
+ AddDragItemFlavor(theDrag, theItem, type , dataPtr, dataSize, 0);
+ }
+ delete[] dataPtr ;
+ }
+ delete[] formats ;
+
+ dragRegion = NewRgn();
+ RgnHandle tempRgn = NewRgn() ;
+
+ EventRecord* ev = NULL ;
+#if !TARGET_CARBON // TODO
+ ev = (EventRecord*) wxTheApp->MacGetCurrentEvent() ;
+#else
+ EventRecord rec ;
+ ev = &rec ;
+ wxMacConvertEventToRecord( (EventRef) wxTheApp->MacGetCurrentEvent() , &rec ) ;
+#endif
+ const short dragRegionOuterBoundary = 10 ;
+ const short dragRegionInnerBoundary = 9 ;
+
+ SetRectRgn( dragRegion , ev->where.h - dragRegionOuterBoundary ,
+ ev->where.v - dragRegionOuterBoundary ,
+ ev->where.h + dragRegionOuterBoundary ,
+ ev->where.v + dragRegionOuterBoundary ) ;
+
+ SetRectRgn( tempRgn , ev->where.h - dragRegionInnerBoundary ,
+ ev->where.v - dragRegionInnerBoundary ,
+ ev->where.h + dragRegionInnerBoundary ,
+ ev->where.v + dragRegionInnerBoundary ) ;
+
+ DiffRgn( dragRegion , tempRgn , dragRegion ) ;
+ DisposeRgn( tempRgn ) ;
+
+ // TODO:work with promises in order to return data only when drag
+ // was successfully completed
+
+ gTrackingGlobals.m_currentSource = this ;
+ result = TrackDrag(theDrag, ev , dragRegion);
+ DisposeRgn(dragRegion);
+ DisposeDrag(theDrag);
+ gTrackingGlobals.m_currentSource = NULL ;
+
+ KeyMap keymap;
+ GetKeys(keymap);
+ bool optionDown = keymap[1] & 4;
+ wxDragResult dndresult = optionDown ? wxDragCopy : wxDragMove;
+ return dndresult;
+}
+
+bool wxDropSource::MacInstallDefaultCursor(wxDragResult effect)
+{
+ const wxCursor& cursor = GetCursor(effect);
+ if ( cursor.Ok() )
+ {
+ cursor.MacInstall() ;
+
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+bool gTrackingGlobalsInstalled = false ;
+
+// passing the globals via refcon is not needed by the CFM and later architectures anymore
+// but I'll leave it in there, just in case...
+
+pascal OSErr wxMacWindowDragTrackingHandler(DragTrackingMessage theMessage, WindowPtr theWindow,
+ void *handlerRefCon, DragReference theDrag) ;
+pascal OSErr wxMacWindowDragReceiveHandler(WindowPtr theWindow, void *handlerRefCon,
+DragReference theDrag) ;
+
+void wxMacEnsureTrackingHandlersInstalled()
+{
+ if( !gTrackingGlobalsInstalled )
+ {
+ OSErr result;
+
+ result = InstallTrackingHandler(NewDragTrackingHandlerUPP(wxMacWindowDragTrackingHandler), 0L,&gTrackingGlobals);
+ wxASSERT( result == noErr ) ;
+ result = InstallReceiveHandler(NewDragReceiveHandlerUPP(wxMacWindowDragReceiveHandler), 0L, &gTrackingGlobals);
+ wxASSERT( result == noErr ) ;
+
+ gTrackingGlobalsInstalled = true ;
+ }
+}
+
+pascal OSErr wxMacWindowDragTrackingHandler(DragTrackingMessage theMessage, WindowPtr theWindow,
+ void *handlerRefCon, DragReference theDrag)
+{
+ MacTrackingGlobals* trackingGlobals = (MacTrackingGlobals*) handlerRefCon;
+ Point mouse, localMouse;
+ DragAttributes attributes;
+ GetDragAttributes(theDrag, &attributes);
+ wxTopLevelWindowMac* toplevel = wxFindWinFromMacWindow( theWindow ) ;
+
+ KeyMap keymap;
+ GetKeys(keymap);
+ bool optionDown = keymap[1] & 4;
+ wxDragResult result = optionDown ? wxDragCopy : wxDragMove;
+
+ switch(theMessage)
+ {
+ case kDragTrackingEnterHandler:
+ break;
+ case kDragTrackingLeaveHandler:
+ break;
+ case kDragTrackingEnterWindow:
+ trackingGlobals->m_currentTargetWindow = NULL ;
+ trackingGlobals->m_currentTarget = NULL ;
+ break;
+ case kDragTrackingInWindow:
+ if (toplevel == NULL)
+ break;
+
+ GetDragMouse(theDrag, &mouse, 0L);
+ localMouse = mouse;
+ GlobalToLocal(&localMouse);
+
+
+
+// if (attributes & kDragHasLeftSenderWindow)
+ {
+ wxPoint point(localMouse.h , localMouse.v) ;
+ wxWindow *win = NULL ;
+ toplevel->MacGetWindowFromPointSub( point , &win ) ;
+ int localx , localy ;
+ localx = localMouse.h ;
+ localy = localMouse.v ;
+ //TODO : should we use client coordinates
+ if ( win )
+ win->MacRootWindowToWindow( &localx , &localy ) ;
+ if ( win != trackingGlobals->m_currentTargetWindow )
+ {
+ if ( trackingGlobals->m_currentTargetWindow )
+ {
+ // this window is left
+ if ( trackingGlobals->m_currentTarget )
+ {
+ HideDragHilite(theDrag);
+ trackingGlobals->m_currentTarget->SetCurrentDrag( theDrag ) ;
+ trackingGlobals->m_currentTarget->OnLeave() ;
+ trackingGlobals->m_currentTarget = NULL;
+ trackingGlobals->m_currentTargetWindow = NULL ;
+ }
+ }
+ if ( win )
+ {
+ // this window is entered
+ trackingGlobals->m_currentTargetWindow = win ;
+ trackingGlobals->m_currentTarget = win->GetDropTarget() ;
+ {
+
+ if ( trackingGlobals->m_currentTarget )
+ {
+ trackingGlobals->m_currentTarget->SetCurrentDrag( theDrag ) ;
+ result = trackingGlobals->m_currentTarget->OnEnter(
+ localx , localy , result ) ;
+ }
+
+
+ if ( result != wxDragNone )
+ {
+ int x , y ;
+ x = y = 0 ;
+ win->MacWindowToRootWindow( &x , &y ) ;
+ RgnHandle hiliteRgn = NewRgn() ;
+ SetRectRgn( hiliteRgn , x , y , x+win->GetSize().x ,y+win->GetSize().y) ;
+ ShowDragHilite(theDrag, hiliteRgn, true);
+ DisposeRgn( hiliteRgn ) ;
+ }
+ }
+ }
+ }
+ else
+ {
+ if( trackingGlobals->m_currentTarget )
+ {
+ trackingGlobals->m_currentTarget->SetCurrentDrag( theDrag ) ;
+ trackingGlobals->m_currentTarget->OnDragOver(
+ localx , localy , result ) ;
+ }
+ }
+
+ // set cursor for OnEnter and OnDragOver
+ if ( trackingGlobals->m_currentSource && trackingGlobals->m_currentSource->GiveFeedback( result ) == FALSE )
+ {
+ if ( trackingGlobals->m_currentSource->MacInstallDefaultCursor( result ) == FALSE )
+ {
+ switch( result )
+ {
+ case wxDragCopy :
+ {
+ wxCursor cursor(wxCURSOR_COPY_ARROW) ;
+ cursor.MacInstall() ;
+ }
+ break ;
+ case wxDragMove :
+ {
+ wxCursor cursor(wxCURSOR_ARROW) ;
+ cursor.MacInstall() ;
+ }
+ break ;
+ case wxDragNone :
+ {
+ wxCursor cursor(wxCURSOR_NO_ENTRY) ;
+ cursor.MacInstall() ;
+ }
+ break ;
+
+ case wxDragError:
+ case wxDragLink:
+ case wxDragCancel:
+ // put these here to make gcc happy
+ ;
+ }
+ }
+ }
+
+ }
+ // MyTrackItemUnderMouse(localMouse, theWindow);
+ break;
+ case kDragTrackingLeaveWindow:
+ if (trackingGlobals->m_currentTarget)
+ {
+ trackingGlobals->m_currentTarget->SetCurrentDrag( theDrag ) ;
+ trackingGlobals->m_currentTarget->OnLeave() ;
+ HideDragHilite(theDrag);
+ trackingGlobals->m_currentTarget = NULL ;
+ }
+ trackingGlobals->m_currentTargetWindow = NULL ;
+ break;
+ }
+ return(noErr);
+}
+
+pascal OSErr wxMacWindowDragReceiveHandler(WindowPtr theWindow,
+ void *handlerRefCon,
+ DragReference theDrag)
+{
+ MacTrackingGlobals* trackingGlobals = (MacTrackingGlobals*) handlerRefCon;
+ if ( trackingGlobals->m_currentTarget )
+ {
+ Point mouse,localMouse ;
+ int localx,localy ;
+
+ trackingGlobals->m_currentTarget->SetCurrentDrag( theDrag ) ;
+ GetDragMouse(theDrag, &mouse, 0L);
+ localMouse = mouse;
+ GlobalToLocal(&localMouse);
+ localx = localMouse.h ;
+ localy = localMouse.v ;
+ //TODO : should we use client coordinates
+ if ( trackingGlobals->m_currentTargetWindow )
+ trackingGlobals->m_currentTargetWindow->MacRootWindowToWindow( &localx , &localy ) ;
+ if ( trackingGlobals->m_currentTarget->OnDrop( localx , localy ) )
+ {
+ KeyMap keymap;
+ GetKeys(keymap);
+ bool optionDown = keymap[1] & 4;
+ wxDragResult result = optionDown ? wxDragCopy : wxDragMove;
+ trackingGlobals->m_currentTarget->OnData( localx , localy , result ) ;
+ }
+ }
+ return(noErr);
+}
+#endif
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: filedlg.cpp
+// Purpose: wxFileDialog
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "filedlg.h"
+#endif
+
+#include "wx/defs.h"
+#include "wx/app.h"
+#include "wx/utils.h"
+#include "wx/dialog.h"
+#include "wx/filedlg.h"
+#include "wx/intl.h"
+#include "wx/tokenzr.h"
+#include "wx/filename.h"
+
+#ifndef __DARWIN__
+ #include "PLStringFuncs.h"
+#endif
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_CLASS(wxFileDialog, wxFileDialogBase)
+#endif
+
+// begin wxmac
+
+#include "wx/mac/private.h"
+
+#include <Navigation.h>
+
+#ifdef __DARWIN__
+# include "MoreFilesX.h"
+#else
+# include "MoreFiles.h"
+# include "MoreFilesExtras.h"
+#endif
+
+extern bool gUseNavServices ;
+
+// the data we need to pass to our standard file hook routine
+// includes a pointer to the dialog, a pointer to the standard
+// file reply record (so we can inspect the current selection)
+// and a copy of the "previous" file spec of the reply record
+// so we can see if the selection has changed
+
+struct OpenUserDataRec {
+ int currentfilter ;
+ bool saveMode ;
+ wxArrayString name ;
+ wxArrayString extensions ;
+ wxArrayLong filtermactypes ;
+ wxString defaultLocation;
+#if TARGET_CARBON
+ CFArrayRef menuitems ;
+#else
+ NavMenuItemSpecArrayHandle menuitems ;
+#endif
+};
+
+typedef struct OpenUserDataRec
+OpenUserDataRec, *OpenUserDataRecPtr;
+
+static pascal void NavEventProc(
+ NavEventCallbackMessage inSelector,
+ NavCBRecPtr ioParams,
+ NavCallBackUserData ioUserData);
+
+#if TARGET_CARBON
+ static NavEventUPP sStandardNavEventFilter = NewNavEventUPP(NavEventProc);
+#else
+ static NavEventUPP sStandardNavEventFilter = NewNavEventProc(NavEventProc);
+#endif
+
+static pascal void
+NavEventProc(
+ NavEventCallbackMessage inSelector,
+ NavCBRecPtr ioParams,
+ NavCallBackUserData ioUserData )
+{
+ OpenUserDataRec * data = ( OpenUserDataRec *) ioUserData ;
+ if (inSelector == kNavCBEvent) {
+#if TARGET_CARBON
+#else
+ wxTheApp->MacHandleOneEvent(ioParams->eventData.eventDataParms.event);
+#endif
+ }
+ else if ( inSelector == kNavCBStart )
+ {
+#if TARGET_CARBON
+ if (data && !(data->defaultLocation).IsEmpty())
+ {
+ // Set default location for the modern Navigation APIs
+ // Apple Technical Q&A 1151
+ FSSpec theFSSpec;
+ wxMacFilename2FSSpec(data->defaultLocation, &theFSSpec);
+ AEDesc theLocation = {typeNull, NULL};
+ if (noErr == ::AECreateDesc(typeFSS, &theFSSpec, sizeof(FSSpec), &theLocation))
+ ::NavCustomControl(ioParams->context, kNavCtlSetLocation, (void *) &theLocation);
+ }
+#else
+ if ( data->menuitems )
+ NavCustomControl(ioParams->context, kNavCtlSelectCustomType, &(*data->menuitems)[data->currentfilter]);
+#endif
+ }
+ else if ( inSelector == kNavCBPopupMenuSelect )
+ {
+ NavMenuItemSpec * menu = (NavMenuItemSpec *) ioParams->eventData.eventDataParms.param ;
+#if TARGET_CARBON
+#else
+ if ( menu->menuCreator == 'WXNG' )
+#endif
+ {
+ data->currentfilter = menu->menuType ;
+ if ( data->saveMode )
+ {
+ int i = menu->menuType ;
+ wxString extension = data->extensions[i].AfterLast('.') ;
+ extension.MakeLower() ;
+ wxString sfilename ;
+
+#if TARGET_CARBON
+ wxMacCFStringHolder cfString( NavDialogGetSaveFileName( ioParams->context ) , false );
+ sfilename = cfString.AsString() ;
+#else
+ Str255 filename ;
+ // get the current filename
+ NavCustomControl(ioParams->context, kNavCtlGetEditFileName, &filename);
+ sfilename = wxMacMakeStringFromPascal( filename ) ;
+#endif
+
+ int pos = sfilename.Find('.', true) ;
+ if ( pos != wxNOT_FOUND )
+ {
+ sfilename = sfilename.Left(pos+1)+extension ;
+#if TARGET_CARBON
+ cfString.Assign( sfilename , wxFONTENCODING_DEFAULT ) ;
+ NavDialogSetSaveFileName( ioParams->context , cfString ) ;
+#else
+ wxMacStringToPascal( sfilename , filename ) ;
+ NavCustomControl(ioParams->context, kNavCtlSetEditFileName, &filename);
+#endif
+ }
+ }
+ }
+ }
+}
+
+
+void MakeUserDataRec(OpenUserDataRec *myData , const wxString& filter )
+{
+ myData->menuitems = NULL ;
+ myData->currentfilter = 0 ;
+ myData->saveMode = false ;
+
+ if ( filter && filter[0] )
+ {
+ wxString filter2(filter) ;
+ int filterIndex = 0;
+ bool isName = true ;
+ wxString current ;
+ for( unsigned int i = 0; i < filter2.Len() ; i++ )
+ {
+ if( filter2.GetChar(i) == wxT('|') )
+ {
+ if( isName ) {
+ myData->name.Add( current ) ;
+ }
+ else {
+ myData->extensions.Add( current.MakeUpper() ) ;
+ ++filterIndex ;
+ }
+ isName = !isName ;
+ current = wxEmptyString ;
+ }
+ else
+ {
+ current += filter2.GetChar(i) ;
+ }
+ }
+ // we allow for compatibility reason to have a single filter expression (like *.*) without
+ // an explanatory text, in that case the first part is name and extension at the same time
+
+ wxASSERT_MSG( filterIndex == 0 || !isName , wxT("incorrect format of format string") ) ;
+ if ( current.IsEmpty() )
+ myData->extensions.Add( myData->name[filterIndex] ) ;
+ else
+ myData->extensions.Add( current.MakeUpper() ) ;
+ if ( filterIndex == 0 || isName )
+ myData->name.Add( current.MakeUpper() ) ;
+
+ ++filterIndex ;
+
+ const size_t extCount = myData->extensions.GetCount();
+ for ( size_t i = 0 ; i < extCount; i++ )
+ {
+ wxUint32 fileType;
+ wxUint32 creator;
+ wxString extension = myData->extensions[i];
+
+ if (extension.GetChar(0) == '*')
+ extension = extension.Mid(1); // Remove leading *
+
+ if (extension.GetChar(0) == '.')
+ {
+ extension = extension.Mid(1); // Remove leading .
+ }
+
+ if (wxFileName::MacFindDefaultTypeAndCreator( extension, &fileType, &creator ))
+ {
+ myData->filtermactypes.Add( (OSType)fileType );
+ }
+ else
+ {
+ myData->filtermactypes.Add( '****' ) ; // We'll fail safe if it's not recognized
+ }
+ }
+ }
+}
+
+static Boolean CheckFile( const wxString &filename , OSType type , OpenUserDataRecPtr data)
+{
+ wxString file(filename) ;
+ file.MakeUpper() ;
+
+ if ( data->extensions.GetCount() > 0 )
+ {
+ //for ( int i = 0 ; i < data->numfilters ; ++i )
+ int i = data->currentfilter ;
+ if ( data->extensions[i].Right(2) == wxT(".*") )
+ return true ;
+
+ {
+ if ( type == (OSType)data->filtermactypes[i] )
+ return true ;
+
+ wxStringTokenizer tokenizer( data->extensions[i] , wxT(";") ) ;
+ while( tokenizer.HasMoreTokens() )
+ {
+ wxString extension = tokenizer.GetNextToken() ;
+ if ( extension.GetChar(0) == '*' )
+ extension = extension.Mid(1) ;
+
+ if ( file.Len() >= extension.Len() && extension == file.Right(extension.Len() ) )
+ return true ;
+ }
+ }
+ return false ;
+ }
+ return true ;
+}
+
+#ifndef __DARWIN__
+static pascal Boolean CrossPlatformFileFilter(CInfoPBPtr myCInfoPBPtr, void *dataPtr)
+{
+ OpenUserDataRecPtr data = (OpenUserDataRecPtr) dataPtr ;
+ // return true if this item is invisible or a file
+
+ Boolean visibleFlag;
+ Boolean folderFlag;
+
+ visibleFlag = ! (myCInfoPBPtr->hFileInfo.ioFlFndrInfo.fdFlags & kIsInvisible);
+ folderFlag = (myCInfoPBPtr->hFileInfo.ioFlAttrib & 0x10);
+
+ // because the semantics of the filter proc are "true means don't show
+ // it" we need to invert the result that we return
+
+ if ( !visibleFlag )
+ return true ;
+
+ if ( !folderFlag )
+ {
+ wxString file = wxMacMakeStringFromPascal( myCInfoPBPtr->hFileInfo.ioNamePtr ) ;
+ return !CheckFile( file , myCInfoPBPtr->hFileInfo.ioFlFndrInfo.fdType , data ) ;
+ }
+
+ return false ;
+}
+#endif
+
+// end wxmac
+
+wxFileDialog::wxFileDialog(wxWindow *parent, const wxString& message,
+ const wxString& defaultDir, const wxString& defaultFileName, const wxString& wildCard,
+ long style, const wxPoint& pos)
+ :wxFileDialogBase(parent, message, defaultDir, defaultFileName, wildCard, style, pos)
+{
+ wxASSERT_MSG( NavServicesAvailable() , wxT("Navigation Services are not running") ) ;
+}
+
+pascal Boolean CrossPlatformFilterCallback (
+ AEDesc *theItem,
+ void *info,
+ void *callBackUD,
+ NavFilterModes filterMode
+)
+{
+ bool display = true;
+ OpenUserDataRecPtr data = (OpenUserDataRecPtr) callBackUD ;
+
+ if (filterMode == kNavFilteringBrowserList)
+ {
+ NavFileOrFolderInfo* theInfo = (NavFileOrFolderInfo*) info ;
+ if ( !theInfo->isFolder )
+ {
+ if (theItem->descriptorType == typeFSS )
+ {
+ FSSpec spec;
+ memcpy( &spec , *theItem->dataHandle , sizeof(FSSpec) ) ;
+ wxString file = wxMacMakeStringFromPascal( spec.name ) ;
+ display = CheckFile( file , theInfo->fileAndFolder.fileInfo.finderInfo.fdType , data ) ;
+ }
+ #if TARGET_CARBON
+ else if ( theItem->descriptorType == typeFSRef )
+ {
+ FSRef fsref ;
+ memcpy( &fsref , *theItem->dataHandle , sizeof(FSRef) ) ;
+
+
+
+ CFURLRef fullURLRef;
+ fullURLRef = ::CFURLCreateFromFSRef(NULL, &fsref);
+#ifdef __UNIX__
+ CFURLPathStyle pathstyle = kCFURLPOSIXPathStyle;
+#else
+ CFURLPathStyle pathstyle = kCFURLHFSPathStyle;
+#endif
+ CFStringRef cfString = CFURLCopyFileSystemPath(fullURLRef, pathstyle);
+ ::CFRelease( fullURLRef ) ;
+ wxString file = wxMacCFStringHolder(cfString).AsString(wxFont::GetDefaultEncoding());
+
+ display = CheckFile( file , theInfo->fileAndFolder.fileInfo.finderInfo.fdType , data ) ;
+ }
+#endif
+ }
+ }
+
+ return display;
+}
+
+int wxFileDialog::ShowModal()
+{
+#if TARGET_CARBON
+ OSErr err;
+ NavDialogCreationOptions dialogCreateOptions;
+ // set default options
+ ::NavGetDefaultDialogCreationOptions(&dialogCreateOptions);
+
+ // this was always unset in the old code
+ dialogCreateOptions.optionFlags &= ~kNavSelectDefaultLocation;
+
+ wxMacCFStringHolder message(m_message, m_font.GetEncoding());
+ dialogCreateOptions.windowTitle = message;
+
+ wxMacCFStringHolder defaultFileName(m_fileName, m_font.GetEncoding());
+ dialogCreateOptions.saveFileName = defaultFileName;
+
+
+ NavDialogRef dialog;
+ NavObjectFilterUPP navFilterUPP = NULL;
+ CFArrayRef cfArray = NULL; // for popupExtension
+ OpenUserDataRec myData;
+ myData.defaultLocation = m_dir;
+
+ if (m_dialogStyle & wxSAVE)
+ {
+ dialogCreateOptions.optionFlags |= kNavNoTypePopup;
+ dialogCreateOptions.optionFlags |= kNavDontAutoTranslate;
+ dialogCreateOptions.optionFlags |= kNavDontAddTranslateItems;
+
+ // The extension is important
+ dialogCreateOptions.optionFlags |= kNavPreserveSaveFileExtension;
+
+ err = ::NavCreatePutFileDialog(&dialogCreateOptions,
+ 'TEXT',
+ 'TEXT',
+ sStandardNavEventFilter,
+ &myData, // for defaultLocation
+ &dialog);
+ }
+ else
+ {
+ MakeUserDataRec(&myData , m_wildCard);
+ size_t numfilters = myData.extensions.GetCount();
+ if (numfilters > 0)
+ {
+ CFMutableArrayRef popup = CFArrayCreateMutable( kCFAllocatorDefault ,
+ numfilters , &kCFTypeArrayCallBacks ) ;
+ dialogCreateOptions.popupExtension = popup ;
+ myData.menuitems = dialogCreateOptions.popupExtension ;
+ for ( size_t i = 0 ; i < numfilters ; ++i )
+ {
+ CFArrayAppendValue( popup , (CFStringRef) wxMacCFStringHolder( myData.name[i] , m_font.GetEncoding() ) ) ;
+ }
+ }
+
+ navFilterUPP = NewNavObjectFilterUPP(CrossPlatformFilterCallback);
+ err = ::NavCreateGetFileDialog(&dialogCreateOptions,
+ NULL, // NavTypeListHandle
+ sStandardNavEventFilter,
+ NULL, // NavPreviewUPP
+ navFilterUPP,
+ (void *) &myData, // inClientData
+ &dialog);
+ }
+
+ if (err == noErr)
+ err = ::NavDialogRun(dialog);
+
+ // clean up filter related data, etc.
+ if (navFilterUPP)
+ ::DisposeNavObjectFilterUPP(navFilterUPP);
+ if (cfArray)
+ ::CFRelease(cfArray);
+
+ if (err != noErr)
+ return wxID_CANCEL;
+
+ NavReplyRecord navReply;
+ err = ::NavDialogGetReply(dialog, &navReply);
+ if (err == noErr && navReply.validRecord)
+ {
+ AEKeyword theKeyword;
+ DescType actualType;
+ Size actualSize;
+ FSRef theFSRef;
+ wxString thePath ;
+ long count;
+ ::AECountItems(&navReply.selection , &count);
+ for (long i = 1; i <= count; ++i)
+ {
+ err = ::AEGetNthPtr(&(navReply.selection), i, typeFSRef, &theKeyword, &actualType,
+ &theFSRef, sizeof(theFSRef), &actualSize);
+ if (err != noErr)
+ break;
+
+ CFURLRef fullURLRef;
+ if (m_dialogStyle & wxSAVE)
+ {
+ CFURLRef parentURLRef = ::CFURLCreateFromFSRef(NULL, &theFSRef);
+
+ if (parentURLRef)
+ {
+ fullURLRef =
+ ::CFURLCreateCopyAppendingPathComponent(NULL,
+ parentURLRef,
+ navReply.saveFileName,
+ false);
+ ::CFRelease(parentURLRef);
+ }
+ }
+ else
+ {
+ fullURLRef = ::CFURLCreateFromFSRef(NULL, &theFSRef);
+ }
+#ifdef __UNIX__
+ CFURLPathStyle pathstyle = kCFURLPOSIXPathStyle;
+#else
+ CFURLPathStyle pathstyle = kCFURLHFSPathStyle;
+#endif
+ CFStringRef cfString = CFURLCopyFileSystemPath(fullURLRef, pathstyle);
+ thePath = wxMacCFStringHolder(cfString).AsString(m_font.GetEncoding());
+ if (!thePath)
+ {
+ ::NavDisposeReply(&navReply);
+ return wxID_CANCEL;
+ }
+ m_path = thePath;
+ m_paths.Add(m_path);
+ m_fileName = wxFileNameFromPath(m_path);
+ m_fileNames.Add(m_fileName);
+ }
+ // set these to the first hit
+ m_path = m_paths[0];
+ m_fileName = wxFileNameFromPath(m_path);
+ m_dir = wxPathOnly(m_path);
+ }
+ ::NavDisposeReply(&navReply);
+
+ return (err == noErr) ? wxID_OK : wxID_CANCEL;
+#else // TARGET_CARBON
+
+ NavDialogOptions mNavOptions;
+ NavObjectFilterUPP mNavFilterUPP = NULL;
+ NavPreviewUPP mNavPreviewUPP = NULL ;
+ NavReplyRecord mNavReply;
+ AEDesc mDefaultLocation ;
+ bool mSelectDefault = false ;
+ OSStatus err = noErr ;
+ // setup dialog
+
+ mNavFilterUPP = nil;
+ mNavPreviewUPP = nil;
+ mSelectDefault = false;
+ mDefaultLocation.descriptorType = typeNull;
+ mDefaultLocation.dataHandle = nil;
+
+ NavGetDefaultDialogOptions(&mNavOptions);
+ wxMacStringToPascal( m_message , (StringPtr)mNavOptions.message ) ;
+ wxMacStringToPascal( m_fileName , (StringPtr)mNavOptions.savedFileName ) ;
+
+ // Set default location, the location
+ // that's displayed when the dialog
+ // first appears
+
+ FSSpec location ;
+ wxMacFilename2FSSpec( m_dir , &location ) ;
+
+ err = ::AECreateDesc(typeFSS, &location, sizeof(FSSpec), &mDefaultLocation );
+
+ if ( mDefaultLocation.dataHandle )
+ {
+ if (mSelectDefault)
+ {
+ mNavOptions.dialogOptionFlags |= kNavSelectDefaultLocation;
+ } else {
+ mNavOptions.dialogOptionFlags &= ~kNavSelectDefaultLocation;
+ }
+ }
+
+ memset( &mNavReply , 0 , sizeof( mNavReply ) ) ;
+ mNavReply.validRecord = false;
+ mNavReply.replacing = false;
+ mNavReply.isStationery = false;
+ mNavReply.translationNeeded = false;
+ mNavReply.selection.descriptorType = typeNull;
+ mNavReply.selection.dataHandle = nil;
+ mNavReply.keyScript = smSystemScript;
+ mNavReply.fileTranslation = nil;
+ mNavReply.version = kNavReplyRecordVersion ;
+
+ // zero all data
+
+ m_path = wxEmptyString ;
+ m_fileName = wxEmptyString ;
+ m_paths.Empty();
+ m_fileNames.Empty();
+
+ OpenUserDataRec myData;
+ MakeUserDataRec( &myData , m_wildCard ) ;
+ myData.currentfilter = m_filterIndex ;
+ if ( myData.extensions.GetCount() > 0 )
+ {
+ mNavOptions.popupExtension = (NavMenuItemSpecArrayHandle) NewHandle( sizeof( NavMenuItemSpec ) * myData.extensions.GetCount() ) ;
+ myData.menuitems = mNavOptions.popupExtension ;
+ for ( size_t i = 0 ; i < myData.extensions.GetCount() ; ++i )
+ {
+ (*mNavOptions.popupExtension)[i].version = kNavMenuItemSpecVersion ;
+ (*mNavOptions.popupExtension)[i].menuCreator = 'WXNG' ;
+ // TODO : according to the new docs -1 to 10 are reserved for the OS
+ (*mNavOptions.popupExtension)[i].menuType = i ;
+ wxMacStringToPascal( myData.name[i] , (StringPtr)(*mNavOptions.popupExtension)[i].menuItemName ) ;
+ }
+ }
+ if ( m_dialogStyle & wxSAVE )
+ {
+ myData.saveMode = true ;
+
+ mNavOptions.dialogOptionFlags |= kNavDontAutoTranslate ;
+ mNavOptions.dialogOptionFlags |= kNavDontAddTranslateItems ;
+
+ err = ::NavPutFile(
+ &mDefaultLocation,
+ &mNavReply,
+ &mNavOptions,
+ sStandardNavEventFilter ,
+ NULL,
+ kNavGenericSignature,
+ &myData); // User Data
+ m_filterIndex = myData.currentfilter ;
+ }
+ else
+ {
+ myData.saveMode = false ;
+
+ mNavFilterUPP = NewNavObjectFilterUPP( CrossPlatformFilterCallback ) ;
+ if ( m_dialogStyle & wxMULTIPLE )
+ mNavOptions.dialogOptionFlags |= kNavAllowMultipleFiles ;
+ else
+ mNavOptions.dialogOptionFlags &= ~kNavAllowMultipleFiles ;
+
+ err = ::NavGetFile(
+ &mDefaultLocation,
+ &mNavReply,
+ &mNavOptions,
+ sStandardNavEventFilter ,
+ mNavPreviewUPP,
+ mNavFilterUPP,
+ NULL ,
+ &myData);
+ m_filterIndex = myData.currentfilter ;
+ }
+
+ DisposeNavObjectFilterUPP(mNavFilterUPP);
+ if ( mDefaultLocation.dataHandle != nil )
+ {
+ ::AEDisposeDesc(&mDefaultLocation);
+ }
+
+ if ( (err != noErr) && (err != userCanceledErr) ) {
+ return wxID_CANCEL ;
+ }
+
+ if (mNavReply.validRecord)
+ {
+ FSSpec outFileSpec ;
+ AEDesc specDesc ;
+ AEKeyword keyWord ;
+
+ long count ;
+ ::AECountItems( &mNavReply.selection , &count ) ;
+ for ( long i = 1 ; i <= count ; ++i )
+ {
+ OSErr err = ::AEGetNthDesc( &mNavReply.selection , i , typeFSS, &keyWord , &specDesc);
+ if ( err != noErr )
+ {
+ m_path = wxT("") ;
+ return wxID_CANCEL ;
+ }
+ outFileSpec = **(FSSpec**) specDesc.dataHandle;
+ if (specDesc.dataHandle != nil) {
+ ::AEDisposeDesc(&specDesc);
+ }
+ m_path = wxMacFSSpec2MacFilename( &outFileSpec ) ;
+
+ m_paths.Add( m_path ) ;
+ m_fileName = wxFileNameFromPath(m_path);
+ m_fileNames.Add(m_fileName);
+ }
+ // set these to the first hit
+ m_path = m_paths[ 0 ] ;
+ m_fileName = wxFileNameFromPath(m_path);
+ m_dir = wxPathOnly(m_path);
+ NavDisposeReply( &mNavReply ) ;
+ return wxID_OK ;
+ }
+ return wxID_CANCEL;
+#endif // TARGET_CARBON
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: font.cpp
+// Purpose: wxFont class
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "font.h"
+#endif
+
+#include "wx/defs.h"
+#include "wx/string.h"
+#include "wx/font.h"
+#include "wx/fontutil.h"
+#include "wx/gdicmn.h"
+#include "wx/utils.h"
+
+#include "wx/fontutil.h"
+
+#include "wx/mac/private.h"
+#include <ATSUnicode.h>
+
+#if !USE_SHARED_LIBRARIES
+IMPLEMENT_DYNAMIC_CLASS(wxFont, wxGDIObject)
+#endif
+
+class WXDLLEXPORT wxFontRefData: public wxGDIRefData
+{
+ friend class WXDLLEXPORT wxFont;
+public:
+ wxFontRefData()
+ : m_fontId(0)
+ , m_pointSize(10)
+ , m_family(wxDEFAULT)
+ , m_style(wxNORMAL)
+ , m_weight(wxNORMAL)
+ , m_underlined(FALSE)
+ , m_faceName(wxT("Geneva"))
+ , m_encoding(wxFONTENCODING_DEFAULT)
+ , m_macFontNum(0)
+ , m_macFontSize(0)
+ , m_macFontStyle(0)
+ , m_macATSUFontID()
+ {
+ Init(10, wxDEFAULT, wxNORMAL, wxNORMAL, FALSE,
+ wxT("Geneva"), wxFONTENCODING_DEFAULT);
+ }
+
+ wxFontRefData(const wxFontRefData& data)
+ : wxGDIRefData()
+ , m_fontId(data.m_fontId)
+ , m_pointSize(data.m_pointSize)
+ , m_family(data.m_family)
+ , m_style(data.m_style)
+ , m_weight(data.m_weight)
+ , m_underlined(data.m_underlined)
+ , m_faceName(data.m_faceName)
+ , m_encoding(data.m_encoding)
+ , m_macFontNum(data.m_macFontNum)
+ , m_macFontSize(data.m_macFontSize)
+ , m_macFontStyle(data.m_macFontStyle)
+ , m_macATSUFontID(data.m_macATSUFontID)
+ {
+ Init(data.m_pointSize, data.m_family, data.m_style, data.m_weight,
+ data.m_underlined, data.m_faceName, data.m_encoding);
+ }
+
+ wxFontRefData(int size,
+ int family,
+ int style,
+ int weight,
+ bool underlined,
+ const wxString& faceName,
+ wxFontEncoding encoding)
+ : m_fontId(0)
+ , m_pointSize(size)
+ , m_family(family)
+ , m_style(style)
+ , m_weight(weight)
+ , m_underlined(underlined)
+ , m_faceName(faceName)
+ , m_encoding(encoding)
+ , m_macFontNum(0)
+ , m_macFontSize(0)
+ , m_macFontStyle(0)
+ , m_macATSUFontID(0)
+ {
+ Init(size, family, style, weight, underlined, faceName, encoding);
+ }
+
+ virtual ~wxFontRefData();
+ void SetNoAntiAliasing( bool no = TRUE ) { m_noAA = no; }
+ bool GetNoAntiAliasing() { return m_noAA; }
+
+protected:
+ // common part of all ctors
+ void Init(int size,
+ int family,
+ int style,
+ int weight,
+ bool underlined,
+ const wxString& faceName,
+ wxFontEncoding encoding);
+
+ // font characterstics
+ int m_fontId;
+ int m_pointSize;
+ int m_family;
+ int m_style;
+ int m_weight;
+ bool m_underlined;
+ wxString m_faceName;
+ wxFontEncoding m_encoding;
+ bool m_noAA; // No anti-aliasing
+
+public:
+ short m_macFontNum;
+ short m_macFontSize;
+ unsigned char m_macFontStyle;
+ wxUint32 m_macATSUFontID;
+
+ wxNativeFontInfo m_info;
+
+public:
+ void MacFindFont() ;
+};
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxFontRefData
+// ----------------------------------------------------------------------------
+
+void wxFontRefData::Init(int pointSize,
+ int family,
+ int style,
+ int weight,
+ bool underlined,
+ const wxString& faceName,
+ wxFontEncoding encoding)
+{
+ m_style = style;
+ m_pointSize = pointSize;
+ m_family = family;
+ m_style = style;
+ m_weight = weight;
+ m_underlined = underlined;
+ m_faceName = faceName;
+ m_encoding = encoding;
+
+ m_macFontNum = 0 ;
+ m_macFontSize = 0;
+ m_macFontStyle = 0;
+ m_fontId = 0;
+ m_noAA = FALSE;
+}
+
+wxFontRefData::~wxFontRefData()
+{
+}
+
+void wxFontRefData::MacFindFont()
+{
+ if( m_faceName.Length() == 0 )
+ {
+ switch( m_family )
+ {
+ case wxDEFAULT :
+ m_macFontNum = ::GetAppFont() ;
+ break ;
+ case wxDECORATIVE :
+ ::GetFNum( "\pTimes" , &m_macFontNum) ;
+ break ;
+ case wxROMAN :
+ ::GetFNum( "\pTimes" , &m_macFontNum) ;
+ break ;
+ case wxSCRIPT :
+ ::GetFNum( "\pTimes" , &m_macFontNum) ;
+ break ;
+ case wxSWISS :
+ ::GetFNum( "\pGeneva" , &m_macFontNum) ;
+ break ;
+ case wxMODERN :
+ ::GetFNum( "\pMonaco" , &m_macFontNum) ;
+ break ;
+ }
+ Str255 name ;
+ GetFontName( m_macFontNum , name ) ;
+ m_faceName = wxMacMakeStringFromPascal( name ) ;
+ }
+ else
+ {
+ if ( m_faceName == wxT("systemfont") )
+ m_macFontNum = ::GetSysFont() ;
+ else if ( m_faceName == wxT("applicationfont") )
+ m_macFontNum = ::GetAppFont() ;
+ else
+ {
+ Str255 fontname ;
+ wxMacStringToPascal( m_faceName , fontname ) ;
+ ::GetFNum( fontname, &m_macFontNum);
+ }
+ }
+
+ m_macFontStyle = 0;
+ if (m_weight == wxBOLD)
+ m_macFontStyle |= bold;
+ if (m_style == wxITALIC || m_style == wxSLANT)
+ m_macFontStyle |= italic;
+ if (m_underlined)
+ m_macFontStyle |= underline;
+ m_macFontSize = m_pointSize ;
+
+ //TODO:if we supply the style as an additional parameter we must make a testing
+ //sequence in order to degrade gracefully while trying to maintain most of the style
+ //information, meanwhile we just take the normal font and apply the features after
+#ifdef __WXDEBUG__
+ OSStatus status =
+#endif // __WXDEBUG__
+ ::ATSUFONDtoFontID(m_macFontNum, normal /*qdStyle*/, (UInt32*)&m_macATSUFontID);
+ /*
+ status = ATSUFindFontFromName ( (Ptr) m_faceName , strlen( m_faceName ) ,
+ kFontFullName, kFontMacintoshPlatform, kFontRomanScript , kFontNoLanguage , (UInt32*)&m_macATSUFontID ) ;
+ */
+ wxASSERT_MSG( status == noErr , wxT("couldn't retrieve font identifier") ) ;
+}
+
+// ----------------------------------------------------------------------------
+// wxFont
+// ----------------------------------------------------------------------------
+
+void wxFont::Init()
+{
+}
+
+bool wxFont::Create(const wxNativeFontInfo& info)
+{
+ return Create(info.pointSize, info.family, info.style, info.weight,
+ info.underlined, info.faceName, info.encoding);
+}
+
+wxFont::wxFont(const wxString& fontdesc)
+{
+ wxNativeFontInfo info;
+ if ( info.FromString(fontdesc) )
+ (void)Create(info);
+}
+
+bool wxFont::Create(int pointSize,
+ int family,
+ int style,
+ int weight,
+ bool underlined,
+ const wxString& faceName,
+ wxFontEncoding encoding)
+{
+ UnRef();
+ m_refData = new wxFontRefData(pointSize, family, style, weight,
+ underlined, faceName, encoding);
+
+ RealizeResource();
+
+ return TRUE;
+}
+
+wxFont::~wxFont()
+{
+}
+
+bool wxFont::RealizeResource()
+{
+ M_FONTDATA->MacFindFont() ;
+ return TRUE;
+}
+
+void wxFont::SetEncoding(wxFontEncoding encoding)
+{
+ Unshare();
+
+ M_FONTDATA->m_encoding = encoding;
+
+ RealizeResource();
+}
+
+void wxFont::Unshare()
+{
+ // Don't change shared data
+ if (!m_refData)
+ {
+ m_refData = new wxFontRefData();
+ }
+ else
+ {
+ wxFontRefData* ref = new wxFontRefData(*(wxFontRefData*)m_refData);
+ UnRef();
+ m_refData = ref;
+ }
+}
+
+void wxFont::SetPointSize(int pointSize)
+{
+ Unshare();
+
+ M_FONTDATA->m_pointSize = pointSize;
+
+ RealizeResource();
+}
+
+void wxFont::SetFamily(int family)
+{
+ Unshare();
+
+ M_FONTDATA->m_family = family;
+
+ RealizeResource();
+}
+
+void wxFont::SetStyle(int style)
+{
+ Unshare();
+
+ M_FONTDATA->m_style = style;
+
+ RealizeResource();
+}
+
+void wxFont::SetWeight(int weight)
+{
+ Unshare();
+
+ M_FONTDATA->m_weight = weight;
+
+ RealizeResource();
+}
+
+void wxFont::SetFaceName(const wxString& faceName)
+{
+ Unshare();
+
+ M_FONTDATA->m_faceName = faceName;
+
+ RealizeResource();
+}
+
+void wxFont::SetUnderlined(bool underlined)
+{
+ Unshare();
+
+ M_FONTDATA->m_underlined = underlined;
+
+ RealizeResource();
+}
+
+void wxFont::SetNoAntiAliasing( bool no )
+{
+ Unshare();
+
+ M_FONTDATA->SetNoAntiAliasing( no );
+
+ RealizeResource();
+}
+
+// ----------------------------------------------------------------------------
+// accessors
+// ----------------------------------------------------------------------------
+
+// TODO: insert checks everywhere for M_FONTDATA == NULL!
+
+int wxFont::GetPointSize() const
+{
+ return M_FONTDATA->m_pointSize;
+}
+
+int wxFont::GetFamily() const
+{
+ return M_FONTDATA->m_family;
+}
+
+int wxFont::GetStyle() const
+{
+ return M_FONTDATA->m_style;
+}
+
+int wxFont::GetWeight() const
+{
+ return M_FONTDATA->m_weight;
+}
+
+bool wxFont::GetUnderlined() const
+{
+ return M_FONTDATA->m_underlined;
+}
+
+wxString wxFont::GetFaceName() const
+{
+ wxString str;
+ if ( M_FONTDATA )
+ str = M_FONTDATA->m_faceName ;
+ return str;
+}
+
+wxFontEncoding wxFont::GetEncoding() const
+{
+ return M_FONTDATA->m_encoding;
+}
+
+bool wxFont::GetNoAntiAliasing()
+{
+ return M_FONTDATA->m_noAA;
+}
+
+short wxFont::GetMacFontNum() const
+{
+ return M_FONTDATA->m_macFontNum;
+}
+
+short wxFont::GetMacFontSize() const
+{
+ return M_FONTDATA->m_macFontSize;
+}
+
+wxByte wxFont::GetMacFontStyle() const
+{
+ return M_FONTDATA->m_macFontStyle;
+}
+
+wxUint32 wxFont::GetMacATSUFontID() const
+{
+ return M_FONTDATA->m_macATSUFontID;
+}
+
+const wxNativeFontInfo *wxFont::GetNativeFontInfo() const
+{
+ wxCHECK_MSG( Ok(), NULL, wxT("invalid font") );
+
+ M_FONTDATA->m_info.InitFromFont(*this);
+
+ return &(M_FONTDATA->m_info);
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: fontdlg.cpp
+// Purpose: wxFontDialog class. NOTE: you can use the generic class
+// if you wish, instead of implementing this.
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "fontdlg.h"
+#endif
+
+#include "wx/mac/fontdlg.h"
+#include "wx/cmndata.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxFontDialog, wxDialog)
+#endif
+
+/*
+ * wxFontDialog
+ */
+
+wxFontDialog::wxFontDialog()
+{
+ m_dialogParent = NULL;
+}
+
+wxFontDialog::wxFontDialog(wxWindow *parent, const wxFontData& data)
+{
+ Create(parent, data);
+}
+
+bool wxFontDialog::Create(wxWindow *parent, const wxFontData& data)
+{
+ m_dialogParent = parent;
+
+ m_fontData = data;
+
+ // TODO: you may need to do dialog creation here, unless it's
+ // done in ShowModal.
+ return TRUE;
+}
+
+int wxFontDialog::ShowModal()
+{
+ // TODO: show (maybe create) the dialog
+ return wxID_CANCEL;
+}
+
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Name: mac/fontenum.cpp
+// Purpose: wxFontEnumerator class for MacOS
+// Author: Stefan Csomor
+// Modified by:
+// Created: 04/01/98
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#ifdef __GNUG__
+ #pragma implementation "fontenum.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+ #include "wx/font.h"
+#endif
+
+#include "wx/fontenum.h"
+#include "wx/fontutil.h"
+#include "wx/fontmap.h"
+#include "wx/fontutil.h"
+#include "wx/encinfo.h"
+
+#include "wx/mac/private.h"
+
+// ----------------------------------------------------------------------------
+// private classes
+// ----------------------------------------------------------------------------
+
+class wxFontEnumeratorHelper
+{
+public:
+ wxFontEnumeratorHelper(wxFontEnumerator *fontEnum);
+
+ // control what exactly are we enumerating
+ bool SetEncoding(wxFontEncoding encoding);
+ void SetFixedOnly(bool fixedOnly)
+ { m_fixedOnly = fixedOnly; }
+
+ // call to start enumeration
+ void DoEnumerate();
+
+private:
+ // the object we forward calls to OnFont() to
+ wxFontEnumerator *m_fontEnum;
+
+ // if != -1, enum only fonts which have this encoding
+ int m_charset;
+
+ // if not empty, enum only the fonts with this facename
+ wxString m_facename;
+
+ // if TRUE, enum only fixed fonts
+ bool m_fixedOnly;
+};
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxFontEnumeratorHelper
+// ----------------------------------------------------------------------------
+
+wxFontEnumeratorHelper::wxFontEnumeratorHelper(wxFontEnumerator *fontEnum)
+{
+ m_fontEnum = fontEnum;
+ m_charset = -1;
+ m_fixedOnly = FALSE;
+}
+
+bool wxFontEnumeratorHelper::SetEncoding(wxFontEncoding encoding)
+{
+ wxNativeEncodingInfo info;
+ if ( !wxGetNativeFontEncoding(encoding, &info) )
+ {
+ if ( !wxFontMapper::Get()->GetAltForEncoding(encoding, &info) )
+ {
+ // no such encodings at all
+ return FALSE;
+ }
+ }
+ m_charset = info.charset;
+ m_facename = info.facename;
+
+ return TRUE;
+}
+
+void wxFontEnumeratorHelper::DoEnumerate()
+{
+ MenuHandle menu ;
+ Str255 p_name ;
+
+ short lines ;
+
+ menu = NewMenu( 32000 , "\pFont" ) ;
+ AppendResMenu( menu , 'FONT' ) ;
+ lines = CountMenuItems( menu ) ;
+
+ for ( int i = 1 ; i < lines+1 ; i ++ )
+ {
+ GetMenuItemText( menu , i , p_name ) ;
+ wxString c_name = wxMacMakeStringFromPascal(p_name) ;
+
+ /*
+
+ if ( m_fixedOnly )
+ {
+ // check that it's a fixed pitch font (there is *no* error here, the
+ // flag name is misleading!)
+ if ( tm->tmPitchAndFamily & TMPF_FIXED_PITCH )
+ {
+ // not a fixed pitch font
+ return TRUE;
+ }
+ }
+
+ if ( m_charset != -1 )
+ {
+ // check that we have the right encoding
+ if ( lf->lfCharSet != m_charset )
+ {
+ return TRUE;
+ }
+ }
+
+ */
+ m_fontEnum->OnFacename( c_name ) ;
+ }
+ DisposeMenu( menu ) ;
+}
+
+// ----------------------------------------------------------------------------
+// wxFontEnumerator
+// ----------------------------------------------------------------------------
+
+bool wxFontEnumerator::EnumerateFacenames(wxFontEncoding encoding,
+ bool fixedWidthOnly)
+{
+ wxFontEnumeratorHelper fe(this);
+ if ( fe.SetEncoding(encoding) )
+ {
+ fe.SetFixedOnly(fixedWidthOnly);
+
+ fe.DoEnumerate();
+ }
+ // else: no such fonts, unknown encoding
+
+ return TRUE;
+}
+
+bool wxFontEnumerator::EnumerateEncodings(const wxString& family)
+{
+ wxFAIL_MSG(wxT("wxFontEnumerator::EnumerateEncodings() not yet implemented"));
+
+ return TRUE;
+}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Name: msw/fontutil.cpp
+// Purpose: font-related helper functions for wxMSW
+// Author: Vadim Zeitlin
+// Modified by:
+// Created: 05.11.99
+// RCS-ID: $Id$
+// Copyright: (c) 1999 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#ifdef __GNUG__
+ #pragma implementation "fontutil.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+ #include "wx/string.h"
+ #include "wx/log.h"
+ #include "wx/intl.h"
+#endif //WX_PRECOMP
+
+#include "wx/fontutil.h"
+#include "wx/fontmap.h"
+#include "wx/encinfo.h"
+
+#include "wx/tokenzr.h"
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxNativeEncodingInfo
+// ----------------------------------------------------------------------------
+
+// convert to/from the string representation: format is
+// facename[;charset]
+
+bool wxNativeEncodingInfo::FromString(const wxString& s)
+{
+ wxStringTokenizer tokenizer(s, _T(";"));
+
+ facename = tokenizer.GetNextToken();
+ if ( !facename )
+ return FALSE;
+
+ wxString tmp = tokenizer.GetNextToken();
+ if ( !tmp )
+ {
+ // default charset (don't use DEFAULT_CHARSET though because of subtle
+ // Windows 9x/NT differences in handling it)
+ charset = 0;
+ }
+ else
+ {
+ if ( wxSscanf(tmp, _T("%u"), &charset) != 1 )
+ {
+ // should be a number!
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+wxString wxNativeEncodingInfo::ToString() const
+{
+ wxString s(facename);
+ if ( charset != 0 )
+ {
+ s << _T(';') << charset;
+ }
+
+ return s;
+}
+
+// ----------------------------------------------------------------------------
+// helper functions
+// ----------------------------------------------------------------------------
+
+bool wxGetNativeFontEncoding(wxFontEncoding encoding,
+ wxNativeEncodingInfo *info)
+{
+ wxCHECK_MSG( info, FALSE, _T("bad pointer in wxGetNativeFontEncoding") );
+
+ if ( encoding == wxFONTENCODING_DEFAULT )
+ {
+ encoding = wxFont::GetDefaultEncoding();
+ }
+
+ info->encoding = encoding ;
+
+ return TRUE;
+}
+
+bool wxTestFontEncoding(const wxNativeEncodingInfo& info)
+{
+ // basically we should be able to support every encoding via the OS
+ return true ;
+}
+
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: frame.cpp
+// Purpose: wxFrame
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "frame.h"
+#endif
+
+#include "wx/frame.h"
+#include "wx/statusbr.h"
+#include "wx/toolbar.h"
+#include "wx/menuitem.h"
+#include "wx/menu.h"
+#include "wx/dcclient.h"
+#include "wx/dialog.h"
+#include "wx/settings.h"
+#include "wx/app.h"
+
+#include "wx/mac/uma.h"
+
+extern wxWindowList wxModelessWindows;
+extern wxList wxPendingDelete;
+
+#if !USE_SHARED_LIBRARY
+BEGIN_EVENT_TABLE(wxFrame, wxFrameBase)
+ EVT_ACTIVATE(wxFrame::OnActivate)
+ // EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight)
+ EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged)
+// EVT_IDLE(wxFrame::OnIdle)
+// EVT_CLOSE(wxFrame::OnCloseWindow)
+END_EVENT_TABLE()
+
+IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxTopLevelWindow)
+#endif
+
+#define WX_MAC_STATUSBAR_HEIGHT 15
+// ----------------------------------------------------------------------------
+// creation/destruction
+// ----------------------------------------------------------------------------
+
+void wxFrame::Init()
+{
+ m_frameMenuBar = NULL;
+
+#if wxUSE_TOOLBAR
+ m_frameToolBar = NULL ;
+#endif
+ m_frameStatusBar = NULL;
+ m_winLastFocused = NULL ;
+
+ m_iconized = FALSE;
+
+#if wxUSE_TOOLTIPS
+ m_hwndToolTip = 0;
+#endif
+}
+
+wxPoint wxFrame::GetClientAreaOrigin() const
+{
+ // on mac we are at position -1,-1 with the control
+ wxPoint pt(0, 0);
+
+#if wxUSE_TOOLBAR
+ if ( GetToolBar() )
+ {
+ int w, h;
+ GetToolBar()->GetSize(& w, & h);
+
+ if ( GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL )
+ {
+ pt.x += w - 1;
+ }
+ else
+ {
+ pt.y += h - 1 ;
+ }
+ }
+#endif // wxUSE_TOOLBAR
+
+ return pt;
+}
+
+bool wxFrame::Create(wxWindow *parent,
+ wxWindowID id,
+ const wxString& title,
+ const wxPoint& pos,
+ const wxSize& size,
+ long style,
+ const wxString& name)
+{
+ SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE));
+
+ if ( !wxTopLevelWindow::Create(parent, id, title, pos, size, style, name) )
+ return FALSE;
+
+ MacCreateRealWindow( title, pos , size , MacRemoveBordersFromStyle(style) , name ) ;
+
+ m_macWindowBackgroundTheme = kThemeBrushDocumentWindowBackground ;
+ SetThemeWindowBackground( (WindowRef) m_macWindow , m_macWindowBackgroundTheme , false ) ;
+
+ wxModelessWindows.Append(this);
+
+ return TRUE;
+}
+
+wxFrame::~wxFrame()
+{
+ m_isBeingDeleted = TRUE;
+ DeleteAllBars();
+}
+
+
+bool wxFrame::Enable(bool enable)
+{
+ if ( !wxWindow::Enable(enable) )
+ return FALSE;
+
+ if ( m_frameMenuBar && m_frameMenuBar == wxMenuBar::MacGetInstalledMenuBar() )
+ {
+ int iMaxMenu = m_frameMenuBar->GetMenuCount();
+ for ( int i = 0 ; i < iMaxMenu ; ++ i )
+ {
+ m_frameMenuBar->EnableTop( i , enable ) ;
+ }
+ }
+
+ return TRUE;
+}
+
+wxStatusBar *wxFrame::OnCreateStatusBar(int number, long style, wxWindowID id,
+ const wxString& name)
+{
+ wxStatusBar *statusBar = NULL;
+
+ statusBar = new wxStatusBar(this, id,
+ style, name);
+ statusBar->SetSize( 100 , 15 ) ;
+ statusBar->SetFieldsCount(number);
+ return statusBar;
+}
+
+void wxFrame::PositionStatusBar()
+{
+ if (m_frameStatusBar )
+ {
+ int w, h;
+ GetClientSize(&w, &h);
+ int sw, sh;
+ m_frameStatusBar->GetSize(&sw, &sh);
+
+ // Since we wish the status bar to be directly under the client area,
+ // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
+ m_frameStatusBar->SetSize(0, h, w, sh);
+ }
+}
+
+// Responds to colour changes, and passes event on to children.
+void wxFrame::OnSysColourChanged(wxSysColourChangedEvent& event)
+{
+ SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE));
+ Refresh();
+
+ if ( m_frameStatusBar )
+ {
+ wxSysColourChangedEvent event2;
+ event2.SetEventObject( m_frameStatusBar );
+ m_frameStatusBar->ProcessEvent(event2);
+ }
+
+ // Propagate the event to the non-top-level children
+ wxWindow::OnSysColourChanged(event);
+}
+
+
+// Default activation behaviour - set the focus for the first child
+// subwindow found.
+void wxFrame::OnActivate(wxActivateEvent& event)
+{
+ if ( !event.GetActive() )
+ {
+ // remember the last focused child if it is our child
+ m_winLastFocused = FindFocus();
+
+ // so we NULL it out if it's a child from some other frame
+ wxWindow *win = m_winLastFocused;
+ while ( win )
+ {
+ if ( win->IsTopLevel() )
+ {
+ if ( win != this )
+ {
+ m_winLastFocused = NULL;
+ }
+
+ break;
+ }
+
+ win = win->GetParent();
+ }
+
+ event.Skip();
+ }
+ else
+ {
+ // restore focus to the child which was last focused
+ wxWindow *parent = m_winLastFocused ? m_winLastFocused->GetParent()
+ : NULL;
+ if ( !parent )
+ {
+ parent = this;
+ }
+
+ wxSetFocusToChild(parent, &m_winLastFocused);
+
+ if ( m_frameMenuBar != NULL )
+ {
+ m_frameMenuBar->MacInstallMenuBar() ;
+ }
+ else if (wxTheApp->GetTopWindow() && wxTheApp->GetTopWindow()->IsKindOf(CLASSINFO(wxFrame)))
+ {
+ // Trying toplevel frame menbar
+ if( ((wxFrame*)wxTheApp->GetTopWindow())->GetMenuBar() )
+ ((wxFrame*)wxTheApp->GetTopWindow())->GetMenuBar()->MacInstallMenuBar();
+ }
+ }
+}
+
+void wxFrame::DetachMenuBar()
+{
+ if ( m_frameMenuBar )
+ {
+ m_frameMenuBar->UnsetInvokingWindow();
+ }
+
+ wxFrameBase::DetachMenuBar();
+}
+
+void wxFrame::AttachMenuBar( wxMenuBar *menuBar )
+{
+ wxFrameBase::AttachMenuBar(menuBar);
+
+ if (m_frameMenuBar)
+ {
+ m_frameMenuBar->SetInvokingWindow( this );
+ }
+}
+
+void wxFrame::DoGetClientSize(int *x, int *y) const
+{
+ wxWindow::DoGetClientSize( x , y ) ;
+
+#if wxUSE_STATUSBAR
+ if ( GetStatusBar() && y )
+ {
+ int statusX, statusY;
+ GetStatusBar()->GetClientSize(&statusX, &statusY);
+ *y -= statusY;
+ }
+#endif // wxUSE_STATUSBAR
+
+ wxPoint pt(GetClientAreaOrigin());
+ if ( y )
+ *y -= pt.y;
+ if ( x )
+ *x -= pt.x;
+}
+
+void wxFrame::DoSetClientSize(int clientwidth, int clientheight)
+{
+ int currentclientwidth , currentclientheight ;
+ int currentwidth , currentheight ;
+
+ GetClientSize( ¤tclientwidth , ¤tclientheight ) ;
+ GetSize( ¤twidth , ¤theight ) ;
+
+ // find the current client size
+
+ // Find the difference between the entire window (title bar and all)
+ // and the client area; add this to the new client size to move the
+ // window
+
+ DoSetSize( -1 , -1 , currentwidth + clientwidth - currentclientwidth ,
+ currentheight + clientheight - currentclientheight , wxSIZE_USE_EXISTING ) ;
+}
+
+
+#if wxUSE_TOOLBAR
+wxToolBar* wxFrame::CreateToolBar(long style, wxWindowID id, const wxString& name)
+{
+ if ( wxFrameBase::CreateToolBar(style, id, name) )
+ {
+ PositionToolBar();
+ }
+
+ return m_frameToolBar;
+}
+
+void wxFrame::PositionToolBar()
+{
+ int cw, ch;
+
+ cw = m_width ;
+ ch = m_height ;
+
+ if ( GetStatusBar() )
+ {
+ int statusX, statusY;
+ GetStatusBar()->GetClientSize(&statusX, &statusY);
+ ch -= statusY;
+ }
+
+ if (GetToolBar())
+ {
+ int tw, th;
+ GetToolBar()->GetSize(& tw, & th);
+
+ if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
+ {
+ // Use the 'real' position. wxSIZE_NO_ADJUSTMENTS
+ // means, pretend we don't have toolbar/status bar, so we
+ // have the original client size.
+ GetToolBar()->SetSize(-1, -1, tw, ch + 2 , wxSIZE_NO_ADJUSTMENTS | wxSIZE_ALLOW_MINUS_ONE );
+ }
+ else
+ {
+ // Use the 'real' position
+ GetToolBar()->SetSize(-1, -1, cw + 2, th, wxSIZE_NO_ADJUSTMENTS | wxSIZE_ALLOW_MINUS_ONE );
+ }
+ }
+}
+#endif
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: gauge.cpp
+// Purpose: wxGauge class
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "gauge.h"
+#endif
+
+#include "wx/gauge.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxGauge, wxControl)
+#endif
+
+#include "wx/mac/uma.h"
+
+bool wxGauge::Create(wxWindow *parent, wxWindowID id,
+ int range,
+ const wxPoint& pos,
+ const wxSize& s,
+ long style,
+ const wxValidator& validator,
+ const wxString& name)
+{
+ if ( !wxGaugeBase::Create(parent, id, range, pos, s, style, validator, name) )
+ return false;
+
+ wxSize size = s ;
+ Rect bounds ;
+ Str255 title ;
+ m_rangeMax = range ;
+ m_gaugePos = 0 ;
+
+ if ( size.x == wxDefaultSize.x && size.y == wxDefaultSize.y)
+ {
+ size = wxSize( 200 , 16 ) ;
+ }
+
+ MacPreControlCreate( parent , id , wxEmptyString , pos , size ,style & 0xE0FFFFFF /* no borders on mac */ , validator , name , &bounds , title ) ;
+
+ m_macControl = ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , title , false , 0 , 0 , range,
+ kControlProgressBarProc , (long) this ) ;
+
+ MacPostControlCreate() ;
+
+ return TRUE;
+}
+
+void wxGauge::SetShadowWidth(int w)
+{
+}
+
+void wxGauge::SetBezelFace(int w)
+{
+}
+
+void wxGauge::SetRange(int r)
+{
+ m_rangeMax = r;
+ ::SetControl32BitMaximum( (ControlHandle) m_macControl , m_rangeMax ) ;
+}
+
+void wxGauge::SetValue(int pos)
+{
+ m_gaugePos = pos;
+ ::SetControl32BitValue( (ControlHandle) m_macControl , m_gaugePos ) ;
+}
+
+int wxGauge::GetShadowWidth() const
+{
+ return 0;
+}
+
+int wxGauge::GetBezelFace() const
+{
+ return 0;
+}
+
+int wxGauge::GetRange() const
+{
+ return m_rangeMax;
+}
+
+int wxGauge::GetValue() const
+{
+ return m_gaugePos;
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: gdiobj.cpp
+// Purpose: wxGDIObject class
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "gdiobj.h"
+#endif
+
+#include "wx/gdiobj.h"
+
+#if !USE_SHARED_LIBRARIES
+IMPLEMENT_DYNAMIC_CLASS(wxGDIObject, wxObject)
+#endif
+
+// TODO: Nothing to do, unless you want to.
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: glcanvas.cpp
+// Purpose: wxGLCanvas, for using OpenGL with wxWindows under Macintosh
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "glcanvas.h"
+#endif
+
+#include "wx/wxprec.h"
+
+#if defined(__BORLANDC__)
+#pragma hdrstop
+#endif
+
+#include "wx/setup.h"
+
+#if wxUSE_GLCANVAS
+
+#ifndef WX_PRECOMP
+#include "wx/frame.h"
+#endif
+
+#include "wx/settings.h"
+#include "wx/log.h"
+
+#include "wx/glcanvas.h"
+#include "wx/mac/uma.h"
+
+// DLL options compatibility check:
+#include "wx/build.h"
+WX_CHECK_BUILD_OPTIONS("wxGL")
+
+/*
+* GLContext implementation
+*/
+
+wxGLContext::wxGLContext(
+ AGLPixelFormat fmt, wxGLCanvas *win,
+ const wxPalette& palette,
+ const wxGLContext *other /* for sharing display lists */
+ )
+{
+ m_window = win;
+
+ m_drawable = (AGLDrawable) UMAGetWindowPort(MAC_WXHWND(win->MacGetRootWindow()));
+
+ m_glContext = aglCreateContext(fmt, other ? other->m_glContext : NULL);
+ wxCHECK_RET( m_glContext, wxT("Couldn't create OpenGl context") );
+
+ GLboolean b;
+ b = aglSetDrawable(m_glContext, m_drawable);
+ wxCHECK_RET( b, wxT("Couldn't bind OpenGl context") );
+ aglEnable(m_glContext , AGL_BUFFER_RECT ) ;
+ b = aglSetCurrentContext(m_glContext);
+ wxCHECK_RET( b, wxT("Couldn't activate OpenGl context") );
+}
+
+wxGLContext::~wxGLContext()
+{
+ if (m_glContext)
+ {
+ aglSetCurrentContext(NULL);
+ aglDestroyContext(m_glContext);
+ }
+}
+
+void wxGLContext::SwapBuffers()
+{
+ if (m_glContext)
+ {
+ aglSwapBuffers(m_glContext);
+ }
+}
+
+void wxGLContext::SetCurrent()
+{
+ if (m_glContext)
+ {
+ aglSetCurrentContext(m_glContext);
+ }
+}
+
+void wxGLContext::Update()
+{
+ if (m_glContext)
+ {
+ aglUpdateContext(m_glContext);
+ }
+}
+
+void wxGLContext::SetColour(const wxChar *colour)
+{
+ wxColour col = wxTheColourDatabase->Find(colour);
+ if (col.Ok())
+ {
+ float r = (float)(col.Red()/256.0);
+ float g = (float)(col.Green()/256.0);
+ float b = (float)(col.Blue()/256.0);
+ glColor3f( r, g, b);
+ }
+}
+
+
+/*
+* wxGLCanvas implementation
+*/
+
+IMPLEMENT_CLASS(wxGLCanvas, wxWindow)
+
+BEGIN_EVENT_TABLE(wxGLCanvas, wxWindow)
+ EVT_SIZE(wxGLCanvas::OnSize)
+END_EVENT_TABLE()
+
+wxGLCanvas::wxGLCanvas(wxWindow *parent, wxWindowID id,
+ const wxPoint& pos, const wxSize& size, long style, const wxString& name,
+ int *attribList, const wxPalette& palette)
+{
+ Create(parent, NULL, id, pos, size, style, name, attribList, palette);
+}
+
+wxGLCanvas::wxGLCanvas( wxWindow *parent,
+ const wxGLContext *shared, wxWindowID id,
+ const wxPoint& pos, const wxSize& size, long style, const wxString& name,
+ int *attribList, const wxPalette& palette )
+{
+ Create(parent, shared, id, pos, size, style, name, attribList, palette);
+}
+
+wxGLCanvas::wxGLCanvas( wxWindow *parent, const wxGLCanvas *shared, wxWindowID id,
+ const wxPoint& pos, const wxSize& size, long style, const wxString& name,
+ int *attribList, const wxPalette& palette )
+{
+ Create(parent, shared ? shared->GetContext() : NULL, id, pos, size, style, name, attribList, palette);
+}
+
+wxGLCanvas::~wxGLCanvas()
+{
+ if (m_glContext != NULL) {
+ delete m_glContext;
+ m_glContext = NULL;
+ }
+}
+
+static AGLPixelFormat ChoosePixelFormat(const int *attribList)
+{
+ GLint data[512];
+ GLint defaultAttribs[] = { AGL_RGBA,
+ AGL_DOUBLEBUFFER,
+ AGL_MINIMUM_POLICY,
+ AGL_DEPTH_SIZE, 1, // use largest available depth buffer
+ AGL_RED_SIZE, 1,
+ AGL_GREEN_SIZE, 1,
+ AGL_BLUE_SIZE, 1,
+ AGL_ALPHA_SIZE, 0,
+ AGL_NONE };
+ GLint *attribs;
+ if (!attribList)
+ {
+ attribs = defaultAttribs;
+ }
+ else
+ {
+ int arg=0, p=0;
+
+ data[p++] = AGL_MINIMUM_POLICY; // make _SIZE tags behave more like GLX
+ while( (attribList[arg]!=0) && (p<512) )
+ {
+ switch( attribList[arg++] )
+ {
+ case WX_GL_RGBA: data[p++] = AGL_RGBA; break;
+ case WX_GL_BUFFER_SIZE:
+ data[p++]=AGL_BUFFER_SIZE; data[p++]=attribList[arg++]; break;
+ case WX_GL_LEVEL:
+ data[p++]=AGL_LEVEL; data[p++]=attribList[arg++]; break;
+ case WX_GL_DOUBLEBUFFER: data[p++] = AGL_DOUBLEBUFFER; break;
+ case WX_GL_STEREO: data[p++] = AGL_STEREO; break;
+ case WX_GL_AUX_BUFFERS:
+ data[p++]=AGL_AUX_BUFFERS; data[p++]=attribList[arg++]; break;
+ case WX_GL_MIN_RED:
+ data[p++]=AGL_RED_SIZE; data[p++]=attribList[arg++]; break;
+ case WX_GL_MIN_GREEN:
+ data[p++]=AGL_GREEN_SIZE; data[p++]=attribList[arg++]; break;
+ case WX_GL_MIN_BLUE:
+ data[p++]=AGL_BLUE_SIZE; data[p++]=attribList[arg++]; break;
+ case WX_GL_MIN_ALPHA:
+ data[p++]=AGL_ALPHA_SIZE; data[p++]=attribList[arg++]; break;
+ case WX_GL_DEPTH_SIZE:
+ data[p++]=AGL_DEPTH_SIZE; data[p++]=attribList[arg++]; break;
+ case WX_GL_STENCIL_SIZE:
+ data[p++]=AGL_STENCIL_SIZE; data[p++]=attribList[arg++]; break;
+ case WX_GL_MIN_ACCUM_RED:
+ data[p++]=AGL_ACCUM_RED_SIZE; data[p++]=attribList[arg++]; break;
+ case WX_GL_MIN_ACCUM_GREEN:
+ data[p++]=AGL_ACCUM_GREEN_SIZE; data[p++]=attribList[arg++]; break;
+ case WX_GL_MIN_ACCUM_BLUE:
+ data[p++]=AGL_ACCUM_BLUE_SIZE; data[p++]=attribList[arg++]; break;
+ case WX_GL_MIN_ACCUM_ALPHA:
+ data[p++]=AGL_ACCUM_ALPHA_SIZE; data[p++]=attribList[arg++]; break;
+ default:
+ break;
+ }
+ }
+ data[p] = 0;
+
+ attribs = data;
+ }
+
+ return aglChoosePixelFormat(NULL, 0, attribs);
+}
+
+bool wxGLCanvas::Create(wxWindow *parent, const wxGLContext *shared, wxWindowID id,
+ const wxPoint& pos, const wxSize& size, long style, const wxString& name,
+ int *attribList, const wxPalette& palette)
+{
+ wxWindow::Create( parent, id, pos, size, style, name );
+
+ AGLPixelFormat fmt = ChoosePixelFormat(attribList);
+ wxCHECK_MSG( fmt, false, wxT("Couldn't create OpenGl pixel format") );
+
+ m_glContext = new wxGLContext(fmt, this, palette, shared);
+ m_macCanvasIsShown = true ;
+ aglDestroyPixelFormat(fmt);
+
+ return true;
+}
+
+void wxGLCanvas::SwapBuffers()
+{
+ if (m_glContext)
+ m_glContext->SwapBuffers();
+}
+
+void wxGLCanvas::UpdateContext()
+{
+ if (m_glContext)
+ m_glContext->Update();
+}
+
+void wxGLCanvas::SetViewport()
+{
+ // viewport is initially set to entire port
+ // adjust glViewport to just this window
+ int x = 0 ;
+ int y = 0 ;
+
+ wxWindow* iter = this ;
+ while( iter->GetParent() )
+ {
+ iter = iter->GetParent() ;
+ }
+
+ if ( iter && iter->IsTopLevel() )
+ {
+ MacClientToRootWindow( &x , &y ) ;
+ int width, height;
+ GetClientSize(& width, & height);
+ Rect bounds ;
+ GetWindowPortBounds( MAC_WXHWND(MacGetRootWindow()) , &bounds ) ;
+ GLint parms[4] ;
+ parms[0] = x ;
+ parms[1] = bounds.bottom - bounds.top - ( y + height ) ;
+ parms[2] = width ;
+ parms[3] = height ;
+
+ if ( !m_macCanvasIsShown )
+ parms[0] += 20000 ;
+ aglSetInteger( m_glContext->m_glContext , AGL_BUFFER_RECT , parms ) ;
+ }
+}
+
+void wxGLCanvas::OnSize(wxSizeEvent& event)
+{
+ MacUpdateView() ;
+}
+
+void wxGLCanvas::MacUpdateView()
+{
+ if (m_glContext)
+ {
+ UpdateContext();
+ m_glContext->SetCurrent();
+ SetViewport();
+ }
+}
+
+void wxGLCanvas::MacSuperChangedPosition()
+{
+ MacUpdateView() ;
+ wxWindow::MacSuperChangedPosition() ;
+}
+
+void wxGLCanvas::MacTopLevelWindowChangedPosition()
+{
+ MacUpdateView() ;
+ wxWindow::MacTopLevelWindowChangedPosition() ;
+}
+
+void wxGLCanvas::SetCurrent()
+{
+ if (m_glContext)
+ {
+ m_glContext->SetCurrent();
+ }
+}
+
+void wxGLCanvas::SetColour(const wxChar *colour)
+{
+ if (m_glContext)
+ m_glContext->SetColour(colour);
+}
+
+bool wxGLCanvas::Show(bool show)
+{
+ if ( !wxWindow::Show( show ) )
+ return FALSE ;
+
+ if ( !show )
+ {
+ if ( m_macCanvasIsShown )
+ {
+ m_macCanvasIsShown = false ;
+ SetViewport() ;
+ }
+ }
+ else
+ {
+ if ( MacIsReallyShown() && !m_macCanvasIsShown )
+ {
+ m_macCanvasIsShown = true ;
+ SetViewport() ;
+ }
+ }
+ return TRUE ;
+}
+
+void wxGLCanvas::MacSuperShown( bool show )
+{
+ if ( !show )
+ {
+ if ( m_macCanvasIsShown )
+ {
+ m_macCanvasIsShown = false ;
+ SetViewport() ;
+ }
+ }
+ else
+ {
+ if ( MacIsReallyShown() && !m_macCanvasIsShown )
+ {
+ m_macCanvasIsShown = true ;
+ SetViewport() ;
+ }
+ }
+
+ wxWindow::MacSuperShown( show ) ;
+}
+
+//---------------------------------------------------------------------------
+// wxGLApp
+//---------------------------------------------------------------------------
+
+IMPLEMENT_CLASS(wxGLApp, wxApp)
+
+bool wxGLApp::InitGLVisual(int *attribList)
+{
+ AGLPixelFormat fmt = ChoosePixelFormat(attribList);
+ if (fmt != NULL) {
+ aglDestroyPixelFormat(fmt);
+ return true;
+ } else
+ return false;
+}
+
+wxGLApp::~wxGLApp(void)
+{
+}
+
+#endif // wxUSE_GLCANVAS
--- /dev/null
+/* -------------------------------------------------------------------------
+ * Project: GSocket (Generic Socket) for WX
+ * Name: gsocket.c
+ * Authors: Guilhem Lavaux,
+ * Guillermo Rodriguez Garcia <guille@iies.es> (maintainer)
+ * Stefan CSomor
+ * Purpose: GSocket main mac file
+ * CVSID: $Id$
+ * -------------------------------------------------------------------------
+ */
+
+/*
+ * PLEASE don't put C++ comments here - this is a C source file.
+ */
+
+#ifndef __GSOCKET_STANDALONE__
+#include "wx/setup.h"
+#include "wx/platform.h"
+#endif
+
+#if wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__)
+
+#ifdef __DARWIN__
+ #include <CoreServices/CoreServices.h>
+
+ #ifndef FALSE
+ #define FALSE 0
+ #endif
+ #ifndef TRUE
+ #define TRUE 1
+ #endif
+#else
+ #include <MacHeaders.c>
+ #define OTUNIXERRORS 1
+ #include <OpenTransport.h>
+ #include <OpenTransportProviders.h>
+ #include <OpenTptInternet.h>
+#endif
+#if TARGET_CARBON && !defined(OTAssert)
+ #define OTAssert( str , cond ) /* does not exists in Carbon */
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <ctype.h>
+#include <utime.h>
+
+/*
+ * INADDR_BROADCAST is identical to INADDR_NONE which is not defined
+ * on all unices. INADDR_BROADCAST should be fine to indicate an error.
+ */
+#ifndef INADDR_BROADCAST
+#define INADDR_BROADCAST 0xFFFFFFFFUL
+#endif
+#ifndef INADDR_NONE
+#define INADDR_NONE INADDR_BROADCAST
+#endif
+#ifndef INADDR_ANY
+#define INADDR_ANY 0x0UL
+#endif
+#ifndef __GSOCKET_STANDALONE__
+
+#include "wx/mac/macnotfy.h"
+#include "wx/mac/gsockmac.h"
+#include "wx/gsocket.h"
+
+#else
+
+#include "gsockmac.h"
+#include "gsocket.h"
+
+#endif /* __GSOCKET_STANDALONE__ */
+
+void wxCYield() ;
+#ifdef __WXDEBUG__
+#define qDebug 1
+#define qDebug2 1
+extern pascal void OTDebugStr(const char* str);
+#endif
+#ifndef __DARWIN__
+ #include <OTDebug.h>
+#endif
+InetSvcRef gInetSvcRef = 0 ;
+int gOTInited = 0 ;
+OTNotifyUPP gOTNotifierUPP = NULL ;
+
+OSStatus DoNegotiateIPReuseAddrOption(EndpointRef ep, Boolean enableReuseIPMode);
+
+/* Input: ep - endpointref on which to negotiate the option
+ enableReuseIPMode - desired option setting - true/false
+ Return: kOTNoError indicates that the option was successfully negotiated
+ OSStatus is an error if < 0, otherwise, the status field is
+ returned and is > 0.
+
+ IMPORTANT NOTE: The endpoint is assumed to be in synchronous more, otherwise
+ this code will not function as desired
+*/
+
+
+OSStatus DoNegotiateIPReuseAddrOption(EndpointRef ep, Boolean enableReuseIPMode)
+
+{
+ UInt8 buf[kOTFourByteOptionSize]; // define buffer for fourByte Option size
+ TOption* opt; // option ptr to make items easier to access
+ TOptMgmt req;
+ TOptMgmt ret;
+ OSStatus err;
+
+ if (!OTIsSynchronous(ep))
+ {
+ return (-1);
+ }
+ opt = (TOption*)buf; // set option ptr to buffer
+ req.opt.buf = buf;
+ req.opt.len = sizeof(buf);
+ req.flags = T_NEGOTIATE; // negotiate for option
+
+ ret.opt.buf = buf;
+ ret.opt.maxlen = kOTFourByteOptionSize;
+
+ opt->level = INET_IP; // dealing with an IP Level function
+#ifdef __DARWIN__
+ opt->name = kIP_REUSEADDR;
+#else
+ opt->name = IP_REUSEADDR;
+#endif
+ opt->len = kOTFourByteOptionSize;
+ opt->status = 0;
+ *(UInt32*)opt->value = enableReuseIPMode; // set the desired option level, true or false
+
+ err = OTOptionManagement(ep, &req, &ret);
+
+ // if no error then return the option status value
+ if (err == kOTNoError)
+ {
+ if (opt->status != T_SUCCESS)
+ err = opt->status;
+ else
+ err = kOTNoError;
+ }
+
+ return err;
+}
+
+
+pascal void OTInetEventHandler(void*s, OTEventCode event, OTResult, void *cookie) ;
+pascal void OTInetEventHandler(void*s, OTEventCode event, OTResult result, void *cookie)
+{
+ int wakeUp = true ;
+ GSocket* sock = (GSocket*) s ;
+
+ if ( event == kOTSyncIdleEvent )
+ {
+ YieldToAnyThread() ;
+ return ;
+ }
+
+ if ( s )
+ {
+ wxMacAddEvent( sock->m_mac_events , _GSocket_Internal_Proc , event , s , wakeUp ) ;
+ }
+
+ return;
+}
+
+static void SetDefaultEndpointModes(EndpointRef ep , void *data )
+ // This routine sets the supplied endpoint into the default
+ // mode used in this application. The specifics are:
+ // blocking, synchronous, and using synch idle events with
+ // the standard YieldingNotifier.
+{
+ OSStatus junk = kOTNoError ;
+ OTAssert ("SetDefaultEndpointModes:invalid ref", ep != kOTInvalidEndpointRef ) ;
+ junk = OTSetAsynchronous(ep);
+ OTAssert("SetDefaultEndpointModes: Could not set asynchronous", junk == noErr);
+/*
+ junk = OTSetBlocking(ep);
+ OTAssert("SetDefaultEndpointModes: Could not set blocking", junk == noErr);
+ junk = OTSetSynchronous(ep);
+ OTAssert("SetDefaultEndpointModes: Could not set synchronous", junk == noErr);
+ junk = OTSetBlocking(ep);
+ OTAssert("SetDefaultEndpointModes: Could not set blocking", junk == noErr);
+*/
+ junk = OTInstallNotifier(ep, gOTNotifierUPP, data);
+ OTAssert("SetDefaultEndpointModes: Could not install notifier", junk == noErr);
+/*
+ junk = OTUseSyncIdleEvents(ep, true);
+ OTAssert("SetDefaultEndpointModes: Could not use sync idle events", junk == noErr);
+*/
+}
+
+/* Global initialisers */
+
+void GSocket_SetGUIFunctions(struct GSocketGUIFunctionsTable *table)
+{
+ // do nothing, wxMac doesn't have wxBase-GUI separation yet
+}
+
+int GSocket_Init()
+{
+ return TRUE;
+}
+
+int GSocket_Verify_Inited() ;
+int GSocket_Verify_Inited()
+{
+ OSStatus err ;
+#if TARGET_CARBON
+ // Marc Newsam: added the clientcontext variable
+ // however, documentation is unclear how this works
+ OTClientContextPtr clientcontext;
+
+ if ( gInetSvcRef )
+ return TRUE ;
+
+ InitOpenTransportInContext(kInitOTForApplicationMask, &clientcontext);
+ gOTInited = 1 ;
+ gInetSvcRef = OTOpenInternetServicesInContext(kDefaultInternetServicesPath,
+ NULL, &err, clientcontext);
+#else
+ if ( gInetSvcRef )
+ return TRUE ;
+
+ InitOpenTransport() ;
+ gOTInited = 1 ;
+ gInetSvcRef = OTOpenInternetServices(kDefaultInternetServicesPath, NULL, &err);
+#endif
+ if ( gInetSvcRef == NULL || err != kOTNoError )
+ {
+ OTAssert("Could not open Inet Services", err == noErr);
+ return FALSE ;
+ }
+ gOTNotifierUPP = NewOTNotifyUPP( OTInetEventHandler ) ;
+ return TRUE ;
+}
+
+void GSocket_Cleanup()
+{
+ if ( gOTInited != 0 )
+ {
+ if ( gInetSvcRef != NULL )
+ OTCloseProvider( gInetSvcRef );
+ #if TARGET_CARBON
+ CloseOpenTransportInContext( NULL ) ;
+ #else
+ CloseOpenTransport() ;
+ #endif
+ if ( gOTNotifierUPP )
+ DisposeOTNotifyUPP( gOTNotifierUPP ) ;
+ }
+}
+
+/* Constructors / Destructors for GSocket */
+
+GSocket *GSocket_new()
+{
+
+ int i;
+ GSocket *socket;
+
+ if ( GSocket_Verify_Inited() == FALSE )
+ return NULL ;
+
+ socket = (GSocket *)malloc(sizeof(GSocket));
+
+ if (socket == NULL)
+ return NULL;
+
+ socket->m_endpoint = NULL ;
+ for (i=0;i<GSOCK_MAX_EVENT;i++)
+ {
+ socket->m_cbacks[i] = NULL;
+ }
+ socket->m_detected = 0;
+ socket->m_local = NULL;
+ socket->m_peer = NULL;
+ socket->m_error = GSOCK_NOERROR;
+ socket->m_server = FALSE;
+ socket->m_stream = TRUE;
+ socket->m_non_blocking = FALSE;
+ socket->m_timeout = 1*1000;
+ /* 10 sec * 1000 millisec */
+ socket->m_takesEvents = TRUE ;
+ socket->m_mac_events = wxMacGetNotifierTable() ;
+ return socket;
+}
+
+void GSocket_destroy(GSocket *socket)
+{
+ assert(socket != NULL);
+
+ /* Check that the socket is really shutdowned */
+ if (socket->m_endpoint != kOTInvalidEndpointRef)
+ GSocket_Shutdown(socket);
+
+
+ /* Destroy private addresses */
+ if (socket->m_local)
+ GAddress_destroy(socket->m_local);
+
+ if (socket->m_peer)
+ GAddress_destroy(socket->m_peer);
+
+ /* Destroy the socket itself */
+ free(socket);
+}
+
+/* GSocket_Shutdown:
+ * Disallow further read/write operations on this socket, close
+ * the fd and disable all callbacks.
+ */
+void GSocket_Shutdown(GSocket *socket)
+{
+ OSStatus err ;
+ int evt;
+
+ assert(socket != NULL);
+
+ /* If socket has been created, shutdown it */
+ if (socket->m_endpoint != kOTInvalidEndpointRef )
+ {
+ err = OTSndOrderlyDisconnect( socket->m_endpoint ) ;
+ if ( err != kOTNoError )
+ {
+
+ }
+ err = OTRcvOrderlyDisconnect( socket->m_endpoint ) ;
+ err = OTUnbind( socket->m_endpoint ) ;
+ err = OTCloseProvider( socket->m_endpoint ) ;
+ socket->m_endpoint = kOTInvalidEndpointRef ;
+ }
+
+ /* Disable GUI callbacks */
+ for (evt = 0; evt < GSOCK_MAX_EVENT; evt++)
+ socket->m_cbacks[evt] = NULL;
+
+ socket->m_detected = 0;
+ _GSocket_Disable_Events(socket);
+ wxMacRemoveAllNotifiersForData( wxMacGetNotifierTable() , socket ) ;
+}
+
+
+/* Address handling */
+
+/* GSocket_SetLocal:
+ * GSocket_GetLocal:
+ * GSocket_SetPeer:
+ * GSocket_GetPeer:
+ * Set or get the local or peer address for this socket. The 'set'
+ * functions return GSOCK_NOERROR on success, an error code otherwise.
+ * The 'get' functions return a pointer to a GAddress object on success,
+ * or NULL otherwise, in which case they set the error code of the
+ * corresponding GSocket.
+ *
+ * Error codes:
+ * GSOCK_INVSOCK - the socket is not valid.
+ * GSOCK_INVADDR - the address is not valid.
+ */
+GSocketError GSocket_SetLocal(GSocket *socket, GAddress *address)
+{
+ assert(socket != NULL);
+
+ /* the socket must be initialized, or it must be a server */
+ if ((socket->m_endpoint != kOTInvalidEndpointRef && !socket->m_server))
+ {
+ socket->m_error = GSOCK_INVSOCK;
+ return GSOCK_INVSOCK;
+ }
+
+ /* check address */
+ if (address == NULL || address->m_family == GSOCK_NOFAMILY)
+ {
+ socket->m_error = GSOCK_INVADDR;
+ return GSOCK_INVADDR;
+ }
+
+ if (socket->m_local)
+ GAddress_destroy(socket->m_local);
+
+ socket->m_local = GAddress_copy(address);
+
+ return GSOCK_NOERROR;
+}
+
+GSocketError GSocket_SetPeer(GSocket *socket, GAddress *address)
+{
+ assert(socket != NULL);
+
+ /* check address */
+ if (address == NULL || address->m_family == GSOCK_NOFAMILY)
+ {
+ socket->m_error = GSOCK_INVADDR;
+ return GSOCK_INVADDR;
+ }
+
+ if (socket->m_peer)
+ GAddress_destroy(socket->m_peer);
+
+ socket->m_peer = GAddress_copy(address);
+
+ return GSOCK_NOERROR;
+}
+
+GAddress *GSocket_GetLocal(GSocket *socket)
+{
+ GAddress *address = NULL ;
+ GSocketError err;
+ InetAddress loc ;
+
+ assert(socket != NULL);
+
+ /* try to get it from the m_local var first */
+ if (socket->m_local)
+ return GAddress_copy(socket->m_local);
+
+ /* else, if the socket is initialized, try getsockname */
+ if (socket->m_endpoint == kOTInvalidEndpointRef)
+ {
+ socket->m_error = GSOCK_INVSOCK;
+ return NULL;
+ }
+
+
+/* we do not support multihoming with this code at the moment
+ OTGetProtAddress will have to be used then - but we don't have a handy
+ method to use right now
+*/
+ {
+ InetInterfaceInfo info;
+ OTInetGetInterfaceInfo(&info, kDefaultInetInterface);
+ loc.fHost = info.fAddress ;
+ loc.fPort = 0 ;
+ loc.fAddressType = AF_INET ;
+ }
+
+ /* got a valid address from getsockname, create a GAddress object */
+ address = GAddress_new();
+ if (address == NULL)
+ {
+ socket->m_error = GSOCK_MEMERR;
+ return NULL;
+ }
+
+ err = _GAddress_translate_from(address, &loc);
+ if (err != GSOCK_NOERROR)
+ {
+ GAddress_destroy(address);
+ socket->m_error = err;
+ return NULL;
+ }
+
+ return address;
+}
+
+GAddress *GSocket_GetPeer(GSocket *socket)
+{
+ assert(socket != NULL);
+
+ /* try to get it from the m_peer var */
+ if (socket->m_peer)
+ return GAddress_copy(socket->m_peer);
+
+ return NULL;
+}
+
+/* Server specific parts */
+
+/* GSocket_SetServer:
+ * Sets up this socket as a server. The local address must have been
+ * set with GSocket_SetLocal() before GSocket_SetServer() is called.
+ * Returns GSOCK_NOERROR on success, one of the following otherwise:
+ *
+ * Error codes:
+ * GSOCK_INVSOCK - the socket is in use.
+ * GSOCK_INVADDR - the local address has not been set.
+ * GSOCK_IOERR - low-level error.
+ */
+GSocketError GSocket_SetServer(GSocket *sck)
+{
+ assert(sck != NULL);
+
+ /* must not be in use */
+ if (sck->m_endpoint != kOTInvalidEndpointRef )
+ {
+ sck->m_error = GSOCK_INVSOCK;
+ return GSOCK_INVSOCK;
+ }
+
+ /* the local addr must have been set */
+ if (!sck->m_local)
+ {
+ sck->m_error = GSOCK_INVADDR;
+ return GSOCK_INVADDR;
+ }
+
+ /* Initialize all fields */
+ sck->m_stream = TRUE;
+ sck->m_server = TRUE;
+ sck->m_oriented = TRUE;
+
+// TODO
+#if 0
+ /* Create the socket */
+ sck->m_endpoint = socket(sck->m_local->m_realfamily, SOCK_STREAM, 0);
+ socket_set_ref( sck->m_endpoint , (unsigned long) &gMacNetEvents , (unsigned long) sck ) ;
+ if (sck->m_endpoint == kOTInvalidEndpointRef)
+ {
+ sck->m_error = GSOCK_IOERR;
+ return GSOCK_IOERR;
+ }
+
+ ioctl(sck->m_endpoint, FIONBIO, &arg);
+ _GSocket_Enable_Events(sck);
+
+ /* Bind to the local address,
+ * retrieve the actual address bound,
+ * and listen up to 5 connections.
+ */
+ if ((bind(sck->m_endpoint, sck->m_local->m_addr, sck->m_local->m_len) != 0) ||
+ (getsockname(sck->m_endpoint,
+ sck->m_local->m_addr,
+ (SOCKLEN_T *) &sck->m_local->m_len) != 0) ||
+ (listen(sck->m_endpoint, 5) != 0))
+ {
+ close(sck->m_endpoint);
+ sck->m_endpoint = -1;
+ sck->m_error = GSOCK_IOERR;
+ return GSOCK_IOERR;
+ }
+#endif
+ return GSOCK_NOERROR;
+}
+
+/* GSocket_WaitConnection:
+ * Waits for an incoming client connection. Returns a pointer to
+ * a GSocket object, or NULL if there was an error, in which case
+ * the last error field will be updated for the calling GSocket.
+ *
+ * Error codes (set in the calling GSocket)
+ * GSOCK_INVSOCK - the socket is not valid or not a server.
+ * GSOCK_TIMEDOUT - timeout, no incoming connections.
+ * GSOCK_WOULDBLOCK - the call would block and the socket is nonblocking.
+ * GSOCK_MEMERR - couldn't allocate memory.
+ * GSOCK_IOERR - low-level error.
+ */
+GSocket *GSocket_WaitConnection(GSocket *socket)
+{
+ GSocket *connection = NULL ;
+
+ assert(socket != NULL);
+
+ /* Reenable CONNECTION events */
+ socket->m_detected &= ~GSOCK_CONNECTION_FLAG;
+
+ /* If the socket has already been created, we exit immediately */
+ if (socket->m_endpoint == kOTInvalidEndpointRef || !socket->m_server)
+ {
+ socket->m_error = GSOCK_INVSOCK;
+ return NULL;
+ }
+
+ /* Create a GSocket object for the new connection */
+ connection = GSocket_new();
+
+ if (!connection)
+ {
+ socket->m_error = GSOCK_MEMERR;
+ return NULL;
+ }
+
+ /* Wait for a connection (with timeout) */
+ if (_GSocket_Input_Timeout(socket) == GSOCK_TIMEDOUT)
+ {
+ GSocket_destroy(connection);
+ /* socket->m_error set by _GSocket_Input_Timeout */
+ return NULL;
+ }
+
+// TODO
+#if 0
+ connection->m_endpoint = accept(socket->m_endpoint, &from, (SOCKLEN_T *) &fromlen);
+#endif
+
+ if (connection->m_endpoint == kOTInvalidEndpointRef )
+ {
+ if (errno == EWOULDBLOCK)
+ socket->m_error = GSOCK_WOULDBLOCK;
+ else
+ socket->m_error = GSOCK_IOERR;
+
+ GSocket_destroy(connection);
+ return NULL;
+ }
+
+ /* Initialize all fields */
+ connection->m_server = FALSE;
+ connection->m_stream = TRUE;
+ connection->m_oriented = TRUE;
+
+ /* Setup the peer address field */
+ connection->m_peer = GAddress_new();
+ if (!connection->m_peer)
+ {
+ GSocket_destroy(connection);
+ socket->m_error = GSOCK_MEMERR;
+ return NULL;
+ }
+ // TODO
+ #if 0
+ err = _GAddress_translate_from(connection->m_peer, &from, fromlen);
+ if (err != GSOCK_NOERROR)
+ {
+ GAddress_destroy(connection->m_peer);
+ GSocket_destroy(connection);
+ socket->m_error = err;
+ return NULL;
+ }
+
+ ioctl(connection->m_endpoint, FIONBIO, &arg);
+#endif
+ _GSocket_Enable_Events(connection);
+
+ return connection;
+}
+
+/* Datagram sockets */
+
+/* GSocket_SetNonOriented:
+ * Sets up this socket as a non-connection oriented (datagram) socket.
+ * Before using this function, the local address must have been set
+ * with GSocket_SetLocal(), or the call will fail. Returns GSOCK_NOERROR
+ * on success, or one of the following otherwise.
+ *
+ * Error codes:
+ * GSOCK_INVSOCK - the socket is in use.
+ * GSOCK_INVADDR - the local address has not been set.
+ * GSOCK_IOERR - low-level error.
+ */
+GSocketError GSocket_SetNonOriented(GSocket *sck)
+{
+ assert(sck != NULL);
+
+ if (sck->m_endpoint != kOTInvalidEndpointRef )
+ {
+ sck->m_error = GSOCK_INVSOCK;
+ return GSOCK_INVSOCK;
+ }
+
+ if (!sck->m_local)
+ {
+ sck->m_error = GSOCK_INVADDR;
+ return GSOCK_INVADDR;
+ }
+
+ /* Initialize all fields */
+ sck->m_stream = FALSE;
+ sck->m_server = FALSE;
+ sck->m_oriented = FALSE;
+
+ /* Create the socket */
+
+// TODO
+#if 0
+ sck->m_endpoint = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0);
+ socket_set_ref( sck->m_endpoint , (unsigned long) &gMacNetEvents , (unsigned long) sck ) ;
+#endif
+ if (sck->m_endpoint == kOTInvalidEndpointRef )
+ {
+ sck->m_error = GSOCK_IOERR;
+ return GSOCK_IOERR;
+ }
+
+// TODO
+#if 0
+ ioctl(sck->m_endpoint, FIONBIO, &arg);
+#endif
+ _GSocket_Enable_Events(sck);
+
+ /* Bind to the local address,
+ * and retrieve the actual address bound.
+ */
+// TODO
+#if 0
+ if ((bind(sck->m_endpoint, sck->m_local->m_addr, sck->m_local->m_len) != 0) ||
+ (getsockname(sck->m_endpoint,
+ sck->m_local->m_addr,
+ (SOCKLEN_T *) &sck->m_local->m_len) != 0))
+ {
+ close(sck->m_endpoint);
+ sck->m_endpoint = -1;
+ sck->m_error = GSOCK_IOERR;
+ return GSOCK_IOERR;
+ }
+#endif
+ return GSOCK_NOERROR;
+}
+
+/* Client specific parts */
+
+/* GSocket_Connect:
+ * For stream (connection oriented) sockets, GSocket_Connect() tries
+ * to establish a client connection to a server using the peer address
+ * as established with GSocket_SetPeer(). Returns GSOCK_NOERROR if the
+ * connection has been succesfully established, or one of the error
+ * codes listed below. Note that for nonblocking sockets, a return
+ * value of GSOCK_WOULDBLOCK doesn't mean a failure. The connection
+ * request can be completed later; you should use GSocket_Select()
+ * to poll for GSOCK_CONNECTION | GSOCK_LOST, or wait for the
+ * corresponding asynchronous events.
+ *
+ * For datagram (non connection oriented) sockets, GSocket_Connect()
+ * just sets the peer address established with GSocket_SetPeer() as
+ * default destination.
+ *
+ * Error codes:
+ * GSOCK_INVSOCK - the socket is in use or not valid.
+ * GSOCK_INVADDR - the peer address has not been established.
+ * GSOCK_TIMEDOUT - timeout, the connection failed.
+ * GSOCK_WOULDBLOCK - connection in progress (nonblocking sockets only)
+ * GSOCK_MEMERR - couldn't allocate memory.
+ * GSOCK_IOERR - low-level error.
+ */
+GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
+{
+ InetAddress addr ;
+ TEndpointInfo info;
+ OSStatus err = kOTNoError;
+ TCall peer ;
+
+ assert(sck != NULL);
+
+ /* Enable CONNECTION events (needed for nonblocking connections) */
+ sck->m_detected &= ~GSOCK_CONNECTION_FLAG;
+
+ if (sck->m_endpoint != kOTInvalidEndpointRef )
+ {
+ sck->m_error = GSOCK_INVSOCK;
+ return GSOCK_INVSOCK;
+ }
+
+ if (!sck->m_peer)
+ {
+ sck->m_error = GSOCK_INVADDR;
+ return GSOCK_INVADDR;
+ }
+
+ /* Streamed or dgram socket? */
+ sck->m_stream = (stream == GSOCK_STREAMED);
+ sck->m_oriented = TRUE;
+ sck->m_server = FALSE;
+
+ /* Create the socket */
+#if TARGET_CARBON
+ sck->m_endpoint =
+ OTOpenEndpointInContext( OTCreateConfiguration( kTCPName) , 0 , &info , &err , NULL ) ;
+#else
+ sck->m_endpoint =
+ OTOpenEndpoint( OTCreateConfiguration( kTCPName) , 0 , &info , &err ) ;
+#endif
+ if ( sck->m_endpoint == kOTInvalidEndpointRef || err != kOTNoError )
+ {
+ sck->m_endpoint = kOTInvalidEndpointRef ;
+ sck->m_error = GSOCK_IOERR;
+ return GSOCK_IOERR;
+ }
+ err = OTBind( sck->m_endpoint , nil , nil ) ;
+ if ( err != kOTNoError )
+ {
+ return GSOCK_IOERR;
+ }
+ SetDefaultEndpointModes( sck->m_endpoint , sck ) ;
+// TODO
+#if 0
+ ioctl(sck->m_endpoint, FIONBIO, &arg);
+#endif
+ _GSocket_Enable_Events(sck);
+
+ _GAddress_translate_to( sck->m_peer , &addr ) ;
+ memset( &peer , 0 , sizeof( TCall ) ) ;
+ peer.addr.len = sizeof( InetAddress ) ;
+ peer.addr.buf = (unsigned char*) &addr ;
+ err = OTConnect( sck->m_endpoint , &peer , nil ) ;
+ if ( err != noErr )
+ {
+ /* If connect failed with EINPROGRESS and the GSocket object
+ * is in blocking mode, we select() for the specified timeout
+ * checking for writability to see if the connection request
+ * completes.
+ */
+
+ if ((err == kOTNoDataErr ) && (!sck->m_non_blocking))
+ {
+ if (_GSocket_Output_Timeout(sck) == GSOCK_TIMEDOUT)
+ {
+ OTSndOrderlyDisconnect( sck->m_endpoint ) ;
+ sck->m_endpoint = kOTInvalidEndpointRef ;
+ /* sck->m_error is set in _GSocket_Output_Timeout */
+ return GSOCK_TIMEDOUT;
+ }
+ else
+ {
+/*
+ int error;
+ SOCKLEN_T len = sizeof(error);
+
+ getsockopt(sck->m_endpoint, SOL_SOCKET, SO_ERROR, (void*) &error, &len);
+
+ if (!error)
+*/
+ return GSOCK_NOERROR;
+ }
+ }
+
+ /* If connect failed with EINPROGRESS and the GSocket object
+ * is set to nonblocking, we set m_error to GSOCK_WOULDBLOCK
+ * (and return GSOCK_WOULDBLOCK) but we don't close the socket;
+ * this way if the connection completes, a GSOCK_CONNECTION
+ * event will be generated, if enabled.
+ */
+ if ((err == kOTNoDataErr) && (sck->m_non_blocking))
+ {
+ sck->m_error = GSOCK_WOULDBLOCK;
+ return GSOCK_WOULDBLOCK;
+ }
+
+ /* If connect failed with an error other than EINPROGRESS,
+ * then the call to GSocket_Connect has failed.
+ */
+ OTSndOrderlyDisconnect( sck->m_endpoint ) ;
+
+ sck->m_endpoint = kOTInvalidEndpointRef ;
+ sck->m_error = GSOCK_IOERR;
+ return GSOCK_IOERR;
+ }
+// OTInetEventHandler(sck, T_CONNECT , kOTNoError , NULL ) ;
+ return GSOCK_NOERROR;
+}
+
+/* Generic IO */
+
+/* Like recv(), send(), ... */
+int GSocket_Read(GSocket *socket, char *buffer, int size)
+{
+ int ret = 0 ;
+
+ assert(socket != NULL);
+
+ /* Reenable INPUT events */
+ socket->m_detected &= ~GSOCK_INPUT_FLAG;
+
+ if (socket->m_endpoint == kOTInvalidEndpointRef || socket->m_server)
+ {
+ socket->m_error = GSOCK_INVSOCK;
+ return -1;
+ }
+
+ /* If the socket is blocking, wait for data (with a timeout) */
+ if (_GSocket_Input_Timeout(socket) == GSOCK_TIMEDOUT)
+ return -1;
+
+ /* Read the data */
+ if (socket->m_stream)
+ ret = _GSocket_Recv_Stream(socket, buffer, size);
+ else
+ ret = _GSocket_Recv_Dgram(socket, buffer, size);
+
+ if (ret == -1)
+ {
+ if (errno == EWOULDBLOCK)
+ socket->m_error = GSOCK_WOULDBLOCK;
+ else
+ socket->m_error = GSOCK_IOERR;
+ }
+
+ return ret;
+}
+
+int GSocket_Write(GSocket *socket, const char *buffer, int size)
+{
+ int ret;
+
+ assert(socket != NULL);
+
+ if (socket->m_endpoint == kOTInvalidEndpointRef || socket->m_server)
+ {
+ socket->m_error = GSOCK_INVSOCK;
+ return -1;
+ }
+
+ /* If the socket is blocking, wait for writability (with a timeout) */
+ if (_GSocket_Output_Timeout(socket) == GSOCK_TIMEDOUT)
+ return -1;
+
+ /* Write the data */
+ if (socket->m_stream)
+ ret = _GSocket_Send_Stream(socket, buffer, size);
+ else
+ ret = _GSocket_Send_Dgram(socket, buffer, size);
+
+ if (ret == -1)
+ {
+ if (errno == EWOULDBLOCK)
+ socket->m_error = GSOCK_WOULDBLOCK;
+ else
+ socket->m_error = GSOCK_IOERR;
+
+ /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
+ * in MSW). Once the first OUTPUT event is received, users can assume
+ * that the socket is writable until a read operation fails. Only then
+ * will further OUTPUT events be posted.
+ */
+ socket->m_detected &= ~GSOCK_OUTPUT_FLAG;
+ return -1;
+ }
+
+ return ret;
+}
+
+/* GSocket_Select:
+ * Polls the socket to determine its status. This function will
+ * check for the events specified in the 'flags' parameter, and
+ * it will return a mask indicating which operations can be
+ * performed. This function won't block, regardless of the
+ * mode (blocking | nonblocking) of the socket.
+ */
+GSocketEventFlags GSocket_Select(GSocket *socket, GSocketEventFlags flags)
+{
+ assert(socket != NULL);
+ wxMacProcessNotifierEvents() ;
+ /*
+ state = OTGetEndpointState(socket->m_endpoint);
+
+ if ( ( flags & GSOCK_INPUT_FLAG ) && ! ( socket->m_detected & GSOCK_INPUT_FLAG ) )
+ {
+ size_t sz = 0 ;
+ OTCountDataBytes( socket->m_endpoint , &sz ) ;
+ if ( state == T_INCON || sz > 0 )
+ {
+ socket->m_detected |= GSOCK_INPUT_FLAG ;
+ (socket->m_cbacks[GSOCK_INPUT])(socket, GSOCK_INPUT, socket->m_data[GSOCK_INPUT]);
+ }
+ }
+ if ( ( flags & GSOCK_INPUT_FLAG ) && ! ( socket->m_detected & GSOCK_OUTPUT_FLAG ) )
+ {
+ if ( state == T_DATAXFER || state == T_INREL )
+ {
+ socket->m_detected |=GSOCK_OUTPUT_FLAG ;
+ (socket->m_cbacks[GSOCK_OUTPUT])(socket, GSOCK_OUTPUT, socket->m_data[GSOCK_OUTPUT]);
+ }
+ }
+ */
+ return ( flags & socket->m_detected ) ;
+}
+
+/* Flags */
+
+/* GSocket_SetNonBlocking:
+ * Sets the socket to non-blocking mode. All IO calls will return
+ * immediately.
+ */
+void GSocket_SetNonBlocking(GSocket *socket, int non_block)
+{
+ assert(socket != NULL);
+
+ socket->m_non_blocking = non_block;
+}
+
+/* GSocket_SetTimeout:
+ * Sets the timeout for blocking calls. Time is expressed in
+ * milliseconds.
+ */
+void GSocket_SetTimeout(GSocket *socket, unsigned long millisec)
+{
+ assert(socket != NULL);
+
+// this is usually set too high and we have not yet been able to detect a closed
+// stream, thus we leave the 10 sec timeout
+// socket->m_timeout = millisec;
+}
+
+/* GSocket_GetError:
+ * Returns the last error occured for this socket. Note that successful
+ * operations do not clear this back to GSOCK_NOERROR, so use it only
+ * after an error.
+ */
+GSocketError GSocket_GetError(GSocket *socket)
+{
+ assert(socket != NULL);
+
+ return socket->m_error;
+}
+
+/* Callbacks */
+
+/* GSOCK_INPUT:
+ * There is data to be read in the input buffer. If, after a read
+ * operation, there is still data available, the callback function will
+ * be called again.
+ * GSOCK_OUTPUT:
+ * The socket is available for writing. That is, the next write call
+ * won't block. This event is generated only once, when the connection is
+ * first established, and then only if a call failed with GSOCK_WOULDBLOCK,
+ * when the output buffer empties again. This means that the app should
+ * assume that it can write since the first OUTPUT event, and no more
+ * OUTPUT events will be generated unless an error occurs.
+ * GSOCK_CONNECTION:
+ * Connection succesfully established, for client sockets, or incoming
+ * client connection, for server sockets. Wait for this event (also watch
+ * out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call.
+ * GSOCK_LOST:
+ * The connection is lost (or a connection request failed); this could
+ * be due to a failure, or due to the peer closing it gracefully.
+ */
+
+/* GSocket_SetCallback:
+ * Enables the callbacks specified by 'flags'. Note that 'flags'
+ * may be a combination of flags OR'ed toghether, so the same
+ * callback function can be made to accept different events.
+ * The callback function must have the following prototype:
+ *
+ * void function(GSocket *socket, GSocketEvent event, char *cdata)
+ */
+void GSocket_SetCallback(GSocket *socket, GSocketEventFlags flags,
+ GSocketCallback callback, char *cdata)
+{
+ int count;
+
+ assert(socket != NULL);
+
+ for (count = 0; count < GSOCK_MAX_EVENT; count++)
+ {
+ if ((flags & (1 << count)) != 0)
+ {
+ socket->m_cbacks[count] = callback;
+ socket->m_data[count] = cdata;
+ }
+ }
+}
+
+/* GSocket_UnsetCallback:
+ * Disables all callbacks specified by 'flags', which may be a
+ * combination of flags OR'ed toghether.
+ */
+void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags flags)
+{
+ int count;
+
+ assert(socket != NULL);
+
+ for (count = 0; count < GSOCK_MAX_EVENT; count++)
+ {
+ if ((flags & (1 << count)) != 0)
+ {
+ socket->m_cbacks[count] = NULL;
+ socket->m_data[count] = NULL;
+ }
+ }
+}
+
+
+#define CALL_CALLBACK(socket, event) { \
+ _GSocket_Disable(socket, event); \
+ if (socket->m_cbacks[event]) \
+ socket->m_cbacks[event](socket, event, socket->m_data[event]); \
+}
+
+int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
+{
+ OTFlags flags ;
+ OTResult res ;
+ OTByteCount sz = 0 ;
+
+ OTCountDataBytes( socket->m_endpoint , &sz ) ;
+ if ( size > (int)sz )
+ size = sz ;
+ res = OTRcv( socket->m_endpoint , buffer , size , &flags ) ;
+ if ( res < 0 )
+ {
+ return -1 ;
+ }
+
+ // we simulate another read event if there are still bytes
+ if ( socket->m_takesEvents )
+ {
+ OTByteCount sz = 0 ;
+ OTCountDataBytes( socket->m_endpoint , &sz ) ;
+ if ( sz > 0 )
+ {
+ socket->m_detected |= GSOCK_INPUT_FLAG ;
+ (socket->m_cbacks[GSOCK_INPUT])(socket, GSOCK_INPUT, socket->m_data[GSOCK_INPUT]);
+ }
+ }
+ return res ;
+}
+
+int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
+{
+// TODO
+ int ret = -1;
+#if 0
+ struct sockaddr from;
+ SOCKLEN_T fromlen = sizeof(from);
+ GSocketError err;
+
+ fromlen = sizeof(from);
+
+ ret = recvfrom(socket->m_endpoint, buffer, size, 0, &from, (SOCKLEN_T *) &fromlen);
+
+ if (ret == -1)
+ return -1;
+
+ /* Translate a system address into a GSocket address */
+ if (!socket->m_peer)
+ {
+ socket->m_peer = GAddress_new();
+ if (!socket->m_peer)
+ {
+ socket->m_error = GSOCK_MEMERR;
+ return -1;
+ }
+ }
+ err = _GAddress_translate_from(socket->m_peer, &from, fromlen);
+ if (err != GSOCK_NOERROR)
+ {
+ GAddress_destroy(socket->m_peer);
+ socket->m_peer = NULL;
+ socket->m_error = err;
+ return -1;
+ }
+#endif
+ return ret;
+}
+
+int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
+{
+ OTFlags flags = 0 ;
+ OTResult res ;
+
+ res = OTSnd( socket->m_endpoint , (void*) buffer , size , flags ) ;
+ return res ;
+}
+
+int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
+{
+ int ret = -1 ;
+// TODO
+#if 0
+ struct sockaddr *addr;
+ int len ;
+ GSocketError err;
+
+ if (!socket->m_peer)
+ {
+ socket->m_error = GSOCK_INVADDR;
+ return -1;
+ }
+
+ err = _GAddress_translate_to(socket->m_peer, &addr, &len);
+ if (err != GSOCK_NOERROR)
+ {
+ socket->m_error = err;
+ return -1;
+ }
+
+ ret = sendto(socket->m_endpoint, buffer, size, 0, addr, len);
+
+ /* Frees memory allocated from _GAddress_translate_to */
+ free(addr);
+#endif
+ return ret;
+}
+
+
+/*
+ * -------------------------------------------------------------------------
+ * GAddress
+ * -------------------------------------------------------------------------
+ */
+
+/* CHECK_ADDRESS verifies that the current family is either GSOCK_NOFAMILY
+ * or GSOCK_*family*, and if it is GSOCK_NOFAMILY, it initalizes address
+ * to be a GSOCK_*family*. In other cases, it returns GSOCK_INVADDR.
+ */
+#define CHECK_ADDRESS(address, family, retval) \
+{ \
+ if (address->m_family == GSOCK_NOFAMILY) \
+ if (_GAddress_Init_##family(address) != GSOCK_NOERROR) \
+ return address->m_error; \
+ if (address->m_family != GSOCK_##family) \
+ { \
+ address->m_error = GSOCK_INVADDR; \
+ return retval; \
+ } \
+}
+
+GAddress *GAddress_new()
+{
+ GAddress *address;
+
+ if ((address = (GAddress *) malloc(sizeof(GAddress))) == NULL)
+ return NULL;
+
+ address->m_family = GSOCK_NOFAMILY;
+ address->m_host = INADDR_NONE ;
+ address->m_port = 0 ;
+
+ return address;
+}
+
+GAddress *GAddress_copy(GAddress *address)
+{
+ GAddress *addr2;
+
+ assert(address != NULL);
+
+ if ((addr2 = (GAddress *) malloc(sizeof(GAddress))) == NULL)
+ return NULL;
+
+ memcpy(addr2, address, sizeof(GAddress));
+ return addr2;
+}
+
+void GAddress_destroy(GAddress *address)
+{
+ assert(address != NULL);
+
+ free(address);
+}
+
+void GAddress_SetFamily(GAddress *address, GAddressType type)
+{
+ assert(address != NULL);
+
+ address->m_family = type;
+}
+
+GAddressType GAddress_GetFamily(GAddress *address)
+{
+ assert(address != NULL);
+
+ return address->m_family;
+}
+
+GSocketError _GAddress_translate_from(GAddress *address,
+ InetAddress *addr)
+{
+ switch (addr->fAddressType)
+ {
+ case AF_INET:
+ address->m_family = GSOCK_INET;
+ break;
+#ifdef AF_INET6
+ case AF_INET6:
+ address->m_family = GSOCK_INET6;
+ break;
+#endif
+ default:
+ {
+ address->m_error = GSOCK_INVOP;
+ return GSOCK_INVOP;
+ }
+ }
+ address->m_host = addr->fHost ;
+ address->m_port = addr->fPort ;
+ return GSOCK_NOERROR;
+}
+
+GSocketError _GAddress_translate_to(GAddress *address,
+ InetAddress *addr)
+{
+ if ( GSocket_Verify_Inited() == FALSE )
+ return GSOCK_IOERR ;
+ memset(addr, 0 , sizeof(struct InetAddress));
+ OTInitInetAddress( addr , address->m_port , address->m_host ) ;
+ return GSOCK_NOERROR;
+}
+
+/*
+ * -------------------------------------------------------------------------
+ * Internet address family
+ * -------------------------------------------------------------------------
+ */
+
+GSocketError _GAddress_Init_INET(GAddress *address)
+{
+ address->m_family = GSOCK_INET;
+ address->m_host = kOTAnyInetAddress ;
+
+ return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
+{
+ InetHostInfo hinfo ;
+ OSStatus ret ;
+
+ if ( GSocket_Verify_Inited() == FALSE )
+ return GSOCK_IOERR ;
+
+ assert(address != NULL);
+
+ CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
+ ret = OTInetStringToAddress( gInetSvcRef , (char*) hostname , &hinfo ) ;
+ if ( ret != kOTNoError )
+ {
+ address->m_host = INADDR_NONE ;
+ address->m_error = GSOCK_NOHOST;
+ return GSOCK_NOHOST;
+ }
+ address->m_host = hinfo.addrs[0] ;
+ return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_INET_SetAnyAddress(GAddress *address)
+{
+ return GAddress_INET_SetHostAddress(address, INADDR_ANY);
+}
+
+GSocketError GAddress_INET_SetHostAddress(GAddress *address,
+ unsigned long hostaddr)
+{
+ assert(address != NULL);
+
+ CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
+
+ address->m_host = hostaddr ;
+
+ return GSOCK_NOERROR;
+}
+
+struct service_entry
+{
+ char * name ;
+ unsigned short port ;
+ char * protocol ;
+} ;
+typedef struct service_entry service_entry ;
+
+service_entry gServices[] =
+{
+ { "http" , 80 , "tcp" }
+} ;
+
+GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
+ const char *protocol)
+{
+ size_t i ;
+
+ assert(address != NULL);
+ CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
+
+ if (!port)
+ {
+ address->m_error = GSOCK_INVPORT;
+ return GSOCK_INVPORT;
+ }
+ for ( i = 0 ; i < sizeof( gServices) / sizeof( service_entry ) ; ++i )
+ {
+ if ( strcmp( port , gServices[i].name ) == 0 )
+ {
+ if ( protocol == NULL || strcmp( protocol , gServices[i].protocol ) )
+ {
+ address->m_port = gServices[i].port ;
+ return GSOCK_NOERROR;
+ }
+ }
+ }
+
+ if (isdigit(port[0]))
+ {
+ address->m_port = atoi(port);
+ return GSOCK_NOERROR;
+ }
+
+ address->m_error = GSOCK_INVPORT;
+ return GSOCK_INVPORT;
+}
+
+GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
+{
+ assert(address != NULL);
+ CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
+ address->m_port = port ;
+
+ return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
+{
+ InetDomainName name ;
+ if ( GSocket_Verify_Inited() == FALSE )
+ return GSOCK_IOERR ;
+
+ assert(address != NULL);
+ CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
+
+ OTInetAddressToName( gInetSvcRef , address->m_host , name ) ;
+ strncpy( hostname , name , sbuf ) ;
+ return GSOCK_NOERROR;
+}
+
+unsigned long GAddress_INET_GetHostAddress(GAddress *address)
+{
+ assert(address != NULL);
+ CHECK_ADDRESS(address, INET, 0);
+
+ return address->m_host;
+}
+
+unsigned short GAddress_INET_GetPort(GAddress *address)
+{
+ assert(address != NULL);
+ CHECK_ADDRESS(address, INET, 0);
+
+ return address->m_port;
+}
+
+void _GSocket_Enable_Events(GSocket *socket)
+{
+ if ( socket->m_takesEvents )
+ return ;
+
+ {
+ OTResult state ;
+ socket->m_takesEvents = TRUE ;
+ state = OTGetEndpointState(socket->m_endpoint);
+
+ {
+ OTByteCount sz = 0 ;
+ OTCountDataBytes( socket->m_endpoint , &sz ) ;
+ if ( state == T_INCON || sz > 0 )
+ {
+ socket->m_detected |= GSOCK_INPUT_FLAG ;
+ (socket->m_cbacks[GSOCK_INPUT])(socket, GSOCK_INPUT, socket->m_data[GSOCK_INPUT]);
+ }
+ }
+ {
+ if ( state == T_DATAXFER || state == T_INREL )
+ {
+ socket->m_detected |=GSOCK_OUTPUT_FLAG ;
+ (socket->m_cbacks[GSOCK_OUTPUT])(socket, GSOCK_OUTPUT, socket->m_data[GSOCK_OUTPUT]);
+ }
+ }
+ }
+}
+
+void _GSocket_Disable_Events(GSocket *socket)
+{
+ socket->m_takesEvents = FALSE ;
+}
+
+/* _GSocket_Input_Timeout:
+ * For blocking sockets, wait until data is available or
+ * until timeout ellapses.
+ */
+GSocketError _GSocket_Input_Timeout(GSocket *socket)
+{
+ if ( !socket->m_non_blocking )
+ {
+ UnsignedWide now , start ;
+ short formerTakesEvents = socket->m_takesEvents ;
+ Microseconds(&start);
+ now = start ;
+ socket->m_takesEvents = FALSE ;
+
+ while( (now.hi * 4294967296.0 + now.lo) - (start.hi * 4294967296.0 + start.lo) < socket->m_timeout * 1000.0 )
+ {
+ OTResult state ;
+ OTByteCount sz = 0 ;
+ state = OTGetEndpointState(socket->m_endpoint);
+
+ OTCountDataBytes( socket->m_endpoint , &sz ) ;
+ if ( state == T_INCON || sz > 0 )
+ {
+ socket->m_takesEvents = formerTakesEvents ;
+ return GSOCK_NOERROR;
+ }
+ Microseconds(&now);
+ }
+ socket->m_takesEvents = formerTakesEvents ;
+ socket->m_error = GSOCK_TIMEDOUT;
+ return GSOCK_TIMEDOUT;
+ }
+ return GSOCK_NOERROR;
+}
+
+/* _GSocket_Output_Timeout:
+ * For blocking sockets, wait until data can be sent without
+ * blocking or until timeout ellapses.
+ */
+GSocketError _GSocket_Output_Timeout(GSocket *socket)
+{
+ if ( !socket->m_non_blocking )
+ {
+ UnsignedWide now , start ;
+ short formerTakesEvents = socket->m_takesEvents ;
+ Microseconds(&start);
+ now = start ;
+ socket->m_takesEvents = FALSE ;
+
+ while( (now.hi * 4294967296.0 + now.lo) - (start.hi * 4294967296.0 + start.lo) < socket->m_timeout * 1000.0 )
+ {
+ OTResult state ;
+ state = OTGetEndpointState(socket->m_endpoint);
+
+ if ( state == T_DATAXFER || state == T_INREL )
+ {
+ socket->m_takesEvents = formerTakesEvents ;
+ return GSOCK_NOERROR;
+ }
+ Microseconds(&now);
+ }
+ socket->m_takesEvents = formerTakesEvents ;
+ socket->m_error = GSOCK_TIMEDOUT;
+ return GSOCK_TIMEDOUT;
+ }
+ return GSOCK_NOERROR;
+}
+
+/* GSOCK_INPUT:
+ * There is data to be read in the input buffer. If, after a read
+ * operation, there is still data available, the callback function will
+ * be called again.
+ * GSOCK_OUTPUT:
+ * The socket is available for writing. That is, the next write call
+ * won't block. This event is generated only once, when the connection is
+ * first established, and then only if a call failed with GSOCK_WOULDBLOCK,
+ * when the output buffer empties again. This means that the app should
+ * assume that it can write since the first OUTPUT event, and no more
+ * OUTPUT events will be generated unless an error occurs.
+ * GSOCK_CONNECTION:
+ * Connection succesfully established, for client sockets, or incoming
+ * client connection, for server sockets. Wait for this event (also watch
+ * out for GSOCK_LOST) after you issue a nonblocking GSocket_Connect() call.
+ * GSOCK_LOST:
+ * The connection is lost (or a connection request failed); this could
+ * be due to a failure, or due to the peer closing it gracefully.
+ */
+
+void _GSocket_Internal_Proc(unsigned long e , void* d )
+{
+
+ GSocket * socket = (GSocket*) d ;
+ OTEventCode ev = (OTEventCode) e ;
+ GSocketEvent event;
+ GSocketEvent event2;
+ GSocketCallback cback;
+ char *data;
+ GSocketCallback cback2;
+ char *data2;
+
+ if ( !socket )
+ return ;
+ event = GSOCK_MAX_EVENT ;
+ event2 = GSOCK_MAX_EVENT ;
+ cback = NULL;
+ data = NULL;
+ cback2 = NULL;
+ data2 = NULL;
+
+ /* Check that the socket still exists (it has not been
+ * destroyed) and for safety, check that the m_endpoint field
+ * is what we expect it to be.
+ */
+ if ((socket != NULL) && (socket->m_takesEvents))
+ {
+ switch (ev)
+ {
+ case T_LISTEN :
+ event = GSOCK_CONNECTION ;
+ break ;
+ case T_CONNECT :
+ event = GSOCK_CONNECTION ;
+ event2 = GSOCK_OUTPUT ;
+ {
+ TCall retCall;
+
+ retCall.addr.buf = NULL;
+ retCall.addr.maxlen = 0;
+ retCall.opt.buf = NULL;
+ retCall.opt.maxlen = 0;
+ retCall.udata.buf = NULL;
+ retCall.udata.maxlen= 0;
+ OTRcvConnect( socket->m_endpoint , &retCall ) ;
+ }
+ break ;
+ case T_DISCONNECT :
+ event = GSOCK_LOST ;
+ break ;
+ case T_GODATA :
+ case T_GOEXDATA :
+ event = GSOCK_OUTPUT ;
+ break ;
+ case T_DATA :
+ event = GSOCK_INPUT ;
+ break ;
+ case T_EXDATA :
+ event = GSOCK_INPUT ;
+ break ;
+ }
+ if (event != GSOCK_MAX_EVENT)
+ {
+ cback = socket->m_cbacks[event];
+ data = socket->m_data[event];
+
+ if (event == GSOCK_LOST)
+ socket->m_detected = GSOCK_LOST_FLAG;
+ else
+ socket->m_detected |= (1 << event);
+ }
+ if (event2 != GSOCK_MAX_EVENT)
+ {
+ cback2 = socket->m_cbacks[event2];
+ data2 = socket->m_data[event2];
+
+ if (event2 == GSOCK_LOST)
+ socket->m_detected = GSOCK_LOST_FLAG;
+ else
+ socket->m_detected |= (1 << event2);
+ }
+ }
+
+ /* OK, we can now leave the critical section because we have
+ * already obtained the callback address (we make no further
+ * accesses to socket->whatever). However, the app should
+ * be prepared to handle events from a socket that has just
+ * been closed!
+ */
+
+ if (cback != NULL)
+ (cback)(socket, event, data);
+ if (cback2 != NULL)
+ (cback2)(socket, event2, data2);
+
+}
+
+/* Hack added for Mac OS X */
+GSocketError GAddress_UNIX_GetPath(GAddress *addr, char *path, size_t buf)
+{
+ return GSOCK_INVADDR;
+}
+
+GSocketError GAddress_UNIX_SetPath(GAddress *addr, const char *path)
+{
+ return GSOCK_INVADDR;
+}
+
+#endif /* wxUSE_SOCKETS || defined(__GSOCKET_STANDALONE__) */
--- /dev/null
+/* -------------------------------------------------------------------------
+ * Project: GSocket (Generic Socket) for WX
+ * Name: gsockosx.c
+ * Purpose: GSocket: Mac OS X mach-o part
+ * CVSID: $Id$
+ * Mac code by Brian Victor, February 2002. Email comments to bhv1@psu.edu
+ * ------------------------------------------------------------------------- */
+
+#include "wx/setup.h"
+
+#if wxUSE_SOCKETS
+
+#include <stdlib.h>
+#include "wx/gsocket.h"
+#include "wx/unix/gsockunx.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#define ALL_CALLBACK_TYPES (kCFSocketReadCallBack | kCFSocketWriteCallBack | kCFSocketConnectCallBack)
+
+struct MacGSocketData
+{
+ CFSocketRef socket;
+ CFRunLoopSourceRef source;
+};
+
+void Mac_Socket_Callback(CFSocketRef s, CFSocketCallBackType callbackType,
+ CFDataRef address, const void* data, void* info)
+{
+ GSocket* socket = (GSocket*)info;
+ struct MacGSocketData* macdata;
+ macdata = (struct MacGSocketData*)socket->m_gui_dependent;
+ if (!macdata) return;
+ switch (callbackType)
+ {
+ case kCFSocketConnectCallBack:
+ assert(!socket->m_server);
+ socket->m_functions->Detected_Write(socket);
+ break;
+ case kCFSocketReadCallBack:
+ socket->m_functions->Detected_Read(socket);
+ break;
+ case kCFSocketWriteCallBack:
+ socket->m_functions->Detected_Write(socket);
+ break;
+ default:
+ break; /* We shouldn't get here. */
+ }
+}
+
+struct MacGSocketData* _GSocket_Get_Mac_Socket(GSocket *socket)
+{
+ /* If socket is already created, returns a pointer to the data */
+ /* Otherwise, creates socket and returns the pointer */
+ CFSocketContext cont;
+ struct MacGSocketData* data = (struct MacGSocketData*)socket->m_gui_dependent;
+
+ if (data && data->source) return data;
+
+ /* CFSocket has not been created, create it: */
+ if (socket->m_fd < 0 || !data) return NULL;
+ cont.version = 0; cont.retain = NULL;
+ cont.release = NULL; cont.copyDescription = NULL;
+ cont.info = socket;
+
+ CFSocketRef cf = CFSocketCreateWithNative(NULL, socket->m_fd,
+ ALL_CALLBACK_TYPES, Mac_Socket_Callback, &cont);
+ CFRunLoopSourceRef source = CFSocketCreateRunLoopSource(NULL, cf, 0);
+ assert(source);
+ socket->m_gui_dependent = (char*)data;
+
+ /* Keep the source and the socket around. */
+ data->source = source;
+ data->socket = cf;
+
+ return data;
+}
+
+int _GSocket_GUI_Init(void)
+{
+ return 1;
+}
+
+void _GSocket_GUI_Cleanup(void)
+{
+}
+
+int _GSocket_GUI_Init_Socket(GSocket *socket)
+{
+ struct MacGSocketData *data = malloc(sizeof(struct MacGSocketData));
+ if (data)
+ {
+ socket->m_gui_dependent = (char*)data;
+ data->socket = NULL;
+ data->source = NULL;
+ return 1;
+ }
+ return 0;
+}
+
+void _GSocket_GUI_Destroy_Socket(GSocket *socket)
+{
+ struct MacGSocketData *data = (struct MacGSocketData*)(socket->m_gui_dependent);
+ if (data)
+ {
+ CFRelease(data->socket);
+ free(data);
+ }
+}
+
+void _GSocket_Install_Callback(GSocket *socket, GSocketEvent event)
+{
+ int c;
+ struct MacGSocketData* data = _GSocket_Get_Mac_Socket(socket);
+ if (!data) return;
+ switch (event)
+ {
+ case GSOCK_CONNECTION:
+ if(socket->m_server)
+ c = kCFSocketReadCallBack;
+ else
+ c = kCFSocketConnectCallBack;
+ break;
+ case GSOCK_LOST:
+ case GSOCK_INPUT:
+ c = kCFSocketReadCallBack;
+ break;
+ case GSOCK_OUTPUT:
+ c = kCFSocketWriteCallBack;
+ break;
+ default:
+ c = 0;
+ }
+ CFSocketEnableCallBacks(data->socket, c);
+}
+
+void _GSocket_Uninstall_Callback(GSocket *socket, GSocketEvent event)
+{
+ int c;
+ struct MacGSocketData* data = _GSocket_Get_Mac_Socket(socket);
+ if (!data) return;
+ switch (event)
+ {
+ case GSOCK_CONNECTION:
+ if(socket->m_server)
+ c = kCFSocketReadCallBack;
+ else
+ c = kCFSocketConnectCallBack;
+ break;
+ case GSOCK_LOST:
+ case GSOCK_INPUT:
+ c = kCFSocketReadCallBack;
+ break;
+ case GSOCK_OUTPUT:
+ c = kCFSocketWriteCallBack;
+ break;
+ default:
+ c = 0;
+ }
+ CFSocketDisableCallBacks(data->socket, c);
+}
+
+void _GSocket_Enable_Events(GSocket *socket)
+{
+ struct MacGSocketData* data = _GSocket_Get_Mac_Socket(socket);
+ if (!data) return;
+
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), data->source, kCFRunLoopDefaultMode);
+}
+
+void _GSocket_Disable_Events(GSocket *socket)
+{
+ struct MacGSocketData* data = _GSocket_Get_Mac_Socket(socket);
+ if (!data) return;
+
+ /* CFSocketInvalidate does CFRunLoopRemoveSource anyway */
+ CFRunLoopRemoveSource(CFRunLoopGetCurrent(), data->source, kCFRunLoopCommonModes);
+ CFSocketInvalidate(data->socket);
+}
+
+#endif // wxUSE_SOCKETS
--- /dev/null
+/* -------------------------------------------------------------------------
+ * Project: GSocket (Generic Socket) for WX
+ * Name: gsockosx.c
+ * Purpose: GSocket: Mac OS X mach-o part
+ * CVSID: $Id$
+ * Mac code by Brian Victor, February 2002. Email comments to bhv1@psu.edu
+ * ------------------------------------------------------------------------- */
+
+#include "wx/setup.h"
+
+#if wxUSE_SOCKETS
+
+#include <stdlib.h>
+#include "wx/gsocket.h"
+#include "wx/unix/gsockunx.h"
+
+#include <CoreFoundation/CoreFoundation.h>
+
+#define ALL_CALLBACK_TYPES (kCFSocketReadCallBack | kCFSocketWriteCallBack | kCFSocketConnectCallBack)
+
+struct MacGSocketData
+{
+ CFSocketRef socket;
+ CFRunLoopSourceRef source;
+};
+
+void Mac_Socket_Callback(CFSocketRef s, CFSocketCallBackType callbackType,
+ CFDataRef address, const void* data, void* info)
+{
+ GSocket* socket = (GSocket*)info;
+ struct MacGSocketData* macdata;
+ macdata = (struct MacGSocketData*)socket->m_gui_dependent;
+ if (!macdata) return;
+ switch (callbackType)
+ {
+ case kCFSocketConnectCallBack:
+ assert(!socket->m_server);
+ socket->m_functions->Detected_Write(socket);
+ break;
+ case kCFSocketReadCallBack:
+ socket->m_functions->Detected_Read(socket);
+ break;
+ case kCFSocketWriteCallBack:
+ socket->m_functions->Detected_Write(socket);
+ break;
+ default:
+ break; /* We shouldn't get here. */
+ }
+}
+
+struct MacGSocketData* _GSocket_Get_Mac_Socket(GSocket *socket)
+{
+ /* If socket is already created, returns a pointer to the data */
+ /* Otherwise, creates socket and returns the pointer */
+ CFSocketContext cont;
+ struct MacGSocketData* data = (struct MacGSocketData*)socket->m_gui_dependent;
+
+ if (data && data->source) return data;
+
+ /* CFSocket has not been created, create it: */
+ if (socket->m_fd < 0 || !data) return NULL;
+ cont.version = 0; cont.retain = NULL;
+ cont.release = NULL; cont.copyDescription = NULL;
+ cont.info = socket;
+
+ CFSocketRef cf = CFSocketCreateWithNative(NULL, socket->m_fd,
+ ALL_CALLBACK_TYPES, Mac_Socket_Callback, &cont);
+ CFRunLoopSourceRef source = CFSocketCreateRunLoopSource(NULL, cf, 0);
+ assert(source);
+ socket->m_gui_dependent = (char*)data;
+
+ /* Keep the source and the socket around. */
+ data->source = source;
+ data->socket = cf;
+
+ return data;
+}
+
+int _GSocket_GUI_Init(void)
+{
+ return 1;
+}
+
+void _GSocket_GUI_Cleanup(void)
+{
+}
+
+int _GSocket_GUI_Init_Socket(GSocket *socket)
+{
+ struct MacGSocketData *data = malloc(sizeof(struct MacGSocketData));
+ if (data)
+ {
+ socket->m_gui_dependent = (char*)data;
+ data->socket = NULL;
+ data->source = NULL;
+ return 1;
+ }
+ return 0;
+}
+
+void _GSocket_GUI_Destroy_Socket(GSocket *socket)
+{
+ struct MacGSocketData *data = (struct MacGSocketData*)(socket->m_gui_dependent);
+ if (data)
+ {
+ CFRelease(data->socket);
+ free(data);
+ }
+}
+
+void _GSocket_Install_Callback(GSocket *socket, GSocketEvent event)
+{
+ int c;
+ struct MacGSocketData* data = _GSocket_Get_Mac_Socket(socket);
+ if (!data) return;
+ switch (event)
+ {
+ case GSOCK_CONNECTION:
+ if(socket->m_server)
+ c = kCFSocketReadCallBack;
+ else
+ c = kCFSocketConnectCallBack;
+ break;
+ case GSOCK_LOST:
+ case GSOCK_INPUT:
+ c = kCFSocketReadCallBack;
+ break;
+ case GSOCK_OUTPUT:
+ c = kCFSocketWriteCallBack;
+ break;
+ default:
+ c = 0;
+ }
+ CFSocketEnableCallBacks(data->socket, c);
+}
+
+void _GSocket_Uninstall_Callback(GSocket *socket, GSocketEvent event)
+{
+ int c;
+ struct MacGSocketData* data = _GSocket_Get_Mac_Socket(socket);
+ if (!data) return;
+ switch (event)
+ {
+ case GSOCK_CONNECTION:
+ if(socket->m_server)
+ c = kCFSocketReadCallBack;
+ else
+ c = kCFSocketConnectCallBack;
+ break;
+ case GSOCK_LOST:
+ case GSOCK_INPUT:
+ c = kCFSocketReadCallBack;
+ break;
+ case GSOCK_OUTPUT:
+ c = kCFSocketWriteCallBack;
+ break;
+ default:
+ c = 0;
+ }
+ CFSocketDisableCallBacks(data->socket, c);
+}
+
+void _GSocket_Enable_Events(GSocket *socket)
+{
+ struct MacGSocketData* data = _GSocket_Get_Mac_Socket(socket);
+ if (!data) return;
+
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), data->source, kCFRunLoopDefaultMode);
+}
+
+void _GSocket_Disable_Events(GSocket *socket)
+{
+ struct MacGSocketData* data = _GSocket_Get_Mac_Socket(socket);
+ if (!data) return;
+
+ /* CFSocketInvalidate does CFRunLoopRemoveSource anyway */
+ CFRunLoopRemoveSource(CFRunLoopGetCurrent(), data->source, kCFRunLoopCommonModes);
+ CFSocketInvalidate(data->socket);
+}
+
+#endif // wxUSE_SOCKETS
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: helpxxxx.cpp
+// Purpose: Help system: native implementation
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "helpxxxx.h"
+#endif
+
+#include "wx/stubs/helpxxxx.h"
+
+#include <string.h>
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxXXXXHelpController, wxHelpControllerBase)
+#endif
+
+wxXXXXHelpController::wxXXXXHelpController()
+{
+ m_helpFile = "";
+}
+
+wxXXXXHelpController::~wxXXXXHelpController()
+{
+}
+
+bool wxXXXXHelpController::Initialize(const wxString& filename)
+{
+ m_helpFile = filename;
+ // TODO any other inits
+ return TRUE;
+}
+
+bool wxXXXXHelpController::LoadFile(const wxString& file)
+{
+ m_helpFile = file;
+ // TODO
+ return TRUE;
+}
+
+bool wxXXXXHelpController::DisplayContents()
+{
+ // TODO
+ return FALSE;
+}
+
+bool wxXXXXHelpController::DisplaySection(int section)
+{
+ // TODO
+ return FALSE;
+}
+
+bool wxXXXXHelpController::DisplayBlock(long block)
+{
+ // TODO
+ return FALSE;
+}
+
+bool wxXXXXHelpController::KeywordSearch(const wxString& k,
+ wxHelpSearchMode WXUNUSED(mode))
+{
+ if (m_helpFile == "") return FALSE;
+
+ // TODO
+ return FALSE;
+}
+
+// Can't close the help window explicitly in WinHelp
+bool wxXXXXHelpController::Quit()
+{
+ // TODO
+ return FALSE;
+}
+
+void wxXXXXHelpController::OnQuit()
+{
+}
+
--- /dev/null
+#include "hid.h"
+
+#define wxFORCECHECK_MSG(arg, msg) \
+{\
+ if (arg) \
+ {\
+ wxLogSysError(wxString::Format(wxT("Message:%s\nHID: %s failed!"), wxT(msg), wxT(#arg)));\
+ return false;\
+ }\
+}
+#define wxIOCHECK(arg, msg) wxFORCECHECK_MSG(arg != kIOReturnSuccess, msg)
+#define wxKERNCHECK(arg, msg) wxFORCECHECK_MSG(arg != KERN_SUCCESS, msg)
+#define wxSCHECK(arg, msg) wxFORCECHECK_MSG(arg != S_OK, msg)
+
+void CFShowTypeIDDescription(CFTypeRef pData)
+{
+ if(!pData)
+ {
+ wxMessageBox("AHHH!");
+ return;
+ }
+
+ wxMessageBox(
+ CFStringGetCStringPtr(
+ CFCopyTypeIDDescription(CFGetTypeID(pData)),CFStringGetSystemEncoding()
+ )
+ );
+}
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+
+bool wxHIDDevice::Create (const int& nClass, const int& nType)
+{
+ //Create the mach port
+ wxIOCHECK(IOMasterPort(bootstrap_port, &m_pPort), "Could not create mach port");
+
+ //Dictionary that will hold first
+ //the matching dictionary for determining which kind of devices we want,
+ //then later some registry properties from an iterator (see below)
+ CFMutableDictionaryRef pDictionary;
+
+ //Create a dictionary
+ //The call to IOServiceMatching filters down the
+ //the services we want to hid services (and also eats the
+ //dictionary up for us (consumes one reference))
+ wxASSERT((pDictionary = IOServiceMatching(kIOHIDDeviceKey)) != NULL );
+
+ //Here we'll filter down the services to what we want
+ if (nType != -1)
+ {
+ CFNumberRef pType = CFNumberCreate(kCFAllocatorDefault,
+ kCFNumberIntType, &nType);
+ CFDictionarySetValue(pDictionary, CFSTR(kIOHIDPrimaryUsageKey), pType);
+ CFRelease(pType);
+ }
+ if (nClass != -1)
+ {
+ CFNumberRef pClass = CFNumberCreate(kCFAllocatorDefault,
+ kCFNumberIntType, &nClass);
+ CFDictionarySetValue(pDictionary, CFSTR(kIOHIDPrimaryUsagePageKey), pClass);
+ CFRelease(pClass);
+ }
+
+ //Now get the maching services
+ io_iterator_t pIterator;
+ wxIOCHECK(IOServiceGetMatchingServices(m_pPort, pDictionary, &pIterator), "No Matching HID Services");
+ wxASSERT(pIterator != NULL);
+
+ //Now we iterate through them
+ io_object_t pObject;
+ while ( (pObject = IOIteratorNext(pIterator)) != NULL)
+ {
+ wxASSERT(IORegistryEntryCreateCFProperties(pObject, &pDictionary,
+ kCFAllocatorDefault, kNilOptions) == KERN_SUCCESS);
+
+ //Just for sanity :)
+ wxASSERT(CFGetTypeID(CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductKey))) == CFStringGetTypeID());
+
+ //Get [product] name
+ m_szName = CFStringGetCStringPtr (
+ (CFStringRef) CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDProductKey)),
+ CFStringGetSystemEncoding()
+ );
+
+ //
+ //Now the hard part - in order to scan things we need "cookies" -
+ //
+ wxCFArray CookieArray = CFDictionaryGetValue(pDictionary, CFSTR(kIOHIDElementKey));
+ BuildCookies(CookieArray);
+ if (m_ppQueue != NULL)
+ wxASSERT((*m_ppQueue)->start(m_ppQueue) == S_OK);
+
+ //Create the interface (good grief - long function names!)
+ SInt32 nScore;
+ IOCFPlugInInterface** ppPlugin;
+ wxIOCHECK(IOCreatePlugInInterfaceForService(pObject, kIOHIDDeviceUserClientTypeID,
+ kIOCFPlugInInterfaceID, &ppPlugin, &nScore), "");
+
+ //Now, the final thing we can check before we fall back to asserts
+ //(because the dtor only checks if the device is ok, so if anything
+ //fails from now on the dtor will delete the device anyway, so we can't break from this).
+
+ //Get the HID interface from the plugin to the mach port
+ wxSCHECK((*ppPlugin)->QueryInterface(ppPlugin,
+ CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), (void**) &m_ppDevice), "");
+
+ //release the plugin
+ (*ppPlugin)->Release(ppPlugin);
+
+ //open the HID interface...
+ wxASSERT((*m_ppDevice)->open(m_ppDevice, 0) == S_OK);
+
+ //cleanup
+ CFRelease(pDictionary);
+ IOObjectRelease(pObject);
+ break;
+ }
+ //iterator cleanup
+ IOObjectRelease(pIterator);
+
+ return true;
+}//end Create()
+
+void wxHIDDevice::AddCookie(CFTypeRef Data, const int& i)
+{
+ CFNumberGetValue(
+ (CFNumberRef) CFDictionaryGetValue ( (CFDictionaryRef) Data
+ , CFSTR(kIOHIDElementCookieKey)
+ ),
+ kCFNumberIntType,
+ &m_pCookies[i]
+ );
+}
+
+void wxHIDDevice::AddCookieInQueue(CFTypeRef Data, const int& i)
+{
+ AddCookie(Data, i);
+ wxASSERT((*m_ppQueue)->addElement(m_ppQueue, m_pCookies[i], 0) == S_OK);//3rd Param flags (none yet)
+}
+
+void wxHIDDevice::InitCookies(const size_t& dwSize, bool bQueue)
+{
+ m_pCookies = new IOHIDElementCookie[dwSize];
+ if (bQueue)
+ {
+ wxASSERT( m_ppQueue != NULL);
+ wxASSERT( (m_ppQueue = (*m_ppDevice)->allocQueue(m_ppDevice)) != NULL);
+ wxASSERT( (*m_ppQueue)->create(m_ppQueue, 0, 512) == S_OK); //Param 2, flags, none yet
+ }
+}
+
+bool wxHIDDevice::IsActive(const int& nIndex)
+{
+ wxASSERT(m_pCookies[nIndex] != NULL);
+ IOHIDEventStruct Event;
+ (*m_ppDevice)->getElementValue(m_ppDevice, m_pCookies[nIndex], &Event);
+ return !!Event.value;
+}
+
+
+wxHIDDevice::~wxHIDDevice()
+{
+ if (m_ppDevice != NULL)
+ {
+ (*m_ppDevice)->close(m_ppDevice);
+ (*m_ppDevice)->Release(m_ppDevice);
+ mach_port_deallocate(mach_task_self(), m_pPort);
+ }
+
+ if (m_pCookies != NULL)
+ {
+ delete [] m_pCookies;
+ if (m_ppQueue != NULL)
+ {
+ (*m_ppQueue)->stop(m_ppQueue);
+ (*m_ppQueue)->dispose(m_ppQueue);
+ (*m_ppQueue)->Release(m_ppQueue);
+ }
+ }
+}
+/*
+enum
+{
+ kHIDUsage_KeyboardHyphen = 0x2D,
+ kHIDUsage_KeyboardEqualSign = 0x2E,
+ kHIDUsage_KeyboardOpenBracket = 0x2F,
+ kHIDUsage_KeyboardCloseBracket = 0x30,
+ kHIDUsage_KeyboardBackslash = 0x31, //* \ or | *
+ kHIDUsage_KeyboardNonUSPound = 0x32, /* Non-US # or _ *
+ kHIDUsage_KeyboardSemicolon = 0x33, /* ; or : *
+ kHIDUsage_KeyboardQuote = 0x34, /* ' or " *
+ kHIDUsage_KeyboardGraveAccentAndTilde = 0x35, /* Grave Accent and Tilde *
+ kHIDUsage_KeyboardComma = 0x36, /* , or < *
+ kHIDUsage_KeyboardPeriod = 0x37, /* . or > *
+ kHIDUsage_KeyboardSlash = 0x38, /* / or ? *
+ kHIDUsage_KeyboardCapsLock = 0x39, /* Caps Lock *
+
+ kHIDUsage_KeyboardPrintScreen = 0x46, /* Print Screen *
+ kHIDUsage_KeyboardScrollLock = 0x47, /* Scroll Lock *
+ kHIDUsage_KeyboardPause = 0x48, /* Pause *
+ kHIDUsage_KeyboardInsert = 0x49, /* Insert *
+ kHIDUsage_KeyboardHome = 0x4A, /* Home *
+ kHIDUsage_KeyboardDeleteForward = 0x4C, /* Delete Forward *
+
+ kHIDUsage_KeyboardUpArrow
+ kHIDUsage_KeypadNumLock
+ kHIDUsage_KeypadSlash
+ kHIDUsage_KeypadAsterisk
+ kHIDUsage_KeypadHyphen
+ kHIDUsage_KeypadPlus
+ kHIDUsage_KeypadEnter
+ kHIDUsage_KeypadPeriod
+ kHIDUsage_KeyboardNonUSBackslash
+ kHIDUsage_KeyboardApplication
+ kHIDUsage_KeyboardPower
+ kHIDUsage_KeypadEqualSign
+};
+/*
+ enum wxKeyCode
+ {
+
+ WXK_START = 300,
+ WXK_LBUTTON,
+ WXK_RBUTTON,
+ WXK_CANCEL,
+ WXK_MBUTTON,
+ WXK_CLEAR,
+ WXK_SHIFT,
+ WXK_ALT,
+ WXK_CONTROL,
+ WXK_MENU,
+ WXK_PAUSE,
+ WXK_PRIOR, * Page up *
+ WXK_NEXT, * Page down *
+ WXK_END,
+ WXK_HOME,
+ WXK_LEFT,
+ WXK_UP,
+ WXK_RIGHT,
+ WXK_DOWN,
+ WXK_SELECT,
+ WXK_PRINT,
+ WXK_EXECUTE,
+ WXK_SNAPSHOT,
+ WXK_INSERT,
+ WXK_HELP,
+ WXK_MULTIPLY,
+ WXK_ADD,
+ WXK_SEPARATOR,
+ WXK_SUBTRACT,
+ WXK_DECIMAL,
+ WXK_DIVIDE,
+ WXK_PAGEUP,
+ WXK_PAGEDOWN,
+
+ WXK_NUMPAD_SPACE,
+ WXK_NUMPAD_TAB,
+ WXK_NUMPAD_ENTER,
+ WXK_NUMPAD_HOME,
+ WXK_NUMPAD_LEFT,
+ WXK_NUMPAD_UP,
+ WXK_NUMPAD_RIGHT,
+ WXK_NUMPAD_DOWN,
+ WXK_NUMPAD_PRIOR,
+ WXK_NUMPAD_PAGEUP,
+ WXK_NUMPAD_NEXT,
+ WXK_NUMPAD_PAGEDOWN,
+ WXK_NUMPAD_END,
+ WXK_NUMPAD_BEGIN,
+ WXK_NUMPAD_INSERT,
+ WXK_NUMPAD_DELETE,
+ WXK_NUMPAD_EQUAL,
+ WXK_NUMPAD_MULTIPLY,
+ WXK_NUMPAD_ADD,
+ WXK_NUMPAD_SEPARATOR,
+ WXK_NUMPAD_SUBTRACT,
+ WXK_NUMPAD_DECIMAL,
+ WXK_NUMPAD_DIVIDE,
+
+ WXK_WINDOWS_LEFT,
+ WXK_WINDOWS_RIGHT,
+ WXK_WINDOWS_MENU ,
+ WXK_COMMAND
+ };
+
+ */
+enum
+{
+ WXK_RSHIFT = 400,
+ WXK_RALT,
+ WXK_RCONTROL,
+ WXK_RMENU
+
+};
+
+bool wxHIDKeyboard::Create()
+{
+ return wxHIDDevice::Create(kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard);
+}
+
+void wxHIDKeyboard::BuildCookies(wxCFArray& Array)
+{
+ Array = CFDictionaryGetValue((CFDictionaryRef)Array[0], CFSTR(kIOHIDElementKey));
+ InitCookies(500);
+ int i,
+ nUsage;
+ for (i = 0; i < Array.Count(); ++i)
+ {
+ CFNumberGetValue(
+ (CFNumberRef) CFDictionaryGetValue((CFDictionaryRef) Array[i], CFSTR(kIOHIDElementUsageKey)),
+ kCFNumberLongType, &nUsage);
+
+ if (nUsage >= kHIDUsage_KeyboardA && nUsage <= kHIDUsage_KeyboardZ)
+ AddCookie(Array[i], 'A' + (nUsage - kHIDUsage_KeyboardA) );
+ else if (nUsage >= kHIDUsage_Keyboard1 && nUsage <= kHIDUsage_Keyboard9)
+ AddCookie(Array[i], '1' + (nUsage - kHIDUsage_Keyboard1) );
+ else if (nUsage >= kHIDUsage_KeyboardF1 && nUsage <= kHIDUsage_KeyboardF12)
+ AddCookie(Array[i], WXK_F1 + (nUsage - kHIDUsage_KeyboardF1) );
+ else if (nUsage >= kHIDUsage_KeyboardF13 && nUsage <= kHIDUsage_KeyboardF24)
+ AddCookie(Array[i], WXK_F13 + (nUsage - kHIDUsage_KeyboardF13) );
+ else if (nUsage >= kHIDUsage_Keypad1 && nUsage <= kHIDUsage_Keypad9)
+ AddCookie(Array[i], WXK_NUMPAD1 + (nUsage - kHIDUsage_Keypad1) );
+ else switch (nUsage)
+ {
+ //0's (wx & ascii go 0-9, but HID goes 1-0)
+ case kHIDUsage_Keyboard0:
+ AddCookie(Array[i],'0');
+ break;
+ case kHIDUsage_Keypad0:
+ AddCookie(Array[i],WXK_NUMPAD0);
+ break;
+
+ //Basic
+ case kHIDUsage_KeyboardReturnOrEnter:
+ AddCookie(Array[i], WXK_RETURN);
+ break;
+ case kHIDUsage_KeyboardEscape:
+ AddCookie(Array[i], WXK_ESCAPE);
+ break;
+ case kHIDUsage_KeyboardDeleteOrBackspace:
+ AddCookie(Array[i], WXK_BACK);
+ break;
+ case kHIDUsage_KeyboardTab:
+ AddCookie(Array[i], WXK_TAB);
+ break;
+ case kHIDUsage_KeyboardSpacebar:
+ AddCookie(Array[i], WXK_SPACE);
+ break;
+ case kHIDUsage_KeyboardPageUp:
+ AddCookie(Array[i], WXK_PRIOR);
+ break;
+ case kHIDUsage_KeyboardEnd:
+ AddCookie(Array[i], WXK_END);
+ break;
+ case kHIDUsage_KeyboardPageDown:
+ AddCookie(Array[i], WXK_NEXT);
+ break;
+ case kHIDUsage_KeyboardRightArrow:
+ AddCookie(Array[i], WXK_RIGHT);
+ break;
+ case kHIDUsage_KeyboardLeftArrow:
+ AddCookie(Array[i], WXK_LEFT);
+ break;
+ case kHIDUsage_KeyboardDownArrow:
+ AddCookie(Array[i], WXK_DOWN);
+ break;
+ case kHIDUsage_KeyboardUpArrow:
+ AddCookie(Array[i], WXK_UP);
+ break;
+
+ //LEDS
+ case kHIDUsage_KeyboardCapsLock:
+ AddCookie(Array[i],WXK_CAPITAL);
+ break;
+ case kHIDUsage_KeypadNumLock:
+ AddCookie(Array[i],WXK_NUMLOCK);
+ break;
+ case kHIDUsage_KeyboardScrollLock:
+ AddCookie(Array[i],WXK_SCROLL);
+ break;
+
+ //Menu keys, Shift, other specials
+ case kHIDUsage_KeyboardLeftControl:
+ AddCookie(Array[i],WXK_CONTROL);
+ break;
+ case kHIDUsage_KeyboardLeftShift:
+ AddCookie(Array[i],WXK_SHIFT);
+ break;
+ case kHIDUsage_KeyboardLeftAlt:
+ AddCookie(Array[i],WXK_ALT);
+ break;
+ case kHIDUsage_KeyboardLeftGUI:
+ AddCookie(Array[i],WXK_MENU);
+ break;
+ case kHIDUsage_KeyboardRightControl:
+ AddCookie(Array[i],WXK_RCONTROL);
+ break;
+ case kHIDUsage_KeyboardRightShift:
+ AddCookie(Array[i],WXK_RSHIFT);
+ break;
+ case kHIDUsage_KeyboardRightAlt:
+ AddCookie(Array[i],WXK_RALT);
+ break;
+ case kHIDUsage_KeyboardRightGUI:
+ AddCookie(Array[i],WXK_RMENU);
+ break;
+
+ //Default
+ default:
+ //not in wx keycodes - do nothing....
+ break;
+ }
+ }
+}//end buildcookies
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: icon.cpp
+// Purpose: wxIcon class
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "icon.h"
+#endif
+
+#include "wx/icon.h"
+
+#if !USE_SHARED_LIBRARIES
+IMPLEMENT_DYNAMIC_CLASS(wxIcon, wxBitmap)
+#endif
+
+#include "wx/mac/private.h"
+
+
+/*
+ * Icons
+ */
+
+wxIcon::wxIcon()
+{
+}
+
+wxIcon::wxIcon(const char bits[], int width, int height) :
+ wxBitmap(bits, width, height)
+{
+
+}
+
+wxIcon::wxIcon( const char **bits ) :
+ wxBitmap(bits)
+{
+}
+
+wxIcon::wxIcon( char **bits ) :
+ wxBitmap(bits)
+{
+}
+
+wxIcon::wxIcon(const wxString& icon_file, int flags,
+ int desiredWidth, int desiredHeight)
+{
+ LoadFile(icon_file, (wxBitmapType) flags, desiredWidth, desiredHeight);
+}
+
+wxIcon::~wxIcon()
+{
+}
+
+bool wxIcon::LoadFile(const wxString& filename, wxBitmapType type,
+ int desiredWidth, int desiredHeight)
+{
+ UnRef();
+
+ m_refData = new wxBitmapRefData;
+
+ wxBitmapHandler *handler = FindHandler((wxBitmapType)type);
+
+ if ( handler )
+ return handler->LoadFile(this, filename, type, desiredWidth, desiredHeight);
+ else
+ return FALSE;
+}
+
+void wxIcon::CopyFromBitmap(const wxBitmap& bmp)
+{
+ wxIcon *icon = (wxIcon*)(&bmp);
+ *this = *icon;
+}
+
+IMPLEMENT_DYNAMIC_CLASS(wxICONResourceHandler, wxBitmapHandler)
+
+bool wxICONResourceHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
+ int desiredWidth, int desiredHeight)
+{
+ short theId = -1 ;
+ if ( name == wxT("wxICON_INFORMATION") )
+ {
+ theId = kNoteIcon ;
+ }
+ else if ( name == wxT("wxICON_QUESTION") )
+ {
+ theId = kCautionIcon ;
+ }
+ else if ( name == wxT("wxICON_WARNING") )
+ {
+ theId = kCautionIcon ;
+ }
+ else if ( name == wxT("wxICON_ERROR") )
+ {
+ theId = kStopIcon ;
+ }
+ else
+ {
+ Str255 theName ;
+ OSType theType ;
+ wxMacStringToPascal( name , theName ) ;
+
+ Handle resHandle = GetNamedResource( 'cicn' , theName ) ;
+ if ( resHandle != 0L )
+ {
+ GetResInfo( resHandle , &theId , &theType , theName ) ;
+ ReleaseResource( resHandle ) ;
+ }
+ }
+ if ( theId != -1 )
+ {
+ CIconHandle theIcon = (CIconHandle ) GetCIcon( theId ) ;
+ if ( theIcon )
+ {
+ M_BITMAPHANDLERDATA->m_hIcon = theIcon ;
+ M_BITMAPHANDLERDATA->m_width = 32 ;
+ M_BITMAPHANDLERDATA->m_height = 32 ;
+
+ M_BITMAPHANDLERDATA->m_depth = 8 ;
+ M_BITMAPHANDLERDATA->m_ok = true ;
+ M_BITMAPHANDLERDATA->m_numColors = 256 ;
+ M_BITMAPHANDLERDATA->m_bitmapType = kMacBitmapTypeIcon ;
+ return TRUE ;
+ }
+ }
+ return FALSE ;
+}
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: joystick.cpp
+// Purpose: wxJoystick class
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "joystick.h"
+#endif
+
+#include "wx/setup.h"
+
+#include "wx/joystick.h"
+
+#if wxUSE_JOYSTICK
+
+IMPLEMENT_DYNAMIC_CLASS(wxJoystick, wxObject)
+
+// Attributes
+////////////////////////////////////////////////////////////////////////////
+
+wxPoint wxJoystick::GetPosition() const
+{
+ // TODO
+ return wxPoint(0, 0);
+}
+
+int wxJoystick::GetZPosition() const
+{
+ // TODO
+ return 0;
+}
+
+int wxJoystick::GetButtonState() const
+{
+ // TODO
+ return 0;
+}
+
+int wxJoystick::GetPOVPosition() const
+{
+ // TODO
+ return 0;
+}
+
+int wxJoystick::GetPOVCTSPosition() const
+{
+ // TODO
+ return 0;
+}
+
+int wxJoystick::GetRudderPosition() const
+{
+ // TODO
+ return 0;
+}
+
+int wxJoystick::GetUPosition() const
+{
+ // TODO
+ return 0;
+}
+
+int wxJoystick::GetVPosition() const
+{
+ // TODO
+ return 0;
+}
+
+int wxJoystick::GetMovementThreshold() const
+{
+ // TODO
+ return 0;
+}
+
+void wxJoystick::SetMovementThreshold(int threshold)
+{
+ // TODO
+}
+
+// Capabilities
+////////////////////////////////////////////////////////////////////////////
+
+bool wxJoystick::IsOk() const
+{
+ // TODO
+ return FALSE;
+}
+
+int wxJoystick::GetNumberJoysticks() const
+{
+ // TODO
+ return 0;
+}
+
+int wxJoystick::GetManufacturerId() const
+{
+ // TODO
+ return 0;
+}
+
+int wxJoystick::GetProductId() const
+{
+ // TODO
+ return 0;
+}
+
+wxString wxJoystick::GetProductName() const
+{
+ // TODO
+ return wxString(wxT(""));
+}
+
+int wxJoystick::GetXMin() const
+{
+ // TODO
+ return 0;
+}
+
+int wxJoystick::GetYMin() const
+{
+ // TODO
+ return 0;
+}
+
+int wxJoystick::GetZMin() const
+{
+ // TODO
+ return 0;
+}
+
+int wxJoystick::GetXMax() const
+{
+ // TODO
+ return 0;
+}
+
+int wxJoystick::GetYMax() const
+{
+ // TODO
+ return 0;
+}
+
+int wxJoystick::GetZMax() const
+{
+ // TODO
+ return 0;
+}
+
+int wxJoystick::GetNumberButtons() const
+{
+ // TODO
+ return 0;
+}
+
+int wxJoystick::GetNumberAxes() const
+{
+ // TODO
+ return 0;
+}
+
+int wxJoystick::GetMaxButtons() const
+{
+ // TODO
+ return 0;
+}
+
+int wxJoystick::GetMaxAxes() const
+{
+ // TODO
+ return 0;
+}
+
+int wxJoystick::GetPollingMin() const
+{
+ // TODO
+ return 0;
+}
+
+int wxJoystick::GetPollingMax() const
+{
+ // TODO
+ return 0;
+}
+
+int wxJoystick::GetRudderMin() const
+{
+ // TODO
+ return 0;
+}
+
+int wxJoystick::GetRudderMax() const
+{
+ // TODO
+ return 0;
+}
+
+int wxJoystick::GetUMin() const
+{
+ // TODO
+ return 0;
+}
+
+int wxJoystick::GetUMax() const
+{
+ // TODO
+ return 0;
+}
+
+int wxJoystick::GetVMin() const
+{
+ // TODO
+ return 0;
+}
+
+int wxJoystick::GetVMax() const
+{
+ // TODO
+ return 0;
+}
+
+bool wxJoystick::HasRudder() const
+{
+ // TODO
+ return FALSE;
+}
+
+bool wxJoystick::HasZ() const
+{
+ // TODO
+ return FALSE;
+}
+
+bool wxJoystick::HasU() const
+{
+ // TODO
+ return FALSE;
+}
+
+bool wxJoystick::HasV() const
+{
+ // TODO
+ return FALSE;
+}
+
+bool wxJoystick::HasPOV() const
+{
+ // TODO
+ return FALSE;
+}
+
+bool wxJoystick::HasPOV4Dir() const
+{
+ // TODO
+ return FALSE;
+}
+
+bool wxJoystick::HasPOVCTS() const
+{
+ // TODO
+ return FALSE;
+}
+
+// Operations
+////////////////////////////////////////////////////////////////////////////
+
+bool wxJoystick::SetCapture(wxWindow* win, int pollingFreq)
+{
+ // TODO
+ return FALSE;
+}
+
+bool wxJoystick::ReleaseCapture()
+{
+ // TODO
+ return FALSE;
+}
+
+#endif
+ // wxUSE_JOYSTICK
+
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Name: listbox.cpp
+// Purpose: wxListBox
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "listbox.h"
+#endif
+
+#include "wx/app.h"
+#include "wx/listbox.h"
+#include "wx/button.h"
+#include "wx/settings.h"
+#include "wx/toplevel.h"
+#include "wx/dynarray.h"
+#include "wx/log.h"
+
+#include "wx/utils.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxListBox, wxControl)
+
+BEGIN_EVENT_TABLE(wxListBox, wxControl)
+ EVT_SIZE( wxListBox::OnSize )
+ EVT_CHAR( wxListBox::OnChar )
+END_EVENT_TABLE()
+#endif
+
+#include "wx/mac/uma.h"
+
+#if PRAGMA_STRUCT_ALIGN
+ #pragma options align=mac68k
+#elif PRAGMA_STRUCT_PACKPUSH
+ #pragma pack(push, 2)
+#elif PRAGMA_STRUCT_PACK
+ #pragma pack(2)
+#endif
+
+typedef struct {
+ unsigned short instruction;
+ void (*function)();
+} ldefRec, *ldefPtr, **ldefHandle;
+
+#if PRAGMA_STRUCT_ALIGN
+ #pragma options align=reset
+#elif PRAGMA_STRUCT_PACKPUSH
+ #pragma pack(pop)
+#elif PRAGMA_STRUCT_PACK
+ #pragma pack()
+#endif
+
+#if TARGET_CARBON
+const short kwxMacListItemHeight = 19 ;
+#else
+const short kwxMacListItemHeight = 14 ;
+#endif
+
+extern "C"
+{
+static pascal void wxMacListDefinition( short message, Boolean isSelected, Rect *drawRect,
+ Cell cell, short dataOffset, short dataLength,
+ ListHandle listHandle ) ;
+}
+
+static pascal void wxMacListDefinition( short message, Boolean isSelected, Rect *drawRect,
+ Cell cell, short dataOffset, short dataLength,
+ ListHandle listHandle )
+{
+ wxListBox* list;
+ list = (wxListBox*) GetControlReference( (ControlHandle) GetListRefCon(listHandle) );
+ if ( list == NULL )
+ return ;
+
+ GrafPtr savePort;
+ GrafPtr grafPtr;
+ RgnHandle savedClipRegion;
+ SInt32 savedPenMode;
+ GetPort(&savePort);
+ SetPort((**listHandle).port);
+ grafPtr = (**listHandle).port ;
+ // typecast our refCon
+
+ // Calculate the cell rect.
+
+ switch( message ) {
+ case lInitMsg:
+ break;
+
+ case lCloseMsg:
+ break;
+
+ case lDrawMsg:
+ {
+ const wxString linetext = list->m_stringArray[cell.v] ;
+
+ // Save the current clip region, and set the clip region to the area we are about
+ // to draw.
+
+ savedClipRegion = NewRgn();
+ GetClip( savedClipRegion );
+
+ ClipRect( drawRect );
+ EraseRect( drawRect );
+
+ const wxFont& font = list->GetFont();
+ if ( font.Ok() )
+ {
+ ::TextFont( font.GetMacFontNum() ) ;
+ ::TextSize( font.GetMacFontSize() ) ;
+ ::TextFace( font.GetMacFontStyle() ) ;
+ }
+ else
+ {
+ ::TextFont( kFontIDMonaco ) ;
+ ::TextSize( 9 );
+ ::TextFace( 0 ) ;
+ }
+
+#if TARGET_CARBON
+ {
+ Rect frame = { drawRect->top, drawRect->left + 4,
+ drawRect->top + kwxMacListItemHeight, drawRect->right + 10000 } ;
+ CFMutableStringRef mString = CFStringCreateMutableCopy( NULL , 0 , wxMacCFStringHolder(linetext , list->GetFont().GetEncoding()) ) ;
+ ::TruncateThemeText( mString , kThemeCurrentPortFont, kThemeStateActive, drawRect->right - drawRect->left , truncEnd , NULL ) ;
+ ::DrawThemeTextBox( mString,
+ kThemeCurrentPortFont,
+ kThemeStateActive,
+ false,
+ &frame,
+ teJustLeft,
+ nil );
+ CFRelease( mString ) ;
+ }
+#else
+ {
+ wxCharBuffer text = linetext.mb_str( wxConvLocal) ;
+ MoveTo(drawRect->left + 4 , drawRect->top + 10 );
+ DrawText(text, 0 , strlen(text) );
+ }
+#endif
+ // If the cell is hilited, do the hilite now. Paint the cell contents with the
+ // appropriate QuickDraw transform mode.
+
+ if( isSelected ) {
+ savedPenMode = GetPortPenMode( (CGrafPtr) grafPtr );
+ SetPortPenMode( (CGrafPtr)grafPtr, hilitetransfermode );
+ PaintRect( drawRect );
+ SetPortPenMode( (CGrafPtr)grafPtr, savedPenMode );
+ }
+
+ // Restore the saved clip region.
+
+ SetClip( savedClipRegion );
+ DisposeRgn( savedClipRegion );
+ }
+ break;
+ case lHiliteMsg:
+
+ // Hilite or unhilite the cell. Paint the cell contents with the
+ // appropriate QuickDraw transform mode.
+
+ GetPort( &grafPtr );
+ savedPenMode = GetPortPenMode( (CGrafPtr)grafPtr );
+ SetPortPenMode( (CGrafPtr)grafPtr, hilitetransfermode );
+ PaintRect( drawRect );
+ SetPortPenMode( (CGrafPtr)grafPtr, savedPenMode );
+ break;
+ default :
+ break ;
+ }
+ SetPort(savePort);
+}
+
+extern "C" void MacDrawStringCell(Rect *cellRect, Cell lCell, ListHandle theList, long refCon) ;
+// resources ldef ids
+const short kwxMacListWithVerticalScrollbar = 128 ;
+const short kwxMacListWithVerticalAndHorizontalScrollbar = 129 ;
+
+// ============================================================================
+// list box control implementation
+// ============================================================================
+
+// Listbox item
+wxListBox::wxListBox()
+{
+ m_noItems = 0;
+ m_selected = 0;
+ m_macList = NULL ;
+}
+
+static ListDefUPP macListDefUPP = NULL ;
+
+bool wxListBox::Create(wxWindow *parent, wxWindowID id,
+ const wxPoint& pos,
+ const wxSize& size,
+ const wxArrayString& choices,
+ long style,
+ const wxValidator& validator,
+ const wxString& name)
+{
+ wxCArrayString chs(choices);
+
+ return Create(parent, id, pos, size, chs.GetCount(), chs.GetStrings(),
+ style, validator, name);
+}
+
+bool wxListBox::Create(wxWindow *parent, wxWindowID id,
+ const wxPoint& pos,
+ const wxSize& size,
+ int n, const wxString choices[],
+ long style,
+ const wxValidator& validator,
+ const wxString& name)
+{
+ if ( !wxListBoxBase::Create(parent, id, pos, size, style & ~(wxHSCROLL|wxVSCROLL), validator, name) )
+ return false;
+
+ m_noItems = 0 ; // this will be increased by our append command
+ m_selected = 0;
+
+ Rect bounds ;
+ Str255 title ;
+
+ MacPreControlCreate( parent , id , wxEmptyString , pos , size ,style, validator , name , &bounds , title ) ;
+
+ ListDefSpec listDef;
+ listDef.defType = kListDefUserProcType;
+ if ( macListDefUPP == NULL )
+ {
+ macListDefUPP = NewListDefUPP( wxMacListDefinition );
+ }
+ listDef.u.userProc = macListDefUPP ;
+
+ Str255 fontName ;
+ SInt16 fontSize ;
+ Style fontStyle ;
+#if TARGET_CARBON
+ GetThemeFont(kThemeViewsFont , GetApplicationScript() , fontName , &fontSize , &fontStyle ) ;
+#else
+ GetFontName( kFontIDMonaco , fontName ) ;
+ fontSize = 9 ;
+ fontStyle = normal ;
+#endif
+ SetFont( wxFont (fontSize, wxSWISS, wxNORMAL, wxNORMAL , false , wxMacMakeStringFromPascal( fontName ) ) ) ;
+#if TARGET_CARBON
+ Size asize;
+
+
+ CreateListBoxControl( MAC_WXHWND(parent->MacGetRootWindow()), &bounds, false, 0, 1, (style & wxLB_HSCROLL), true,
+ kwxMacListItemHeight, kwxMacListItemHeight, false, &listDef, (ControlRef *)&m_macControl );
+
+ GetControlData( (ControlHandle) m_macControl, kControlNoPart, kControlListBoxListHandleTag,
+ sizeof(ListHandle), (Ptr) &m_macList, &asize);
+
+ SetControlReference( (ControlHandle) m_macControl, (long) this);
+ SetControlVisibility( (ControlHandle) m_macControl, false, false);
+
+#else
+
+ long result ;
+ wxStAppResource resload ;
+ m_macControl = ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , title , false ,
+ (style & wxLB_HSCROLL) ? kwxMacListWithVerticalAndHorizontalScrollbar : kwxMacListWithVerticalScrollbar ,
+ 0 , 0, kControlListBoxProc , (long) this ) ;
+ ::GetControlData( (ControlHandle) m_macControl , kControlNoPart , kControlListBoxListHandleTag ,
+ sizeof( ListHandle ) , (char*) &m_macList , &result ) ;
+
+ HLock( (Handle) m_macList ) ;
+ ldefHandle ldef ;
+ ldef = (ldefHandle) NewHandle( sizeof(ldefRec) ) ;
+ if ( (**(ListHandle)m_macList).listDefProc != NULL )
+ {
+ (**ldef).instruction = 0x4EF9; /* JMP instruction */
+ (**ldef).function = (void(*)()) listDef.u.userProc;
+ (**(ListHandle)m_macList).listDefProc = (Handle) ldef ;
+ }
+
+ Point pt = (**(ListHandle)m_macList).cellSize ;
+ pt.v = kwxMacListItemHeight ;
+ LCellSize( pt , (ListHandle)m_macList ) ;
+ LAddColumn( 1 , 0 , (ListHandle)m_macList ) ;
+#endif
+ OptionBits options = 0;
+ if ( style & wxLB_MULTIPLE )
+ {
+ options += lExtendDrag + lUseSense ;
+ }
+ else if ( style & wxLB_EXTENDED )
+ {
+ // default behaviour
+ }
+ else
+ {
+ options = (OptionBits) lOnlyOne ;
+ }
+ SetListSelectionFlags((ListHandle)m_macList, options);
+
+ for ( int i = 0 ; i < n ; i++ )
+ {
+ Append( choices[i] ) ;
+ }
+
+ MacPostControlCreate() ;
+
+ LSetDrawingMode( true , (ListHandle)m_macList ) ;
+
+ return TRUE;
+}
+
+wxListBox::~wxListBox()
+{
+ FreeData() ;
+ // avoid access during destruction
+ SetControlReference( (ControlHandle) m_macControl , NULL ) ;
+ if ( m_macList )
+ {
+#if !TARGET_CARBON
+ DisposeHandle( (**(ListHandle)m_macList).listDefProc ) ;
+ (**(ListHandle)m_macList).listDefProc = NULL ;
+#endif
+ m_macList = NULL ;
+ }
+}
+
+void wxListBox::FreeData()
+{
+#if wxUSE_OWNER_DRAWN
+ if ( m_windowStyle & wxLB_OWNERDRAW )
+ {
+ size_t uiCount = m_aItems.Count();
+ while ( uiCount-- != 0 ) {
+ delete m_aItems[uiCount];
+ m_aItems[uiCount] = NULL;
+ }
+
+ m_aItems.Clear();
+ }
+ else
+#endif // wxUSE_OWNER_DRAWN
+ if ( HasClientObjectData() )
+ {
+ for ( size_t n = 0; n < (size_t)m_noItems; n++ )
+ {
+ delete GetClientObject(n);
+ }
+ }
+}
+
+void wxListBox::DoSetSize(int x, int y,
+ int width, int height,
+ int sizeFlags )
+{
+ wxControl::DoSetSize( x , y , width , height , sizeFlags ) ;
+#if TARGET_CARBON
+ Rect bounds ;
+ GetControlBounds( (ControlHandle) m_macControl , &bounds ) ;
+ ControlRef control = GetListVerticalScrollBar( (ListHandle)m_macList ) ;
+ if ( control )
+ {
+ Rect scrollbounds ;
+ GetControlBounds( control , &scrollbounds ) ;
+ if( scrollbounds.right != bounds.right + 1 )
+ {
+ UMAMoveControl( control , bounds.right - (scrollbounds.right - scrollbounds.left) + 1 ,
+ scrollbounds.top ) ;
+ }
+ }
+#endif
+}
+void wxListBox::DoSetFirstItem(int N)
+{
+ MacScrollTo( N ) ;
+}
+
+void wxListBox::Delete(int N)
+{
+ wxCHECK_RET( N >= 0 && N < m_noItems,
+ wxT("invalid index in wxListBox::Delete") );
+
+#if wxUSE_OWNER_DRAWN
+ delete m_aItems[N];
+ m_aItems.RemoveAt(N);
+#else // !wxUSE_OWNER_DRAWN
+ if ( HasClientObjectData() )
+ {
+ delete GetClientObject(N);
+ }
+#endif // wxUSE_OWNER_DRAWN/!wxUSE_OWNER_DRAWN
+ m_stringArray.RemoveAt( N ) ;
+ m_dataArray.RemoveAt( N ) ;
+ m_noItems --;
+
+ MacDelete( N ) ;
+}
+
+int wxListBox::DoAppend(const wxString& item)
+{
+ int index = m_noItems ;
+ m_stringArray.Add( item ) ;
+ m_dataArray.Add( NULL );
+ m_noItems ++;
+ DoSetItemClientData( index , NULL ) ;
+ MacAppend( item ) ;
+
+ return index ;
+}
+
+void wxListBox::DoSetItems(const wxArrayString& choices, void** clientData)
+{
+ MacSetRedraw( false ) ;
+ Clear() ;
+ int n = choices.GetCount();
+
+ for( int i = 0 ; i < n ; ++i )
+ {
+ if ( clientData )
+ {
+#if wxUSE_OWNER_DRAWN
+ wxASSERT_MSG(clientData[i] == NULL,
+ wxT("Can't use client data with owner-drawn listboxes"));
+#else // !wxUSE_OWNER_DRAWN
+ Append( choices[i] , clientData[i] ) ;
+#endif
+ }
+ else
+ Append( choices[i] ) ;
+ }
+
+#if wxUSE_OWNER_DRAWN
+ if ( m_windowStyle & wxLB_OWNERDRAW ) {
+ // first delete old items
+ size_t ui = m_aItems.Count();
+ while ( ui-- != 0 ) {
+ delete m_aItems[ui];
+ m_aItems[ui] = NULL;
+ }
+ m_aItems.Empty();
+
+ // then create new ones
+ for ( ui = 0; ui < (size_t)m_noItems; ui++ ) {
+ wxOwnerDrawn *pNewItem = CreateItem(ui);
+ pNewItem->SetName(choices[ui]);
+ m_aItems.Add(pNewItem);
+ }
+ }
+#endif // wxUSE_OWNER_DRAWN
+ MacSetRedraw( true ) ;
+}
+
+bool wxListBox::HasMultipleSelection() const
+{
+ return (m_windowStyle & wxLB_MULTIPLE) || (m_windowStyle & wxLB_EXTENDED);
+}
+
+int wxListBox::FindString(const wxString& s) const
+{
+
+ if ( s.Right(1) == wxT("*") )
+ {
+ wxString search = s.Left( s.Length() - 1 ) ;
+ int len = search.Length() ;
+ Str255 s1 , s2 ;
+ wxMacStringToPascal( search , s2 ) ;
+
+ for ( int i = 0 ; i < m_noItems ; ++ i )
+ {
+ wxMacStringToPascal( m_stringArray[i].Left( len ) , s1 ) ;
+
+ if ( EqualString( s1 , s2 , false , false ) )
+ return i ;
+ }
+ if ( s.Left(1) == wxT("*") && s.Length() > 1 )
+ {
+ wxString st = s ;
+ st.MakeLower() ;
+ for ( int i = 0 ; i < m_noItems ; ++i )
+ {
+ if ( GetString(i).Lower().Matches(st) )
+ return i ;
+ }
+ }
+
+ }
+ else
+ {
+ Str255 s1 , s2 ;
+
+ wxMacStringToPascal( s , s2 ) ;
+
+ for ( int i = 0 ; i < m_noItems ; ++ i )
+ {
+ wxMacStringToPascal( m_stringArray[i] , s1 ) ;
+
+ if ( EqualString( s1 , s2 , false , false ) )
+ return i ;
+ }
+ }
+ return -1;
+}
+
+void wxListBox::Clear()
+{
+ FreeData();
+ m_noItems = 0;
+ m_stringArray.Empty() ;
+ m_dataArray.Empty() ;
+ MacClear() ;
+}
+
+void wxListBox::SetSelection(int N, bool select)
+{
+ wxCHECK_RET( N >= 0 && N < m_noItems,
+ wxT("invalid index in wxListBox::SetSelection") );
+ MacSetSelection( N , select ) ;
+ GetSelections( m_selectionPreImage ) ;
+}
+
+bool wxListBox::IsSelected(int N) const
+{
+ wxCHECK_MSG( N >= 0 && N < m_noItems, FALSE,
+ wxT("invalid index in wxListBox::Selected") );
+
+ return MacIsSelected( N ) ;
+}
+
+void *wxListBox::DoGetItemClientData(int N) const
+{
+ wxCHECK_MSG( N >= 0 && N < m_noItems, NULL,
+ wxT("invalid index in wxListBox::GetClientData"));
+
+ return (void *)m_dataArray[N];
+}
+
+wxClientData *wxListBox::DoGetItemClientObject(int N) const
+{
+ return (wxClientData *) DoGetItemClientData( N ) ;
+}
+
+void wxListBox::DoSetItemClientData(int N, void *Client_data)
+{
+ wxCHECK_RET( N >= 0 && N < m_noItems,
+ wxT("invalid index in wxListBox::SetClientData") );
+
+#if wxUSE_OWNER_DRAWN
+ if ( m_windowStyle & wxLB_OWNERDRAW )
+ {
+ // client data must be pointer to wxOwnerDrawn, otherwise we would crash
+ // in OnMeasure/OnDraw.
+ wxFAIL_MSG(wxT("Can't use client data with owner-drawn listboxes"));
+ }
+#endif // wxUSE_OWNER_DRAWN
+ wxASSERT_MSG( m_dataArray.GetCount() >= (size_t) N , wxT("invalid client_data array") ) ;
+
+ if ( m_dataArray.GetCount() > (size_t) N )
+ {
+ m_dataArray[N] = (char*) Client_data ;
+ }
+ else
+ {
+ m_dataArray.Add( (char*) Client_data ) ;
+ }
+}
+
+void wxListBox::DoSetItemClientObject(int n, wxClientData* clientData)
+{
+ DoSetItemClientData(n, clientData);
+}
+
+// Return number of selections and an array of selected integers
+int wxListBox::GetSelections(wxArrayInt& aSelections) const
+{
+ return MacGetSelections( aSelections ) ;
+}
+
+// Get single selection, for single choice list items
+int wxListBox::GetSelection() const
+{
+ return MacGetSelection() ;
+}
+
+// Find string for position
+wxString wxListBox::GetString(int N) const
+{
+ return m_stringArray[N] ;
+}
+
+void wxListBox::DoInsertItems(const wxArrayString& items, int pos)
+{
+ wxCHECK_RET( pos >= 0 && pos <= m_noItems,
+ wxT("invalid index in wxListBox::InsertItems") );
+
+ int nItems = items.GetCount();
+
+ for ( int i = 0 ; i < nItems ; i++ )
+ {
+ m_stringArray.Insert( items[i] , pos + i ) ;
+ m_dataArray.Insert( NULL , pos + i ) ;
+ MacInsert( pos + i , items[i] ) ;
+ }
+
+ m_noItems += nItems;
+}
+
+void wxListBox::SetString(int N, const wxString& s)
+{
+ m_stringArray[N] = s ;
+ MacSet( N , s ) ;
+}
+
+wxSize wxListBox::DoGetBestSize() const
+{
+ int lbWidth = 100; // some defaults
+ int lbHeight = 110;
+ int wLine;
+
+ {
+ wxMacPortStateHelper st( UMAGetWindowPort( (WindowRef) MacGetRootWindow() ) ) ;
+
+ if ( m_font.Ok() )
+ {
+ ::TextFont( m_font.GetMacFontNum() ) ;
+ ::TextSize( m_font.GetMacFontSize() ) ;
+ ::TextFace( m_font.GetMacFontStyle() ) ;
+ }
+ else
+ {
+ ::TextFont( kFontIDMonaco ) ;
+ ::TextSize( 9 );
+ ::TextFace( 0 ) ;
+ }
+
+ // Find the widest line
+ for(int i = 0; i < GetCount(); i++) {
+ wxString str(GetString(i));
+ #if wxUSE_UNICODE
+ Point bounds={0,0} ;
+ SInt16 baseline ;
+ ::GetThemeTextDimensions( wxMacCFStringHolder( str , m_font.GetEncoding() ) ,
+ kThemeCurrentPortFont,
+ kThemeStateActive,
+ false,
+ &bounds,
+ &baseline );
+ wLine = bounds.h ;
+ #else
+ wLine = ::TextWidth( str.c_str() , 0 , str.Length() ) ;
+ #endif
+ lbWidth = wxMax(lbWidth, wLine);
+ }
+
+ // Add room for the scrollbar
+ lbWidth += wxSystemSettings::GetMetric(wxSYS_VSCROLL_X);
+
+ // And just a bit more
+ int cy = 12 ;
+ int cx = ::TextWidth( "X" , 0 , 1 ) ;
+ lbWidth += cx ;
+
+ // don't make the listbox too tall (limit height to around 10 items) but don't
+ // make it too small neither
+ lbHeight = (cy+4) * wxMin(wxMax(GetCount(), 3), 10);
+ }
+ return wxSize(lbWidth, lbHeight);
+}
+
+int wxListBox::GetCount() const
+{
+ return m_noItems;
+}
+
+void wxListBox::SetupColours()
+{
+ SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
+ SetForegroundColour(GetParent()->GetForegroundColour());
+}
+
+void wxListBox::Refresh(bool eraseBack, const wxRect *rect)
+{
+ wxControl::Refresh( eraseBack , rect ) ;
+ // MacRedrawControl() ;
+}
+
+#if wxUSE_OWNER_DRAWN
+
+class wxListBoxItem : public wxOwnerDrawn
+{
+public:
+ wxListBoxItem(const wxString& str = "");
+};
+
+wxListBoxItem::wxListBoxItem(const wxString& str) : wxOwnerDrawn(str, FALSE)
+{
+ // no bitmaps/checkmarks
+ SetMarginWidth(0);
+}
+
+wxOwnerDrawn *wxListBox::CreateItem(size_t n)
+{
+ return new wxListBoxItem();
+}
+
+#endif //USE_OWNER_DRAWN
+
+// ============================================================================
+// list box control implementation
+// ============================================================================
+
+/*
+void MacDrawStringCell(Rect *cellRect, Cell lCell, ListHandle theList, long refCon)
+{
+wxListBox* list;
+// typecast our refCon
+list = (wxListBox*)refCon;
+
+ MoveTo(cellRect->left + 4 , cellRect->top + 10 );
+ const wxString text = list->m_stringArray[lCell.v] ;
+ ::TextFont( kFontIDMonaco ) ;
+ ::TextSize( 9 );
+ ::TextFace( 0 ) ;
+ DrawText(text, 0 , text.Length());
+
+ }
+*/
+void wxListBox::MacDelete( int N )
+{
+ LDelRow( 1 , N , (ListHandle)m_macList) ;
+ Refresh();
+}
+
+void wxListBox::MacInsert( int n , const wxString& text)
+{
+ Cell cell = { 0 , 0 } ;
+ cell.v = n ;
+ LAddRow( 1 , cell.v , (ListHandle)m_macList ) ;
+ // LSetCell(text, strlen(text), cell, m_macList);
+ Refresh();
+}
+
+void wxListBox::MacAppend( const wxString& text)
+{
+ Cell cell = { 0 , 0 } ;
+ cell.v = (**(ListHandle)m_macList).dataBounds.bottom ;
+ LAddRow( 1 , cell.v , (ListHandle)m_macList ) ;
+ // LSetCell(text, strlen(text), cell, m_macList);
+ Refresh();
+}
+
+void wxListBox::MacClear()
+{
+ LDelRow( (**(ListHandle)m_macList).dataBounds.bottom , 0 ,(ListHandle) m_macList ) ;
+ Refresh();
+}
+
+void wxListBox::MacSetSelection( int n , bool select )
+{
+ Cell cell = { 0 , 0 } ;
+ if ( ! (m_windowStyle & wxLB_MULTIPLE) )
+ {
+ if ( LGetSelect( true , &cell , (ListHandle)m_macList ) )
+ {
+ LSetSelect( false , cell , (ListHandle)m_macList ) ;
+ }
+ }
+
+ cell.v = n ;
+ LSetSelect( select , cell , (ListHandle)m_macList ) ;
+ LAutoScroll( (ListHandle)m_macList ) ;
+ Refresh();
+}
+
+bool wxListBox::MacIsSelected( int n ) const
+{
+ Cell cell = { 0 , 0 } ;
+ cell.v = n ;
+ return LGetSelect( false , &cell , (ListHandle)m_macList ) ;
+}
+
+void wxListBox::MacDestroy()
+{
+ // DisposeExtLDEFInfo( m_macList ) ;
+}
+
+int wxListBox::MacGetSelection() const
+{
+ Cell cell = { 0 , 0 } ;
+ if ( LGetSelect( true , &cell , (ListHandle)m_macList ) )
+ return cell.v ;
+ else
+ return -1 ;
+}
+
+int wxListBox::MacGetSelections( wxArrayInt& aSelections ) const
+{
+ int no_sel = 0 ;
+
+ aSelections.Empty();
+
+ Cell cell = { 0 , 0 } ;
+ cell.v = 0 ;
+
+ while ( LGetSelect( true , &cell ,(ListHandle) m_macList ) )
+ {
+ aSelections.Add( cell.v ) ;
+ no_sel++ ;
+ cell.v++ ;
+ }
+ return no_sel ;
+}
+
+void wxListBox::MacSet( int n , const wxString& text )
+{
+ // our implementation does not store anything in the list
+ // so we just have to redraw
+ Cell cell = { 0 , 0 } ;
+ cell.v = n ;
+ // LSetCell(text, strlen(text), cell, m_macList);
+ Refresh();
+}
+
+void wxListBox::MacScrollTo( int n )
+{
+ // TODO implement scrolling
+}
+
+void wxListBox::OnSize( wxSizeEvent &event)
+{
+ Point pt;
+
+#if TARGET_CARBON
+ GetListCellSize((ListHandle)m_macList, &pt);
+#else
+ pt = (**(ListHandle)m_macList).cellSize ;
+#endif
+ pt.h = m_width - 15 ;
+ LCellSize( pt , (ListHandle)m_macList ) ;
+}
+
+void wxListBox::MacHandleControlClick( WXWidget control , wxInt16 controlpart , bool WXUNUSED(mouseStillDown))
+{
+ Boolean wasDoubleClick = false ;
+ long result ;
+
+ ::GetControlData( (ControlHandle) m_macControl , kControlNoPart , kControlListBoxDoubleClickTag , sizeof( wasDoubleClick ) , (char*) &wasDoubleClick , &result ) ;
+ if ( !wasDoubleClick )
+ {
+ MacDoClick() ;
+ }
+ else
+ {
+ MacDoDoubleClick() ;
+ }
+}
+
+void wxListBox::MacSetRedraw( bool doDraw )
+{
+ LSetDrawingMode( doDraw , (ListHandle)m_macList ) ;
+
+}
+
+void wxListBox::MacDoClick()
+{
+ wxArrayInt aSelections;
+ int n ;
+ size_t count = GetSelections(aSelections);
+
+ if ( count == m_selectionPreImage.GetCount() )
+ {
+ bool hasChanged = false ;
+ for ( size_t i = 0 ; i < count ; ++i )
+ {
+ if ( aSelections[i] != m_selectionPreImage[i] )
+ {
+ hasChanged = true ;
+ break ;
+ }
+ }
+ if ( !hasChanged )
+ {
+ return ;
+ }
+ }
+
+ m_selectionPreImage = aSelections;
+
+ wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, m_windowId);
+ event.SetEventObject( this );
+
+ if ( count > 0 )
+ {
+ n = aSelections[0];
+ if ( HasClientObjectData() )
+ event.SetClientObject( GetClientObject(n) );
+ else if ( HasClientUntypedData() )
+ event.SetClientData( GetClientData(n) );
+ event.SetString( GetString(n) );
+ }
+ else
+ {
+ n = -1;
+ }
+
+ event.m_commandInt = n;
+
+ GetEventHandler()->ProcessEvent(event);
+}
+
+void wxListBox::MacDoDoubleClick()
+{
+ wxCommandEvent event(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, m_windowId);
+ event.SetEventObject( this );
+ GetEventHandler()->ProcessEvent(event) ;
+}
+
+void wxListBox::OnChar(wxKeyEvent& event)
+{
+ if ( event.GetKeyCode() == WXK_RETURN || event.GetKeyCode() == WXK_NUMPAD_ENTER)
+ {
+ wxWindow* parent = GetParent() ;
+ while( parent && !parent->IsTopLevel() && parent->GetDefaultItem() == NULL )
+ parent = parent->GetParent() ;
+
+ if ( parent && parent->GetDefaultItem() )
+ {
+ wxButton *def = wxDynamicCast(parent->GetDefaultItem(),
+ wxButton);
+ if ( def && def->IsEnabled() )
+ {
+ wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() );
+ event.SetEventObject(def);
+ def->Command(event);
+ return ;
+ }
+ }
+ event.Skip() ;
+ }
+ /* generate wxID_CANCEL if command-. or <esc> has been pressed (typically in dialogs) */
+ else if (event.GetKeyCode() == WXK_ESCAPE || (event.GetKeyCode() == '.' && event.MetaDown() ) )
+ {
+ // FIXME: look in ancestors, not just parent.
+ wxWindow* win = GetParent()->FindWindow( wxID_CANCEL ) ;
+ if (win)
+ {
+ wxCommandEvent new_event(wxEVT_COMMAND_BUTTON_CLICKED,wxID_CANCEL);
+ new_event.SetEventObject( win );
+ win->GetEventHandler()->ProcessEvent( new_event );
+ }
+ }
+ else if ( event.GetKeyCode() == WXK_TAB )
+ {
+ wxNavigationKeyEvent new_event;
+ new_event.SetEventObject( this );
+ new_event.SetDirection( !event.ShiftDown() );
+ /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
+ new_event.SetWindowChange( event.ControlDown() );
+ new_event.SetCurrentFocus( this );
+ if ( !GetEventHandler()->ProcessEvent( new_event ) )
+ event.Skip() ;
+ }
+ else if ( event.GetKeyCode() == WXK_DOWN || event.GetKeyCode() == WXK_UP )
+ {
+ // perform the default key handling first
+ wxControl::OnKeyDown( event ) ;
+
+ wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, m_windowId);
+ event.SetEventObject( this );
+
+ wxArrayInt aSelections;
+ int n, count = GetSelections(aSelections);
+ if ( count > 0 )
+ {
+ n = aSelections[0];
+ if ( HasClientObjectData() )
+ event.SetClientObject( GetClientObject(n) );
+ else if ( HasClientUntypedData() )
+ event.SetClientData( GetClientData(n) );
+ event.SetString( GetString(n) );
+ }
+ else
+ {
+ n = -1;
+ }
+
+ event.m_commandInt = n;
+
+ GetEventHandler()->ProcessEvent(event);
+ }
+ else
+ {
+ if ( event.GetTimestamp() > m_lastTypeIn + 60 )
+ {
+ m_typeIn = wxEmptyString ;
+ }
+ m_lastTypeIn = event.GetTimestamp() ;
+ m_typeIn += (char) event.GetKeyCode() ;
+ int line = FindString(wxT("*")+m_typeIn+wxT("*")) ;
+ if ( line >= 0 )
+ {
+ if ( GetSelection() != line )
+ {
+ SetSelection(line) ;
+ wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, m_windowId);
+ event.SetEventObject( this );
+
+ if ( HasClientObjectData() )
+ event.SetClientObject( GetClientObject( line ) );
+ else if ( HasClientUntypedData() )
+ event.SetClientData( GetClientData(line) );
+ event.SetString( GetString(line) );
+
+ event.m_commandInt = line ;
+
+ GetEventHandler()->ProcessEvent(event);
+ }
+ }
+ }
+}
+
--- /dev/null
+/* -------------------------------------------------------------------------
+ * Project: Mac Notifier Support
+ * Name: macnotfy.c
+ * Author: Stefan CSomor
+ * Purpose: Mac Notifier main file
+ * CVSID: $Id$
+ * -------------------------------------------------------------------------
+ */
+
+#include "wx/wx.h"
+
+#include "wx/mac/private.h"
+
+#include "wx/mac/macnotfy.h"
+
+const short kMaxEvents = 1000 ;
+
+struct wxMacNotificationEvents
+{
+ short top ;
+ short bottom ;
+
+ wxMacNotificationProcPtr proc[kMaxEvents] ;
+ unsigned long events[kMaxEvents] ;
+ void* data[kMaxEvents] ;
+} ;
+
+typedef struct wxMacNotificationEvents wxMacNotificationEvents ;
+static wxMacNotificationEvents gMacNotificationEvents ;
+
+static ProcessSerialNumber gAppProcess ;
+
+void wxMacWakeUp()
+{
+ ProcessSerialNumber psn ;
+ Boolean isSame ;
+ psn.highLongOfPSN = 0 ;
+ psn.lowLongOfPSN = kCurrentProcess ;
+ SameProcess( &gAppProcess , &psn , &isSame ) ;
+ if ( isSame )
+ {
+#if TARGET_CARBON
+ EventRef dummyEvent ;
+ OSStatus err = MacCreateEvent(nil, 'WXMC', 'WXMC', GetCurrentEventTime(),
+ kEventAttributeNone, &dummyEvent);
+ if (err == noErr)
+ {
+ err = PostEventToQueue(GetMainEventQueue(), dummyEvent,
+ kEventPriorityHigh);
+ }
+#else
+ PostEvent( nullEvent , 0 ) ;
+#endif
+ }
+ else
+ {
+ WakeUpProcess( &gAppProcess ) ;
+ }
+}
+
+void wxMacCreateNotifierTable()
+{
+ GetCurrentProcess(&gAppProcess);
+ gMacNotificationEvents.top = 0 ;
+ gMacNotificationEvents.bottom = 0 ;
+ for ( int i = 0 ; i < kMaxEvents ; ++i )
+ {
+ gMacNotificationEvents.proc[i] = NULL ;
+ gMacNotificationEvents.events[i] = NULL ;
+ gMacNotificationEvents.data[i] = NULL ;
+ }
+}
+
+void wxMacDestroyNotifierTable()
+{
+}
+
+wxMacNotifierTableRef wxMacGetNotifierTable()
+{
+ return (wxMacNotifierTableRef) &gMacNotificationEvents ;
+}
+
+void wxMacAddEvent(
+ wxMacNotifierTableRef table ,
+ wxMacNotificationProcPtr handler ,
+ unsigned long event ,
+ void* data ,
+ short wakeUp )
+{
+ wxMacNotificationEvents *e = (wxMacNotificationEvents *) table ;
+ wxASSERT_MSG( handler != NULL , wxT("illegal notification proc ptr") ) ;
+ /* this should be protected eventually */
+ short index = e->top++ ;
+
+ if ( e->top == kMaxEvents )
+ e->top = 0 ;
+
+ e->proc[index] = handler ;
+ e->events[index] = event ;
+ e->data[index] = data ;
+ if ( wakeUp )
+ wxMacWakeUp() ;
+}
+
+bool gInProcessing = false ;
+
+void wxMacRemoveAllNotifiersForData( wxMacNotifierTableRef table , void* data )
+{
+ wxMacNotificationEvents *e = (wxMacNotificationEvents *) table ;
+ /* this should be protected eventually */
+ short index = e->bottom ;
+
+ while ( e->top != index )
+ {
+ if ( e->data[index] == data )
+ e->data[index] = NULL ;
+ index++ ;
+ if ( index == kMaxEvents )
+ index = 0 ;
+ }
+}
+
+void wxMacProcessNotifierEvents()
+{
+ // if ( gInProcessing )
+ // return ;
+
+ gInProcessing = true ;
+ if ( gMacNotificationEvents.top != gMacNotificationEvents.bottom )
+ {
+ // we only should process the notifiers that were here when we entered it
+ // otherwise we might never get out...
+ short count = gMacNotificationEvents.top - gMacNotificationEvents.bottom ;
+ if ( count < 0 )
+ count += kMaxEvents ;
+
+ while ( count-- )
+ {
+ // consume event at bottom
+ short index = gMacNotificationEvents.bottom++ ;
+ if ( gMacNotificationEvents.bottom == kMaxEvents )
+ gMacNotificationEvents.bottom = 0 ;
+ void* data = gMacNotificationEvents.data[index] ;
+ unsigned long event = gMacNotificationEvents.events[index] ;
+ wxMacNotificationProcPtr handler = gMacNotificationEvents.proc[index] ;
+
+ gMacNotificationEvents.data[index] = NULL ;
+ gMacNotificationEvents.events[index] = NULL ;
+ gMacNotificationEvents.proc[index] = NULL ;
+
+ if ( handler )
+ handler( event , data ) ;
+ }
+ }
+ gInProcessing = false ;
+}
+
+void wxMacProcessNotifierAndPendingEvents()
+{
+ wxMacProcessNotifierEvents() ;
+ wxTheApp->ProcessPendingEvents() ;
+}
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: main.cpp
+// Purpose: Entry point
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+// We don't put main() in the library any more. GD.
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: mdi.cpp
+// Purpose: MDI classes
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "mdi.h"
+#endif
+
+#include "wx/mdi.h"
+#include "wx/menu.h"
+#include "wx/settings.h"
+#include "wx/log.h"
+
+#include "wx/mac/private.h"
+#include "wx/mac/uma.h"
+
+extern wxWindowList wxModelessWindows;
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame, wxFrame)
+IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame, wxFrame)
+IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow, wxWindow)
+
+BEGIN_EVENT_TABLE(wxMDIParentFrame, wxFrame)
+ EVT_ACTIVATE(wxMDIParentFrame::OnActivate)
+ EVT_SYS_COLOUR_CHANGED(wxMDIParentFrame::OnSysColourChanged)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(wxMDIClientWindow, wxWindow)
+ EVT_SCROLL(wxMDIClientWindow::OnScroll)
+END_EVENT_TABLE()
+
+#endif
+
+static const int IDM_WINDOWTILE = 4001;
+static const int IDM_WINDOWTILEHOR = 4001;
+static const int IDM_WINDOWCASCADE = 4002;
+static const int IDM_WINDOWICONS = 4003;
+static const int IDM_WINDOWNEXT = 4004;
+static const int IDM_WINDOWTILEVERT = 4005;
+static const int IDM_WINDOWPREV = 4006;
+
+// This range gives a maximum of 500 MDI children. Should be enough :-)
+static const int wxFIRST_MDI_CHILD = 4100;
+static const int wxLAST_MDI_CHILD = 4600;
+
+// Status border dimensions
+static const int wxTHICK_LINE_BORDER = 3;
+
+// Parent frame
+
+wxMDIParentFrame::wxMDIParentFrame()
+{
+ m_clientWindow = NULL;
+ m_currentChild = NULL;
+ m_windowMenu = (wxMenu*) NULL;
+ m_parentFrameActive = TRUE;
+}
+
+bool wxMDIParentFrame::Create(wxWindow *parent,
+ wxWindowID id,
+ const wxString& title,
+ const wxPoint& pos,
+ const wxSize& size,
+ long style,
+ const wxString& name)
+{
+ m_clientWindow = NULL;
+ m_currentChild = NULL;
+
+ // this style can be used to prevent a window from having the standard MDI
+ // "Window" menu
+ if ( style & wxFRAME_NO_WINDOW_MENU )
+ {
+ m_windowMenu = (wxMenu *)NULL;
+ style -= wxFRAME_NO_WINDOW_MENU ;
+ }
+ else // normal case: we have the window menu, so construct it
+ {
+ m_windowMenu = new wxMenu;
+
+ m_windowMenu->Append(IDM_WINDOWCASCADE, wxT("&Cascade"));
+ m_windowMenu->Append(IDM_WINDOWTILEHOR, wxT("Tile &Horizontally"));
+ m_windowMenu->Append(IDM_WINDOWTILEVERT, wxT("Tile &Vertically"));
+ m_windowMenu->AppendSeparator();
+ m_windowMenu->Append(IDM_WINDOWICONS, wxT("&Arrange Icons"));
+ m_windowMenu->Append(IDM_WINDOWNEXT, wxT("&Next"));
+ }
+
+ wxFrame::Create( parent , id , title , pos , size , style , name ) ;
+ m_parentFrameActive = TRUE;
+
+ OnCreateClient();
+
+ return TRUE;
+}
+
+wxMDIParentFrame::~wxMDIParentFrame()
+{
+ DestroyChildren();
+ // already delete by DestroyChildren()
+#if wxUSE_TOOLBAR
+ m_frameToolBar = NULL;
+#endif
+#if wxUSE_STATUSBAR
+ m_frameStatusBar = NULL;
+#endif
+ m_clientWindow = NULL ;
+
+ if (m_windowMenu)
+ {
+ delete m_windowMenu;
+ m_windowMenu = (wxMenu*) NULL;
+ }
+
+ if ( m_clientWindow )
+ {
+ delete m_clientWindow;
+ m_clientWindow = NULL ;
+ }
+}
+
+
+void wxMDIParentFrame::SetMenuBar(wxMenuBar *menu_bar)
+{
+ wxFrame::SetMenuBar( menu_bar ) ;
+}
+
+void wxMDIParentFrame::MacActivate(long timestamp, bool activating)
+{
+ wxLogDebug(wxT("MDI PARENT=%p MacActivate(0x%08lx,%s)"),this,timestamp,activating?wxT("ACTIV"):wxT("deact"));
+ if(activating)
+ {
+ if(s_macDeactivateWindow && s_macDeactivateWindow->GetParent()==this)
+ {
+ wxLogDebug(wxT("child had been scheduled for deactivation, rehighlighting"));
+ UMAHighlightAndActivateWindow((WindowRef)s_macDeactivateWindow->MacGetWindowRef(), true);
+ wxLogDebug(wxT("done highliting child"));
+ s_macDeactivateWindow = NULL;
+ }
+ else if(s_macDeactivateWindow == this)
+ {
+ wxLogDebug(wxT("Avoided deactivation/activation of this=%p"), this);
+ s_macDeactivateWindow = NULL;
+ }
+ else // window to deactivate is NULL or is not us or one of our kids
+ {
+ // activate kid instead
+ if(m_currentChild)
+ m_currentChild->MacActivate(timestamp,activating);
+ else
+ wxFrame::MacActivate(timestamp,activating);
+ }
+ }
+ else
+ {
+ // We were scheduled for deactivation, and now we do it.
+ if(s_macDeactivateWindow==this)
+ {
+ s_macDeactivateWindow = NULL;
+ if(m_currentChild)
+ m_currentChild->MacActivate(timestamp,activating);
+ wxFrame::MacActivate(timestamp,activating);
+ }
+ else // schedule ourselves for deactivation
+ {
+ if(s_macDeactivateWindow)
+ wxLogDebug(wxT("window=%p SHOULD have been deactivated, oh well!"),s_macDeactivateWindow);
+ wxLogDebug(wxT("Scheduling delayed MDI Parent deactivation"));
+ s_macDeactivateWindow = this;
+ }
+ }
+}
+
+void wxMDIParentFrame::OnActivate(wxActivateEvent& event)
+{
+ event.Skip();
+}
+
+// Returns the active MDI child window
+wxMDIChildFrame *wxMDIParentFrame::GetActiveChild() const
+{
+ return m_currentChild ;
+}
+
+// Create the client window class (don't Create the window,
+// just return a new class)
+wxMDIClientWindow *wxMDIParentFrame::OnCreateClient()
+{
+ m_clientWindow = new wxMDIClientWindow( this );
+ return m_clientWindow;
+}
+
+// Responds to colour changes, and passes event on to children.
+void wxMDIParentFrame::OnSysColourChanged(wxSysColourChangedEvent& event)
+{
+ // TODO
+
+ // Propagate the event to the non-top-level children
+ wxFrame::OnSysColourChanged(event);
+}
+
+// MDI operations
+void wxMDIParentFrame::Cascade()
+{
+ // TODO
+}
+
+void wxMDIParentFrame::Tile()
+{
+ // TODO
+}
+
+void wxMDIParentFrame::ArrangeIcons()
+{
+ // TODO
+}
+
+void wxMDIParentFrame::ActivateNext()
+{
+ // TODO
+}
+
+void wxMDIParentFrame::ActivatePrevious()
+{
+ // TODO
+}
+
+// Child frame
+
+wxMDIChildFrame::wxMDIChildFrame()
+{
+ Init() ;
+}
+void wxMDIChildFrame::Init()
+{
+}
+
+bool wxMDIChildFrame::Create(wxMDIParentFrame *parent,
+ wxWindowID id,
+ const wxString& title,
+ const wxPoint& pos,
+ const wxSize& size,
+ long style,
+ const wxString& name)
+{
+ SetName(name);
+
+ if ( id > -1 )
+ m_windowId = id;
+ else
+ m_windowId = (int)NewControlId();
+
+ if (parent) parent->AddChild(this);
+
+ MacCreateRealWindow( title, pos , size , MacRemoveBordersFromStyle(style) , name ) ;
+
+ m_macWindowBackgroundTheme = kThemeBrushDocumentWindowBackground ;
+ SetThemeWindowBackground( (WindowRef) m_macWindow , m_macWindowBackgroundTheme , false ) ;
+
+ wxModelessWindows.Append(this);
+ return FALSE;
+}
+
+wxMDIChildFrame::~wxMDIChildFrame()
+{
+ wxMDIParentFrame *mdiparent = wxDynamicCast(m_parent, wxMDIParentFrame);
+ wxASSERT(mdiparent);
+ if(mdiparent->m_currentChild == this)
+ mdiparent->m_currentChild = NULL;
+ DestroyChildren();
+ // already delete by DestroyChildren()
+#if wxUSE_TOOLBAR
+ m_frameToolBar = NULL;
+#endif
+#if wxUSE_STATUSBAR
+ m_frameStatusBar = NULL;
+#endif
+}
+
+void wxMDIChildFrame::SetMenuBar(wxMenuBar *menu_bar)
+{
+ return wxFrame::SetMenuBar( menu_bar ) ;
+}
+
+void wxMDIChildFrame::MacActivate(long timestamp, bool activating)
+{
+ wxLogDebug(wxT("MDI child=%p MacActivate(0x%08lx,%s)"),this,timestamp,activating?wxT("ACTIV"):wxT("deact"));
+ wxMDIParentFrame *mdiparent = wxDynamicCast(m_parent, wxMDIParentFrame);
+ wxASSERT(mdiparent);
+ if(activating)
+ {
+ if(s_macDeactivateWindow == m_parent)
+ {
+ wxLogDebug(wxT("parent had been scheduled for deactivation, rehighlighting"));
+ UMAHighlightAndActivateWindow((WindowRef)s_macDeactivateWindow->MacGetWindowRef(), true);
+ wxLogDebug(wxT("done highliting parent"));
+ s_macDeactivateWindow = NULL;
+ }
+ else if((mdiparent->m_currentChild==this) || !s_macDeactivateWindow)
+ mdiparent->wxFrame::MacActivate(timestamp,activating);
+
+ if(mdiparent->m_currentChild && mdiparent->m_currentChild!=this)
+ mdiparent->m_currentChild->wxFrame::MacActivate(timestamp,false);
+ mdiparent->m_currentChild = this;
+
+ if(s_macDeactivateWindow==this)
+ {
+ wxLogDebug(wxT("Avoided deactivation/activation of this=%p"),this);
+ s_macDeactivateWindow=NULL;
+ }
+ else
+ wxFrame::MacActivate(timestamp, activating);
+ }
+ else
+ {
+ // We were scheduled for deactivation, and now we do it.
+ if(s_macDeactivateWindow==this)
+ {
+ s_macDeactivateWindow = NULL;
+ wxFrame::MacActivate(timestamp,activating);
+ if(mdiparent->m_currentChild==this)
+ mdiparent->wxFrame::MacActivate(timestamp,activating);
+ }
+ else // schedule ourselves for deactivation
+ {
+ if(s_macDeactivateWindow)
+ wxLogDebug(wxT("window=%p SHOULD have been deactivated, oh well!"),s_macDeactivateWindow);
+ wxLogDebug(wxT("Scheduling delayed deactivation"));
+ s_macDeactivateWindow = this;
+ }
+ }
+}
+
+// MDI operations
+void wxMDIChildFrame::Maximize()
+{
+ wxFrame::Maximize() ;
+}
+
+void wxMDIChildFrame::Restore()
+{
+ wxFrame::Restore() ;
+}
+
+void wxMDIChildFrame::Activate()
+{
+}
+
+//-----------------------------------------------------------------------------
+// wxMDIClientWindow
+//-----------------------------------------------------------------------------
+
+wxMDIClientWindow::wxMDIClientWindow()
+{
+}
+
+wxMDIClientWindow::~wxMDIClientWindow()
+{
+ DestroyChildren();
+}
+
+bool wxMDIClientWindow::CreateClient(wxMDIParentFrame *parent, long style)
+{
+
+ m_windowId = (int)NewControlId();
+
+ if ( parent )
+ {
+ parent->AddChild(this);
+ }
+ m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE);
+
+ wxModelessWindows.Append(this);
+ return TRUE;
+}
+
+// Get size *available for subwindows* i.e. excluding menu bar.
+void wxMDIClientWindow::DoGetClientSize(int *x, int *y) const
+{
+ wxDisplaySize( x , y ) ;
+}
+
+// Explicitly call default scroll behaviour
+void wxMDIClientWindow::OnScroll(wxScrollEvent& event)
+{
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: menu.cpp
+// Purpose: wxMenu, wxMenuBar, wxMenuItem
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "menu.h"
+#pragma implementation "menuitem.h"
+#endif
+
+// ============================================================================
+// headers & declarations
+// ============================================================================
+
+// wxWindows headers
+// -----------------
+
+#include "wx/app.h"
+#include "wx/menu.h"
+#include "wx/menuitem.h"
+#include "wx/window.h"
+#include "wx/log.h"
+#include "wx/utils.h"
+#include "wx/frame.h"
+
+#include "wx/mac/uma.h"
+
+// other standard headers
+// ----------------------
+#include <string.h>
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxMenu, wxEvtHandler)
+IMPLEMENT_DYNAMIC_CLASS(wxMenuBar, wxEvtHandler)
+#endif
+
+// the (popup) menu title has this special id
+static const int idMenuTitle = -2;
+static MenuItemIndex firstUserHelpMenuItem = 0 ;
+
+const short kwxMacMenuBarResource = 1 ;
+const short kwxMacAppleMenuId = 1 ;
+
+// ============================================================================
+// implementation
+// ============================================================================
+static void wxMenubarUnsetInvokingWindow( wxMenu *menu ) ;
+static void wxMenubarSetInvokingWindow( wxMenu *menu, wxWindow *win );
+
+// Menus
+
+// Construct a menu with optional title (then use append)
+
+#ifdef __DARWIN__
+short wxMenu::s_macNextMenuId = 3 ;
+#else
+short wxMenu::s_macNextMenuId = 2 ;
+#endif
+
+void wxMenu::Init()
+{
+ m_doBreak = FALSE;
+ m_startRadioGroup = -1;
+
+ // create the menu
+ m_macMenuId = s_macNextMenuId++;
+ m_hMenu = UMANewMenu(m_macMenuId, m_title, wxFont::GetDefaultEncoding() );
+
+ if ( !m_hMenu )
+ {
+ wxLogLastError(wxT("UMANewMenu failed"));
+ }
+
+ // if we have a title, insert it in the beginning of the menu
+ if ( !!m_title )
+ {
+ Append(idMenuTitle, m_title) ;
+ AppendSeparator() ;
+ }
+}
+
+wxMenu::~wxMenu()
+{
+ if (MAC_WXHMENU(m_hMenu))
+ ::DisposeMenu(MAC_WXHMENU(m_hMenu));
+}
+
+void wxMenu::Break()
+{
+ // not available on the mac platform
+}
+
+void wxMenu::Attach(wxMenuBarBase *menubar)
+{
+ wxMenuBase::Attach(menubar);
+
+ EndRadioGroup();
+}
+
+// function appends a new item or submenu to the menu
+// append a new item or submenu to the menu
+bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos)
+{
+ wxASSERT_MSG( pItem != NULL, wxT("can't append NULL item to the menu") );
+
+ if ( pItem->IsSeparator() )
+ {
+ if ( pos == (size_t)-1 )
+ MacAppendMenu(MAC_WXHMENU(m_hMenu), "\p-");
+ else
+ MacInsertMenuItem(MAC_WXHMENU(m_hMenu), "\p-" , pos);
+ }
+ else
+ {
+ wxMenu *pSubMenu = pItem->GetSubMenu() ;
+ if ( pSubMenu != NULL )
+ {
+ wxASSERT_MSG( pSubMenu->m_hMenu != NULL , wxT("invalid submenu added"));
+ pSubMenu->m_menuParent = this ;
+
+ if (wxMenuBar::MacGetInstalledMenuBar() == m_menuBar)
+ {
+ pSubMenu->MacBeforeDisplay( true ) ;
+ }
+
+ if ( pos == (size_t)-1 )
+ UMAAppendSubMenuItem(MAC_WXHMENU(m_hMenu), pItem->GetText(), wxFont::GetDefaultEncoding() , pSubMenu->m_macMenuId);
+ else
+ UMAInsertSubMenuItem(MAC_WXHMENU(m_hMenu), pItem->GetText(), wxFont::GetDefaultEncoding() , pos, pSubMenu->m_macMenuId);
+ pItem->UpdateItemBitmap() ;
+ pItem->UpdateItemStatus() ;
+ }
+ else
+ {
+ if ( pos == (size_t)-1 )
+ {
+ UMAAppendMenuItem(MAC_WXHMENU(m_hMenu), wxT("a") , wxFont::GetDefaultEncoding() );
+ pos = CountMenuItems(MAC_WXHMENU(m_hMenu)) ;
+ }
+ else
+ {
+ // MacOS counts menu items from 1 and inserts after, therefore having the
+ // same effect as wx 0 based and inserting before, we must correct pos
+ // after however for updates to be correct
+ UMAInsertMenuItem(MAC_WXHMENU(m_hMenu), wxT("a"), wxFont::GetDefaultEncoding(), pos);
+ pos += 1 ;
+ }
+
+ SetMenuItemCommandID( MAC_WXHMENU(m_hMenu) , pos , pItem->GetId() ) ;
+ pItem->UpdateItemText() ;
+ pItem->UpdateItemBitmap() ;
+ pItem->UpdateItemStatus() ;
+
+ if ( pItem->GetId() == idMenuTitle )
+ {
+ UMAEnableMenuItem(MAC_WXHMENU(m_hMenu) , pos , false ) ;
+ }
+ }
+ }
+ // if we're already attached to the menubar, we must update it
+ if ( IsAttached() )
+ {
+ m_menuBar->Refresh();
+ }
+ return TRUE ;
+}
+
+void wxMenu::EndRadioGroup()
+{
+ // we're not inside a radio group any longer
+ m_startRadioGroup = -1;
+}
+
+wxMenuItem* wxMenu::DoAppend(wxMenuItem *item)
+{
+ wxCHECK_MSG( item, NULL, _T("NULL item in wxMenu::DoAppend") );
+
+ bool check = FALSE;
+
+ if ( item->GetKind() == wxITEM_RADIO )
+ {
+ int count = GetMenuItemCount();
+
+ if ( m_startRadioGroup == -1 )
+ {
+ // start a new radio group
+ m_startRadioGroup = count;
+
+ // for now it has just one element
+ item->SetAsRadioGroupStart();
+ item->SetRadioGroupEnd(m_startRadioGroup);
+
+ // ensure that we have a checked item in the radio group
+ check = TRUE;
+ }
+ else // extend the current radio group
+ {
+ // we need to update its end item
+ item->SetRadioGroupStart(m_startRadioGroup);
+ wxMenuItemList::Node *node = GetMenuItems().Item(m_startRadioGroup);
+
+ if ( node )
+ {
+ node->GetData()->SetRadioGroupEnd(count);
+ }
+ else
+ {
+ wxFAIL_MSG( _T("where is the radio group start item?") );
+ }
+ }
+ }
+ else // not a radio item
+ {
+ EndRadioGroup();
+ }
+
+ if ( !wxMenuBase::DoAppend(item) || !DoInsertOrAppend(item) )
+ {
+ return NULL;
+ }
+
+ if ( check )
+ {
+ // check the item initially
+ item->Check(TRUE);
+ }
+
+ return item;
+}
+
+wxMenuItem* wxMenu::DoInsert(size_t pos, wxMenuItem *item)
+{
+ if (wxMenuBase::DoInsert(pos, item) && DoInsertOrAppend(item, pos))
+ return item;
+ else
+ return NULL;
+}
+
+wxMenuItem *wxMenu::DoRemove(wxMenuItem *item)
+{
+ // we need to find the items position in the child list
+ size_t pos;
+ wxMenuItemList::Node *node = GetMenuItems().GetFirst();
+ for ( pos = 0; node; pos++ )
+ {
+ if ( node->GetData() == item )
+ break;
+
+ node = node->GetNext();
+ }
+
+ // DoRemove() (unlike Remove) can only be called for existing item!
+ wxCHECK_MSG( node, NULL, wxT("bug in wxMenu::Remove logic") );
+
+ ::DeleteMenuItem(MAC_WXHMENU(m_hMenu) , pos + 1);
+
+ if ( IsAttached() )
+ {
+ // otherwise, the change won't be visible
+ m_menuBar->Refresh();
+ }
+
+ // and from internal data structures
+ return wxMenuBase::DoRemove(item);
+}
+
+void wxMenu::SetTitle(const wxString& label)
+{
+ m_title = label ;
+ UMASetMenuTitle(MAC_WXHMENU(m_hMenu) , label , wxFont::GetDefaultEncoding() ) ;
+}
+bool wxMenu::ProcessCommand(wxCommandEvent & event)
+{
+ bool processed = FALSE;
+
+ // Try the menu's event handler
+ if ( !processed && GetEventHandler())
+ {
+ processed = GetEventHandler()->ProcessEvent(event);
+ }
+
+ // Try the window the menu was popped up from (and up through the
+ // hierarchy)
+ wxWindow *win = GetInvokingWindow();
+ if ( !processed && win )
+ processed = win->GetEventHandler()->ProcessEvent(event);
+
+ return processed;
+}
+
+
+// ---------------------------------------------------------------------------
+// other
+// ---------------------------------------------------------------------------
+
+wxWindow *wxMenu::GetWindow() const
+{
+ if ( m_invokingWindow != NULL )
+ return m_invokingWindow;
+ else if ( m_menuBar != NULL)
+ return (wxWindow *) m_menuBar->GetFrame();
+
+ return NULL;
+}
+
+// helper functions returning the mac menu position for a certain item, note that this is
+// mac-wise 1 - based, i.e. the first item has index 1 whereas on MSWin it has pos 0
+
+int wxMenu::MacGetIndexFromId( int id )
+{
+ size_t pos;
+ wxMenuItemList::Node *node = GetMenuItems().GetFirst();
+ for ( pos = 0; node; pos++ )
+ {
+ if ( node->GetData()->GetId() == id )
+ break;
+
+ node = node->GetNext();
+ }
+
+ if (!node)
+ return 0;
+
+ return pos + 1 ;
+}
+
+int wxMenu::MacGetIndexFromItem( wxMenuItem *pItem )
+{
+ size_t pos;
+ wxMenuItemList::Node *node = GetMenuItems().GetFirst();
+ for ( pos = 0; node; pos++ )
+ {
+ if ( node->GetData() == pItem )
+ break;
+
+ node = node->GetNext();
+ }
+
+ if (!node)
+ return 0;
+
+ return pos + 1 ;
+}
+
+void wxMenu::MacEnableMenu( bool bDoEnable )
+{
+ UMAEnableMenuItem(MAC_WXHMENU(m_hMenu) , 0 , bDoEnable ) ;
+
+ ::DrawMenuBar() ;
+}
+
+// MacOS needs to know about submenus somewhere within this menu
+// before it can be displayed , also hide special menu items like preferences
+// that are handled by the OS
+void wxMenu::MacBeforeDisplay( bool isSubMenu )
+{
+ wxMenuItem* previousItem = NULL ;
+ size_t pos ;
+ wxMenuItemList::Node *node;
+ wxMenuItem *item;
+ for (pos = 0, node = GetMenuItems().GetFirst(); node; node = node->GetNext(), pos++)
+ {
+ item = (wxMenuItem *)node->GetData();
+ wxMenu* subMenu = item->GetSubMenu() ;
+ if (subMenu)
+ {
+ subMenu->MacBeforeDisplay( true ) ;
+ }
+ else
+ {
+ #if TARGET_CARBON
+ if ( UMAGetSystemVersion() >= 0x1000 )
+ {
+ if ( item->GetId() == wxApp::s_macPreferencesMenuItemId || item->GetId() == wxApp::s_macExitMenuItemId)
+ {
+ ChangeMenuItemAttributes( MAC_WXHMENU( GetHMenu() ) , pos + 1, kMenuItemAttrHidden, 0 );
+ if ( GetMenuItems().GetCount() == pos + 1 &&
+ previousItem != NULL &&
+ previousItem->IsSeparator() )
+ {
+ ChangeMenuItemAttributes( MAC_WXHMENU( GetHMenu() ) , pos , kMenuItemAttrHidden, 0 );
+ }
+ }
+ }
+ #endif
+ }
+ previousItem = item ;
+ }
+
+ if ( isSubMenu )
+ ::InsertMenu(MAC_WXHMENU( GetHMenu()), -1);
+
+}
+// undo all changes from the MacBeforeDisplay call
+void wxMenu::MacAfterDisplay( bool isSubMenu )
+{
+ if ( isSubMenu )
+ ::DeleteMenu(MacGetMenuId());
+
+ wxMenuItem* previousItem = NULL ;
+ int pos ;
+ wxMenuItemList::Node *node;
+ wxMenuItem *item;
+ for (pos = 0, node = GetMenuItems().GetFirst(); node; node = node->GetNext(), pos++)
+ {
+ item = (wxMenuItem *)node->GetData();
+ wxMenu* subMenu = item->GetSubMenu() ;
+ if (subMenu)
+ {
+ subMenu->MacAfterDisplay( true ) ;
+ }
+ else
+ {
+ // no need to undo hidings
+ }
+ previousItem = item ;
+ }
+}
+
+// Menu Bar
+
+/*
+
+Mac Implementation note :
+
+The Mac has only one global menubar, so we attempt to install the currently
+active menubar from a frame, we currently don't take into account mdi-frames
+which would ask for menu-merging
+
+Secondly there is no mac api for changing a menubar that is not the current
+menubar, so we have to wait for preparing the actual menubar until the
+wxMenubar is to be used
+
+We can in subsequent versions use MacInstallMenuBar to provide some sort of
+auto-merge for MDI in case this will be necessary
+
+*/
+
+wxMenuBar* wxMenuBar::s_macInstalledMenuBar = NULL ;
+wxMenuBar* wxMenuBar::s_macCommonMenuBar = NULL ;
+
+void wxMenuBar::Init()
+{
+ m_eventHandler = this;
+ m_menuBarFrame = NULL;
+ m_invokingWindow = (wxWindow*) NULL;
+}
+
+wxMenuBar::wxMenuBar()
+{
+ Init();
+}
+
+wxMenuBar::wxMenuBar( long WXUNUSED(style) )
+{
+ Init();
+}
+
+
+wxMenuBar::wxMenuBar(int count, wxMenu *menus[], const wxString titles[])
+{
+ Init();
+
+ m_titles.Alloc(count);
+
+ for ( int i = 0; i < count; i++ )
+ {
+ m_menus.Append(menus[i]);
+ m_titles.Add(titles[i]);
+
+ menus[i]->Attach(this);
+ }
+}
+
+wxMenuBar::~wxMenuBar()
+{
+ if (s_macCommonMenuBar == this)
+ s_macCommonMenuBar = NULL;
+ if (s_macInstalledMenuBar == this)
+ {
+ ::ClearMenuBar();
+ s_macInstalledMenuBar = NULL;
+ }
+
+}
+
+void wxMenuBar::Refresh(bool WXUNUSED(eraseBackground), const wxRect *WXUNUSED(rect))
+{
+ wxCHECK_RET( IsAttached(), wxT("can't refresh unatteched menubar") );
+
+ DrawMenuBar();
+}
+
+void wxMenuBar::MacInstallMenuBar()
+{
+ if ( s_macInstalledMenuBar == this )
+ return ;
+
+ wxStAppResource resload ;
+
+ Handle menubar = ::GetNewMBar( kwxMacMenuBarResource ) ;
+ wxString message ;
+ wxCHECK_RET( menubar != NULL, wxT("can't read MBAR resource") );
+ ::SetMenuBar( menubar ) ;
+#if TARGET_API_MAC_CARBON
+ ::DisposeMenuBar( menubar ) ;
+#else
+ ::DisposeHandle( menubar ) ;
+#endif
+
+#if TARGET_API_MAC_OS8
+ MenuHandle menu = ::GetMenuHandle( kwxMacAppleMenuId ) ;
+ if ( CountMenuItems( menu ) == 2 )
+ {
+ ::AppendResMenu(menu, 'DRVR');
+ }
+#endif
+
+ // clean-up the help menu before adding new items
+ MenuHandle mh = NULL ;
+ if ( UMAGetHelpMenu( &mh , &firstUserHelpMenuItem) == noErr )
+ {
+ for ( int i = CountMenuItems( mh ) ; i >= firstUserHelpMenuItem ; --i )
+ {
+ DeleteMenuItem( mh , i ) ;
+ }
+ }
+ else
+ {
+ mh = NULL ;
+ }
+#if TARGET_CARBON
+ if ( UMAGetSystemVersion() >= 0x1000 && wxApp::s_macPreferencesMenuItemId)
+ {
+ wxMenuItem *item = FindItem( wxApp::s_macPreferencesMenuItemId , NULL ) ;
+ if ( item == NULL || !(item->IsEnabled()) )
+ DisableMenuCommand( NULL , kHICommandPreferences ) ;
+ else
+ EnableMenuCommand( NULL , kHICommandPreferences ) ;
+ }
+#endif
+ for (size_t i = 0; i < m_menus.GetCount(); i++)
+ {
+ wxMenuItemList::Node *node;
+ wxMenuItem *item;
+ int pos ;
+ wxMenu* menu = m_menus[i] , *subMenu = NULL ;
+
+ if( m_titles[i] == wxT("?") || m_titles[i] == wxT("&?") || m_titles[i] == wxApp::s_macHelpMenuTitleName )
+ {
+ if ( mh == NULL )
+ {
+ continue ;
+ }
+
+ for (pos = 0 , node = menu->GetMenuItems().GetFirst(); node; node = node->GetNext(), pos++)
+ {
+ item = (wxMenuItem *)node->GetData();
+ subMenu = item->GetSubMenu() ;
+ if (subMenu)
+ {
+ // we don't support hierarchical menus in the help menu yet
+ }
+ else
+ {
+ if ( item->IsSeparator() )
+ {
+ if ( mh )
+ MacAppendMenu(mh, "\p-" );
+ }
+ else
+ {
+ wxAcceleratorEntry* entry = wxGetAccelFromString( item->GetText() ) ;
+
+ if ( item->GetId() == wxApp::s_macAboutMenuItemId )
+ {
+ UMASetMenuItemText( GetMenuHandle( kwxMacAppleMenuId ) , 1 , item->GetText() , wxFont::GetDefaultEncoding() );
+ UMAEnableMenuItem( GetMenuHandle( kwxMacAppleMenuId ) , 1 , true );
+ SetMenuItemCommandID( GetMenuHandle( kwxMacAppleMenuId ) , 1 , item->GetId() ) ;
+ UMASetMenuItemShortcut( GetMenuHandle( kwxMacAppleMenuId ) , 1 , entry ) ;
+ }
+ else
+ {
+ if ( mh )
+ {
+ UMAAppendMenuItem(mh, item->GetText() , wxFont::GetDefaultEncoding(), entry);
+ SetMenuItemCommandID( mh , CountMenuItems(mh) , item->GetId() ) ;
+ }
+ }
+
+ delete entry ;
+ }
+ }
+ }
+ }
+ else
+ {
+ UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , m_titles[i], m_font.GetEncoding() ) ;
+ m_menus[i]->MacBeforeDisplay(false) ;
+ ::InsertMenu(MAC_WXHMENU(m_menus[i]->GetHMenu()), 0);
+ }
+ }
+ ::DrawMenuBar() ;
+ s_macInstalledMenuBar = this;
+}
+
+void wxMenuBar::EnableTop(size_t pos, bool enable)
+{
+ wxCHECK_RET( IsAttached(), wxT("doesn't work with unattached menubars") );
+ m_menus[pos]->MacEnableMenu( enable ) ;
+ Refresh();
+}
+
+void wxMenuBar::SetLabelTop(size_t pos, const wxString& label)
+{
+ wxCHECK_RET( pos < GetMenuCount(), wxT("invalid menu index") );
+
+ m_titles[pos] = label;
+
+ if ( !IsAttached() )
+ {
+ return;
+ }
+
+ m_menus[pos]->SetTitle( label ) ;
+ if (wxMenuBar::s_macInstalledMenuBar == this) // are we currently installed ?
+ {
+ ::SetMenuBar( GetMenuBar() ) ;
+ ::InvalMenuBar() ;
+ }
+}
+
+wxString wxMenuBar::GetLabelTop(size_t pos) const
+{
+ wxCHECK_MSG( pos < GetMenuCount(), wxEmptyString,
+ wxT("invalid menu index in wxMenuBar::GetLabelTop") );
+
+ return m_titles[pos];
+}
+
+int wxMenuBar::FindMenu(const wxString& title)
+{
+ wxString menuTitle = wxStripMenuCodes(title);
+
+ size_t count = GetMenuCount();
+ for ( size_t i = 0; i < count; i++ )
+ {
+ wxString title = wxStripMenuCodes(m_titles[i]);
+ if ( menuTitle == title )
+ return i;
+ }
+
+ return wxNOT_FOUND;
+
+}
+
+
+// ---------------------------------------------------------------------------
+// wxMenuBar construction
+// ---------------------------------------------------------------------------
+
+// ---------------------------------------------------------------------------
+// wxMenuBar construction
+// ---------------------------------------------------------------------------
+
+wxMenu *wxMenuBar::Replace(size_t pos, wxMenu *menu, const wxString& title)
+{
+ wxMenu *menuOld = wxMenuBarBase::Replace(pos, menu, title);
+ if ( !menuOld )
+ return FALSE;
+ m_titles[pos] = title;
+
+ if ( IsAttached() )
+ {
+ if (s_macInstalledMenuBar == this)
+ {
+ menuOld->MacAfterDisplay( false ) ;
+ ::DeleteMenu( menuOld->MacGetMenuId() /* m_menus[pos]->MacGetMenuId() */ ) ;
+ {
+ menu->MacBeforeDisplay( false ) ;
+ UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , title , m_font.GetEncoding() ) ;
+ if ( pos == m_menus.GetCount() - 1)
+ {
+ ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , 0 ) ;
+ }
+ else
+ {
+ ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , m_menus[pos+1]->MacGetMenuId() ) ;
+ }
+ }
+ }
+
+ Refresh();
+ }
+
+ return menuOld;
+}
+
+bool wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title)
+{
+ if ( !wxMenuBarBase::Insert(pos, menu, title) )
+ return FALSE;
+
+ m_titles.Insert(title, pos);
+
+ UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , title , m_font.GetEncoding() ) ;
+
+ if ( IsAttached() && s_macInstalledMenuBar == this )
+ {
+ if (s_macInstalledMenuBar == this)
+ {
+ menu->MacBeforeDisplay( false ) ;
+ if ( pos == (size_t) -1 || pos + 1 == m_menus.GetCount() )
+ {
+ ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , 0 ) ;
+ }
+ else
+ {
+ ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , m_menus[pos+1]->MacGetMenuId() ) ;
+ }
+ }
+ Refresh();
+ }
+
+ return TRUE;
+}
+
+wxMenu *wxMenuBar::Remove(size_t pos)
+{
+ wxMenu *menu = wxMenuBarBase::Remove(pos);
+ if ( !menu )
+ return NULL;
+
+ if ( IsAttached() )
+ {
+ if (s_macInstalledMenuBar == this)
+ {
+ ::DeleteMenu( menu->MacGetMenuId() /* m_menus[pos]->MacGetMenuId() */ ) ;
+ }
+
+ Refresh();
+ }
+
+ m_titles.RemoveAt(pos);
+
+ return menu;
+}
+
+bool wxMenuBar::Append(wxMenu *menu, const wxString& title)
+{
+ WXHMENU submenu = menu ? menu->GetHMenu() : 0;
+ wxCHECK_MSG( submenu, FALSE, wxT("can't append invalid menu to menubar") );
+
+ if ( !wxMenuBarBase::Append(menu, title) )
+ return FALSE;
+
+ m_titles.Add(title);
+
+ UMASetMenuTitle( MAC_WXHMENU(menu->GetHMenu()) , title , m_font.GetEncoding() ) ;
+
+ if ( IsAttached() )
+ {
+ if (s_macInstalledMenuBar == this)
+ {
+ ::InsertMenu( MAC_WXHMENU(menu->GetHMenu()) , 0 ) ;
+ }
+
+ Refresh();
+ }
+
+ // m_invokingWindow is set after wxFrame::SetMenuBar(). This call enables
+ // adding menu later on.
+ if (m_invokingWindow)
+ wxMenubarSetInvokingWindow( menu, m_invokingWindow );
+
+ return TRUE;
+}
+
+static void wxMenubarUnsetInvokingWindow( wxMenu *menu )
+{
+ menu->SetInvokingWindow( (wxWindow*) NULL );
+
+ wxMenuItemList::Node *node = menu->GetMenuItems().GetFirst();
+ while (node)
+ {
+ wxMenuItem *menuitem = node->GetData();
+ if (menuitem->IsSubMenu())
+ wxMenubarUnsetInvokingWindow( menuitem->GetSubMenu() );
+ node = node->GetNext();
+ }
+}
+
+static void wxMenubarSetInvokingWindow( wxMenu *menu, wxWindow *win )
+{
+ menu->SetInvokingWindow( win );
+
+ wxMenuItemList::Node *node = menu->GetMenuItems().GetFirst();
+ while (node)
+ {
+ wxMenuItem *menuitem = node->GetData();
+ if (menuitem->IsSubMenu())
+ wxMenubarSetInvokingWindow( menuitem->GetSubMenu() , win );
+ node = node->GetNext();
+ }
+}
+
+void wxMenuBar::UnsetInvokingWindow()
+{
+ m_invokingWindow = (wxWindow*) NULL;
+ wxMenuList::Node *node = m_menus.GetFirst();
+ while (node)
+ {
+ wxMenu *menu = node->GetData();
+ wxMenubarUnsetInvokingWindow( menu );
+ node = node->GetNext();
+ }
+}
+
+void wxMenuBar::SetInvokingWindow(wxFrame *frame)
+{
+ m_invokingWindow = frame;
+ wxMenuList::Node *node = m_menus.GetFirst();
+ while (node)
+ {
+ wxMenu *menu = node->GetData();
+ wxMenubarSetInvokingWindow( menu, frame );
+ node = node->GetNext();
+ }
+}
+
+void wxMenuBar::Detach()
+{
+ wxMenuBarBase::Detach() ;
+}
+
+void wxMenuBar::Attach(wxFrame *frame)
+{
+ wxMenuBarBase::Attach( frame ) ;
+}
+// ---------------------------------------------------------------------------
+// wxMenuBar searching for menu items
+// ---------------------------------------------------------------------------
+
+// Find the itemString in menuString, and return the item id or wxNOT_FOUND
+int wxMenuBar::FindMenuItem(const wxString& menuString,
+ const wxString& itemString) const
+{
+ wxString menuLabel = wxStripMenuCodes(menuString);
+ size_t count = GetMenuCount();
+ for ( size_t i = 0; i < count; i++ )
+ {
+ wxString title = wxStripMenuCodes(m_titles[i]);
+ if ( menuString == title )
+ return m_menus[i]->FindItem(itemString);
+ }
+
+ return wxNOT_FOUND;
+}
+
+wxMenuItem *wxMenuBar::FindItem(int id, wxMenu **itemMenu) const
+{
+ if ( itemMenu )
+ *itemMenu = NULL;
+
+ wxMenuItem *item = NULL;
+ size_t count = GetMenuCount();
+ for ( size_t i = 0; !item && (i < count); i++ )
+ {
+ item = m_menus[i]->FindItem(id, itemMenu);
+ }
+
+ return item;
+}
+
+
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Name: menuitem.cpp
+// Purpose: wxMenuItem implementation
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// headers & declarations
+// ============================================================================
+
+#include "wx/app.h"
+#include "wx/menu.h"
+#include "wx/menuitem.h"
+
+#include "wx/mac/uma.h"
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// dynamic classes implementation
+// ----------------------------------------------------------------------------
+
+#if !USE_SHARED_LIBRARY
+ IMPLEMENT_DYNAMIC_CLASS(wxMenuItem, wxObject)
+#endif //USE_SHARED_LIBRARY
+
+// ----------------------------------------------------------------------------
+// wxMenuItem
+// ----------------------------------------------------------------------------
+
+//
+// ctor & dtor
+// -----------
+
+wxMenuItem::wxMenuItem(wxMenu *pParentMenu,
+ int id,
+ const wxString& text,
+ const wxString& strHelp,
+ wxItemKind kind,
+ wxMenu *pSubMenu)
+ : wxMenuItemBase(pParentMenu, id, text, strHelp, kind, pSubMenu)
+{
+ // TO DISCUSS on dev : whether we can veto id 0
+ // wxASSERT_MSG( id != 0 || pSubMenu != NULL , wxT("A MenuItem ID of Zero does not work under Mac") ) ;
+
+ // In other languages there is no difference in naming the Exit/Quit menu item between MacOS and Windows guidelines
+ // therefore these item must not be translated
+ if ( wxStripMenuCodes(m_text).Upper() == wxT("EXIT") )
+ {
+ m_text =wxT("Quit\tCtrl+Q") ;
+ }
+
+ m_radioGroup.start = -1;
+ m_isRadioGroupStart = FALSE;
+}
+
+wxMenuItem::~wxMenuItem()
+{
+}
+
+// change item state
+// -----------------
+
+void wxMenuItem::SetBitmap(const wxBitmap& bitmap)
+{
+ m_bitmap = bitmap;
+ UpdateItemBitmap() ;
+}
+
+void wxMenuItem::UpdateItemBitmap()
+{
+ if ( !m_parentMenu )
+ return ;
+
+ MenuHandle mhandle = MAC_WXHMENU(m_parentMenu->GetHMenu()) ;
+ MenuItemIndex index = m_parentMenu->MacGetIndexFromItem( this ) ;
+ if( mhandle == NULL || index == 0)
+ return ;
+
+ if ( m_bitmap.Ok() )
+ {
+ ControlButtonContentInfo info ;
+ wxMacCreateBitmapButton( &info , m_bitmap , kControlContentCIconHandle ) ;
+ if ( info.contentType != kControlNoContent )
+ {
+ if ( info.contentType == kControlContentCIconHandle )
+ SetMenuItemIconHandle( mhandle , index ,
+ kMenuColorIconType , (Handle) info.u.cIconHandle ) ;
+ }
+
+ }
+}
+
+void wxMenuItem::UpdateItemStatus()
+{
+ if ( !m_parentMenu )
+ return ;
+
+#if TARGET_CARBON
+ if ( UMAGetSystemVersion() >= 0x1000 && GetId() == wxApp::s_macPreferencesMenuItemId)
+ {
+ if ( !IsEnabled() )
+ DisableMenuCommand( NULL , kHICommandPreferences ) ;
+ else
+ EnableMenuCommand( NULL , kHICommandPreferences ) ;
+ }
+ if ( UMAGetSystemVersion() >= 0x1000 && GetId() == wxApp::s_macExitMenuItemId)
+ {
+ if ( !IsEnabled() )
+ DisableMenuCommand( NULL , kHICommandQuit ) ;
+ else
+ EnableMenuCommand( NULL , kHICommandQuit ) ;
+ }
+#endif
+ {
+ MenuHandle mhandle = MAC_WXHMENU(m_parentMenu->GetHMenu()) ;
+ MenuItemIndex index = m_parentMenu->MacGetIndexFromItem( this ) ;
+ if( mhandle == NULL || index == 0)
+ return ;
+
+ UMAEnableMenuItem( mhandle , index , m_isEnabled ) ;
+ if ( IsCheckable() && IsChecked() )
+ ::SetItemMark( mhandle , index , 0x12 ) ; // checkmark
+ else
+ ::SetItemMark( mhandle , index , 0 ) ; // no mark
+
+ UMASetMenuItemText( mhandle , index , m_text , wxFont::GetDefaultEncoding() ) ;
+ wxAcceleratorEntry *entry = wxGetAccelFromString( m_text ) ;
+ UMASetMenuItemShortcut( mhandle , index , entry ) ;
+ delete entry ;
+ }
+}
+
+void wxMenuItem::UpdateItemText()
+{
+ if ( !m_parentMenu )
+ return ;
+
+ MenuHandle mhandle = MAC_WXHMENU(m_parentMenu->GetHMenu()) ;
+ MenuItemIndex index = m_parentMenu->MacGetIndexFromItem( this ) ;
+ if( mhandle == NULL || index == 0)
+ return ;
+
+ UMASetMenuItemText( mhandle , index , m_text , wxFont::GetDefaultEncoding() ) ;
+ wxAcceleratorEntry *entry = wxGetAccelFromString( m_text ) ;
+ UMASetMenuItemShortcut( mhandle , index , entry ) ;
+ delete entry ;
+}
+
+
+void wxMenuItem::Enable(bool bDoEnable)
+{
+ if ( m_isEnabled != bDoEnable )
+ {
+ wxMenuItemBase::Enable( bDoEnable ) ;
+ UpdateItemStatus() ;
+ }
+}
+void wxMenuItem::UncheckRadio()
+{
+ if ( m_isChecked )
+ {
+ wxMenuItemBase::Check( false ) ;
+ UpdateItemStatus() ;
+ }
+}
+
+void wxMenuItem::Check(bool bDoCheck)
+{
+ wxCHECK_RET( IsCheckable(), wxT("only checkable items may be checked") );
+
+ if ( m_isChecked != bDoCheck )
+ {
+ if ( GetKind() == wxITEM_RADIO )
+ {
+ if ( bDoCheck )
+ {
+ wxMenuItemBase::Check( bDoCheck ) ;
+ UpdateItemStatus() ;
+
+ // get the index of this item in the menu
+ const wxMenuItemList& items = m_parentMenu->GetMenuItems();
+ int pos = items.IndexOf(this);
+ wxCHECK_RET( pos != wxNOT_FOUND,
+ _T("menuitem not found in the menu items list?") );
+
+ // get the radio group range
+ int start,
+ end;
+
+ if ( m_isRadioGroupStart )
+ {
+ // we already have all information we need
+ start = pos;
+ end = m_radioGroup.end;
+ }
+ else // next radio group item
+ {
+ // get the radio group end from the start item
+ start = m_radioGroup.start;
+ end = items.Item(start)->GetData()->m_radioGroup.end;
+ }
+
+ // also uncheck all the other items in this radio group
+ wxMenuItemList::Node *node = items.Item(start);
+ for ( int n = start; n <= end && node; n++ )
+ {
+ if ( n != pos )
+ {
+ ((wxMenuItem*)node->GetData())->UncheckRadio();
+ }
+ node = node->GetNext();
+ }
+ }
+ }
+ else
+ {
+ wxMenuItemBase::Check( bDoCheck ) ;
+ UpdateItemStatus() ;
+ }
+ }
+}
+
+void wxMenuItem::SetText(const wxString& text)
+{
+ // don't do anything if label didn't change
+ if ( m_text == text )
+ return;
+
+ wxMenuItemBase::SetText(text);
+
+ UpdateItemText() ;
+}
+
+// radio group stuff
+// -----------------
+
+void wxMenuItem::SetAsRadioGroupStart()
+{
+ m_isRadioGroupStart = TRUE;
+}
+
+void wxMenuItem::SetRadioGroupStart(int start)
+{
+ wxASSERT_MSG( !m_isRadioGroupStart,
+ _T("should only be called for the next radio items") );
+
+ m_radioGroup.start = start;
+}
+
+void wxMenuItem::SetRadioGroupEnd(int end)
+{
+ wxASSERT_MSG( m_isRadioGroupStart,
+ _T("should only be called for the first radio item") );
+
+ m_radioGroup.end = end;
+}
+
+// ----------------------------------------------------------------------------
+// wxMenuItemBase
+// ----------------------------------------------------------------------------
+
+/* static */
+wxString wxMenuItemBase::GetLabelFromText(const wxString& text)
+{
+ return wxStripMenuCodes(text);
+}
+
+wxMenuItem *wxMenuItemBase::New(wxMenu *parentMenu,
+ int id,
+ const wxString& name,
+ const wxString& help,
+ wxItemKind kind,
+ wxMenu *subMenu)
+{
+ return new wxMenuItem(parentMenu, id, name, help, kind, subMenu);
+}
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: metafile.cpp
+// Purpose: wxMetaFile, wxMetaFileDC etc. These classes are optional.
+// Author: Stefan Csomor
+// Modified by:
+// Created: 04/01/98
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "metafile.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/setup.h"
+#endif
+
+#if wxUSE_METAFILE
+
+#ifndef WX_PRECOMP
+#include "wx/utils.h"
+#include "wx/app.h"
+#endif
+
+#include "wx/metafile.h"
+#include "wx/clipbrd.h"
+
+#include "wx/mac/private.h"
+
+#include <stdio.h>
+#include <string.h>
+
+extern bool wxClipboardIsOpen;
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxMetafile, wxObject)
+IMPLEMENT_ABSTRACT_CLASS(wxMetafileDC, wxDC)
+#endif
+
+/*
+ * Metafiles
+ * Currently, the only purpose for making a metafile is to put
+ * it on the clipboard.
+ */
+
+wxMetafileRefData::wxMetafileRefData(void)
+{
+ m_metafile = 0;
+}
+
+wxMetafileRefData::~wxMetafileRefData(void)
+{
+ if (m_metafile)
+ {
+ KillPicture( (PicHandle) m_metafile ) ;
+ m_metafile = 0;
+ }
+}
+
+wxMetaFile::wxMetaFile(const wxString& file)
+{
+ m_refData = new wxMetafileRefData;
+
+
+ M_METAFILEDATA->m_metafile = 0;
+ wxASSERT_MSG( file.IsEmpty() , wxT("no file based metafile support yet") ) ;
+/*
+ if (!file.IsNull() && (file.Cmp("") == 0))
+ M_METAFILEDATA->m_metafile = (WXHANDLE) GetMetaFile(file);
+*/
+}
+
+wxMetaFile::~wxMetaFile()
+{
+}
+
+bool wxMetaFile::SetClipboard(int width, int height)
+{
+#if wxUSE_DRAG_AND_DROP
+ //TODO finishi this port , we need the data obj first
+ if (!m_refData)
+ return FALSE;
+
+ bool alreadyOpen=wxTheClipboard->IsOpened() ;
+ if (!alreadyOpen)
+ {
+ wxTheClipboard->Open();
+ wxTheClipboard->Clear();
+ }
+ wxDataObject *data =
+ new wxMetafileDataObject( *this) ;
+ bool success = wxTheClipboard->SetData(data);
+ if (!alreadyOpen)
+ wxTheClipboard->Close();
+ return (bool) success;
+#endif
+ return TRUE ;
+}
+
+void wxMetafile::SetHMETAFILE(WXHMETAFILE mf)
+{
+ if (!m_refData)
+ m_refData = new wxMetafileRefData;
+ if ( M_METAFILEDATA->m_metafile )
+ KillPicture( (PicHandle) M_METAFILEDATA->m_metafile ) ;
+
+ M_METAFILEDATA->m_metafile = mf;
+}
+
+bool wxMetaFile::Play(wxDC *dc)
+{
+ if (!m_refData)
+ return FALSE;
+
+ if (!dc->Ok() )
+ return FALSE;
+
+ {
+ wxMacPortSetter helper( dc ) ;
+ PicHandle pict = (PicHandle) GetHMETAFILE() ;
+ DrawPicture( pict , &(**pict).picFrame ) ;
+ }
+ return TRUE;
+}
+
+wxSize wxMetaFile::GetSize() const
+{
+ wxSize size = wxDefaultSize ;
+ if ( Ok() )
+ {
+ PicHandle pict = (PicHandle) GetHMETAFILE() ;
+ Rect &r = (**pict).picFrame ;
+ size.x = r.right - r.left ;
+ size.y = r.bottom - r.top ;
+ }
+
+ return size;
+}
+
+/*
+ * Metafile device context
+ *
+ */
+
+// New constructor that takes origin and extent. If you use this, don't
+// give origin/extent arguments to wxMakeMetaFilePlaceable.
+
+wxMetaFileDC::wxMetaFileDC(const wxString& filename ,
+ int width , int height ,
+ const wxString& WXUNUSED(description) )
+{
+ wxASSERT_MSG( width == 0 || height == 0 , _T("no arbitration of metafilesize supported") ) ;
+ wxASSERT_MSG( filename.IsEmpty() , _T("no file based metafile support yet")) ;
+
+ m_metaFile = new wxMetaFile(filename) ;
+ Rect r={0,0,height,width} ;
+
+ RectRgn( (RgnHandle) m_macBoundaryClipRgn , &r ) ;
+ CopyRgn( (RgnHandle) m_macBoundaryClipRgn , (RgnHandle) m_macCurrentClipRgn ) ;
+
+ m_metaFile->SetHMETAFILE( OpenPicture( &r ) ) ;
+ ::GetPort( (GrafPtr*) &m_macPort ) ;
+ m_ok = TRUE ;
+
+ SetMapMode(wxMM_TEXT);
+}
+
+wxMetaFileDC::~wxMetaFileDC()
+{
+}
+
+void wxMetaFileDC::DoGetSize(int *width, int *height) const
+{
+ wxCHECK_RET( m_metaFile , _T("GetSize() doesn't work without a metafile") );
+
+ wxSize sz = m_metaFile->GetSize() ;
+ if (width) (*width) = sz.x;
+ if (height) (*height) = sz.y;
+}
+
+wxMetaFile *wxMetaFileDC::Close()
+{
+ ClosePicture() ;
+ return m_metaFile;
+}
+
+#if wxUSE_DATAOBJ
+size_t wxMetafileDataObject::GetDataSize() const
+{
+ return GetHandleSize( (Handle) (*((wxMetafile*)&m_metafile)).GetHMETAFILE() ) ;
+}
+
+bool wxMetafileDataObject::GetDataHere(void *buf) const
+{
+ memcpy( buf , (*(PicHandle)(*((wxMetafile*)&m_metafile)).GetHMETAFILE()) ,
+ GetHandleSize( (Handle) (*((wxMetafile*)&m_metafile)).GetHMETAFILE() ) ) ;
+ return true ;
+}
+
+bool wxMetafileDataObject::SetData(size_t len, const void *buf)
+{
+ Handle handle = NewHandle( len ) ;
+ SetHandleSize( handle , len ) ;
+ memcpy( *handle , buf , len ) ;
+ m_metafile.SetHMETAFILE( handle ) ;
+ return true ;
+}
+#endif
+
+#endif
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: mac/mimetype.cpp
+// Purpose: classes and functions to manage MIME types
+// Author: Vadim Zeitlin
+// Modified by:
+// Created: 23.09.98
+// RCS-ID: $Id$
+// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
+// Licence: wxWindows licence (part of wxExtra library)
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "mimetype.h"
+#endif
+
+// for compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+ #include "wx/defs.h"
+#endif
+
+#ifndef WX_PRECOMP
+ #include "wx/string.h"
+ #if wxUSE_GUI
+ #include "wx/icon.h"
+ #endif
+#endif //WX_PRECOMP
+
+
+#include "wx/log.h"
+#include "wx/file.h"
+#include "wx/intl.h"
+#include "wx/dynarray.h"
+#include "wx/confbase.h"
+
+#include "wx/mac/mimetype.h"
+
+// other standard headers
+#include <ctype.h>
+
+// in case we're compiling in non-GUI mode
+class WXDLLEXPORT wxIcon;
+
+bool wxFileTypeImpl::SetCommand(const wxString& cmd, const wxString& verb, bool overwriteprompt)
+{
+ return FALSE;
+}
+
+bool wxFileTypeImpl::SetDefaultIcon(const wxString& strIcon, int index)
+{
+ return FALSE;
+}
+
+bool wxFileTypeImpl::GetCommand(wxString *command, const char *verb) const
+{
+ return FALSE;
+}
+
+// @@ this function is half implemented
+bool wxFileTypeImpl::GetExtensions(wxArrayString& extensions)
+{
+ return FALSE;
+}
+
+bool wxFileTypeImpl::GetMimeType(wxString *mimeType) const
+{
+ if ( m_strFileType.Length() > 0 )
+ {
+ *mimeType = m_strFileType ;
+ return TRUE ;
+ }
+ else
+ return FALSE;
+}
+
+bool wxFileTypeImpl::GetMimeTypes(wxArrayString& mimeTypes) const
+{
+ wxString s;
+
+ if (GetMimeType(&s))
+ {
+ mimeTypes.Clear();
+ mimeTypes.Add(s);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+bool wxFileTypeImpl::GetIcon(wxIconLocation *WXUNUSED(icon)) const
+{
+ // no such file type or no value or incorrect icon entry
+ return FALSE;
+}
+
+bool wxFileTypeImpl::GetDescription(wxString *desc) const
+{
+ return FALSE;
+}
+
+size_t
+wxFileTypeImpl::GetAllCommands(wxArrayString * verbs, wxArrayString * commands,
+ const wxFileType::MessageParameters& params) const
+{
+ wxFAIL_MSG( _T("wxFileTypeImpl::GetAllCommands() not yet implemented") );
+ return 0;
+}
+
+void
+wxMimeTypesManagerImpl::Initialize(int mailcapStyles, const wxString& extraDir)
+{
+ wxFAIL_MSG( _T("wxMimeTypesManagerImpl::Initialize() not yet implemented") );
+}
+
+void
+wxMimeTypesManagerImpl::ClearData()
+{
+ wxFAIL_MSG( _T("wxMimeTypesManagerImpl::ClearData() not yet implemented") );
+}
+
+// extension -> file type
+wxFileType *
+wxMimeTypesManagerImpl::GetFileTypeFromExtension(const wxString& e)
+{
+ wxString ext = e ;
+ ext = ext.Lower() ;
+ if ( ext == wxT("txt") )
+ {
+ wxFileType *fileType = new wxFileType;
+ fileType->m_impl->SetFileType(wxT("text/text"));
+ fileType->m_impl->SetExt(ext);
+ return fileType;
+ }
+ else if ( ext == wxT("htm") || ext == wxT("html") )
+ {
+ wxFileType *fileType = new wxFileType;
+ fileType->m_impl->SetFileType(wxT("text/html"));
+ fileType->m_impl->SetExt(ext);
+ return fileType;
+ }
+ else if ( ext == wxT("gif") )
+ {
+ wxFileType *fileType = new wxFileType;
+ fileType->m_impl->SetFileType(wxT("image/gif"));
+ fileType->m_impl->SetExt(ext);
+ return fileType;
+ }
+ else if ( ext == wxT("png" ))
+ {
+ wxFileType *fileType = new wxFileType;
+ fileType->m_impl->SetFileType(wxT("image/png"));
+ fileType->m_impl->SetExt(ext);
+ return fileType;
+ }
+ else if ( ext == wxT("jpg" )|| ext == wxT("jpeg") )
+ {
+ wxFileType *fileType = new wxFileType;
+ fileType->m_impl->SetFileType(wxT("image/jpeg"));
+ fileType->m_impl->SetExt(ext);
+ return fileType;
+ }
+ else if ( ext == wxT("bmp") )
+ {
+ wxFileType *fileType = new wxFileType;
+ fileType->m_impl->SetFileType(wxT("image/bmp"));
+ fileType->m_impl->SetExt(ext);
+ return fileType;
+ }
+ else if ( ext == wxT("tif") || ext == wxT("tiff") )
+ {
+ wxFileType *fileType = new wxFileType;
+ fileType->m_impl->SetFileType(wxT("image/tiff"));
+ fileType->m_impl->SetExt(ext);
+ return fileType;
+ }
+ else if ( ext == wxT("xpm") )
+ {
+ wxFileType *fileType = new wxFileType;
+ fileType->m_impl->SetFileType(wxT("image/xpm"));
+ fileType->m_impl->SetExt(ext);
+ return fileType;
+ }
+ else if ( ext == wxT("xbm") )
+ {
+ wxFileType *fileType = new wxFileType;
+ fileType->m_impl->SetFileType(wxT("image/xbm"));
+ fileType->m_impl->SetExt(ext);
+ return fileType;
+ }
+
+ // unknown extension
+ return NULL;
+}
+
+// MIME type -> extension -> file type
+wxFileType *
+wxMimeTypesManagerImpl::GetFileTypeFromMimeType(const wxString& mimeType)
+{
+ return NULL;
+}
+
+size_t wxMimeTypesManagerImpl::EnumAllFileTypes(wxArrayString& mimetypes)
+{
+ // VZ: don't know anything about this for Mac
+ wxFAIL_MSG( _T("wxMimeTypesManagerImpl::EnumAllFileTypes() not yet implemented") );
+
+ return 0;
+}
+
+wxFileType *
+wxMimeTypesManagerImpl::Associate(const wxFileTypeInfo& ftInfo)
+{
+ wxFAIL_MSG( _T("wxMimeTypesManagerImpl::Associate() not yet implemented") );
+
+ return NULL;
+}
+
+bool
+wxMimeTypesManagerImpl::Unassociate(wxFileType *ft)
+{
+ return FALSE;
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: minifram.cpp
+// Purpose: wxMiniFrame. Optional; identical to wxFrame if not supported.
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "minifram.h"
+#endif
+
+#include "wx/minifram.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxMiniFrame, wxFrame)
+#endif
+
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: msgdlg.cpp
+// Purpose: wxMessageDialog
+// Author: Stefan Csomor
+// Modified by:
+// Created: 04/01/98
+// RCS-ID: $$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "msgdlg.h"
+#endif
+
+#include "wx/app.h"
+#include "wx/msgdlg.h"
+#include "wx/intl.h"
+#include "wx/mac/uma.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_CLASS(wxMessageDialog, wxDialog)
+#endif
+
+wxMessageDialog::wxMessageDialog(wxWindow *parent, const wxString& message, const wxString& caption,
+ long style, const wxPoint& pos)
+{
+ m_caption = caption;
+ m_message = message;
+ m_dialogStyle = style;
+ m_parent = parent;
+}
+
+int wxMessageDialog::ShowModal()
+{
+ int resultbutton = wxID_CANCEL ;
+
+ short result ;
+
+ wxASSERT_MSG( ( m_dialogStyle & 0x3F ) != wxYES , wxT("this style is not supported on mac") ) ;
+
+ AlertType alertType = kAlertPlainAlert ;
+ if (m_dialogStyle & wxICON_EXCLAMATION)
+ alertType = kAlertNoteAlert ;
+ else if (m_dialogStyle & wxICON_HAND)
+ alertType = kAlertStopAlert ;
+ else if (m_dialogStyle & wxICON_INFORMATION)
+ alertType = kAlertNoteAlert ;
+ else if (m_dialogStyle & wxICON_QUESTION)
+ alertType = kAlertCautionAlert ;
+
+#if TARGET_CARBON
+ if ( UMAGetSystemVersion() >= 0x1000 )
+ {
+ AlertStdCFStringAlertParamRec param ;
+ wxMacCFStringHolder cfNoString(_("No") , m_font.GetEncoding()) ;
+ wxMacCFStringHolder cfYesString( _("Yes") , m_font.GetEncoding()) ;
+
+ wxMacCFStringHolder cfTitle(m_caption , m_font.GetEncoding());
+ wxMacCFStringHolder cfText(m_message , m_font.GetEncoding());
+
+ param.movable = true;
+ param.flags = 0 ;
+
+ bool skipDialog = false ;
+
+ if (m_dialogStyle & wxYES_NO)
+ {
+ if (m_dialogStyle & wxCANCEL)
+ {
+ param.defaultText = cfYesString ;
+ param.cancelText = (CFStringRef) kAlertDefaultCancelText;
+ param.otherText = cfNoString ;
+ param.helpButton = false ;
+ param.defaultButton = kAlertStdAlertOKButton;
+ param.cancelButton = kAlertStdAlertCancelButton;
+ }
+ else
+ {
+ param.defaultText = cfYesString ;
+ param.cancelText = NULL;
+ param.otherText = cfNoString ;
+ param.helpButton = false ;
+ param.defaultButton = kAlertStdAlertOKButton;
+ param.cancelButton = 0;
+ }
+ }
+ // the msw implementation even shows an ok button if it is not specified, we'll do the same
+ else
+ {
+ if (m_dialogStyle & wxCANCEL)
+ {
+ // thats a cancel missing
+ param.defaultText = (CFStringRef) kAlertDefaultOKText ;
+ param.cancelText = (CFStringRef) kAlertDefaultCancelText ;
+ param.otherText = NULL;
+ param.helpButton = false ;
+ param.defaultButton = kAlertStdAlertOKButton;
+ param.cancelButton = 0;
+ }
+ else
+ {
+ param.defaultText = (CFStringRef) kAlertDefaultOKText ;
+ param.cancelText = NULL;
+ param.otherText = NULL;
+ param.helpButton = false ;
+ param.defaultButton = kAlertStdAlertOKButton;
+ param.cancelButton = 0;
+ }
+ }
+ /*
+ else
+ {
+ skipDialog = true ;
+ }
+ */
+
+ param.position = kWindowDefaultPosition;
+ if ( !skipDialog )
+ {
+ DialogRef alertRef ;
+ CreateStandardAlert( alertType , cfTitle , cfText , ¶m , &alertRef ) ;
+ RunStandardAlert( alertRef , NULL , &result ) ;
+ }
+ if ( skipDialog )
+ return wxID_CANCEL ;
+ }
+ else
+#endif
+ {
+ AlertStdAlertParamRec param;
+
+ Str255 yesPString ;
+ Str255 noPString ;
+
+ Str255 pascalTitle ;
+ Str255 pascalText ;
+ wxMacStringToPascal( m_caption , pascalTitle ) ;
+ wxMacStringToPascal( _("Yes") , yesPString ) ;
+ wxMacStringToPascal( _("No") , noPString ) ;
+ wxMacStringToPascal( m_message , pascalText ) ;
+
+ param.movable = true;
+ param.filterProc = NULL ;
+ if (m_dialogStyle & wxYES_NO)
+ {
+ if (m_dialogStyle & wxCANCEL)
+ {
+ param.defaultText = yesPString ;
+ param.cancelText = (StringPtr) kAlertDefaultCancelText;
+ param.otherText = noPString ;
+ param.helpButton = false ;
+ param.defaultButton = kAlertStdAlertOKButton;
+ param.cancelButton = kAlertStdAlertCancelButton;
+ }
+ else
+ {
+ param.defaultText = yesPString ;
+ param.cancelText = NULL;
+ param.otherText = noPString ;
+ param.helpButton = false ;
+ param.defaultButton = kAlertStdAlertOKButton;
+ param.cancelButton = 0;
+ }
+ }
+ else if (m_dialogStyle & wxOK)
+ {
+ if (m_dialogStyle & wxCANCEL)
+ {
+ param.defaultText = (StringPtr) kAlertDefaultOKText ;
+ param.cancelText = (StringPtr) kAlertDefaultCancelText ;
+ param.otherText = NULL;
+ param.helpButton = false ;
+ param.defaultButton = kAlertStdAlertOKButton;
+ param.cancelButton = 0;
+ }
+ else
+ {
+ param.defaultText = (StringPtr) kAlertDefaultOKText ;
+ param.cancelText = NULL;
+ param.otherText = NULL;
+ param.helpButton = false ;
+ param.defaultButton = kAlertStdAlertOKButton;
+ param.cancelButton = 0;
+ }
+ }
+ else
+ {
+ return resultbutton ;
+ }
+
+ param.position = 0;
+
+ StandardAlert( alertType, pascalTitle, pascalText, ¶m, &result );
+ }
+
+ if (m_dialogStyle & wxOK)
+ {
+ if (m_dialogStyle & wxCANCEL)
+ {
+ //TODO add Cancelbutton
+ switch( result )
+ {
+ case 1 :
+ resultbutton = wxID_OK ;
+ break ;
+ case 2 :
+ break ;
+ case 3 :
+ break ;
+ }
+ }
+ else
+ {
+ switch( result )
+ {
+ case 1 :
+ resultbutton = wxID_OK ;
+ break ;
+ case 2 :
+ break ;
+ case 3 :
+ break ;
+ }
+ }
+ }
+ else if (m_dialogStyle & wxYES_NO)
+ {
+ if (m_dialogStyle & wxCANCEL)
+ {
+ switch( result )
+ {
+ case 1 :
+ resultbutton = wxID_YES ;
+ break ;
+ case 2 :
+ resultbutton = wxID_CANCEL ;
+ break ;
+ case 3 :
+ resultbutton = wxID_NO ;
+ break ;
+ }
+ }
+ else
+ {
+ switch( result )
+ {
+ case 1 :
+ resultbutton = wxID_YES ;
+ break ;
+ case 2 :
+ break ;
+ case 3 :
+ resultbutton = wxID_NO ;
+ break ;
+ }
+ }
+ }
+
+ return resultbutton ;
+}
+
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Name: notebook.cpp
+// Purpose: implementation of wxNotebook
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "notebook.h"
+#endif
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+#include "wx/app.h"
+#include "wx/string.h"
+#include "wx/log.h"
+#include "wx/imaglist.h"
+#include "wx/image.h"
+#include "wx/notebook.h"
+#include "wx/mac/uma.h"
+// ----------------------------------------------------------------------------
+// macros
+// ----------------------------------------------------------------------------
+
+// check that the page index is valid
+#define IS_VALID_PAGE(nPage) ((nPage) < GetPageCount())
+
+
+// ----------------------------------------------------------------------------
+// event table
+// ----------------------------------------------------------------------------
+
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING)
+
+BEGIN_EVENT_TABLE(wxNotebook, wxControl)
+ EVT_NOTEBOOK_PAGE_CHANGED(-1, wxNotebook::OnSelChange)
+ EVT_MOUSE_EVENTS(wxNotebook::OnMouse)
+
+ EVT_SIZE(wxNotebook::OnSize)
+ EVT_SET_FOCUS(wxNotebook::OnSetFocus)
+ EVT_NAVIGATION_KEY(wxNotebook::OnNavigationKey)
+END_EVENT_TABLE()
+
+IMPLEMENT_DYNAMIC_CLASS(wxNotebook, wxControl)
+IMPLEMENT_DYNAMIC_CLASS(wxNotebookEvent, wxCommandEvent)
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// The Appearance Manager docs show using tab controls in either edge to edge
+// mode, or inset. I think edge to edge conforms better to the other ports,
+// and inset mode is better accomplished with space around the wxNotebook rather
+// than within it. --Robin
+
+// CS : had to switch off tight spacing due to 10.3 problems
+#define wxMAC_EDGE_TO_EDGE 0
+
+static inline int wxMacTabMargin(long nbStyle, long side)
+{
+ static int tabMargin = -1;
+ static int otherMargin = -1;
+
+ if ( tabMargin == -1)
+ {
+ if ( UMAHasAquaLayout() )
+ {
+ tabMargin = 26; // From Appearance Manager docs for small tab control dimensions
+#if wxMAC_EDGE_TO_EDGE
+ otherMargin = 0;
+#else
+// otherMargin = 20;
+ // JACS - this seems fine on 10.3; 20 is way too much
+ otherMargin = 8;
+#endif
+ }
+ else
+ {
+ tabMargin = 30;
+#if wxMAC_EDGE_TO_EDGE
+ otherMargin = 0;
+#else
+ otherMargin = 16;
+#endif
+ }
+ }
+
+ // If the style matches the side asked for then return the tab margin,
+ // but we have to special case wxNB_TOP since it is zero...
+ if ( side == wxNB_TOP)
+ {
+ if ( nbStyle != 0 && nbStyle & (wxNB_LEFT|wxNB_RIGHT|wxNB_BOTTOM))
+ {
+ return otherMargin;
+ }
+ else
+ {
+ return tabMargin;
+ }
+ }
+ else if ( nbStyle & side)
+ return tabMargin;
+ else
+ return otherMargin;
+}
+
+static inline int wxMacTabLeftMargin(long style)
+{
+ return wxMacTabMargin(style, wxNB_LEFT);
+}
+
+static inline int wxMacTabTopMargin(long style)
+{
+ return wxMacTabMargin(style, wxNB_TOP);
+}
+
+static inline int wxMacTabRightMargin(long style)
+{
+ return wxMacTabMargin(style, wxNB_RIGHT);
+}
+
+static inline int wxMacTabBottomMargin(long style)
+{
+ return wxMacTabMargin(style, wxNB_BOTTOM);
+}
+
+// ----------------------------------------------------------------------------
+// wxNotebook construction
+// ----------------------------------------------------------------------------
+
+// common part of all ctors
+void wxNotebook::Init()
+{
+ if ( UMAHasAquaLayout() )
+ {
+ // Should these depend on wxMAC_EDGE_TO_EDGE too?
+ m_macHorizontalBorder = 7;
+ m_macVerticalBorder = 8;
+ }
+
+ m_nSelection = -1;
+}
+
+// default for dynamic class
+wxNotebook::wxNotebook()
+{
+ Init();
+}
+
+// the same arguments as for wxControl
+wxNotebook::wxNotebook(wxWindow *parent,
+ wxWindowID id,
+ const wxPoint& pos,
+ const wxSize& size,
+ long style,
+ const wxString& name)
+{
+ Init();
+
+ Create(parent, id, pos, size, style, name);
+}
+
+// Create() function
+bool wxNotebook::Create(wxWindow *parent,
+ wxWindowID id,
+ const wxPoint& pos,
+ const wxSize& size,
+ long style,
+ const wxString& name)
+{
+ if ( !wxNotebookBase::Create(parent, id, pos, size, style, name) )
+ return false;
+
+ Rect bounds ;
+ Str255 title ;
+
+ MacPreControlCreate( parent , id , wxEmptyString , pos , size ,style, wxDefaultValidator , name , &bounds , title ) ;
+
+ int tabstyle = kControlTabSmallNorthProc ;
+ if ( HasFlag(wxNB_LEFT) )
+ tabstyle = kControlTabSmallWestProc ;
+ else if ( HasFlag( wxNB_RIGHT ) )
+ tabstyle = kControlTabSmallEastProc ;
+ else if ( HasFlag( wxNB_BOTTOM ) )
+ tabstyle = kControlTabSmallSouthProc ;
+
+
+ m_macControl = ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , title , false , 0 , 0 , 1,
+ tabstyle , (long) this ) ;
+
+ MacPostControlCreate() ;
+ return TRUE ;
+}
+
+// dtor
+wxNotebook::~wxNotebook()
+{
+}
+
+// ----------------------------------------------------------------------------
+// wxNotebook accessors
+// ----------------------------------------------------------------------------
+
+void wxNotebook::SetPadding(const wxSize& padding)
+{
+ // unsupported by OS
+}
+
+void wxNotebook::SetTabSize(const wxSize& sz)
+{
+ // unsupported by OS
+}
+
+void wxNotebook::SetPageSize(const wxSize& size)
+{
+ SetSize( CalcSizeFromPage( size ) );
+}
+
+wxSize wxNotebook::CalcSizeFromPage(const wxSize& sizePage) const
+{
+ wxSize sizeTotal = sizePage;
+ sizeTotal.x += 2 * m_macHorizontalBorder + wxMacTabLeftMargin(GetWindowStyle()) +
+ wxMacTabRightMargin(GetWindowStyle()) ;
+ sizeTotal.y += 2 * m_macVerticalBorder + wxMacTabTopMargin(GetWindowStyle()) +
+ wxMacTabBottomMargin(GetWindowStyle()) ;
+
+ return sizeTotal;
+}
+
+wxSize wxNotebook::DoGetBestSize() const
+{
+ // calculate the max page size
+ wxSize size(0, 0);
+
+ size_t count = GetPageCount();
+ if ( count )
+ {
+ for ( size_t n = 0; n < count; n++ )
+ {
+ wxSize sizePage = m_pages[n]->GetSize();
+
+ if ( size.x < sizePage.x )
+ size.x = sizePage.x;
+ if ( size.y < sizePage.y )
+ size.y = sizePage.y;
+ }
+ }
+ else // no pages
+ {
+ // use some arbitrary default size
+ size.x =
+ size.y = 100;
+ }
+
+ return CalcSizeFromPage(size);
+}
+
+int wxNotebook::SetSelection(size_t nPage)
+{
+ wxCHECK_MSG( IS_VALID_PAGE(nPage), -1, wxT("notebook page out of range") );
+
+ if ( int(nPage) != m_nSelection )
+ {
+ wxNotebookEvent event(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, m_windowId);
+ event.SetSelection(nPage);
+ event.SetOldSelection(m_nSelection);
+ event.SetEventObject(this);
+ if ( !GetEventHandler()->ProcessEvent(event) || event.IsAllowed() )
+ {
+ // program allows the page change
+ event.SetEventType(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED);
+ (void)GetEventHandler()->ProcessEvent(event);
+
+ ChangePage(m_nSelection, nPage);
+ }
+ }
+
+ return m_nSelection;
+}
+
+bool wxNotebook::SetPageText(size_t nPage, const wxString& strText)
+{
+ wxASSERT( IS_VALID_PAGE(nPage) );
+
+ wxNotebookPage *page = m_pages[nPage];
+ page->SetLabel(strText);
+ MacSetupTabs();
+
+ return true;
+}
+
+wxString wxNotebook::GetPageText(size_t nPage) const
+{
+ wxASSERT( IS_VALID_PAGE(nPage) );
+
+ wxNotebookPage *page = m_pages[nPage];
+ return page->GetLabel();
+}
+
+int wxNotebook::GetPageImage(size_t nPage) const
+{
+ wxCHECK_MSG( IS_VALID_PAGE(nPage), -1, _T("invalid notebook page") );
+
+ return m_images[nPage];
+}
+
+bool wxNotebook::SetPageImage(size_t nPage, int nImage)
+{
+ wxCHECK_MSG( IS_VALID_PAGE(nPage), FALSE, _T("invalid notebook page") );
+
+ wxCHECK_MSG( m_imageList && nImage < m_imageList->GetImageCount(), FALSE,
+ _T("invalid image index in SetPageImage()") );
+
+ if ( nImage != m_images[nPage] )
+ {
+ // if the item didn't have an icon before or, on the contrary, did have
+ // it but has lost it now, its size will change - but if the icon just
+ // changes, it won't
+ m_images[nPage] = nImage;
+
+ MacSetupTabs() ;
+ }
+
+ return TRUE;
+}
+
+// ----------------------------------------------------------------------------
+// wxNotebook operations
+// ----------------------------------------------------------------------------
+
+// remove one page from the notebook, without deleting the window
+wxNotebookPage* wxNotebook::DoRemovePage(size_t nPage)
+{
+ wxCHECK( IS_VALID_PAGE(nPage), NULL );
+ wxNotebookPage* page = m_pages[nPage] ;
+ m_pages.RemoveAt(nPage);
+
+ MacSetupTabs();
+
+ if(m_nSelection >= (int)GetPageCount()) {
+ m_nSelection = GetPageCount() - 1;
+ }
+ if(m_nSelection >= 0) {
+ m_pages[m_nSelection]->Show(true);
+ }
+ return page;
+}
+
+// remove all pages
+bool wxNotebook::DeleteAllPages()
+{
+ WX_CLEAR_ARRAY(m_pages) ;
+ MacSetupTabs();
+ m_nSelection = -1 ;
+ return TRUE;
+}
+
+
+// same as AddPage() but does it at given position
+bool wxNotebook::InsertPage(size_t nPage,
+ wxNotebookPage *pPage,
+ const wxString& strText,
+ bool bSelect,
+ int imageId)
+{
+ if ( !wxNotebookBase::InsertPage(nPage, pPage, strText, bSelect, imageId) )
+ return false;
+
+ wxASSERT_MSG( pPage->GetParent() == this,
+ _T("notebook pages must have notebook as parent") );
+
+ // don't show pages by default (we'll need to adjust their size first)
+ pPage->Show( false ) ;
+
+ pPage->SetLabel(strText);
+
+ m_images.Insert(imageId, nPage);
+
+ MacSetupTabs();
+
+ wxRect rect = GetPageRect() ;
+ pPage->SetSize(rect);
+ if ( pPage->GetAutoLayout() ) {
+ pPage->Layout();
+ }
+
+
+ // now deal with the selection
+ // ---------------------------
+
+ // if the inserted page is before the selected one, we must update the
+ // index of the selected page
+
+ if ( int(nPage) <= m_nSelection )
+ {
+ m_nSelection++;
+ // while this still is the same page showing, we need to update the tabs
+ SetControl32BitValue( (ControlHandle) m_macControl , m_nSelection + 1 ) ;
+ }
+
+ // some page should be selected: either this one or the first one if there
+ // is still no selection
+ int selNew = -1;
+ if ( bSelect )
+ selNew = nPage;
+ else if ( m_nSelection == -1 )
+ selNew = 0;
+
+ if ( selNew != -1 )
+ SetSelection(selNew);
+
+ return true;
+}
+
+/* Added by Mark Newsam
+* When a page is added or deleted to the notebook this function updates
+* information held in the m_macControl so that it matches the order
+* the user would expect.
+*/
+void wxNotebook::MacSetupTabs()
+{
+ SetControl32BitMaximum( (ControlHandle) m_macControl , GetPageCount() ) ;
+
+ wxNotebookPage *page;
+ ControlTabInfoRec info;
+
+ const size_t countPages = GetPageCount();
+ for(size_t ii = 0; ii < countPages; ii++)
+ {
+ page = m_pages[ii];
+ info.version = 0;
+ info.iconSuiteID = 0;
+ wxMacStringToPascal( page->GetLabel() , info.name ) ;
+
+ SetControlData( (ControlHandle) m_macControl, ii+1, kControlTabInfoTag,
+ sizeof( ControlTabInfoRec) , (char*) &info ) ;
+ SetTabEnabled( (ControlHandle) m_macControl , ii+1 , true ) ;
+#if TARGET_CARBON
+ if ( GetImageList() && GetPageImage(ii) >= 0 && UMAGetSystemVersion() >= 0x1020 )
+ {
+ // tab controls only support very specific types of images, therefore we are doing an odyssee
+ // accross the icon worlds (even Apple DTS did not find a shorter path)
+ // in order not to pollute the icon registry we put every icon into (OSType) 1 and immediately
+ // afterwards Unregister it (IconRef is ref counted, so it will stay on the tab even if we
+ // unregister it) in case this will ever lead to having the same icon everywhere add some kind
+ // of static counter
+ const wxBitmap* bmap = GetImageList()->GetBitmap( GetPageImage(ii ) ) ;
+ if ( bmap )
+ {
+ wxBitmap scaledBitmap ;
+ if ( bmap->GetWidth() != 16 || bmap->GetHeight() != 16 )
+ {
+ scaledBitmap = wxBitmap( bmap->ConvertToImage().Scale(16,16) ) ;
+ bmap = &scaledBitmap ;
+ }
+ ControlButtonContentInfo info ;
+ wxMacCreateBitmapButton( &info , *bmap , kControlContentPictHandle) ;
+ IconFamilyHandle iconFamily = (IconFamilyHandle) NewHandle(0) ;
+ OSErr err = SetIconFamilyData( iconFamily, 'PICT' , (Handle) info.u.picture ) ;
+ wxASSERT_MSG( err == noErr , wxT("Error when adding bitmap") ) ;
+ IconRef iconRef ;
+ err = RegisterIconRefFromIconFamily( 'WXNG' , (OSType) 1, iconFamily, &iconRef ) ;
+ wxASSERT_MSG( err == noErr , wxT("Error when adding bitmap") ) ;
+ info.contentType = kControlContentIconRef ;
+ info.u.iconRef = iconRef ;
+ SetControlData( (ControlHandle) m_macControl, ii+1,kControlTabImageContentTag,
+ sizeof( info ), (Ptr)&info );
+ wxASSERT_MSG( err == noErr , wxT("Error when setting icon on tab") ) ;
+ if ( UMAGetSystemVersion() < 0x1030 )
+ {
+ UnregisterIconRef( 'WXNG' , (OSType) 1 ) ;
+ }
+
+ ReleaseIconRef( iconRef ) ;
+ DisposeHandle( (Handle) iconFamily ) ;
+ }
+ }
+#endif
+ }
+ Rect bounds;
+ GetControlBounds((ControlHandle)m_macControl, &bounds);
+ InvalWindowRect((WindowRef)MacGetRootWindow(), &bounds);
+}
+
+wxRect wxNotebook::GetPageRect() const
+{
+ // fit the notebook page to the tab control's display area
+ int w, h;
+ GetSize(&w, &h);
+
+ return wxRect(
+ wxMacTabLeftMargin(GetWindowStyle()) + m_macHorizontalBorder,
+ wxMacTabTopMargin(GetWindowStyle()) + m_macVerticalBorder,
+ w - wxMacTabLeftMargin(GetWindowStyle()) - wxMacTabRightMargin(GetWindowStyle()) - 2*m_macHorizontalBorder,
+ h - wxMacTabTopMargin(GetWindowStyle()) - wxMacTabBottomMargin(GetWindowStyle()) - 2*m_macVerticalBorder);
+}
+// ----------------------------------------------------------------------------
+// wxNotebook callbacks
+// ----------------------------------------------------------------------------
+
+// @@@ OnSize() is used for setting the font when it's called for the first
+// time because doing it in ::Create() doesn't work (for unknown reasons)
+void wxNotebook::OnSize(wxSizeEvent& event)
+{
+
+ unsigned int nCount = m_pages.Count();
+ wxRect rect = GetPageRect() ;
+ for ( unsigned int nPage = 0; nPage < nCount; nPage++ ) {
+ wxNotebookPage *pPage = m_pages[nPage];
+ pPage->SetSize(rect);
+ if ( pPage->GetAutoLayout() ) {
+ pPage->Layout();
+ }
+ }
+
+ // Processing continues to next OnSize
+ event.Skip();
+}
+
+void wxNotebook::OnSelChange(wxNotebookEvent& event)
+{
+ // is it our tab control?
+ if ( event.GetEventObject() == this )
+ ChangePage(event.GetOldSelection(), event.GetSelection());
+
+ // we want to give others a chance to process this message as well
+ event.Skip();
+}
+
+void wxNotebook::OnSetFocus(wxFocusEvent& event)
+{
+ // set focus to the currently selected page if any
+ if ( m_nSelection != -1 )
+ m_pages[m_nSelection]->SetFocus();
+
+ event.Skip();
+}
+
+void wxNotebook::OnNavigationKey(wxNavigationKeyEvent& event)
+{
+ if ( event.IsWindowChange() ) {
+ // change pages
+ AdvanceSelection(event.GetDirection());
+ }
+ else {
+ // we get this event in 2 cases
+ //
+ // a) one of our pages might have generated it because the user TABbed
+ // out from it in which case we should propagate the event upwards and
+ // our parent will take care of setting the focus to prev/next sibling
+ //
+ // or
+ //
+ // b) the parent panel wants to give the focus to us so that we
+ // forward it to our selected page. We can't deal with this in
+ // OnSetFocus() because we don't know which direction the focus came
+ // from in this case and so can't choose between setting the focus to
+ // first or last panel child
+ wxWindow *parent = GetParent();
+ // the cast is here to fic a GCC ICE
+ if ( ((wxWindow*)event.GetEventObject()) == parent )
+ {
+ // no, it doesn't come from child, case (b): forward to a page
+ if ( m_nSelection != -1 )
+ {
+ // so that the page knows that the event comes from it's parent
+ // and is being propagated downwards
+ event.SetEventObject(this);
+
+ wxWindow *page = m_pages[m_nSelection];
+ if ( !page->GetEventHandler()->ProcessEvent(event) )
+ {
+ page->SetFocus();
+ }
+ //else: page manages focus inside it itself
+ }
+ else
+ {
+ // we have no pages - still have to give focus to _something_
+ SetFocus();
+ }
+ }
+ else
+ {
+ // it comes from our child, case (a), pass to the parent
+ if ( parent ) {
+ event.SetCurrentFocus(this);
+ parent->GetEventHandler()->ProcessEvent(event);
+ }
+ }
+ }
+}
+
+// ----------------------------------------------------------------------------
+// wxNotebook base class virtuals
+// ----------------------------------------------------------------------------
+
+#if wxUSE_CONSTRAINTS
+
+// override these 2 functions to do nothing: everything is done in OnSize
+
+void wxNotebook::SetConstraintSizes(bool WXUNUSED(recurse))
+{
+ // don't set the sizes of the pages - their correct size is not yet known
+ wxControl::SetConstraintSizes(FALSE);
+}
+
+bool wxNotebook::DoPhase(int WXUNUSED(nPhase))
+{
+ return TRUE;
+}
+
+#endif // wxUSE_CONSTRAINTS
+
+void wxNotebook::Command(wxCommandEvent& event)
+{
+ wxFAIL_MSG(wxT("wxNotebook::Command not implemented"));
+}
+
+// ----------------------------------------------------------------------------
+// wxNotebook helper functions
+// ----------------------------------------------------------------------------
+
+// hide the currently active panel and show the new one
+void wxNotebook::ChangePage(int nOldSel, int nSel)
+{
+ if ( nOldSel != -1 )
+ {
+ m_pages[nOldSel]->Show(FALSE);
+ }
+
+ if ( nSel != -1 )
+ {
+ wxNotebookPage *pPage = m_pages[nSel];
+ pPage->Show(TRUE);
+ pPage->SetFocus();
+ }
+
+ m_nSelection = nSel;
+ SetControl32BitValue( (ControlHandle) m_macControl , m_nSelection + 1 ) ;
+}
+
+
+void wxNotebook::OnMouse( wxMouseEvent &event )
+{
+ if ( (ControlHandle) m_macControl == NULL )
+ {
+ event.Skip() ;
+ return ;
+ }
+
+ if (event.GetEventType() == wxEVT_LEFT_DOWN || event.GetEventType() == wxEVT_LEFT_DCLICK )
+ {
+ int x = event.m_x ;
+ int y = event.m_y ;
+
+ MacClientToRootWindow( &x , &y ) ;
+
+ ControlHandle control ;
+ Point localwhere ;
+ SInt16 controlpart ;
+
+ localwhere.h = x ;
+ localwhere.v = y ;
+
+ short modifiers = 0;
+
+ if ( !event.m_leftDown && !event.m_rightDown )
+ modifiers |= btnState ;
+
+ if ( event.m_shiftDown )
+ modifiers |= shiftKey ;
+
+ if ( event.m_controlDown )
+ modifiers |= controlKey ;
+
+ if ( event.m_altDown )
+ modifiers |= optionKey ;
+
+ if ( event.m_metaDown )
+ modifiers |= cmdKey ;
+
+ control = (ControlHandle) m_macControl ;
+ if ( control && ::IsControlActive( control ) )
+ {
+ {
+ wxNotebookEvent changing(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, m_windowId,
+ ::GetControl32BitValue(control) - 1, m_nSelection);
+ changing.SetEventObject(this);
+ GetEventHandler()->ProcessEvent(changing);
+
+ if(changing.IsAllowed())
+ {
+ controlpart = ::HandleControlClick(control, localwhere, modifiers,
+ (ControlActionUPP) -1);
+ wxTheApp->s_lastMouseDown = 0 ;
+
+ wxNotebookEvent event(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, m_windowId,
+ ::GetControl32BitValue(control) - 1, m_nSelection);
+ event.SetEventObject(this);
+
+ GetEventHandler()->ProcessEvent(event);
+ }
+ }
+ }
+ }
+}
+
+
+void wxNotebook::MacHandleControlClick( WXWidget control , wxInt16 controlpart , bool WXUNUSED( mouseStillDown ) )
+{
+#if 0
+ wxNotebookEvent event(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, m_windowId , ::GetControl32BitValue((ControlHandle)m_macControl) - 1, m_nSelection);
+ event.SetEventObject(this);
+
+ ProcessEvent(event);
+#endif
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: palette.cpp
+// Purpose: wxPalette
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "palette.h"
+#endif
+
+#include "wx/defs.h"
+
+#if wxUSE_PALETTE
+
+#include "wx/palette.h"
+
+#if !USE_SHARED_LIBRARIES
+IMPLEMENT_DYNAMIC_CLASS(wxPalette, wxGDIObject)
+#endif
+
+/*
+ * Palette
+ *
+ */
+
+wxPaletteRefData::wxPaletteRefData()
+{
+ m_palette = NULL ;
+ m_count = 0 ;
+}
+
+wxPaletteRefData::~wxPaletteRefData()
+{
+ if (m_palette != NULL) {
+ delete[] m_palette ;
+ m_palette = NULL;
+ }
+}
+
+wxPalette::wxPalette()
+{
+}
+
+wxPalette::wxPalette(int n, const unsigned char *red, const unsigned char *green, const unsigned char *blue)
+{
+ Create(n, red, green, blue);
+}
+
+wxPalette::~wxPalette()
+{
+}
+
+bool wxPalette::Create(int n, const unsigned char *red, const unsigned char *green, const unsigned char *blue)
+{
+ UnRef();
+
+ m_refData = new wxPaletteRefData;
+
+ M_PALETTEDATA->m_count = n ;
+ M_PALETTEDATA->m_palette = new wxColour[n] ;
+
+ for ( int i = 0 ; i < n ; ++i)
+ {
+ M_PALETTEDATA->m_palette[i].Set( red[i] , green[i] , blue[i] ) ;
+ }
+
+ return FALSE;
+}
+
+int wxPalette::GetPixel(const unsigned char red, const unsigned char green, const unsigned char blue) const
+{
+ if ( !m_refData )
+ return -1;
+
+ long bestdiff = 3 * 256 ;
+ long bestpos = 0 ;
+ long currentdiff ;
+
+ for ( int i = 0 ; i < M_PALETTEDATA->m_count ; ++i )
+ {
+ const wxColour& col = &M_PALETTEDATA->m_palette[i] ;
+ currentdiff = abs ( col.Red() - red ) + abs( col.Green() - green ) + abs ( col.Blue() - blue ) ;
+ if ( currentdiff < bestdiff )
+ {
+ bestdiff = currentdiff ;
+ bestpos = i ;
+ if ( bestdiff == 0 )
+ break ;
+ }
+ }
+
+ return bestpos;
+}
+
+bool wxPalette::GetRGB(int index, unsigned char *red, unsigned char *green, unsigned char *blue) const
+{
+ if ( !m_refData )
+ return FALSE;
+
+ if (index < 0 || index >= M_PALETTEDATA->m_count)
+ return FALSE;
+
+ const wxColour& col = &M_PALETTEDATA->m_palette[index] ;
+ *red = col.Red() ;
+ *green = col.Green() ;
+ *blue = col.Blue() ;
+
+ return TRUE;
+}
+
+#endif
+// wxUSE_PALETTE
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: pen.cpp
+// Purpose: wxPen
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "pen.h"
+#endif
+
+#include "wx/setup.h"
+#include "wx/utils.h"
+#include "wx/pen.h"
+
+#if !USE_SHARED_LIBRARIES
+IMPLEMENT_DYNAMIC_CLASS(wxPen, wxGDIObject)
+#endif
+
+wxPenRefData::wxPenRefData()
+{
+ m_style = wxSOLID;
+ m_width = 1;
+ m_join = wxJOIN_ROUND ;
+ m_cap = wxCAP_ROUND ;
+ m_nbDash = 0 ;
+ m_dash = 0 ;
+}
+
+wxPenRefData::wxPenRefData(const wxPenRefData& data)
+: wxGDIRefData()
+{
+ m_style = data.m_style;
+ m_width = data.m_width;
+ m_join = data.m_join;
+ m_cap = data.m_cap;
+ m_nbDash = data.m_nbDash;
+ m_dash = data.m_dash;
+ m_colour = data.m_colour;
+}
+
+wxPenRefData::~wxPenRefData()
+{
+}
+
+// Pens
+
+wxPen::wxPen()
+{
+}
+
+wxPen::~wxPen()
+{
+}
+
+// Should implement Create
+wxPen::wxPen(const wxColour& col, int Width, int Style)
+{
+ m_refData = new wxPenRefData;
+
+ M_PENDATA->m_colour = col;
+ M_PENDATA->m_width = Width;
+ M_PENDATA->m_style = Style;
+ M_PENDATA->m_join = wxJOIN_ROUND ;
+ M_PENDATA->m_cap = wxCAP_ROUND ;
+ M_PENDATA->m_nbDash = 0 ;
+ M_PENDATA->m_dash = 0 ;
+
+ RealizeResource();
+}
+
+wxPen::wxPen(const wxBitmap& stipple, int Width)
+{
+ m_refData = new wxPenRefData;
+
+ M_PENDATA->m_stipple = stipple;
+ M_PENDATA->m_width = Width;
+ M_PENDATA->m_style = wxSTIPPLE;
+ M_PENDATA->m_join = wxJOIN_ROUND ;
+ M_PENDATA->m_cap = wxCAP_ROUND ;
+ M_PENDATA->m_nbDash = 0 ;
+ M_PENDATA->m_dash = 0 ;
+
+ RealizeResource();
+}
+
+void wxPen::Unshare()
+{
+ // Don't change shared data
+ if (!m_refData)
+ {
+ m_refData = new wxPenRefData();
+ }
+ else
+ {
+ wxPenRefData* ref = new wxPenRefData(*(wxPenRefData*)m_refData);
+ UnRef();
+ m_refData = ref;
+ }
+}
+
+void wxPen::SetColour(const wxColour& col)
+{
+ Unshare();
+
+ M_PENDATA->m_colour = col;
+
+ RealizeResource();
+}
+
+void wxPen::SetColour(unsigned char r, unsigned char g, unsigned char b)
+{
+ Unshare();
+
+ M_PENDATA->m_colour.Set(r, g, b);
+
+ RealizeResource();
+}
+
+void wxPen::SetWidth(int Width)
+{
+ Unshare();
+
+ M_PENDATA->m_width = Width;
+
+ RealizeResource();
+}
+
+void wxPen::SetStyle(int Style)
+{
+ Unshare();
+
+ M_PENDATA->m_style = Style;
+
+ RealizeResource();
+}
+
+void wxPen::SetStipple(const wxBitmap& Stipple)
+{
+ Unshare();
+
+ M_PENDATA->m_stipple = Stipple;
+ M_PENDATA->m_style = wxSTIPPLE;
+
+ RealizeResource();
+}
+
+void wxPen::SetDashes(int nb_dashes, const wxDash *Dash)
+{
+ Unshare();
+
+ M_PENDATA->m_nbDash = nb_dashes;
+ M_PENDATA->m_dash = (wxDash *)Dash;
+
+ RealizeResource();
+}
+
+void wxPen::SetJoin(int Join)
+{
+ Unshare();
+
+ M_PENDATA->m_join = Join;
+
+ RealizeResource();
+}
+
+void wxPen::SetCap(int Cap)
+{
+ Unshare();
+
+ M_PENDATA->m_cap = Cap;
+
+ RealizeResource();
+}
+
+bool wxPen::RealizeResource()
+{
+ // nothing to do here for mac
+ return TRUE;
+}
+
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: pnghand.cpp
+// Purpose: Implements a PNG reader class + handler
+// Author: Julian Smart
+// Modified by:
+// Created: 04/01/98
+// RCS-ID: $Id$
+// Copyright: (c) Julian Smart
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+# pragma implementation "pngread.h"
+# pragma implementation "pnghand.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+# pragma hdrstop
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#if wxUSE_IOSTREAMH
+# include <fstream.h>
+#else
+# include <fstream>
+#endif
+
+#ifndef __DARWIN__
+# include <windows.h>
+#endif
+#include "wx/msgdlg.h"
+#include "wx/palette.h"
+#include "wx/bitmap.h"
+#include "wx/mac/pnghand.h"
+#include "wx/mac/pngread.h"
+#include "wx/mac/private.h"
+
+extern "C" {
+#include "png.h"
+}
+
+extern "C" void png_read_init PNGARG((png_structp png_ptr));
+extern "C" void png_write_init PNGARG((png_structp png_ptr));
+
+extern CTabHandle wxMacCreateColorTable( int numColors ) ;
+extern void wxMacDestroyColorTable( CTabHandle colors ) ;
+extern void wxMacSetColorTableEntry( CTabHandle newColors , int index , int red , int green , int blue ) ;
+extern GWorldPtr wxMacCreateGWorld( int width , int height , int depth ) ;
+extern void wxMacDestroyGWorld( GWorldPtr gw ) ;
+
+void
+ima_png_error(png_struct *png_ptr, char *message)
+{
+ wxMessageBox(wxString::FromAscii(message), wxT("PNG error"));
+ longjmp(png_ptr->jmpbuf, 1);
+}
+
+
+// static wxGifReaderIter* iter;
+wxPalette *wxCopyPalette(const wxPalette *cmap);
+
+wxPNGReader::wxPNGReader(void)
+{
+ filetype = 0;
+ RawImage = NULL; // Image data
+
+ Width = 0; Height = 0; // Dimensions
+ Depth = 0; // (bits x pixel)
+ ColorType = 0; // Bit 1 = Palette used
+ // Bit 2 = Color used
+ // Bit 3 = Alpha used
+
+ EfeWidth = 0; // Efective Width
+
+ lpbi = NULL;
+ bgindex = -1;
+ m_palette = 0;
+ imageOK = FALSE;
+}
+
+wxPNGReader::wxPNGReader ( char* ImageFileName )
+{
+ imageOK = FALSE;
+ filetype = 0;
+ RawImage = NULL; // Image data
+
+ Width = 0; Height = 0; // Dimensions
+ Depth = 0; // (bits x pixel)
+ ColorType = 0; // Bit 1 = m_palette used
+ // Bit 2 = Color used
+ // Bit 3 = Alpha used
+
+ EfeWidth = 0; // Efective Width
+
+ lpbi = NULL;
+ bgindex = -1;
+ m_palette = 0;
+
+ imageOK = ReadFile (ImageFileName);
+}
+
+void
+wxPNGReader::Create(int width, int height, int depth, int colortype)
+{
+ Width = width; Height = height; Depth = depth;
+ ColorType = (colortype>=0) ? colortype: ((Depth>8) ? COLORTYPE_COLOR: 0);
+ delete m_palette;
+ m_palette = NULL;
+ delete[] RawImage;
+ RawImage = NULL;
+
+ if (lpbi) {
+ wxMacDestroyGWorld( (GWorldPtr) lpbi ) ;
+ }
+ lpbi = wxMacCreateGWorld( Width , Height , Depth);
+ if (lpbi)
+ {
+ EfeWidth = (long)(((long)Width*Depth + 31) / 32) * 4;
+ int bitwidth = width ;
+ if ( EfeWidth > bitwidth )
+ bitwidth = EfeWidth ;
+
+ RawImage = (byte*) new char[ ( bitwidth * Height * ((Depth+7)>>3) ) ];
+ imageOK = TRUE;
+ }
+}
+
+wxPNGReader::~wxPNGReader ( )
+{
+ if (RawImage != NULL) {
+ delete[] RawImage ;
+ RawImage = NULL;
+ }
+ if (lpbi) {
+ wxMacDestroyGWorld( (GWorldPtr) lpbi ) ;
+ lpbi = NULL;
+ }
+ if (m_palette != NULL) {
+ delete m_palette;
+ m_palette = NULL;
+ }
+}
+
+
+int wxPNGReader::GetIndex(int x, int y)
+{
+ if (!Inside(x, y) || (Depth>8)) return -1;
+
+ ImagePointerType ImagePointer = RawImage + EfeWidth*y + (x*Depth >> 3);
+ int index = (int)(*ImagePointer);
+ return index;
+}
+
+bool wxPNGReader::GetRGB(int x, int y, byte* r, byte* g, byte* b)
+{
+ if (!Inside(x, y)) return FALSE;
+
+ if (m_palette) {
+ return m_palette->GetRGB(GetIndex(x, y), r, g, b);
+ /* PALETTEENTRY entry;
+ ::GetPaletteEntries((HPALETTE) m_palette->GetHPALETTE(), GetIndex(x, y), 1, &entry);
+ *r = entry.peRed;
+ *g = entry.peGreen;
+ *b = entry.peBlue; */
+ } else {
+ ImagePointerType ImagePointer = RawImage + EfeWidth*y + (x*Depth >> 3);
+ *b = ImagePointer[0];
+ *g = ImagePointer[1];
+ *r = ImagePointer[2];
+ }
+ return TRUE;
+}
+
+
+bool wxPNGReader::SetIndex(int x, int y, int index)
+{
+ if (!Inside(x, y) || (Depth>8)) return FALSE;
+
+ ImagePointerType ImagePointer = RawImage + EfeWidth*y + (x*Depth >> 3);
+ *ImagePointer = index;
+
+ return TRUE;
+}
+
+bool wxPNGReader::SetRGB(int x, int y, byte r, byte g, byte b)
+{
+ if (!Inside(x, y)) return FALSE;
+
+ if (ColorType & COLORTYPE_PALETTE)
+ {
+ if (!m_palette) return FALSE;
+ SetIndex(x, y, m_palette->GetPixel(r, g, b));
+
+ } else {
+ ImagePointerType ImagePointer = RawImage + EfeWidth*y + (x*Depth >> 3);
+ ImagePointer[0] = b;
+ ImagePointer[1] = g;
+ ImagePointer[2] = r;
+ }
+
+ return TRUE;
+}
+
+bool wxPNGReader::SetPalette(wxPalette* colourmap)
+{
+ delete m_palette ;
+ if (!colourmap)
+ return FALSE;
+ ColorType |= (COLORTYPE_PALETTE | COLORTYPE_COLOR);
+ m_palette = new wxPalette( *colourmap );
+ return true ;
+ // return (DibSetUsage(lpbi, (HPALETTE) m_palette->GetHPALETTE(), WXIMA_COLORS ) != 0);
+}
+
+bool
+wxPNGReader::SetPalette(int n, byte *r, byte *g, byte *b)
+{
+ delete m_palette ;
+ m_palette = new wxPalette();
+ if (!m_palette)
+ return FALSE;
+
+ if (!g) g = r;
+ if (!b) b = g;
+ m_palette->Create(n, r, g, b);
+ ColorType |= (COLORTYPE_PALETTE | COLORTYPE_COLOR);
+ return true ;
+ // return (DibSetUsage(lpbi, (HPALETTE) m_palette->GetHPALETTE(), WXIMA_COLORS ) != 0);
+}
+
+bool
+wxPNGReader::SetPalette(int n, rgb_color_struct *rgb_struct)
+{
+ delete m_palette ;
+ m_palette = new wxPalette();
+ if (!m_palette)
+ return FALSE;
+
+ byte r[256], g[256], b[256];
+
+ for(int i=0; i<n; i++)
+ {
+ r[i] = rgb_struct[i].red;
+ g[i] = rgb_struct[i].green;
+ b[i] = rgb_struct[i].blue;
+ }
+ // Added by JACS copying from Andrew Davison's additions
+ // to GIF-reading code
+ // Make transparency colour black...
+ if (bgindex != -1)
+ r[bgindex] = g[bgindex] = b[bgindex] = 0;
+
+ m_palette->Create(n, r, g, b);
+ ColorType |= (COLORTYPE_PALETTE | COLORTYPE_COLOR);
+ return true ;
+ // return (DibSetUsage(lpbi, (HPALETTE) m_palette->GetHPALETTE(), WXIMA_COLORS ) != 0);
+}
+
+void wxPNGReader::NullData()
+{
+ if (lpbi) {
+ wxMacDestroyGWorld( (GWorldPtr) lpbi ) ;
+ lpbi = NULL;
+ }
+ if (m_palette != NULL) {
+ delete m_palette;
+ m_palette = NULL;
+ }
+}
+
+wxBitmap* wxPNGReader::GetBitmap(void)
+{
+ wxBitmap *bitmap = new wxBitmap;
+ if ( InstantiateBitmap(bitmap) )
+ return bitmap;
+ else
+ {
+ delete bitmap;
+ return NULL;
+ }
+}
+
+bool wxPNGReader::InstantiateBitmap(wxBitmap *bitmap)
+{
+ if ( lpbi )
+ {
+ bitmap->SetHBITMAP((WXHBITMAP) lpbi);
+ bitmap->SetWidth(GetWidth());
+ bitmap->SetHeight(GetHeight());
+ bitmap->SetDepth(GetDepth());
+ if ( GetDepth() > 1 && m_palette )
+ bitmap->SetPalette(*m_palette);
+ bitmap->SetOk(TRUE);
+
+
+ // Make a mask if appropriate
+ /*
+ if ( bgindex > -1 )
+ {
+ wxMask *mask = CreateMask();
+ bitmap->SetMask(mask);
+ }
+ */
+ lpbi = NULL ; // bitmap has taken over ownership
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+ /*
+ HDC dc = ::CreateCompatibleDC(NULL);
+
+ if (dc)
+ {
+ // tmpBitmap is a dummy, to satisfy ::CreateCompatibleDC (it
+ // is a memory dc that must have a bitmap selected into it)
+ HDC dc2 = GetDC(NULL);
+ HBITMAP tmpBitmap = ::CreateCompatibleBitmap(dc2, GetWidth(), GetHeight());
+ ReleaseDC(NULL, dc2);
+ HBITMAP oldBitmap = (HBITMAP) ::SelectObject(dc, tmpBitmap);
+
+ if ( m_palette )
+ {
+ HPALETTE oldPal = ::SelectPalette(dc, (HPALETTE) m_palette->GetHPALETTE(), FALSE);
+ ::RealizePalette(dc);
+ }
+
+ HBITMAP hBitmap = ::CreateDIBitmap(dc, lpbi,
+ CBM_INIT, RawImage, (LPBITMAPINFO) lpbi, DIB_PAL_COLORS);
+
+ ::SelectPalette(dc, NULL, TRUE);
+ ::SelectObject(dc, oldBitmap);
+ ::DeleteObject(tmpBitmap);
+ ::DeleteDC(dc);
+
+ if ( hBitmap )
+ {
+ bitmap->SetHBITMAP((WXHBITMAP) hBitmap);
+ bitmap->SetWidth(GetWidth());
+ bitmap->SetHeight(GetHeight());
+ bitmap->SetDepth(GetDepth());
+ if ( GetDepth() > 1 && m_palette )
+ bitmap->SetPalette(*m_palette);
+ bitmap->SetOk(TRUE);
+
+
+ // Make a mask if appropriate
+ if ( bgindex > -1 )
+ {
+ wxMask *mask = CreateMask();
+ bitmap->SetMask(mask);
+ }
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ return FALSE;
+ }
+ */
+ return false ;
+}
+
+wxPalette *wxCopyPalette(const wxPalette *cmap)
+{
+ wxPalette *newCmap = new wxPalette( *cmap ) ;
+ return newCmap;
+}
+
+wxMask *wxPNGReader::CreateMask(void)
+{
+/*
+HBITMAP hBitmap = ::CreateBitmap(GetWidth(), GetHeight(), 1, 1, NULL);
+
+ HDC dc = ::CreateCompatibleDC(NULL);
+ HBITMAP oldBitmap = (HBITMAP) ::SelectObject(dc, hBitmap);
+
+ int bgIndex = GetBGIndex();
+
+ int x,y;
+
+ for (x=0; x<GetWidth(); x++)
+ {
+ for (y=0; y<GetHeight(); y++)
+ {
+ int index = GetIndex(x, y);
+ if ( index == bgIndex )
+ ::SetPixel(dc, x, GetHeight() - y - 1, RGB(0, 0, 0));
+ else
+ ::SetPixel(dc, x, GetHeight() - y - 1, RGB(255, 255, 255));
+
+ }
+ }
+ ::SelectObject(dc, oldBitmap);
+ wxMask *mask = new wxMask;
+ mask->SetMaskBitmap((WXHBITMAP) hBitmap);
+ return mask;
+ */
+ return NULL ;
+}
+
+bool wxPNGReader::ReadFile(char * ImageFileName)
+{
+ int number_passes;
+
+ if (ImageFileName)
+ strcpy(filename, ImageFileName);
+
+ FILE *fp;
+ png_struct *png_ptr;
+ png_info *info_ptr;
+ wxPNGReaderIter iter(this);
+
+ /* open the file */
+ fp = fopen( ImageFileName , "rb" );
+
+ if (!fp)
+ return FALSE;
+
+ /* allocate the necessary structures */
+ png_ptr = new (png_struct);
+ if (!png_ptr)
+ {
+ fclose(fp);
+ return FALSE;
+ }
+
+ info_ptr = new (png_info);
+ if (!info_ptr)
+ {
+ fclose(fp);
+ delete png_ptr;
+ return FALSE;
+ }
+ /* set error handling */
+ if (setjmp(png_ptr->jmpbuf))
+ {
+ png_read_destroy(png_ptr, info_ptr, (png_info *)0);
+ fclose(fp);
+ delete png_ptr;
+ delete info_ptr;
+
+ /* If we get here, we had a problem reading the file */
+ return FALSE;
+ }
+ //png_set_error(ima_png_error, NULL);
+
+ /* initialize the structures, info first for error handling */
+ png_info_init(info_ptr);
+ png_read_init(png_ptr);
+
+ /* set up the input control */
+ png_init_io(png_ptr, fp);
+
+ /* read the file information */
+ png_read_info(png_ptr, info_ptr);
+
+ /* allocate the memory to hold the image using the fields
+ of png_info. */
+ png_color_16 my_background={ 0, 31, 127, 255, 0 };
+
+ if (info_ptr->valid & PNG_INFO_bKGD)
+ {
+ png_set_background(png_ptr, &(info_ptr->background),
+ PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
+ if ( info_ptr->num_palette > 0 )
+ bgindex = info_ptr->background.index;
+ }
+ else {
+ png_set_background(png_ptr, &my_background,
+ PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+
+ // Added by JACS: guesswork!
+ if ( info_ptr->num_trans != 0 )
+ bgindex = info_ptr->num_trans - 1 ;
+ }
+
+ /* tell libpng to strip 16 bit depth files down to 8 bits */
+ if (info_ptr->bit_depth == 16)
+ png_set_strip_16(png_ptr);
+
+ int pixel_depth=(info_ptr->pixel_depth<24) ? info_ptr->pixel_depth: 24;
+ Create(info_ptr->width, info_ptr->height, pixel_depth,
+ info_ptr->color_type);
+
+ if (info_ptr->num_palette>0)
+ {
+ SetPalette((int)info_ptr->num_palette, (rgb_color_struct*)info_ptr->palette);
+ }
+
+ int row_stride = info_ptr->width * ((pixel_depth+7)>>3);
+ // printf("P = %d D = %d RS= %d ", info_ptr->num_palette, info_ptr->pixel_depth,row_stride);
+ // printf("CT = %d TRS = %d BD= %d ", info_ptr->color_type, info_ptr->valid & PNG_INFO_tRNS,info_ptr->bit_depth);
+
+ byte *row_pointers = new byte[row_stride];
+
+ /* turn on interlace handling */
+ if (info_ptr->interlace_type)
+ number_passes = png_set_interlace_handling(png_ptr);
+ else
+ number_passes = 1;
+ // printf("NP = %d ", number_passes);
+
+ for (int pass=0; pass< number_passes; pass++)
+ {
+ iter.upset();
+ int y=0;
+ CGrafPtr origPort ;
+ GDHandle origDevice ;
+
+ GetGWorld( &origPort , &origDevice ) ;
+ // ignore shapedc
+ SetGWorld( (GWorldPtr) lpbi , NULL ) ;
+ do
+ {
+ // (unsigned char *)iter.GetRow();
+ if (info_ptr->interlace_type)
+ {
+ if (pass>0)
+ iter.GetRow(row_pointers, row_stride);
+ png_read_row(png_ptr, row_pointers, NULL);
+ }
+ else
+ png_read_row(png_ptr, row_pointers, NULL);
+
+ if ( info_ptr->palette )
+ {
+ if ( pixel_depth == 8 )
+ {
+ for ( size_t i = 0 ; i < info_ptr->width ; ++i )
+ {
+ png_color_struct* color ;
+ RGBColor col ;
+
+ int index = row_pointers[i] ;
+ color = &info_ptr->palette[index] ;
+ col.red = (((int)color->red) << 8) | ((int)color->red) ;
+ col.green = (((int)color->green) << 8) | ((int)color->green) ;
+ col.blue = (((int)color->blue) << 8) | ((int)color->blue) ;
+ SetCPixel( i, y, &col);
+ }
+ /*
+ png_color_struct* color ;
+ RGBColor col ;
+ unsigned char* p = &row_pointers[0] ;
+ PenNormal() ;
+ MoveTo( 0 , y ) ;
+ int index = *p ;
+ color = &info_ptr->palette[index] ;
+ col.red = (color->red << 8) | color->red ;
+ col.green = (color->green << 8) | color->green ;
+ col.blue = (color->blue << 8) | color->blue ;
+ RGBForeColor( &col ) ;
+ col.red = col.green = col.blue = 0xFFFF ;
+ RGBBackColor( &col ) ;
+ for ( int i = 0 ; i < info_ptr->width ; ++i , ++p)
+ {
+ if ( *p != index )
+ {
+ LineTo( i , y ) ;
+ index = *p ;
+ color = &info_ptr->palette[index] ;
+ col.red = (((int)color->red) << 8) | ((int)color->red) ;
+ col.green = (((int)color->green) << 8) | ((int)color->green) ;
+ col.blue = (((int)color->blue) << 8) | ((int)color->blue) ;
+ RGBForeColor( &col ) ;
+ }
+ }
+ LineTo( info_ptr->width , y ) ;
+ */
+ }
+ else
+ {
+ for ( size_t i = 0 ; i < info_ptr->width ; ++i )
+ {
+ png_color_struct* color ;
+ RGBColor col ;
+
+ int byte = ( i * pixel_depth ) / 8 ;
+ int offset = ( 8 - pixel_depth ) - ( i * pixel_depth ) % 8 ;
+
+ int index = ( row_pointers[byte] >> offset ) & ( 0xFF >> ( 8 - pixel_depth ) );
+ color = &info_ptr->palette[index] ;
+ col.red = (((int)color->red) << 8) | ((int)color->red) ;
+ col.green = (((int)color->green) << 8) | ((int)color->green) ;
+ col.blue = (((int)color->blue) << 8) | ((int)color->blue) ;
+ SetCPixel( i, y, &col);
+ }
+ }
+ }
+ else
+ {
+ for ( size_t i = 0 ; i < info_ptr->width ; ++i )
+ {
+ png_color_struct* color ;
+ RGBColor col ;
+ color =(png_color_struct*) (&row_pointers[i*3]) ;
+ col.red = (((int)color->red) << 8) | ((int)color->red) ;
+ col.green = (((int)color->green) << 8) | ((int)color->green) ;
+ col.blue = (((int)color->blue) << 8) | ((int)color->blue) ;
+ SetCPixel( i, y, &col);
+ }
+ }
+ if (number_passes)
+ iter.SetRow(row_pointers, row_stride);
+ y++;
+ }
+ while(iter.PrevRow());
+ SetGWorld( origPort , origDevice ) ;
+
+ // printf("Y=%d ",y);
+ }
+ delete[] row_pointers;
+
+ /* read the rest of the file, getting any additional chunks
+ in info_ptr */
+ png_read_end(png_ptr, info_ptr);
+
+ /* clean up after the read, and free any memory allocated */
+ png_read_destroy(png_ptr, info_ptr, (png_info *)0);
+
+ /* free the structures */
+ delete png_ptr;
+ delete info_ptr;
+
+ /* close the file */
+ fclose(fp);
+
+ /* that's it */
+ return TRUE;
+}
+
+
+/* write a png file */
+
+bool wxPNGReader::SaveFile(char * ImageFileName)
+{
+ if (ImageFileName)
+ strcpy(filename, ImageFileName);
+
+ wxPNGReaderIter iter(this);
+ FILE *fp;
+ png_struct *png_ptr;
+ png_info *info_ptr;
+
+ /* open the file */
+ fp = fopen(filename, "wb");
+ if (!fp)
+ return FALSE;
+
+ /* allocate the necessary structures */
+ png_ptr = new (png_struct);
+ if (!png_ptr)
+ {
+ fclose(fp);
+ return FALSE;
+ }
+
+ info_ptr = new (png_info);
+ if (!info_ptr)
+ {
+ fclose(fp);
+ delete png_ptr;
+ return FALSE;
+ }
+
+ /* set error handling */
+ if (setjmp(png_ptr->jmpbuf))
+ {
+ png_write_destroy(png_ptr);
+ fclose(fp);
+ delete png_ptr;
+ delete info_ptr;
+
+ /* If we get here, we had a problem reading the file */
+ return FALSE;
+ }
+ //png_set_error(ima_png_error, NULL);
+
+ // printf("writig pg %s ", filename);
+ /* initialize the structures */
+ png_info_init(info_ptr);
+ png_write_init(png_ptr);
+
+ int row_stride = GetWidth() * ((GetDepth()+7)>>3);
+ /* set up the output control */
+ png_init_io(png_ptr, fp);
+
+ /* set the file information here */
+ info_ptr->width = GetWidth();
+ info_ptr->height = GetHeight();
+ info_ptr->pixel_depth = GetDepth();
+ info_ptr->channels = (GetDepth()>8) ? 3: 1;
+ info_ptr->bit_depth = GetDepth()/info_ptr->channels;
+ info_ptr->color_type = GetColorType();
+ info_ptr->compression_type = info_ptr->filter_type = info_ptr->interlace_type=0;
+ info_ptr->valid = 0;
+ info_ptr->rowbytes = row_stride;
+
+
+ // printf("P = %d D = %d RS= %d GD= %d CH= %d ", info_ptr->pixel_depth, info_ptr->bit_depth, row_stride, GetDepth(), info_ptr->channels);
+ /* set the palette if there is one */
+ if ((GetColorType() & COLORTYPE_PALETTE) && GetPalette())
+ {
+ // printf("writing paleta[%d %d %x]",GetColorType() ,COLORTYPE_PALETTE, GetPalette());
+ info_ptr->valid |= PNG_INFO_PLTE;
+ info_ptr->palette = new png_color[256];
+ info_ptr->num_palette = 256;
+ for (int i=0; i<256; i++)
+ GetPalette()->GetRGB(i, &info_ptr->palette[i].red, &info_ptr->palette[i].green, &info_ptr->palette[i].blue);
+ }
+ // printf("Paleta [%d %d %x]",GetColorType() ,COLORTYPE_PALETTE, GetPalette());
+
+
+ /* optional significant bit chunk */
+ // info_ptr->valid |= PNG_INFO_sBIT;
+ // info_ptr->sig_bit = true_bit_depth;
+
+ /* optional gamma chunk */
+ // info_ptr->valid |= PNG_INFO_gAMA;
+ // info_ptr->gamma = gamma;
+
+ /* other optional chunks */
+
+ /* write the file information */
+ png_write_info(png_ptr, info_ptr);
+
+ /* set up the transformations you want. Note that these are
+ all optional. Only call them if you want them */
+
+ /* shift the pixels up to a legal bit depth and fill in
+ as appropriate to correctly scale the image */
+ // png_set_shift(png_ptr, &(info_ptr->sig_bit));
+
+ /* pack pixels into bytes */
+ // png_set_packing(png_ptr);
+
+ /* flip bgr pixels to rgb */
+ // png_set_bgr(png_ptr);
+
+ /* swap bytes of 16 bit files to most significant bit first */
+ // png_set_swap(png_ptr);
+
+ /* get rid of filler bytes, pack rgb into 3 bytes */
+ // png_set_rgbx(png_ptr);
+
+ /* If you are only writing one row at a time, this works */
+
+ byte *row_pointers = new byte[row_stride];
+ iter.upset();
+ do {
+ // (unsigned char *)iter.GetRow();
+ iter.GetRow(row_pointers, row_stride);
+ png_write_row(png_ptr, row_pointers);
+ } while(iter.PrevRow());
+
+ delete[] row_pointers;
+
+ /* write the rest of the file */
+ png_write_end(png_ptr, info_ptr);
+
+ /* clean up after the write, and free any memory allocated */
+ png_write_destroy(png_ptr);
+
+ /* if you malloced the palette, free it here */
+ if (info_ptr->palette)
+ delete[] (info_ptr->palette);
+
+ /* free the structures */
+ delete png_ptr;
+ delete info_ptr;
+
+ /* close the file */
+ fclose(fp);
+
+ /* that's it */
+ return TRUE;
+}
+
+static int Power(int x, int y)
+{
+ int z = 1;
+ int i;
+ for ( i = 0; i < y; i++)
+ {
+ z *= x;
+ }
+ return z;
+}
+
+static char hexArray[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B',
+'C', 'D', 'E', 'F' };
+
+static void DecToHex(int dec, char *buf)
+{
+ int firstDigit = (int)(dec/16.0);
+ int secondDigit = (int)(dec - (firstDigit*16.0));
+ buf[0] = hexArray[firstDigit];
+ buf[1] = hexArray[secondDigit];
+ buf[2] = 0;
+}
+
+
+bool wxPNGReader::SaveXPM(char *filename, char *name)
+{
+ char nameStr[256];
+ if ( name )
+ strcpy(nameStr, name);
+ else
+ {
+ wxString str = wxString::FromAscii(filename) ;
+ wxStripExtension( str ) ;
+ strcpy(nameStr, str.ToAscii() );
+ }
+
+ if ( GetDepth() > 4 )
+ {
+ // Only a depth of 4 and below allowed
+ return FALSE;
+ }
+
+ if ( !GetPalette() )
+ return FALSE;
+
+ wxSTD ofstream str(filename);
+ if ( str.bad() )
+ return FALSE;
+
+ int noColours = Power(2, GetDepth());
+
+ // Output header
+ str << "/* XPM */\n";
+ str << "static char * " << nameStr << "_xpm[] = {\n";
+ str << "\"" << GetWidth() << " " << GetHeight() << " " << noColours << " 1\",\n";
+
+ // Output colourmap
+ int base = 97 ; // start from 'a'
+
+ unsigned char red, green, blue;
+ char hexBuf[4];
+ int i;
+ for ( i = 0; i < noColours; i ++)
+ {
+ str << "\"" << (char)(base + i) << " c #";
+ GetPalette()->GetRGB(i, &red, &green, &blue);
+ DecToHex(red, hexBuf);
+ str << hexBuf;
+ DecToHex(green, hexBuf);
+ str << hexBuf;
+ DecToHex(blue, hexBuf);
+ str << hexBuf;
+ str << "\",\n";
+ }
+
+ // Output the data
+ int x, y;
+ for ( y = 0; y < GetHeight(); y++)
+ {
+ str << "\"";
+ for ( x = 0; x < GetWidth(); x++)
+ {
+ int index = GetIndex(x, y);
+ str << (char)(base + index) ;
+ }
+ str << "\",\n";
+ }
+
+ str << "};\n";
+ str.flush();
+
+ return TRUE;
+}
+
+
+IMPLEMENT_DYNAMIC_CLASS(wxPNGFileHandler, wxBitmapHandler)
+
+bool wxPNGFileHandler::LoadFile(wxBitmap *bitmap, const wxString& name, long flags,
+ int desiredWidth, int desiredHeight)
+{
+ wxPNGReader reader;
+ if (reader.ReadFile( (char*)(const char*) name.ToAscii() ) )
+ {
+ return reader.InstantiateBitmap(bitmap);
+ }
+ else
+ return FALSE;
+}
+
+bool wxPNGFileHandler::SaveFile(const wxBitmap *bitmap, const wxString& name, int type, const wxPalette *pal)
+{
+ return FALSE;
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: printdlg.cpp
+// Purpose: wxPrintDialog, wxPageSetupDialog
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "printdlg.h"
+#endif
+
+#include "wx/object.h"
+#include "wx/printdlg.h"
+#include "wx/dcprint.h"
+#include "wx/msgdlg.h"
+#include "wx/mac/private/print.h"
+
+// Use generic page setup dialog: use your own native one if one exists.
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxPrintDialog, wxDialog)
+IMPLEMENT_CLASS(wxPageSetupDialog, wxDialog)
+#endif
+
+wxPrintDialog::wxPrintDialog()
+{
+ m_dialogParent = NULL;
+ m_printerDC = NULL;
+ m_destroyDC = TRUE;
+}
+
+wxPrintDialog::wxPrintDialog(wxWindow *p, wxPrintDialogData* data)
+{
+ Create(p, data);
+}
+
+wxPrintDialog::wxPrintDialog(wxWindow *p, wxPrintData* data)
+{
+ wxPrintDialogData data2;
+ if ( data )
+ data2 = *data;
+
+ Create(p, &data2);
+}
+
+bool wxPrintDialog::Create(wxWindow *p, wxPrintDialogData* data)
+{
+ m_dialogParent = p;
+ m_printerDC = NULL;
+ m_destroyDC = TRUE;
+
+ if ( data )
+ m_printDialogData = *data;
+
+ return TRUE;
+}
+
+wxPrintDialog::~wxPrintDialog()
+{
+ if (m_destroyDC && m_printerDC) {
+ delete m_printerDC;
+ m_printerDC = NULL;
+ }
+}
+
+int wxPrintDialog::ShowModal()
+{
+ m_printDialogData.ConvertToNative() ;
+ int result = m_printDialogData.GetPrintData().m_nativePrintData->ShowPrintDialog() ;
+ if ( result == wxID_OK )
+ m_printDialogData.ConvertFromNative() ;
+
+ return result ;
+}
+
+wxDC *wxPrintDialog::GetPrintDC()
+{
+ return new wxPrinterDC( m_printDialogData.GetPrintData() ) ;
+}
+
+/*
+* wxPageSetupDialog
+*/
+
+wxPageSetupDialog::wxPageSetupDialog():
+wxDialog()
+{
+ m_dialogParent = NULL;
+}
+
+wxPageSetupDialog::wxPageSetupDialog(wxWindow *p, wxPageSetupData *data):
+wxDialog()
+{
+ Create(p, data);
+}
+
+bool wxPageSetupDialog::Create(wxWindow *p, wxPageSetupData *data)
+{
+ m_dialogParent = p;
+
+ if (data)
+ m_pageSetupData = (*data);
+
+ return TRUE;
+}
+
+wxPageSetupDialog::~wxPageSetupDialog()
+{
+}
+
+int wxPageSetupDialog::ShowModal()
+{
+ m_pageSetupData.ConvertToNative() ;
+ int result = m_pageSetupData.GetPrintData().m_nativePrintData->ShowPageSetupDialog() ;
+ if (result == wxID_OK )
+ m_pageSetupData.ConvertFromNative() ;
+
+ return result ;
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: printwin.cpp
+// Purpose: wxMacPrinter framework
+// Author: Julian Smart
+// Modified by:
+// Created: 04/01/98
+// RCS-ID: $Id$
+// Copyright: (c) Julian Smart
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "printwin.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#include "wx/defs.h"
+
+#ifndef WX_PRECOMP
+#include "wx/utils.h"
+#include "wx/dc.h"
+#include "wx/app.h"
+#include "wx/msgdlg.h"
+#endif
+
+#include "wx/mac/uma.h"
+
+#include "wx/mac/printmac.h"
+#include "wx/mac/private/print.h"
+
+#define mm2pt 2.83464566929
+#define pt2mm 0.352777777778
+
+#include "wx/dcprint.h"
+#include "wx/printdlg.h"
+
+#include <stdlib.h>
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxMacPrinter, wxPrinterBase)
+IMPLEMENT_CLASS(wxMacPrintPreview, wxPrintPreviewBase)
+#endif
+
+#if TARGET_CARBON
+
+wxNativePrintData* wxNativePrintData::Create()
+{
+ return new wxMacCarbonPrintData() ;
+}
+
+wxMacCarbonPrintData::wxMacCarbonPrintData()
+{
+ m_macPageFormat = kPMNoPageFormat;
+ m_macPrintSettings = kPMNoPrintSettings;
+ m_macPrintSession = kPMNoReference ;
+ ValidateOrCreate() ;
+}
+
+wxMacCarbonPrintData::~wxMacCarbonPrintData()
+{
+ if (m_macPageFormat != kPMNoPageFormat)
+ {
+ (void)PMRelease(m_macPageFormat);
+ m_macPageFormat = kPMNoPageFormat;
+ }
+
+ if (m_macPrintSettings != kPMNoPrintSettings)
+ {
+ (void)PMRelease(m_macPrintSettings);
+ m_macPrintSettings = kPMNoPrintSettings;
+ }
+
+ if ( m_macPrintSession != kPMNoReference )
+ {
+ (void)PMRelease(m_macPrintSession);
+ m_macPrintSession = kPMNoReference;
+ }
+}
+
+void wxMacCarbonPrintData::ValidateOrCreate()
+{
+ OSStatus err = noErr ;
+ if ( m_macPrintSession == kPMNoReference )
+ {
+ err = PMCreateSession( (PMPrintSession *) &m_macPrintSession ) ;
+ }
+ // Set up a valid PageFormat object.
+ if ( m_macPageFormat == kPMNoPageFormat)
+ {
+ err = PMCreatePageFormat((PMPageFormat *) &m_macPageFormat);
+
+ // Note that PMPageFormat is not session-specific, but calling
+ // PMSessionDefaultPageFormat assigns values specific to the printer
+ // associated with the current printing session.
+ if ((err == noErr) &&
+ ( m_macPageFormat != kPMNoPageFormat))
+ {
+ err = PMSessionDefaultPageFormat((PMPrintSession) m_macPrintSession,
+ (PMPageFormat) m_macPageFormat);
+ }
+ }
+ else
+ {
+ err = PMSessionValidatePageFormat((PMPrintSession) m_macPrintSession,
+ (PMPageFormat) m_macPageFormat,
+ kPMDontWantBoolean);
+ }
+
+ // Set up a valid PrintSettings object.
+ if ( m_macPrintSettings == kPMNoPrintSettings)
+ {
+ err = PMCreatePrintSettings((PMPrintSettings *) &m_macPrintSettings);
+
+ // Note that PMPrintSettings is not session-specific, but calling
+ // PMSessionDefaultPrintSettings assigns values specific to the printer
+ // associated with the current printing session.
+ if ((err == noErr) &&
+ ( m_macPrintSettings != kPMNoPrintSettings))
+ {
+ err = PMSessionDefaultPrintSettings((PMPrintSession) m_macPrintSession,
+ (PMPrintSettings) m_macPrintSettings);
+ }
+ }
+ else
+ {
+ err = PMSessionValidatePrintSettings((PMPrintSession) m_macPrintSession,
+ (PMPrintSettings) m_macPrintSettings,
+ kPMDontWantBoolean);
+ }
+}
+
+void wxMacCarbonPrintData::TransferFrom( wxPrintData* data )
+{
+ ValidateOrCreate() ;
+ PMSetCopies( (PMPrintSettings) m_macPrintSettings , data->GetNoCopies() , false ) ;
+ PMSetOrientation( (PMPageFormat) m_macPageFormat , ( data->GetOrientation() == wxLANDSCAPE ) ?
+ kPMLandscape : kPMPortrait , false ) ;
+ // collate cannot be set
+#if 0 // not yet tested
+ if ( m_printerName.Length() > 0 )
+ PMSessionSetCurrentPrinter( (PMPrintSession) m_macPrintSession , wxMacCFStringHolder( m_printerName , wxFont::GetDefaultEncoding() ) ) ;
+#endif
+ PMColorMode color ;
+ PMGetColorMode( (PMPrintSettings) m_macPrintSettings, &color ) ;
+ if ( data->GetColour() )
+ {
+ if ( color == kPMBlackAndWhite )
+ PMSetColorMode( (PMPrintSettings) m_macPrintSettings, kPMColor ) ;
+ }
+ else
+ PMSetColorMode( (PMPrintSettings) m_macPrintSettings, kPMBlackAndWhite ) ;
+
+ // PMDuplexMode not yet accessible via API
+ // PMQualityMode not yet accessible via API
+ // todo paperSize
+}
+
+void wxMacCarbonPrintData::TransferTo( wxPrintData* data )
+{
+ OSStatus err = noErr ;
+
+ UInt32 copies ;
+ err = PMGetCopies( m_macPrintSettings , &copies ) ;
+ if ( err == noErr )
+ data->SetNoCopies( copies ) ;
+
+ PMOrientation orientation ;
+ err = PMGetOrientation( m_macPageFormat , &orientation ) ;
+ if ( err == noErr )
+ {
+ if ( orientation == kPMPortrait || orientation == kPMReversePortrait )
+ data->SetOrientation( wxPORTRAIT );
+ else
+ data->SetOrientation( wxLANDSCAPE );
+ }
+
+ // collate cannot be set
+#if 0
+ {
+ wxMacCFStringHolder name ;
+ PMPrinter printer ;
+ PMSessionGetCurrentPrinter( m_macPrintSession ,
+ &printer ) ;
+ m_printerName = name.AsString() ;
+ }
+#endif
+
+ PMColorMode color ;
+ err = PMGetColorMode( m_macPrintSettings, &color ) ;
+ if ( err == noErr )
+ data->SetColour( !(color == kPMBlackAndWhite) ) ;
+
+ // PMDuplexMode not yet accessible via API
+ // PMQualityMode not yet accessible via API
+ // todo paperSize
+ PMRect rPaper;
+ err = PMGetUnadjustedPaperRect( m_macPageFormat, &rPaper);
+ if ( err == noErr )
+ {
+ data->SetPaperSize( wxSize (
+ (int)(( rPaper.right - rPaper.left ) * pt2mm + 0.5 ) ,
+ (int)(( rPaper.bottom - rPaper.top ) * pt2mm + 0.5 ) ) );
+ }
+}
+
+void wxMacCarbonPrintData::TransferFrom( wxPageSetupData *data )
+{
+ // should we setup the page rect here ?
+ // since MacOS sometimes has two same paper rects with different
+ // page rects we could make it roundtrip safe perhaps
+#if TARGET_CARBON
+#else
+#endif
+}
+
+void wxMacCarbonPrintData::TransferTo( wxPageSetupData* data )
+{
+ PMRect rPaper;
+ OSStatus err = PMGetUnadjustedPaperRect(m_macPageFormat, &rPaper);
+ if ( err == noErr )
+ {
+ PMRect rPage ;
+ err = PMGetUnadjustedPageRect(m_macPageFormat , &rPage ) ;
+ if ( err == noErr )
+ {
+ data->SetMinMarginTopLeft( wxPoint (
+ (int)(((double) rPage.left - rPaper.left ) * pt2mm) ,
+ (int)(((double) rPage.top - rPaper.top ) * pt2mm) ) ) ;
+
+ data->SetMinMarginBottomRight( wxPoint (
+ (wxCoord)(((double) rPaper.right - rPage.right ) * pt2mm),
+ (wxCoord)(((double) rPaper.bottom - rPage.bottom ) * pt2mm)) ) ;
+ }
+ }
+}
+
+void wxMacCarbonPrintData::TransferTo( wxPrintDialogData* data )
+{
+ UInt32 minPage , maxPage ;
+ PMGetPageRange( m_macPrintSettings , &minPage , &maxPage ) ;
+ data->SetMinPage( minPage ) ;
+ data->SetMaxPage( maxPage ) ;
+ UInt32 copies ;
+ PMGetCopies( m_macPrintSettings , &copies ) ;
+ data->SetNoCopies( copies ) ;
+ UInt32 from , to ;
+ PMGetFirstPage( m_macPrintSettings , &from ) ;
+ PMGetLastPage( m_macPrintSettings , &to ) ;
+ data->SetFromPage( from ) ;
+ data->SetToPage( to ) ;
+}
+
+void wxMacCarbonPrintData::TransferFrom( wxPrintDialogData* data )
+{
+ PMSetPageRange( m_macPrintSettings , data->GetMinPage() , data->GetMaxPage() ) ;
+ PMSetCopies( m_macPrintSettings , data->GetNoCopies() , false ) ;
+ PMSetFirstPage( m_macPrintSettings , data->GetFromPage() , false ) ;
+
+ int toPage = data->GetToPage();
+ if (toPage < 1)
+ toPage = data->GetFromPage();
+ PMSetLastPage( m_macPrintSettings , toPage , false ) ;
+}
+
+void wxMacCarbonPrintData::CopyFrom( wxNativePrintData* d )
+{
+ wxMacCarbonPrintData *data = (wxMacCarbonPrintData*) d ;
+ if ( data->m_macPrintSession != kPMNoReference )
+ PMRetain( data->m_macPrintSession ) ;
+ if ( m_macPrintSession != kPMNoReference )
+ {
+ PMRelease( m_macPrintSession ) ;
+ m_macPrintSession = kPMNoReference ;
+ }
+ if ( data->m_macPrintSession != kPMNoReference )
+ m_macPrintSession = data->m_macPrintSession ;
+
+ if ( data->m_macPrintSettings != kPMNoPrintSettings )
+ PMRetain( data->m_macPrintSettings ) ;
+ if ( m_macPrintSettings != kPMNoPrintSettings )
+ {
+ PMRelease( m_macPrintSettings ) ;
+ m_macPrintSettings = kPMNoPrintSettings ;
+ }
+ if ( data->m_macPrintSettings != kPMNoPrintSettings )
+ m_macPrintSettings = data->m_macPrintSettings ;
+
+ if ( data->m_macPageFormat != kPMNoPageFormat )
+ PMRetain( data->m_macPageFormat ) ;
+ if ( m_macPageFormat != kPMNoPageFormat )
+ {
+ PMRelease( m_macPageFormat ) ;
+ m_macPageFormat = kPMNoPageFormat ;
+ }
+ if ( data->m_macPageFormat != kPMNoPageFormat )
+ m_macPageFormat = data->m_macPageFormat ;
+}
+
+int wxMacCarbonPrintData::ShowPrintDialog()
+{
+ int result = wxID_CANCEL ;
+ OSErr err = noErr ;
+ wxString message ;
+
+ Boolean accepted;
+
+ {
+ // Display the Print dialog.
+ if (err == noErr)
+ {
+ err = PMSessionPrintDialog( m_macPrintSession,
+ m_macPrintSettings,
+ m_macPageFormat,
+ &accepted);
+ if ((err == noErr) && !accepted)
+ {
+ err = kPMCancel; // user clicked Cancel button
+ }
+ }
+ if ( err == noErr )
+ {
+ result = wxID_OK ;
+ }
+ }
+ if ((err != noErr) && (err != kPMCancel))
+ {
+ message.Printf( wxT("Print Error %d"), err ) ;
+ wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ;
+ dialog.ShowModal();
+ }
+
+ return result ;
+}
+
+int wxMacCarbonPrintData::ShowPageSetupDialog()
+{
+ int result = wxID_CANCEL ;
+ OSErr err = noErr ;
+ wxString message ;
+
+ Boolean accepted;
+ {
+ // Display the Page Setup dialog.
+ if (err == noErr)
+ {
+ err = PMSessionPageSetupDialog( m_macPrintSession,
+ m_macPageFormat,
+ &accepted);
+ if ((err == noErr) && !accepted)
+ {
+ err = kPMCancel; // user clicked Cancel button
+ }
+ }
+
+ // If the user did not cancel, flatten and save the PageFormat object
+ // with our document.
+ if (err == noErr) {
+ result = wxID_OK ;
+ }
+ }
+ if ((err != noErr) && (err != kPMCancel))
+ {
+ message.Printf( wxT("Print Error %d"), err ) ;
+ wxMessageDialog dialog( NULL , message , wxEmptyString, wxICON_HAND | wxOK) ;
+ dialog.ShowModal();
+ }
+
+ return result ;
+}
+
+#else
+
+wxNativePrintData* wxNativePrintData::Create()
+{
+ return new wxMacClassicPrintData() ;
+}
+
+wxMacClassicPrintData::wxMacClassicPrintData()
+{
+ m_macPrintSettings = NULL ;
+ ValidateOrCreate() ;
+}
+
+wxMacClassicPrintData::~wxMacClassicPrintData()
+{
+ wxASSERT( m_macPrintSettings );
+ DisposeHandle( (Handle) m_macPrintSettings ) ;
+}
+
+void wxMacClassicPrintData::ValidateOrCreate()
+{
+ if ( m_macPrintSettings == NULL )
+ {
+ m_macPrintSettings = (THPrint) NewHandleClear( sizeof( TPrint ) );
+ (**m_macPrintSettings).iPrVersion = 0; // something invalid
+
+ (**m_macPrintSettings).prInfo.iHRes = 72;
+ (**m_macPrintSettings).prInfo.iVRes = 72;
+ Rect r1 = { 0, 0, 8*72 - 2 * 18, 11*72 - 2 * 36 };
+ (**m_macPrintSettings).prInfo.rPage = r1;// must have its top left & (0,0)
+
+ Rect r2 = { -18, -36, 8*72 - 18, 11*72 - 36 };
+ (**m_macPrintSettings).rPaper = r2;
+ (**m_macPrintSettings).prStl.iPageV = 11 * 120 ; // 11 inches in 120th of an inch
+ (**m_macPrintSettings).prStl.iPageH = 8 * 120 ; // 8 inches in 120th of an inch
+ }
+ else
+ {
+ }
+}
+
+void wxMacClassicPrintData::TransferFrom( wxPrintData* data )
+{
+ ValidateOrCreate() ;
+ (**m_macPrintSettings).prJob.iCopies = data->GetNoCopies() ;
+ // on mac the paper rect has a negative top left corner, because the page rect (printable area) is at 0,0
+ // if all printing data is consolidated in on structure we will be able to set additional infos about pages
+}
+
+void wxMacClassicPrintData::TransferTo( wxPrintData* data )
+{
+ data->SetNoCopies( (**m_macPrintSettings).prJob.iCopies );
+ data->SetPaperSize( wxSize(
+ ((double) (**m_macPrintSettings).rPaper.right - (**m_macPrintSettings).rPaper.left ) * pt2mm ,
+ ((double) (**m_macPrintSettings).rPaper.bottom - (**m_macPrintSettings).rPaper.top ) * pt2mm ) ) ;
+}
+
+void wxMacClassicPrintData::TransferFrom( wxPageSetupData *data )
+{
+}
+
+void wxMacClassicPrintData::TransferTo( wxPageSetupData* data )
+{
+ data->SetMinMarginTopLeft( wxPoint(
+ ((double) (**m_macPrintSettings).prInfo.rPage.left -(**m_macPrintSettings).rPaper.left ) * pt2mm ,
+ ((double) (**m_macPrintSettings).prInfo.rPage.top -(**m_macPrintSettings).rPaper.top ) * pt2mm ) ) ;
+ data->SetMinMarginBottomRight( wxPoint(
+ ((double) (**m_macPrintSettings).rPaper.right - (**m_macPrintSettings).prInfo.rPage.right ) * pt2mm ,
+ ((double)(**m_macPrintSettings).rPaper.bottom - (**m_macPrintSettings).prInfo.rPage.bottom ) * pt2mm ) ) ;
+}
+
+void wxMacClassicPrintData::TransferFrom( wxPrintDialogData* data )
+{
+ int toPage = data->GetToPage();
+ if (toPage < 1)
+ toPage = data->GetFromPage();
+ (**m_macPrintSettings).prJob.iFstPage = data->GetFromPage() ;
+ (**m_macPrintSettings).prJob.iLstPage = toPage;
+}
+
+void wxMacClassicPrintData::TransferTo( wxPrintDialogData* data )
+{
+ data->SetFromPage( (**m_macPrintSettings).prJob.iFstPage ) ;
+ data->SetToPage( (**m_macPrintSettings).prJob.iLstPage ) ;
+}
+
+void wxMacClassicPrintData::CopyFrom( wxNativePrintData* data )
+{
+ DisposeHandle( (Handle) m_macPrintSettings ) ;
+ m_macPrintSettings = ((wxMacClassicPrintData*)data)->m_macPrintSettings;
+ HandToHand( (Handle*) &m_macPrintSettings );
+}
+
+int wxMacClassicPrintData::ShowPrintDialog()
+{
+ int result = wxID_CANCEL ;
+ OSErr err = noErr ;
+ wxString message ;
+
+ err = ::UMAPrOpen() ;
+ if ( err == noErr )
+ {
+ if ( ::PrJobDialog( m_macPrintSettings ) )
+ {
+ result = wxID_OK ;
+ }
+
+ }
+ else
+ {
+ message.Printf( wxT("Print Error %d"), err ) ;
+ wxMessageDialog dialog( NULL , message , wxT(""), wxICON_HAND | wxOK) ;
+ dialog.ShowModal();
+ }
+ ::UMAPrClose() ;
+
+ return result ;
+}
+
+int wxMacClassicPrintData::ShowPageSetupDialog()
+{
+ int result = wxID_CANCEL ;
+ OSErr err = noErr ;
+ wxString message ;
+
+ err = ::UMAPrOpen() ;
+ if ( err == noErr )
+ {
+ if ( ::PrStlDialog( m_macPrintSettings ) )
+ {
+ result = wxID_OK ;
+ }
+
+ }
+ else
+ {
+ message.Printf( wxT("Print Error %d"), err ) ;
+ wxMessageDialog dialog( NULL , message , wxEmptyString , wxICON_HAND | wxOK) ;
+ dialog.ShowModal();
+ }
+ ::UMAPrClose() ;
+ return result ;
+}
+
+#endif
+
+/*
+* Printer
+*/
+
+wxMacPrinter::wxMacPrinter(wxPrintDialogData *data):
+wxPrinterBase(data)
+{
+}
+
+wxMacPrinter::~wxMacPrinter(void)
+{
+}
+
+bool wxMacPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt)
+{
+ sm_abortIt = FALSE;
+ sm_abortWindow = NULL;
+
+ if (!printout)
+ return FALSE;
+
+ printout->SetIsPreview(FALSE);
+ if (m_printDialogData.GetMinPage() < 1)
+ m_printDialogData.SetMinPage(1);
+ if (m_printDialogData.GetMaxPage() < 1)
+ m_printDialogData.SetMaxPage(9999);
+
+ // Create a suitable device context
+ wxDC *dc = NULL;
+ if (prompt)
+ {
+ wxPrintDialog dialog(parent, & m_printDialogData);
+ if (dialog.ShowModal() == wxID_OK)
+ {
+ dc = dialog.GetPrintDC();
+ m_printDialogData = dialog.GetPrintDialogData();
+ }
+ }
+ else
+ {
+ dc = new wxPrinterDC( m_printDialogData.GetPrintData() ) ;
+ }
+
+
+ // May have pressed cancel.
+ if (!dc || !dc->Ok())
+ {
+ if (dc) delete dc;
+ return FALSE;
+ }
+
+ // on the mac we have always pixels as addressing mode with 72 dpi
+
+ printout->SetPPIScreen(72, 72);
+ printout->SetPPIPrinter(72, 72);
+
+ // Set printout parameters
+ printout->SetDC(dc);
+
+ int w, h;
+ wxCoord ww, hh;
+ dc->GetSize(&w, &h);
+ printout->SetPageSizePixels((int)w, (int)h);
+ dc->GetSizeMM(&ww, &hh);
+ printout->SetPageSizeMM((int)ww, (int)hh);
+
+ // Create an abort window
+ wxBeginBusyCursor();
+
+ printout->OnPreparePrinting();
+
+ // Get some parameters from the printout, if defined
+ int fromPage, toPage;
+ int minPage, maxPage;
+ printout->GetPageInfo(&minPage, &maxPage, &fromPage, &toPage);
+
+ if (maxPage == 0)
+ {
+ wxEndBusyCursor();
+ return FALSE;
+ }
+
+ // Only set min and max, because from and to have been
+ // set by the user
+ m_printDialogData.SetMinPage(minPage);
+ m_printDialogData.SetMaxPage(maxPage);
+
+ wxWindow *win = CreateAbortWindow(parent, printout);
+ wxSafeYield(win,true);
+
+ if (!win)
+ {
+ wxEndBusyCursor();
+ wxMessageBox(wxT("Sorry, could not create an abort dialog."), wxT("Print Error"), wxOK, parent);
+ delete dc;
+ return FALSE;
+ }
+ sm_abortWindow = win;
+ sm_abortWindow->Show(TRUE);
+ wxSafeYield(win,true);
+
+ printout->OnBeginPrinting();
+
+ bool keepGoing = TRUE;
+
+ int copyCount;
+ for (copyCount = 1; copyCount <= m_printDialogData.GetNoCopies(); copyCount ++)
+ {
+ if (!printout->OnBeginDocument(m_printDialogData.GetFromPage(), m_printDialogData.GetToPage()))
+ {
+ wxEndBusyCursor();
+ wxMessageBox(wxT("Could not start printing."), wxT("Print Error"), wxOK, parent);
+ break;
+ }
+ if (sm_abortIt)
+ break;
+
+ int pn;
+ for (pn = m_printDialogData.GetFromPage(); keepGoing && (pn <= m_printDialogData.GetToPage()) && printout->HasPage(pn);
+ pn++)
+ {
+ if (sm_abortIt)
+ {
+ keepGoing = FALSE;
+ break;
+ }
+ else
+ {
+#if TARGET_CARBON
+ if ( UMAGetSystemVersion() >= 0x1000 )
+#endif
+ {
+ GrafPtr thePort ;
+ GetPort( &thePort ) ;
+ wxSafeYield(win,true);
+ SetPort( thePort ) ;
+ }
+ dc->StartPage();
+ keepGoing = printout->OnPrintPage(pn);
+ dc->EndPage();
+ }
+ }
+ printout->OnEndDocument();
+ }
+
+ printout->OnEndPrinting();
+
+ if (sm_abortWindow)
+ {
+ sm_abortWindow->Show(FALSE);
+ delete sm_abortWindow;
+ sm_abortWindow = NULL;
+ }
+
+ wxEndBusyCursor();
+
+ delete dc;
+
+ return TRUE;
+}
+
+wxDC* wxMacPrinter::PrintDialog(wxWindow *parent)
+{
+ wxDC* dc = (wxDC*) NULL;
+
+ wxPrintDialog dialog(parent, & m_printDialogData);
+ int ret = dialog.ShowModal();
+
+ if (ret == wxID_OK)
+ {
+ dc = dialog.GetPrintDC();
+ m_printDialogData = dialog.GetPrintDialogData();
+ }
+
+ return dc;
+}
+
+bool wxMacPrinter::Setup(wxWindow *parent)
+{
+ wxPrintDialog dialog(parent, & m_printDialogData);
+ dialog.GetPrintDialogData().SetSetupDialog(TRUE);
+
+ int ret = dialog.ShowModal();
+
+ if (ret == wxID_OK)
+ {
+ m_printDialogData = dialog.GetPrintDialogData();
+ }
+
+ return (ret == wxID_OK);
+}
+
+/*
+* Print preview
+*/
+
+wxMacPrintPreview::wxMacPrintPreview(wxPrintout *printout,
+ wxPrintout *printoutForPrinting,
+ wxPrintDialogData *data)
+ : wxPrintPreviewBase(printout, printoutForPrinting, data)
+{
+ DetermineScaling();
+}
+
+wxMacPrintPreview::wxMacPrintPreview(wxPrintout *printout, wxPrintout *printoutForPrinting, wxPrintData *data):
+wxPrintPreviewBase(printout, printoutForPrinting, data)
+{
+ DetermineScaling();
+}
+
+wxMacPrintPreview::~wxMacPrintPreview(void)
+{
+}
+
+bool wxMacPrintPreview::Print(bool interactive)
+{
+ if (!m_printPrintout)
+ return FALSE;
+ wxMacPrinter printer(&m_printDialogData);
+ return printer.Print(m_previewFrame, m_printPrintout, interactive);
+}
+
+void wxMacPrintPreview::DetermineScaling(void)
+{
+ int screenWidth , screenHeight ;
+ wxDisplaySize( &screenWidth , &screenHeight ) ;
+
+ m_previewPrintout->SetPPIScreen( 72 , 72 ) ;
+ m_previewPrintout->SetPPIPrinter( 72 , 72 ) ;
+ m_previewPrintout->SetPageSizeMM( (int) (8.0 * 25.6), (int) (11.0 * 25.6) );
+ m_previewPrintout->SetPageSizePixels( 8 * 72 , 11 * 72 ) ;
+ m_pageWidth = 8 * 72 ;
+ m_pageHeight = 11 * 72 ;
+ m_previewScale = 1 ;
+
+ // Get a device context for the currently selected printer
+ wxPrinterDC printerDC(m_printDialogData.GetPrintData());
+ if (printerDC.Ok())
+ {
+ int x , y ;
+ wxCoord ww, hh;
+ printerDC.GetSizeMM(&ww, &hh);
+ printerDC.GetSize( &x , &y ) ;
+ m_previewPrintout->SetPageSizeMM((int)ww, (int)hh);
+ m_previewPrintout->SetPageSizePixels( x , y) ;
+ m_pageWidth = x ;
+ m_pageHeight = y ;
+ m_isOk = true ;
+ }
+ else
+ {
+ m_isOk = false ;
+ }
+ // At 100%, the page should look about page-size on the screen.
+ // m_previewScale = (float)((float)screenWidth/(float)printerWidth);
+ // m_previewScale = m_previewScale * (float)((float)screenXRes/(float)printerXRes);
+
+ m_previewScale = 1 ;
+}
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: radiobox.cpp
+// Purpose: wxRadioBox
+// Author: Stefan Csomor
+// Modified by: JS Lair (99/11/15) first implementation
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "radioboxbase.h"
+#pragma implementation "radiobox.h"
+#endif
+
+//-------------------------------------------------------------------------------------
+// headers
+//-------------------------------------------------------------------------------------
+
+#include "wx/defs.h"
+#include "wx/arrstr.h"
+
+#include "wx/radiobox.h"
+#include "wx/radiobut.h"
+#include "wx/mac/uma.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxRadioBox, wxControl)
+#endif
+
+//-------------------------------------------------------------------------------------
+// ¥ wxRadioBox()
+//-------------------------------------------------------------------------------------
+// Default constructor
+BEGIN_EVENT_TABLE(wxRadioBox, wxControl)
+EVT_RADIOBUTTON( -1 , wxRadioBox::OnRadioButton )
+END_EVENT_TABLE()
+
+void wxRadioBox::OnRadioButton( wxCommandEvent &outer )
+{
+ if ( outer.IsChecked() )
+ {
+ wxCommandEvent event(wxEVT_COMMAND_RADIOBOX_SELECTED, m_windowId);
+ int i = GetSelection() ;
+ event.SetInt( i );
+ event.SetString( GetString( i ) );
+ event.SetEventObject( this );
+ ProcessCommand(event);
+ }
+}
+
+wxRadioBox::wxRadioBox()
+{
+ m_noItems = 0;
+ m_noRowsOrCols = 0;
+ m_majorDim = 0 ;
+ m_radioButtonCycle = NULL;
+}
+
+//-------------------------------------------------------------------------------------
+// ¥ wxRadioBox(wxWindow*, wxWindowID, const wxString&, const wxPoint&,
+// const wxSize&, int, const wxString[], int, long,
+// const wxValidator&, const wxString&)
+//-------------------------------------------------------------------------------------
+// Contructor, creating and showing a radiobox
+//
+// inline defined
+//
+
+//-------------------------------------------------------------------------------------
+// ¥ ~wxRadioBox
+//-------------------------------------------------------------------------------------
+// Destructor, destroying the radiobox item
+
+wxRadioBox::~wxRadioBox()
+{
+ m_isBeingDeleted = TRUE;
+
+ wxRadioButton *next,*current;
+
+ current=m_radioButtonCycle->NextInCycle();
+ next=current->NextInCycle();
+ while (current!=m_radioButtonCycle) {
+ delete current;
+ current=next;
+ next=current->NextInCycle();
+ }
+ delete current;
+}
+
+//-------------------------------------------------------------------------------------
+// ¥ Create
+//-------------------------------------------------------------------------------------
+// Create the radiobox for two-step construction
+
+bool wxRadioBox::Create(wxWindow *parent, wxWindowID id, const wxString& label,
+ const wxPoint& pos, const wxSize& size,
+ const wxArrayString& choices,
+ int majorDim, long style,
+ const wxValidator& val, const wxString& name)
+{
+ wxCArrayString chs(choices);
+
+ return Create(parent, id, label, pos, size, chs.GetCount(),
+ chs.GetStrings(), majorDim, style, val, name);
+}
+
+bool wxRadioBox::Create(wxWindow *parent, wxWindowID id, const wxString& label,
+ const wxPoint& pos, const wxSize& size,
+ int n, const wxString choices[],
+ int majorDim, long style,
+ const wxValidator& val, const wxString& name)
+{
+ if ( !wxControl::Create(parent, id, pos, size, style, val, name) )
+ return false;
+
+ int i;
+
+ m_noItems = n;
+ m_noRowsOrCols = majorDim;
+ m_radioButtonCycle = NULL;
+
+ if (majorDim==0)
+ m_majorDim = n ;
+ else
+ m_majorDim = majorDim ;
+
+
+ Rect bounds ;
+ Str255 title ;
+
+ MacPreControlCreate( parent , id , wxStripMenuCodes(label) , pos , size ,style, val , name , &bounds , title ) ;
+
+ m_macControl = ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , title , false , 0 , 0 , 1,
+ kControlGroupBoxTextTitleProc , (long) this ) ;
+
+ for (i = 0; i < n; i++)
+ {
+ wxRadioButton *radBtn = new wxRadioButton
+ (
+ this,
+ wxID_ANY,
+ wxStripMenuCodes(choices[i]),
+ wxPoint(5,20*i+10),
+ wxDefaultSize,
+ i == 0 ? wxRB_GROUP : 0
+ );
+ if ( i == 0 )
+ m_radioButtonCycle = radBtn ;
+ // m_radioButtonCycle=radBtn->AddInCycle(m_radioButtonCycle);
+ }
+
+ SetSelection(0);
+ MacPostControlCreate() ;
+
+ return TRUE;
+}
+
+
+//-------------------------------------------------------------------------------------
+// ¥ Enable(bool)
+//-------------------------------------------------------------------------------------
+// Enables or disables the entire radiobox
+
+bool wxRadioBox::Enable(bool enable)
+{
+ int i;
+ wxRadioButton *current;
+
+ if (!wxControl::Enable(enable))
+ return false;
+
+ current = m_radioButtonCycle;
+ for (i = 0; i < m_noItems; i++) {
+ current->Enable(enable);
+ current = current->NextInCycle();
+ }
+ return true;
+}
+
+//-------------------------------------------------------------------------------------
+// ¥ Enable(int, bool)
+//-------------------------------------------------------------------------------------
+// Enables or disables an given button
+
+void wxRadioBox::Enable(int item, bool enable)
+{
+ int i;
+ wxRadioButton *current;
+
+ if ((item < 0) || (item >= m_noItems))
+ return;
+
+ i = 0;
+ current = m_radioButtonCycle;
+ while (i != item) {
+ i++;
+ current = current->NextInCycle();
+ }
+ current->Enable(enable);
+}
+
+//-------------------------------------------------------------------------------------
+// ¥ GetLabel()
+//-------------------------------------------------------------------------------------
+// Returns the radiobox label
+
+wxString wxRadioBox::GetLabel() const
+{
+ return wxControl::GetLabel();
+}
+
+//-------------------------------------------------------------------------------------
+// ¥ GetLabel(int)
+//-------------------------------------------------------------------------------------
+// Returns the label for the given button
+
+wxString wxRadioBox::GetString(int item) const
+{
+ int i;
+ wxRadioButton *current;
+
+ if ((item < 0) || (item >= m_noItems))
+ return wxEmptyString;
+
+ i = 0;
+ current = m_radioButtonCycle;
+ while (i != item) {
+ i++;
+ current = current->NextInCycle();
+ }
+ return current->GetLabel();
+}
+
+//-------------------------------------------------------------------------------------
+// ¥ GetSelection
+//-------------------------------------------------------------------------------------
+// Returns the zero-based position of the selected button
+
+int wxRadioBox::GetSelection() const
+{
+ int i;
+ wxRadioButton *current;
+
+ i=0;
+ current=m_radioButtonCycle;
+ while (!current->GetValue()) {
+ i++;
+ current=current->NextInCycle();
+ }
+
+ return i;
+}
+
+//-------------------------------------------------------------------------------------
+// ¥ Number
+//-------------------------------------------------------------------------------------
+// Returns the number of buttons in the radiobox
+//
+// inline defined
+//
+
+//-------------------------------------------------------------------------------------
+// ¥ SetLabel(const wxString&)
+//-------------------------------------------------------------------------------------
+// Sets the radiobox label
+
+void wxRadioBox::SetLabel(const wxString& label)
+{
+ return wxControl::SetLabel(label);
+}
+
+//-------------------------------------------------------------------------------------
+// ¥ SetLabel(int, const wxString&)
+//-------------------------------------------------------------------------------------
+// Sets the label of a given button
+
+void wxRadioBox::SetString(int item,const wxString& label)
+{
+ int i;
+ wxRadioButton *current;
+
+ if ((item < 0) || (item >= m_noItems))
+ return;
+ i=0;
+ current=m_radioButtonCycle;
+ while (i!=item) {
+ i++;
+ current=current->NextInCycle();
+ }
+ return current->SetLabel(label);
+}
+
+//-------------------------------------------------------------------------------------
+// ¥ SetSelection
+//-------------------------------------------------------------------------------------
+// Sets a button by passing the desired position. This does not cause
+// wxEVT_COMMAND_RADIOBOX_SELECTED event to get emitted
+
+void wxRadioBox::SetSelection(int item)
+{
+ int i;
+ wxRadioButton *current;
+
+ if ((item < 0) || (item >= m_noItems))
+ return;
+ i=0;
+ current=m_radioButtonCycle;
+ while (i!=item) {
+ i++;
+ current=current->NextInCycle();
+ }
+ current->SetValue(true);
+
+}
+
+//-------------------------------------------------------------------------------------
+// ¥ Show(bool)
+//-------------------------------------------------------------------------------------
+// Shows or hides the entire radiobox
+
+bool wxRadioBox::Show(bool show)
+{
+ int i;
+ wxRadioButton *current;
+
+ wxControl::Show(show);
+
+ current=m_radioButtonCycle;
+ for (i=0;i<m_noItems;i++) {
+ current->Show(show);
+ current=current->NextInCycle();
+ }
+ return true;
+}
+
+//-------------------------------------------------------------------------------------
+// ¥ Show(int, bool)
+//-------------------------------------------------------------------------------------
+// Shows or hides the given button
+
+void wxRadioBox::Show(int item, bool show)
+{
+ int i;
+ wxRadioButton *current;
+
+ if ((item < 0) || (item >= m_noItems))
+ return;
+ i=0;
+ current=m_radioButtonCycle;
+ while (i!=item) {
+ i++;
+ current=current->NextInCycle();
+ }
+ current->Show(show);
+}
+
+//-------------------------------------------------------------------------------------
+// ¥ Command
+//-------------------------------------------------------------------------------------
+// Simulates the effect of the user issuing a command to the item
+
+void wxRadioBox::Command (wxCommandEvent & event)
+{
+ SetSelection (event.GetInt());
+ ProcessCommand (event);
+}
+
+//-------------------------------------------------------------------------------------
+// ¥ SetFocus
+//-------------------------------------------------------------------------------------
+// Sets the selected button to receive keyboard input
+
+void wxRadioBox::SetFocus()
+{
+ int i;
+ wxRadioButton *current;
+
+ i=0;
+ current=m_radioButtonCycle;
+ while (!current->GetValue()) {
+ i++;
+ current=current->NextInCycle();
+ }
+ current->SetFocus();
+}
+
+
+//-------------------------------------------------------------------------------------
+// ¥ DoSetSize
+//-------------------------------------------------------------------------------------
+// Simulates the effect of the user issuing a command to the item
+
+#define RADIO_SIZE 20
+
+void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags)
+{
+ int i;
+ wxRadioButton *current;
+
+ // define the position
+
+ int x_current, y_current;
+ int x_offset,y_offset;
+ int widthOld, heightOld;
+ GetSize(&widthOld, &heightOld);
+
+ x_offset = x;
+ y_offset = y;
+ GetPosition(&x_current, &y_current);
+ if ((x == -1) && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
+ x_offset = x_current;
+ if ((y == -1)&& !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
+ y_offset = y_current;
+
+ // define size
+
+ int charWidth,charHeight;
+ int maxWidth,maxHeight;
+ int eachWidth[128],eachHeight[128];
+ int totWidth,totHeight;
+
+ SetFont(GetParent()->GetFont());
+ GetTextExtent(wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), &charWidth, &charHeight);
+ charWidth/=52;
+
+ maxWidth=-1;
+ maxHeight=-1;
+ for (i = 0 ; i < m_noItems; i++)
+ {
+ GetTextExtent(GetString(i), &eachWidth[i], &eachHeight[i]);
+ eachWidth[i] = (int)(eachWidth[i] + RADIO_SIZE);
+ eachHeight[i] = (int)((3*eachHeight[i])/2);
+ if (maxWidth<eachWidth[i]) maxWidth = eachWidth[i];
+ if (maxHeight<eachHeight[i]) maxHeight = eachHeight[i];
+ }
+
+ totHeight = GetRowCount() * (maxHeight + charHeight/2) + charHeight ;
+ totWidth = GetColumnCount() * (maxWidth + charWidth) + charWidth;
+
+ // only change our width/height if asked for
+ if ( width == -1 )
+ {
+ if ( sizeFlags & wxSIZE_AUTO_WIDTH )
+ width = totWidth ;
+ else
+ width = widthOld;
+ }
+
+ if ( height == -1 )
+ {
+ if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
+ height = totHeight ;
+ else
+ height = heightOld;
+ }
+
+ wxControl::DoSetSize(x_offset,y_offset,width,height,wxSIZE_AUTO);
+
+ // arrange radiobuttons
+
+ int x_start,y_start;
+
+
+ x_start = charWidth;
+ y_start = 15 ;
+ if ( UMAGetSystemVersion() >= 0x1030 )
+ {
+ //need to add a few more pixels for the top border on panther
+ y_start = y_start + 5; //how many exactly should this be to meet the HIG?
+ }
+ x_offset = x_start;
+ y_offset = y_start;
+
+ current=m_radioButtonCycle;
+ for ( i = 0 ; i < m_noItems; i++)
+ {
+ if (i&&((i%m_majorDim)==0)) // not to do for the zero button!
+ {
+ if (m_windowStyle & wxRA_VERTICAL)
+ {
+ x_offset += maxWidth + charWidth;
+ y_offset = y_start;
+ }
+ else
+ {
+ x_offset = x_start;
+ y_offset += maxHeight ; /*+ charHeight/2;*/
+ }
+ }
+
+ current->SetSize(x_offset,y_offset,eachWidth[i],eachHeight[i]);
+ current=current->NextInCycle();
+
+ if (m_windowStyle & wxRA_SPECIFY_ROWS)
+ y_offset += maxHeight ; /*+ charHeight/2;*/
+ else
+ x_offset += maxWidth + charWidth;
+ }
+}
+
+wxSize wxRadioBox::DoGetBestSize() const
+{
+ int charWidth, charHeight;
+ int maxWidth, maxHeight;
+ int eachWidth, eachHeight;
+ int totWidth, totHeight;
+
+ wxFont font = GetParent()->GetFont();
+ GetTextExtent(wxT("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"),
+ &charWidth, &charHeight, NULL, NULL, &font);
+ charWidth /= 52;
+
+ maxWidth = -1;
+ maxHeight = -1;
+
+ for (int i = 0 ; i < m_noItems; i++)
+ {
+ GetTextExtent(GetString(i), &eachWidth, &eachHeight);
+ eachWidth = (int)(eachWidth + RADIO_SIZE) ;
+ eachHeight = (int)((3 * eachHeight) / 2);
+ if (maxWidth < eachWidth) maxWidth = eachWidth;
+ if (maxHeight < eachHeight) maxHeight = eachHeight;
+ }
+
+ totHeight = GetRowCount() * (maxHeight + charHeight/2) + charHeight ;
+ totWidth = GetColumnCount() * (maxWidth + charWidth) + charWidth;
+
+ if ( UMAGetSystemVersion() >= 0x1030 )
+ {
+ //need to add a few more pixels for the static boxborder on panther
+ totHeight = totHeight + 10; //how many exactly should this be to meet the HIG?
+ }
+ // handle radio box title as well
+ GetTextExtent(GetTitle(), &eachWidth, NULL);
+ eachWidth = (int)(eachWidth + RADIO_SIZE) + 3 * charWidth ;
+ if (totWidth < eachWidth)
+ totWidth = eachWidth;
+
+ return wxSize(totWidth, totHeight);
+}
+//-------------------------------------------------------------------------------------
+// ¥ GetNumVer
+//-------------------------------------------------------------------------------------
+// return the number of buttons in the vertical direction
+
+int wxRadioBox::GetRowCount() const
+{
+ if ( m_windowStyle & wxRA_SPECIFY_ROWS )
+ {
+ return m_majorDim;
+ }
+ else
+ {
+ return (m_noItems + m_majorDim - 1)/m_majorDim;
+ }
+}
+
+//-------------------------------------------------------------------------------------
+// ¥ GetNumHor
+//-------------------------------------------------------------------------------------
+// return the number of buttons in the horizontal direction
+
+int wxRadioBox::GetColumnCount() const
+{
+ if ( m_windowStyle & wxRA_SPECIFY_ROWS )
+ {
+ return (m_noItems + m_majorDim - 1)/m_majorDim;
+ }
+ else
+ {
+ return m_majorDim;
+ }
+}
+
+
+
+
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: radiobut.cpp
+// Purpose: wxRadioButton
+// Author: AUTHOR
+// Modified by: JS Lair (99/11/15) adding the cyclic groupe notion for radiobox
+// Created: ??/??/98
+// RCS-ID: $Id$
+// Copyright: (c) AUTHOR
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "radiobut.h"
+#endif
+
+#include "wx/defs.h"
+
+#include "wx/radiobut.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxRadioButton, wxControl)
+#endif
+
+#include "wx/mac/uma.h"
+
+bool wxRadioButton::Create(wxWindow *parent, wxWindowID id,
+ const wxString& label,
+ const wxPoint& pos,
+ const wxSize& size, long style,
+ const wxValidator& validator,
+ const wxString& name)
+{
+ if ( !wxControl::Create(parent, id, pos, size, style, validator, name) )
+ return false;
+
+ Rect bounds ;
+ Str255 title ;
+
+ MacPreControlCreate( parent , id , label , pos , size ,style, validator , name , &bounds , title ) ;
+
+ m_macControl = ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , title , false , 0 , 0 , 1,
+ kControlRadioButtonProc , (long) this ) ;
+
+ MacPostControlCreate() ;
+
+ m_cycle = this ;
+
+ if (HasFlag(wxRB_GROUP))
+ {
+ AddInCycle( NULL ) ;
+ }
+ else
+ {
+ /* search backward for last group start */
+ wxRadioButton *chief = (wxRadioButton*) NULL;
+ wxWindowList::Node *node = parent->GetChildren().GetLast();
+ while (node)
+ {
+ wxWindow *child = node->GetData();
+ if (child->IsKindOf( CLASSINFO( wxRadioButton ) ) )
+ {
+ chief = (wxRadioButton*) child;
+ if (child->HasFlag(wxRB_GROUP)) break;
+ }
+ node = node->GetPrevious();
+ }
+ AddInCycle( chief ) ;
+ }
+ return TRUE;
+}
+
+void wxRadioButton::SetValue(bool val)
+{
+ wxRadioButton *cycle;
+ if ( GetControl32BitValue( (ControlHandle) m_macControl ) == val )
+ return ;
+
+ ::SetControl32BitValue( (ControlHandle) m_macControl , val ) ;
+ if (val)
+ {
+ cycle=this->NextInCycle();
+ if (cycle!=NULL) {
+ while (cycle!=this) {
+ cycle->SetValue(false);
+ cycle=cycle->NextInCycle();
+ }
+ }
+ }
+ MacRedrawControl() ;
+}
+
+bool wxRadioButton::GetValue() const
+{
+ return ::GetControl32BitValue( (ControlHandle) m_macControl ) ;
+}
+
+void wxRadioButton::Command (wxCommandEvent & event)
+{
+ SetValue ( (event.GetInt() != 0) );
+ ProcessCommand (event);
+}
+
+void wxRadioButton::MacHandleControlClick( WXWidget control , wxInt16 controlpart , bool WXUNUSED(mouseStillDown))
+{
+ if ( GetValue() )
+ return ;
+
+ wxRadioButton *cycle, *old = NULL ;
+ cycle=this->NextInCycle();
+ if (cycle!=NULL) {
+ while (cycle!=this) {
+ if ( cycle->GetValue() ) {
+ old = cycle ;
+ cycle->SetValue(false);
+ }
+ cycle=cycle->NextInCycle();
+ }
+ }
+
+ SetValue(true) ;
+
+ if ( old ) {
+ wxCommandEvent event(wxEVT_COMMAND_RADIOBUTTON_SELECTED, old->m_windowId );
+ event.SetEventObject(old);
+ event.SetInt( false );
+ old->ProcessCommand(event);
+ }
+ wxCommandEvent event2(wxEVT_COMMAND_RADIOBUTTON_SELECTED, m_windowId );
+ event2.SetEventObject(this);
+ event2.SetInt( true );
+ ProcessCommand(event2);
+}
+
+wxRadioButton *wxRadioButton::AddInCycle(wxRadioButton *cycle)
+{
+ wxRadioButton *next,*current;
+
+ if (cycle==NULL) {
+ m_cycle=this;
+ return(this);
+ }
+ else {
+ current=cycle;
+ while ((next=current->m_cycle)!=cycle)
+ current=current->m_cycle;
+ m_cycle=cycle;
+ current->m_cycle=this;
+ return(cycle);
+ }
+}
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// File: region.cpp
+// Purpose: Region class
+// Author: Stefan Csomor
+// Created: Fri Oct 24 10:46:34 MET 1997
+// RCS-ID: $Id$
+// Copyright: (c) 1997 Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "region.h"
+#endif
+
+#include "wx/region.h"
+#include "wx/gdicmn.h"
+#include "wx/mac/uma.h"
+
+#if !USE_SHARED_LIBRARY
+ IMPLEMENT_DYNAMIC_CLASS(wxRegion, wxGDIObject)
+ IMPLEMENT_DYNAMIC_CLASS(wxRegionIterator, wxObject)
+#endif
+
+//-----------------------------------------------------------------------------
+// wxRegionRefData implementation
+//-----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxRegionRefData : public wxGDIRefData {
+public:
+ wxRegionRefData()
+ {
+ m_macRgn = NewRgn() ;
+ }
+
+ wxRegionRefData(const wxRegionRefData& data)
+ : wxGDIRefData()
+ {
+ m_macRgn = NewRgn() ;
+ CopyRgn( data.m_macRgn , m_macRgn ) ;
+ }
+
+ ~wxRegionRefData()
+ {
+ DisposeRgn( m_macRgn ) ;
+ }
+ RgnHandle m_macRgn ;
+};
+
+#define M_REGION (((wxRegionRefData*)m_refData)->m_macRgn)
+#define OTHER_M_REGION(a) (((wxRegionRefData*)(a.m_refData))->m_macRgn)
+
+//-----------------------------------------------------------------------------
+// wxRegion
+//-----------------------------------------------------------------------------
+
+/*!
+ * Create an empty region.
+ */
+wxRegion::wxRegion()
+{
+ m_refData = new wxRegionRefData;
+}
+
+wxRegion::wxRegion(WXHRGN hRegion )
+{
+ m_refData = new wxRegionRefData;
+ CopyRgn( (RgnHandle) hRegion , (RgnHandle) M_REGION ) ;
+}
+
+wxRegion::wxRegion(long x, long y, long w, long h)
+{
+ m_refData = new wxRegionRefData;
+ SetRectRgn( (RgnHandle) M_REGION , x , y , x+w , y+h ) ;
+}
+
+wxRegion::wxRegion(const wxPoint& topLeft, const wxPoint& bottomRight)
+{
+ m_refData = new wxRegionRefData;
+ SetRectRgn( (RgnHandle) M_REGION , topLeft.x , topLeft.y , bottomRight.x , bottomRight.y ) ;
+}
+
+wxRegion::wxRegion(const wxRect& rect)
+{
+ m_refData = new wxRegionRefData;
+ SetRectRgn( (RgnHandle) M_REGION , rect.x , rect.y , rect.x+rect.width , rect.y+rect.height ) ;
+}
+
+/*!
+ * Destroy the region.
+ */
+wxRegion::~wxRegion()
+{
+ // m_refData unrefed in ~wxObject
+}
+
+//-----------------------------------------------------------------------------
+//# Modify region
+//-----------------------------------------------------------------------------
+
+//! Clear current region
+void wxRegion::Clear()
+{
+ UnRef();
+}
+
+//! Combine rectangle (x, y, w, h) with this.
+bool wxRegion::Combine(long x, long y, long width, long height, wxRegionOp op)
+{
+ // Don't change shared data
+ if (!m_refData)
+ {
+ m_refData = new wxRegionRefData();
+ }
+ else if (m_refData->GetRefCount() > 1)
+ {
+ wxRegionRefData* ref = (wxRegionRefData*)m_refData;
+ UnRef();
+ m_refData = new wxRegionRefData(*ref);
+ }
+ RgnHandle rgn = NewRgn() ;
+ SetRectRgn( rgn , x , y, x+width,y + height ) ;
+
+ switch (op)
+ {
+ case wxRGN_AND:
+ SectRgn( M_REGION , rgn , M_REGION ) ;
+ break ;
+ case wxRGN_OR:
+ UnionRgn( M_REGION , rgn , M_REGION ) ;
+ break ;
+ case wxRGN_XOR:
+ XorRgn( M_REGION , rgn , M_REGION ) ;
+ break ;
+ case wxRGN_DIFF:
+ DiffRgn( M_REGION , rgn , M_REGION ) ;
+ break ;
+ case wxRGN_COPY:
+ default:
+ CopyRgn( rgn ,M_REGION ) ;
+ break ;
+ }
+
+ DisposeRgn( rgn ) ;
+
+ return TRUE;
+}
+
+//! Union /e region with this.
+bool wxRegion::Combine(const wxRegion& region, wxRegionOp op)
+{
+ if (region.Empty())
+ return FALSE;
+
+ // Don't change shared data
+ if (!m_refData) {
+ m_refData = new wxRegionRefData();
+ }
+ else if (m_refData->GetRefCount() > 1)
+ {
+ wxRegionRefData* ref = (wxRegionRefData*)m_refData;
+ UnRef();
+ m_refData = new wxRegionRefData(*ref);
+ }
+
+ switch (op)
+ {
+ case wxRGN_AND:
+ SectRgn( M_REGION , OTHER_M_REGION(region) , M_REGION ) ;
+ break ;
+ case wxRGN_OR:
+ UnionRgn( M_REGION , OTHER_M_REGION(region) , M_REGION ) ;
+ break ;
+ case wxRGN_XOR:
+ XorRgn( M_REGION , OTHER_M_REGION(region) , M_REGION ) ;
+ break ;
+ case wxRGN_DIFF:
+ DiffRgn( M_REGION , OTHER_M_REGION(region) , M_REGION ) ;
+ break ;
+ case wxRGN_COPY:
+ default:
+ CopyRgn( OTHER_M_REGION(region) ,M_REGION ) ;
+ break ;
+ }
+
+ return TRUE;
+}
+
+bool wxRegion::Combine(const wxRect& rect, wxRegionOp op)
+{
+ return Combine(rect.GetLeft(), rect.GetTop(), rect.GetWidth(), rect.GetHeight(), op);
+}
+
+//-----------------------------------------------------------------------------
+//# Information on region
+//-----------------------------------------------------------------------------
+
+// Outer bounds of region
+void wxRegion::GetBox(wxCoord& x, wxCoord& y, wxCoord& w, wxCoord& h) const
+{
+ if (m_refData)
+ {
+ Rect box ;
+ GetRegionBounds( M_REGION , &box ) ;
+ x = box.left ;
+ y = box.top ;
+ w = box.right - box.left ;
+ h = box.bottom - box.top ;
+ }
+ else
+ {
+ x = y = w = h = 0;
+ }
+}
+
+wxRect wxRegion::GetBox() const
+{
+ wxCoord x, y, w, h;
+ GetBox(x, y, w, h);
+ return wxRect(x, y, w, h);
+}
+
+// Is region empty?
+bool wxRegion::Empty() const
+{
+ return EmptyRgn( M_REGION ) ;
+}
+
+const WXHRGN wxRegion::GetWXHRGN() const
+{
+ return M_REGION ;
+}
+
+//-----------------------------------------------------------------------------
+//# Tests
+//-----------------------------------------------------------------------------
+
+// Does the region contain the point (x,y)?
+wxRegionContain wxRegion::Contains(long x, long y) const
+{
+ if (!m_refData)
+ return wxOutRegion;
+
+ // TODO. Return wxInRegion if within region.
+ if (0)
+ return wxInRegion;
+ return wxOutRegion;
+}
+
+// Does the region contain the point pt?
+wxRegionContain wxRegion::Contains(const wxPoint& pt) const
+{
+ if (!m_refData)
+ return wxOutRegion;
+
+ Point p = { pt.y , pt.x } ;
+ if (PtInRgn( p , M_REGION ) )
+ return wxInRegion;
+
+ return wxOutRegion;
+}
+
+// Does the region contain the rectangle (x, y, w, h)?
+wxRegionContain wxRegion::Contains(long x, long y, long w, long h) const
+{
+ if (!m_refData)
+ return wxOutRegion;
+
+ Rect rect = { y , x , y + h , x + w } ;
+ if (RectInRgn( &rect , M_REGION ) )
+ return wxInRegion;
+ else
+ return wxOutRegion;
+}
+
+// Does the region contain the rectangle rect
+wxRegionContain wxRegion::Contains(const wxRect& rect) const
+{
+ if (!m_refData)
+ return wxOutRegion;
+
+ long x, y, w, h;
+ x = rect.x;
+ y = rect.y;
+ w = rect.GetWidth();
+ h = rect.GetHeight();
+ return Contains(x, y, w, h);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// //
+// wxRegionIterator //
+// //
+///////////////////////////////////////////////////////////////////////////////
+
+/*!
+ * Initialize empty iterator
+ */
+wxRegionIterator::wxRegionIterator()
+ : m_current(0), m_numRects(0), m_rects(NULL)
+{
+}
+
+wxRegionIterator::~wxRegionIterator()
+{
+ if (m_rects) {
+ delete[] m_rects;
+ m_rects = NULL;
+ }
+}
+
+wxRegionIterator::wxRegionIterator(const wxRegionIterator& iterator)
+ : wxObject()
+ , m_current(iterator.m_current)
+ , m_numRects(0)
+ , m_rects(NULL)
+{
+ SetRects(iterator.m_numRects, iterator.m_rects);
+}
+
+wxRegionIterator& wxRegionIterator::operator=(const wxRegionIterator& iterator)
+{
+ m_current = iterator.m_current;
+ SetRects(iterator.m_numRects, iterator.m_rects);
+ return *this;
+}
+
+/*!
+ * Set iterator rects for region
+ */
+void wxRegionIterator::SetRects(long numRects, wxRect *rects)
+{
+ if (m_rects) {
+ delete[] m_rects;
+ m_rects = NULL;
+ }
+ if (rects)
+ {
+ int i;
+ m_rects = new wxRect[numRects];
+ for (i = 0; i < numRects; i++)
+ m_rects[i] = rects[i];
+ }
+ m_numRects = numRects;
+}
+
+/*!
+ * Initialize iterator for region
+ */
+wxRegionIterator::wxRegionIterator(const wxRegion& region)
+{
+ m_rects = NULL;
+
+ Reset(region);
+}
+
+/*!
+ * Reset iterator for a new /e region.
+ */
+void wxRegionIterator::Reset(const wxRegion& region)
+{
+ m_current = 0;
+ m_region = region;
+
+ if (m_rects) {
+ delete[] m_rects;
+ m_rects = NULL;
+ }
+
+ if (m_region.Empty())
+ m_numRects = 0;
+ else
+ {
+ // we cannot dissolve it into rects on mac
+ m_rects = new wxRect[1];
+ Rect rect ;
+ GetRegionBounds( OTHER_M_REGION( region ) , &rect ) ;
+ m_rects[0].x = rect.left;
+ m_rects[0].y = rect.top;
+ m_rects[0].width = rect.right - rect.left;
+ m_rects[0].height = rect.bottom - rect.top;
+ m_numRects = 1;
+ }
+}
+
+/*!
+ * Increment iterator. The rectangle returned is the one after the
+ * incrementation.
+ */
+wxRegionIterator& wxRegionIterator::operator ++ ()
+{
+ if (m_current < m_numRects)
+ ++m_current;
+ return *this;
+}
+
+/*!
+ * Increment iterator. The rectangle returned is the one before the
+ * incrementation.
+ */
+wxRegionIterator wxRegionIterator::operator ++ (int)
+{
+ wxRegionIterator previous(*this);
+
+ if (m_current < m_numRects)
+ ++m_current;
+
+ return previous;
+}
+
+long wxRegionIterator::GetX() const
+{
+ if (m_current < m_numRects)
+ return m_rects[m_current].x;
+ return 0;
+}
+
+long wxRegionIterator::GetY() const
+{
+ if (m_current < m_numRects)
+ return m_rects[m_current].y;
+ return 0;
+}
+
+long wxRegionIterator::GetW() const
+{
+ if (m_current < m_numRects)
+ return m_rects[m_current].width ;
+ return 0;
+}
+
+long wxRegionIterator::GetH() const
+{
+ if (m_current < m_numRects)
+ return m_rects[m_current].height;
+ return 0;
+}
+
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Name: mac/renderer.cpp
+// Purpose: implementation of wxRendererNative for Mac
+// Author: Vadim Zeitlin
+// Modified by:
+// Created: 20.07.2003
+// RCS-ID: $Id$
+// Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
+// License: wxWindows license
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+// for compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+ #include "wx/string.h"
+ #include "wx/dc.h"
+ #include "wx/bitmap.h"
+ #include "wx/settings.h"
+#endif //WX_PRECOMP
+
+#include "wx/renderer.h"
+
+// ----------------------------------------------------------------------------
+// wxRendererMac: our wxRendererNative implementation
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxRendererMac : public wxDelegateRendererNative
+{
+public:
+ // draw the header control button (used by wxListCtrl)
+ virtual void DrawHeaderButton(wxWindow *win,
+ wxDC& dc,
+ const wxRect& rect,
+ int flags = 0);
+
+ // draw the expanded/collapsed icon for a tree control item
+ virtual void DrawTreeItemButton(wxWindow *win,
+ wxDC& dc,
+ const wxRect& rect,
+ int flags = 0);
+
+ // draw a (vertical) sash
+ virtual void DrawSplitterSash(wxWindow *win,
+ wxDC& dc,
+ const wxSize& size,
+ wxCoord position,
+ wxOrientation orient,
+ int flags = 0);
+
+private:
+ // the tree buttons
+ wxBitmap m_bmpTreeExpanded,
+ m_bmpTreeCollapsed;
+};
+
+// ----------------------------------------------------------------------------
+// Aqua arrows
+// ----------------------------------------------------------------------------
+
+/* XPM */
+static const char *aqua_arrow_right_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"13 11 4 1",
+" c None",
+"b c #C0C0C0",
+"c c #707070",
+"d c #A0A0A0",
+/* pixels */
+" b ",
+" ddb ",
+" cccdb ",
+" cccccd ",
+" ccccccdb ",
+" ccccccccd",
+" ccccccdb ",
+" cccccb ",
+" cccdb ",
+" ddb ",
+" b "
+};
+
+/* XPM */
+static const char *aqua_arrow_down_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"13 11 4 1",
+" c None",
+"b c #C0C0C0",
+"c c #707070",
+"d c #A0A0A0",
+/* pixels */
+" ",
+" ",
+" bdcccccccdb ",
+" dcccccccd ",
+" bcccccccb ",
+" dcccccd ",
+" bcccccb ",
+" bcccd ",
+" dcd ",
+" bcb ",
+" d "
+};
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+/* static */
+wxRendererNative& wxRendererNative::GetDefault()
+{
+ static wxRendererMac s_rendererMac;
+
+ return s_rendererMac;
+}
+
+void
+wxRendererMac::DrawHeaderButton(wxWindow *win,
+ wxDC& dc,
+ const wxRect& rect,
+ int WXUNUSED(flags))
+{
+ const int CORNER = 1;
+
+ const wxCoord x = rect.x-1,
+ y = rect.y-1,
+ w = rect.width,
+ h = rect.height;
+
+ int major,minor;
+ wxGetOsVersion( &major, &minor );
+
+ dc.SetBrush( *wxTRANSPARENT_BRUSH );
+
+ if (major >= 10)
+ {
+ dc.SetPen( wxPen( wxColour( 0xC5 , 0xC5 , 0xC5 ) , 1 , wxSOLID ) );
+ dc.DrawRectangle( x, y+CORNER, 1, h-CORNER ); // left
+ // The right border is overdrawn by the left border of the right neighbouring
+ // header (to maintain a proper single pixel border). Except for the
+ // rightmost header of the listctrl.
+ dc.DrawRectangle( x+w+(CORNER*2), y+CORNER, 1, h-CORNER ); // right
+ dc.SetPen( wxPen( wxColour( 0xB1 , 0xB1 , 0xB1 ) , 1 , wxSOLID ) );
+ dc.DrawRectangle( x, y+h, w+(CORNER*3), 1 ); // bottom
+ dc.DrawRectangle( x, y, w+(CORNER*3), 1 ); // top
+
+ // Do a fill of the interior for background:
+ dc.SetPen( wxPen( wxColour( 0xF6 , 0xF6 , 0xF6 ) , 1 , wxSOLID ) );
+ dc.DrawRectangle( x+CORNER, y+CORNER, w+CORNER, h-CORNER );
+
+ // Do the gradient fill:
+ static int grayValues[] =
+ {
+ 0xF6, 0xF2, 0xEF, 0xED, 0xED, 0xEB, 0xEA, 0xEA, 0xE8,
+ 0xE8, 0xE2, 0xE5, 0xE8, 0xEB, 0xEF, 0xF2, 0xFD
+ };
+ int i;
+ for (i=0; i < h && i < (int)WXSIZEOF(grayValues); i++)
+ {
+ dc.SetPen( wxPen( wxColour( grayValues[i] , grayValues[i] , grayValues[i] ),
+ 1 , wxSOLID ) );
+ dc.DrawRectangle( x+CORNER, y+CORNER+i, w+CORNER, 1 );
+ }
+ }
+ else
+ {
+ dc.SetPen( wxPen( wxSystemSettings::GetColour( wxSYS_COLOUR_BTNSHADOW ) , 1 , wxSOLID ) );
+ dc.DrawLine( x+w-CORNER+1, y, x+w, y+h ); // right (outer)
+ dc.DrawRectangle( x, y+h, w+1, 1 ); // bottom (outer)
+
+ wxPen pen( wxColour( 0x88 , 0x88 , 0x88 ), 1, wxSOLID );
+
+ dc.SetPen( pen );
+ dc.DrawLine( x+w-CORNER, y, x+w-1, y+h ); // right (inner)
+ dc.DrawRectangle( x+1, y+h-1, w-2, 1 ); // bottom (inner)
+
+ dc.SetPen( *wxWHITE_PEN );
+ dc.DrawRectangle( x, y, w-CORNER+1, 1 ); // top (outer)
+ dc.DrawRectangle( x, y, 1, h ); // left (outer)
+ dc.DrawLine( x, y+h-1, x+1, y+h-1 );
+ dc.DrawLine( x+w-1, y, x+w-1, y+1 );
+ }
+}
+
+void
+wxRendererMac::DrawTreeItemButton(wxWindow *win,
+ wxDC& dc,
+ const wxRect& rect,
+ int flags)
+{
+ // init the buttons on demand
+ if ( !m_bmpTreeExpanded.Ok() )
+ {
+ m_bmpTreeExpanded = wxBitmap(aqua_arrow_down_xpm);
+ m_bmpTreeCollapsed = wxBitmap(aqua_arrow_right_xpm);
+ }
+
+ // draw them
+
+ // VZ: this is the old code from treectlg.cpp which apparently doesn't work
+ // but I kept it here just in case it is needed -- if not, please
+ // remove it
+#if 0 // def __WXMAC__
+ wxMacPortSetter helper(&dc) ;
+ wxMacWindowClipper clipper(this) ;
+ wxDC::MacSetupBackgroundForCurrentPort( MacGetBackgroundBrush() ) ;
+
+ int loc_x = x - 5 ;
+ int loc_y = y_mid - 6 ;
+ MacWindowToRootWindow( & loc_x , & loc_y ) ;
+ Rect bounds = { loc_y , loc_x , loc_y + 18 , loc_x + 12 } ;
+ ThemeButtonDrawInfo info = { kThemeStateActive , item->IsExpanded() ? kThemeDisclosureDown : kThemeDisclosureRight ,
+ kThemeAdornmentNone };
+ DrawThemeButton( &bounds, kThemeDisclosureButton ,
+ &info , NULL , NULL , NULL , NULL ) ;
+#else // 1
+ dc.DrawBitmap(flags & wxCONTROL_EXPANDED ? m_bmpTreeExpanded
+ : m_bmpTreeCollapsed,
+ rect.x, rect.y, true /* use mask */);
+#endif // 0/1
+}
+
+void
+wxRendererMac::DrawSplitterSash(wxWindow *win,
+ wxDC& dc,
+ const wxSize& size,
+ wxCoord position,
+ wxOrientation orient,
+ int WXUNUSED(flags))
+{
+ // VZ: we have to somehow determine if we're drawing a normal sash or
+ // a brushed metal one as they look quite differently... this is
+ // completely bogus anyhow, of course (TODO)
+
+#if 0
+ dc.SetPen(*wxLIGHT_GREY_PEN);
+ dc.SetBrush(*wxWHITE_BRUSH);
+ if ( orient == wxVERTICAL )
+ dc.DrawRectangle(position, 0, 7, size.y);
+ else
+ dc.DrawRectangle(0, position, size.x, 7);
+#else
+ // Do the gradient fill:
+ static int grayValues[] =
+ {
+ 0xA0, 0xF6, 0xED, 0xE4, 0xE2, 0xD0, 0xA0
+ };
+ dc.SetBrush( *wxTRANSPARENT_BRUSH );
+ if ( orient == wxVERTICAL )
+ {
+ int i;
+ for (i=0; i < (int)WXSIZEOF(grayValues); i++)
+ {
+ dc.SetPen( wxPen( wxColour( grayValues[i] , grayValues[i] , grayValues[i] ),
+ 1 , wxSOLID ) );
+ dc.DrawRectangle( position+i, 0, 1, size.y );
+ }
+ }
+ else
+ {
+ int i;
+ for (i=0; i < (int)WXSIZEOF(grayValues); i++)
+ {
+ dc.SetPen( wxPen( wxColour( grayValues[i] , grayValues[i] , grayValues[i] ),
+ 1 , wxSOLID ) );
+ dc.DrawRectangle( 0, position+i, size.x, 1 );
+ }
+ }
+#endif
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: scrolbar.cpp
+// Purpose: wxScrollBar
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "scrolbar.h"
+#endif
+
+#include "wx/defs.h"
+
+#ifndef WX_PRECOMP
+ #include "wx/intl.h"
+ #include "wx/log.h"
+#endif // WX_PRECOMP
+
+#include "wx/scrolbar.h"
+#include "wx/mac/uma.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxScrollBar, wxControl)
+
+BEGIN_EVENT_TABLE(wxScrollBar, wxControl)
+END_EVENT_TABLE()
+
+#endif
+
+extern ControlActionUPP wxMacLiveScrollbarActionUPP ;
+
+// Scrollbar
+bool wxScrollBar::Create(wxWindow *parent, wxWindowID id,
+ const wxPoint& pos,
+ const wxSize& size, long style,
+ const wxValidator& validator,
+ const wxString& name)
+{
+ if ( !wxControl::Create(parent, id, pos, size, style, validator, name) )
+ return FALSE;
+
+ Rect bounds ;
+ Str255 title ;
+
+ MacPreControlCreate( parent , id , wxEmptyString , pos , size ,style, validator , name , &bounds , title ) ;
+
+ m_macControl = ::NewControl(MAC_WXHWND(parent->MacGetRootWindow()) ,
+ &bounds , title , false , 0 , 0 , 100,
+ kControlScrollBarLiveProc , (long) this) ;
+
+ wxASSERT_MSG( (ControlHandle) m_macControl != NULL , wxT("No valid mac control") ) ;
+
+ ::SetControlAction( (ControlHandle) m_macControl , wxMacLiveScrollbarActionUPP ) ;
+
+ MacPostControlCreate() ;
+
+ return TRUE;
+}
+
+wxScrollBar::~wxScrollBar()
+{
+}
+
+void wxScrollBar::SetThumbPosition(int viewStart)
+{
+ ::SetControl32BitValue( (ControlHandle) m_macControl , viewStart ) ;
+}
+
+int wxScrollBar::GetThumbPosition() const
+{
+ return ::GetControl32BitValue( (ControlHandle) m_macControl ) ;
+}
+
+void wxScrollBar::SetScrollbar(int position, int thumbSize, int range, int pageSize,
+ bool refresh)
+{
+ m_pageSize = pageSize;
+ m_viewSize = thumbSize;
+ m_objectSize = range;
+
+ int range1 = wxMax((m_objectSize - m_viewSize), 0) ;
+
+ SetControl32BitMaximum( (ControlHandle) m_macControl , range1 ) ;
+ SetControl32BitMinimum( (ControlHandle) m_macControl , 0 ) ;
+ SetControl32BitValue( (ControlHandle) m_macControl , position ) ;
+
+ if ( UMAGetAppearanceVersion() >= 0x0110 )
+ {
+ if ( SetControlViewSize != (void*) kUnresolvedCFragSymbolAddress )
+ {
+ SetControlViewSize( (ControlHandle) m_macControl , m_viewSize ) ;
+ }
+ }
+ if ( refresh )
+ MacRedrawControl() ;
+}
+
+
+void wxScrollBar::Command(wxCommandEvent& event)
+{
+ SetThumbPosition(event.m_commandInt);
+ ProcessCommand(event);
+}
+
+void wxScrollBar::MacHandleControlClick( WXWidget control , wxInt16 controlpart , bool mouseStillDown )
+{
+ if ( (ControlHandle) m_macControl == NULL )
+ return ;
+
+ int position = GetControl32BitValue( (ControlHandle) m_macControl) ;
+ int minPos = GetControl32BitMinimum( (ControlHandle) m_macControl) ;
+ int maxPos = GetControl32BitMaximum( (ControlHandle) m_macControl) ;
+
+ wxEventType scrollEvent = wxEVT_NULL;
+ int nScrollInc = 0;
+
+ // all events have already been reported during mouse down, except for THUMBRELEASE
+ if ( !mouseStillDown && controlpart !=kControlIndicatorPart )
+ return ;
+
+ switch( controlpart )
+ {
+ case kControlUpButtonPart :
+ nScrollInc = -1;
+ scrollEvent = wxEVT_SCROLL_LINEUP;
+ break ;
+ case kControlDownButtonPart :
+ nScrollInc = 1;
+ scrollEvent = wxEVT_SCROLL_LINEDOWN;
+ break ;
+ case kControlPageUpPart :
+ nScrollInc = -m_pageSize;
+ scrollEvent = wxEVT_SCROLL_PAGEUP;
+ break ;
+ case kControlPageDownPart :
+ nScrollInc = m_pageSize;
+ scrollEvent = wxEVT_SCROLL_PAGEDOWN;
+ break ;
+ case kControlIndicatorPart :
+ nScrollInc = 0 ;
+ if ( mouseStillDown )
+ scrollEvent = wxEVT_SCROLL_THUMBTRACK;
+ else
+ scrollEvent = wxEVT_SCROLL_THUMBRELEASE;
+ break ;
+ default :
+ wxFAIL_MSG(wxT("illegal scrollbar selector"));
+ break ;
+ }
+
+ int new_pos = position + nScrollInc;
+
+ if (new_pos < minPos)
+ new_pos = minPos;
+ if (new_pos > maxPos)
+ new_pos = maxPos;
+ if ( nScrollInc )
+ SetThumbPosition(new_pos);
+
+ wxScrollEvent event(scrollEvent, m_windowId);
+ if ( m_windowStyle & wxHORIZONTAL )
+ {
+ event.SetOrientation( wxHORIZONTAL ) ;
+ }
+ else
+ {
+ event.SetOrientation( wxVERTICAL ) ;
+ }
+ event.SetPosition(new_pos);
+ event.SetEventObject( this );
+ wxWindow* window = GetParent() ;
+ if (window && window->MacIsWindowScrollbar(this) )
+ {
+ // this is hardcoded
+ window->MacOnScroll(event);
+ }
+ else
+ GetEventHandler()->ProcessEvent(event);
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: settings.cpp
+// Purpose: wxSettings
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "settings.h"
+#endif
+
+#include "wx/settings.h"
+#include "wx/gdicmn.h"
+#include "wx/utils.h"
+
+#include "wx/mac/uma.h"
+
+// ----------------------------------------------------------------------------
+// wxSystemSettingsNative
+// ----------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------
+// colours
+// ----------------------------------------------------------------------------
+
+wxColour wxSystemSettingsNative::GetColour(wxSystemColour index)
+{
+ int major,minor;
+ wxGetOsVersion( &major, &minor );
+
+ switch( index )
+ {
+ case wxSYS_COLOUR_SCROLLBAR :
+ case wxSYS_COLOUR_BACKGROUND:
+ case wxSYS_COLOUR_ACTIVECAPTION:
+ case wxSYS_COLOUR_INACTIVECAPTION:
+ case wxSYS_COLOUR_MENU:
+ case wxSYS_COLOUR_WINDOW:
+ case wxSYS_COLOUR_WINDOWFRAME:
+ case wxSYS_COLOUR_ACTIVEBORDER:
+ case wxSYS_COLOUR_INACTIVEBORDER:
+ case wxSYS_COLOUR_BTNFACE:
+ case wxSYS_COLOUR_MENUBAR:
+ return wxColor( 0xDD , 0xDD , 0xDD ) ;
+ break ;
+
+ case wxSYS_COLOUR_LISTBOX :
+ {
+ if (major >= 10)
+ return *wxWHITE ;
+ else
+ return wxColor( 0xEE , 0xEE , 0xEE ) ;
+ break ;
+ }
+ case wxSYS_COLOUR_BTNSHADOW:
+ if (major >= 10)
+ return wxColor( 0xBE , 0xBE , 0xBE ) ;
+ else
+ return wxColor( 0x44 , 0x44 , 0x44 ) ;
+ break ;
+
+ case wxSYS_COLOUR_BTNTEXT:
+ case wxSYS_COLOUR_MENUTEXT:
+ case wxSYS_COLOUR_WINDOWTEXT:
+ case wxSYS_COLOUR_CAPTIONTEXT:
+ case wxSYS_COLOUR_INFOTEXT:
+ case wxSYS_COLOUR_INACTIVECAPTIONTEXT:
+ return *wxBLACK;
+ break ;
+ case wxSYS_COLOUR_HIGHLIGHT:
+ {
+ RGBColor hilite ;
+ LMGetHiliteRGB(&hilite) ;
+ return wxColor( hilite.red >> 8 , hilite.green >> 8 , hilite.blue >> 8 ) ;
+ }
+ break ;
+ case wxSYS_COLOUR_BTNHIGHLIGHT:
+ case wxSYS_COLOUR_GRAYTEXT:
+ return wxColor( 0xCC , 0xCC , 0xCC ) ;
+ break ;
+
+ case wxSYS_COLOUR_3DDKSHADOW:
+ return wxColor( 0x44 , 0x44 , 0x44 ) ;
+ break ;
+ case wxSYS_COLOUR_3DLIGHT:
+ return wxColor( 0xCC , 0xCC , 0xCC ) ;
+ break ;
+ case wxSYS_COLOUR_HIGHLIGHTTEXT :
+ {
+ RGBColor hilite ;
+ LMGetHiliteRGB(&hilite) ;
+ if ( ( hilite.red + hilite.green + hilite.blue ) == 0 )
+ return *wxWHITE ;
+ else
+ return *wxBLACK ;
+ }
+ break ;
+ case wxSYS_COLOUR_INFOBK :
+ case wxSYS_COLOUR_APPWORKSPACE:
+ return *wxWHITE ;
+ break ;
+
+ case wxSYS_COLOUR_HOTLIGHT:
+ case wxSYS_COLOUR_GRADIENTACTIVECAPTION:
+ case wxSYS_COLOUR_GRADIENTINACTIVECAPTION:
+ case wxSYS_COLOUR_MENUHILIGHT:
+ // TODO
+ return *wxBLACK;
+
+ case wxSYS_COLOUR_MAX:
+ wxFAIL_MSG( _T("unknown system colour index") );
+ break ;
+ }
+ return *wxWHITE;
+}
+
+// ----------------------------------------------------------------------------
+// fonts
+// ----------------------------------------------------------------------------
+
+wxFont wxSystemSettingsNative::GetFont(wxSystemFont index)
+{
+ switch (index)
+ {
+ case wxSYS_ANSI_VAR_FONT :
+ case wxSYS_SYSTEM_FONT :
+ case wxSYS_DEVICE_DEFAULT_FONT :
+ case wxSYS_DEFAULT_GUI_FONT :
+ {
+ return *wxSMALL_FONT ;
+ } ;
+ break ;
+ case wxSYS_OEM_FIXED_FONT :
+ case wxSYS_ANSI_FIXED_FONT :
+ case wxSYS_SYSTEM_FIXED_FONT :
+ default :
+ {
+ return *wxNORMAL_FONT ;
+ } ;
+ break ;
+
+ }
+ return *wxNORMAL_FONT;
+}
+
+// ----------------------------------------------------------------------------
+// system metrics/features
+// ----------------------------------------------------------------------------
+
+// Get a system metric, e.g. scrollbar size
+int wxSystemSettingsNative::GetMetric(wxSystemMetric index)
+{
+ int value;
+
+ switch ( index)
+ {
+ case wxSYS_MOUSE_BUTTONS:
+ // we emulate a two button mouse (ctrl + click = right button )
+ return 2;
+ case wxSYS_BORDER_X:
+ // TODO
+ return 0;
+ case wxSYS_BORDER_Y:
+ // TODO
+ return 0;
+ case wxSYS_CURSOR_X:
+ // TODO
+ return 0;
+ case wxSYS_CURSOR_Y:
+ // TODO
+ return 0;
+ case wxSYS_DCLICK_X:
+ // TODO
+ return 0;
+ case wxSYS_DCLICK_Y:
+ // TODO
+ return 0;
+ case wxSYS_DRAG_X:
+ // TODO
+ return 0;
+ case wxSYS_DRAG_Y:
+ // TODO
+ return 0;
+ case wxSYS_EDGE_X:
+ // TODO
+ return 0;
+ case wxSYS_EDGE_Y:
+ // TODO
+ return 0;
+ case wxSYS_HSCROLL_ARROW_X:
+ return 16;
+ case wxSYS_HSCROLL_ARROW_Y:
+ return 16;
+ case wxSYS_HTHUMB_X:
+ return 16;
+ case wxSYS_ICON_X:
+ // TODO
+ return 0;
+ case wxSYS_ICON_Y:
+ // TODO
+ return 0;
+ case wxSYS_ICONSPACING_X:
+ // TODO
+ return 0;
+ case wxSYS_ICONSPACING_Y:
+ // TODO
+ return 0;
+ case wxSYS_WINDOWMIN_X:
+ // TODO
+ return 0;
+ case wxSYS_WINDOWMIN_Y:
+ // TODO
+ return 0;
+ case wxSYS_SCREEN_X:
+ wxDisplaySize(&value, NULL);
+ return value;
+ case wxSYS_SCREEN_Y:
+ wxDisplaySize(NULL, &value);
+ return value;
+ case wxSYS_FRAMESIZE_X:
+ // TODO
+ return 0;
+ case wxSYS_FRAMESIZE_Y:
+ // TODO
+ return 0;
+ case wxSYS_SMALLICON_X:
+ // TODO
+ return 0;
+ case wxSYS_SMALLICON_Y:
+ // TODO
+ return 0;
+ case wxSYS_HSCROLL_Y:
+ return 16;
+ case wxSYS_VSCROLL_X:
+ return 16;
+ case wxSYS_VSCROLL_ARROW_X:
+ return 16;
+ case wxSYS_VSCROLL_ARROW_Y:
+ return 16;
+ case wxSYS_VTHUMB_Y:
+ return 16;
+ case wxSYS_CAPTION_Y:
+ // TODO
+ return 0;
+ case wxSYS_MENU_Y:
+ // TODO
+ return 0;
+ case wxSYS_NETWORK_PRESENT:
+ // TODO
+ return 0;
+ case wxSYS_PENWINDOWS_PRESENT:
+ return 0;
+ case wxSYS_SHOW_SOUNDS:
+ // TODO
+ return 0;
+ case wxSYS_SWAP_BUTTONS:
+ return 0;
+ default:
+ return 0;
+ }
+ return 0;
+}
+
+bool wxSystemSettingsNative::HasFeature(wxSystemFeature index)
+{
+ switch (index)
+ {
+ case wxSYS_CAN_ICONIZE_FRAME:
+ case wxSYS_CAN_DRAW_FRAME_DECORATIONS:
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+}
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: slider.cpp
+// Purpose: wxSlider
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "slider.h"
+#endif
+
+#include "wx/slider.h"
+#include "wx/mac/uma.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxSlider, wxControl)
+
+BEGIN_EVENT_TABLE(wxSlider, wxControl)
+END_EVENT_TABLE()
+#endif
+
+ // The dimensions of the different styles of sliders (From Aqua document)
+#define wxSLIDER_DIMENSIONACROSS 15
+#define wxSLIDER_DIMENSIONACROSS_WITHTICKMARKS 24
+#define wxSLIDER_DIMENSIONACROSS_ARROW 18
+
+// Distance between slider and text
+#define wxSLIDER_BORDERTEXT 5
+
+/* NB! The default orientation for a slider is horizontal however if the user specifies
+ * some slider styles but dosen't specify the orientation we have to assume he wants a
+ * horizontal one. Therefore in this file when testing for the sliders orientation
+ * vertical is tested for if this is not set then we use the horizontal one
+ * eg. if(GetWindowStyle() & wxSL_VERTICAL) {} else { horizontal case }>
+ */
+
+ // Slider
+ wxSlider::wxSlider()
+{
+ m_pageSize = 1;
+ m_lineSize = 1;
+ m_rangeMax = 0;
+ m_rangeMin = 0;
+ m_tickFreq = 0;
+}
+
+extern ControlActionUPP wxMacLiveScrollbarActionUPP ;
+
+bool wxSlider::Create(wxWindow *parent, wxWindowID id,
+ int value, int minValue, int maxValue,
+ const wxPoint& pos,
+ const wxSize& size, long style,
+ const wxValidator& validator,
+ const wxString& name)
+{
+ if ( !wxControl::Create(parent, id, pos, size, style, validator, name) )
+ return false;
+
+ Rect bounds ;
+ Str255 title ;
+ SInt16 procID;
+
+ m_macMinimumStatic = NULL ;
+ m_macMaximumStatic = NULL ;
+ m_macValueStatic = NULL ;
+
+
+ m_lineSize = 1;
+ m_tickFreq = 0;
+
+ m_rangeMax = maxValue;
+ m_rangeMin = minValue;
+
+ m_pageSize = (int)((maxValue-minValue)/10);
+
+ MacPreControlCreate( parent, id, wxEmptyString, pos, size, style,
+ validator, name, &bounds, title );
+
+ procID = kControlSliderProc + kControlSliderLiveFeedback;
+ if(style & wxSL_AUTOTICKS) {
+ procID += kControlSliderHasTickMarks;
+ }
+
+
+ m_macControl = ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()), &bounds, title, false,
+ value, minValue, maxValue, procID, (long) this);
+
+ wxASSERT_MSG( (ControlHandle) m_macControl != NULL , wxT("No valid mac control") ) ;
+
+ ::SetControlAction( (ControlHandle) m_macControl , wxMacLiveScrollbarActionUPP ) ;
+
+ if(style & wxSL_LABELS)
+ {
+ m_macMinimumStatic = new wxStaticText( this, -1, wxEmptyString );
+ m_macMaximumStatic = new wxStaticText( this, -1, wxEmptyString );
+ m_macValueStatic = new wxStaticText( this, -1, wxEmptyString );
+ SetRange(minValue, maxValue);
+ SetValue(value);
+ }
+
+ else {
+ m_macMinimumStatic = NULL ;
+ m_macMaximumStatic = NULL ;
+ m_macValueStatic = NULL ;
+ }
+
+ if(style & wxSL_VERTICAL) {
+ SetSizeHints(10, -1, 10, -1); // Forces SetSize to use the proper width
+ }
+ else {
+ SetSizeHints(-1, 10, -1, 10); // Forces SetSize to use the proper height
+ }
+ // NB! SetSizeHints is overloaded by wxSlider and will substitute 10 with the
+ // proper dimensions, it also means other people cannot bugger the slider with
+ // other values
+
+ MacPostControlCreate() ;
+
+ return true;
+}
+
+wxSlider::~wxSlider()
+{
+}
+
+int wxSlider::GetValue() const
+{
+ return GetControl32BitValue( (ControlHandle) m_macControl) ;
+}
+
+void wxSlider::SetValue(int value)
+{
+ wxString valuestring ;
+ valuestring.Printf( wxT("%d") , value ) ;
+ if ( m_macValueStatic )
+ m_macValueStatic->SetLabel( valuestring ) ;
+ SetControl32BitValue( (ControlHandle) m_macControl , value ) ;
+}
+
+void wxSlider::SetRange(int minValue, int maxValue)
+{
+ wxString value;
+
+ m_rangeMin = minValue;
+ m_rangeMax = maxValue;
+
+ SetControl32BitMinimum( (ControlHandle) m_macControl, m_rangeMin);
+ SetControl32BitMaximum( (ControlHandle) m_macControl, m_rangeMax);
+
+ if(m_macMinimumStatic) {
+ value.Printf(wxT("%d"), m_rangeMin);
+ m_macMinimumStatic->SetLabel(value);
+ }
+ if(m_macMaximumStatic) {
+ value.Printf(wxT("%d"), m_rangeMax);
+ m_macMaximumStatic->SetLabel(value);
+ }
+ SetValue(m_rangeMin);
+}
+
+// For trackbars only
+void wxSlider::SetTickFreq(int n, int pos)
+{
+ // TODO
+ m_tickFreq = n;
+}
+
+void wxSlider::SetPageSize(int pageSize)
+{
+ // TODO
+ m_pageSize = pageSize;
+}
+
+int wxSlider::GetPageSize() const
+{
+ return m_pageSize;
+}
+
+void wxSlider::ClearSel()
+{
+ // TODO
+}
+
+void wxSlider::ClearTicks()
+{
+ // TODO
+}
+
+void wxSlider::SetLineSize(int lineSize)
+{
+ m_lineSize = lineSize;
+ // TODO
+}
+
+int wxSlider::GetLineSize() const
+{
+ // TODO
+ return 0;
+}
+
+int wxSlider::GetSelEnd() const
+{
+ // TODO
+ return 0;
+}
+
+int wxSlider::GetSelStart() const
+{
+ // TODO
+ return 0;
+}
+
+void wxSlider::SetSelection(int minPos, int maxPos)
+{
+ // TODO
+}
+
+void wxSlider::SetThumbLength(int len)
+{
+ // TODO
+}
+
+int wxSlider::GetThumbLength() const
+{
+ // TODO
+ return 0;
+}
+
+void wxSlider::SetTick(int tickPos)
+{
+ // TODO
+}
+
+void wxSlider::Command (wxCommandEvent & event)
+{
+ SetValue (event.GetInt());
+ ProcessCommand (event);
+}
+
+void wxSlider::MacHandleControlClick( WXWidget control , wxInt16 controlpart, bool mouseStillDown )
+{
+ SInt16 value = ::GetControl32BitValue( (ControlHandle) m_macControl ) ;
+
+ SetValue( value ) ;
+
+ wxEventType scrollEvent = wxEVT_NULL ;
+
+ if ( mouseStillDown )
+ scrollEvent = wxEVT_SCROLL_THUMBTRACK;
+ else
+ scrollEvent = wxEVT_SCROLL_THUMBRELEASE;
+
+ wxScrollEvent event(scrollEvent, m_windowId);
+ event.SetPosition(value);
+ event.SetEventObject( this );
+ GetEventHandler()->ProcessEvent(event);
+
+ wxCommandEvent cevent( wxEVT_COMMAND_SLIDER_UPDATED, m_windowId );
+ cevent.SetInt( value );
+ cevent.SetEventObject( this );
+
+ GetEventHandler()->ProcessEvent( cevent );
+}
+
+/* This is overloaded in wxSlider so that the proper width/height will always be used
+* for the slider different values would cause redrawing and mouse detection problems */
+void wxSlider::SetSizeHints( int minW, int minH,
+ int maxW , int maxH ,
+ int incW , int incH )
+{
+ wxSize size = GetBestSize();
+
+ if(GetWindowStyle() & wxSL_VERTICAL) {
+ wxWindow::SetSizeHints(size.x, minH, size.x, maxH, incW, incH);
+ }
+ else {
+ wxWindow::SetSizeHints(minW, size.y, maxW, size.y, incW, incH);
+ }
+}
+
+wxSize wxSlider::DoGetBestSize() const
+{
+ wxSize size;
+ int textwidth, textheight;
+
+ if(GetWindowStyle() & wxSL_LABELS)
+ {
+ wxString text;
+ int ht, wd;
+
+ // Get maximum text label width and height
+ text.Printf(wxT("%d"), m_rangeMin);
+ GetTextExtent(text, &textwidth, &textheight);
+ text.Printf(wxT("%d"), m_rangeMax);
+ GetTextExtent(text, &wd, &ht);
+ if(ht > textheight) {
+ textheight = ht;
+ }
+ if (wd > textwidth) {
+ textwidth = wd;
+ }
+ }
+
+ if(GetWindowStyle() & wxSL_VERTICAL)
+ {
+ if(GetWindowStyle() & wxSL_AUTOTICKS) {
+ size.x = wxSLIDER_DIMENSIONACROSS_WITHTICKMARKS;
+ }
+ else {
+ size.x = wxSLIDER_DIMENSIONACROSS_ARROW;
+ }
+ if(GetWindowStyle() & wxSL_LABELS) {
+ size.x += textwidth + wxSLIDER_BORDERTEXT;
+ }
+ size.y = 150;
+ }
+ else
+ {
+ if(GetWindowStyle() & wxSL_AUTOTICKS) {
+ size.y = wxSLIDER_DIMENSIONACROSS_WITHTICKMARKS;
+ }
+ else {
+ size.y = wxSLIDER_DIMENSIONACROSS_ARROW;
+ }
+ if(GetWindowStyle() & wxSL_LABELS) {
+ size.y += textheight + wxSLIDER_BORDERTEXT;
+ }
+ size.x = 150;
+ }
+ return size;
+}
+
+void wxSlider::DoSetSize(int x, int y, int width, int height, int sizeFlags)
+{
+ wxControl::DoSetSize( x, y , width , height ,sizeFlags ) ;
+}
+
+void wxSlider::MacUpdateDimensions()
+{
+ // actually in the current systems this should never be possible, but later reparenting
+ // may become a reality
+
+ if ( (ControlHandle) m_macControl == NULL )
+ return ;
+
+ if ( GetParent() == NULL )
+ return ;
+
+ WindowRef rootwindow = (WindowRef) MacGetRootWindow() ;
+ if ( rootwindow == NULL )
+ return ;
+
+ int xborder, yborder;
+ int minValWidth, maxValWidth, textwidth, textheight;
+ int sliderBreadth;
+
+ xborder = yborder = 0;
+
+ if (GetWindowStyle() & wxSL_LABELS)
+ {
+ wxString text;
+ int ht;
+
+ // Get maximum text label width and height
+ text.Printf(wxT("%d"), m_rangeMin);
+ GetTextExtent(text, &minValWidth, &textheight);
+ text.Printf(wxT("%d"), m_rangeMax);
+ GetTextExtent(text, &maxValWidth, &ht);
+ if(ht > textheight) {
+ textheight = ht;
+ }
+ textwidth = (minValWidth > maxValWidth ? minValWidth : maxValWidth);
+
+ xborder = textwidth + wxSLIDER_BORDERTEXT;
+ yborder = textheight + wxSLIDER_BORDERTEXT;
+
+ // Get slider breadth
+ if(GetWindowStyle() & wxSL_AUTOTICKS) {
+ sliderBreadth = wxSLIDER_DIMENSIONACROSS_WITHTICKMARKS;
+ }
+ else {
+ sliderBreadth = wxSLIDER_DIMENSIONACROSS_ARROW;
+ }
+
+ if(GetWindowStyle() & wxSL_VERTICAL)
+ {
+ m_macMinimumStatic->Move(sliderBreadth + wxSLIDER_BORDERTEXT,
+ m_height - yborder - textheight);
+ m_macMaximumStatic->Move(sliderBreadth + wxSLIDER_BORDERTEXT, 0);
+ m_macValueStatic->Move(0, m_height - textheight);
+ }
+ else
+ {
+ m_macMinimumStatic->Move(0, sliderBreadth + wxSLIDER_BORDERTEXT);
+ m_macMaximumStatic->Move(m_width - xborder - maxValWidth / 2,
+ sliderBreadth + wxSLIDER_BORDERTEXT);
+ m_macValueStatic->Move(m_width - textwidth, 0);
+ }
+ }
+
+ Rect oldBounds ;
+ GetControlBounds( (ControlHandle) m_macControl , &oldBounds ) ;
+
+ int new_x = m_x + MacGetLeftBorderSize() + m_macHorizontalBorder ;
+ int new_y = m_y + MacGetTopBorderSize() + m_macVerticalBorder ;
+ int new_width = m_width - MacGetLeftBorderSize() - MacGetRightBorderSize() - 2 * m_macHorizontalBorder - xborder ;
+ int new_height = m_height - MacGetTopBorderSize() - MacGetBottomBorderSize() - 2 * m_macVerticalBorder - yborder ;
+
+ GetParent()->MacWindowToRootWindow( & new_x , & new_y ) ;
+ bool doMove = new_x != oldBounds.left || new_y != oldBounds.top ;
+ bool doResize = ( oldBounds.right - oldBounds.left ) != new_width || (oldBounds.bottom - oldBounds.top ) != new_height ;
+ if ( doMove || doResize )
+ {
+ InvalWindowRect( rootwindow, &oldBounds ) ;
+ if ( doMove )
+ {
+ UMAMoveControl( (ControlHandle) m_macControl , new_x , new_y ) ;
+ }
+ if ( doResize )
+ {
+ UMASizeControl( (ControlHandle) m_macControl , new_width , new_height ) ;
+ }
+ }
+}
+
+void wxSlider::DoMoveWindow(int x, int y, int width, int height)
+{
+ wxControl::DoMoveWindow(x,y,width,height) ;
+}
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: sound.cpp
+// Purpose: wxSound class implementation: optional
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "sound.h"
+#endif
+
+#include "wx/object.h"
+#include "wx/string.h"
+#include "wx/sound.h"
+
+#if wxUSE_SOUND
+
+#ifdef __WXMAC__
+#include "wx/mac/private.h"
+#ifndef __DARWIN__
+#include <Sound.h>
+#endif
+#endif
+
+wxSound::wxSound()
+ : m_sndChan(0), m_hSnd(NULL), m_waveLength(0), m_isResource(true)
+{
+}
+
+wxSound::wxSound(const wxString& sFileName, bool isResource)
+ : m_sndChan(0), m_hSnd(NULL), m_waveLength(0), m_isResource(true)
+{
+ Create(sFileName, isResource);
+}
+
+
+wxSound::~wxSound()
+{
+ FreeData();
+}
+
+wxSound::wxSound(int size, const wxByte* data)
+ : m_sndChan(0), m_hSnd(NULL), m_waveLength(0), m_isResource(false)
+{
+ //TODO convert data
+}
+
+bool wxSound::Create(const wxString& fileName, bool isResource)
+{
+ bool ret = false;
+ m_sndname = fileName;
+ m_isResource = isResource;
+
+ if (m_isResource)
+ ret = true;
+ else
+ { /*
+ if (sndChan)
+ { // we're playing
+ FSClose(SndRefNum);
+ SndRefNum = 0;
+ SndDisposeChannel(sndChan, TRUE);
+ free(sndChan);
+ sndChan = 0;
+ KillTimer(0,timerID);
+ }
+
+ if (!lpSnd)
+ return true;
+
+ if (_access(lpSnd,0)) // no file, no service
+ return false;
+
+ // Allocate SndChannel
+ sndChan = (SndChannelPtr) malloc (sizeof(SndChannel));
+
+ if (!sndChan)
+ return false;
+
+ sndChan->qLength = 128;
+
+ if (noErr != SndNewChannel (&sndChan, sampledSynth, initMono | initNoInterp, 0))
+ {
+ free(sndChan);
+ sndChan = 0;
+ return false;
+ }
+
+ if (!(SndRefNum = MacOpenSndFile ((char *)lpSnd)))
+ {
+ SndDisposeChannel(sndChan, TRUE);
+ free(sndChan);
+ sndChan = 0;
+
+ return false;
+ }
+
+ bool async = false;
+
+ if (fdwSound & SND_ASYNC)
+ async = true;
+
+ if (SndStartFilePlay(sndChan, SndRefNum, 0, 81920, 0, 0, 0, async) != noErr)
+ {
+ FSClose (SndRefNum);
+ SndRefNum = 0;
+ SndDisposeChannel (sndChan, TRUE);
+ free (sndChan);
+ sndChan = 0;
+ return false;
+ }
+
+ if (async)
+ { // haven't finish yet
+ timerID = SetTimer(0, 0, 250, TimerCallBack);
+ }
+ else
+ {
+ FSClose (SndRefNum);
+ SndRefNum = 0;
+ SndDisposeChannel (sndChan, TRUE);
+ free (sndChan);
+ sndChan = 0;
+ }*/
+ }
+
+ return ret;
+}
+
+
+//don't know what to do with looped, wth
+bool wxSound::DoPlay(unsigned flags) const
+{
+ bool ret = false;
+
+ if (m_isResource)
+ {
+ Str255 snd ;
+ wxMacStringToPascal( m_sndname , snd ) ;
+ SndListHandle hSnd;
+
+ hSnd = (SndListHandle) GetNamedResource('snd ', snd);
+
+ if ((hSnd != NULL) && (SndPlay((SndChannelPtr)m_sndChan, (SndListHandle) hSnd, (flags & wxSOUND_ASYNC)) == noErr))
+ ret = true;
+ }
+
+ return ret;
+}
+
+
+bool wxSound::FreeData()
+{
+ bool ret = false;
+
+ if (m_isResource)
+ {
+ m_sndname.Empty();
+ ret = true;
+ }
+ else
+ {
+ //TODO,
+ }
+
+ return ret;
+}
+
+
+//code below is from an old implementation used for telinfo with MSVC crossplatform support
+//technology proceeds, so it would be the wisest to drop this code, but it's left here just
+//for the sake of a reference. BTW: Wave files can now be played with QT, starting from V3
+
+/*static short MacOpenSndFile (char * path)
+{
+ VolumeParam vp;
+ FSSpec fspec;
+ Str255 name;
+ char *c;
+
+ // first, get the volume reference number for the file. Start by
+ // making a Pstring with just the volume name
+ strcpy ((char *) name, path);
+ if (c = strchr ((char *) name, ':'))
+ {
+ c++;
+ *c = '\0';
+ }
+
+ c2pstr ((char *) name);
+ vp.ioCompletion = 0;
+ vp.ioVolIndex = -1;
+ vp.ioNamePtr = name;
+ vp.ioVRefNum = 0;
+
+ if (PBGetVInfo((ParamBlockRec *)&vp, 0) != noErr)
+ return 0;
+
+ // next, buld an FSSpec for the file
+ strcpy ((char *) name, path);
+ c2pstr ((char *) name);
+ if (FSMakeFSSpec (vp.ioVRefNum, 0, name, &fspec) != noErr)
+ return 0;
+
+ short frefnum;
+ // now open the file, and return it's reference number
+ if (FSpOpenDF(&fspec, fsRdPerm, &frefnum) != noErr)
+ return 0;
+
+ return frefnum;
+}
+
+
+void TimerCallBack(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime)
+{
+ if(!sndChan)
+ {
+ KillTimer(0,timerID);
+ return;
+ }
+
+ SCStatus scstat;
+
+ if (noErr == SndChannelStatus (sndChan, sizeof (SCStatus), &scstat)) {
+ if (scstat.scChannelPaused || scstat.scChannelBusy)
+ return; // not done yet
+ }
+
+ // either error or done.
+ FSClose (SndRefNum);
+ SndRefNum = 0;
+ SndDisposeChannel (sndChan, TRUE);
+ free (sndChan);
+ sndChan = 0;
+ KillTimer(0,timerID);
+}*/
+
+
+#endif
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: spinbutt.cpp
+// Purpose: wxSpinButton
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "spinbutt.h"
+#pragma implementation "spinbuttbase.h"
+#endif
+
+#include "wx/spinbutt.h"
+#include "wx/mac/uma.h"
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxWin macros
+// ----------------------------------------------------------------------------
+
+#if !USE_SHARED_LIBRARY
+ IMPLEMENT_DYNAMIC_CLASS(wxSpinButton, wxControl)
+ IMPLEMENT_DYNAMIC_CLASS(wxSpinEvent, wxScrollEvent)
+#endif
+
+wxSpinButton::wxSpinButton()
+ : wxSpinButtonBase()
+{
+}
+
+bool wxSpinButton::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
+ long style, const wxString& name)
+{
+ if ( !wxSpinButtonBase::Create(parent, id, pos, size,
+ style, wxDefaultValidator, name) )
+ return false;
+
+ m_min = 0;
+ m_max = 100;
+
+ if (!parent)
+ return FALSE;
+
+ Rect bounds ;
+ Str255 title ;
+
+ MacPreControlCreate( parent , id , wxEmptyString , pos , size ,style,*( (wxValidator*) NULL ) , name , &bounds , title ) ;
+
+ m_macControl = ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , title , false , 0 , 0 , 100,
+ kControlLittleArrowsProc , (long) this ) ;
+
+ wxASSERT_MSG( (ControlHandle) m_macControl != NULL , wxT("No valid mac control") ) ;
+
+ MacPostControlCreate() ;
+
+ return TRUE;
+}
+
+wxSpinButton::~wxSpinButton()
+{
+}
+
+// Attributes
+////////////////////////////////////////////////////////////////////////////
+
+int wxSpinButton::GetMin() const
+{
+ return m_min;
+}
+
+int wxSpinButton::GetMax() const
+{
+ return m_max;
+}
+
+int wxSpinButton::GetValue() const
+{
+ return m_value;
+}
+
+void wxSpinButton::SetValue(int val)
+{
+ m_value = val ;
+}
+
+void wxSpinButton::SetRange(int minVal, int maxVal)
+{
+ m_min = minVal;
+ m_max = maxVal;
+ SetControl32BitMaximum( (ControlHandle) m_macControl , maxVal ) ;
+ SetControl32BitMinimum((ControlHandle) m_macControl , minVal ) ;
+}
+
+void wxSpinButton::MacHandleValueChanged( int inc )
+{
+
+ wxEventType scrollEvent = wxEVT_NULL;
+ int oldValue = m_value ;
+
+ m_value = oldValue + inc;
+
+ if (m_value < m_min)
+ {
+ if ( m_windowStyle & wxSP_WRAP )
+ m_value = m_max;
+ else
+ m_value = m_min;
+ }
+
+ if (m_value > m_max)
+ {
+ if ( m_windowStyle & wxSP_WRAP )
+ m_value = m_min;
+ else
+ m_value = m_max;
+ }
+
+ if ( m_value - oldValue == -1 )
+ scrollEvent = wxEVT_SCROLL_LINEDOWN ;
+ else if ( m_value - oldValue == 1 )
+ scrollEvent = wxEVT_SCROLL_LINEUP ;
+ else
+ scrollEvent = wxEVT_SCROLL_THUMBTRACK ;
+
+ wxSpinEvent event(scrollEvent, m_windowId);
+
+ event.SetPosition(m_value);
+ event.SetEventObject( this );
+ if ((GetEventHandler()->ProcessEvent( event )) &&
+ !event.IsAllowed() )
+ {
+ m_value = oldValue ;
+ }
+ SetControl32BitValue( (ControlHandle) m_macControl , m_value ) ;
+
+ /* always send a thumbtrack event */
+ if (scrollEvent != wxEVT_SCROLL_THUMBTRACK)
+ {
+ scrollEvent = wxEVT_SCROLL_THUMBTRACK;
+ wxSpinEvent event2( scrollEvent, GetId());
+ event2.SetPosition( m_value );
+ event2.SetEventObject( this );
+ GetEventHandler()->ProcessEvent( event2 );
+ }
+}
+
+void wxSpinButton::MacHandleControlClick( WXWidget control , wxInt16 controlpart , bool WXUNUSED(mouseStillDown))
+{
+ if ( (ControlHandle) m_macControl == NULL )
+ return ;
+
+ int nScrollInc = 0;
+
+ switch( controlpart )
+ {
+ case kControlUpButtonPart :
+ nScrollInc = 1;
+ break ;
+ case kControlDownButtonPart :
+ nScrollInc = -1;
+ break ;
+ }
+ MacHandleValueChanged( nScrollInc ) ;
+
+}
+
+// ----------------------------------------------------------------------------
+// size calculation
+// ----------------------------------------------------------------------------
+
+wxSize wxSpinButton::DoGetBestSize() const
+{
+ return wxSize(16,24);
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: spinbutt.cpp
+// Purpose: wxSpinCtrl
+// Author: Robert
+// Modified by: Mark Newsam (Based on GTK file)
+// RCS-ID: $Id$
+// Copyright: (c) Robert Roebling
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "spinctlg.h"
+#endif
+
+#include "wx/defs.h"
+
+#ifndef WX_PRECOMP
+ #include "wx/textctrl.h"
+#endif //WX_PRECOMP
+
+#if wxUSE_SPINCTRL
+
+#include "wx/spinbutt.h"
+#include "wx/spinctrl.h"
+
+
+#include "wx/spinctrl.h"
+
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+// the margin between the text control and the spin
+static const wxCoord MARGIN = 2;
+
+// ----------------------------------------------------------------------------
+// wxSpinCtrlText: text control used by spin control
+// ----------------------------------------------------------------------------
+
+class wxSpinCtrlText : public wxTextCtrl
+{
+public:
+ wxSpinCtrlText(wxSpinCtrl *spin, const wxString& value)
+ : wxTextCtrl(spin , -1, value)
+ {
+ m_spin = spin;
+ }
+
+protected:
+ void OnTextChange(wxCommandEvent& event)
+ {
+ int val;
+ if ( m_spin->GetTextValue(&val) )
+ {
+ m_spin->GetSpinButton()->SetValue(val);
+ }
+
+ event.Skip();
+ }
+
+ bool ProcessEvent(wxEvent &event)
+ {
+ // Hand button down events to wxSpinCtrl. Doesn't work.
+ if (event.GetEventType() == wxEVT_LEFT_DOWN && m_spin->ProcessEvent( event ))
+ return TRUE;
+
+ return wxTextCtrl::ProcessEvent( event );
+ }
+
+private:
+ wxSpinCtrl *m_spin;
+
+ DECLARE_EVENT_TABLE()
+};
+
+BEGIN_EVENT_TABLE(wxSpinCtrlText, wxTextCtrl)
+ EVT_TEXT(-1, wxSpinCtrlText::OnTextChange)
+END_EVENT_TABLE()
+
+// ----------------------------------------------------------------------------
+// wxSpinCtrlButton: spin button used by spin control
+// ----------------------------------------------------------------------------
+
+class wxSpinCtrlButton : public wxSpinButton
+{
+public:
+ wxSpinCtrlButton(wxSpinCtrl *spin, int style)
+ : wxSpinButton(spin )
+ {
+ m_spin = spin;
+
+ SetWindowStyle(style | wxSP_VERTICAL);
+ }
+
+protected:
+ void OnSpinButton(wxSpinEvent& eventSpin)
+ {
+#if defined(__WXMAC__) || defined(__WXMOTIF__)
+ m_spin->SetTextValue(eventSpin.GetPosition());
+
+ wxCommandEvent event(wxEVT_COMMAND_SPINCTRL_UPDATED, m_spin->GetId());
+ event.SetEventObject(m_spin);
+ event.SetInt(eventSpin.GetPosition());
+
+ m_spin->GetEventHandler()->ProcessEvent(event);
+#else
+ m_spin->SetTextValue(eventSpin.GetPosition());
+ eventSpin.Skip();
+#endif
+ }
+
+private:
+ wxSpinCtrl *m_spin;
+
+ DECLARE_EVENT_TABLE()
+};
+
+BEGIN_EVENT_TABLE(wxSpinCtrlButton, wxSpinButton)
+ EVT_SPIN(-1, wxSpinCtrlButton::OnSpinButton)
+END_EVENT_TABLE()
+
+IMPLEMENT_DYNAMIC_CLASS(wxSpinCtrl, wxControl)
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxSpinCtrl creation
+// ----------------------------------------------------------------------------
+
+void wxSpinCtrl::Init()
+{
+ m_text = NULL;
+ m_btn = NULL;
+}
+
+bool wxSpinCtrl::Create(wxWindow *parent,
+ wxWindowID id,
+ const wxString& value,
+ const wxPoint& pos,
+ const wxSize& size,
+ long style,
+ int min,
+ int max,
+ int initial,
+ const wxString& name)
+{
+ if ( !wxControl::Create(parent, id, wxDefaultPosition, wxDefaultSize, style,
+ wxDefaultValidator, name) )
+ {
+ return FALSE;
+ }
+
+ // the string value overrides the numeric one (for backwards compatibility
+ // reasons and also because it is simpler to satisfy the string value which
+ // comes much sooner in the list of arguments and leave the initial
+ // parameter unspecified)
+ if ( !value.empty() )
+ {
+ long l;
+ if ( value.ToLong(&l) )
+ initial = l;
+ }
+
+ wxSize csize = size ;
+ m_text = new wxSpinCtrlText(this, value);
+ m_btn = new wxSpinCtrlButton(this, style);
+
+ m_btn->SetRange(min, max);
+ m_btn->SetValue(initial);
+
+ if ( size.y == -1 ) {
+ csize.y = m_text->GetSize().y ;
+ }
+ DoSetSize(pos.x , pos.y , csize.x, csize.y);
+
+ return TRUE;
+}
+
+wxSpinCtrl::~wxSpinCtrl()
+{
+ // delete the controls now, don't leave them alive even though they would
+ // still be eventually deleted by our parent - but it will be too late, the
+ // user code expects them to be gone now
+ delete m_text;
+ m_text = NULL ;
+ delete m_btn;
+ m_btn = NULL ;
+}
+
+// ----------------------------------------------------------------------------
+// geometry
+// ----------------------------------------------------------------------------
+
+wxSize wxSpinCtrl::DoGetBestSize() const
+{
+ wxSize sizeBtn = m_btn->GetBestSize(),
+ sizeText = m_text->GetBestSize();
+
+ return wxSize(sizeBtn.x + sizeText.x + MARGIN, sizeText.y);
+}
+
+void wxSpinCtrl::DoMoveWindow(int x, int y, int width, int height)
+{
+ wxControl::DoMoveWindow(x, y, width, height);
+
+ // position the subcontrols inside the client area
+ wxSize sizeBtn = m_btn->GetSize();
+
+ wxCoord wText = width - sizeBtn.x;
+ m_text->SetSize(0, 0, wText, height);
+ m_btn->SetSize(0 + wText + MARGIN, 0, -1, -1);
+}
+
+// ----------------------------------------------------------------------------
+// operations forwarded to the subcontrols
+// ----------------------------------------------------------------------------
+
+bool wxSpinCtrl::Enable(bool enable)
+{
+ if ( !wxControl::Enable(enable) )
+ return FALSE;
+ return TRUE;
+}
+
+bool wxSpinCtrl::Show(bool show)
+{
+ if ( !wxControl::Show(show) )
+ return FALSE;
+ return TRUE;
+}
+
+// ----------------------------------------------------------------------------
+// value and range access
+// ----------------------------------------------------------------------------
+
+bool wxSpinCtrl::GetTextValue(int *val) const
+{
+ long l;
+ if ( !m_text->GetValue().ToLong(&l) )
+ {
+ // not a number at all
+ return FALSE;
+ }
+
+ if ( l < GetMin() || l > GetMax() )
+ {
+ // out of range
+ return FALSE;
+ }
+
+ *val = l;
+
+ return TRUE;
+}
+
+int wxSpinCtrl::GetValue() const
+{
+ return m_btn ? m_btn->GetValue() : 0;
+}
+
+int wxSpinCtrl::GetMin() const
+{
+ return m_btn ? m_btn->GetMin() : 0;
+}
+
+int wxSpinCtrl::GetMax() const
+{
+ return m_btn ? m_btn->GetMax() : 0;
+}
+
+// ----------------------------------------------------------------------------
+// changing value and range
+// ----------------------------------------------------------------------------
+
+void wxSpinCtrl::SetTextValue(int val)
+{
+ wxCHECK_RET( m_text, _T("invalid call to wxSpinCtrl::SetTextValue") );
+
+ m_text->SetValue(wxString::Format(_T("%d"), val));
+
+ // select all text
+ m_text->SetSelection(0, -1);
+
+ // and give focus to the control!
+ // m_text->SetFocus(); Why???? TODO.
+}
+
+void wxSpinCtrl::SetValue(int val)
+{
+ wxCHECK_RET( m_btn, _T("invalid call to wxSpinCtrl::SetValue") );
+
+ SetTextValue(val);
+
+ m_btn->SetValue(val);
+}
+
+void wxSpinCtrl::SetValue(const wxString& text)
+{
+ wxCHECK_RET( m_text, _T("invalid call to wxSpinCtrl::SetValue") );
+
+ long val;
+ if ( text.ToLong(&val) && ((val > INT_MIN) && (val < INT_MAX)) )
+ {
+ SetValue((int)val);
+ }
+ else // not a number at all or out of range
+ {
+ m_text->SetValue(text);
+ m_text->SetSelection(0, -1);
+ }
+}
+
+void wxSpinCtrl::SetRange(int min, int max)
+{
+ wxCHECK_RET( m_btn, _T("invalid call to wxSpinCtrl::SetRange") );
+
+ m_btn->SetRange(min, max);
+}
+
+void wxSpinCtrl::SetSelection(long from, long to)
+{
+ // if from and to are both -1, it means (in wxWindows) that all text should
+ // be selected
+ if ( (from == -1) && (to == -1) )
+ {
+ from = 0;
+ }
+ m_text->SetSelection(from, to);
+}
+
+#endif // wxUSE_SPINCTRL
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: statbmp.cpp
+// Purpose: wxStaticBitmap
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+ #pragma implementation "statbmp.h"
+#endif
+
+#include "wx/defs.h"
+
+#include "wx/statbmp.h"
+#include "wx/dcclient.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxStaticBitmap, wxControl)
+#endif
+
+/*
+ * wxStaticBitmap
+ */
+
+BEGIN_EVENT_TABLE(wxStaticBitmap, wxStaticBitmapBase)
+ EVT_PAINT(wxStaticBitmap::OnPaint)
+END_EVENT_TABLE()
+
+bool wxStaticBitmap::Create(wxWindow *parent, wxWindowID id,
+ const wxBitmap& bitmap,
+ const wxPoint& pos,
+ const wxSize& s,
+ long style,
+ const wxString& name)
+{
+ SetName(name);
+ wxSize size = s ;
+ if ( bitmap.Ok() )
+ {
+ if ( size.x == -1 )
+ size.x = bitmap.GetWidth() ;
+ if ( size.y == -1 )
+ size.y = bitmap.GetHeight() ;
+ }
+
+ m_backgroundColour = parent->GetBackgroundColour() ;
+ m_foregroundColour = parent->GetForegroundColour() ;
+
+ m_bitmap = bitmap;
+ if ( id == -1 )
+ m_windowId = (int)NewControlId();
+ else
+ m_windowId = id;
+
+ m_windowStyle = style;
+
+ bool ret = wxControl::Create( parent, id, pos, size, style , wxDefaultValidator , name );
+ SetBestSize( size ) ;
+
+ return ret;
+}
+
+void wxStaticBitmap::SetBitmap(const wxBitmap& bitmap)
+{
+ m_bitmap = bitmap;
+ SetSize(wxSize(bitmap.GetWidth(), bitmap.GetHeight()));
+ Refresh() ;
+}
+
+void wxStaticBitmap::OnPaint( wxPaintEvent& WXUNUSED(event) )
+{
+ wxPaintDC dc(this);
+ PrepareDC(dc);
+
+ dc.DrawBitmap( m_bitmap , 0 , 0 , TRUE ) ;
+}
+
+wxSize wxStaticBitmap::DoGetBestSize() const
+{
+ return wxWindow::DoGetBestSize() ;
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: statbox.cpp
+// Purpose: wxStaticBox
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "statbox.h"
+#endif
+
+#include "wx/defs.h"
+
+#include "wx/statbox.h"
+#include "wx/mac/uma.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxStaticBox, wxControl)
+
+BEGIN_EVENT_TABLE(wxStaticBox, wxControl)
+ EVT_ERASE_BACKGROUND(wxStaticBox::OnEraseBackground)
+END_EVENT_TABLE()
+
+#endif
+
+/*
+ * Static box
+ */
+
+bool wxStaticBox::Create(wxWindow *parent, wxWindowID id,
+ const wxString& label,
+ const wxPoint& pos,
+ const wxSize& size,
+ long style,
+ const wxString& name)
+{
+ if ( !wxControl::Create(parent, id, pos, size,
+ style, wxDefaultValidator, name) )
+ return false;
+
+ Rect bounds ;
+ Str255 title ;
+
+ MacPreControlCreate( parent , id , label , pos , size ,style, wxDefaultValidator , name , &bounds , title ) ;
+
+ m_macControl = ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , title , false , 0 , 0 , 1,
+ kControlGroupBoxTextTitleProc , (long) this ) ;
+
+ MacPostControlCreate() ;
+
+ return TRUE;
+}
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Name: statbar.cpp
+// Purpose: native implementation of wxStatusBar (optional)
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) 1998 Stefan Csomor
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "statbrma.h"
+#endif
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#include "wx/statusbr.h"
+#include "wx/dc.h"
+#include "wx/dcclient.h"
+
+BEGIN_EVENT_TABLE(wxStatusBarMac, wxStatusBarGeneric)
+ EVT_PAINT(wxStatusBarMac::OnPaint)
+END_EVENT_TABLE()
+
+#ifdef __WXMAC__
+#include "wx/mac/private.h"
+#endif
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxStatusBarMac class
+// ----------------------------------------------------------------------------
+
+wxStatusBarMac::wxStatusBarMac()
+{
+ SetParent(NULL);
+}
+
+wxStatusBarMac::~wxStatusBarMac()
+{
+}
+
+bool wxStatusBarMac::Create(wxWindow *parent, wxWindowID id,
+ long style ,
+ const wxString& name)
+{
+ return wxStatusBarGeneric::Create( parent , id , style , name ) ;
+}
+
+void wxStatusBarMac::DrawFieldText(wxDC& dc, int i)
+{
+ int leftMargin = 2;
+
+ wxRect rect;
+ GetFieldRect(i, rect);
+
+ if ( !IsWindowHilited( MAC_WXHWND( MacGetRootWindow() ) ) )
+ {
+ dc.SetTextForeground( wxColour( 0x80 , 0x80 , 0x80 ) ) ;
+ }
+
+ wxString text(GetStatusText(i));
+
+ long x, y;
+
+ dc.GetTextExtent(text, &x, &y);
+
+ int xpos = rect.x + leftMargin + 1 ;
+ int ypos = 1 ;
+
+ dc.SetClippingRegion(rect.x, 0, rect.width, m_height);
+
+ dc.DrawText(text, xpos, ypos);
+
+ dc.DestroyClippingRegion();
+}
+
+void wxStatusBarMac::DrawField(wxDC& dc, int i)
+{
+ DrawFieldText(dc, i);
+}
+
+void wxStatusBarMac::SetStatusText(const wxString& text, int number)
+{
+ wxCHECK_RET( (number >= 0) && (number < m_nFields),
+ _T("invalid status bar field index") );
+
+ m_statusStrings[number] = text;
+ wxRect rect;
+ GetFieldRect(number, rect);
+ rect.y=0;
+ rect.height = m_height ;
+ Refresh( TRUE , &rect ) ;
+ Update();
+}
+
+void wxStatusBarMac::OnPaint(wxPaintEvent& WXUNUSED(event) )
+{
+ wxPaintDC dc(this);
+ dc.Clear() ;
+
+ int major,minor;
+ wxGetOsVersion( &major, &minor );
+
+ if ( IsWindowHilited( MAC_WXHWND( MacGetRootWindow() ) ) )
+ {
+ wxPen white( wxWHITE , 1 , wxSOLID ) ;
+ if (major >= 10)
+ {
+ //Finder statusbar border color: (Project builder similar is 9B9B9B)
+ dc.SetPen(wxPen(wxColour(0xB1,0xB1,0xB1),1,wxSOLID));
+ }
+ else
+ {
+ wxPen black( wxBLACK , 1 , wxSOLID ) ;
+ dc.SetPen(black);
+ }
+ dc.DrawLine(0, 0 ,
+ m_width , 0);
+ dc.SetPen(white);
+ dc.DrawLine(0, 1 ,
+ m_width , 1);
+ }
+ else
+ {
+ if (major >= 10)
+ //Finder statusbar border color: (Project builder similar is 9B9B9B)
+ dc.SetPen(wxPen(wxColour(0xB1,0xB1,0xB1),1,wxSOLID));
+ else
+ dc.SetPen(wxPen(wxColour(0x80,0x80,0x80),1,wxSOLID));
+
+ dc.DrawLine(0, 0 ,
+ m_width , 0);
+ }
+
+ int i;
+ if ( GetFont().Ok() )
+ dc.SetFont(GetFont());
+ dc.SetBackgroundMode(wxTRANSPARENT);
+
+ for ( i = 0; i < m_nFields; i ++ )
+ DrawField(dc, i);
+}
+
+void wxStatusBarMac::MacSuperEnabled( bool enabled )
+{
+ Refresh(FALSE) ;
+ wxWindow::MacSuperEnabled( enabled ) ;
+}
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: generic/statline.cpp
+// Purpose: a generic wxStaticLine class
+// Author: Vadim Zeitlin
+// Created: 28.06.99
+// Version: $Id$
+// Copyright: (c) 1998 Vadim Zeitlin
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#ifdef __GNUG__
+ #pragma implementation "statline.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#include "wx/statline.h"
+#include "wx/statbox.h"
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+IMPLEMENT_DYNAMIC_CLASS(wxStaticLine, wxControl)
+
+// ----------------------------------------------------------------------------
+// wxStaticLine
+// ----------------------------------------------------------------------------
+
+bool wxStaticLine::Create( wxWindow *parent,
+ wxWindowID id,
+ const wxPoint &pos,
+ const wxSize &size,
+ long style,
+ const wxString &name)
+{
+ if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
+ return FALSE;
+
+ // ok, this is ugly but it's better than nothing: use a thin static box to
+ // emulate static line
+
+ wxSize sizeReal = AdjustSize(size);
+
+// m_statbox = new wxStaticBox(parent, id, wxT(""), pos, sizeReal, style, name);
+
+ return TRUE;
+}
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: generic/statline.cpp
+// Purpose: a generic wxStaticLine class
+// Author: Vadim Zeitlin
+// Created: 28.06.99
+// Version: $Id$
+// Copyright: (c) 1998 Vadim Zeitlin
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#ifdef __GNUG__
+ #pragma implementation "statline.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#include "wx/statline.h"
+#include "wx/statbox.h"
+
+#include "wx/mac/uma.h"
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+IMPLEMENT_DYNAMIC_CLASS(wxStaticLine, wxControl)
+
+// ----------------------------------------------------------------------------
+// wxStaticLine
+// ----------------------------------------------------------------------------
+
+bool wxStaticLine::Create( wxWindow *parent,
+ wxWindowID id,
+ const wxPoint &pos,
+ const wxSize &size,
+ long style,
+ const wxString &name)
+{
+ if ( !wxStaticLineBase::Create(parent, id, pos, size,
+ style, wxDefaultValidator, name) )
+ return false;
+
+ Rect bounds ;
+ Str255 title ;
+
+ MacPreControlCreate( parent , id , wxEmptyString , pos , size ,style, wxDefaultValidator , name , &bounds , title ) ;
+
+ m_macControl = ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , title , false , 0 , 0 , 1,
+ kControlSeparatorLineProc , (long) this ) ;
+
+ MacPostControlCreate() ;
+
+ return TRUE;
+}
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: stattext.cpp
+// Purpose: wxStaticText
+// Author: Stefan Csomor
+// Modified by:
+// Created: 04/01/98
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "stattext.h"
+#endif
+
+#include "wx/app.h"
+#include "wx/stattext.h"
+#include "wx/notebook.h"
+#include "wx/tabctrl.h"
+#include "wx/dc.h"
+#include "wx/dcclient.h"
+#include "wx/utils.h"
+#include "wx/settings.h"
+
+#include <stdio.h>
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxStaticText, wxControl)
+#endif
+
+#include "wx/mac/uma.h"
+
+BEGIN_EVENT_TABLE(wxStaticText, wxStaticTextBase)
+ EVT_PAINT(wxStaticText::OnPaint)
+END_EVENT_TABLE()
+
+bool wxStaticText::Create(wxWindow *parent, wxWindowID id,
+ const wxString& label,
+ const wxPoint& pos,
+ const wxSize& size,
+ long style,
+ const wxString& name)
+{
+ m_label = wxStripMenuCodes(label) ;
+
+ if ( !wxControl::Create( parent, id, pos, size, style,
+ wxDefaultValidator , name ) )
+ {
+ return false;
+ }
+
+ SetBestSize( size ) ;
+
+ return true;
+}
+
+const wxString punct = wxT(" ,.-;:!?");
+
+void wxStaticText::DrawParagraph(wxDC &dc, wxString paragraph, int &y)
+{
+ long width, height ;
+
+ if (paragraph.Length() == 0)
+ {
+ // empty line
+ dc.GetTextExtent( wxT("H"), &width, &height );
+ y += height;
+
+ return;
+ }
+
+ int x = 0 ;
+
+ bool linedrawn = true;
+ while( paragraph.Length() > 0 )
+ {
+ dc.GetTextExtent( paragraph , &width , &height ) ;
+
+ if ( width > m_width )
+ {
+ for ( size_t p = paragraph.Length() - 1 ; p > 0 ; --p )
+ {
+ if ((punct.Find(paragraph[p]) != wxNOT_FOUND) || !linedrawn)
+ {
+ int blank = (paragraph[p] == ' ') ? 0 : 1;
+
+ dc.GetTextExtent( paragraph.Left(p + blank) , &width , &height ) ;
+
+ if ( width <= m_width )
+ {
+ int pos = x ;
+ if ( HasFlag( wxALIGN_CENTER ) )
+ {
+ pos += ( m_width - width ) / 2 ;
+ }
+ else if ( HasFlag( wxALIGN_RIGHT ) )
+ {
+ pos += ( m_width - width ) ;
+ }
+
+ dc.DrawText( paragraph.Left(p + blank), pos , y) ;
+ y += height ;
+ paragraph = paragraph.Mid(p+1) ;
+ linedrawn = true;
+ break ;
+ }
+ }
+ }
+
+ linedrawn = false;
+ }
+ else
+ {
+ int pos = x ;
+ if ( HasFlag( wxALIGN_CENTER ) )
+ {
+ pos += ( m_width - width ) / 2 ;
+ }
+ else if ( HasFlag( wxALIGN_RIGHT ) )
+ {
+ pos += ( m_width - width ) ;
+ }
+
+ dc.DrawText( paragraph, pos , y) ;
+ paragraph=wxEmptyString;
+ y += height ;
+ }
+ }
+}
+
+void wxStaticText::OnDraw( wxDC &dc )
+{
+ if (m_width <= 0 || m_height <= 0)
+ return;
+ /*
+ dc.Clear() ;
+ wxRect rect(0,0,m_width,m_height) ;
+ dc.SetFont(*wxSMALL_FONT) ;
+
+ dc.DrawRectangle(rect) ;
+ */
+ if ( !IsWindowHilited( (WindowRef) MacGetRootWindow() ) &&
+ ( GetBackgroundColour() == wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE )
+ || GetBackgroundColour() == wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE) ) )
+ {
+ dc.SetTextForeground( wxColour( 0x80 , 0x80 , 0x80 ) ) ;
+ }
+ else
+ {
+ dc.SetTextForeground( GetForegroundColour() ) ;
+ }
+
+ wxString paragraph;
+ size_t i = 0 ;
+ wxString text = m_label;
+ int y = 0 ;
+ while (i < text.Length())
+ {
+
+ if (text[i] == 13 || text[i] == 10)
+ {
+ DrawParagraph(dc, paragraph,y);
+ paragraph = wxEmptyString ;
+ }
+ else
+ {
+ paragraph += text[i];
+ }
+ ++i;
+ }
+ if (paragraph.Length() > 0)
+ DrawParagraph(dc, paragraph,y);
+}
+
+void wxStaticText::OnPaint( wxPaintEvent & WXUNUSED(event) )
+{
+ wxPaintDC dc(this);
+ OnDraw( dc ) ;
+}
+
+wxSize wxStaticText::DoGetBestSize() const
+{
+ int widthTextMax = 0, widthLine,
+ heightTextTotal = 0, heightLineDefault = 0, heightLine = 0;
+
+ wxString curLine;
+ for ( const wxChar *pc = m_label; ; pc++ )
+ {
+ if ( *pc == wxT('\n') || *pc == wxT('\r') || *pc == wxT('\0') )
+ {
+ if ( !curLine )
+ {
+ // we can't use GetTextExtent - it will return 0 for both width
+ // and height and an empty line should count in height
+ // calculation
+ if ( !heightLineDefault )
+ heightLineDefault = heightLine;
+ if ( !heightLineDefault )
+ GetTextExtent(_T("W"), NULL, &heightLineDefault);
+
+ heightTextTotal += heightLineDefault;
+
+ heightTextTotal++; // FIXME: why is this necessary?
+ }
+ else
+ {
+ GetTextExtent(curLine, &widthLine, &heightLine);
+ if ( widthLine > widthTextMax )
+ widthTextMax = widthLine;
+ heightTextTotal += heightLine;
+
+ heightTextTotal++; // FIXME: why is this necessary?
+ }
+
+ if ( *pc == wxT('\n') || *pc == wxT('\r')) {
+ curLine.Empty();
+ }
+ else {
+ // the end of string
+ break;
+ }
+ }
+ else {
+ curLine += *pc;
+ }
+ }
+
+ return wxSize(widthTextMax, heightTextTotal);
+}
+
+void wxStaticText::SetLabel(const wxString& st )
+{
+ SetTitle( st ) ;
+ m_label = st ;
+ if ( !(GetWindowStyle() & wxST_NO_AUTORESIZE) )
+ {
+ // temporary fix until layout measurement and drawing are in synch again
+ Refresh() ;
+ SetSize( GetBestSize() ) ;
+ }
+ Refresh() ;
+ Update() ;
+}
+
+bool wxStaticText::SetFont(const wxFont& font)
+{
+ bool ret = wxControl::SetFont(font);
+
+ if ( ret )
+ {
+ // adjust the size of the window to fit to the label unless autoresizing is
+ // disabled
+ if ( !(GetWindowStyle() & wxST_NO_AUTORESIZE) )
+ {
+ // temporary fix until layout measurement and drawing are in synch again
+ Refresh() ;
+ SetSize( GetBestSize() );
+ }
+ }
+
+ return ret;
+}
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: tabctrl.cpp
+// Purpose: wxTabCtrl
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "tabctrl.h"
+#endif
+
+#include "wx/defs.h"
+
+#include "wx/control.h"
+#include "wx/tabctrl.h"
+#include "wx/mac/uma.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxTabCtrl, wxControl)
+
+BEGIN_EVENT_TABLE(wxTabCtrl, wxControl)
+END_EVENT_TABLE()
+#endif
+
+wxTabCtrl::wxTabCtrl()
+{
+ m_imageList = NULL;
+}
+
+bool wxTabCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
+ long style, const wxString& name)
+{
+ if ( !wxControl::Create(parent, id, pos, size,
+ style, wxDefaultValidator, name) )
+ return false;
+
+ Rect bounds ;
+ Str255 title ;
+
+ m_imageList = NULL;
+
+ MacPreControlCreate( parent , id , wxEmptyString , pos , size ,style, wxDefaultValidator , name , &bounds , title ) ;
+
+ m_macControl = ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , title , false , 0 , 0 , 1,
+ kControlTabSmallProc , (long) this ) ;
+
+ MacPostControlCreate() ;
+ return TRUE ;
+}
+
+wxTabCtrl::~wxTabCtrl()
+{
+}
+
+void wxTabCtrl::Command(wxCommandEvent& event)
+{
+}
+
+// Delete all items
+bool wxTabCtrl::DeleteAllItems()
+{
+ // TODO
+ return FALSE;
+}
+
+// Delete an item
+bool wxTabCtrl::DeleteItem(int item)
+{
+ // TODO
+ return FALSE;
+}
+
+// Get the selection
+int wxTabCtrl::GetSelection() const
+{
+ // TODO
+ return 0;
+}
+
+// Get the tab with the current keyboard focus
+int wxTabCtrl::GetCurFocus() const
+{
+ // TODO
+ return 0;
+}
+
+// Get the associated image list
+wxImageList* wxTabCtrl::GetImageList() const
+{
+ return m_imageList;
+}
+
+// Get the number of items
+int wxTabCtrl::GetItemCount() const
+{
+ // TODO
+ return 0;
+}
+
+// Get the rect corresponding to the tab
+bool wxTabCtrl::GetItemRect(int item, wxRect& wxrect) const
+{
+ // TODO
+ return FALSE;
+}
+
+// Get the number of rows
+int wxTabCtrl::GetRowCount() const
+{
+ // TODO
+ return 0;
+}
+
+// Get the item text
+wxString wxTabCtrl::GetItemText(int item) const
+{
+ // TODO
+ return wxEmptyString;
+}
+
+// Get the item image
+int wxTabCtrl::GetItemImage(int item) const
+{
+ // TODO
+ return 0;
+}
+
+// Get the item data
+void* wxTabCtrl::GetItemData(int item) const
+{
+ // TODO
+ return NULL;
+}
+
+// Hit test
+int wxTabCtrl::HitTest(const wxPoint& pt, long& flags)
+{
+ // TODO
+ return 0;
+}
+
+// Insert an item
+bool wxTabCtrl::InsertItem(int item, const wxString& text, int imageId, void* data)
+{
+ // TODO
+ return FALSE;
+}
+
+// Set the selection
+int wxTabCtrl::SetSelection(int item)
+{
+ // TODO
+ return 0;
+}
+
+// Set the image list
+void wxTabCtrl::SetImageList(wxImageList* imageList)
+{
+ // TODO
+}
+
+// Set the text for an item
+bool wxTabCtrl::SetItemText(int item, const wxString& text)
+{
+ // TODO
+ return FALSE;
+}
+
+// Set the image for an item
+bool wxTabCtrl::SetItemImage(int item, int image)
+{
+ // TODO
+ return FALSE;
+}
+
+// Set the data for an item
+bool wxTabCtrl::SetItemData(int item, void* data)
+{
+ // TODO
+ return FALSE;
+}
+
+// Set the size for a fixed-width tab control
+void wxTabCtrl::SetItemSize(const wxSize& size)
+{
+ // TODO
+}
+
+// Set the padding between tabs
+void wxTabCtrl::SetPadding(const wxSize& padding)
+{
+ // TODO
+}
+
+// Tab event
+IMPLEMENT_DYNAMIC_CLASS(wxTabEvent, wxCommandEvent)
+
+wxTabEvent::wxTabEvent(wxEventType commandType, int id):
+ wxCommandEvent(commandType, id)
+{
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: textctrl.cpp
+// Purpose: wxTextCtrl
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "textctrl.h"
+#endif
+
+#include "wx/defs.h"
+
+#if wxUSE_TEXTCTRL
+
+#ifdef __DARWIN__
+ #include <sys/types.h>
+ #include <sys/stat.h>
+#else
+ #include <stat.h>
+#endif
+
+#include "wx/msgdlg.h"
+
+#if wxUSE_STD_IOSTREAM
+ #if wxUSE_IOSTREAMH
+ #include <fstream.h>
+ #else
+ #include <fstream>
+ #endif
+#endif
+
+#include "wx/app.h"
+#include "wx/dc.h"
+#include "wx/button.h"
+#include "wx/toplevel.h"
+#include "wx/textctrl.h"
+#include "wx/notebook.h"
+#include "wx/tabctrl.h"
+#include "wx/settings.h"
+#include "wx/filefn.h"
+#include "wx/utils.h"
+
+#if defined(__BORLANDC__) && !defined(__WIN32__)
+ #include <alloc.h>
+#elif !defined(__MWERKS__) && !defined(__GNUWIN32) && !defined(__DARWIN__)
+ #include <malloc.h>
+#endif
+
+#ifndef __DARWIN__
+#include <Scrap.h>
+#endif
+#include <MacTextEditor.h>
+#include <ATSUnicode.h>
+#include <TextCommon.h>
+#include <TextEncodingConverter.h>
+#include "wx/mac/uma.h"
+
+#define TE_UNLIMITED_LENGTH 0xFFFFFFFFUL
+
+extern wxControl *wxFindControlFromMacControl(ControlHandle inControl ) ;
+
+// CS:TODO we still have a problem getting properly at the text events of a control because under Carbon
+// the MLTE engine registers itself for the key events thus the normal flow never occurs, the only measure for the
+// moment is to avoid setting the true focus on the control, the proper solution at the end would be to have
+// an alternate path for carbon key events that routes automatically into the same wx flow of events
+
+/* part codes */
+
+/* kmUPTextPart is the part code we return to indicate the user has clicked
+ in the text area of our control */
+#define kmUPTextPart 1
+
+/* kmUPScrollPart is the part code we return to indicate the user has clicked
+ in the scroll bar part of the control. */
+#define kmUPScrollPart 2
+
+
+/* routines for using existing user pane controls.
+ These routines are useful for cases where you would like to use an
+ existing user pane control in, say, a dialog window as a scrolling
+ text edit field.*/
+
+/* mUPOpenControl initializes a user pane control so it will be drawn
+ and will behave as a scrolling text edit field inside of a window.
+ This routine performs all of the initialization steps necessary,
+ except it does not create the user pane control itself. theControl
+ should refer to a user pane control that you have either created
+ yourself or extracted from a dialog's control heirarchy using
+ the GetDialogItemAsControl routine. */
+OSStatus mUPOpenControl(ControlHandle theControl, long wxStyle);
+
+/* Utility Routines */
+
+enum {
+ kShiftKeyCode = 56
+};
+
+/* kUserClickedToFocusPart is a part code we pass to the SetKeyboardFocus
+ routine. In our focus switching routine this part code is understood
+ as meaning 'the user has clicked in the control and we need to switch
+ the current focus to ourselves before we can continue'. */
+#define kUserClickedToFocusPart 100
+
+
+/* kmUPClickScrollDelayTicks is a time measurement in ticks used to
+ slow the speed of 'auto scrolling' inside of our clickloop routine.
+ This value prevents the text from wizzzzzing by while the mouse
+ is being held down inside of the text area. */
+#define kmUPClickScrollDelayTicks 3
+
+
+/* STPTextPaneVars is a structure used for storing the the mUP Control's
+ internal variables and state information. A handle to this record is
+ stored in the pane control's reference value field using the
+ SetControlReference routine. */
+
+typedef struct {
+ /* OS records referenced */
+ TXNObject fTXNRec; /* the txn record */
+ TXNFrameID fTXNFrame; /* the txn frame ID */
+ ControlHandle fUserPaneRec; /* handle to the user pane control */
+ WindowPtr fOwner; /* window containing control */
+ GrafPtr fDrawingEnvironment; /* grafport where control is drawn */
+ /* flags */
+ Boolean fInFocus; /* true while the focus rect is drawn around the control */
+ Boolean fIsActive; /* true while the control is drawn in the active state */
+ Boolean fTEActive; /* reflects the activation state of the text edit record */
+ Boolean fInDialogWindow; /* true if displayed in a dialog window */
+ /* calculated locations */
+ Rect fRTextArea; /* area where the text is drawn */
+ Rect fRFocusOutline; /* rectangle used to draw the focus box */
+ Rect fRTextOutline; /* rectangle used to draw the border */
+ RgnHandle fTextBackgroundRgn; /* background region for the text, erased before calling TEUpdate */
+ /* our focus advance override routine */
+ EventHandlerUPP handlerUPP;
+ EventHandlerRef handlerRef;
+ bool fMultiline ;
+} STPTextPaneVars;
+
+
+
+
+/* Univerals Procedure Pointer variables used by the
+ mUP Control. These variables are set up
+ the first time that mUPOpenControl is called. */
+ControlUserPaneDrawUPP gTPDrawProc = NULL;
+ControlUserPaneHitTestUPP gTPHitProc = NULL;
+ControlUserPaneTrackingUPP gTPTrackProc = NULL;
+ControlUserPaneIdleUPP gTPIdleProc = NULL;
+ControlUserPaneKeyDownUPP gTPKeyProc = NULL;
+ControlUserPaneActivateUPP gTPActivateProc = NULL;
+ControlUserPaneFocusUPP gTPFocusProc = NULL;
+
+/* TPActivatePaneText activates or deactivates the text edit record
+ according to the value of setActive. The primary purpose of this
+ routine is to ensure each call is only made once. */
+static void TPActivatePaneText(STPTextPaneVars **tpvars, Boolean setActive) {
+ STPTextPaneVars *varsp;
+ varsp = *tpvars;
+ if (varsp->fTEActive != setActive) {
+
+ varsp->fTEActive = setActive;
+
+ TXNActivate(varsp->fTXNRec, varsp->fTXNFrame, varsp->fTEActive);
+
+ if (varsp->fInFocus)
+ TXNFocus( varsp->fTXNRec, varsp->fTEActive);
+ }
+}
+
+
+/* TPFocusPaneText set the focus state for the text record. */
+static void TPFocusPaneText(STPTextPaneVars **tpvars, Boolean setFocus) {
+ STPTextPaneVars *varsp;
+ varsp = *tpvars;
+ if (varsp->fInFocus != setFocus) {
+ varsp->fInFocus = setFocus;
+ TXNFocus( varsp->fTXNRec, varsp->fInFocus);
+ }
+}
+
+
+/* TPPaneDrawProc is called to redraw the control and for update events
+ referring to the control. This routine erases the text area's background,
+ and redraws the text. This routine assumes the scroll bar has been
+ redrawn by a call to DrawControls. */
+static pascal void TPPaneDrawProc(ControlRef theControl, ControlPartCode thePart) {
+ STPTextPaneVars **tpvars, *varsp;
+ char state;
+ Rect bounds;
+ /* set up our globals */
+
+ tpvars = (STPTextPaneVars **) GetControlReference(theControl);
+ if (tpvars != NULL) {
+ state = HGetState((Handle) tpvars);
+ HLock((Handle) tpvars);
+ varsp = *tpvars;
+
+ /* save the drawing state */
+ SetPort((**tpvars).fDrawingEnvironment);
+ /* verify our boundary */
+ GetControlBounds(theControl, &bounds);
+
+ wxMacWindowClipper clipper( wxFindControlFromMacControl(theControl ) ) ;
+ if ( ! EqualRect(&bounds, &varsp->fRFocusOutline) ) {
+ // scrollbar is on the border, we add one
+ Rect oldbounds = varsp->fRFocusOutline ;
+ InsetRect( &oldbounds , -1 , -1 ) ;
+
+ if ( IsControlVisible( theControl ) )
+ InvalWindowRect( GetControlOwner( theControl ) , &oldbounds ) ;
+ SetRect(&varsp->fRFocusOutline, bounds.left, bounds.top, bounds.right, bounds.bottom);
+ SetRect(&varsp->fRTextOutline, bounds.left, bounds.top, bounds.right, bounds.bottom);
+ SetRect(&varsp->fRTextArea, bounds.left + 2 , bounds.top + (varsp->fMultiline ? 0 : 2) ,
+ bounds.right - (varsp->fMultiline ? 0 : 2), bounds.bottom - (varsp->fMultiline ? 0 : 2));
+ RectRgn(varsp->fTextBackgroundRgn, &varsp->fRTextOutline);
+ if ( IsControlVisible( theControl ) )
+ TXNSetFrameBounds( varsp->fTXNRec, varsp->fRTextArea.top, varsp->fRTextArea.left,
+ varsp->fRTextArea.bottom, varsp->fRTextArea.right, varsp->fTXNFrame);
+ else
+ TXNSetFrameBounds( varsp->fTXNRec, varsp->fRTextArea.top + 30000 , varsp->fRTextArea.left + 30000 ,
+ varsp->fRTextArea.bottom + 30000 , varsp->fRTextArea.right + 30000 , varsp->fTXNFrame);
+
+ }
+
+ if ( IsControlVisible( theControl ) )
+ {
+ /* update the text region */
+ RGBColor white = { 65535 , 65535 , 65535 } ;
+ RGBBackColor( &white ) ;
+ EraseRgn(varsp->fTextBackgroundRgn);
+ TXNDraw(varsp->fTXNRec, NULL);
+ /* restore the drawing environment */
+ /* draw the text frame and focus frame (if necessary) */
+ DrawThemeEditTextFrame(&varsp->fRTextOutline, varsp->fIsActive ? kThemeStateActive: kThemeStateInactive);
+ if ((**tpvars).fIsActive && varsp->fInFocus)
+ DrawThemeFocusRect(&varsp->fRFocusOutline, true);
+ /* release our globals */
+ HSetState((Handle) tpvars, state);
+ }
+ }
+}
+
+
+/* TPPaneHitTestProc is called when the control manager would
+ like to determine what part of the control the mouse resides over.
+ We also call this routine from our tracking proc to determine how
+ to handle mouse clicks. */
+static pascal ControlPartCode TPPaneHitTestProc(ControlHandle theControl, Point where) {
+ STPTextPaneVars **tpvars;
+ ControlPartCode result;
+ char state;
+ /* set up our locals and lock down our globals*/
+ result = 0;
+ tpvars = (STPTextPaneVars **) GetControlReference(theControl);
+ if (tpvars != NULL && IsControlVisible( theControl) ) {
+ state = HGetState((Handle) tpvars);
+ HLock((Handle) tpvars);
+ /* find the region where we clicked */
+ if (PtInRect(where, &(**tpvars).fRTextArea)) {
+ result = kmUPTextPart;
+ } else result = 0;
+ /* release oure globals */
+ HSetState((Handle) tpvars, state);
+ }
+ return result;
+}
+
+
+
+
+
+/* TPPaneTrackingProc is called when the mouse is being held down
+ over our control. This routine handles clicks in the text area
+ and in the scroll bar. */
+static pascal ControlPartCode TPPaneTrackingProc(ControlHandle theControl, Point startPt, ControlActionUPP actionProc) {
+ STPTextPaneVars **tpvars, *varsp;
+ char state;
+ ControlPartCode partCodeResult;
+ /* make sure we have some variables... */
+ partCodeResult = 0;
+ tpvars = (STPTextPaneVars **) GetControlReference(theControl);
+ if (tpvars != NULL && IsControlVisible( theControl ) ) {
+ /* lock 'em down */
+ state = HGetState((Handle) tpvars);
+ HLock((Handle) tpvars);
+ varsp = *tpvars;
+ /* we don't do any of these functions unless we're in focus */
+ if ( ! varsp->fInFocus) {
+ WindowPtr owner;
+ owner = GetControlOwner(theControl);
+ ClearKeyboardFocus(owner);
+ SetKeyboardFocus(owner, theControl, kUserClickedToFocusPart);
+ }
+ /* find the location for the click */
+ switch (TPPaneHitTestProc(theControl, startPt)) {
+
+ /* handle clicks in the text part */
+ case kmUPTextPart:
+ { SetPort((**tpvars).fDrawingEnvironment);
+ wxMacWindowClipper clipper( wxFindControlFromMacControl(theControl ) ) ;
+#if !TARGET_CARBON
+ TXNClick( varsp->fTXNRec, (const EventRecord*) wxTheApp->MacGetCurrentEvent());
+#else
+ EventRecord rec ;
+ ConvertEventRefToEventRecord( (EventRef) wxTheApp->MacGetCurrentEvent() , &rec ) ;
+ TXNClick( varsp->fTXNRec, &rec );
+#endif
+ }
+ break;
+
+ }
+
+ HSetState((Handle) tpvars, state);
+ }
+ return partCodeResult;
+}
+
+
+/* TPPaneIdleProc is our user pane idle routine. When our text field
+ is active and in focus, we use this routine to set the cursor. */
+static pascal void TPPaneIdleProc(ControlHandle theControl) {
+ STPTextPaneVars **tpvars, *varsp;
+ /* set up locals */
+ tpvars = (STPTextPaneVars **) GetControlReference(theControl);
+ if (tpvars != NULL && IsControlVisible( theControl ) ) {
+ /* if we're not active, then we have nothing to say about the cursor */
+ if ((**tpvars).fIsActive) {
+ char state;
+ Rect bounds;
+ Point mousep;
+ /* lock down the globals */
+ state = HGetState((Handle) tpvars);
+ HLock((Handle) tpvars);
+ varsp = *tpvars;
+ /* get the current mouse coordinates (in our window) */
+ SetPortWindowPort(GetControlOwner(theControl));
+ wxMacWindowClipper clipper( wxFindControlFromMacControl(theControl ) ) ;
+ GetMouse(&mousep);
+ /* there's a 'focus thing' and an 'unfocused thing' */
+ if (varsp->fInFocus) {
+ /* flash the cursor */
+ SetPort((**tpvars).fDrawingEnvironment);
+ TXNIdle(varsp->fTXNRec);
+ /* set the cursor */
+ if (PtInRect(mousep, &varsp->fRTextArea)) {
+ RgnHandle theRgn;
+ RectRgn((theRgn = NewRgn()), &varsp->fRTextArea);
+ TXNAdjustCursor(varsp->fTXNRec, theRgn);
+ DisposeRgn(theRgn);
+ }
+ else
+ {
+ // SetThemeCursor(kThemeArrowCursor);
+ }
+ } else {
+ /* if it's in our bounds, set the cursor */
+ GetControlBounds(theControl, &bounds);
+ if (PtInRect(mousep, &bounds))
+ {
+ // SetThemeCursor(kThemeArrowCursor);
+ }
+ }
+
+ HSetState((Handle) tpvars, state);
+ }
+ }
+}
+
+
+/* TPPaneKeyDownProc is called whenever a keydown event is directed
+ at our control. Here, we direct the keydown event to the text
+ edit record and redraw the scroll bar and text field as appropriate. */
+static pascal ControlPartCode TPPaneKeyDownProc(ControlHandle theControl,
+ SInt16 keyCode, SInt16 charCode, SInt16 modifiers) {
+ STPTextPaneVars **tpvars;
+ tpvars = (STPTextPaneVars **) GetControlReference(theControl);
+ if (tpvars != NULL) {
+ if ((**tpvars).fInFocus) {
+ /* turn autoscrolling on and send the key event to text edit */
+ SetPort((**tpvars).fDrawingEnvironment);
+ wxMacWindowClipper clipper( wxFindControlFromMacControl(theControl ) ) ;
+ EventRecord ev ;
+ memset( &ev , 0 , sizeof( ev ) ) ;
+ ev.what = keyDown ;
+ ev.modifiers = modifiers ;
+ ev.message = (( keyCode << 8 ) & keyCodeMask ) + ( charCode & charCodeMask ) ;
+ TXNKeyDown( (**tpvars).fTXNRec, &ev);
+ }
+ }
+ return kControlEntireControl;
+}
+
+
+/* TPPaneActivateProc is called when the window containing
+ the user pane control receives activate events. Here, we redraw
+ the control and it's text as necessary for the activation state. */
+static pascal void TPPaneActivateProc(ControlHandle theControl, Boolean activating) {
+ Rect bounds;
+ STPTextPaneVars **tpvars, *varsp;
+ char state;
+ /* set up locals */
+ tpvars = (STPTextPaneVars **) GetControlReference(theControl);
+ if (tpvars != NULL) {
+ state = HGetState((Handle) tpvars);
+ HLock((Handle) tpvars);
+ varsp = *tpvars;
+ /* de/activate the text edit record */
+ SetPort((**tpvars).fDrawingEnvironment);
+ wxMacWindowClipper clipper( wxFindControlFromMacControl(theControl ) ) ;
+ GetControlBounds(theControl, &bounds);
+ varsp->fIsActive = activating;
+ TPActivatePaneText(tpvars, varsp->fIsActive && varsp->fInFocus);
+ /* redraw the frame */
+ if ( IsControlVisible( theControl ) )
+ {
+ DrawThemeEditTextFrame(&varsp->fRTextOutline, varsp->fIsActive ? kThemeStateActive: kThemeStateInactive);
+ if (varsp->fInFocus)
+ DrawThemeFocusRect(&varsp->fRFocusOutline, varsp->fIsActive);
+ }
+ HSetState((Handle) tpvars, state);
+ }
+}
+
+
+/* TPPaneFocusProc is called when every the focus changes to or
+ from our control. Herein, switch the focus appropriately
+ according to the parameters and redraw the control as
+ necessary. */
+static pascal ControlPartCode TPPaneFocusProc(ControlHandle theControl, ControlFocusPart action) {
+ ControlPartCode focusResult;
+ STPTextPaneVars **tpvars, *varsp;
+ char state;
+ /* set up locals */
+ focusResult = kControlFocusNoPart;
+ tpvars = (STPTextPaneVars **) GetControlReference(theControl);
+ if (tpvars != NULL ) {
+ state = HGetState((Handle) tpvars);
+ HLock((Handle) tpvars);
+ varsp = *tpvars;
+ /* if kControlFocusPrevPart and kControlFocusNextPart are received when the user is
+ tabbing forwards (or shift tabbing backwards) through the items in the dialog,
+ and kControlFocusNextPart will be received. When the user clicks in our field
+ and it is not the current focus, then the constant kUserClickedToFocusPart will
+ be received. The constant kControlFocusNoPart will be received when our control
+ is the current focus and the user clicks in another control. In your focus routine,
+ you should respond to these codes as follows:
+
+ kControlFocusNoPart - turn off focus and return kControlFocusNoPart. redraw
+ the control and the focus rectangle as necessary.
+
+ kControlFocusPrevPart or kControlFocusNextPart - toggle focus on or off
+ depending on its current state. redraw the control and the focus rectangle
+ as appropriate for the new focus state. If the focus state is 'off', return the constant
+ kControlFocusNoPart, otherwise return a non-zero part code.
+ kUserClickedToFocusPart - is a constant defined for this example. You should
+ define your own value for handling click-to-focus type events. */
+ /* calculate the next highlight state */
+ switch (action) {
+ default:
+ case kControlFocusNoPart:
+ TPFocusPaneText(tpvars, false);
+ focusResult = kControlFocusNoPart;
+ break;
+ case kUserClickedToFocusPart:
+ TPFocusPaneText(tpvars, true);
+ focusResult = 1;
+ break;
+ case kControlFocusPrevPart:
+ case kControlFocusNextPart:
+ TPFocusPaneText(tpvars, ( ! varsp->fInFocus));
+ focusResult = varsp->fInFocus ? 1 : kControlFocusNoPart;
+ break;
+ }
+ TPActivatePaneText(tpvars, varsp->fIsActive && varsp->fInFocus);
+ /* redraw the text fram and focus rectangle to indicate the
+ new focus state */
+ if ( IsControlVisible( theControl ) )
+ {
+ /* save the drawing state */
+ SetPort((**tpvars).fDrawingEnvironment);
+ wxMacWindowClipper clipper( wxFindControlFromMacControl(theControl ) ) ;
+ DrawThemeEditTextFrame(&varsp->fRTextOutline, varsp->fIsActive ? kThemeStateActive: kThemeStateInactive);
+ DrawThemeFocusRect(&varsp->fRFocusOutline, varsp->fIsActive && varsp->fInFocus);
+ }
+ /* done */
+ HSetState((Handle) tpvars, state);
+ }
+ return focusResult;
+}
+
+
+/* mUPOpenControl initializes a user pane control so it will be drawn
+ and will behave as a scrolling text edit field inside of a window.
+ This routine performs all of the initialization steps necessary,
+ except it does not create the user pane control itself. theControl
+ should refer to a user pane control that you have either created
+ yourself or extracted from a dialog's control heirarchy using
+ the GetDialogItemAsControl routine. */
+OSStatus mUPOpenControl(ControlHandle theControl, long wxStyle )
+{
+ Rect bounds;
+ WindowRef theWindow;
+ STPTextPaneVars **tpvars, *varsp;
+ OSStatus err = noErr ;
+ RGBColor rgbWhite = {0xFFFF, 0xFFFF, 0xFFFF};
+ TXNBackground tback;
+
+ /* set up our globals */
+ if (gTPDrawProc == NULL) gTPDrawProc = NewControlUserPaneDrawUPP(TPPaneDrawProc);
+ if (gTPHitProc == NULL) gTPHitProc = NewControlUserPaneHitTestUPP(TPPaneHitTestProc);
+ if (gTPTrackProc == NULL) gTPTrackProc = NewControlUserPaneTrackingUPP(TPPaneTrackingProc);
+ if (gTPIdleProc == NULL) gTPIdleProc = NewControlUserPaneIdleUPP(TPPaneIdleProc);
+ if (gTPKeyProc == NULL) gTPKeyProc = NewControlUserPaneKeyDownUPP(TPPaneKeyDownProc);
+ if (gTPActivateProc == NULL) gTPActivateProc = NewControlUserPaneActivateUPP(TPPaneActivateProc);
+ if (gTPFocusProc == NULL) gTPFocusProc = NewControlUserPaneFocusUPP(TPPaneFocusProc);
+
+ /* allocate our private storage */
+ tpvars = (STPTextPaneVars **) NewHandleClear(sizeof(STPTextPaneVars));
+ SetControlReference(theControl, (long) tpvars);
+ HLock((Handle) tpvars);
+ varsp = *tpvars;
+ /* set the initial settings for our private data */
+ varsp->fMultiline = wxStyle & wxTE_MULTILINE ;
+ varsp->fInFocus = false;
+ varsp->fIsActive = true;
+ varsp->fTEActive = true; // in order to get a deactivate
+ varsp->fUserPaneRec = theControl;
+ theWindow = varsp->fOwner = GetControlOwner(theControl);
+
+ varsp->fDrawingEnvironment = (GrafPtr) GetWindowPort(theWindow);
+
+ varsp->fInDialogWindow = ( GetWindowKind(varsp->fOwner) == kDialogWindowKind );
+ /* set up the user pane procedures */
+ SetControlData(theControl, kControlEntireControl, kControlUserPaneDrawProcTag, sizeof(gTPDrawProc), &gTPDrawProc);
+ SetControlData(theControl, kControlEntireControl, kControlUserPaneHitTestProcTag, sizeof(gTPHitProc), &gTPHitProc);
+ SetControlData(theControl, kControlEntireControl, kControlUserPaneTrackingProcTag, sizeof(gTPTrackProc), &gTPTrackProc);
+ SetControlData(theControl, kControlEntireControl, kControlUserPaneIdleProcTag, sizeof(gTPIdleProc), &gTPIdleProc);
+ SetControlData(theControl, kControlEntireControl, kControlUserPaneKeyDownProcTag, sizeof(gTPKeyProc), &gTPKeyProc);
+ SetControlData(theControl, kControlEntireControl, kControlUserPaneActivateProcTag, sizeof(gTPActivateProc), &gTPActivateProc);
+ SetControlData(theControl, kControlEntireControl, kControlUserPaneFocusProcTag, sizeof(gTPFocusProc), &gTPFocusProc);
+ /* calculate the rectangles used by the control */
+ GetControlBounds(theControl, &bounds);
+ SetRect(&varsp->fRFocusOutline, bounds.left, bounds.top, bounds.right, bounds.bottom);
+ SetRect(&varsp->fRTextOutline, bounds.left, bounds.top, bounds.right, bounds.bottom);
+ SetRect(&varsp->fRTextArea, bounds.left + 2 , bounds.top + (varsp->fMultiline ? 0 : 2) ,
+ bounds.right - (varsp->fMultiline ? 0 : 2), bounds.bottom - (varsp->fMultiline ? 0 : 2));
+ /* calculate the background region for the text. In this case, it's kindof
+ and irregular region because we're setting the scroll bar a little ways inside
+ of the text area. */
+ RectRgn((varsp->fTextBackgroundRgn = NewRgn()), &varsp->fRTextOutline);
+
+ /* set up the drawing environment */
+ SetPort(varsp->fDrawingEnvironment);
+
+ /* create the new edit field */
+
+ TXNFrameOptions frameOptions =
+ kTXNDontDrawCaretWhenInactiveMask ;
+ if ( ! ( wxStyle & wxTE_NOHIDESEL ) )
+ frameOptions |= kTXNDontDrawSelectionWhenInactiveMask ;
+
+ if ( wxStyle & wxTE_MULTILINE )
+ {
+ if ( ! ( wxStyle & wxTE_DONTWRAP ) )
+ frameOptions |= kTXNAlwaysWrapAtViewEdgeMask ;
+ else
+ {
+ frameOptions |= kTXNAlwaysWrapAtViewEdgeMask ;
+ frameOptions |= kTXNWantHScrollBarMask ;
+ }
+
+ if ( !(wxStyle & wxTE_NO_VSCROLL ) )
+ frameOptions |= kTXNWantVScrollBarMask ;
+ }
+ else
+ frameOptions |= kTXNSingleLineOnlyMask ;
+
+ if ( wxStyle & wxTE_READONLY )
+ frameOptions |= kTXNReadOnlyMask ;
+
+ TXNNewObject(NULL, varsp->fOwner, &varsp->fRTextArea,
+ frameOptions ,
+ kTXNTextEditStyleFrameType,
+ kTXNTextensionFile,
+ kTXNSystemDefaultEncoding,
+ &varsp->fTXNRec, &varsp->fTXNFrame, (TXNObjectRefcon) tpvars);
+
+ if ( !IsControlVisible( theControl ) )
+ TXNSetFrameBounds( varsp->fTXNRec, varsp->fRTextArea.top + 30000 , varsp->fRTextArea.left + 30000 ,
+ varsp->fRTextArea.bottom + 30000 , varsp->fRTextArea.right + 30000 , varsp->fTXNFrame);
+
+
+ if ( (wxStyle & wxTE_MULTILINE) && (wxStyle & wxTE_DONTWRAP) )
+ {
+ TXNControlTag tag = kTXNWordWrapStateTag ;
+ TXNControlData dat ;
+ dat.uValue = kTXNNoAutoWrap ;
+ TXNSetTXNObjectControls( varsp->fTXNRec , false , 1 , &tag , &dat ) ;
+ }
+ Str255 fontName ;
+ SInt16 fontSize ;
+ Style fontStyle ;
+
+ GetThemeFont(kThemeSmallSystemFont , GetApplicationScript() , fontName , &fontSize , &fontStyle ) ;
+
+ TXNTypeAttributes typeAttr[] =
+ {
+ { kTXNQDFontNameAttribute , kTXNQDFontNameAttributeSize , { (void*) fontName } } ,
+ { kTXNQDFontSizeAttribute , kTXNFontSizeAttributeSize , { (void*) (fontSize << 16) } } ,
+ { kTXNQDFontStyleAttribute , kTXNQDFontStyleAttributeSize , { (void*) normal } } ,
+ } ;
+
+ err = TXNSetTypeAttributes (varsp->fTXNRec, sizeof( typeAttr ) / sizeof(TXNTypeAttributes) , typeAttr,
+ kTXNStartOffset,
+ kTXNEndOffset);
+ /* set the field's background */
+
+ tback.bgType = kTXNBackgroundTypeRGB;
+ tback.bg.color = rgbWhite;
+ TXNSetBackground( varsp->fTXNRec, &tback);
+
+ /* unlock our storage */
+ HUnlock((Handle) tpvars);
+ /* perform final activations and setup for our text field. Here,
+ we assume that the window is going to be the 'active' window. */
+ TPActivatePaneText(tpvars, varsp->fIsActive && varsp->fInFocus);
+ /* all done */
+ return err;
+}
+
+
+
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxTextCtrl, wxControl)
+
+BEGIN_EVENT_TABLE(wxTextCtrl, wxControl)
+ EVT_DROP_FILES(wxTextCtrl::OnDropFiles)
+ EVT_CHAR(wxTextCtrl::OnChar)
+ EVT_MENU(wxID_CUT, wxTextCtrl::OnCut)
+ EVT_MENU(wxID_COPY, wxTextCtrl::OnCopy)
+ EVT_MENU(wxID_PASTE, wxTextCtrl::OnPaste)
+ EVT_MENU(wxID_UNDO, wxTextCtrl::OnUndo)
+ EVT_MENU(wxID_REDO, wxTextCtrl::OnRedo)
+
+ EVT_UPDATE_UI(wxID_CUT, wxTextCtrl::OnUpdateCut)
+ EVT_UPDATE_UI(wxID_COPY, wxTextCtrl::OnUpdateCopy)
+ EVT_UPDATE_UI(wxID_PASTE, wxTextCtrl::OnUpdatePaste)
+ EVT_UPDATE_UI(wxID_UNDO, wxTextCtrl::OnUpdateUndo)
+ EVT_UPDATE_UI(wxID_REDO, wxTextCtrl::OnUpdateRedo)
+END_EVENT_TABLE()
+#endif
+
+static void SetTXNData( TXNObject txn , const wxString& st , TXNOffset start , TXNOffset end )
+{
+#if wxUSE_UNICODE
+#if SIZEOF_WCHAR_T == 2
+ size_t len = st.Len() ;
+ TXNSetData( txn , kTXNUnicodeTextData, (void*)st.wc_str(), len * 2,
+ start, end);
+#else
+ wxMBConvUTF16BE converter ;
+ ByteCount byteBufferLen = converter.WC2MB( NULL , st.wc_str() , 0 ) ;
+ UniChar *unibuf = (UniChar*) malloc(byteBufferLen) ;
+ converter.WC2MB( (char*) unibuf , st.wc_str() , byteBufferLen ) ;
+ TXNSetData( txn , kTXNUnicodeTextData, (void*)unibuf, byteBufferLen ,
+ start, end);
+ free( unibuf ) ;
+#endif
+#else
+ wxCharBuffer text = st.mb_str(wxConvLocal) ;
+ TXNSetData( txn , kTXNTextData, (void*)text.data(), strlen( text ) ,
+ start, end);
+#endif
+}
+
+// Text item
+void wxTextCtrl::Init()
+{
+ m_macTE = NULL ;
+ m_macTXN = NULL ;
+ m_macTXNvars = NULL ;
+ m_macUsesTXN = false ;
+
+ m_editable = true ;
+ m_dirty = false;
+
+ m_maxLength = TE_UNLIMITED_LENGTH ;
+}
+
+wxTextCtrl::~wxTextCtrl()
+{
+ if ( m_macUsesTXN )
+ {
+ SetControlReference((ControlHandle)m_macControl, 0) ;
+ TXNDeleteObject((TXNObject)m_macTXN);
+ /* delete our private storage */
+ DisposeHandle((Handle) m_macTXNvars);
+ /* zero the control reference */
+ }
+}
+
+const short kVerticalMargin = 2 ;
+const short kHorizontalMargin = 2 ;
+
+bool wxTextCtrl::Create(wxWindow *parent, wxWindowID id,
+ const wxString& str,
+ const wxPoint& pos,
+ const wxSize& size, long style,
+ const wxValidator& validator,
+ const wxString& name)
+{
+ m_macTE = NULL ;
+ m_macTXN = NULL ;
+ m_macTXNvars = NULL ;
+ m_macUsesTXN = false ;
+ m_editable = true ;
+
+ m_macUsesTXN = ! (style & wxTE_PASSWORD ) ;
+
+ m_macUsesTXN &= (TXNInitTextension != (void*) kUnresolvedCFragSymbolAddress) ;
+
+ // base initialization
+ if ( !wxTextCtrlBase::Create(parent, id, pos, size, style & ~(wxHSCROLL|wxVSCROLL), validator, name) )
+ return FALSE;
+
+ wxSize mySize = size ;
+ if ( m_macUsesTXN )
+ {
+ m_macHorizontalBorder = 5 ; // additional pixels around the real control
+ m_macVerticalBorder = 3 ;
+ }
+ else
+ {
+ m_macHorizontalBorder = 5 ; // additional pixels around the real control
+ m_macVerticalBorder = 5 ;
+ }
+
+
+ Rect bounds ;
+ Str255 title ;
+ /*
+ if ( mySize.y == -1 )
+ {
+ mySize.y = 13 ;
+ if ( m_windowStyle & wxTE_MULTILINE )
+ mySize.y *= 5 ;
+
+ mySize.y += 2 * m_macVerticalBorder ;
+ }
+ */
+ MacPreControlCreate( parent , id , wxEmptyString , pos , mySize ,style, validator , name , &bounds , title ) ;
+
+ if ( m_windowStyle & wxTE_MULTILINE )
+ {
+ wxASSERT_MSG( !(m_windowStyle & wxTE_PROCESS_ENTER),
+ wxT("wxTE_PROCESS_ENTER style is ignored for multiline text controls (they always process it)") );
+
+ m_windowStyle |= wxTE_PROCESS_ENTER;
+ }
+
+ if ( m_windowStyle & wxTE_READONLY)
+ {
+ m_editable = FALSE ;
+ }
+
+ wxString st = str ;
+ wxMacConvertNewlines13To10( &st ) ;
+ if ( !m_macUsesTXN )
+ {
+ m_macControl = ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , "\p" , false , 0 , 0 , 1,
+ (style & wxTE_PASSWORD) ? kControlEditTextPasswordProc : kControlEditTextProc , (long) this ) ;
+ long size ;
+ ::GetControlData((ControlHandle) m_macControl , 0, kControlEditTextTEHandleTag , sizeof( TEHandle ) , (char*)((TEHandle *)&m_macTE) , &size ) ;
+
+ }
+ else
+ {
+ short featurSet;
+
+ featurSet = kControlSupportsEmbedding | kControlSupportsFocus | kControlWantsIdle
+ | kControlWantsActivate | kControlHandlesTracking | kControlHasSpecialBackground
+ | kControlGetsFocusOnClick | kControlSupportsLiveFeedback;
+ /* create the control */
+ m_macControl = NewControl(MAC_WXHWND(parent->MacGetRootWindow()), &bounds, "\p", false , featurSet, 0, featurSet, kControlUserPaneProc, 0);
+ /* set up the mUP specific features and data */
+ mUPOpenControl((ControlHandle) m_macControl, m_windowStyle );
+ }
+ MacPostControlCreate() ;
+
+ if ( !m_macUsesTXN )
+ {
+ wxCharBuffer text = st.mb_str(wxConvLocal) ;
+ ::SetControlData( (ControlHandle) m_macControl, 0, ( m_windowStyle & wxTE_PASSWORD ) ? kControlEditTextPasswordTag : kControlEditTextTextTag , strlen(text) , text ) ;
+ }
+ else
+ {
+ STPTextPaneVars **tpvars;
+ /* set up locals */
+ tpvars = (STPTextPaneVars **) GetControlReference((ControlHandle) m_macControl);
+ /* set the text in the record */
+ m_macTXN = (**tpvars).fTXNRec ;
+ SetTXNData( (TXNObject) m_macTXN , st , kTXNStartOffset, kTXNEndOffset ) ;
+ m_macTXNvars = tpvars ;
+ m_macUsesTXN = true ;
+ TXNSetSelection( (TXNObject) m_macTXN, 0, 0);
+ TXNShowSelection( (TXNObject) m_macTXN, kTXNShowStart);
+ }
+
+ return TRUE;
+}
+
+wxString wxTextCtrl::GetValue() const
+{
+ Size actualSize = 0;
+ wxString result ;
+ OSStatus err ;
+ if ( !m_macUsesTXN )
+ {
+ err = ::GetControlDataSize((ControlHandle) m_macControl, 0,
+ ( m_windowStyle & wxTE_PASSWORD ) ? kControlEditTextPasswordTag : kControlEditTextTextTag, &actualSize ) ;
+
+ if ( err )
+ return wxEmptyString ;
+
+ if ( actualSize > 0 )
+ {
+ wxCharBuffer buf(actualSize) ;
+ ::GetControlData( (ControlHandle) m_macControl, 0,
+ ( m_windowStyle & wxTE_PASSWORD ) ? kControlEditTextPasswordTag : kControlEditTextTextTag,
+ actualSize , buf.data() , &actualSize ) ;
+ result = wxString( buf , wxConvLocal) ;
+ }
+ }
+ else
+ {
+#if wxUSE_UNICODE
+ Handle theText ;
+ err = TXNGetDataEncoded( ((TXNObject) m_macTXN), kTXNStartOffset, kTXNEndOffset, &theText , kTXNUnicodeTextData );
+ // all done
+ if ( err )
+ {
+ actualSize = 0 ;
+ }
+ else
+ {
+ actualSize = GetHandleSize( theText ) / sizeof( UniChar) ;
+ if ( actualSize > 0 )
+ {
+ wxChar *ptr = result.GetWriteBuf(actualSize*sizeof(wxChar)) ;
+#if SIZEOF_WCHAR_T == 2
+ wxStrncpy( ptr , (wxChar*) *theText , actualSize ) ;
+#else
+ wxMBConvUTF16BE converter ;
+ HLock( theText ) ;
+ converter.MB2WC( ptr , (const char*)*theText , actualSize ) ;
+ HUnlock( theText ) ;
+#endif
+ ptr[actualSize] = 0 ;
+ result.UngetWriteBuf( actualSize *sizeof(wxChar) ) ;
+ }
+ DisposeHandle( theText ) ;
+ }
+#else
+ Handle theText ;
+ err = TXNGetDataEncoded( ((TXNObject) m_macTXN), kTXNStartOffset, kTXNEndOffset, &theText , kTXNTextData );
+ // all done
+ if ( err )
+ {
+ actualSize = 0 ;
+ }
+ else
+ {
+ actualSize = GetHandleSize( theText ) ;
+ if ( actualSize > 0 )
+ {
+ HLock( theText ) ;
+ result = wxString( *theText , wxConvLocal , actualSize ) ;
+ HUnlock( theText ) ;
+ }
+ DisposeHandle( theText ) ;
+ }
+#endif
+ }
+ wxMacConvertNewlines10To13( &result ) ;
+ return result ;
+}
+
+void wxTextCtrl::GetSelection(long* from, long* to) const
+{
+ if ( !m_macUsesTXN )
+ {
+ *from = (**((TEHandle) m_macTE)).selStart;
+ *to = (**((TEHandle) m_macTE)).selEnd;
+ }
+ else
+ {
+ TXNGetSelection( (TXNObject) m_macTXN , (TXNOffset*) from , (TXNOffset*) to ) ;
+ }
+}
+
+void wxTextCtrl::SetValue(const wxString& str)
+{
+ wxString st = str ;
+ wxMacConvertNewlines13To10( &st ) ;
+ if ( !m_macUsesTXN )
+ {
+ wxCharBuffer text = st.mb_str(wxConvLocal) ;
+ ::SetControlData( (ControlHandle) m_macControl, 0, ( m_windowStyle & wxTE_PASSWORD ) ? kControlEditTextPasswordTag : kControlEditTextTextTag , strlen(text) , text ) ;
+ }
+ else
+ {
+ bool formerEditable = m_editable ;
+ if ( !formerEditable )
+ SetEditable(true) ;
+ SetTXNData( (TXNObject) m_macTXN , st , kTXNStartOffset, kTXNEndOffset ) ;
+ TXNSetSelection( (TXNObject) m_macTXN, 0, 0);
+ TXNShowSelection( (TXNObject) m_macTXN, kTXNShowStart);
+ if ( !formerEditable )
+ SetEditable(formerEditable) ;
+ }
+ MacRedrawControl() ;
+}
+
+void wxTextCtrl::SetMaxLength(unsigned long len)
+{
+ m_maxLength = len ;
+}
+
+bool wxTextCtrl::SetStyle(long start, long end, const wxTextAttr& style)
+{
+ if ( m_macUsesTXN )
+ {
+ bool formerEditable = m_editable ;
+ if ( !formerEditable )
+ SetEditable(true) ;
+ TXNTypeAttributes typeAttr[4] ;
+ Str255 fontName = "\pMonaco" ;
+ SInt16 fontSize = 12 ;
+ Style fontStyle = normal ;
+ RGBColor color ;
+ int attrCounter = 0 ;
+ if ( style.HasFont() )
+ {
+ const wxFont &font = style.GetFont() ;
+ wxMacStringToPascal( font.GetFaceName() , fontName ) ;
+ fontSize = font.GetPointSize() ;
+ if ( font.GetUnderlined() )
+ fontStyle |= underline ;
+ if ( font.GetWeight() == wxBOLD )
+ fontStyle |= bold ;
+ if ( font.GetStyle() == wxITALIC )
+ fontStyle |= italic ;
+
+ typeAttr[attrCounter].tag = kTXNQDFontNameAttribute ;
+ typeAttr[attrCounter].size = kTXNQDFontNameAttributeSize ;
+ typeAttr[attrCounter].data.dataPtr = (void*) fontName ;
+ typeAttr[attrCounter+1].tag = kTXNQDFontSizeAttribute ;
+ typeAttr[attrCounter+1].size = kTXNFontSizeAttributeSize ;
+ typeAttr[attrCounter+1].data.dataValue = (fontSize << 16) ;
+ typeAttr[attrCounter+2].tag = kTXNQDFontStyleAttribute ;
+ typeAttr[attrCounter+2].size = kTXNQDFontStyleAttributeSize ;
+ typeAttr[attrCounter+2].data.dataValue = fontStyle ;
+ attrCounter += 3 ;
+
+ }
+ if ( style.HasTextColour() )
+ {
+ typeAttr[attrCounter].tag = kTXNQDFontColorAttribute ;
+ typeAttr[attrCounter].size = kTXNQDFontColorAttributeSize ;
+ typeAttr[attrCounter].data.dataPtr = (void*) &color ;
+ color = MAC_WXCOLORREF(style.GetTextColour().GetPixel()) ;
+ attrCounter += 1 ;
+ }
+
+ if ( attrCounter > 0 )
+ {
+#ifdef __WXDEBUG__
+ OSStatus status =
+#endif // __WXDEBUG__
+ TXNSetTypeAttributes ((TXNObject)m_macTXN, attrCounter , typeAttr, start,end);
+ wxASSERT_MSG( status == noErr , wxT("Couldn't set text attributes") ) ;
+ }
+ if ( !formerEditable )
+ SetEditable(formerEditable) ;
+ }
+ return TRUE ;
+}
+
+bool wxTextCtrl::SetDefaultStyle(const wxTextAttr& style)
+{
+ wxTextCtrlBase::SetDefaultStyle( style ) ;
+ SetStyle( kTXNUseCurrentSelection , kTXNUseCurrentSelection , GetDefaultStyle() ) ;
+ return TRUE ;
+}
+
+// Clipboard operations
+void wxTextCtrl::Copy()
+{
+ if (CanCopy())
+ {
+ if ( !m_macUsesTXN )
+ {
+ TECopy( ((TEHandle) m_macTE) ) ;
+ ClearCurrentScrap();
+ TEToScrap() ;
+ MacRedrawControl() ;
+ }
+ else
+ {
+ ClearCurrentScrap();
+ TXNCopy((TXNObject)m_macTXN);
+ TXNConvertToPublicScrap();
+ }
+ }
+}
+
+void wxTextCtrl::Cut()
+{
+ if (CanCut())
+ {
+ if ( !m_macUsesTXN )
+ {
+ TECut( ((TEHandle) m_macTE) ) ;
+ ClearCurrentScrap();
+ TEToScrap() ;
+ MacRedrawControl() ;
+ }
+ else
+ {
+ ClearCurrentScrap();
+ TXNCut((TXNObject)m_macTXN);
+ TXNConvertToPublicScrap();
+ }
+ wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
+ event.SetString( GetValue() ) ;
+ event.SetEventObject( this );
+ GetEventHandler()->ProcessEvent(event);
+ }
+}
+
+void wxTextCtrl::Paste()
+{
+ if (CanPaste())
+ {
+ if ( !m_macUsesTXN )
+ {
+ TEFromScrap() ;
+ TEPaste( (TEHandle) m_macTE ) ;
+ MacRedrawControl() ;
+ }
+ else
+ {
+ TXNConvertFromPublicScrap();
+ TXNPaste((TXNObject)m_macTXN);
+ SetStyle( kTXNUseCurrentSelection , kTXNUseCurrentSelection , GetDefaultStyle() ) ;
+ }
+ wxCommandEvent event(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
+ event.SetString( GetValue() ) ;
+ event.SetEventObject( this );
+ GetEventHandler()->ProcessEvent(event);
+ }
+}
+
+bool wxTextCtrl::CanCopy() const
+{
+ // Can copy if there's a selection
+ long from, to;
+ GetSelection(& from, & to);
+ return (from != to);
+}
+
+bool wxTextCtrl::CanCut() const
+{
+ if ( !IsEditable() )
+ {
+ return false ;
+ }
+ // Can cut if there's a selection
+ long from, to;
+ GetSelection(& from, & to);
+ return (from != to);
+}
+
+bool wxTextCtrl::CanPaste() const
+{
+ if (!IsEditable())
+ return FALSE;
+
+#if TARGET_CARBON
+ OSStatus err = noErr;
+ ScrapRef scrapRef;
+
+ err = GetCurrentScrap( &scrapRef );
+ if ( err != noTypeErr && err != memFullErr )
+ {
+ ScrapFlavorFlags flavorFlags;
+ Size byteCount;
+
+ if (( err = GetScrapFlavorFlags( scrapRef, 'TEXT', &flavorFlags )) == noErr)
+ {
+ if (( err = GetScrapFlavorSize( scrapRef, 'TEXT', &byteCount )) == noErr)
+ {
+ return TRUE ;
+ }
+ }
+ }
+ return FALSE;
+
+#else
+ long offset ;
+ if ( GetScrap( NULL , 'TEXT' , &offset ) > 0 )
+ {
+ return TRUE ;
+ }
+#endif
+ return FALSE ;
+}
+
+void wxTextCtrl::SetEditable(bool editable)
+{
+ if ( editable != m_editable )
+ {
+ m_editable = editable ;
+ if ( !m_macUsesTXN )
+ {
+ if ( editable )
+ UMAActivateControl( (ControlHandle) m_macControl ) ;
+ else
+ UMADeactivateControl((ControlHandle) m_macControl ) ;
+ }
+ else
+ {
+ TXNControlTag tag[] = { kTXNIOPrivilegesTag } ;
+ TXNControlData data[] = { { editable ? kTXNReadWrite : kTXNReadOnly } } ;
+ TXNSetTXNObjectControls( (TXNObject) m_macTXN , false , sizeof(tag) / sizeof (TXNControlTag) , tag , data ) ;
+ }
+ }
+}
+
+void wxTextCtrl::SetInsertionPoint(long pos)
+{
+ SetSelection( pos , pos ) ;
+}
+
+void wxTextCtrl::SetInsertionPointEnd()
+{
+ long pos = GetLastPosition();
+ SetInsertionPoint(pos);
+}
+
+long wxTextCtrl::GetInsertionPoint() const
+{
+ long begin,end ;
+ GetSelection( &begin , &end ) ;
+ return begin ;
+}
+
+long wxTextCtrl::GetLastPosition() const
+{
+ if ( !m_macUsesTXN )
+ {
+ return (**((TEHandle) m_macTE)).teLength ;
+ }
+ else
+ {
+ Handle theText ;
+ long actualsize ;
+ OSErr err = TXNGetDataEncoded( (TXNObject) m_macTXN, kTXNStartOffset, kTXNEndOffset, &theText , kTXNTextData );
+ /* all done */
+ if ( err )
+ {
+ actualsize = 0 ;
+ }
+ else
+ {
+ actualsize = GetHandleSize( theText ) ;
+ DisposeHandle( theText ) ;
+ }
+ return actualsize ;
+ }
+}
+
+void wxTextCtrl::Replace(long from, long to, const wxString& str)
+{
+ wxString value = str ;
+ wxMacConvertNewlines13To10( &value ) ;
+ if ( !m_macUsesTXN )
+ {
+ ControlEditTextSelectionRec selection ;
+
+ selection.selStart = from ;
+ selection.selEnd = to ;
+ ::SetControlData((ControlHandle) m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection ) ;
+ TESetSelect( from , to , ((TEHandle) m_macTE) ) ;
+ TEDelete( ((TEHandle) m_macTE) ) ;
+ TEInsert( value , value.Length() , ((TEHandle) m_macTE) ) ;
+ }
+ else
+ {
+ bool formerEditable = m_editable ;
+ if ( !formerEditable )
+ SetEditable(true) ;
+ TXNSetSelection( ((TXNObject) m_macTXN) , from , to ) ;
+ TXNClear( ((TXNObject) m_macTXN) ) ;
+ SetTXNData( (TXNObject) m_macTXN , str , kTXNUseCurrentSelection, kTXNUseCurrentSelection ) ;
+ if ( !formerEditable )
+ SetEditable( formerEditable ) ;
+ }
+ Refresh() ;
+}
+
+void wxTextCtrl::Remove(long from, long to)
+{
+ if ( !m_macUsesTXN )
+ {
+ ControlEditTextSelectionRec selection ;
+
+ selection.selStart = from ;
+ selection.selEnd = to ;
+ ::SetControlData( (ControlHandle) m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection ) ;
+ TEDelete( ((TEHandle) m_macTE) ) ;
+ }
+ else
+ {
+ bool formerEditable = m_editable ;
+ if ( !formerEditable )
+ SetEditable(true) ;
+ TXNSetSelection( ((TXNObject) m_macTXN) , from , to ) ;
+ TXNClear( ((TXNObject) m_macTXN) ) ;
+ if ( !formerEditable )
+ SetEditable( formerEditable ) ;
+ }
+ Refresh() ;
+}
+
+void wxTextCtrl::SetSelection(long from, long to)
+{
+ if ( !m_macUsesTXN )
+ {
+ ControlEditTextSelectionRec selection ;
+ if ((from == -1) && (to == -1))
+ {
+ selection.selStart = 0 ;
+ selection.selEnd = 32767 ;
+ }
+ else
+ {
+ selection.selStart = from ;
+ selection.selEnd = to ;
+ }
+
+ TESetSelect( selection.selStart , selection.selEnd , ((TEHandle) m_macTE) ) ;
+ ::SetControlData((ControlHandle) m_macControl , 0, kControlEditTextSelectionTag , sizeof( selection ) , (char*) &selection ) ;
+ }
+ else
+ {
+ STPTextPaneVars **tpvars;
+ /* set up our locals */
+ tpvars = (STPTextPaneVars **) GetControlReference((ControlHandle) m_macControl);
+ /* and our drawing environment as the operation
+ may force a redraw in the text area. */
+ SetPort((**tpvars).fDrawingEnvironment);
+ /* change the selection */
+ if ((from == -1) && (to == -1))
+ TXNSelectAll((TXNObject) m_macTXN);
+ else
+ TXNSetSelection( (**tpvars).fTXNRec, from, to);
+ TXNShowSelection( (TXNObject) m_macTXN, kTXNShowStart);
+ }
+}
+
+bool wxTextCtrl::LoadFile(const wxString& file)
+{
+ if ( wxTextCtrlBase::LoadFile(file) )
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void wxTextCtrl::WriteText(const wxString& str)
+{
+ wxString st = str ;
+ wxMacConvertNewlines13To10( &st ) ;
+ if ( !m_macUsesTXN )
+ {
+ wxCharBuffer text = st.mb_str(wxConvLocal) ;
+ TEInsert( text , strlen(text) , ((TEHandle) m_macTE) ) ;
+ }
+ else
+ {
+ bool formerEditable = m_editable ;
+ if ( !formerEditable )
+ SetEditable(true) ;
+ long start , end , dummy ;
+ GetSelection( &start , &dummy ) ;
+ SetTXNData( (TXNObject) m_macTXN , st , kTXNUseCurrentSelection, kTXNUseCurrentSelection ) ;
+ GetSelection( &dummy , &end ) ;
+ SetStyle( start , end , GetDefaultStyle() ) ;
+ if ( !formerEditable )
+ SetEditable( formerEditable ) ;
+ }
+ MacRedrawControl() ;
+}
+
+void wxTextCtrl::AppendText(const wxString& text)
+{
+ SetInsertionPointEnd();
+ WriteText(text);
+}
+
+void wxTextCtrl::Clear()
+{
+ if ( !m_macUsesTXN )
+ {
+ ::SetControlData((ControlHandle) m_macControl, 0, ( m_windowStyle & wxTE_PASSWORD ) ? kControlEditTextPasswordTag : kControlEditTextTextTag , 0 , (char*) ((const char*)NULL) ) ;
+ }
+ else
+ {
+ TXNSetSelection( (TXNObject)m_macTXN , kTXNStartOffset , kTXNEndOffset ) ;
+ TXNClear((TXNObject)m_macTXN);
+ }
+ Refresh() ;
+}
+
+bool wxTextCtrl::IsModified() const
+{
+ return m_dirty;
+}
+
+bool wxTextCtrl::IsEditable() const
+{
+ return IsEnabled() && m_editable ;
+}
+
+bool wxTextCtrl::AcceptsFocus() const
+{
+ // we don't want focus if we can't be edited
+ return /*IsEditable() && */ wxControl::AcceptsFocus();
+}
+
+wxSize wxTextCtrl::DoGetBestSize() const
+{
+ int wText = 100 ;
+
+ int hText;
+ if ( m_macUsesTXN )
+ {
+ hText = 17 ;
+ }
+ else
+ {
+ hText = 13 ;
+ }
+/*
+ int cx, cy;
+ wxGetCharSize(GetHWND(), &cx, &cy, &GetFont());
+
+ int wText = DEFAULT_ITEM_WIDTH;
+
+ int hText = EDIT_HEIGHT_FROM_CHAR_HEIGHT(cy);
+
+ return wxSize(wText, hText);
+*/
+ if ( m_windowStyle & wxTE_MULTILINE )
+ {
+ hText *= 5 ;
+ }
+ hText += 2 * m_macVerticalBorder ;
+ wText += 2 * m_macHorizontalBorder ;
+ //else: for single line control everything is ok
+ return wxSize(wText, hText);
+}
+
+// ----------------------------------------------------------------------------
+// Undo/redo
+// ----------------------------------------------------------------------------
+
+void wxTextCtrl::Undo()
+{
+ if (CanUndo())
+ {
+ if ( m_macUsesTXN )
+ {
+ TXNUndo((TXNObject)m_macTXN);
+ }
+ }
+}
+
+void wxTextCtrl::Redo()
+{
+ if (CanRedo())
+ {
+ if ( m_macUsesTXN )
+ {
+ TXNRedo((TXNObject)m_macTXN);
+ }
+ }
+}
+
+bool wxTextCtrl::CanUndo() const
+{
+ if ( !IsEditable() )
+ {
+ return false ;
+ }
+ if ( m_macUsesTXN )
+ {
+ return TXNCanUndo((TXNObject)m_macTXN,NULL);
+ }
+ return FALSE ;
+}
+
+bool wxTextCtrl::CanRedo() const
+{
+ if ( !IsEditable() )
+ {
+ return false ;
+ }
+ if ( m_macUsesTXN )
+ {
+ return TXNCanRedo((TXNObject)m_macTXN,NULL);
+ }
+ return FALSE ;
+}
+
+// Makes modifie or unmodified
+void wxTextCtrl::MarkDirty()
+{
+ m_dirty = true;
+}
+
+void wxTextCtrl::DiscardEdits()
+{
+ m_dirty = false;
+}
+
+int wxTextCtrl::GetNumberOfLines() const
+{
+ if ( m_macUsesTXN )
+ {
+ ItemCount lines ;
+ TXNGetLineCount((TXNObject)m_macTXN, &lines ) ;
+ return lines ;
+ }
+ else
+ {
+ wxString content = GetValue() ;
+
+ int count = 1;
+ for (size_t i = 0; i < content.Length() ; i++)
+ {
+ if (content[i] == '\r') count++;
+ }
+ return count;
+ }
+}
+
+long wxTextCtrl::XYToPosition(long x, long y) const
+{
+ // TODO
+ return 0;
+}
+
+bool wxTextCtrl::PositionToXY(long pos, long *x, long *y) const
+{
+ return FALSE ;
+}
+
+void wxTextCtrl::ShowPosition(long pos)
+{
+#if TARGET_RT_MAC_MACHO && defined(AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER)
+ if ( m_macUsesTXN )
+ {
+ Point current ;
+ Point desired ;
+ TXNOffset selstart , selend ;
+ TXNGetSelection( (TXNObject) m_macTXN , &selstart , &selend) ;
+ TXNOffsetToPoint( (TXNObject) m_macTXN, selstart , ¤t);
+ TXNOffsetToPoint( (TXNObject) m_macTXN, pos , &desired);
+ //TODO use HIPoints for 10.3 and above
+ if ( (UInt32) TXNScroll != (UInt32) kUnresolvedCFragSymbolAddress )
+ {
+ OSErr theErr = noErr;
+ SInt32 dv = desired.v - current.v ;
+ SInt32 dh = desired.h - current.h ;
+ TXNShowSelection( (TXNObject) m_macTXN , true ) ;
+ theErr = TXNScroll( (TXNObject) m_macTXN, kTXNScrollUnitsInPixels , kTXNScrollUnitsInPixels , &dv , &dh );
+ wxASSERT_MSG( theErr == noErr, _T("TXNScroll returned an error!") );
+ }
+ }
+#endif
+}
+
+int wxTextCtrl::GetLineLength(long lineNo) const
+{
+ // TODO change this if possible to reflect real lines
+ wxString content = GetValue() ;
+
+ // Find line first
+ int count = 0;
+ for (size_t i = 0; i < content.Length() ; i++)
+ {
+ if (count == lineNo)
+ {
+ // Count chars in line then
+ count = 0;
+ for (size_t j = i; j < content.Length(); j++)
+ {
+ count++;
+ if (content[j] == '\n') return count;
+ }
+
+ return count;
+ }
+ if (content[i] == '\n') count++;
+ }
+ return 0;
+}
+
+wxString wxTextCtrl::GetLineText(long lineNo) const
+{
+ // TODO change this if possible to reflect real lines
+ wxString content = GetValue() ;
+
+ // Find line first
+ int count = 0;
+ for (size_t i = 0; i < content.Length() ; i++)
+ {
+ if (count == lineNo)
+ {
+ // Add chars in line then
+ wxString tmp;
+
+ for (size_t j = i; j < content.Length(); j++)
+ {
+ if (content[j] == '\n')
+ return tmp;
+
+ tmp += content[j];
+ }
+
+ return tmp;
+ }
+ if (content[i] == '\n') count++;
+ }
+ return wxEmptyString ;
+}
+
+/*
+ * Text item
+ */
+
+void wxTextCtrl::Command(wxCommandEvent & event)
+{
+ SetValue (event.GetString());
+ ProcessCommand (event);
+}
+
+void wxTextCtrl::OnDropFiles(wxDropFilesEvent& event)
+{
+ // By default, load the first file into the text window.
+ if (event.GetNumberOfFiles() > 0)
+ {
+ LoadFile(event.GetFiles()[0]);
+ }
+}
+
+void wxTextCtrl::OnChar(wxKeyEvent& event)
+{
+ int key = event.GetKeyCode() ;
+ bool eat_key = false ;
+
+ if ( key == 'c' && event.MetaDown() )
+ {
+ if ( CanCopy() )
+ Copy() ;
+ return ;
+ }
+
+ if ( !IsEditable() && key != WXK_LEFT && key != WXK_RIGHT && key != WXK_DOWN && key != WXK_UP && key != WXK_TAB &&
+ !( key == WXK_RETURN && ( (m_windowStyle & wxPROCESS_ENTER) || (m_windowStyle & wxTE_MULTILINE) ) )
+/* && key != WXK_PRIOR && key != WXK_NEXT && key != WXK_HOME && key != WXK_END */
+ )
+ {
+ // eat it
+ return ;
+ }
+
+ // assume that any key not processed yet is going to modify the control
+ m_dirty = true;
+
+ if ( key == 'v' && event.MetaDown() )
+ {
+ if ( CanPaste() )
+ Paste() ;
+ return ;
+ }
+ if ( key == 'x' && event.MetaDown() )
+ {
+ if ( CanCut() )
+ Cut() ;
+ return ;
+ }
+ switch ( key )
+ {
+ case WXK_RETURN:
+ if (m_windowStyle & wxPROCESS_ENTER)
+ {
+ wxCommandEvent event(wxEVT_COMMAND_TEXT_ENTER, m_windowId);
+ event.SetEventObject( this );
+ event.SetString( GetValue() );
+ if ( GetEventHandler()->ProcessEvent(event) )
+ return;
+ }
+ if ( !(m_windowStyle & wxTE_MULTILINE) )
+ {
+ wxWindow *parent = GetParent();
+ while( parent && !parent->IsTopLevel() && parent->GetDefaultItem() == NULL ) {
+ parent = parent->GetParent() ;
+ }
+ if ( parent && parent->GetDefaultItem() )
+ {
+ wxButton *def = wxDynamicCast(parent->GetDefaultItem(),
+ wxButton);
+ if ( def && def->IsEnabled() )
+ {
+ wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, def->GetId() );
+ event.SetEventObject(def);
+ def->Command(event);
+ return ;
+ }
+ }
+
+ // this will make wxWindows eat the ENTER key so that
+ // we actually prevent line wrapping in a single line
+ // text control
+ eat_key = TRUE;
+ }
+
+ break;
+
+ case WXK_TAB:
+ // always produce navigation event - even if we process TAB
+ // ourselves the fact that we got here means that the user code
+ // decided to skip processing of this TAB - probably to let it
+ // do its default job.
+ {
+ wxNavigationKeyEvent eventNav;
+ eventNav.SetDirection(!event.ShiftDown());
+ eventNav.SetWindowChange(event.ControlDown());
+ eventNav.SetEventObject(this);
+
+ if ( GetParent()->GetEventHandler()->ProcessEvent(eventNav) )
+ return;
+
+ event.Skip() ;
+ return;
+ }
+ break;
+ }
+
+ if (!eat_key)
+ {
+ // perform keystroke handling
+#if TARGET_CARBON
+ if ( m_macUsesTXN && wxTheApp->MacGetCurrentEvent() != NULL && wxTheApp->MacGetCurrentEventHandlerCallRef() != NULL )
+ CallNextEventHandler((EventHandlerCallRef)wxTheApp->MacGetCurrentEventHandlerCallRef() , (EventRef) wxTheApp->MacGetCurrentEvent() ) ;
+ else
+ {
+ EventRecord rec ;
+ if ( wxMacConvertEventToRecord( (EventRef) wxTheApp->MacGetCurrentEvent() , &rec ) )
+ {
+ EventRecord *ev = &rec ;
+ short keycode ;
+ short keychar ;
+ keychar = short(ev->message & charCodeMask);
+ keycode = short(ev->message & keyCodeMask) >> 8 ;
+
+ ::HandleControlKey( (ControlHandle) m_macControl , keycode , keychar , ev->modifiers ) ;
+ }
+ }
+#else
+ EventRecord *ev = (EventRecord*) wxTheApp->MacGetCurrentEvent() ;
+ short keycode ;
+ short keychar ;
+ keychar = short(ev->message & charCodeMask);
+ keycode = short(ev->message & keyCodeMask) >> 8 ;
+
+ ::HandleControlKey( (ControlHandle) m_macControl , keycode , keychar , ev->modifiers ) ;
+#endif
+ }
+ if ( ( key >= 0x20 && key < WXK_START ) ||
+ key == WXK_RETURN ||
+ key == WXK_DELETE ||
+ key == WXK_BACK)
+ {
+ wxCommandEvent event1(wxEVT_COMMAND_TEXT_UPDATED, m_windowId);
+ event1.SetString( GetValue() ) ;
+ event1.SetEventObject( this );
+ wxPostEvent(GetEventHandler(),event1);
+ }
+}
+
+void wxTextCtrl::MacSuperShown( bool show )
+{
+ bool former = m_macControlIsShown ;
+ wxControl::MacSuperShown( show ) ;
+ if ( (former != m_macControlIsShown) && m_macUsesTXN )
+ {
+ if ( m_macControlIsShown )
+ TXNSetFrameBounds( (TXNObject) m_macTXN, (**(STPTextPaneVars **)m_macTXNvars).fRTextArea.top, (**(STPTextPaneVars **)m_macTXNvars).fRTextArea.left,
+ (**(STPTextPaneVars **)m_macTXNvars).fRTextArea.bottom,(**(STPTextPaneVars **)m_macTXNvars).fRTextArea.right, (**(STPTextPaneVars **)m_macTXNvars).fTXNFrame);
+ else
+ TXNSetFrameBounds( (TXNObject) m_macTXN, (**(STPTextPaneVars **)m_macTXNvars).fRTextArea.top + 30000, (**(STPTextPaneVars **)m_macTXNvars).fRTextArea.left,
+ (**(STPTextPaneVars **)m_macTXNvars).fRTextArea.bottom + 30000, (**(STPTextPaneVars **)m_macTXNvars).fRTextArea.right, (**(STPTextPaneVars **)m_macTXNvars).fTXNFrame);
+ }
+}
+
+bool wxTextCtrl::Show(bool show)
+{
+ bool former = m_macControlIsShown ;
+
+ bool retval = wxControl::Show( show ) ;
+
+ if ( former != m_macControlIsShown && m_macUsesTXN )
+ {
+ if ( m_macControlIsShown )
+ TXNSetFrameBounds( (TXNObject) m_macTXN, (**(STPTextPaneVars **)m_macTXNvars).fRTextArea.top, (**(STPTextPaneVars **)m_macTXNvars).fRTextArea.left,
+ (**(STPTextPaneVars **)m_macTXNvars).fRTextArea.bottom,(**(STPTextPaneVars **)m_macTXNvars).fRTextArea.right, (**(STPTextPaneVars **)m_macTXNvars).fTXNFrame);
+ else
+ TXNSetFrameBounds( (TXNObject) m_macTXN, (**(STPTextPaneVars **)m_macTXNvars).fRTextArea.top + 30000, (**(STPTextPaneVars **)m_macTXNvars).fRTextArea.left,
+ (**(STPTextPaneVars **)m_macTXNvars).fRTextArea.bottom + 30000, (**(STPTextPaneVars **)m_macTXNvars).fRTextArea.right, (**(STPTextPaneVars **)m_macTXNvars).fTXNFrame);
+ }
+
+ return retval ;
+}
+
+// ----------------------------------------------------------------------------
+// standard handlers for standard edit menu events
+// ----------------------------------------------------------------------------
+
+void wxTextCtrl::OnCut(wxCommandEvent& WXUNUSED(event))
+{
+ Cut();
+}
+
+void wxTextCtrl::OnCopy(wxCommandEvent& WXUNUSED(event))
+{
+ Copy();
+}
+
+void wxTextCtrl::OnPaste(wxCommandEvent& WXUNUSED(event))
+{
+ Paste();
+}
+
+void wxTextCtrl::OnUndo(wxCommandEvent& WXUNUSED(event))
+{
+ Undo();
+}
+
+void wxTextCtrl::OnRedo(wxCommandEvent& WXUNUSED(event))
+{
+ Redo();
+}
+
+void wxTextCtrl::OnUpdateCut(wxUpdateUIEvent& event)
+{
+ event.Enable( CanCut() );
+}
+
+void wxTextCtrl::OnUpdateCopy(wxUpdateUIEvent& event)
+{
+ event.Enable( CanCopy() );
+}
+
+void wxTextCtrl::OnUpdatePaste(wxUpdateUIEvent& event)
+{
+ event.Enable( CanPaste() );
+}
+
+void wxTextCtrl::OnUpdateUndo(wxUpdateUIEvent& event)
+{
+ event.Enable( CanUndo() );
+}
+
+void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent& event)
+{
+ event.Enable( CanRedo() );
+}
+
+bool wxTextCtrl::MacSetupCursor( const wxPoint& pt )
+{
+ if ( m_macUsesTXN )
+ return true ;
+ else
+ return wxWindow::MacSetupCursor( pt ) ;
+}
+
+#endif
+ // wxUSE_TEXTCTRL
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: src/mac/tglbtn.cpp
+// Purpose: Definition of the wxToggleButton class, which implements a
+// toggle button under wxMac.
+// Author: Stefan Csomor
+// Modified by:
+// Created: 08.02.01
+// RCS-ID: $Id$
+// Copyright: (c) 2000 Johnny C. Norris II
+// License: Rocketeer license
+/////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declatations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#ifdef __GNUG__
+#pragma implementation "button.h"
+#endif
+
+#include "wx/defs.h"
+#include "wx/tglbtn.h"
+
+#if wxUSE_TOGGLEBTN
+
+#include "wx/mac/uma.h"
+// Button
+
+static const int kMacOSXHorizontalBorder = 2 ;
+static const int kMacOSXVerticalBorder = 4 ;
+
+// ----------------------------------------------------------------------------
+// macros
+// ----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxToggleButton, wxControl)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED)
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxToggleButton
+// ----------------------------------------------------------------------------
+
+// Single check box item
+bool wxToggleButton::Create(wxWindow *parent, wxWindowID id,
+ const wxString& label,
+ const wxPoint& pos,
+ const wxSize& size, long style,
+ const wxValidator& validator,
+ const wxString& name)
+{
+ if ( !wxControl::Create(parent, id, pos, size, style, validator, name) )
+ return false;
+
+ Rect bounds ;
+ Str255 title ;
+
+ if ( UMAHasAquaLayout() )
+ {
+ m_macHorizontalBorder = kMacOSXHorizontalBorder;
+ m_macVerticalBorder = kMacOSXVerticalBorder;
+ }
+
+ MacPreControlCreate( parent , id , label , pos , size ,style, validator , name , &bounds , title ) ;
+
+ m_macControl = ::NewControl( MAC_WXHWND(parent->MacGetRootWindow()) , &bounds , title , false , 0 , kControlBehaviorToggles , 1,
+ kControlBevelButtonNormalBevelProc , (long) this ) ;
+ wxASSERT_MSG( (ControlHandle) m_macControl != NULL , wxT("No valid mac control") ) ;
+
+ MacPostControlCreate() ;
+
+ return TRUE;
+}
+
+wxSize wxToggleButton::DoGetBestSize() const
+{
+ int wBtn = 70 ;
+ int hBtn = 20 ;
+
+ int lBtn = m_label.Length() * 8 + 12 ;
+ if (lBtn > wBtn)
+ wBtn = lBtn;
+
+ if ( UMAHasAquaLayout() )
+ {
+ wBtn += 2 * kMacOSXHorizontalBorder ;
+ hBtn += 2 * kMacOSXVerticalBorder ;
+ }
+ return wxSize ( wBtn , hBtn ) ;
+}
+
+void wxToggleButton::SetValue(bool val)
+{
+ ::SetControl32BitValue( (ControlHandle) m_macControl , val ) ;
+}
+
+bool wxToggleButton::GetValue() const
+{
+ return GetControl32BitValue( (ControlHandle) m_macControl ) ;
+}
+
+void wxToggleButton::Command(wxCommandEvent & event)
+{
+ SetValue((event.GetInt() != 0));
+ ProcessCommand(event);
+}
+
+void wxToggleButton::MacHandleControlClick( WXWidget WXUNUSED(control) , wxInt16 controlpart , bool WXUNUSED(mouseStillDown) )
+{
+ if ( controlpart != kControlNoPart )
+ {
+ wxCommandEvent event(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, m_windowId);
+ event.SetInt(GetValue());
+ event.SetEventObject(this);
+ ProcessCommand(event);
+ }
+}
+
+#endif // wxUSE_TOGGLEBTN
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: thread.cpp
+// Purpose: wxThread Implementation
+// Author: Original from Wolfram Gloger/Guilhem Lavaux/Vadim Zeitlin
+// Modified by: Stefan Csomor
+// Created: 04/22/98
+// RCS-ID: $Id$
+// Copyright: (c) Wolfram Gloger (1996, 1997); Guilhem Lavaux (1998),
+// Vadim Zeitlin (1999) , Stefan Csomor (2000)
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+ #pragma implementation "thread.h"
+#endif
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#if defined(__BORLANDC__)
+ #pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+ #include "wx/wx.h"
+#endif
+
+#if wxUSE_THREADS
+
+#include "wx/module.h"
+#include "wx/thread.h"
+
+#ifdef __WXMAC__
+#include <Threads.h>
+#include "wx/mac/uma.h"
+#include "wx/mac/macnotfy.h"
+#include <Timer.h>
+#endif
+
+#define INFINITE 0xFFFFFFFF
+
+
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+// 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
+};
+
+// ----------------------------------------------------------------------------
+// this module globals
+// ----------------------------------------------------------------------------
+
+static ThreadID gs_idMainThread = kNoThreadID ;
+static bool gs_waitingForThread = FALSE ;
+size_t g_numberOfThreads = 0;
+
+// ============================================================================
+// MacOS implementation of thread classes
+// ============================================================================
+
+class wxMacStCritical
+{
+public :
+ wxMacStCritical()
+ {
+ if ( UMASystemIsInitialized() )
+ ThreadBeginCritical() ;
+ }
+ ~wxMacStCritical()
+ {
+ if ( UMASystemIsInitialized() )
+ ThreadEndCritical() ;
+ }
+};
+
+// ----------------------------------------------------------------------------
+// wxMutex implementation
+// ----------------------------------------------------------------------------
+
+class wxMutexInternal
+{
+public:
+ wxMutexInternal(wxMutexType WXUNUSED(mutexType))
+ {
+ m_owner = kNoThreadID ;
+ m_locked = 0;
+ }
+
+ ~wxMutexInternal()
+ {
+ if ( m_locked > 0 )
+ {
+ wxLogDebug(_T("Warning: freeing a locked mutex (%ld locks)."), m_locked);
+ }
+ }
+
+ bool IsOk() const { return true; }
+
+ wxMutexError Lock() ;
+ wxMutexError TryLock() ;
+ wxMutexError Unlock();
+public:
+ ThreadID m_owner ;
+ wxArrayLong m_waiters ;
+ long m_locked ;
+};
+
+wxMutexError wxMutexInternal::Lock()
+{
+ wxMacStCritical critical ;
+ if ( UMASystemIsInitialized() )
+ {
+ OSErr err ;
+ ThreadID current = kNoThreadID;
+ err = ::MacGetCurrentThread(¤t);
+ // if we are not the owner, add this thread to the list of waiting threads, stop this thread
+ // and invoke the scheduler to continue executing the owner's thread
+ while ( m_owner != kNoThreadID && m_owner != current)
+ {
+ m_waiters.Add(current);
+ err = ::SetThreadStateEndCritical(kCurrentThreadID, kStoppedThreadState, m_owner);
+ err = ::ThreadBeginCritical();
+ }
+ m_owner = current;
+ }
+ m_locked++;
+
+ return wxMUTEX_NO_ERROR;
+}
+
+wxMutexError wxMutexInternal::TryLock()
+{
+ wxMacStCritical critical ;
+ if ( UMASystemIsInitialized() )
+ {
+ ThreadID current = kNoThreadID;
+ ::MacGetCurrentThread(¤t);
+ // if we are not the owner, give an error back
+ if ( m_owner != kNoThreadID && m_owner != current )
+ return wxMUTEX_BUSY;
+
+ m_owner = current;
+ }
+ m_locked++;
+
+ return wxMUTEX_NO_ERROR;
+}
+
+wxMutexError wxMutexInternal::Unlock()
+{
+ if ( UMASystemIsInitialized() )
+ {
+ OSErr err;
+ err = ::ThreadBeginCritical();
+
+ if (m_locked > 0)
+ m_locked--;
+
+ // this mutex is not owned by anybody anmore
+ m_owner = kNoThreadID;
+
+ // now pass on to the first waiting thread
+ ThreadID firstWaiting = kNoThreadID;
+ bool found = false;
+ while (!m_waiters.IsEmpty() && !found)
+ {
+ firstWaiting = m_waiters[0];
+ err = ::SetThreadState(firstWaiting, kReadyThreadState, kNoThreadID);
+ // in case this was not successful (dead thread), we just loop on and reset the id
+ found = (err != threadNotFoundErr);
+ if ( !found )
+ firstWaiting = kNoThreadID ;
+ m_waiters.RemoveAt(0) ;
+ }
+ // now we have a valid firstWaiting thread, which has been scheduled to run next, just end the
+ // critical section and invoke the scheduler
+ err = ::SetThreadStateEndCritical(kCurrentThreadID, kReadyThreadState, firstWaiting);
+ }
+ else
+ {
+ if (m_locked > 0)
+ m_locked--;
+ }
+ return wxMUTEX_NO_ERROR;
+}
+
+// --------------------------------------------------------------------------
+// wxSemaphore
+// --------------------------------------------------------------------------
+
+// TODO not yet implemented
+
+class wxSemaphoreInternal
+{
+public:
+ wxSemaphoreInternal(int initialcount, int maxcount);
+ ~wxSemaphoreInternal();
+
+ bool IsOk() const { return true ; }
+
+ wxSemaError Wait() { return WaitTimeout(INFINITE); }
+ wxSemaError TryWait() { return WaitTimeout(0); }
+ wxSemaError WaitTimeout(unsigned long milliseconds);
+
+ wxSemaError Post();
+
+private:
+};
+
+wxSemaphoreInternal::wxSemaphoreInternal(int initialcount, int maxcount)
+{
+ if ( maxcount == 0 )
+ {
+ // make it practically infinite
+ maxcount = INT_MAX;
+ }
+}
+
+wxSemaphoreInternal::~wxSemaphoreInternal()
+{
+}
+
+wxSemaError wxSemaphoreInternal::WaitTimeout(unsigned long milliseconds)
+{
+ return wxSEMA_MISC_ERROR;
+}
+
+wxSemaError wxSemaphoreInternal::Post()
+{
+ return wxSEMA_MISC_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+// wxCondition implementation
+// ----------------------------------------------------------------------------
+
+// TODO this is not yet completed
+
+class wxConditionInternal
+{
+public:
+ wxConditionInternal(wxMutex& mutex) : m_mutex(mutex)
+ {
+ m_excessSignals = 0 ;
+ }
+ ~wxConditionInternal()
+ {
+ }
+
+ bool IsOk() const { return m_mutex.IsOk() ; }
+
+ wxCondError Wait()
+ {
+ return WaitTimeout(0xFFFFFFFF );
+ }
+
+ wxCondError WaitTimeout(unsigned long msectimeout)
+ {
+ wxMacStCritical critical ;
+ if ( m_excessSignals > 0 )
+ {
+ --m_excessSignals ;
+ return wxCOND_NO_ERROR ;
+ }
+ else if ( msectimeout == 0 )
+ {
+ return wxCOND_MISC_ERROR ;
+ }
+ else
+ {
+ }
+ /*
+ waiters++;
+
+ // FIXME this should be MsgWaitForMultipleObjects() as well probably
+ DWORD rc = ::WaitForSingleObject(event, timeout);
+
+ waiters--;
+
+ return rc != WAIT_TIMEOUT;
+ */
+ return wxCOND_NO_ERROR ;
+ }
+ wxCondError Signal()
+ {
+ wxMacStCritical critical ;
+ return wxCOND_NO_ERROR;
+ }
+
+ wxCondError Broadcast()
+ {
+ wxMacStCritical critical ;
+ return wxCOND_NO_ERROR;
+ }
+
+ wxArrayLong m_waiters ;
+ wxInt32 m_excessSignals ;
+ wxMutex& m_mutex;
+};
+
+// ----------------------------------------------------------------------------
+// wxCriticalSection implementation
+// ----------------------------------------------------------------------------
+
+// it's implemented as a mutex on mac os, so it is defined in the headers
+
+// ----------------------------------------------------------------------------
+// wxThread implementation
+// ----------------------------------------------------------------------------
+
+// wxThreadInternal class
+// ----------------------
+
+class wxThreadInternal
+{
+public:
+ wxThreadInternal()
+ {
+ m_tid = kNoThreadID ;
+ m_state = STATE_NEW;
+ m_priority = WXTHREAD_DEFAULT_PRIORITY;
+ }
+
+ ~wxThreadInternal()
+ {
+ }
+
+ void Free()
+ {
+ }
+
+ // create a new (suspended) thread (for the given thread object)
+ bool Create(wxThread *thread, unsigned int stackSize);
+
+ // suspend/resume/terminate
+ bool Suspend();
+ bool Resume();
+ void Cancel() { m_state = STATE_CANCELED; }
+
+ // thread state
+ void SetState(wxThreadState state) { m_state = state; }
+ wxThreadState GetState() const { return m_state; }
+
+ // thread priority
+ void SetPriority(unsigned int priority);
+ unsigned int GetPriority() const { return m_priority; }
+
+ void SetResult( void *res ) { m_result = res ; }
+ void *GetResult() { return m_result ; }
+
+ // thread handle and id
+ ThreadID GetId() const { return m_tid; }
+
+ // thread function
+ static pascal void* MacThreadStart(wxThread* arg);
+
+private:
+ wxThreadState m_state; // state, see wxThreadState enum
+ unsigned int m_priority; // thread priority in "wx" units
+ ThreadID m_tid; // thread id
+ void* m_result;
+ static ThreadEntryUPP s_threadEntry ;
+};
+
+static wxArrayPtrVoid s_threads ;
+
+ThreadEntryUPP wxThreadInternal::s_threadEntry = NULL ;
+pascal void* wxThreadInternal::MacThreadStart(wxThread *thread)
+{
+ // first of all, check whether we hadn't been cancelled already
+ if ( thread->m_internal->GetState() == STATE_EXITED )
+ {
+ return (void*)-1;
+ }
+
+ void* rc = thread->Entry();
+
+ // enter m_critsect before changing the thread state
+ thread->m_critsect.Enter();
+ bool wasCancelled = thread->m_internal->GetState() == STATE_CANCELED;
+ thread->m_internal->SetState(STATE_EXITED);
+ thread->m_critsect.Leave();
+
+ thread->OnExit();
+
+ // if the thread was cancelled (from Delete()), then it the handle is still
+ // needed there
+ if ( thread->IsDetached() && !wasCancelled )
+ {
+ // auto delete
+ delete thread;
+ }
+ //else: the joinable threads handle will be closed when Wait() is done
+
+ return rc;
+}
+void wxThreadInternal::SetPriority(unsigned int priority)
+{
+ // Priorities don't exist on Mac
+}
+
+bool wxThreadInternal::Create(wxThread *thread, unsigned int stackSize)
+{
+ if ( s_threadEntry == NULL )
+ {
+ s_threadEntry = NewThreadEntryUPP( (ThreadEntryProcPtr) MacThreadStart ) ;
+ }
+ OSErr err = NewThread( kCooperativeThread,
+ s_threadEntry,
+ (void*) thread,
+ stackSize,
+ kNewSuspend,
+ &m_result,
+ &m_tid );
+
+ if ( err != noErr )
+ {
+ wxLogSysError(_("Can't create thread"));
+ return FALSE;
+ }
+
+ if ( m_priority != WXTHREAD_DEFAULT_PRIORITY )
+ {
+ SetPriority(m_priority);
+ }
+
+ m_state = STATE_NEW;
+
+ return TRUE;
+}
+
+bool wxThreadInternal::Suspend()
+{
+ OSErr err ;
+
+ ::ThreadBeginCritical();
+
+ if ( m_state != STATE_RUNNING )
+ {
+ ::ThreadEndCritical() ;
+ wxLogSysError(_("Can not suspend thread %x"), m_tid);
+ return FALSE;
+ }
+
+ m_state = STATE_PAUSED;
+
+ err = ::SetThreadStateEndCritical(m_tid, kStoppedThreadState, kNoThreadID);
+
+ return TRUE;
+}
+
+bool wxThreadInternal::Resume()
+{
+ ThreadID current ;
+ OSErr err ;
+ err = MacGetCurrentThread( ¤t ) ;
+
+ wxASSERT( err == noErr ) ;
+ wxASSERT( current != m_tid ) ;
+
+ ::ThreadBeginCritical();
+ if ( m_state != STATE_PAUSED && m_state != STATE_NEW )
+ {
+ ::ThreadEndCritical() ;
+ wxLogSysError(_("Can not resume thread %x"), m_tid);
+ return FALSE;
+
+ }
+ err = ::SetThreadStateEndCritical(m_tid, kReadyThreadState, kNoThreadID);
+ wxASSERT( err == noErr ) ;
+
+ m_state = STATE_RUNNING;
+ ::ThreadEndCritical() ;
+ ::YieldToAnyThread() ;
+ return TRUE;
+}
+
+// static functions
+// ----------------
+wxThread *wxThread::This()
+{
+ wxMacStCritical critical ;
+
+ ThreadID current ;
+ OSErr err ;
+
+ err = MacGetCurrentThread( ¤t ) ;
+
+ for ( size_t i = 0 ; i < s_threads.Count() ; ++i )
+ {
+ if ( ( (wxThread*) s_threads[i] )->GetId() == current )
+ return (wxThread*) s_threads[i] ;
+ }
+
+ wxLogSysError(_("Couldn't get the current thread pointer"));
+ return NULL;
+}
+
+bool wxThread::IsMain()
+{
+ ThreadID current ;
+ OSErr err ;
+
+ err = MacGetCurrentThread( ¤t ) ;
+ return current == gs_idMainThread;
+}
+
+#ifdef Yield
+#undef Yield
+#endif
+
+void wxThread::Yield()
+{
+ ::YieldToAnyThread() ;
+}
+
+void wxThread::Sleep(unsigned long milliseconds)
+{
+ UnsignedWide start, now;
+
+ Microseconds(&start);
+
+ double mssleep = milliseconds * 1000 ;
+ double msstart, msnow ;
+ msstart = (start.hi * 4294967296.0 + start.lo) ;
+
+ do
+ {
+ YieldToAnyThread();
+ Microseconds(&now);
+ msnow = (now.hi * 4294967296.0 + now.lo) ;
+ } while( msnow - msstart < mssleep );
+}
+
+int wxThread::GetCPUCount()
+{
+ // we will use whatever MP API will be used for the new MP Macs
+ return 1;
+}
+
+unsigned long wxThread::GetCurrentId()
+{
+ ThreadID current ;
+ MacGetCurrentThread( ¤t ) ;
+ return (unsigned long)current;
+}
+
+bool wxThread::SetConcurrency(size_t level)
+{
+ wxASSERT_MSG( IsMain(), _T("should only be called from the main thread") );
+
+ // ok only for the default one
+ if ( level == 0 )
+ return 0;
+
+ // how many CPUs have we got?
+ if ( GetCPUCount() == 1 )
+ {
+ // don't bother with all this complicated stuff - on a single
+ // processor system it doesn't make much sense anyhow
+ return level == 1;
+ }
+
+ return TRUE ;
+}
+
+// ctor and dtor
+// -------------
+
+wxThread::wxThread(wxThreadKind kind)
+{
+ g_numberOfThreads++;
+ m_internal = new wxThreadInternal();
+
+ m_isDetached = kind == wxTHREAD_DETACHED;
+ s_threads.Add( (void*) this ) ;
+}
+
+wxThread::~wxThread()
+{
+ if (g_numberOfThreads>0)
+ {
+ g_numberOfThreads--;
+ }
+#ifdef __WXDEBUG__
+ else
+ {
+ wxFAIL_MSG(wxT("More threads deleted than created."));
+ }
+#endif
+
+ s_threads.Remove( (void*) this ) ;
+ if (m_internal != NULL) {
+ delete m_internal;
+ m_internal = NULL;
+ }
+}
+
+// create/start thread
+// -------------------
+
+wxThreadError wxThread::Create(unsigned int stackSize)
+{
+ wxCriticalSectionLocker lock(m_critsect);
+
+ if ( !m_internal->Create(this, stackSize) )
+ return wxTHREAD_NO_RESOURCE;
+
+ return wxTHREAD_NO_ERROR;
+}
+
+wxThreadError wxThread::Run()
+{
+ wxCriticalSectionLocker lock(m_critsect);
+
+ if ( m_internal->GetState() != STATE_NEW )
+ {
+ // actually, it may be almost any state at all, not only STATE_RUNNING
+ return wxTHREAD_RUNNING;
+ }
+
+ // the thread has just been created and is still suspended - let it run
+ return Resume();
+}
+
+// suspend/resume thread
+// ---------------------
+
+wxThreadError wxThread::Pause()
+{
+ wxCriticalSectionLocker lock(m_critsect);
+
+ return m_internal->Suspend() ? wxTHREAD_NO_ERROR : wxTHREAD_MISC_ERROR;
+}
+
+wxThreadError wxThread::Resume()
+{
+ wxCriticalSectionLocker lock(m_critsect);
+
+ return m_internal->Resume() ? wxTHREAD_NO_ERROR : wxTHREAD_MISC_ERROR;
+}
+
+// stopping thread
+// ---------------
+
+wxThread::ExitCode wxThread::Wait()
+{
+ // although under MacOS we can wait for any thread, it's an error to
+ // wait for a detached one in wxWin API
+ wxCHECK_MSG( !IsDetached(), (ExitCode)-1,
+ _T("can't wait for detached thread") );
+
+ ExitCode rc = (ExitCode)-1;
+
+ (void)Delete(&rc);
+
+ m_internal->Free();
+
+ return rc;
+}
+
+wxThreadError wxThread::Delete(ExitCode *pRc)
+{
+ ExitCode rc = 0;
+
+ // Delete() is always safe to call, so consider all possible states
+
+ // has the thread started to run?
+ bool shouldResume = FALSE;
+
+ {
+ wxCriticalSectionLocker lock(m_critsect);
+
+ if ( m_internal->GetState() == STATE_NEW )
+ {
+ // WinThreadStart() will see it and terminate immediately
+ m_internal->SetState(STATE_EXITED);
+
+ shouldResume = TRUE;
+ }
+ }
+
+ // is the thread paused?
+ if ( shouldResume || IsPaused() )
+ Resume();
+
+ // does is still run?
+ if ( IsRunning() )
+ {
+ if ( IsMain() )
+ {
+ // set flag for wxIsWaitingForThread()
+ gs_waitingForThread = TRUE;
+
+#if wxUSE_GUI
+ wxBeginBusyCursor();
+#endif // wxUSE_GUI
+ }
+
+ // ask the thread to terminate
+ {
+ wxCriticalSectionLocker lock(m_critsect);
+
+ m_internal->Cancel();
+ }
+
+#if wxUSE_GUI
+ // simply wait for the thread to terminate
+ while( TestDestroy() )
+ {
+ ::YieldToAnyThread() ;
+ }
+#else // !wxUSE_GUI
+ // simply wait for the thread to terminate
+ while( TestDestroy() )
+ {
+ ::YieldToAnyThread() ;
+ }
+#endif // wxUSE_GUI/!wxUSE_GUI
+
+ if ( IsMain() )
+ {
+ gs_waitingForThread = FALSE;
+
+#if wxUSE_GUI
+ wxEndBusyCursor();
+#endif // wxUSE_GUI
+ }
+ }
+
+ if ( IsDetached() )
+ {
+ // if the thread exits normally, this is done in WinThreadStart, but in
+ // this case it would have been too early because
+ // MsgWaitForMultipleObject() would fail if the therad handle was
+ // closed while we were waiting on it, so we must do it here
+ delete this;
+ }
+
+ if ( pRc )
+ *pRc = rc;
+
+ return rc == (ExitCode)-1 ? wxTHREAD_MISC_ERROR : wxTHREAD_NO_ERROR;
+}
+
+wxThreadError wxThread::Kill()
+{
+ if ( !IsRunning() )
+ return wxTHREAD_NOT_RUNNING;
+
+// if ( !::TerminateThread(m_internal->GetHandle(), (DWORD)-1) )
+ {
+ wxLogSysError(_("Couldn't terminate thread"));
+
+ return wxTHREAD_MISC_ERROR;
+ }
+
+ m_internal->Free();
+
+ if ( IsDetached() )
+ {
+ delete this;
+ }
+
+ return wxTHREAD_NO_ERROR;
+}
+
+void wxThread::Exit(ExitCode status)
+{
+ m_internal->Free();
+
+ if ( IsDetached() )
+ {
+ delete this;
+ }
+
+ m_internal->SetResult( status ) ;
+
+/*
+#if defined(__VISUALC__) || (defined(__BORLANDC__) && (__BORLANDC__ >= 0x500))
+ _endthreadex((unsigned)status);
+#else // !VC++
+ ::ExitThread((DWORD)status);
+#endif // VC++/!VC++
+*/
+ wxFAIL_MSG(wxT("Couldn't return from ExitThread()!"));
+}
+
+// priority setting
+// ----------------
+
+// since all these calls are execute cooperatively we don't have to use the critical section
+
+void wxThread::SetPriority(unsigned int prio)
+{
+ m_internal->SetPriority(prio);
+}
+
+unsigned int wxThread::GetPriority() const
+{
+ return m_internal->GetPriority();
+}
+
+unsigned long wxThread::GetId() const
+{
+ return (unsigned long)m_internal->GetId();
+}
+
+bool wxThread::IsRunning() const
+{
+ return m_internal->GetState() == STATE_RUNNING;
+}
+
+bool wxThread::IsAlive() const
+{
+ return (m_internal->GetState() == STATE_RUNNING) ||
+ (m_internal->GetState() == STATE_PAUSED);
+}
+
+bool wxThread::IsPaused() const
+{
+ return m_internal->GetState() == STATE_PAUSED;
+}
+
+bool wxThread::TestDestroy()
+{
+ return m_internal->GetState() == STATE_CANCELED;
+}
+
+// ----------------------------------------------------------------------------
+// Automatic initialization for thread module
+// ----------------------------------------------------------------------------
+
+class wxThreadModule : public wxModule
+{
+public:
+ virtual bool OnInit();
+ virtual void OnExit();
+
+private:
+ DECLARE_DYNAMIC_CLASS(wxThreadModule)
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
+
+bool wxThreadModule::OnInit()
+{
+ long response;
+ bool hasThreadManager ;
+ hasThreadManager = Gestalt( gestaltThreadMgrAttr, &response) == noErr && response & 1;
+#if !TARGET_CARBON
+#if GENERATINGCFM
+ // verify presence of shared library
+ hasThreadManager = hasThreadManager && ((Ptr)NewThread != (Ptr)kUnresolvedCFragSymbolAddress);
+#endif
+#endif
+ if ( !hasThreadManager )
+ {
+ wxLogSysError( wxT("Thread Support is not available on this System") );
+ return FALSE ;
+ }
+
+ // no error return for GetCurrentThreadId()
+ MacGetCurrentThread( &gs_idMainThread ) ;
+
+ return TRUE;
+}
+
+void wxThreadModule::OnExit()
+{
+}
+
+// ----------------------------------------------------------------------------
+// under MacOS we don't have currently preemptive threads, so any thread may access
+// the GUI at any time
+// ----------------------------------------------------------------------------
+
+void WXDLLEXPORT wxMutexGuiEnter()
+{
+}
+
+void WXDLLEXPORT wxMutexGuiLeave()
+{
+}
+
+void WXDLLEXPORT wxMutexGuiLeaveOrEnter()
+{
+}
+
+bool WXDLLEXPORT wxGuiOwnedByMainThread()
+{
+ return false ;
+}
+
+// wake up the main thread
+void WXDLLEXPORT wxWakeUpMainThread()
+{
+ wxMacWakeUp() ;
+}
+
+bool WXDLLEXPORT wxIsWaitingForThread()
+{
+ return false ;
+}
+
+#include "wx/thrimpl.cpp"
+
+#endif // wxUSE_THREADS
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: timer.cpp
+// Purpose: wxTimer implementation
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "timer.h"
+#endif
+
+#include "wx/timer.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_ABSTRACT_CLASS(wxTimer, wxObject)
+#endif
+
+#ifdef __WXMAC__
+#include "wx/mac/private.h"
+#endif
+#ifndef __DARWIN__
+#include <Timer.h>
+#endif
+
+#include "wx/dynarray.h"
+
+typedef struct MacTimerInfo
+{
+ TMTask m_task;
+ wxMacNotifierTableRef m_table ;
+ wxTimer* m_timer ;
+} ;
+
+static void wxProcessTimer( unsigned long event , void *data ) ;
+
+static pascal void MacTimerProc( TMTask * t )
+{
+ MacTimerInfo * tm = (MacTimerInfo*) t ;
+ wxMacAddEvent( tm->m_table , wxProcessTimer, 0 , (void*) tm->m_timer , TRUE ) ;
+}
+
+// we need this array to track timers that are being deleted within the Notify procedure
+// adding the timer before the Notify call and checking after whether it still is in there
+// as the destructor would have removed it from the array
+
+wxArrayPtrVoid gTimersInProcess ;
+
+static void wxProcessTimer( unsigned long event , void *data )
+{
+ if ( !data )
+ return ;
+
+ wxTimer* timer = (wxTimer*) data ;
+
+ if ( timer->IsOneShot() )
+ timer->Stop() ;
+
+ gTimersInProcess.Add( timer ) ;
+
+ timer->Notify();
+
+ int index = gTimersInProcess.Index( timer ) ;
+
+ if ( index != wxNOT_FOUND )
+ {
+ gTimersInProcess.RemoveAt( index ) ;
+
+ if ( !timer->IsOneShot() && timer->m_info->m_task.tmAddr )
+ {
+ PrimeTime( (QElemPtr) &timer->m_info->m_task , timer->GetInterval() ) ;
+ }
+
+ }
+}
+
+void wxTimer::Init()
+{
+ m_info = new MacTimerInfo() ;
+ m_info->m_task.tmAddr = NULL ;
+ m_info->m_task.tmWakeUp = 0 ;
+ m_info->m_task.tmReserved = 0 ;
+ m_info->m_task.qType = 0 ;
+ m_info->m_table = wxMacGetNotifierTable() ;
+ m_info->m_timer = this ;
+}
+
+bool wxTimer::IsRunning() const
+{
+ // as the qType may already indicate it is elapsed, but it
+ // was not handled internally yet
+ return ( m_info->m_task.tmAddr != NULL ) ;
+}
+
+wxTimer::~wxTimer()
+{
+ Stop();
+ if (m_info != NULL) {
+ delete m_info ;
+ m_info = NULL ;
+ }
+ int index = gTimersInProcess.Index( this ) ;
+ if ( index != wxNOT_FOUND )
+ gTimersInProcess.RemoveAt( index ) ;
+}
+
+bool wxTimer::Start(int milliseconds,bool mode)
+{
+ (void)wxTimerBase::Start(milliseconds, mode);
+
+ wxCHECK_MSG( m_milli > 0, FALSE, wxT("invalid value for timer timeout") );
+ wxCHECK_MSG( m_info->m_task.tmAddr == NULL , FALSE, wxT("attempting to restart a timer") );
+
+#if defined(UNIVERSAL_INTERFACES_VERSION) && (UNIVERSAL_INTERFACES_VERSION >= 0x0340)
+ m_info->m_task.tmAddr = NewTimerUPP( MacTimerProc ) ;
+#else
+ m_info->m_task.tmAddr = NewTimerProc( MacTimerProc ) ;
+#endif
+ m_info->m_task.tmWakeUp = 0 ;
+ m_info->m_task.tmReserved = 0 ;
+ m_info->m_task.qType = 0 ;
+ m_info->m_timer = this ;
+ InsXTime((QElemPtr) &m_info->m_task ) ;
+ PrimeTime( (QElemPtr) &m_info->m_task , m_milli ) ;
+ return TRUE;
+}
+
+void wxTimer::Stop()
+{
+ if ( m_info->m_task.tmAddr )
+ {
+ RmvTime( (QElemPtr) &m_info->m_task ) ;
+ DisposeTimerUPP(m_info->m_task.tmAddr) ;
+ m_info->m_task.tmAddr = NULL ;
+ }
+ wxMacRemoveAllNotifiersForData( wxMacGetNotifierTable() , this ) ;
+}
+
+
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: toolbar.cpp
+// Purpose: wxToolBar
+// Author: Stefan Csomor
+// Modified by:
+// Created: 04/01/98
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: The wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "toolbar.h"
+#endif
+
+#include "wx/wx.h"
+
+#if wxUSE_TOOLBAR
+
+#include "wx/toolbar.h"
+#include "wx/notebook.h"
+#include "wx/tabctrl.h"
+#include "wx/bitmap.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl)
+
+BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase)
+ EVT_MOUSE_EVENTS( wxToolBar::OnMouse )
+ EVT_PAINT( wxToolBar::OnPaint )
+END_EVENT_TABLE()
+#endif
+
+#include "wx/mac/uma.h"
+#include "wx/geometry.h"
+// ----------------------------------------------------------------------------
+// private classes
+// ----------------------------------------------------------------------------
+
+class wxToolBarTool : public wxToolBarToolBase
+{
+public:
+ wxToolBarTool(wxToolBar *tbar,
+ int id,
+ const wxString& label,
+ const wxBitmap& bmpNormal,
+ const wxBitmap& bmpDisabled,
+ wxItemKind kind,
+ wxObject *clientData,
+ const wxString& shortHelp,
+ const wxString& longHelp) ;
+
+ wxToolBarTool(wxToolBar *tbar, wxControl *control)
+ : wxToolBarToolBase(tbar, control)
+ {
+ Init() ;
+ }
+
+ ~wxToolBarTool()
+ {
+ if ( m_controlHandle )
+ DisposeControl( m_controlHandle ) ;
+ }
+
+ ControlHandle GetControlHandle() { return m_controlHandle ; }
+ void SetControlHandle( ControlHandle handle ) { m_controlHandle = handle ; }
+
+ void SetSize(const wxSize& size) ;
+ void SetPosition( const wxPoint& position ) ;
+ wxSize GetSize() const
+ {
+ if ( IsControl() )
+ {
+ return GetControl()->GetSize() ;
+ }
+ else if ( IsButton() )
+ {
+ return GetToolBar()->GetToolSize() ;
+ }
+ else
+ {
+ wxSize sz = GetToolBar()->GetToolSize() ;
+ sz.x /= 4 ;
+ sz.y /= 4 ;
+ return sz ;
+ }
+ }
+ wxPoint GetPosition() const
+ {
+ return wxPoint(m_x, m_y);
+ }
+private :
+ void Init()
+ {
+ m_controlHandle = NULL ;
+ }
+ ControlHandle m_controlHandle ;
+
+ wxCoord m_x;
+ wxCoord m_y;
+};
+
+// ============================================================================
+// implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxToolBarTool
+// ----------------------------------------------------------------------------
+
+void wxToolBarTool::SetSize(const wxSize& size)
+{
+ if ( IsControl() )
+ {
+ GetControl()->SetSize( size ) ;
+ }
+}
+
+void wxToolBarTool::SetPosition(const wxPoint& position)
+{
+ m_x = position.x;
+ m_y = position.y;
+
+ if ( IsButton() )
+ {
+ int x , y ;
+ x = y = 0 ;
+ WindowRef rootwindow = (WindowRef) GetToolBar()->MacGetRootWindow() ;
+ GetToolBar()->MacWindowToRootWindow( &x , &y ) ;
+ int mac_x = x + position.x ;
+ int mac_y = y + position.y ;
+
+
+ Rect contrlRect ;
+ GetControlBounds( m_controlHandle , &contrlRect ) ;
+ int former_mac_x = contrlRect.left ;
+ int former_mac_y = contrlRect.top ;
+ wxSize sz = GetToolBar()->GetToolSize() ;
+
+ if ( mac_x != former_mac_x || mac_y != former_mac_y )
+ {
+ {
+ Rect inval = { former_mac_y , former_mac_x , former_mac_y + sz.y , former_mac_x + sz.x } ;
+ InvalWindowRect( rootwindow , &inval ) ;
+ }
+ UMAMoveControl( m_controlHandle , mac_x , mac_y ) ;
+ {
+ Rect inval = { mac_y , mac_x , mac_y + sz.y , mac_x + sz.x } ;
+ InvalWindowRect( rootwindow , &inval ) ;
+ }
+ }
+ }
+ else if ( IsControl() )
+ {
+ GetControl()->Move( position ) ;
+ }
+}
+
+const short kwxMacToolBarToolDefaultWidth = 24 ;
+const short kwxMacToolBarToolDefaultHeight = 22 ;
+const short kwxMacToolBarTopMargin = 2 ;
+const short kwxMacToolBarLeftMargin = 2 ;
+
+wxToolBarTool::wxToolBarTool(wxToolBar *tbar,
+ int id,
+ const wxString& label,
+ const wxBitmap& bmpNormal,
+ const wxBitmap& bmpDisabled,
+ wxItemKind kind,
+ wxObject *clientData,
+ const wxString& shortHelp,
+ const wxString& longHelp)
+ : wxToolBarToolBase(tbar, id, label, bmpNormal, bmpDisabled, kind,
+ clientData, shortHelp, longHelp)
+{
+ Init();
+
+ if (id == wxID_SEPARATOR) return;
+
+ WindowRef window = (WindowRef) tbar->MacGetRootWindow() ;
+ wxSize toolSize = tbar->GetToolSize() ;
+ Rect toolrect = { 0, 0 , toolSize.y , toolSize.x } ;
+
+ ControlButtonContentInfo info ;
+ wxMacCreateBitmapButton( &info , GetNormalBitmap() ) ;
+
+ SInt16 behaviour = kControlBehaviorOffsetContents ;
+ if ( CanBeToggled() )
+ behaviour += kControlBehaviorToggles ;
+
+ if ( info.contentType != kControlNoContent )
+ {
+ m_controlHandle = ::NewControl( window , &toolrect , "\p" , false , 0 ,
+ behaviour + info.contentType , 0 , kControlBevelButtonNormalBevelProc , (long) this ) ;
+
+ ::SetControlData( m_controlHandle , kControlButtonPart , kControlBevelButtonContentTag , sizeof(info) , (char*) &info ) ;
+ }
+ else
+ {
+ m_controlHandle = ::NewControl( window , &toolrect , "\p" , false , 0 ,
+ behaviour , 0 , kControlBevelButtonNormalBevelProc , (long) this ) ;
+ }
+ UMAShowControl( m_controlHandle ) ;
+ if ( !IsEnabled() )
+ {
+ UMADeactivateControl( m_controlHandle ) ;
+ }
+ if ( CanBeToggled() && IsToggled() )
+ {
+ ::SetControl32BitValue( m_controlHandle , 1 ) ;
+ }
+ else
+ {
+ ::SetControl32BitValue( m_controlHandle , 0 ) ;
+ }
+
+ ControlHandle container = (ControlHandle) tbar->MacGetContainerForEmbedding() ;
+ wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ;
+ ::EmbedControl( m_controlHandle , container ) ;
+}
+
+
+wxToolBarToolBase *wxToolBar::CreateTool(int id,
+ const wxString& label,
+ const wxBitmap& bmpNormal,
+ const wxBitmap& bmpDisabled,
+ wxItemKind kind,
+ wxObject *clientData,
+ const wxString& shortHelp,
+ const wxString& longHelp)
+{
+ return new wxToolBarTool(this, id, label, bmpNormal, bmpDisabled, kind,
+ clientData, shortHelp, longHelp);
+}
+
+wxToolBarToolBase *wxToolBar::CreateTool(wxControl *control)
+{
+ return new wxToolBarTool(this, control);
+}
+
+void wxToolBar::Init()
+{
+ m_maxWidth = -1;
+ m_maxHeight = -1;
+ m_defaultWidth = kwxMacToolBarToolDefaultWidth;
+ m_defaultHeight = kwxMacToolBarToolDefaultHeight;
+}
+
+bool wxToolBar::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
+ long style, const wxString& name)
+{
+ int x = pos.x;
+ int y = pos.y;
+ int width = size.x;
+ int height = size.y;
+
+ if (width <= 0)
+ width = 100;
+ if (height <= 0)
+ height = 30;
+ if (x < 0)
+ x = 0;
+ if (y < 0)
+ y = 0;
+
+ SetName(name);
+
+ m_windowStyle = style;
+ parent->AddChild(this);
+
+ m_backgroundColour = parent->GetBackgroundColour() ;
+ m_foregroundColour = parent->GetForegroundColour() ;
+
+ if (id == -1)
+ m_windowId = NewControlId();
+ else
+ m_windowId = id;
+
+ {
+ m_width = size.x ;
+ m_height = size.y ;
+ int x = pos.x ;
+ int y = pos.y ;
+ AdjustForParentClientOrigin(x, y, wxSIZE_USE_EXISTING);
+ m_x = x ;
+ m_y = y ;
+ }
+
+ return TRUE;
+}
+
+wxToolBar::~wxToolBar()
+{
+ // we must refresh the frame size when the toolbar is deleted but the frame
+ // is not - otherwise toolbar leaves a hole in the place it used to occupy
+}
+
+bool wxToolBar::Realize()
+{
+ if (m_tools.GetCount() == 0)
+ return FALSE;
+
+ int x = m_xMargin + kwxMacToolBarLeftMargin ;
+ int y = m_yMargin + kwxMacToolBarTopMargin ;
+
+ int tw, th;
+ GetSize(& tw, & th);
+
+ int maxWidth = 0 ;
+ int maxHeight = 0 ;
+
+ int maxToolWidth = 0;
+ int maxToolHeight = 0;
+
+ // Find the maximum tool width and height
+ wxToolBarToolsList::Node *node = m_tools.GetFirst();
+ while ( node )
+ {
+ wxToolBarTool *tool = (wxToolBarTool *)node->GetData();
+ wxSize sz = tool->GetSize() ;
+
+ if ( sz.x > maxToolWidth )
+ maxToolWidth = sz.x ;
+ if (sz.y> maxToolHeight)
+ maxToolHeight = sz.y;
+
+ node = node->GetNext();
+ }
+
+ node = m_tools.GetFirst();
+ while (node)
+ {
+ wxToolBarTool *tool = (wxToolBarTool *)node->GetData();
+ wxSize cursize = tool->GetSize() ;
+
+ // for the moment we just do a single row/column alignement
+ if ( x + cursize.x > maxWidth )
+ maxWidth = x + cursize.x ;
+ if ( y + cursize.y > maxHeight )
+ maxHeight = y + cursize.y ;
+
+ tool->SetPosition( wxPoint( x , y ) ) ;
+
+ if ( GetWindowStyleFlag() & wxTB_VERTICAL )
+ {
+ y += cursize.y ;
+ }
+ else
+ {
+ x += cursize.x ;
+ }
+
+ node = node->GetNext();
+ }
+
+ if ( GetWindowStyleFlag() & wxTB_HORIZONTAL )
+ {
+ if ( m_maxRows == 0 )
+ {
+ // if not set yet, only one row
+ SetRows(1);
+ }
+ maxWidth = tw ;
+ maxHeight += m_yMargin + kwxMacToolBarTopMargin;
+ m_maxHeight = maxHeight ;
+ }
+ else
+ {
+ if ( GetToolsCount() > 0 && m_maxRows == 0 )
+ {
+ // if not set yet, have one column
+ SetRows(GetToolsCount());
+ }
+ maxHeight = th ;
+ maxWidth += m_xMargin + kwxMacToolBarLeftMargin;
+ m_maxWidth = maxWidth ;
+ }
+
+ SetSize(maxWidth, maxHeight);
+
+ return TRUE;
+}
+
+void wxToolBar::SetToolBitmapSize(const wxSize& size)
+{
+ m_defaultWidth = size.x+4; m_defaultHeight = size.y+4;
+}
+
+// The button size is bigger than the bitmap size
+wxSize wxToolBar::GetToolSize() const
+{
+ return wxSize(m_defaultWidth + 4, m_defaultHeight + 4);
+}
+
+void wxToolBar::MacHandleControlClick( WXWidget control , wxInt16 controlpart , bool WXUNUSED( mouseStillDown ) )
+{
+ wxToolBarToolsList::Node *node;
+ for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
+ {
+ wxToolBarTool* tool = (wxToolBarTool*) node->GetData() ;
+ if ( tool->IsButton() )
+ {
+ if( tool->GetControlHandle() == control )
+ {
+ if ( tool->CanBeToggled() )
+ {
+ tool->Toggle( GetControl32BitValue( (ControlHandle) control ) ) ;
+ }
+ OnLeftClick( tool->GetId() , tool -> IsToggled() ) ;
+ break ;
+ }
+ }
+ }
+}
+
+void wxToolBar::SetRows(int nRows)
+{
+ if ( nRows == m_maxRows )
+ {
+ // avoid resizing the frame uselessly
+ return;
+ }
+
+ m_maxRows = nRows;
+}
+
+void wxToolBar::MacSuperChangedPosition()
+{
+ wxWindow::MacSuperChangedPosition() ;
+ Realize() ;
+}
+
+wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord x, wxCoord y) const
+{
+ wxToolBarToolsList::Node *node = m_tools.GetFirst();
+ while (node)
+ {
+ wxToolBarTool *tool = (wxToolBarTool *)node->GetData() ;
+ wxRect2DInt r( tool->GetPosition() , tool->GetSize() ) ;
+ if ( r.Contains( wxPoint( x , y ) ) )
+ {
+ return tool;
+ }
+
+ node = node->GetNext();
+ }
+
+ return (wxToolBarToolBase *)NULL;
+}
+
+wxString wxToolBar::MacGetToolTipString( wxPoint &pt )
+{
+ wxToolBarToolBase* tool = FindToolForPosition( pt.x , pt.y ) ;
+ if ( tool )
+ {
+ return tool->GetShortHelp() ;
+ }
+ return wxEmptyString ;
+}
+
+void wxToolBar::DoEnableTool(wxToolBarToolBase *t, bool enable)
+{
+ if (!IsShown())
+ return ;
+
+ wxToolBarTool *tool = (wxToolBarTool *)t;
+ if ( tool->IsControl() )
+ {
+ tool->GetControl()->Enable( enable ) ;
+ }
+ else if ( tool->IsButton() )
+ {
+ if ( enable )
+ UMAActivateControl( tool->GetControlHandle() ) ;
+ else
+ UMADeactivateControl( tool->GetControlHandle() ) ;
+ }
+}
+
+void wxToolBar::DoToggleTool(wxToolBarToolBase *t, bool toggle)
+{
+ if (!IsShown())
+ return ;
+
+ wxToolBarTool *tool = (wxToolBarTool *)t;
+ if ( tool->IsButton() )
+ {
+ ::SetControl32BitValue( tool->GetControlHandle() , toggle ) ;
+ }
+}
+
+bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos),
+ wxToolBarToolBase *tool)
+{
+ // nothing special to do here - we relayout in Realize() later
+ tool->Attach(this);
+
+ return TRUE;
+}
+
+void wxToolBar::DoSetToggle(wxToolBarToolBase *WXUNUSED(tool), bool WXUNUSED(toggle))
+{
+ wxFAIL_MSG( _T("not implemented") );
+}
+
+bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), wxToolBarToolBase *tool)
+{
+ wxToolBarToolsList::Node *node;
+ for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
+ {
+ wxToolBarToolBase *tool2 = node->GetData();
+ if ( tool2 == tool )
+ {
+ // let node point to the next node in the list
+ node = node->GetNext();
+
+ break;
+ }
+ }
+
+ wxSize sz = ((wxToolBarTool*)tool)->GetSize() ;
+
+ tool->Detach();
+
+ // and finally reposition all the controls after this one
+
+ for ( /* node -> first after deleted */ ; node; node = node->GetNext() )
+ {
+ wxToolBarTool *tool2 = (wxToolBarTool*) node->GetData();
+ wxPoint pt = tool2->GetPosition() ;
+
+ if ( GetWindowStyleFlag() & wxTB_VERTICAL )
+ {
+ pt.y -= sz.y ;
+ }
+ else
+ {
+ pt.x -= sz.x ;
+ }
+ tool2->SetPosition( pt ) ;
+ }
+
+ return TRUE ;
+}
+
+void wxToolBar::OnPaint(wxPaintEvent& event)
+{
+ wxPaintDC dc(this) ;
+ wxMacPortSetter helper(&dc) ;
+
+ Rect toolbarrect = { dc.YLOG2DEVMAC(0) , dc.XLOG2DEVMAC(0) ,
+ dc.YLOG2DEVMAC(m_height) , dc.XLOG2DEVMAC(m_width) } ;
+ UMADrawThemePlacard( &toolbarrect , IsEnabled() ? kThemeStateActive : kThemeStateInactive) ;
+ {
+ wxToolBarToolsList::Node *node;
+ for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
+ {
+ wxToolBarTool* tool = (wxToolBarTool*) node->GetData() ;
+ if ( tool->IsButton() )
+ {
+ UMADrawControl( tool->GetControlHandle() ) ;
+ }
+ }
+ }
+}
+
+void wxToolBar::OnMouse( wxMouseEvent &event )
+{
+ if (event.GetEventType() == wxEVT_LEFT_DOWN || event.GetEventType() == wxEVT_LEFT_DCLICK )
+ {
+
+ int x = event.m_x ;
+ int y = event.m_y ;
+
+ MacClientToRootWindow( &x , &y ) ;
+
+ ControlHandle control ;
+ Point localwhere ;
+ SInt16 controlpart ;
+ WindowRef window = (WindowRef) MacGetRootWindow() ;
+
+ localwhere.h = x ;
+ localwhere.v = y ;
+
+ short modifiers = 0;
+
+ if ( !event.m_leftDown && !event.m_rightDown )
+ modifiers |= btnState ;
+
+ if ( event.m_shiftDown )
+ modifiers |= shiftKey ;
+
+ if ( event.m_controlDown )
+ modifiers |= controlKey ;
+
+ if ( event.m_altDown )
+ modifiers |= optionKey ;
+
+ if ( event.m_metaDown )
+ modifiers |= cmdKey ;
+
+ controlpart = ::FindControl( localwhere , window , &control ) ;
+ {
+ if ( control && ::IsControlActive( control ) )
+ {
+ {
+ controlpart = ::HandleControlClick( control , localwhere , modifiers , (ControlActionUPP) -1 ) ;
+ wxTheApp->s_lastMouseDown = 0 ;
+ if ( control && controlpart != kControlNoPart ) // otherwise we will get the event twice
+ {
+ MacHandleControlClick( control , controlpart , false /* not down anymore */ ) ;
+ }
+ }
+ }
+ }
+ }
+}
+
+#endif // wxUSE_TOOLBAR
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: tooltip.cpp
+// Purpose: wxToolTip implementation
+// Author: Robert Roebling
+// Id: $Id$
+// Copyright: (c) 1998 Robert Roebling
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+ #pragma implementation "tooltip.h"
+#endif
+
+#include "wx/defs.h"
+
+#if wxUSE_TOOLTIPS
+
+#include "wx/app.h"
+#include "wx/dc.h"
+#include "wx/window.h"
+#include "wx/tooltip.h"
+#include "wx/timer.h"
+#include "wx/geometry.h"
+#include "wx/mac/uma.h"
+
+//-----------------------------------------------------------------------------
+// global data
+//-----------------------------------------------------------------------------
+
+class wxMacToolTipTimer ;
+
+class wxMacToolTip
+{
+ public :
+ wxMacToolTip( ) ;
+ ~wxMacToolTip() ;
+
+ void Setup( WindowRef window , const wxString& text , wxPoint localPosition ) ;
+ long GetMark() { return m_mark ; }
+ void Draw() ;
+ void Clear() ;
+ bool IsShown() { return m_shown ; }
+ private :
+
+ wxString m_label ;
+ wxPoint m_position ;
+ Rect m_rect ;
+ WindowRef m_window ;
+ PicHandle m_backpict ;
+ bool m_shown ;
+ long m_mark ;
+ wxMacToolTipTimer* m_timer ;
+#if TARGET_CARBON
+ wxMacCFStringHolder m_helpTextRef ;
+#endif
+} ;
+
+class wxMacToolTipTimer : public wxTimer
+{
+public:
+ wxMacToolTipTimer() {} ;
+ wxMacToolTipTimer(wxMacToolTip* tip, int iMilliseconds) ;
+ virtual ~wxMacToolTipTimer() {} ;
+ void Notify()
+ {
+ if ( m_mark == m_tip->GetMark() )
+ m_tip->Draw() ;
+ }
+protected:
+ wxMacToolTip* m_tip;
+ long m_mark ;
+};
+
+//-----------------------------------------------------------------------------
+// wxToolTip
+//-----------------------------------------------------------------------------
+static long s_ToolTipDelay = 500 ;
+static bool s_ShowToolTips = true ;
+static wxMacToolTip s_ToolTip ;
+static wxWindow* s_LastWindowEntered = NULL ;
+static wxRect2DInt s_ToolTipArea ;
+static WindowRef s_ToolTipWindowRef = NULL ;
+
+IMPLEMENT_ABSTRACT_CLASS(wxToolTip, wxObject)
+
+wxToolTip::wxToolTip( const wxString &tip )
+{
+ m_text = tip;
+ m_window = (wxWindow*) NULL;
+}
+
+wxToolTip::~wxToolTip()
+{
+}
+
+void wxToolTip::SetTip( const wxString &tip )
+{
+ m_text = tip;
+
+ if ( m_window )
+ {
+ /*
+ // update it immediately
+ wxToolInfo ti(GetHwndOf(m_window));
+ ti.lpszText = (wxChar *)m_text.c_str();
+
+ (void)SendTooltipMessage(GetToolTipCtrl(), TTM_UPDATETIPTEXT, 0, &ti);
+ */
+ }
+}
+
+void wxToolTip::SetWindow( wxWindow *win )
+{
+ m_window = win ;
+}
+
+void wxToolTip::Enable( bool flag )
+{
+ if ( s_ShowToolTips != flag )
+ {
+ s_ShowToolTips = flag ;
+ if ( s_ShowToolTips )
+ {
+ }
+ else
+ {
+ s_ToolTip.Clear() ;
+ }
+ }
+}
+
+void wxToolTip::SetDelay( long msecs )
+{
+ s_ToolTipDelay = msecs ;
+}
+
+void wxToolTip::RelayEvent( wxWindow *win , wxMouseEvent &event )
+{
+ if ( s_ShowToolTips )
+ {
+ if ( event.GetEventType() == wxEVT_LEAVE_WINDOW )
+ {
+ s_ToolTip.Clear() ;
+ }
+ else if (event.GetEventType() == wxEVT_ENTER_WINDOW || event.GetEventType() == wxEVT_MOTION )
+ {
+ wxPoint2DInt where( event.m_x , event.m_y ) ;
+ if ( s_LastWindowEntered == win && s_ToolTipArea.Contains( where ) )
+ {
+ }
+ else
+ {
+ s_ToolTip.Clear() ;
+ s_ToolTipArea = wxRect2DInt( event.m_x - 2 , event.m_y - 2 , 4 , 4 ) ;
+ s_LastWindowEntered = win ;
+
+ WindowRef window = MAC_WXHWND( win->MacGetRootWindow() ) ;
+ int x = event.m_x ;
+ int y = event.m_y ;
+ wxPoint local( x , y ) ;
+ win->MacClientToRootWindow( &x, &y ) ;
+ wxPoint windowlocal( x , y ) ;
+ s_ToolTip.Setup( window , win->MacGetToolTipString( local ) , windowlocal ) ;
+ }
+ }
+ }
+}
+
+void wxToolTip::RemoveToolTips()
+{
+ s_ToolTip.Clear() ;
+}
+// --- mac specific
+
+wxMacToolTipTimer::wxMacToolTipTimer( wxMacToolTip *tip , int msec )
+{
+ m_tip = tip;
+ m_mark = tip->GetMark() ;
+ Start(msec, true);
+}
+
+wxMacToolTip::wxMacToolTip()
+{
+ m_window = NULL ;
+ m_backpict = NULL ;
+ m_mark = 0 ;
+ m_shown = false ;
+ m_timer = NULL ;
+}
+
+void wxMacToolTip::Setup( WindowRef win , const wxString& text , wxPoint localPosition )
+{
+ m_mark++ ;
+ Clear() ;
+ m_position = localPosition ;
+ m_label = text ;
+ m_window =win;
+ s_ToolTipWindowRef = m_window ;
+ m_backpict = NULL ;
+ if ( m_timer )
+ delete m_timer ;
+ m_timer = new wxMacToolTipTimer( this , s_ToolTipDelay ) ;
+}
+
+wxMacToolTip::~wxMacToolTip()
+{
+ if ( m_timer ) {
+ delete m_timer ;
+ m_timer = NULL;
+ }
+ if ( m_backpict )
+ Clear() ;
+}
+
+const short kTipBorder = 2 ;
+const short kTipOffset = 5 ;
+
+void wxMacToolTip::Draw()
+{
+ if ( m_label.Length() == 0 )
+ return ;
+
+ if ( m_window == s_ToolTipWindowRef )
+ {
+ m_shown = true ;
+#if TARGET_CARBON
+ HMHelpContentRec tag ;
+ tag.version = kMacHelpVersion;
+ SetRect( &tag.absHotRect , m_position.x - 2 , m_position.y - 2 , m_position.x + 2 , m_position.y + 2 ) ;
+ GrafPtr port ;
+ GetPort( &port ) ;
+ SetPortWindowPort(m_window) ;
+ LocalToGlobal( (Point *) &tag.absHotRect.top );
+ LocalToGlobal( (Point *) &tag.absHotRect.bottom );
+ SetPort( port );
+ m_helpTextRef.Assign( m_label , wxFONTENCODING_DEFAULT ) ;
+ tag.content[kHMMinimumContentIndex].contentType = kHMCFStringContent ;
+ tag.content[kHMMinimumContentIndex].u.tagCFString = m_helpTextRef ;
+ tag.content[kHMMaximumContentIndex].contentType = kHMCFStringContent ;
+ tag.content[kHMMaximumContentIndex].u.tagCFString = m_helpTextRef ;
+ tag.tagSide = kHMDefaultSide;
+ HMDisplayTag( &tag );
+#else
+ wxMacPortStateHelper help( (GrafPtr) GetWindowPort( m_window ) );
+ FontFamilyID fontId ;
+ Str255 fontName ;
+ SInt16 fontSize ;
+ Style fontStyle ;
+ GetThemeFont(kThemeSmallSystemFont , GetApplicationScript() , fontName , &fontSize , &fontStyle ) ;
+ GetFNum( fontName, &fontId );
+
+ TextFont( fontId ) ;
+ TextSize( fontSize ) ;
+ TextFace( fontStyle ) ;
+ FontInfo fontInfo;
+ ::GetFontInfo(&fontInfo);
+ short lineh = fontInfo.ascent + fontInfo.descent + fontInfo.leading;
+ short height = 0 ;
+
+ int i = 0 ;
+ int length = m_label.Length() ;
+ int width = 0 ;
+ int thiswidth = 0 ;
+ int laststop = 0 ;
+ wxCharBuffer text = m_label.mb_str( wxConvLocal) ;
+
+ while( i < length )
+ {
+ if( text[i] == 13 || text[i] == 10)
+ {
+ thiswidth = ::TextWidth( text , laststop , i - laststop ) ;
+ if ( thiswidth > width )
+ width = thiswidth ;
+
+ height += lineh ;
+ laststop = i+1 ;
+ }
+ i++ ;
+ }
+ if ( i - laststop > 0 )
+ {
+ thiswidth = ::TextWidth( text , laststop , i - laststop ) ;
+ if ( thiswidth > width )
+ width = thiswidth ;
+ height += lineh ;
+ }
+
+ m_rect.left = m_position.x + kTipOffset;
+ m_rect.top = m_position.y + kTipOffset;
+ m_rect.right = m_rect.left + width + 2 * kTipBorder;
+
+ m_rect.bottom = m_rect.top + height + 2 * kTipBorder;
+ Rect r ;
+ GetPortBounds( GetWindowPort( m_window ) , &r ) ;
+ if ( m_rect.top < 0 )
+ {
+ m_rect.bottom += -m_rect.top ;
+ m_rect.top = 0 ;
+ }
+ if ( m_rect.left < 0 )
+ {
+ m_rect.right += -m_rect.left ;
+ m_rect.left = 0 ;
+ }
+ if ( m_rect.right > r.right )
+ {
+ m_rect.left -= (m_rect.right - r.right ) ;
+ m_rect.right = r.right ;
+ }
+ if ( m_rect.bottom > r.bottom )
+ {
+ m_rect.top -= (m_rect.bottom - r.bottom) ;
+ m_rect.bottom = r.bottom ;
+ }
+ ClipRect( &m_rect ) ;
+ BackColor( whiteColor ) ;
+ ForeColor(blackColor ) ;
+ GWorldPtr port ;
+ NewGWorld( &port , wxDisplayDepth() , &m_rect , NULL , NULL , 0 ) ;
+ CGrafPtr origPort ;
+ GDHandle origDevice ;
+
+ GetGWorld( &origPort , &origDevice ) ;
+ SetGWorld( port , NULL ) ;
+
+ m_backpict = OpenPicture(&m_rect);
+
+ CopyBits(GetPortBitMapForCopyBits(GetWindowPort(m_window)),
+ GetPortBitMapForCopyBits(port),
+ &m_rect,
+ &m_rect,
+ srcCopy,
+ NULL);
+ ClosePicture();
+ SetGWorld( origPort , origDevice ) ;
+ DisposeGWorld( port ) ;
+ PenNormal() ;
+
+ RGBColor tooltipbackground = { 0xFFFF , 0xFFFF , 0xC000 } ;
+ BackColor( whiteColor ) ;
+ RGBForeColor( &tooltipbackground ) ;
+
+ PaintRect( &m_rect ) ;
+ ForeColor(blackColor ) ;
+ FrameRect( &m_rect ) ;
+ SetThemeTextColor(kThemeTextColorNotification,wxDisplayDepth(),true) ;
+ ::MoveTo( m_rect.left + kTipBorder , m_rect.top + fontInfo.ascent + kTipBorder);
+
+ i = 0 ;
+ laststop = 0 ;
+ height = 0 ;
+
+ while( i < length )
+ {
+ if( text[i] == 13 || text[i] == 10)
+ {
+ ::DrawText( text , laststop , i - laststop ) ;
+ height += lineh ;
+ ::MoveTo( m_rect.left + kTipBorder , m_rect.top + fontInfo.ascent + kTipBorder + height );
+ laststop = i+1 ;
+ }
+ i++ ;
+ }
+ ::DrawText( text , laststop , i - laststop ) ;
+ ::TextMode( srcOr ) ;
+#endif
+ }
+}
+
+void wxToolTip::NotifyWindowDelete( WXHWND win )
+{
+ if ( win == s_ToolTipWindowRef )
+ {
+ s_ToolTipWindowRef = NULL ;
+ }
+}
+
+void wxMacToolTip::Clear()
+{
+ m_mark++ ;
+ if ( m_timer )
+ {
+ delete m_timer ;
+ m_timer = NULL ;
+ }
+ if ( !m_shown )
+ return ;
+#if TARGET_CARBON
+ HMHideTag() ;
+ m_helpTextRef.Release() ;
+#else
+ if ( m_window == s_ToolTipWindowRef && m_backpict )
+ {
+ wxMacPortStateHelper help( (GrafPtr) GetWindowPort(m_window) ) ;
+
+ m_shown = false ;
+
+ BackColor( whiteColor ) ;
+ ForeColor(blackColor ) ;
+ DrawPicture(m_backpict, &m_rect);
+ KillPicture(m_backpict);
+ m_backpict = NULL ;
+ }
+#endif
+}
+
+#endif
+
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Name: mac/toplevel.cpp
+// Purpose: implements wxTopLevelWindow for Mac
+// Author: Stefan Csomor
+// Modified by:
+// Created: 24.09.01
+// RCS-ID: $Id$
+// Copyright: (c) 2001-2004 Stefan Csomor
+// License: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#ifdef __GNUG__
+ #pragma implementation "toplevel.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+ #include "wx/app.h"
+ #include "wx/toplevel.h"
+ #include "wx/frame.h"
+ #include "wx/string.h"
+ #include "wx/log.h"
+ #include "wx/intl.h"
+#endif //WX_PRECOMP
+
+#include "wx/mac/uma.h"
+#include "wx/mac/aga.h"
+#include "wx/app.h"
+#include "wx/tooltip.h"
+#include "wx/dnd.h"
+#if wxUSE_SYSTEM_OPTIONS
+ #include "wx/sysopt.h"
+#endif
+
+#include <ToolUtils.h>
+
+
+#define wxMAC_DEBUG_REDRAW 0
+#ifndef wxMAC_DEBUG_REDRAW
+#define wxMAC_DEBUG_REDRAW 0
+#endif
+
+// ----------------------------------------------------------------------------
+// globals
+// ----------------------------------------------------------------------------
+
+// list of all frames and modeless dialogs
+wxWindowList wxModelessWindows;
+
+// double click testing
+static Point gs_lastWhere;
+static long gs_lastWhen = 0;
+
+
+#if TARGET_CARBON
+static pascal long wxShapedMacWindowDef(short varCode, WindowRef window, SInt16 message, SInt32 param);
+#endif
+
+// ============================================================================
+// wxTopLevelWindowMac implementation
+// ============================================================================
+
+// ---------------------------------------------------------------------------
+// Carbon Events
+// ---------------------------------------------------------------------------
+
+#if TARGET_CARBON
+
+extern long wxMacTranslateKey(unsigned char key, unsigned char code) ;
+
+static const EventTypeSpec eventList[] =
+{
+ { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent } ,
+
+ { kEventClassKeyboard, kEventRawKeyDown } ,
+ { kEventClassKeyboard, kEventRawKeyRepeat } ,
+ { kEventClassKeyboard, kEventRawKeyUp } ,
+ { kEventClassKeyboard, kEventRawKeyModifiersChanged } ,
+
+ { kEventClassWindow , kEventWindowShown } ,
+ { kEventClassWindow , kEventWindowUpdate } ,
+ { kEventClassWindow , kEventWindowActivated } ,
+ { kEventClassWindow , kEventWindowDeactivated } ,
+ { kEventClassWindow , kEventWindowBoundsChanging } ,
+ { kEventClassWindow , kEventWindowBoundsChanged } ,
+ { kEventClassWindow , kEventWindowClose } ,
+
+ { kEventClassMouse , kEventMouseDown } ,
+ { kEventClassMouse , kEventMouseUp } ,
+ { kEventClassMouse , kEventMouseWheelMoved } ,
+ { kEventClassMouse , kEventMouseMoved } ,
+ { kEventClassMouse , kEventMouseDragged } ,
+
+} ;
+
+static pascal OSStatus TextInputEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
+{
+ OSStatus result = eventNotHandledErr ;
+
+ wxWindow* focus = wxWindow::FindFocus() ;
+ char charCode ;
+ UInt32 keyCode ;
+ UInt32 modifiers ;
+ Point point ;
+
+ EventRef rawEvent ;
+
+ GetEventParameter( event , kEventParamTextInputSendKeyboardEvent ,typeEventRef,NULL,sizeof(rawEvent),NULL,&rawEvent ) ;
+
+ GetEventParameter( rawEvent, kEventParamKeyMacCharCodes, typeChar, NULL,sizeof(char), NULL,&charCode );
+ GetEventParameter( rawEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode );
+ GetEventParameter( rawEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);
+ GetEventParameter( rawEvent, kEventParamMouseLocation, typeQDPoint, NULL,
+ sizeof( Point ), NULL, &point );
+
+ switch ( GetEventKind( event ) )
+ {
+ case kEventTextInputUnicodeForKeyEvent :
+ // this is only called when no default handler has jumped in, eg a wxControl on a floater window does not
+ // get its own kEventTextInputUnicodeForKeyEvent, so we route back the
+ wxControl* control = wxDynamicCast( focus , wxControl ) ;
+ if ( control )
+ {
+ ControlHandle macControl = (ControlHandle) control->GetMacControl() ;
+ if ( macControl )
+ {
+ ::HandleControlKey( macControl , keyCode , charCode , modifiers ) ;
+ result = noErr ;
+ }
+ }
+ /*
+ // this may lead to double events sent to a window in case all handlers have skipped the key down event
+ UInt32 when = EventTimeToTicks( GetEventTime( event ) ) ;
+ UInt32 message = (keyCode << 8) + charCode;
+
+ if ( (focus != NULL) && wxTheApp->MacSendKeyDownEvent(
+ focus , message , modifiers , when , point.h , point.v ) )
+ {
+ result = noErr ;
+ }
+ */
+ break ;
+ }
+
+ return result ;
+}
+
+static pascal OSStatus KeyboardEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
+{
+ OSStatus result = eventNotHandledErr ;
+
+ wxWindow* focus = wxWindow::FindFocus() ;
+ char charCode ;
+ UInt32 keyCode ;
+ UInt32 modifiers ;
+ Point point ;
+ UInt32 when = EventTimeToTicks( GetEventTime( event ) ) ;
+
+ GetEventParameter( event, kEventParamKeyMacCharCodes, typeChar, NULL,sizeof(char), NULL,&charCode );
+ GetEventParameter( event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode );
+ GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);
+ GetEventParameter( event, kEventParamMouseLocation, typeQDPoint, NULL,
+ sizeof( Point ), NULL, &point );
+
+ UInt32 message = (keyCode << 8) + charCode;
+ switch( GetEventKind( event ) )
+ {
+ case kEventRawKeyRepeat :
+ case kEventRawKeyDown :
+ {
+ WXEVENTREF formerEvent = wxTheApp->MacGetCurrentEvent() ;
+ WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ;
+ wxTheApp->MacSetCurrentEvent( event , handler ) ;
+ if ( (focus != NULL) && wxTheApp->MacSendKeyDownEvent(
+ focus , message , modifiers , when , point.h , point.v ) )
+ {
+ result = noErr ;
+ }
+ wxTheApp->MacSetCurrentEvent( formerEvent , formerHandler ) ;
+ }
+ break ;
+ case kEventRawKeyUp :
+ if ( (focus != NULL) && wxTheApp->MacSendKeyUpEvent(
+ focus , message , modifiers , when , point.h , point.v ) )
+ {
+ result = noErr ;
+ }
+ break ;
+ case kEventRawKeyModifiersChanged :
+ {
+ wxKeyEvent event(wxEVT_KEY_DOWN);
+
+ event.m_shiftDown = modifiers & shiftKey;
+ event.m_controlDown = modifiers & controlKey;
+ event.m_altDown = modifiers & optionKey;
+ event.m_metaDown = modifiers & cmdKey;
+
+ event.m_x = point.h;
+ event.m_y = point.v;
+ event.m_timeStamp = when;
+ wxWindow* focus = wxWindow::FindFocus() ;
+ event.SetEventObject(focus);
+
+ if ( focus && (modifiers ^ wxTheApp->s_lastModifiers ) & controlKey )
+ {
+ event.m_keyCode = WXK_CONTROL ;
+ event.SetEventType( ( modifiers & controlKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
+ focus->GetEventHandler()->ProcessEvent( event ) ;
+ }
+ if ( focus && (modifiers ^ wxTheApp->s_lastModifiers ) & shiftKey )
+ {
+ event.m_keyCode = WXK_SHIFT ;
+ event.SetEventType( ( modifiers & shiftKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
+ focus->GetEventHandler()->ProcessEvent( event ) ;
+ }
+ if ( focus && (modifiers ^ wxTheApp->s_lastModifiers ) & optionKey )
+ {
+ event.m_keyCode = WXK_ALT ;
+ event.SetEventType( ( modifiers & optionKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
+ focus->GetEventHandler()->ProcessEvent( event ) ;
+ }
+ if ( focus && (modifiers ^ wxTheApp->s_lastModifiers ) & cmdKey )
+ {
+ event.m_keyCode = WXK_COMMAND ;
+ event.SetEventType( ( modifiers & cmdKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ;
+ focus->GetEventHandler()->ProcessEvent( event ) ;
+ }
+ wxTheApp->s_lastModifiers = modifiers ;
+ }
+ break ;
+ }
+
+ return result ;
+}
+
+pascal OSStatus MouseEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
+{
+ OSStatus result = eventNotHandledErr ;
+
+ wxTopLevelWindowMac* toplevelWindow = (wxTopLevelWindowMac*) data ;
+ Point point ;
+ UInt32 modifiers = 0;
+ EventMouseButton button = 0 ;
+ UInt32 click = 0 ;
+
+ GetEventParameter( event, kEventParamMouseLocation, typeQDPoint, NULL,
+ sizeof( Point ), NULL, &point );
+ GetEventParameter( event, kEventParamKeyModifiers, typeUInt32, NULL,
+ sizeof( UInt32 ), NULL, &modifiers );
+ GetEventParameter( event, kEventParamMouseButton, typeMouseButton, NULL,
+ sizeof( EventMouseButton ), NULL, &button );
+ GetEventParameter( event, kEventParamClickCount, typeUInt32, NULL,
+ sizeof( UInt32 ), NULL, &click );
+
+ if ( button == 0 || GetEventKind( event ) == kEventMouseUp )
+ modifiers += btnState ;
+
+ // temporary hack to support true two button mouse
+ if ( button == kEventMouseButtonSecondary )
+ {
+ modifiers |= controlKey ;
+ }
+ WindowRef window ;
+ short windowPart = ::FindWindow(point, &window);
+
+ // either we really are active or we are capturing mouse events
+
+ if ( (IsWindowActive(window) && windowPart == inContent) ||
+ (wxTheApp->s_captureWindow && wxTheApp->s_captureWindow->MacGetTopLevelWindow() == toplevelWindow) )
+ {
+ switch ( GetEventKind( event ) )
+ {
+ case kEventMouseDown :
+ toplevelWindow->MacFireMouseEvent( mouseDown , point.h , point.v , modifiers , EventTimeToTicks( GetEventTime( event ) ) ) ;
+ result = noErr ;
+ break ;
+ case kEventMouseUp :
+ toplevelWindow->MacFireMouseEvent( mouseUp , point.h , point.v , modifiers , EventTimeToTicks( GetEventTime( event ) ) ) ;
+ result = noErr ;
+ break ;
+ case kEventMouseMoved :
+ wxTheApp->MacHandleMouseMovedEvent( point.h , point.v , modifiers , EventTimeToTicks( GetEventTime( event ) ) ) ;
+ result = noErr ;
+ break ;
+ case kEventMouseDragged :
+ toplevelWindow->MacFireMouseEvent( nullEvent , point.h , point.v , modifiers , EventTimeToTicks( GetEventTime( event ) ) ) ;
+ result = noErr ;
+ break ;
+ case kEventMouseWheelMoved :
+ {
+ //bClearTooltip = false;
+ EventMouseWheelAxis axis = kEventMouseWheelAxisY;
+ SInt32 delta = 0;
+ Point mouseLoc = {0, 0};
+ if (::GetEventParameter(event, kEventParamMouseWheelAxis, typeMouseWheelAxis,
+ NULL, sizeof(EventMouseWheelAxis), NULL, &axis) == noErr &&
+ ::GetEventParameter(event, kEventParamMouseWheelDelta, typeLongInteger,
+ NULL, sizeof(SInt32), NULL, &delta) == noErr &&
+ ::GetEventParameter(event, kEventParamMouseLocation, typeQDPoint,
+ NULL, sizeof(Point), NULL, &mouseLoc) == noErr)
+ {
+ wxMouseEvent wheelEvent(wxEVT_MOUSEWHEEL);
+
+ wheelEvent.m_x = mouseLoc.h;
+ wheelEvent.m_y = mouseLoc.v;
+
+ wheelEvent.m_wheelRotation = delta;
+ wheelEvent.m_wheelDelta = 1;
+ wheelEvent.m_linesPerAction = 1;
+
+ wxWindow* currentMouseWindow = NULL;
+ wxWindow::MacGetWindowFromPoint(wxPoint(mouseLoc.h, mouseLoc.v), ¤tMouseWindow);
+
+ if (currentMouseWindow)
+ {
+ currentMouseWindow->GetEventHandler()->ProcessEvent(wheelEvent);
+ result = noErr;
+ }
+ }
+ }
+ break ;
+ default :
+ break ;
+ }
+ }
+
+ return result ;
+
+
+}
+static pascal OSStatus WindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
+{
+ OSStatus result = eventNotHandledErr ;
+ OSStatus err = noErr ;
+
+ UInt32 attributes;
+ WindowRef windowRef ;
+ wxTopLevelWindowMac* toplevelWindow = (wxTopLevelWindowMac*) data ;
+
+ GetEventParameter( event, kEventParamDirectObject, typeWindowRef, NULL,
+ sizeof( WindowRef ), NULL, &windowRef );
+
+ switch( GetEventKind( event ) )
+ {
+ case kEventWindowUpdate :
+ if ( !wxPendingDelete.Member(toplevelWindow) )
+ toplevelWindow->MacUpdate( EventTimeToTicks( GetEventTime( event ) ) ) ;
+ result = noErr ;
+ break ;
+ case kEventWindowActivated :
+ toplevelWindow->MacActivate( EventTimeToTicks( GetEventTime( event ) ) , true) ;
+ result = noErr ;
+ break ;
+ case kEventWindowDeactivated :
+ toplevelWindow->MacActivate( EventTimeToTicks( GetEventTime( event ) ) , false) ;
+ result = noErr ;
+ break ;
+ case kEventWindowShown :
+ toplevelWindow->Refresh() ;
+ result = noErr ;
+ break ;
+ case kEventWindowClose :
+ toplevelWindow->Close() ;
+ result = noErr ;
+ break ;
+ case kEventWindowBoundsChanged :
+ err = GetEventParameter( event, kEventParamAttributes, typeUInt32,
+ NULL, sizeof( UInt32 ), NULL, &attributes );
+ if ( err == noErr )
+ {
+ Rect newContentRect ;
+
+ GetEventParameter( event, kEventParamCurrentBounds, typeQDRectangle, NULL,
+ sizeof( newContentRect ), NULL, &newContentRect );
+
+ toplevelWindow->SetSize( newContentRect.left , newContentRect.top ,
+ newContentRect.right - newContentRect.left ,
+ newContentRect.bottom - newContentRect.top, wxSIZE_USE_EXISTING);
+
+ result = noErr;
+ }
+ break ;
+ case kEventWindowBoundsChanging :
+ err = GetEventParameter( event, kEventParamAttributes, typeUInt32,
+ NULL, sizeof( UInt32 ), NULL, &attributes );
+ if ( err == noErr )
+ {
+ Rect newContentRect ;
+
+ GetEventParameter( event, kEventParamCurrentBounds, typeQDRectangle, NULL,
+ sizeof( newContentRect ), NULL, &newContentRect );
+
+ wxSize formerSize = toplevelWindow->GetSize() ;
+
+ if ( (attributes & kWindowBoundsChangeSizeChanged ) ||
+ ( attributes & kWindowBoundsChangeOriginChanged ) )
+ toplevelWindow->SetSize( newContentRect.left , newContentRect.top ,
+ newContentRect.right - newContentRect.left ,
+ newContentRect.bottom - newContentRect.top, wxSIZE_USE_EXISTING);
+
+ int x , y , w , h ;
+ toplevelWindow->GetPosition( &x , &y ) ;
+ toplevelWindow->GetSize( &w , &h ) ;
+ Rect adjustedRect = { y , x , y + h , x + w } ;
+
+ if ( !EqualRect( &newContentRect , &adjustedRect ) )
+ {
+ SetEventParameter( event , kEventParamCurrentBounds , typeQDRectangle, sizeof( adjustedRect ) , &adjustedRect ) ;
+ }
+
+ if ( toplevelWindow->GetSize() != formerSize )
+ toplevelWindow->Update() ;
+
+ result = noErr ;
+ }
+ break ;
+ default :
+ break ;
+ }
+ return result ;
+}
+
+pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
+{
+ OSStatus result = eventNotHandledErr ;
+
+ switch ( GetEventClass( event ) )
+ {
+ case kEventClassKeyboard :
+ result = KeyboardEventHandler( handler, event , data ) ;
+ break ;
+ case kEventClassTextInput :
+ result = TextInputEventHandler( handler, event , data ) ;
+ break ;
+ case kEventClassWindow :
+ result = WindowEventHandler( handler, event , data ) ;
+ break ;
+ case kEventClassMouse :
+ result = MouseEventHandler( handler, event , data ) ;
+ break ;
+ default :
+ break ;
+ }
+ return result ;
+}
+
+DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler )
+
+#endif
+
+// ---------------------------------------------------------------------------
+// wxWindowMac utility functions
+// ---------------------------------------------------------------------------
+
+// Find an item given the Macintosh Window Reference
+
+wxList *wxWinMacWindowList = NULL;
+wxTopLevelWindowMac *wxFindWinFromMacWindow(WXWindow inWindowRef)
+{
+ if ( wxWinMacWindowList == NULL )
+ return NULL ;
+ wxNode *node = wxWinMacWindowList->Find((long)inWindowRef);
+ if (!node)
+ return NULL;
+ return (wxTopLevelWindowMac *)node->GetData();
+}
+
+void wxAssociateWinWithMacWindow(WXWindow inWindowRef, wxTopLevelWindowMac *win)
+{
+ // adding NULL WindowRef is (first) surely a result of an error and
+ // (secondly) breaks menu command processing
+ wxCHECK_RET( inWindowRef != (WindowRef) NULL, wxT("attempt to add a NULL WindowRef to window list") );
+
+ if ( !wxWinMacWindowList->Find((long)inWindowRef) )
+ wxWinMacWindowList->Append((long)inWindowRef, win);
+}
+
+void wxRemoveMacWindowAssociation(wxTopLevelWindowMac *win)
+{
+ wxWinMacWindowList->DeleteObject(win);
+}
+
+
+// ----------------------------------------------------------------------------
+// wxTopLevelWindowMac creation
+// ----------------------------------------------------------------------------
+
+WXHWND wxTopLevelWindowMac::s_macWindowInUpdate = NULL;
+wxTopLevelWindowMac *wxTopLevelWindowMac::s_macDeactivateWindow = NULL;
+bool wxTopLevelWindowMac::s_macWindowCompositing = FALSE;
+
+void wxTopLevelWindowMac::Init()
+{
+ m_iconized =
+ m_maximizeOnShow = FALSE;
+ m_macNoEraseUpdateRgn = NewRgn() ;
+ m_macNeedsErasing = false ;
+ m_macWindow = NULL ;
+ m_macUsesCompositing = FALSE ;
+#if TARGET_CARBON
+ m_macEventHandler = NULL ;
+ #endif
+}
+
+class wxMacDeferredWindowDeleter : public wxObject
+{
+public :
+ wxMacDeferredWindowDeleter( WindowRef windowRef )
+ {
+ m_macWindow = windowRef ;
+ }
+ virtual ~wxMacDeferredWindowDeleter()
+ {
+ UMADisposeWindow( (WindowRef) m_macWindow ) ;
+ }
+ protected :
+ WindowRef m_macWindow ;
+} ;
+
+bool wxTopLevelWindowMac::Create(wxWindow *parent,
+ wxWindowID id,
+ const wxString& title,
+ const wxPoint& pos,
+ const wxSize& size,
+ long style,
+ const wxString& name)
+{
+ // init our fields
+ Init();
+
+ m_windowStyle = style;
+
+ SetName(name);
+
+ m_windowId = id == -1 ? NewControlId() : id;
+
+ wxTopLevelWindows.Append(this);
+
+ if ( parent )
+ parent->AddChild(this);
+
+ return TRUE;
+}
+
+wxTopLevelWindowMac::~wxTopLevelWindowMac()
+{
+ if ( m_macWindow )
+ {
+ wxToolTip::NotifyWindowDelete(m_macWindow) ;
+ wxPendingDelete.Append( new wxMacDeferredWindowDeleter( (WindowRef) m_macWindow ) ) ;
+ }
+
+#if TARGET_CARBON
+ if ( m_macEventHandler )
+ {
+ ::RemoveEventHandler((EventHandlerRef) m_macEventHandler);
+ m_macEventHandler = NULL ;
+ }
+#endif
+
+ wxRemoveMacWindowAssociation( this ) ;
+
+ if ( wxModelessWindows.Find(this) )
+ wxModelessWindows.DeleteObject(this);
+
+ DisposeRgn( (RgnHandle) m_macNoEraseUpdateRgn ) ;
+}
+
+
+// ----------------------------------------------------------------------------
+// wxTopLevelWindowMac maximize/minimize
+// ----------------------------------------------------------------------------
+
+void wxTopLevelWindowMac::Maximize(bool maximize)
+{
+ wxMacPortStateHelper help( (GrafPtr) GetWindowPort( (WindowRef) m_macWindow) ) ;
+ wxMacWindowClipper clip (this);
+ ZoomWindow( (WindowRef)m_macWindow , maximize ? inZoomOut : inZoomIn , false ) ;
+
+ Rect tempRect ;
+ GrafPtr port ;
+ GetPort( &port ) ;
+ Point pt = { 0, 0 } ;
+ SetPortWindowPort((WindowRef)m_macWindow) ;
+ LocalToGlobal( &pt ) ;
+ SetPort( port ) ;
+
+ GetWindowPortBounds((WindowRef)m_macWindow, &tempRect ) ;
+ SetSize( pt.h , pt.v , tempRect.right-tempRect.left ,
+ tempRect.bottom-tempRect.top, wxSIZE_USE_EXISTING);
+}
+
+bool wxTopLevelWindowMac::IsMaximized() const
+{
+ return IsWindowInStandardState( (WindowRef)m_macWindow , NULL , NULL ) ;
+}
+
+void wxTopLevelWindowMac::Iconize(bool iconize)
+{
+ if ( IsWindowCollapsable((WindowRef)m_macWindow) )
+ CollapseWindow((WindowRef)m_macWindow , iconize ) ;
+}
+
+bool wxTopLevelWindowMac::IsIconized() const
+{
+ return IsWindowCollapsed((WindowRef)m_macWindow ) ;
+}
+
+void wxTopLevelWindowMac::Restore()
+{
+ // not available on mac
+}
+
+// ----------------------------------------------------------------------------
+// wxTopLevelWindowMac misc
+// ----------------------------------------------------------------------------
+
+void wxTopLevelWindowMac::SetIcon(const wxIcon& icon)
+{
+ // this sets m_icon
+ wxTopLevelWindowBase::SetIcon(icon);
+}
+
+void wxTopLevelWindowMac::MacCreateRealWindow( const wxString& title,
+ const wxPoint& pos,
+ const wxSize& size,
+ long style,
+ const wxString& name )
+{
+ OSStatus err = noErr ;
+ SetName(name);
+ m_windowStyle = style;
+ m_isShown = FALSE;
+
+ // create frame.
+
+ Rect theBoundsRect;
+
+ m_x = (int)pos.x;
+ m_y = (int)pos.y;
+ if ( m_y < 50 )
+ m_y = 50 ;
+ if ( m_x < 20 )
+ m_x = 20 ;
+
+ m_width = WidthDefault(size.x);
+ m_height = HeightDefault(size.y);
+
+ ::SetRect(&theBoundsRect, m_x, m_y , m_x + m_width, m_y + m_height);
+
+ // translate the window attributes in the appropriate window class and attributes
+
+ WindowClass wclass = 0;
+ WindowAttributes attr = kWindowNoAttributes ;
+
+ if ( HasFlag( wxFRAME_TOOL_WINDOW) )
+ {
+ if (
+ HasFlag( wxMINIMIZE_BOX ) || HasFlag( wxMAXIMIZE_BOX ) ||
+ HasFlag( wxSYSTEM_MENU ) || HasFlag( wxCAPTION ) ||
+ HasFlag(wxTINY_CAPTION_HORIZ) || HasFlag(wxTINY_CAPTION_VERT)
+ )
+ {
+ wclass = kFloatingWindowClass ;
+ if ( HasFlag(wxTINY_CAPTION_VERT) )
+ {
+ attr |= kWindowSideTitlebarAttribute ;
+ }
+ }
+ else
+ {
+#if TARGET_CARBON
+ wclass = kPlainWindowClass ;
+#else
+ wclass = kFloatingWindowClass ;
+#endif
+ }
+ }
+ else if ( HasFlag( wxCAPTION ) )
+ {
+ wclass = kDocumentWindowClass ;
+ }
+ else
+ {
+ if ( HasFlag( wxMINIMIZE_BOX ) || HasFlag( wxMAXIMIZE_BOX ) ||
+ HasFlag( wxCLOSE_BOX ) || HasFlag( wxSYSTEM_MENU ) )
+ {
+ wclass = kDocumentWindowClass ;
+ }
+ else
+ {
+#if TARGET_CARBON
+ wclass = kPlainWindowClass ;
+#else
+ wclass = kModalWindowClass ;
+#endif
+ }
+ }
+
+ if ( HasFlag( wxMINIMIZE_BOX ) )
+ {
+ attr |= kWindowCollapseBoxAttribute ;
+ }
+ if ( HasFlag( wxMAXIMIZE_BOX ) )
+ {
+ attr |= kWindowFullZoomAttribute ;
+ }
+ if ( HasFlag( wxRESIZE_BORDER ) )
+ {
+ attr |= kWindowResizableAttribute ;
+ }
+ if ( HasFlag( wxCLOSE_BOX) )
+ {
+ attr |= kWindowCloseBoxAttribute ;
+ }
+
+ if (UMAGetSystemVersion() >= 0x1000)
+ {
+ //turn on live resizing (OS X only)
+ attr |= kWindowLiveResizeAttribute;
+ }
+
+#if TARGET_CARBON
+#if 0 // having problems right now with that
+ if (HasFlag(wxSTAY_ON_TOP))
+ wclass = kUtilityWindowClass;
+#endif
+#endif
+
+ //this setup lets us have compositing and non-compositing
+ //windows in the same application.
+
+#if UNIVERSAL_INTERFACES_VERSION >= 0x0400
+ if ( wxTopLevelWindowMac::s_macWindowCompositing )
+ {
+ attr |= kWindowCompositingAttribute;
+ m_macUsesCompositing = TRUE;
+ }
+ else
+#endif
+ {
+ m_macUsesCompositing = FALSE;
+ }
+
+#if TARGET_CARBON
+ if ( HasFlag(wxFRAME_SHAPED) )
+ {
+ WindowDefSpec customWindowDefSpec;
+ customWindowDefSpec.defType = kWindowDefProcPtr;
+ customWindowDefSpec.u.defProc = NewWindowDefUPP(wxShapedMacWindowDef);
+
+ err = ::CreateCustomWindow( &customWindowDefSpec, wclass,
+ attr, &theBoundsRect,
+ (WindowRef*) &m_macWindow);
+ }
+ else
+#endif
+ {
+ err = ::CreateNewWindow( wclass , attr , &theBoundsRect , (WindowRef*)&m_macWindow ) ;
+ }
+
+ wxCHECK_RET( err == noErr, wxT("Mac OS error when trying to create new window") );
+ wxAssociateWinWithMacWindow( m_macWindow , this ) ;
+ UMASetWTitle( (WindowRef)m_macWindow , title , m_font.GetEncoding() ) ;
+ if ( wxTopLevelWindowMac::s_macWindowCompositing )
+ {
+ ::GetRootControl( (WindowRef)m_macWindow, (ControlHandle*)&m_macRootControl ) ;
+ }
+ else
+ {
+ ::CreateRootControl( (WindowRef)m_macWindow , (ControlHandle*)&m_macRootControl ) ;
+ }
+#if TARGET_CARBON
+ InstallStandardEventHandler( GetWindowEventTarget(MAC_WXHWND(m_macWindow)) ) ;
+ InstallWindowEventHandler(MAC_WXHWND(m_macWindow), GetwxMacWindowEventHandlerUPP(),
+ GetEventTypeCount(eventList), eventList, this, (EventHandlerRef *)&m_macEventHandler);
+#endif
+ m_macFocus = NULL ;
+
+
+#if TARGET_CARBON
+ if ( HasFlag(wxFRAME_SHAPED) )
+ {
+ // default shape matches the window size
+ wxRegion rgn(0, 0, m_width, m_height);
+ SetShape(rgn);
+ }
+#endif
+
+ wxWindowCreateEvent event(this);
+ GetEventHandler()->ProcessEvent(event);
+}
+
+bool wxTopLevelWindowMac::MacEnableCompositing( bool useCompositing )
+{
+ bool oldval = s_macWindowCompositing;
+ s_macWindowCompositing = useCompositing;
+ return oldval;
+}
+
+void wxTopLevelWindowMac::MacGetPortParams(WXPOINTPTR localOrigin, WXRECTPTR clipRect, WXHWND *window , wxWindowMac** rootwin)
+{
+ ((Point*)localOrigin)->h = 0;
+ ((Point*)localOrigin)->v = 0;
+ ((Rect*)clipRect)->left = 0;
+ ((Rect*)clipRect)->top = 0;
+ ((Rect*)clipRect)->right = m_width;
+ ((Rect*)clipRect)->bottom = m_height;
+ *window = m_macWindow ;
+ *rootwin = this ;
+}
+
+void wxTopLevelWindowMac::ClearBackground()
+{
+ wxWindow::ClearBackground() ;
+}
+
+WXWidget wxTopLevelWindowMac::MacGetContainerForEmbedding()
+{
+ return m_macRootControl ;
+}
+
+
+void wxTopLevelWindowMac::MacUpdate( long timestamp)
+{
+ wxMacPortStateHelper help( (GrafPtr) GetWindowPort( (WindowRef) m_macWindow) ) ;
+
+ RgnHandle visRgn = NewRgn() ;
+ GetPortVisibleRegion( GetWindowPort( (WindowRef)m_macWindow ), visRgn );
+ BeginUpdate( (WindowRef)m_macWindow ) ;
+
+ RgnHandle updateRgn = NewRgn();
+ RgnHandle diffRgn = NewRgn() ;
+
+ if ( updateRgn && diffRgn )
+ {
+#if 1
+ // macos internal control redraws clean up areas we'd like to redraw ourselves
+ // therefore we pick the boundary rect and make sure we can redraw it
+ // this has to be intersected by the visRgn in order to avoid drawing over its own
+ // boundaries
+ RgnHandle trueUpdateRgn = NewRgn() ;
+ Rect trueUpdateRgnBoundary ;
+ GetPortVisibleRegion( GetWindowPort( (WindowRef)m_macWindow ), trueUpdateRgn );
+ GetRegionBounds( trueUpdateRgn , &trueUpdateRgnBoundary ) ;
+ RectRgn( updateRgn , &trueUpdateRgnBoundary ) ;
+ SectRgn( updateRgn , visRgn , updateRgn ) ;
+ if ( trueUpdateRgn )
+ DisposeRgn( trueUpdateRgn ) ;
+ SetPortVisibleRegion( GetWindowPort( (WindowRef)m_macWindow ), updateRgn ) ;
+#else
+ GetPortVisibleRegion( GetWindowPort( (WindowRef)m_macWindow ), updateRgn );
+#endif
+ DiffRgn( updateRgn , (RgnHandle) m_macNoEraseUpdateRgn , diffRgn ) ;
+ if ( !EmptyRgn( updateRgn ) )
+ {
+ MacRedraw( updateRgn , timestamp , m_macNeedsErasing || !EmptyRgn( diffRgn ) ) ;
+ }
+ }
+ if ( updateRgn )
+ DisposeRgn( updateRgn );
+ if ( diffRgn )
+ DisposeRgn( diffRgn );
+ if ( visRgn )
+ DisposeRgn( visRgn ) ;
+
+ EndUpdate( (WindowRef)m_macWindow ) ;
+ SetEmptyRgn( (RgnHandle) m_macNoEraseUpdateRgn ) ;
+ m_macNeedsErasing = false ;
+}
+
+
+// Raise the window to the top of the Z order
+void wxTopLevelWindowMac::Raise()
+{
+ ::SelectWindow( (WindowRef)m_macWindow ) ;
+}
+
+// Lower the window to the bottom of the Z order
+void wxTopLevelWindowMac::Lower()
+{
+ ::SendBehind( (WindowRef)m_macWindow , NULL ) ;
+}
+
+void wxTopLevelWindowMac::MacFireMouseEvent(
+ wxUint16 kind , wxInt32 x , wxInt32 y ,wxUint32 modifiers , long timestamp )
+{
+ wxMouseEvent event(wxEVT_LEFT_DOWN);
+ bool isDown = !(modifiers & btnState) ; // 1 is for up
+ bool controlDown = modifiers & controlKey ; // for simulating right mouse
+
+ event.m_leftDown = isDown && !controlDown;
+
+ event.m_middleDown = FALSE;
+ event.m_rightDown = isDown && controlDown;
+
+ if ( kind == mouseDown )
+ {
+ if ( controlDown )
+ event.SetEventType(wxEVT_RIGHT_DOWN ) ;
+ else
+ event.SetEventType(wxEVT_LEFT_DOWN ) ;
+ }
+ else if ( kind == mouseUp )
+ {
+ if ( controlDown )
+ event.SetEventType(wxEVT_RIGHT_UP ) ;
+ else
+ event.SetEventType(wxEVT_LEFT_UP ) ;
+ }
+ else
+ {
+ event.SetEventType(wxEVT_MOTION ) ;
+ }
+
+ event.m_shiftDown = modifiers & shiftKey;
+ event.m_controlDown = modifiers & controlKey;
+ event.m_altDown = modifiers & optionKey;
+ event.m_metaDown = modifiers & cmdKey;
+
+ Point localwhere ;
+ localwhere.h = x ;
+ localwhere.v = y ;
+
+ GrafPtr port ;
+ ::GetPort( &port ) ;
+ ::SetPort( UMAGetWindowPort( (WindowRef)m_macWindow ) ) ;
+ ::GlobalToLocal( &localwhere ) ;
+ ::SetPort( port ) ;
+
+ if ( kind == mouseDown )
+ {
+ if ( timestamp - gs_lastWhen <= (long) GetDblTime() )
+ {
+ if ( abs( localwhere.h - gs_lastWhere.h ) < 3 && abs( localwhere.v - gs_lastWhere.v ) < 3 )
+ {
+ // This is not right if the second mouse down
+ // event occured in a differen window. We
+ // correct this in MacDispatchMouseEvent.
+ if ( controlDown )
+ event.SetEventType(wxEVT_RIGHT_DCLICK ) ;
+ else
+ event.SetEventType(wxEVT_LEFT_DCLICK ) ;
+ }
+ gs_lastWhen = 0 ;
+ }
+ else
+ {
+ gs_lastWhen = timestamp ;
+ }
+ gs_lastWhere = localwhere ;
+ }
+
+ event.m_x = localwhere.h;
+ event.m_y = localwhere.v;
+ event.m_x += m_x;
+ event.m_y += m_y;
+
+ event.m_timeStamp = timestamp;
+ event.SetEventObject(this);
+ if ( wxTheApp->s_captureWindow )
+ {
+ int x = event.m_x ;
+ int y = event.m_y ;
+ wxTheApp->s_captureWindow->ScreenToClient( &x , &y ) ;
+ event.m_x = x ;
+ event.m_y = y ;
+ event.SetEventObject( wxTheApp->s_captureWindow ) ;
+ wxTheApp->s_captureWindow->GetEventHandler()->ProcessEvent( event ) ;
+
+ if ( kind == mouseUp )
+ {
+ wxTheApp->s_captureWindow = NULL ;
+ if ( !wxIsBusy() )
+ {
+ m_cursor.MacInstall() ;
+ }
+ }
+ }
+ else
+ {
+ MacDispatchMouseEvent( event ) ;
+ }
+}
+
+#if !TARGET_CARBON
+
+void wxTopLevelWindowMac::MacMouseDown( WXEVENTREF ev , short part)
+{
+ MacFireMouseEvent( mouseDown , ((EventRecord*)ev)->where.h , ((EventRecord*)ev)->where.v ,
+ ((EventRecord*)ev)->modifiers , ((EventRecord*)ev)->when ) ;
+}
+
+void wxTopLevelWindowMac::MacMouseUp( WXEVENTREF ev , short part)
+{
+ switch (part)
+ {
+ case inContent:
+ {
+ MacFireMouseEvent( mouseUp , ((EventRecord*)ev)->where.h , ((EventRecord*)ev)->where.v ,
+ ((EventRecord*)ev)->modifiers , ((EventRecord*)ev)->when ) ;
+ }
+ break ;
+ }
+}
+
+void wxTopLevelWindowMac::MacMouseMoved( WXEVENTREF ev , short part)
+{
+ switch (part)
+ {
+ case inContent:
+ {
+ MacFireMouseEvent( nullEvent /*moved*/ , ((EventRecord*)ev)->where.h , ((EventRecord*)ev)->where.v ,
+ ((EventRecord*)ev)->modifiers , ((EventRecord*)ev)->when ) ;
+ }
+ break ;
+ }
+}
+
+#endif
+
+void wxTopLevelWindowMac::MacDelayedDeactivation(long timestamp)
+{
+ if(s_macDeactivateWindow)
+ {
+ wxLogDebug(wxT("Doing delayed deactivation of %p"),s_macDeactivateWindow);
+ s_macDeactivateWindow->MacActivate(timestamp, false);
+ }
+}
+
+void wxTopLevelWindowMac::MacActivate( long timestamp , bool inIsActivating )
+{
+ // wxLogDebug(wxT("TopLevel=%p::MacActivate"),this);
+
+ if(s_macDeactivateWindow==this)
+ s_macDeactivateWindow=NULL;
+ MacDelayedDeactivation(timestamp);
+ wxActivateEvent event(wxEVT_ACTIVATE, inIsActivating , m_windowId);
+ event.m_timeStamp = timestamp ;
+ event.SetEventObject(this);
+
+ GetEventHandler()->ProcessEvent(event);
+
+ UMAHighlightAndActivateWindow( (WindowRef)m_macWindow , inIsActivating ) ;
+
+ // Early versions of MacOS X don't refresh backgrounds properly,
+ // so refresh the whole window on activation and deactivation.
+ long osVersion = UMAGetSystemVersion();
+ if (osVersion >= 0x1000 && osVersion < 0x1020 )
+ {
+ Refresh(TRUE);
+ }
+ else
+ {
+ // for the moment we have to resolve some redrawing issues like this
+ // the OS is stealing some redrawing areas as soon as it draws a control
+ Refresh(TRUE);
+ }
+}
+
+#if !TARGET_CARBON
+
+void wxTopLevelWindowMac::MacKeyDown( WXEVENTREF ev )
+{
+}
+
+#endif
+
+void wxTopLevelWindowMac::SetTitle(const wxString& title)
+{
+ wxWindow::SetTitle( title ) ;
+ UMASetWTitle( (WindowRef)m_macWindow , title , m_font.GetEncoding() ) ;
+}
+
+bool wxTopLevelWindowMac::Show(bool show)
+{
+ if ( !wxWindow::Show(show) )
+ return FALSE;
+
+ if (show)
+ {
+ #if wxUSE_SYSTEM_OPTIONS //code contributed by Ryan Wilcox December 18, 2003
+ if ( (wxSystemOptions::HasOption(wxMAC_WINDOW_PLAIN_TRANSITION) ) && ( wxSystemOptions::GetOptionInt( wxMAC_WINDOW_PLAIN_TRANSITION ) == 1) )
+ {
+ ::ShowWindow( (WindowRef)m_macWindow );
+ }
+ else
+ #endif
+ {
+ ::TransitionWindow((WindowRef)m_macWindow,kWindowZoomTransitionEffect,kWindowShowTransitionAction,nil);
+ }
+ ::SelectWindow( (WindowRef)m_macWindow ) ;
+ // no need to generate events here, they will get them triggered by macos
+ // actually they should be , but apparently they are not
+ wxSize size(m_width, m_height);
+ wxSizeEvent event(size, m_windowId);
+ event.SetEventObject(this);
+ GetEventHandler()->ProcessEvent(event);
+ }
+ else
+ {
+ #if wxUSE_SYSTEM_OPTIONS
+ if ( (wxSystemOptions::HasOption(wxMAC_WINDOW_PLAIN_TRANSITION) ) && ( wxSystemOptions::GetOptionInt( wxMAC_WINDOW_PLAIN_TRANSITION ) == 1) )
+ {
+ ::HideWindow((WindowRef) m_macWindow );
+ }
+ else
+ #endif
+ {
+ ::TransitionWindow((WindowRef)m_macWindow,kWindowZoomTransitionEffect,kWindowHideTransitionAction,nil);
+ }
+ }
+
+ if ( !show )
+ {
+ }
+ else
+ {
+ Refresh() ;
+ }
+
+ return TRUE;
+}
+
+void wxTopLevelWindowMac::DoMoveWindow(int x, int y, int width, int height)
+{
+ wxMacPortStateHelper help( (GrafPtr) GetWindowPort( (WindowRef) m_macWindow) ) ;
+ wxMacWindowClipper clip (this);
+
+ int former_x = m_x ;
+ int former_y = m_y ;
+ int former_w = m_width ;
+ int former_h = m_height ;
+
+ int actualWidth = width;
+ int actualHeight = height;
+ int actualX = x;
+ int actualY = y;
+
+ if ((m_minWidth != -1) && (actualWidth < m_minWidth))
+ actualWidth = m_minWidth;
+ if ((m_minHeight != -1) && (actualHeight < m_minHeight))
+ actualHeight = m_minHeight;
+ if ((m_maxWidth != -1) && (actualWidth > m_maxWidth))
+ actualWidth = m_maxWidth;
+ if ((m_maxHeight != -1) && (actualHeight > m_maxHeight))
+ actualHeight = m_maxHeight;
+
+ bool doMove = false ;
+ bool doResize = false ;
+
+ if ( actualX != former_x || actualY != former_y )
+ {
+ doMove = true ;
+ }
+ if ( actualWidth != former_w || actualHeight != former_h )
+ {
+ doResize = true ;
+ }
+
+ if ( doMove || doResize )
+ {
+ m_x = actualX ;
+ m_y = actualY ;
+
+ if ( doMove )
+ ::MoveWindow((WindowRef)m_macWindow, m_x, m_y , false); // don't make frontmost
+
+ m_width = actualWidth ;
+ m_height = actualHeight ;
+
+ if ( doResize )
+ ::SizeWindow((WindowRef)m_macWindow, m_width, m_height , true);
+
+ // the OS takes care of invalidating and erasing the new area so we only have to
+ // take care of refreshing for full repaints
+
+ if ( doResize && HasFlag(wxFULL_REPAINT_ON_RESIZE) )
+ Refresh() ;
+
+
+ if ( IsKindOf( CLASSINFO( wxFrame ) ) )
+ {
+ wxFrame* frame = (wxFrame*) this ;
+#if wxUSE_STATUSBAR
+ frame->PositionStatusBar();
+#endif
+#if wxUSE_TOOLBAR
+ frame->PositionToolBar();
+#endif
+ }
+ if ( doMove )
+ wxWindowMac::MacTopLevelWindowChangedPosition() ; // like this only children will be notified
+
+ MacRepositionScrollBars() ;
+ if ( doMove )
+ {
+ wxPoint point(m_x, m_y);
+ wxMoveEvent event(point, m_windowId);
+ event.SetEventObject(this);
+ GetEventHandler()->ProcessEvent(event) ;
+ }
+ if ( doResize )
+ {
+ MacRepositionScrollBars() ;
+ wxSize size(m_width, m_height);
+ wxSizeEvent event(size, m_windowId);
+ event.SetEventObject(this);
+ GetEventHandler()->ProcessEvent(event);
+ }
+ }
+
+}
+
+/*
+ * Invalidation Mechanism
+ *
+ * The update mechanism reflects exactely the windows mechanism
+ * the rect gets added to the window invalidate region, if the eraseBackground flag
+ * has been true for any part of the update rgn the background is erased in the entire region
+ * not just in the specified rect.
+ *
+ * In order to achive this, we also have an internal m_macNoEraseUpdateRgn, all rects that have
+ * the eraseBackground flag set to false are also added to this rgn. upon receiving an update event
+ * the update rgn is compared to the m_macNoEraseUpdateRgn and in case they differ, every window
+ * will get the eraseBackground event first
+ */
+
+void wxTopLevelWindowMac::MacInvalidate( const WXRECTPTR rect, bool eraseBackground )
+{
+ GrafPtr formerPort ;
+ GetPort( &formerPort ) ;
+ SetPortWindowPort( (WindowRef)m_macWindow ) ;
+
+ m_macNeedsErasing |= eraseBackground ;
+
+ // if we already know that we will have to erase, there's no need to track the rest
+ if ( !m_macNeedsErasing)
+ {
+ // we end only here if eraseBackground is false
+ // if we already have a difference between m_macNoEraseUpdateRgn and UpdateRgn
+ // we will have to erase anyway
+
+ RgnHandle updateRgn = NewRgn();
+ RgnHandle diffRgn = NewRgn() ;
+ if ( updateRgn && diffRgn )
+ {
+ GetWindowUpdateRgn( (WindowRef)m_macWindow , updateRgn );
+ Point pt = {0,0} ;
+ LocalToGlobal( &pt ) ;
+ OffsetRgn( updateRgn , -pt.h , -pt.v ) ;
+ DiffRgn( updateRgn , (RgnHandle) m_macNoEraseUpdateRgn , diffRgn ) ;
+ if ( !EmptyRgn( diffRgn ) )
+ {
+ m_macNeedsErasing = true ;
+ }
+ }
+ if ( updateRgn )
+ DisposeRgn( updateRgn );
+ if ( diffRgn )
+ DisposeRgn( diffRgn );
+
+ if ( !m_macNeedsErasing )
+ {
+ RgnHandle rectRgn = NewRgn() ;
+ SetRectRgn( rectRgn , ((Rect*)rect)->left , ((Rect*)rect)->top , ((Rect*)rect)->right , ((Rect*)rect)->bottom ) ;
+ UnionRgn( (RgnHandle) m_macNoEraseUpdateRgn , rectRgn , (RgnHandle) m_macNoEraseUpdateRgn ) ;
+ DisposeRgn( rectRgn ) ;
+ }
+ }
+ InvalWindowRect( (WindowRef)m_macWindow , (Rect*)rect ) ;
+ // turn this on to debug the refreshing cycle
+#if wxMAC_DEBUG_REDRAW
+ PaintRect( rect ) ;
+#endif
+ SetPort( formerPort ) ;
+}
+
+
+bool wxTopLevelWindowMac::SetShape(const wxRegion& region)
+{
+ wxCHECK_MSG( HasFlag(wxFRAME_SHAPED), FALSE,
+ _T("Shaped windows must be created with the wxFRAME_SHAPED style."));
+
+#if TARGET_CARBON
+ // The empty region signifies that the shape should be removed from the
+ // window.
+ if ( region.IsEmpty() )
+ {
+ wxSize sz = GetClientSize();
+ wxRegion rgn(0, 0, sz.x, sz.y);
+ return SetShape(rgn);
+ }
+
+ // Make a copy of the region
+ RgnHandle shapeRegion = NewRgn();
+ CopyRgn( (RgnHandle)region.GetWXHRGN(), shapeRegion );
+
+ // Dispose of any shape region we may already have
+ RgnHandle oldRgn = (RgnHandle)GetWRefCon( (WindowRef)MacGetWindowRef() );
+ if ( oldRgn )
+ DisposeRgn(oldRgn);
+
+ // Save the region so we can use it later
+ SetWRefCon((WindowRef)MacGetWindowRef(), (SInt32)shapeRegion);
+
+ // Tell the window manager that the window has changed shape
+ ReshapeCustomWindow((WindowRef)MacGetWindowRef());
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+
+// ---------------------------------------------------------------------------
+// Support functions for shaped windows, based on Apple's CustomWindow sample at
+// http://developer.apple.com/samplecode/Sample_Code/Human_Interface_Toolbox/Mac_OS_High_Level_Toolbox/CustomWindow.htm
+// ---------------------------------------------------------------------------
+
+#if TARGET_CARBON
+
+static void wxShapedMacWindowGetPos(WindowRef window, Rect* inRect)
+{
+ GetWindowPortBounds(window, inRect);
+ Point pt = {inRect->left, inRect->top};
+ SetPort((GrafPtr) GetWindowPort(window));
+ LocalToGlobal(&pt);
+ inRect->top = pt.v;
+ inRect->left = pt.h;
+ inRect->bottom += pt.v;
+ inRect->right += pt.h;
+}
+
+
+static SInt32 wxShapedMacWindowGetFeatures(WindowRef window, SInt32 param)
+{
+ /*------------------------------------------------------
+ Define which options your custom window supports.
+ --------------------------------------------------------*/
+ //just enable everything for our demo
+ *(OptionBits*)param=//kWindowCanGrow|
+ //kWindowCanZoom|
+ //kWindowCanCollapse|
+ //kWindowCanGetWindowRegion|
+ //kWindowHasTitleBar|
+ //kWindowSupportsDragHilite|
+ kWindowCanDrawInCurrentPort|
+ //kWindowCanMeasureTitle|
+ kWindowWantsDisposeAtProcessDeath|
+ kWindowSupportsSetGrowImageRegion|
+ kWindowDefSupportsColorGrafPort;
+ return 1;
+}
+
+// The content region is left as a rectangle matching the window size, this is
+// so the origin in the paint event, and etc. still matches what the
+// programmer expects.
+static void wxShapedMacWindowContentRegion(WindowRef window, RgnHandle rgn)
+{
+ SetEmptyRgn(rgn);
+ wxTopLevelWindowMac* win = wxFindWinFromMacWindow(window);
+ if (win)
+ {
+ wxRect r = win->GetRect();
+ SetRectRgn(rgn, r.GetLeft(), r.GetTop(), r.GetRight(), r.GetBottom());
+ }
+}
+
+// The structure region is set to the shape given to the SetShape method.
+static void wxShapedMacWindowStructureRegion(WindowRef window, RgnHandle rgn)
+{
+ RgnHandle cachedRegion = (RgnHandle) GetWRefCon(window);
+
+ SetEmptyRgn(rgn);
+ if (cachedRegion)
+ {
+ Rect windowRect;
+ wxShapedMacWindowGetPos(window, &windowRect); //how big is the window
+ CopyRgn(cachedRegion, rgn); //make a copy of our cached region
+ OffsetRgn(rgn, windowRect.left, windowRect.top); // position it over window
+ //MapRgn(rgn, &mMaskSize, &windowRect); //scale it to our actual window size
+ }
+}
+
+
+
+static SInt32 wxShapedMacWindowGetRegion(WindowRef window, SInt32 param)
+{
+ GetWindowRegionPtr rgnRec=(GetWindowRegionPtr)param;
+
+ switch(rgnRec->regionCode)
+ {
+ case kWindowStructureRgn:
+ wxShapedMacWindowStructureRegion(window, rgnRec->winRgn);
+ break;
+ case kWindowContentRgn:
+ wxShapedMacWindowContentRegion(window, rgnRec->winRgn);
+ break;
+ default:
+ SetEmptyRgn(rgnRec->winRgn);
+ } //switch
+
+ return noErr;
+}
+
+
+static SInt32 wxShapedMacWindowHitTest(WindowRef window,SInt32 param)
+{
+ /*------------------------------------------------------
+ Determine the region of the window which was hit
+ --------------------------------------------------------*/
+ Point hitPoint;
+ static RgnHandle tempRgn=nil;
+
+ if(!tempRgn)
+ tempRgn=NewRgn();
+
+ SetPt(&hitPoint,LoWord(param),HiWord(param));//get the point clicked
+
+ //Mac OS 8.5 or later
+ wxShapedMacWindowStructureRegion(window, tempRgn);
+ if (PtInRgn(hitPoint, tempRgn)) //in window content region?
+ return wInContent;
+
+ return wNoHit;//no significant area was hit.
+}
+
+
+static pascal long wxShapedMacWindowDef(short varCode, WindowRef window, SInt16 message, SInt32 param)
+{
+ switch(message)
+ {
+ case kWindowMsgHitTest:
+ return wxShapedMacWindowHitTest(window,param);
+
+ case kWindowMsgGetFeatures:
+ return wxShapedMacWindowGetFeatures(window,param);
+
+ // kWindowMsgGetRegion is sent during CreateCustomWindow and ReshapeCustomWindow
+ case kWindowMsgGetRegion:
+ return wxShapedMacWindowGetRegion(window,param);
+ }
+
+ return 0;
+}
+
+#endif
+// ---------------------------------------------------------------------------
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: treectrl.cpp
+// Purpose: wxTreeCtrl. See also Robert's generic wxTreeCtrl.
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "treectrl.h"
+#endif
+
+#include "wx/stubs/textctrl.h"
+#include "wx/treebase.h"
+#include "wx/stubs/treectrl.h"
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxTreeCtrl, wxControl)
+IMPLEMENT_DYNAMIC_CLASS(wxTreeItem, wxObject)
+
+#endif
+
+wxTreeCtrl::wxTreeCtrl()
+{
+ m_imageListNormal = NULL;
+ m_imageListState = NULL;
+ m_textCtrl = NULL;
+}
+
+bool wxTreeCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
+ long style, const wxValidator& validator, const wxString& name)
+{
+ SetName(name);
+ SetValidator(validator);
+
+ m_imageListNormal = NULL;
+ m_imageListState = NULL;
+ m_textCtrl = NULL;
+
+ m_windowStyle = style;
+
+ SetParent(parent);
+
+ m_windowId = (id == -1) ? NewControlId() : id;
+
+ if (parent) parent->AddChild(this);
+
+ // TODO create tree control
+
+ return FALSE;
+}
+
+wxTreeCtrl::~wxTreeCtrl()
+{
+ if (m_textCtrl)
+ {
+ delete m_textCtrl;
+ }
+}
+
+// Attributes
+int wxTreeCtrl::GetCount() const
+{
+ // TODO
+ return 0;
+}
+
+int wxTreeCtrl::GetIndent() const
+{
+ // TODO
+ return 0;
+}
+
+void wxTreeCtrl::SetIndent(int indent)
+{
+ // TODO
+}
+
+wxImageList *wxTreeCtrl::GetImageList(int which) const
+{
+ if ( which == wxIMAGE_LIST_NORMAL )
+ {
+ return m_imageListNormal;
+ }
+ else if ( which == wxIMAGE_LIST_STATE )
+ {
+ return m_imageListState;
+ }
+ return NULL;
+}
+
+void wxTreeCtrl::SetImageList(wxImageList *imageList, int which)
+{
+ if ( which == wxIMAGE_LIST_NORMAL )
+ {
+ m_imageListNormal = imageList;
+ }
+ else if ( which == wxIMAGE_LIST_STATE )
+ {
+ m_imageListState = imageList;
+ }
+ // TODO
+}
+
+long wxTreeCtrl::GetNextItem(long item, int code) const
+{
+ // TODO
+ return 0;
+}
+
+bool wxTreeCtrl::ItemHasChildren(long item) const
+{
+ // TODO
+ return FALSE;
+}
+
+long wxTreeCtrl::GetChild(long item) const
+{
+ // TODO
+ return 0;
+}
+
+long wxTreeCtrl::GetItemParent(long item) const
+{
+ // TODO
+ return 0;
+}
+
+long wxTreeCtrl::GetFirstVisibleItem() const
+{
+ // TODO
+ return 0;
+}
+
+long wxTreeCtrl::GetNextVisibleItem(long item) const
+{
+ // TODO
+ return 0;
+}
+
+long wxTreeCtrl::GetSelection() const
+{
+ // TODO
+ return 0;
+}
+
+long wxTreeCtrl::GetRootItem() const
+{
+ // TODO
+ return 0;
+}
+
+bool wxTreeCtrl::GetItem(wxTreeItem& info) const
+{
+ // TODO
+ return FALSE;
+}
+
+bool wxTreeCtrl::SetItem(wxTreeItem& info)
+{
+ // TODO
+ return FALSE;
+}
+
+int wxTreeCtrl::GetItemState(long item, long stateMask) const
+{
+ wxTreeItem info;
+
+ info.m_mask = wxTREE_MASK_STATE ;
+ info.m_stateMask = stateMask;
+ info.m_itemId = item;
+
+ if (!GetItem(info))
+ return 0;
+
+ return info.m_state;
+}
+
+bool wxTreeCtrl::SetItemState(long item, long state, long stateMask)
+{
+ wxTreeItem info;
+
+ info.m_mask = wxTREE_MASK_STATE ;
+ info.m_state = state;
+ info.m_stateMask = stateMask;
+ info.m_itemId = item;
+
+ return SetItem(info);
+}
+
+bool wxTreeCtrl::SetItemImage(long item, int image, int selImage)
+{
+ wxTreeItem info;
+
+ info.m_mask = wxTREE_MASK_IMAGE ;
+ info.m_image = image;
+ if ( selImage > -1)
+ {
+ info.m_selectedImage = selImage;
+ info.m_mask |= wxTREE_MASK_SELECTED_IMAGE;
+ }
+ info.m_itemId = item;
+
+ return SetItem(info);
+}
+
+wxString wxTreeCtrl::GetItemText(long item) const
+{
+ wxTreeItem info;
+
+ info.m_mask = wxTREE_MASK_TEXT ;
+ info.m_itemId = item;
+
+ if (!GetItem(info))
+ return wxString("");
+ return info.m_text;
+}
+
+void wxTreeCtrl::SetItemText(long item, const wxString& str)
+{
+ wxTreeItem info;
+
+ info.m_mask = wxTREE_MASK_TEXT ;
+ info.m_itemId = item;
+ info.m_text = str;
+
+ SetItem(info);
+}
+
+long wxTreeCtrl::GetItemData(long item) const
+{
+ wxTreeItem info;
+
+ info.m_mask = wxTREE_MASK_DATA ;
+ info.m_itemId = item;
+
+ if (!GetItem(info))
+ return 0;
+ return info.m_data;
+}
+
+bool wxTreeCtrl::SetItemData(long item, long data)
+{
+ wxTreeItem info;
+
+ info.m_mask = wxTREE_MASK_DATA ;
+ info.m_itemId = item;
+ info.m_data = data;
+
+ return SetItem(info);
+}
+
+bool wxTreeCtrl::GetItemRect(long item, wxRect& rect, bool textOnly) const
+{
+ // TODO
+ return FALSE;
+}
+
+wxTextCtrl* wxTreeCtrl::GetEditControl() const
+{
+ return m_textCtrl;
+}
+
+// Operations
+bool wxTreeCtrl::DeleteItem(long item)
+{
+ // TODO
+ return FALSE;
+}
+
+bool wxTreeCtrl::ExpandItem(long item, int action)
+{
+ // TODO
+ switch ( action )
+ {
+ case wxTREE_EXPAND_EXPAND:
+ break;
+
+ case wxTREE_EXPAND_COLLAPSE:
+ break;
+
+ case wxTREE_EXPAND_COLLAPSE_RESET:
+ break;
+
+ case wxTREE_EXPAND_TOGGLE:
+ break;
+
+ default:
+ wxFAIL_MSG("unknown action in wxTreeCtrl::ExpandItem");
+ }
+
+ bool bOk = FALSE; // TODO expand item
+
+ // May not send messages, so emulate them
+ if ( bOk ) {
+ wxTreeEvent event(wxEVT_NULL, m_windowId);
+ event.m_item.m_itemId = item;
+ event.m_item.m_mask =
+ event.m_item.m_stateMask = 0xffff; // get all
+ GetItem(event.m_item);
+
+ bool bIsExpanded = (event.m_item.m_state & wxTREE_STATE_EXPANDED) != 0;
+
+ event.m_code = action;
+ event.SetEventObject(this);
+
+ // @@@ return values of {EXPAND|COLLAPS}ING event handler is discarded
+ event.SetEventType(bIsExpanded ? wxEVT_COMMAND_TREE_ITEM_EXPANDING
+ : wxEVT_COMMAND_TREE_ITEM_COLLAPSING);
+ GetEventHandler()->ProcessEvent(event);
+
+ event.SetEventType(bIsExpanded ? wxEVT_COMMAND_TREE_ITEM_EXPANDED
+ : wxEVT_COMMAND_TREE_ITEM_COLLAPSED);
+ GetEventHandler()->ProcessEvent(event);
+ }
+
+ return bOk;
+}
+
+long wxTreeCtrl::InsertItem(long parent, wxTreeItem& info, long insertAfter)
+{
+ // TODO
+ return 0;
+}
+
+long wxTreeCtrl::InsertItem(long parent, const wxString& label, int image, int selImage,
+ long insertAfter)
+{
+ wxTreeItem info;
+ info.m_text = label;
+ info.m_mask = wxTREE_MASK_TEXT;
+ if ( image > -1 )
+ {
+ info.m_mask |= wxTREE_MASK_IMAGE | wxTREE_MASK_SELECTED_IMAGE;
+ info.m_image = image;
+ if ( selImage == -1 )
+ info.m_selectedImage = image;
+ else
+ info.m_selectedImage = selImage;
+ }
+
+ return InsertItem(parent, info, insertAfter);
+}
+
+bool wxTreeCtrl::SelectItem(long item)
+{
+ // TODO
+ return FALSE;
+}
+
+bool wxTreeCtrl::ScrollTo(long item)
+{
+ // TODO
+ return FALSE;
+}
+
+bool wxTreeCtrl::DeleteAllItems()
+{
+ // TODO
+ return FALSE;
+}
+
+wxTextCtrl* wxTreeCtrl::EditLabel(long item, wxClassInfo* textControlClass)
+{
+ // TODO
+ return NULL;
+}
+
+// End label editing, optionally cancelling the edit
+bool wxTreeCtrl::EndEditLabel(bool cancel)
+{
+ // TODO
+ return FALSE;
+}
+
+long wxTreeCtrl::HitTest(const wxPoint& point, int& flags)
+{
+ // TODO
+ return 0;
+}
+
+bool wxTreeCtrl::SortChildren(long item)
+{
+ // TODO
+ return FALSE;
+}
+
+bool wxTreeCtrl::EnsureVisible(long item)
+{
+ // TODO
+ return FALSE;
+}
+
+// Tree item structure
+wxTreeItem::wxTreeItem()
+{
+ m_mask = 0;
+ m_itemId = 0;
+ m_state = 0;
+ m_stateMask = 0;
+ m_image = -1;
+ m_selectedImage = -1;
+ m_children = 0;
+ m_data = 0;
+}
+
+// Tree event
+IMPLEMENT_DYNAMIC_CLASS(wxTreeEvent, wxCommandEvent)
+
+wxTreeEvent::wxTreeEvent(wxEventType commandType, int id):
+ wxCommandEvent(commandType, id)
+{
+ m_code = 0;
+ m_oldItem = 0;
+}
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: uma.cpp
+// Purpose: UMA support
+// Author: Stefan Csomor
+// Modified by:
+// Created: 04/01/98
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: The wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#include "wx/defs.h"
+
+#if wxUSE_GUI
+
+#include "wx/dc.h"
+#include <MacTextEditor.h>
+
+#ifndef __DARWIN__
+# include <Navigation.h>
+# if defined(TARGET_CARBON)
+# if PM_USE_SESSION_APIS
+# include <PMCore.h>
+# endif
+# include <PMApplication.h>
+# else
+# include <Printing.h>
+# endif
+#endif
+
+#ifndef __DARWIN__
+#include <Scrap.h>
+#endif
+#include "wx/mac/uma.h"
+
+
+// since we have decided that we only support 8.6 upwards we are
+// checking for these minimum requirements in the startup code of
+// the application so all wxWindows code can safely assume that appearance 1.1
+// windows manager, control manager, navigation services etc. are
+// present
+
+static bool sUMAHasAppearance = false ;
+static long sUMAAppearanceVersion = 0 ;
+static long sUMASystemVersion = 0 ;
+static bool sUMAHasAquaLayout = false ;
+
+static bool sUMAHasInittedAppearance = false;
+
+extern int gAGABackgroundColor ;
+bool UMAHasAppearance() { return sUMAHasAppearance ; }
+long UMAGetAppearanceVersion() { return sUMAAppearanceVersion ; }
+long UMAGetSystemVersion() { return sUMASystemVersion ; }
+
+static bool sUMAHasWindowManager = false ;
+static long sUMAWindowManagerAttr = 0 ;
+
+bool UMAHasWindowManager() { return sUMAHasWindowManager ; }
+long UMAGetWindowManagerAttr() { return sUMAWindowManagerAttr ; }
+bool UMAHasAquaLayout() { return sUMAHasAquaLayout ; }
+
+
+void UMACleanupToolbox()
+{
+ if (sUMAHasInittedAppearance)
+ {
+ UnregisterAppearanceClient() ;
+ }
+ if ( NavServicesAvailable() )
+ {
+ NavUnload() ;
+ }
+ if ( TXNTerminateTextension != (void*) kUnresolvedCFragSymbolAddress )
+ TXNTerminateTextension( ) ;
+}
+void UMAInitToolbox( UInt16 inMoreMastersCalls, bool isEmbedded )
+{
+#if !TARGET_CARBON
+ ::MaxApplZone();
+ for (long i = 1; i <= inMoreMastersCalls; i++)
+ ::MoreMasters();
+
+ if (!isEmbedded)
+ {
+ ::InitGraf(&qd.thePort);
+ ::InitFonts();
+ ::InitMenus();
+ ::TEInit();
+ ::InitDialogs(0L);
+ ::FlushEvents(everyEvent, 0);
+ }
+
+ long total,contig;
+ PurgeSpace(&total, &contig);
+#endif
+
+ ::InitCursor();
+
+ if ( Gestalt(gestaltSystemVersion, &sUMASystemVersion) != noErr)
+ sUMASystemVersion = 0x0000 ;
+
+ long theAppearance ;
+ if ( Gestalt( gestaltAppearanceAttr, &theAppearance ) == noErr )
+ {
+ sUMAHasAppearance = true ;
+ OSStatus status = RegisterAppearanceClient();
+ // If status equals appearanceProcessRegisteredErr it means the
+ // appearance client already was registered (For example if we run
+ // embedded, the host might have registered it). In such a case
+ // we don't unregister it later on.
+ if (status != appearanceProcessRegisteredErr)
+ {
+ // Appearance client wasn't registered yet.
+ sUMAHasInittedAppearance = true;
+ }
+
+ if ( Gestalt( gestaltAppearanceVersion, &theAppearance ) == noErr )
+ {
+ sUMAAppearanceVersion = theAppearance ;
+ }
+ else
+ {
+ sUMAAppearanceVersion = 0x0100 ;
+ }
+ }
+ if ( Gestalt( gestaltWindowMgrAttr, &sUMAWindowManagerAttr ) == noErr )
+ {
+ sUMAHasWindowManager = sUMAWindowManagerAttr & gestaltWindowMgrPresent ;
+ }
+
+#if TARGET_CARBON
+// Call currently implicitely done : InitFloatingWindows() ;
+#else
+ if (!isEmbedded)
+ {
+ if ( sUMAHasWindowManager )
+ InitFloatingWindows() ;
+ else
+ InitWindows();
+ }
+#endif
+
+ if ( NavServicesAvailable() )
+ {
+ NavLoad() ;
+ }
+
+ long menuMgrAttr ;
+ Gestalt( gestaltMenuMgrAttr , &menuMgrAttr ) ;
+ if ( menuMgrAttr & gestaltMenuMgrAquaLayoutMask )
+ sUMAHasAquaLayout = true ;
+
+ if ( TXNInitTextension != (void*) kUnresolvedCFragSymbolAddress )
+ {
+ FontFamilyID fontId ;
+ Str255 fontName ;
+ SInt16 fontSize ;
+ Style fontStyle ;
+ GetThemeFont(kThemeSmallSystemFont , GetApplicationScript() , fontName , &fontSize , &fontStyle ) ;
+ GetFNum( fontName, &fontId );
+
+ TXNMacOSPreferredFontDescription fontDescriptions[] =
+ {
+ { fontId , (fontSize << 16) ,kTXNDefaultFontStyle, kTXNSystemDefaultEncoding }
+ } ;
+ int noOfFontDescriptions = sizeof( fontDescriptions ) / sizeof(TXNMacOSPreferredFontDescription) ;
+
+ // kTXNAlwaysUseQuickDrawTextMask might be desirable because of speed increases but it crashes the app under OS X upon key stroke
+#if 0
+ // leads to unexpected content for clients, TODO configurable
+ OptionBits options = kTXNWantMoviesMask | kTXNWantSoundMask | kTXNWantGraphicsMask ;
+#else
+ OptionBits options = 0 ;
+#endif
+
+#if TARGET_CARBON
+ if ( !UMAHasAquaLayout() )
+#endif
+ {
+ options |= kTXNAlwaysUseQuickDrawTextMask ;
+ }
+ TXNInitTextension(fontDescriptions, noOfFontDescriptions, options );
+ }
+
+
+ UMASetSystemIsInitialized(true);
+
+}
+
+/*
+Boolean CanUseATSUI()
+ {
+ long result;
+ OSErr err = Gestalt(gestaltATSUVersion, &result);
+ return (err == noErr);
+ }
+*/
+// process manager
+long UMAGetProcessMode()
+{
+ OSErr err ;
+ ProcessInfoRec processinfo;
+ ProcessSerialNumber procno ;
+
+ procno.highLongOfPSN = NULL ;
+ procno.lowLongOfPSN = kCurrentProcess ;
+ processinfo.processInfoLength = sizeof(ProcessInfoRec);
+ processinfo.processName = NULL;
+ processinfo.processAppSpec = NULL;
+
+ err = ::GetProcessInformation( &procno , &processinfo ) ;
+ wxASSERT( err == noErr ) ;
+ return processinfo.processMode ;
+}
+
+bool UMAGetProcessModeDoesActivateOnFGSwitch()
+{
+ return UMAGetProcessMode() & modeDoesActivateOnFGSwitch ;
+}
+
+// menu manager
+
+MenuRef UMANewMenu( SInt16 id , const wxString& title , wxFontEncoding encoding )
+{
+ wxString str = wxStripMenuCodes( title ) ;
+ MenuRef menu ;
+#if TARGET_CARBON
+ CreateNewMenu( id , 0 , &menu ) ;
+ SetMenuTitleWithCFString( menu , wxMacCFStringHolder(str , encoding ) ) ;
+#else
+ Str255 ptitle ;
+ wxMacStringToPascal( str , ptitle ) ;
+ menu = ::NewMenu( id , ptitle ) ;
+#endif
+ return menu ;
+}
+
+void UMASetMenuTitle( MenuRef menu , const wxString& title , wxFontEncoding encoding)
+{
+ wxString str = wxStripMenuCodes( title ) ;
+#if TARGET_CARBON
+ SetMenuTitleWithCFString( menu , wxMacCFStringHolder(str , encoding) ) ;
+#else
+ Str255 ptitle ;
+ wxMacStringToPascal( str , ptitle ) ;
+ SetMenuTitle( menu , ptitle ) ;
+#endif
+}
+
+void UMASetMenuItemText( MenuRef menu, MenuItemIndex item, const wxString& title , wxFontEncoding encoding)
+{
+ wxString str = wxStripMenuCodes( title ) ;
+#if TARGET_CARBON
+ SetMenuItemTextWithCFString( menu , item , wxMacCFStringHolder(str , encoding) ) ;
+#else
+ Str255 ptitle ;
+ wxMacStringToPascal( str , ptitle ) ;
+ SetMenuItemText( menu , item , ptitle ) ;
+#endif
+}
+
+
+UInt32 UMAMenuEvent( EventRecord *inEvent )
+{
+ return MenuEvent( inEvent ) ;
+}
+
+void UMAEnableMenuItem( MenuRef inMenu , MenuItemIndex inItem , bool enable)
+{
+ if ( enable )
+ EnableMenuItem( inMenu , inItem ) ;
+ else
+ DisableMenuItem( inMenu , inItem ) ;
+}
+
+void UMAAppendSubMenuItem( MenuRef menu , const wxString& title, wxFontEncoding encoding , SInt16 id )
+{
+ MacAppendMenu(menu, "\pA");
+ UMASetMenuItemText(menu, (SInt16) ::CountMenuItems(menu), title , encoding );
+ SetMenuItemHierarchicalID( menu , CountMenuItems( menu ) , id ) ;
+}
+
+void UMAInsertSubMenuItem( MenuRef menu , const wxString& title, wxFontEncoding encoding , MenuItemIndex item , SInt16 id )
+{
+ MacInsertMenuItem(menu, "\pA" , item);
+ UMASetMenuItemText(menu, item , title , encoding);
+ SetMenuItemHierarchicalID( menu , item , id ) ;
+}
+
+void UMASetMenuItemShortcut( MenuRef menu , MenuItemIndex item , wxAcceleratorEntry *entry )
+{
+ if ( !entry )
+ return ;
+
+ UInt8 modifiers = 0 ;
+ SInt16 key = entry->GetKeyCode() ;
+ if ( key )
+ {
+ bool explicitCommandKey = false ;
+
+ if ( entry->GetFlags() & wxACCEL_CTRL )
+ {
+ explicitCommandKey = true ;
+ }
+
+ if (entry->GetFlags() & wxACCEL_ALT )
+ {
+ modifiers |= kMenuOptionModifier ;
+ }
+
+ if (entry->GetFlags() & wxACCEL_SHIFT)
+ {
+ modifiers |= kMenuShiftModifier ;
+ }
+
+ SInt16 glyph = 0 ;
+ SInt16 macKey = key ;
+ if ( key >= WXK_F1 && key <= WXK_F15 )
+ {
+ // for some reasons this must be 0 right now
+ // everything else leads to just the first function key item
+ // to be selected. Thanks to Ryan Wilcox for finding out.
+ macKey = 0 ;
+ glyph = kMenuF1Glyph + ( key - WXK_F1 ) ;
+ if ( key >= WXK_F13 )
+ glyph += 13 ;
+ if ( !explicitCommandKey )
+ modifiers |= kMenuNoCommandModifier ;
+ }
+ else
+ {
+ switch( key )
+ {
+ case WXK_BACK :
+ macKey = kBackspaceCharCode ;
+ glyph = kMenuDeleteLeftGlyph ;
+ break ;
+ case WXK_TAB :
+ macKey = kTabCharCode ;
+ glyph = kMenuTabRightGlyph ;
+ break ;
+ case kEnterCharCode :
+ macKey = kEnterCharCode ;
+ glyph = kMenuEnterGlyph ;
+ break ;
+ case WXK_RETURN :
+ macKey = kReturnCharCode ;
+ glyph = kMenuReturnGlyph ;
+ break ;
+ case WXK_ESCAPE :
+ macKey = kEscapeCharCode ;
+ glyph = kMenuEscapeGlyph ;
+ break ;
+ case WXK_SPACE :
+ macKey = ' ' ;
+ glyph = kMenuSpaceGlyph ;
+ break ;
+ case WXK_DELETE :
+ macKey = kDeleteCharCode ;
+ glyph = kMenuDeleteRightGlyph ;
+ break ;
+ case WXK_CLEAR :
+ macKey = kClearCharCode ;
+ glyph = kMenuClearGlyph ;
+ break ;
+ case WXK_PRIOR : // PAGE UP
+ macKey = kPageUpCharCode ;
+ glyph = kMenuPageUpGlyph ;
+ break ;
+ case WXK_NEXT :
+ macKey = kPageDownCharCode ;
+ glyph = kMenuPageDownGlyph ;
+ break ;
+ case WXK_LEFT :
+ macKey = kLeftArrowCharCode ;
+ glyph = kMenuLeftArrowGlyph ;
+ break ;
+ case WXK_UP :
+ macKey = kUpArrowCharCode ;
+ glyph = kMenuUpArrowGlyph ;
+ break ;
+ case WXK_RIGHT :
+ macKey = kRightArrowCharCode ;
+ glyph = kMenuRightArrowGlyph ;
+ break ;
+ case WXK_DOWN :
+ macKey = kDownArrowCharCode ;
+ glyph = kMenuDownArrowGlyph ;
+ break ;
+ }
+ }
+
+ SetItemCmd( menu, item , macKey );
+ SetMenuItemModifiers(menu, item , modifiers ) ;
+
+ if ( glyph )
+ SetMenuItemKeyGlyph(menu, item , glyph ) ;
+ }
+}
+
+void UMAAppendMenuItem( MenuRef menu , const wxString& title, wxFontEncoding encoding , wxAcceleratorEntry *entry )
+{
+ MacAppendMenu(menu, "\pA");
+ UMASetMenuItemText(menu, (SInt16) ::CountMenuItems(menu), title , encoding );
+ UMASetMenuItemShortcut( menu , (SInt16) ::CountMenuItems(menu), entry ) ;
+}
+
+void UMAInsertMenuItem( MenuRef menu , const wxString& title, wxFontEncoding encoding , MenuItemIndex item , wxAcceleratorEntry *entry )
+{
+ MacInsertMenuItem( menu , "\pA" , item) ;
+ UMASetMenuItemText(menu, item+1 , title , encoding );
+ UMASetMenuItemShortcut( menu , item+1 , entry ) ;
+}
+
+// quickdraw
+
+#if !TARGET_CARBON
+
+int gPrOpenCounter = 0 ;
+
+OSStatus UMAPrOpen()
+{
+ OSErr err = noErr ;
+ ++gPrOpenCounter ;
+ if ( gPrOpenCounter == 1 )
+ {
+ PrOpen() ;
+ err = PrError() ;
+ wxASSERT( err == noErr ) ;
+ }
+ return err ;
+}
+
+OSStatus UMAPrClose()
+{
+ OSErr err = noErr ;
+ wxASSERT( gPrOpenCounter >= 1 ) ;
+ if ( gPrOpenCounter == 1 )
+ {
+ PrClose() ;
+ err = PrError() ;
+ wxASSERT( err == noErr ) ;
+ }
+ --gPrOpenCounter ;
+ return err ;
+}
+
+pascal QDGlobalsPtr GetQDGlobalsPtr (void) ;
+pascal QDGlobalsPtr GetQDGlobalsPtr (void)
+{
+ return QDGlobalsPtr (* (Ptr*) LMGetCurrentA5 ( ) - 0xCA);
+}
+
+#endif
+
+void UMAShowWatchCursor()
+{
+ OSErr err = noErr;
+
+ CursHandle watchFob = GetCursor (watchCursor);
+
+ if (!watchFob)
+ err = nilHandleErr;
+ else
+ {
+ #if TARGET_CARBON
+// Cursor preservedArrow;
+// GetQDGlobalsArrow (&preservedArrow);
+// SetQDGlobalsArrow (*watchFob);
+// InitCursor ( );
+// SetQDGlobalsArrow (&preservedArrow);
+ SetCursor (*watchFob);
+ #else
+ SetCursor (*watchFob);
+ #endif
+ }
+}
+
+void UMAShowArrowCursor()
+{
+#if TARGET_CARBON
+ Cursor arrow;
+ SetCursor (GetQDGlobalsArrow (&arrow));
+#else
+ SetCursor (&(qd.arrow));
+#endif
+}
+
+// window manager
+
+GrafPtr UMAGetWindowPort( WindowRef inWindowRef )
+{
+ wxASSERT( inWindowRef != NULL ) ;
+#if TARGET_CARBON
+ return (GrafPtr) GetWindowPort( inWindowRef ) ;
+#else
+ return (GrafPtr) inWindowRef ;
+#endif
+}
+
+void UMADisposeWindow( WindowRef inWindowRef )
+{
+ wxASSERT( inWindowRef != NULL ) ;
+ DisposeWindow( inWindowRef ) ;
+}
+
+void UMASetWTitle( WindowRef inWindowRef , const wxString& title , wxFontEncoding encoding)
+{
+#if TARGET_CARBON
+ SetWindowTitleWithCFString( inWindowRef , wxMacCFStringHolder(title , encoding) ) ;
+#else
+ Str255 ptitle ;
+ wxMacStringToPascal( title , ptitle ) ;
+ SetWTitle( inWindowRef , ptitle ) ;
+#endif
+}
+
+// appearance additions
+
+void UMASetControlTitle( ControlHandle inControl , const wxString& title , wxFontEncoding encoding)
+{
+#if TARGET_CARBON
+ SetControlTitleWithCFString( inControl , wxMacCFStringHolder(title , encoding) ) ;
+#else
+ Str255 ptitle ;
+ wxMacStringToPascal( title , ptitle ) ;
+ SetControlTitle( inControl , ptitle ) ;
+#endif
+}
+
+void UMAActivateControl( ControlHandle inControl )
+{
+ // we have to add the control after again to the update rgn
+ // otherwise updates get lost
+ if ( !IsControlActive( inControl ) )
+ {
+ bool visible = IsControlVisible( inControl ) ;
+ if ( visible )
+ SetControlVisibility( inControl , false , false ) ;
+ ::ActivateControl( inControl ) ;
+ if ( visible ) {
+ SetControlVisibility( inControl , true , false ) ;
+ Rect ctrlBounds ;
+ InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
+ }
+ }
+}
+
+void UMADrawControl( ControlHandle inControl )
+{
+ WindowRef theWindow = GetControlOwner(inControl) ;
+ wxMacPortStateHelper help( (GrafPtr) GetWindowPort(theWindow) ) ;
+ RgnHandle updateRgn = NewRgn() ;
+ GetWindowUpdateRgn( theWindow , updateRgn ) ;
+ Point zero = { 0 , 0 } ;
+ LocalToGlobal( &zero ) ;
+ OffsetRgn( updateRgn , -zero.h , -zero.v ) ;
+ ::DrawControlInCurrentPort( inControl ) ;
+ InvalWindowRgn( theWindow, updateRgn) ;
+ DisposeRgn( updateRgn ) ;
+}
+
+void UMAMoveControl( ControlHandle inControl , short x , short y )
+{
+ bool visible = IsControlVisible( inControl ) ;
+ if ( visible ) {
+ SetControlVisibility( inControl , false , false ) ;
+ Rect ctrlBounds ;
+ InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
+ }
+ ::MoveControl( inControl , x , y ) ;
+ if ( visible ) {
+ SetControlVisibility( inControl , true , false ) ;
+ Rect ctrlBounds ;
+ InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
+ }
+}
+
+void UMASizeControl( ControlHandle inControl , short x , short y )
+{
+ bool visible = IsControlVisible( inControl ) ;
+ if ( visible ) {
+ SetControlVisibility( inControl , false , false ) ;
+ Rect ctrlBounds ;
+ InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
+ }
+ ::SizeControl( inControl , x , y ) ;
+ if ( visible ) {
+ SetControlVisibility( inControl , true , false ) ;
+ Rect ctrlBounds ;
+ InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
+ }
+}
+
+void UMADeactivateControl( ControlHandle inControl )
+{
+ // we have to add the control after again to the update rgn
+ // otherwise updates get lost
+ bool visible = IsControlVisible( inControl ) ;
+ if ( visible )
+ SetControlVisibility( inControl , false , false ) ;
+ ::DeactivateControl( inControl ) ;
+ if ( visible ) {
+ SetControlVisibility( inControl , true , false ) ;
+ Rect ctrlBounds ;
+ InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
+ }
+}
+// shows the control and adds the region to the update region
+void UMAShowControl (ControlHandle inControl)
+{
+ SetControlVisibility( inControl , true , false ) ;
+ Rect ctrlBounds ;
+ InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
+}
+
+// shows the control and adds the region to the update region
+void UMAHideControl (ControlHandle inControl)
+{
+ SetControlVisibility( inControl , false , false ) ;
+ Rect ctrlBounds ;
+ InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
+}
+// keyboard focus
+OSErr UMASetKeyboardFocus (WindowPtr inWindow,
+ ControlHandle inControl,
+ ControlFocusPart inPart)
+{
+ OSErr err = noErr;
+ GrafPtr port ;
+ GetPort( &port ) ;
+
+ SetPortWindowPort( inWindow ) ;
+
+ err = SetKeyboardFocus( inWindow , inControl , inPart ) ;
+ SetPort( port ) ;
+ return err ;
+}
+
+
+// events
+void UMAUpdateControls( WindowPtr inWindow , RgnHandle inRgn )
+{
+ wxMacPortStateHelper help( (GrafPtr) GetWindowPort( (WindowRef) inWindow) ) ;
+ RgnHandle updateRgn = NewRgn() ;
+ GetWindowUpdateRgn( inWindow , updateRgn ) ;
+
+ Point zero = { 0 , 0 } ;
+ LocalToGlobal( &zero ) ;
+ OffsetRgn( updateRgn , -zero.h , -zero.v ) ;
+
+ UpdateControls( inWindow , inRgn ) ;
+ InvalWindowRgn( inWindow, updateRgn) ;
+ DisposeRgn( updateRgn ) ;
+}
+
+bool UMAIsWindowFloating( WindowRef inWindow )
+{
+ WindowClass cl ;
+
+ GetWindowClass( inWindow , &cl ) ;
+ return cl == kFloatingWindowClass ;
+}
+
+bool UMAIsWindowModal( WindowRef inWindow )
+{
+ WindowClass cl ;
+
+ GetWindowClass( inWindow , &cl ) ;
+ return cl < kFloatingWindowClass ;
+}
+
+// others
+
+void UMAHighlightAndActivateWindow( WindowRef inWindowRef , bool inActivate )
+{
+ if ( inWindowRef )
+ {
+// bool isHighlighted = IsWindowHighlited( inWindowRef ) ;
+// if ( inActivate != isHightlited )
+ GrafPtr port ;
+ GetPort( &port ) ;
+ SetPortWindowPort( inWindowRef ) ;
+ HiliteWindow( inWindowRef , inActivate ) ;
+ ControlHandle control = NULL ;
+ ::GetRootControl( inWindowRef , & control ) ;
+ if ( control )
+ {
+ if ( inActivate )
+ UMAActivateControl( control ) ;
+ else
+ UMADeactivateControl( control ) ;
+ }
+ SetPort( port ) ;
+ }
+}
+
+OSStatus UMADrawThemePlacard( const Rect *inRect , ThemeDrawState inState )
+{
+ return ::DrawThemePlacard( inRect , inState ) ;
+}
+
+#if !TARGET_CARBON
+static OSStatus helpMenuStatus = noErr ;
+static MenuItemIndex firstCustomItemIndex = 0 ;
+#endif
+
+OSStatus UMAGetHelpMenu(
+ MenuRef * outHelpMenu,
+ MenuItemIndex * outFirstCustomItemIndex)
+{
+#if TARGET_CARBON
+ return HMGetHelpMenu( outHelpMenu , outFirstCustomItemIndex ) ;
+#else
+ MenuRef helpMenuHandle ;
+ helpMenuStatus = HMGetHelpMenuHandle( &helpMenuHandle ) ;
+ if ( firstCustomItemIndex == 0 && helpMenuStatus == noErr )
+ {
+ firstCustomItemIndex = CountMenuItems( helpMenuHandle ) + 1 ;
+ }
+ if ( outFirstCustomItemIndex )
+ {
+ *outFirstCustomItemIndex = firstCustomItemIndex ;
+ }
+ *outHelpMenu = helpMenuHandle ;
+ return helpMenuStatus ;
+#endif
+}
+
+wxMacPortStateHelper::wxMacPortStateHelper( GrafPtr newport)
+{
+ m_clip = NULL ;
+ Setup( newport ) ;
+}
+
+wxMacPortStateHelper::wxMacPortStateHelper()
+{
+ m_clip = NULL ;
+}
+
+void wxMacPortStateHelper::Setup( GrafPtr newport )
+{
+ GetPort( &m_oldPort ) ;
+ SetPort( newport ) ;
+ SetOrigin(0,0);
+ wxASSERT_MSG( m_clip == NULL , wxT("Cannot call setup twice") ) ;
+ m_clip = NewRgn() ;
+ GetClip( m_clip );
+ m_textFont = GetPortTextFont( (CGrafPtr) newport);
+ m_textSize = GetPortTextSize( (CGrafPtr) newport);
+ m_textStyle = GetPortTextFace( (CGrafPtr) newport);
+ m_textMode = GetPortTextMode( (CGrafPtr) newport);
+ GetThemeDrawingState( &m_drawingState ) ;
+ m_currentPort = newport ;
+}
+void wxMacPortStateHelper::Clear()
+{
+ if ( m_clip )
+ {
+ DisposeRgn( m_clip ) ;
+ DisposeThemeDrawingState( m_drawingState ) ;
+ m_clip = NULL ;
+ }
+}
+
+wxMacPortStateHelper::~wxMacPortStateHelper()
+{
+ if ( m_clip )
+ {
+ SetPort( m_currentPort ) ;
+ SetClip( m_clip ) ;
+ DisposeRgn( m_clip ) ;
+ TextFont( m_textFont );
+ TextSize( m_textSize );
+ TextFace( m_textStyle );
+ TextMode( m_textMode );
+ SetThemeDrawingState( m_drawingState , true ) ;
+ SetPort( m_oldPort ) ;
+ }
+}
+
+OSStatus UMAPutScrap( Size size , OSType type , void *data )
+{
+ OSStatus err = noErr ;
+#if !TARGET_CARBON
+ err = PutScrap( size , type , data ) ;
+#else
+ ScrapRef scrap;
+ err = GetCurrentScrap (&scrap);
+ if ( !err )
+ {
+ err = PutScrapFlavor (scrap, type , 0, size, data);
+ }
+#endif
+ return err ;
+}
+
+#endif // wxUSE_GUI
+
+#if wxUSE_BASE
+
+static bool sUMASystemInitialized = false ;
+
+bool UMASystemIsInitialized()
+{
+ return sUMASystemInitialized ;
+}
+
+void UMASetSystemIsInitialized(bool val)
+{
+ sUMASystemInitialized = val;
+}
+
+
+#endif // wxUSE_BASE
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: utils.cpp
+// Purpose: Various utilities
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+// Note: this is done in utilscmn.cpp now.
+// #pragma implementation "utils.h"
+#endif
+
+#include "wx/setup.h"
+#include "wx/utils.h"
+#include "wx/app.h"
+#include "wx/apptrait.h"
+
+#if wxUSE_GUI
+ #include "wx/mac/uma.h"
+ #include "wx/font.h"
+#else
+ #include "wx/intl.h"
+#endif
+
+#include <ctype.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#ifdef __DARWIN__
+# include "MoreFilesX.h"
+#else
+# include "MoreFiles.h"
+# include "MoreFilesExtras.h"
+#endif
+
+#ifndef __DARWIN__
+#include <Threads.h>
+#include <Sound.h>
+#endif
+
+#include <ATSUnicode.h>
+#include <TextCommon.h>
+#include <TextEncodingConverter.h>
+
+#include "wx/mac/private.h" // includes mac headers
+
+#if defined(__MWERKS__) && wxUSE_UNICODE
+ #include <wtime.h>
+#endif
+
+// ---------------------------------------------------------------------------
+// code used in both base and GUI compilation
+// ---------------------------------------------------------------------------
+
+// our OS version is the same in non GUI and GUI cases
+static int DoGetOSVersion(int *majorVsn, int *minorVsn)
+{
+ long theSystem ;
+
+ // are there x-platform conventions ?
+
+ Gestalt(gestaltSystemVersion, &theSystem) ;
+ if (minorVsn != NULL) {
+ *minorVsn = (theSystem & 0xFF ) ;
+ }
+ if (majorVsn != NULL) {
+ *majorVsn = (theSystem >> 8 ) ;
+ }
+#ifdef __DARWIN__
+ return wxMAC_DARWIN;
+#else
+ return wxMAC;
+#endif
+}
+
+#if wxUSE_BASE
+
+#ifndef __DARWIN__
+// defined in unix/utilsunx.cpp for Mac OS X
+
+// get full hostname (with domain name if possible)
+bool wxGetFullHostName(wxChar *buf, int maxSize)
+{
+ return wxGetHostName(buf, maxSize);
+}
+
+// Get hostname only (without domain name)
+bool wxGetHostName(wxChar *buf, int maxSize)
+{
+ // Gets Chooser name of user by examining a System resource.
+
+ const short kComputerNameID = -16413;
+
+ short oldResFile = CurResFile() ;
+ UseResFile(0);
+ StringHandle chooserName = (StringHandle)::GetString(kComputerNameID);
+ UseResFile(oldResFile);
+
+ if (chooserName && *chooserName)
+ {
+ HLock( (Handle) chooserName ) ;
+ wxString name = wxMacMakeStringFromPascal( *chooserName ) ;
+ HUnlock( (Handle) chooserName ) ;
+ ReleaseResource( (Handle) chooserName ) ;
+ wxStrncpy( buf , name , maxSize - 1 ) ;
+ }
+ else
+ buf[0] = 0 ;
+
+ return TRUE;
+}
+
+// Get user ID e.g. jacs
+bool wxGetUserId(wxChar *buf, int maxSize)
+{
+ return wxGetUserName( buf , maxSize ) ;
+}
+
+const wxChar* wxGetHomeDir(wxString *pstr)
+{
+ *pstr = wxMacFindFolder( (short) kOnSystemDisk, kPreferencesFolderType, kDontCreateFolder ) ;
+ return pstr->c_str() ;
+}
+
+// Get user name e.g. Stefan Csomor
+bool wxGetUserName(wxChar *buf, int maxSize)
+{
+ // Gets Chooser name of user by examining a System resource.
+
+ const short kChooserNameID = -16096;
+
+ short oldResFile = CurResFile() ;
+ UseResFile(0);
+ StringHandle chooserName = (StringHandle)::GetString(kChooserNameID);
+ UseResFile(oldResFile);
+
+ if (chooserName && *chooserName)
+ {
+ HLock( (Handle) chooserName ) ;
+ wxString name = wxMacMakeStringFromPascal( *chooserName ) ;
+ HUnlock( (Handle) chooserName ) ;
+ ReleaseResource( (Handle) chooserName ) ;
+ wxStrncpy( buf , name , maxSize - 1 ) ;
+ }
+ else
+ buf[0] = 0 ;
+
+ return TRUE;
+}
+
+int wxKill(long pid, wxSignal sig , wxKillError *rc )
+{
+ // TODO
+ return 0;
+}
+
+WXDLLEXPORT bool wxGetEnv(const wxString& var, wxString *value)
+{
+ // TODO : under classic there is no environement support, under X yes
+ return false ;
+}
+
+// set the env var name to the given value, return TRUE on success
+WXDLLEXPORT bool wxSetEnv(const wxString& var, const wxChar *value)
+{
+ // TODO : under classic there is no environement support, under X yes
+ return false ;
+}
+
+//
+// Execute a program in an Interactive Shell
+//
+bool wxShell(const wxString& command)
+{
+ // TODO
+ return FALSE;
+}
+
+// Shutdown or reboot the PC
+bool wxShutdown(wxShutdownFlags wFlags)
+{
+ // TODO
+ return FALSE;
+}
+
+// Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
+long wxGetFreeMemory()
+{
+ return FreeMem() ;
+}
+
+void wxUsleep(unsigned long milliseconds)
+{
+ clock_t start = clock() ;
+ do
+ {
+ YieldToAnyThread() ;
+ } while( clock() - start < milliseconds / 1000.0 * CLOCKS_PER_SEC ) ;
+}
+
+void wxSleep(int nSecs)
+{
+ wxUsleep(1000*nSecs);
+}
+
+// Consume all events until no more left
+void wxFlushEvents()
+{
+}
+
+#endif // !__DARWIN__
+
+// Emit a beeeeeep
+void wxBell()
+{
+ SysBeep(30);
+}
+
+wxToolkitInfo& wxConsoleAppTraits::GetToolkitInfo()
+{
+ static wxToolkitInfo info;
+ info.os = DoGetOSVersion(&info.versionMajor, &info.versionMinor);
+ info.name = _T("wxBase");
+ return info;
+}
+
+#endif // wxUSE_BASE
+
+#if wxUSE_GUI
+
+wxToolkitInfo& wxGUIAppTraits::GetToolkitInfo()
+{
+ static wxToolkitInfo info;
+ info.os = DoGetOSVersion(&info.versionMajor, &info.versionMinor);
+ info.shortName = _T("mac");
+ info.name = _T("wxMac");
+#ifdef __WXUNIVERSAL__
+ info.shortName << _T("univ");
+ info.name << _T("/wxUniversal");
+#endif
+ return info;
+}
+
+// Reading and writing resources (eg WIN.INI, .Xdefaults)
+#if wxUSE_RESOURCES
+bool wxWriteResource(const wxString& section, const wxString& entry, const wxString& value, const wxString& file)
+{
+ // TODO
+ return FALSE;
+}
+
+bool wxWriteResource(const wxString& section, const wxString& entry, float value, const wxString& file)
+{
+ wxString buf;
+ buf.Printf(wxT("%.4f"), value);
+
+ return wxWriteResource(section, entry, buf, file);
+}
+
+bool wxWriteResource(const wxString& section, const wxString& entry, long value, const wxString& file)
+{
+ wxString buf;
+ buf.Printf(wxT("%ld"), value);
+
+ return wxWriteResource(section, entry, buf, file);
+}
+
+bool wxWriteResource(const wxString& section, const wxString& entry, int value, const wxString& file)
+{
+ wxString buf;
+ buf.Printf(wxT("%d"), value);
+
+ return wxWriteResource(section, entry, buf, file);
+}
+
+bool wxGetResource(const wxString& section, const wxString& entry, char **value, const wxString& file)
+{
+ // TODO
+ return FALSE;
+}
+
+bool wxGetResource(const wxString& section, const wxString& entry, float *value, const wxString& file)
+{
+ char *s = NULL;
+ bool succ = wxGetResource(section, entry, (char **)&s, file);
+ if (succ)
+ {
+ *value = (float)strtod(s, NULL);
+ delete[] s;
+ return TRUE;
+ }
+ else return FALSE;
+}
+
+bool wxGetResource(const wxString& section, const wxString& entry, long *value, const wxString& file)
+{
+ char *s = NULL;
+ bool succ = wxGetResource(section, entry, (char **)&s, file);
+ if (succ)
+ {
+ *value = strtol(s, NULL, 10);
+ delete[] s;
+ return TRUE;
+ }
+ else return FALSE;
+}
+
+bool wxGetResource(const wxString& section, const wxString& entry, int *value, const wxString& file)
+{
+ char *s = NULL;
+ bool succ = wxGetResource(section, entry, (char **)&s, file);
+ if (succ)
+ {
+ *value = (int)strtol(s, NULL, 10);
+ delete[] s;
+ return TRUE;
+ }
+ else return FALSE;
+}
+#endif // wxUSE_RESOURCES
+
+int gs_wxBusyCursorCount = 0;
+extern wxCursor gMacCurrentCursor ;
+wxCursor gMacStoredActiveCursor ;
+
+// Set the cursor to the busy cursor for all windows
+void wxBeginBusyCursor(wxCursor *cursor)
+{
+ if (gs_wxBusyCursorCount++ == 0)
+ {
+ gMacStoredActiveCursor = gMacCurrentCursor ;
+ cursor->MacInstall() ;
+ }
+ //else: nothing to do, already set
+}
+
+// Restore cursor to normal
+void wxEndBusyCursor()
+{
+ wxCHECK_RET( gs_wxBusyCursorCount > 0,
+ wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") );
+
+ if (--gs_wxBusyCursorCount == 0)
+ {
+ gMacStoredActiveCursor.MacInstall() ;
+ gMacStoredActiveCursor = wxNullCursor ;
+ }
+}
+
+// TRUE if we're between the above two calls
+bool wxIsBusy()
+{
+ return (gs_wxBusyCursorCount > 0);
+}
+
+#endif // wxUSE_GUI
+
+#if wxUSE_BASE
+
+wxString wxMacFindFolder( short vol,
+ OSType folderType,
+ Boolean createFolder)
+{
+ short vRefNum ;
+ long dirID ;
+ wxString strDir ;
+
+ if ( FindFolder( vol, folderType, createFolder, &vRefNum, &dirID) == noErr)
+ {
+ FSSpec file ;
+ if ( FSMakeFSSpec( vRefNum , dirID , "\p" , &file ) == noErr )
+ {
+ strDir = wxMacFSSpec2MacFilename( &file ) + wxFILE_SEP_PATH ;
+ }
+ }
+ return strDir ;
+}
+
+#endif // wxUSE_BASE
+
+#if wxUSE_GUI
+
+// Check whether this window wants to process messages, e.g. Stop button
+// in long calculations.
+bool wxCheckForInterrupt(wxWindow *wnd)
+{
+ // TODO
+ return FALSE;
+}
+
+void wxGetMousePosition( int* x, int* y )
+{
+ Point pt ;
+
+ GetMouse( &pt ) ;
+ LocalToGlobal( &pt ) ;
+ *x = pt.h ;
+ *y = pt.v ;
+};
+
+// Return TRUE if we have a colour display
+bool wxColourDisplay()
+{
+ return TRUE;
+}
+
+// Returns depth of screen
+int wxDisplayDepth()
+{
+ Rect globRect ;
+ SetRect(&globRect, -32760, -32760, 32760, 32760);
+ GDHandle theMaxDevice;
+
+ int theDepth = 8;
+ theMaxDevice = GetMaxDevice(&globRect);
+ if (theMaxDevice != nil)
+ theDepth = (**(**theMaxDevice).gdPMap).pixelSize;
+
+ return theDepth ;
+}
+
+// Get size of display
+void wxDisplaySize(int *width, int *height)
+{
+ BitMap screenBits;
+ GetQDGlobalsScreenBits( &screenBits );
+
+ if (width != NULL) {
+ *width = screenBits.bounds.right - screenBits.bounds.left ;
+ }
+ if (height != NULL) {
+ *height = screenBits.bounds.bottom - screenBits.bounds.top ;
+ }
+}
+
+void wxDisplaySizeMM(int *width, int *height)
+{
+ wxDisplaySize(width, height);
+ // on mac 72 is fixed (at least now ;-)
+ float cvPt2Mm = 25.4 / 72;
+
+ if (width != NULL) {
+ *width = int( *width * cvPt2Mm );
+ }
+ if (height != NULL) {
+ *height = int( *height * cvPt2Mm );
+ }
+}
+
+void wxClientDisplayRect(int *x, int *y, int *width, int *height)
+{
+#if TARGET_CARBON
+ Rect r ;
+ GetAvailableWindowPositioningBounds( GetMainDevice() , &r ) ;
+ if ( x )
+ *x = r.left ;
+ if ( y )
+ *y = r.top ;
+ if ( width )
+ *width = r.right - r.left ;
+ if ( height )
+ *height = r.bottom - r.top ;
+#else
+ BitMap screenBits;
+ GetQDGlobalsScreenBits( &screenBits );
+
+ if (x) *x = 0;
+ if (y) *y = 0;
+
+ if (width != NULL) {
+ *width = screenBits.bounds.right - screenBits.bounds.left ;
+ }
+ if (height != NULL) {
+ *height = screenBits.bounds.bottom - screenBits.bounds.top ;
+ }
+
+ SInt16 mheight ;
+#if TARGET_CARBON
+ GetThemeMenuBarHeight( &mheight ) ;
+#else
+ mheight = LMGetMBarHeight() ;
+#endif
+ if (height != NULL) {
+ *height -= mheight ;
+ }
+ if (y)
+ *y = mheight ;
+#endif
+}
+
+wxWindow* wxFindWindowAtPoint(const wxPoint& pt)
+{
+ return wxGenericFindWindowAtPoint(pt);
+}
+
+#endif // wxUSE_GUI
+
+#if wxUSE_BASE
+
+wxString wxGetOsDescription()
+{
+#ifdef WXWIN_OS_DESCRIPTION
+ // use configure generated description if available
+ return wxString(wxT("MacOS (")) + wxT(WXWIN_OS_DESCRIPTION) + wxString(wxT(")"));
+#else
+ return wxT("MacOS") ; //TODO:define further
+#endif
+}
+
+#ifndef __DARWIN__
+wxChar *wxGetUserHome (const wxString& user)
+{
+ // TODO
+ return NULL;
+}
+
+bool wxGetDiskSpace(const wxString& path, wxLongLong *pTotal, wxLongLong *pFree)
+{
+ if ( path.empty() )
+ return FALSE;
+
+ wxString p = path ;
+ if (p[0u] == ':' ) {
+ p = wxGetCwd() + p ;
+ }
+
+ int pos = p.Find(':') ;
+ if ( pos != wxNOT_FOUND ) {
+ p = p.Mid(1,pos) ;
+ }
+
+ p = p + wxT(":") ;
+
+ Str255 volumeName ;
+ XVolumeParam pb ;
+
+ wxMacStringToPascal( p , volumeName ) ;
+ OSErr err = XGetVolumeInfoNoName( volumeName , 0 , &pb ) ;
+ if ( err == noErr ) {
+ if ( pTotal ) {
+ (*pTotal) = wxLongLong( pb.ioVTotalBytes ) ;
+ }
+ if ( pFree ) {
+ (*pFree) = wxLongLong( pb.ioVFreeBytes ) ;
+ }
+ }
+
+ return err == noErr ;
+}
+#endif // !__DARWIN__
+
+//---------------------------------------------------------------------------
+// wxMac Specific utility functions
+//---------------------------------------------------------------------------
+
+void wxMacStringToPascal( const wxString&from , StringPtr to )
+{
+ wxCharBuffer buf = from.mb_str( wxConvLocal ) ;
+ int len = strlen(buf) ;
+
+ if ( len > 255 )
+ len = 255 ;
+ to[0] = len ;
+ memcpy( (char*) &to[1] , buf , len ) ;
+}
+
+wxString wxMacMakeStringFromPascal( ConstStringPtr from )
+{
+ return wxString( (char*) &from[1] , wxConvLocal , from[0] ) ;
+}
+
+
+wxUint32 wxMacGetSystemEncFromFontEnc(wxFontEncoding encoding)
+{
+ TextEncodingBase enc = 0 ;
+ if ( encoding == wxFONTENCODING_DEFAULT )
+ {
+#if wxUSE_GUI
+ encoding = wxFont::GetDefaultEncoding() ;
+#else
+ encoding = wxLocale::GetSystemEncoding() ;
+#endif
+ }
+
+ switch( encoding)
+ {
+ case wxFONTENCODING_ISO8859_1 :
+ enc = kTextEncodingISOLatin1 ;
+ break ;
+ case wxFONTENCODING_ISO8859_2 :
+ enc = kTextEncodingISOLatin2;
+ break ;
+ case wxFONTENCODING_ISO8859_3 :
+ enc = kTextEncodingISOLatin3 ;
+ break ;
+ case wxFONTENCODING_ISO8859_4 :
+ enc = kTextEncodingISOLatin4;
+ break ;
+ case wxFONTENCODING_ISO8859_5 :
+ enc = kTextEncodingISOLatinCyrillic;
+ break ;
+ case wxFONTENCODING_ISO8859_6 :
+ enc = kTextEncodingISOLatinArabic;
+ break ;
+ case wxFONTENCODING_ISO8859_7 :
+ enc = kTextEncodingISOLatinGreek;
+ break ;
+ case wxFONTENCODING_ISO8859_8 :
+ enc = kTextEncodingISOLatinHebrew;
+ break ;
+ case wxFONTENCODING_ISO8859_9 :
+ enc = kTextEncodingISOLatin5;
+ break ;
+ case wxFONTENCODING_ISO8859_10 :
+ enc = kTextEncodingISOLatin6;
+ break ;
+ case wxFONTENCODING_ISO8859_13 :
+ enc = kTextEncodingISOLatin7;
+ break ;
+ case wxFONTENCODING_ISO8859_14 :
+ enc = kTextEncodingISOLatin8;
+ break ;
+ case wxFONTENCODING_ISO8859_15 :
+ enc = kTextEncodingISOLatin9;
+ break ;
+
+ case wxFONTENCODING_KOI8 :
+ enc = kTextEncodingKOI8_R;
+ break ;
+ case wxFONTENCODING_ALTERNATIVE : // MS-DOS CP866
+ enc = kTextEncodingDOSRussian;
+ break ;
+/*
+ case wxFONTENCODING_BULGARIAN :
+ enc = ;
+ break ;
+*/
+ case wxFONTENCODING_CP437 :
+ enc =kTextEncodingDOSLatinUS ;
+ break ;
+ case wxFONTENCODING_CP850 :
+ enc = kTextEncodingDOSLatin1;
+ break ;
+ case wxFONTENCODING_CP852 :
+ enc = kTextEncodingDOSLatin2;
+ break ;
+ case wxFONTENCODING_CP855 :
+ enc = kTextEncodingDOSCyrillic;
+ break ;
+ case wxFONTENCODING_CP866 :
+ enc =kTextEncodingDOSRussian ;
+ break ;
+ case wxFONTENCODING_CP874 :
+ enc = kTextEncodingDOSThai;
+ break ;
+ case wxFONTENCODING_CP932 :
+ enc = kTextEncodingDOSJapanese;
+ break ;
+ case wxFONTENCODING_CP936 :
+ enc =kTextEncodingDOSChineseSimplif ;
+ break ;
+ case wxFONTENCODING_CP949 :
+ enc = kTextEncodingDOSKorean;
+ break ;
+ case wxFONTENCODING_CP950 :
+ enc = kTextEncodingDOSChineseTrad;
+ break ;
+
+ case wxFONTENCODING_CP1250 :
+ enc = kTextEncodingWindowsLatin2;
+ break ;
+ case wxFONTENCODING_CP1251 :
+ enc =kTextEncodingWindowsCyrillic ;
+ break ;
+ case wxFONTENCODING_CP1252 :
+ enc =kTextEncodingWindowsLatin1 ;
+ break ;
+ case wxFONTENCODING_CP1253 :
+ enc = kTextEncodingWindowsGreek;
+ break ;
+ case wxFONTENCODING_CP1254 :
+ enc = kTextEncodingWindowsLatin5;
+ break ;
+ case wxFONTENCODING_CP1255 :
+ enc =kTextEncodingWindowsHebrew ;
+ break ;
+ case wxFONTENCODING_CP1256 :
+ enc =kTextEncodingWindowsArabic ;
+ break ;
+ case wxFONTENCODING_CP1257 :
+ enc = kTextEncodingWindowsBalticRim;
+ break ;
+
+ case wxFONTENCODING_UTF7 :
+ enc = CreateTextEncoding(kTextEncodingUnicodeDefault,0,kUnicodeUTF7Format) ;
+ break ;
+ case wxFONTENCODING_UTF8 :
+ enc = CreateTextEncoding(kTextEncodingUnicodeDefault,0,kUnicodeUTF8Format) ;
+ break ;
+ case wxFONTENCODING_EUC_JP :
+ enc = kTextEncodingEUC_JP;
+ break ;
+ case wxFONTENCODING_UTF16BE :
+ enc = CreateTextEncoding(kTextEncodingUnicodeDefault,0,kUnicode16BitFormat) ;
+ break ;
+ case wxFONTENCODING_UTF16LE :
+ enc = CreateTextEncoding(kTextEncodingUnicodeDefault,0,kUnicode16BitFormat) ;
+ break ;
+ case wxFONTENCODING_UTF32BE :
+ enc = CreateTextEncoding(kTextEncodingUnicodeDefault,0,kUnicode32BitFormat) ;
+ break ;
+ case wxFONTENCODING_UTF32LE :
+ enc = CreateTextEncoding(kTextEncodingUnicodeDefault,0,kUnicode32BitFormat) ;
+ break ;
+
+ case wxFONTENCODING_MACROMAN :
+ enc = kTextEncodingMacRoman ;
+ break ;
+ case wxFONTENCODING_MACJAPANESE :
+ enc = kTextEncodingMacJapanese ;
+ break ;
+ case wxFONTENCODING_MACCHINESETRAD :
+ enc = kTextEncodingMacChineseTrad ;
+ break ;
+ case wxFONTENCODING_MACKOREAN :
+ enc = kTextEncodingMacKorean ;
+ break ;
+ case wxFONTENCODING_MACARABIC :
+ enc = kTextEncodingMacArabic ;
+ break ;
+ case wxFONTENCODING_MACHEBREW :
+ enc = kTextEncodingMacHebrew ;
+ break ;
+ case wxFONTENCODING_MACGREEK :
+ enc = kTextEncodingMacGreek ;
+ break ;
+ case wxFONTENCODING_MACCYRILLIC :
+ enc = kTextEncodingMacCyrillic ;
+ break ;
+ case wxFONTENCODING_MACDEVANAGARI :
+ enc = kTextEncodingMacDevanagari ;
+ break ;
+ case wxFONTENCODING_MACGURMUKHI :
+ enc = kTextEncodingMacGurmukhi ;
+ break ;
+ case wxFONTENCODING_MACGUJARATI :
+ enc = kTextEncodingMacGujarati ;
+ break ;
+ case wxFONTENCODING_MACORIYA :
+ enc = kTextEncodingMacOriya ;
+ break ;
+ case wxFONTENCODING_MACBENGALI :
+ enc = kTextEncodingMacBengali ;
+ break ;
+ case wxFONTENCODING_MACTAMIL :
+ enc = kTextEncodingMacTamil ;
+ break ;
+ case wxFONTENCODING_MACTELUGU :
+ enc = kTextEncodingMacTelugu ;
+ break ;
+ case wxFONTENCODING_MACKANNADA :
+ enc = kTextEncodingMacKannada ;
+ break ;
+ case wxFONTENCODING_MACMALAJALAM :
+ enc = kTextEncodingMacMalayalam ;
+ break ;
+ case wxFONTENCODING_MACSINHALESE :
+ enc = kTextEncodingMacSinhalese ;
+ break ;
+ case wxFONTENCODING_MACBURMESE :
+ enc = kTextEncodingMacBurmese ;
+ break ;
+ case wxFONTENCODING_MACKHMER :
+ enc = kTextEncodingMacKhmer ;
+ break ;
+ case wxFONTENCODING_MACTHAI :
+ enc = kTextEncodingMacThai ;
+ break ;
+ case wxFONTENCODING_MACLAOTIAN :
+ enc = kTextEncodingMacLaotian ;
+ break ;
+ case wxFONTENCODING_MACGEORGIAN :
+ enc = kTextEncodingMacGeorgian ;
+ break ;
+ case wxFONTENCODING_MACARMENIAN :
+ enc = kTextEncodingMacArmenian ;
+ break ;
+ case wxFONTENCODING_MACCHINESESIMP :
+ enc = kTextEncodingMacChineseSimp ;
+ break ;
+ case wxFONTENCODING_MACTIBETAN :
+ enc = kTextEncodingMacTibetan ;
+ break ;
+ case wxFONTENCODING_MACMONGOLIAN :
+ enc = kTextEncodingMacMongolian ;
+ break ;
+ case wxFONTENCODING_MACETHIOPIC :
+ enc = kTextEncodingMacEthiopic ;
+ break ;
+ case wxFONTENCODING_MACCENTRALEUR :
+ enc = kTextEncodingMacCentralEurRoman ;
+ break ;
+ case wxFONTENCODING_MACVIATNAMESE :
+ enc = kTextEncodingMacVietnamese ;
+ break ;
+ case wxFONTENCODING_MACARABICEXT :
+ enc = kTextEncodingMacExtArabic ;
+ break ;
+ case wxFONTENCODING_MACSYMBOL :
+ enc = kTextEncodingMacSymbol ;
+ break ;
+ case wxFONTENCODING_MACDINGBATS :
+ enc = kTextEncodingMacDingbats ;
+ break ;
+ case wxFONTENCODING_MACTURKISH :
+ enc = kTextEncodingMacTurkish ;
+ break ;
+ case wxFONTENCODING_MACCROATIAN :
+ enc = kTextEncodingMacCroatian ;
+ break ;
+ case wxFONTENCODING_MACICELANDIC :
+ enc = kTextEncodingMacIcelandic ;
+ break ;
+ case wxFONTENCODING_MACROMANIAN :
+ enc = kTextEncodingMacRomanian ;
+ break ;
+ case wxFONTENCODING_MACCELTIC :
+ enc = kTextEncodingMacCeltic ;
+ break ;
+ case wxFONTENCODING_MACGAELIC :
+ enc = kTextEncodingMacGaelic ;
+ break ;
+ case wxFONTENCODING_MACKEYBOARD :
+ enc = kTextEncodingMacKeyboardGlyphs ;
+ break ;
+ default :
+ // to make gcc happy
+ break ;
+ } ;
+ return enc ;
+}
+
+wxFontEncoding wxMacGetFontEncFromSystemEnc(wxUint32 encoding)
+{
+ wxFontEncoding enc = wxFONTENCODING_DEFAULT ;
+
+ switch( encoding)
+ {
+ case kTextEncodingISOLatin1 :
+ enc = wxFONTENCODING_ISO8859_1 ;
+ break ;
+ case kTextEncodingISOLatin2 :
+ enc = wxFONTENCODING_ISO8859_2;
+ break ;
+ case kTextEncodingISOLatin3 :
+ enc = wxFONTENCODING_ISO8859_3 ;
+ break ;
+ case kTextEncodingISOLatin4 :
+ enc = wxFONTENCODING_ISO8859_4;
+ break ;
+ case kTextEncodingISOLatinCyrillic :
+ enc = wxFONTENCODING_ISO8859_5;
+ break ;
+ case kTextEncodingISOLatinArabic :
+ enc = wxFONTENCODING_ISO8859_6;
+ break ;
+ case kTextEncodingISOLatinGreek :
+ enc = wxFONTENCODING_ISO8859_7;
+ break ;
+ case kTextEncodingISOLatinHebrew :
+ enc = wxFONTENCODING_ISO8859_8;
+ break ;
+ case kTextEncodingISOLatin5 :
+ enc = wxFONTENCODING_ISO8859_9;
+ break ;
+ case kTextEncodingISOLatin6 :
+ enc = wxFONTENCODING_ISO8859_10;
+ break ;
+ case kTextEncodingISOLatin7 :
+ enc = wxFONTENCODING_ISO8859_13;
+ break ;
+ case kTextEncodingISOLatin8 :
+ enc = wxFONTENCODING_ISO8859_14;
+ break ;
+ case kTextEncodingISOLatin9 :
+ enc =wxFONTENCODING_ISO8859_15 ;
+ break ;
+
+ case kTextEncodingKOI8_R :
+ enc = wxFONTENCODING_KOI8;
+ break ;
+/*
+ case :
+ enc = wxFONTENCODING_BULGARIAN;
+ break ;
+*/
+ case kTextEncodingDOSLatinUS :
+ enc = wxFONTENCODING_CP437;
+ break ;
+ case kTextEncodingDOSLatin1 :
+ enc = wxFONTENCODING_CP850;
+ break ;
+ case kTextEncodingDOSLatin2 :
+ enc =wxFONTENCODING_CP852 ;
+ break ;
+ case kTextEncodingDOSCyrillic :
+ enc = wxFONTENCODING_CP855;
+ break ;
+ case kTextEncodingDOSRussian :
+ enc = wxFONTENCODING_CP866;
+ break ;
+ case kTextEncodingDOSThai :
+ enc =wxFONTENCODING_CP874 ;
+ break ;
+ case kTextEncodingDOSJapanese :
+ enc = wxFONTENCODING_CP932;
+ break ;
+ case kTextEncodingDOSChineseSimplif :
+ enc = wxFONTENCODING_CP936;
+ break ;
+ case kTextEncodingDOSKorean :
+ enc = wxFONTENCODING_CP949;
+ break ;
+ case kTextEncodingDOSChineseTrad :
+ enc = wxFONTENCODING_CP950;
+ break ;
+
+ case kTextEncodingWindowsLatin2 :
+ enc = wxFONTENCODING_CP1250;
+ break ;
+ case kTextEncodingWindowsCyrillic :
+ enc = wxFONTENCODING_CP1251;
+ break ;
+ case kTextEncodingWindowsLatin1 :
+ enc = wxFONTENCODING_CP1252;
+ break ;
+ case kTextEncodingWindowsGreek :
+ enc = wxFONTENCODING_CP1253;
+ break ;
+ case kTextEncodingWindowsLatin5 :
+ enc = wxFONTENCODING_CP1254;
+ break ;
+ case kTextEncodingWindowsHebrew :
+ enc = wxFONTENCODING_CP1255;
+ break ;
+ case kTextEncodingWindowsArabic :
+ enc = wxFONTENCODING_CP1256;
+ break ;
+ case kTextEncodingWindowsBalticRim :
+ enc =wxFONTENCODING_CP1257 ;
+ break ;
+ case kTextEncodingEUC_JP :
+ enc = wxFONTENCODING_EUC_JP;
+ break ;
+ /*
+ case wxFONTENCODING_UTF7 :
+ enc = CreateTextEncoding(kTextEncodingUnicodeDefault,0,kUnicodeUTF7Format) ;
+ break ;
+ case wxFONTENCODING_UTF8 :
+ enc = CreateTextEncoding(kTextEncodingUnicodeDefault,0,kUnicodeUTF8Format) ;
+ break ;
+ case wxFONTENCODING_UTF16BE :
+ enc = CreateTextEncoding(kTextEncodingUnicodeDefault,0,kUnicode16BitFormat) ;
+ break ;
+ case wxFONTENCODING_UTF16LE :
+ enc = CreateTextEncoding(kTextEncodingUnicodeDefault,0,kUnicode16BitFormat) ;
+ break ;
+ case wxFONTENCODING_UTF32BE :
+ enc = CreateTextEncoding(kTextEncodingUnicodeDefault,0,kUnicode32BitFormat) ;
+ break ;
+ case wxFONTENCODING_UTF32LE :
+ enc = CreateTextEncoding(kTextEncodingUnicodeDefault,0,kUnicode32BitFormat) ;
+ break ;
+ */
+ case kTextEncodingMacRoman :
+ enc = wxFONTENCODING_MACROMAN ;
+ break ;
+ case kTextEncodingMacJapanese :
+ enc = wxFONTENCODING_MACJAPANESE ;
+ break ;
+ case kTextEncodingMacChineseTrad :
+ enc = wxFONTENCODING_MACCHINESETRAD ;
+ break ;
+ case kTextEncodingMacKorean :
+ enc = wxFONTENCODING_MACKOREAN ;
+ break ;
+ case kTextEncodingMacArabic :
+ enc =wxFONTENCODING_MACARABIC ;
+ break ;
+ case kTextEncodingMacHebrew :
+ enc = wxFONTENCODING_MACHEBREW ;
+ break ;
+ case kTextEncodingMacGreek :
+ enc = wxFONTENCODING_MACGREEK ;
+ break ;
+ case kTextEncodingMacCyrillic :
+ enc = wxFONTENCODING_MACCYRILLIC ;
+ break ;
+ case kTextEncodingMacDevanagari :
+ enc = wxFONTENCODING_MACDEVANAGARI ;
+ break ;
+ case kTextEncodingMacGurmukhi :
+ enc = wxFONTENCODING_MACGURMUKHI ;
+ break ;
+ case kTextEncodingMacGujarati :
+ enc = wxFONTENCODING_MACGUJARATI ;
+ break ;
+ case kTextEncodingMacOriya :
+ enc =wxFONTENCODING_MACORIYA ;
+ break ;
+ case kTextEncodingMacBengali :
+ enc =wxFONTENCODING_MACBENGALI ;
+ break ;
+ case kTextEncodingMacTamil :
+ enc = wxFONTENCODING_MACTAMIL ;
+ break ;
+ case kTextEncodingMacTelugu :
+ enc = wxFONTENCODING_MACTELUGU ;
+ break ;
+ case kTextEncodingMacKannada :
+ enc = wxFONTENCODING_MACKANNADA ;
+ break ;
+ case kTextEncodingMacMalayalam :
+ enc = wxFONTENCODING_MACMALAJALAM ;
+ break ;
+ case kTextEncodingMacSinhalese :
+ enc = wxFONTENCODING_MACSINHALESE ;
+ break ;
+ case kTextEncodingMacBurmese :
+ enc = wxFONTENCODING_MACBURMESE ;
+ break ;
+ case kTextEncodingMacKhmer :
+ enc = wxFONTENCODING_MACKHMER ;
+ break ;
+ case kTextEncodingMacThai :
+ enc = wxFONTENCODING_MACTHAI ;
+ break ;
+ case kTextEncodingMacLaotian :
+ enc = wxFONTENCODING_MACLAOTIAN ;
+ break ;
+ case kTextEncodingMacGeorgian :
+ enc = wxFONTENCODING_MACGEORGIAN ;
+ break ;
+ case kTextEncodingMacArmenian :
+ enc = wxFONTENCODING_MACARMENIAN ;
+ break ;
+ case kTextEncodingMacChineseSimp :
+ enc = wxFONTENCODING_MACCHINESESIMP ;
+ break ;
+ case kTextEncodingMacTibetan :
+ enc = wxFONTENCODING_MACTIBETAN ;
+ break ;
+ case kTextEncodingMacMongolian :
+ enc = wxFONTENCODING_MACMONGOLIAN ;
+ break ;
+ case kTextEncodingMacEthiopic :
+ enc = wxFONTENCODING_MACETHIOPIC ;
+ break ;
+ case kTextEncodingMacCentralEurRoman:
+ enc = wxFONTENCODING_MACCENTRALEUR ;
+ break ;
+ case kTextEncodingMacVietnamese:
+ enc = wxFONTENCODING_MACVIATNAMESE ;
+ break ;
+ case kTextEncodingMacExtArabic :
+ enc = wxFONTENCODING_MACARABICEXT ;
+ break ;
+ case kTextEncodingMacSymbol :
+ enc = wxFONTENCODING_MACSYMBOL ;
+ break ;
+ case kTextEncodingMacDingbats :
+ enc = wxFONTENCODING_MACDINGBATS ;
+ break ;
+ case kTextEncodingMacTurkish :
+ enc = wxFONTENCODING_MACTURKISH ;
+ break ;
+ case kTextEncodingMacCroatian :
+ enc = wxFONTENCODING_MACCROATIAN ;
+ break ;
+ case kTextEncodingMacIcelandic :
+ enc = wxFONTENCODING_MACICELANDIC ;
+ break ;
+ case kTextEncodingMacRomanian :
+ enc = wxFONTENCODING_MACROMANIAN ;
+ break ;
+ case kTextEncodingMacCeltic :
+ enc = wxFONTENCODING_MACCELTIC ;
+ break ;
+ case kTextEncodingMacGaelic :
+ enc = wxFONTENCODING_MACGAELIC ;
+ break ;
+ case kTextEncodingMacKeyboardGlyphs :
+ enc = wxFONTENCODING_MACKEYBOARD ;
+ break ;
+ } ;
+ return enc ;
+}
+
+#endif // wxUSE_BASE
+
+#if wxUSE_GUI
+
+
+//
+// CFStringRefs (Carbon only)
+//
+
+#if TARGET_CARBON
+
+// converts this string into a carbon foundation string with optional pc 2 mac encoding
+void wxMacCFStringHolder::Assign( const wxString &st , wxFontEncoding encoding )
+{
+ Release() ;
+
+ wxString str = st ;
+ wxMacConvertNewlines13To10( &str ) ;
+#if wxUSE_UNICODE
+#if SIZEOF_WCHAR_T == 2
+ m_cfs = CFStringCreateWithCharacters( kCFAllocatorDefault,
+ (UniChar*)str.wc_str() , str.Len() );
+#else
+ wxMBConvUTF16BE converter ;
+ size_t unicharlen = converter.WC2MB( NULL , str.wc_str() , 0 ) ;
+ UniChar *unibuf = new UniChar[ unicharlen / sizeof(UniChar) + 1 ] ;
+ converter.WC2MB( (char*)unibuf , str.wc_str() , unicharlen ) ;
+ m_cfs = CFStringCreateWithCharacters( kCFAllocatorDefault ,
+ unibuf , unicharlen / sizeof(UniChar) ) ;
+ delete[] unibuf ;
+#endif
+#else // not wxUSE_UNICODE
+ m_cfs = CFStringCreateWithCString( kCFAllocatorSystemDefault , str.c_str() ,
+ wxMacGetSystemEncFromFontEnc( encoding ) ) ;
+#endif
+ m_release = true ;
+}
+
+wxString wxMacCFStringHolder::AsString(wxFontEncoding encoding)
+{
+ Size cflen = CFStringGetLength( m_cfs ) ;
+ size_t noChars ;
+ wxChar* buf = NULL ;
+
+#if wxUSE_UNICODE
+#if SIZEOF_WCHAR_T == 2
+ buf = new wxChar[ cflen + 1 ] ;
+ CFStringGetCharacters( m_cfs , CFRangeMake( 0 , cflen ) , (UniChar*) buf ) ;
+ noChars = cflen ;
+#else
+ UniChar* unibuf = new UniChar[ cflen + 1 ] ;
+ CFStringGetCharacters( m_cfs , CFRangeMake( 0 , cflen ) , (UniChar*) unibuf ) ;
+ unibuf[cflen] = 0 ;
+ wxMBConvUTF16BE converter ;
+ noChars = converter.MB2WC( NULL , (const char*)unibuf , 0 ) ;
+ buf = new wxChar[ noChars + 1 ] ;
+ converter.MB2WC( buf , (const char*)unibuf , noChars ) ;
+ delete[] unibuf ;
+#endif
+#else
+ CFIndex cStrLen ;
+ CFStringGetBytes( m_cfs , CFRangeMake(0, cflen) , wxMacGetSystemEncFromFontEnc( encoding ) ,
+ '?' , false , NULL , 0 , &cStrLen ) ;
+ buf = new wxChar[ cStrLen + 1 ] ;
+ CFStringGetBytes( m_cfs , CFRangeMake(0, cflen) , wxMacGetSystemEncFromFontEnc( encoding ) ,
+ '?' , false , (unsigned char*) buf , cStrLen , &cStrLen) ;
+ noChars = cStrLen ;
+#endif
+
+ buf[noChars] = 0 ;
+ wxMacConvertNewlines10To13( buf ) ;
+ wxString result(buf) ;
+ delete[] buf ;
+ return result ;
+}
+
+#endif //TARGET_CARBON
+
+void wxMacConvertNewlines13To10( char * data )
+{
+ char * buf = data ;
+ while( (buf=strchr(buf,0x0d)) != NULL )
+ {
+ *buf = 0x0a ;
+ buf++ ;
+ }
+}
+
+void wxMacConvertNewlines10To13( char * data )
+{
+ char * buf = data ;
+ while( (buf=strchr(buf,0x0a)) != NULL )
+ {
+ *buf = 0x0d ;
+ buf++ ;
+ }
+}
+
+void wxMacConvertNewlines13To10( wxString * data )
+{
+ size_t len = data->Length() ;
+
+ if ( len == 0 || wxStrchr(data->c_str(),0x0d)==NULL)
+ return ;
+
+ wxString temp(*data) ;
+ wxStringBuffer buf(*data,len ) ;
+ memcpy( buf , temp.c_str() , (len+1)*sizeof(wxChar) ) ;
+
+ wxMacConvertNewlines13To10( buf ) ;
+}
+
+void wxMacConvertNewlines10To13( wxString * data )
+{
+ size_t len = data->Length() ;
+
+ if ( data->Length() == 0 || wxStrchr(data->c_str(),0x0a)==NULL)
+ return ;
+
+ wxString temp(*data) ;
+ wxStringBuffer buf(*data,len ) ;
+ memcpy( buf , temp.c_str() , (len+1)*sizeof(wxChar) ) ;
+ wxMacConvertNewlines10To13( buf ) ;
+}
+
+
+#if wxUSE_UNICODE
+void wxMacConvertNewlines13To10( wxChar * data )
+{
+ wxChar * buf = data ;
+ while( (buf=wxStrchr(buf,0x0d)) != NULL )
+ {
+ *buf = 0x0a ;
+ buf++ ;
+ }
+}
+
+void wxMacConvertNewlines10To13( wxChar * data )
+{
+ wxChar * buf = data ;
+ while( (buf=wxStrchr(buf,0x0a)) != NULL )
+ {
+ *buf = 0x0d ;
+ buf++ ;
+ }
+}
+#endif
+
+// ----------------------------------------------------------------------------
+// debugging support
+// ----------------------------------------------------------------------------
+
+#if defined(__WXMAC__) && !defined(__DARWIN__) && defined(__MWERKS__) && (__MWERKS__ >= 0x2400)
+
+// MetroNub stuff doesn't seem to work in CodeWarrior 5.3 Carbon builds...
+
+#ifndef __MetroNubUtils__
+#include "MetroNubUtils.h"
+#endif
+
+#ifndef __GESTALT__
+#include <Gestalt.h>
+#endif
+
+#if TARGET_API_MAC_CARBON
+
+ #include <CodeFragments.h>
+
+ extern "C" long CallUniversalProc(UniversalProcPtr theProcPtr, ProcInfoType procInfo, ...);
+
+ ProcPtr gCallUniversalProc_Proc = NULL;
+
+#endif
+
+static MetroNubUserEntryBlock* gMetroNubEntry = NULL;
+
+static long fRunOnce = false;
+
+/* ---------------------------------------------------------------------------
+ IsMetroNubInstalled
+ --------------------------------------------------------------------------- */
+
+Boolean IsMetroNubInstalled()
+{
+ if (!fRunOnce)
+ {
+ long result, value;
+
+ fRunOnce = true;
+ gMetroNubEntry = NULL;
+
+ if (Gestalt(gestaltSystemVersion, &value) == noErr && value < 0x1000)
+ {
+ /* look for MetroNub's Gestalt selector */
+ if (Gestalt(kMetroNubUserSignature, &result) == noErr)
+ {
+
+ #if TARGET_API_MAC_CARBON
+ if (gCallUniversalProc_Proc == NULL)
+ {
+ CFragConnectionID connectionID;
+ Ptr mainAddress;
+ Str255 errorString;
+ ProcPtr symbolAddress;
+ OSErr err;
+ CFragSymbolClass symbolClass;
+
+ symbolAddress = NULL;
+ err = GetSharedLibrary("\pInterfaceLib", kPowerPCCFragArch, kFindCFrag,
+ &connectionID, &mainAddress, errorString);
+
+ if (err != noErr)
+ {
+ gCallUniversalProc_Proc = NULL;
+ goto end;
+ }
+
+ err = FindSymbol(connectionID, "\pCallUniversalProc",
+ (Ptr *) &gCallUniversalProc_Proc, &symbolClass);
+
+ if (err != noErr)
+ {
+ gCallUniversalProc_Proc = NULL;
+ goto end;
+ }
+ }
+ #endif
+
+ {
+ MetroNubUserEntryBlock* block = (MetroNubUserEntryBlock *)result;
+
+ /* make sure the version of the API is compatible */
+ if (block->apiLowVersion <= kMetroNubUserAPIVersion &&
+ kMetroNubUserAPIVersion <= block->apiHiVersion)
+ gMetroNubEntry = block; /* success! */
+ }
+
+ }
+ }
+ }
+
+end:
+
+#if TARGET_API_MAC_CARBON
+ return (gMetroNubEntry != NULL && gCallUniversalProc_Proc != NULL);
+#else
+ return (gMetroNubEntry != NULL);
+#endif
+}
+
+/* ---------------------------------------------------------------------------
+ IsMWDebuggerRunning [v1 API]
+ --------------------------------------------------------------------------- */
+
+Boolean IsMWDebuggerRunning()
+{
+ if (IsMetroNubInstalled())
+ return CallIsDebuggerRunningProc(gMetroNubEntry->isDebuggerRunning);
+ else
+ return false;
+}
+
+/* ---------------------------------------------------------------------------
+ AmIBeingMWDebugged [v1 API]
+ --------------------------------------------------------------------------- */
+
+Boolean AmIBeingMWDebugged()
+{
+ if (IsMetroNubInstalled())
+ return CallAmIBeingDebuggedProc(gMetroNubEntry->amIBeingDebugged);
+ else
+ return false;
+}
+
+extern bool WXDLLEXPORT wxIsDebuggerRunning()
+{
+ return IsMWDebuggerRunning() && AmIBeingMWDebugged();
+}
+
+#else
+
+extern bool WXDLLEXPORT wxIsDebuggerRunning()
+{
+ return false;
+}
+
+#endif // defined(__WXMAC__) && !defined(__DARWIN__) && (__MWERKS__ >= 0x2400)
+
+#endif // wxUSE_GUI
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: utilsexec.cpp
+// Purpose: Execution-related utilities
+// Author: Stefan Csomor
+// Modified by: David Elliott
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+//#pragma implementation
+#endif
+
+#include "wx/log.h"
+#include "wx/utils.h"
+#ifdef __DARWIN__
+#include "wx/unix/execute.h"
+#include <unistd.h>
+#include <sys/wait.h>
+extern "C" {
+#include <mach/mach.h>
+}
+#include <CoreFoundation/CFMachPort.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef __DARWIN__
+#define wxEXECUTE_WIN_MESSAGE 10000
+
+#include "wx/mac/private.h"
+
+/*
+Below FinderLaunch function comes from:
+http://developer.apple.com/technotes/tn/tn1002.html#fndrask
+*/
+ /* FinderLaunch converts a list of nTargets FSSpec records
+ pointed to by the targetList parameter and converts the
+ list to an Apple Event. It then sends that event to the
+ Finder. The array of FSSpec records pointed to by the
+ targetList parameter may contain references to files,
+ folders, or applications. The net effect of this command
+ is equivalent to the user selecting an icon in one of the
+ Finder's windows and then choosing the open command from
+ the Finder's file menu. */
+static OSErr FinderLaunch(long nTargets, FSSpec *targetList) {
+ OSErr err;
+ AppleEvent theAEvent, theReply;
+ AEAddressDesc fndrAddress;
+ AEDescList targetListDesc;
+ OSType fndrCreator;
+ Boolean wasChanged;
+ AliasHandle targetAlias;
+ long index;
+
+ /* set up locals */
+ AECreateDesc(typeNull, NULL, 0, &theAEvent);
+ AECreateDesc(typeNull, NULL, 0, &fndrAddress);
+ AECreateDesc(typeNull, NULL, 0, &theReply);
+ AECreateDesc(typeNull, NULL, 0, &targetListDesc);
+ targetAlias = NULL;
+ fndrCreator = 'MACS';
+
+ /* verify parameters */
+ if ((nTargets == 0) || (targetList == NULL)) {
+ err = paramErr;
+ goto bail;
+ }
+
+ /* create an open documents event targeting the
+ finder */
+ err = AECreateDesc(typeApplSignature, (Ptr) &fndrCreator,
+ sizeof(fndrCreator), &fndrAddress);
+ if (err != noErr) goto bail;
+ err = AECreateAppleEvent(kCoreEventClass, kAEOpenDocuments,
+ &fndrAddress, kAutoGenerateReturnID,
+ kAnyTransactionID, &theAEvent);
+ if (err != noErr) goto bail;
+
+ /* create the list of files to open */
+ err = AECreateList(NULL, 0, false, &targetListDesc);
+ if (err != noErr) goto bail;
+ for ( index=0; index < nTargets; index++) {
+ if (targetAlias == NULL)
+ err = NewAlias(NULL, (targetList + index),
+ &targetAlias);
+ else err = UpdateAlias(NULL, (targetList + index),
+ targetAlias, &wasChanged);
+ if (err != noErr) goto bail;
+ HLock((Handle) targetAlias);
+ err = AEPutPtr(&targetListDesc, (index + 1),
+ typeAlias, *targetAlias,
+ GetHandleSize((Handle) targetAlias));
+ HUnlock((Handle) targetAlias);
+ if (err != noErr) goto bail;
+ }
+
+ /* add the file list to the Apple Event */
+ err = AEPutParamDesc(&theAEvent, keyDirectObject,
+ &targetListDesc);
+ if (err != noErr) goto bail;
+
+ /* send the event to the Finder */
+ err = AESend(&theAEvent, &theReply, kAENoReply,
+ kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
+
+ /* clean up and leave */
+bail:
+ if (targetAlias != NULL) DisposeHandle((Handle) targetAlias);
+ AEDisposeDesc(&targetListDesc);
+ AEDisposeDesc(&theAEvent);
+ AEDisposeDesc(&fndrAddress);
+ AEDisposeDesc(&theReply);
+ return err;
+}
+
+long wxExecute(const wxString& command, int flags, wxProcess *WXUNUSED(handler))
+{
+ wxASSERT_MSG( flags == wxEXEC_ASYNC,
+ wxT("wxExecute: Only wxEXEC_ASYNC is supported") );
+
+ FSSpec fsSpec;
+ wxMacFilename2FSSpec(command, &fsSpec);
+
+ // 0 means execution failed. Returning non-zero is a PID, but not
+ // on Mac where PIDs are 64 bits and won't fit in a long, so we
+ // return a dummy value for now.
+ return ( FinderLaunch(1 /*one file*/, &fsSpec) == noErr ) ? -1 : 0;
+}
+
+#endif
+
+#ifdef __DARWIN__
+void wxMAC_MachPortEndProcessDetect(CFMachPortRef port, void *data)
+{
+ wxEndProcessData *proc_data = (wxEndProcessData*)data;
+ wxLogDebug(wxT("Wow.. this actually worked!"));
+ int status = 0;
+ int rc = waitpid(abs(proc_data->pid), &status, WNOHANG);
+ if(!rc)
+ {
+ wxLogDebug(wxT("Mach port was invalidated, but process hasn't terminated!"));
+ return;
+ }
+ if((rc != -1) && WIFEXITED(status))
+ proc_data->exitcode = WEXITSTATUS(status);
+ else
+ proc_data->exitcode = -1;
+ wxHandleProcessTermination(proc_data);
+}
+
+int wxAddProcessCallbackForPid(wxEndProcessData *proc_data, int pid)
+{
+ if(pid < 1)
+ return -1;
+ kern_return_t kernResult;
+ mach_port_t taskOfOurProcess;
+ mach_port_t machPortForProcess;
+ taskOfOurProcess = mach_task_self();
+ if(taskOfOurProcess == MACH_PORT_NULL)
+ {
+ wxLogDebug(wxT("No mach_task_self()"));
+ return -1;
+ }
+ wxLogDebug(wxT("pid=%d"),pid);
+ kernResult = task_for_pid(taskOfOurProcess,pid, &machPortForProcess);
+ if(kernResult != KERN_SUCCESS)
+ {
+ wxLogDebug(wxT("no task_for_pid()"));
+ // try seeing if it is already dead or something
+ // FIXME: a better method would be to call the callback function
+ // from idle time until the process terminates. Of course, how
+ // likely is it that it will take more than 0.1 seconds for the
+ // mach terminate event to make its way to the BSD subsystem?
+ usleep(100); // sleep for 0.1 seconds
+ wxMAC_MachPortEndProcessDetect(NULL, (void*)proc_data);
+ return -1;
+ }
+ CFMachPortContext termcb_contextinfo;
+ termcb_contextinfo.version = NULL;
+ termcb_contextinfo.info = (void*)proc_data;
+ termcb_contextinfo.retain = NULL;
+ termcb_contextinfo.release = NULL;
+ termcb_contextinfo.copyDescription = NULL;
+ CFMachPortRef CFMachPortForProcess;
+ Boolean ShouldFreePort;
+ CFMachPortForProcess = CFMachPortCreateWithPort(NULL, machPortForProcess, NULL, &termcb_contextinfo, &ShouldFreePort);
+ if(!CFMachPortForProcess)
+ {
+ wxLogDebug(wxT("No CFMachPortForProcess"));
+ mach_port_deallocate(taskOfOurProcess, machPortForProcess);
+ return -1;
+ }
+ if(ShouldFreePort)
+ {
+ kernResult = mach_port_deallocate(taskOfOurProcess, machPortForProcess);
+ if(kernResult!=KERN_SUCCESS)
+ {
+ wxLogDebug(wxT("Couldn't deallocate mach port"));
+ return -1;
+ }
+ }
+ CFMachPortSetInvalidationCallBack(CFMachPortForProcess, &wxMAC_MachPortEndProcessDetect);
+ CFRunLoopSourceRef runloopsource;
+ runloopsource = CFMachPortCreateRunLoopSource(NULL,CFMachPortForProcess, (CFIndex)0);
+ if(!runloopsource)
+ {
+ wxLogDebug(wxT("Couldn't create runloopsource"));
+ return -1;
+ }
+
+ CFRelease(CFMachPortForProcess);
+
+ CFRunLoopAddSource(CFRunLoopGetCurrent(),runloopsource,kCFRunLoopDefaultMode);
+ CFRelease(runloopsource);
+ wxLogDebug(wxT("Successfully added notification to the runloop"));
+ return 0;
+}
+#endif
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: windows.cpp
+// Purpose: wxWindowMac
+// Author: Stefan Csomor
+// Modified by:
+// Created: 1998-01-01
+// RCS-ID: $Id$
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "window.h"
+#endif
+
+#include "wx/setup.h"
+#include "wx/menu.h"
+#include "wx/window.h"
+#include "wx/dc.h"
+#include "wx/dcclient.h"
+#include "wx/utils.h"
+#include "wx/app.h"
+#include "wx/panel.h"
+#include "wx/layout.h"
+#include "wx/dialog.h"
+#include "wx/listbox.h"
+#include "wx/scrolbar.h"
+#include "wx/statbox.h"
+#include "wx/button.h"
+#include "wx/settings.h"
+#include "wx/msgdlg.h"
+#include "wx/frame.h"
+#include "wx/notebook.h"
+#include "wx/tabctrl.h"
+#include "wx/tooltip.h"
+#include "wx/statusbr.h"
+#include "wx/menuitem.h"
+#include "wx/spinctrl.h"
+#include "wx/log.h"
+#include "wx/geometry.h"
+
+#if wxUSE_CARET
+ #include "wx/caret.h"
+#endif // wxUSE_CARET
+
+#define wxWINDOW_HSCROLL 5998
+#define wxWINDOW_VSCROLL 5997
+#define MAC_SCROLLBAR_SIZE 16
+
+#include "wx/mac/uma.h"
+#ifndef __DARWIN__
+#include <Windows.h>
+#include <ToolUtils.h>
+#endif
+
+#if wxUSE_DRAG_AND_DROP
+#include "wx/dnd.h"
+#endif
+
+#include <string.h>
+
+extern wxList wxPendingDelete;
+wxWindowMac* gFocusWindow = NULL ;
+
+#ifdef __WXUNIVERSAL__
+ IMPLEMENT_ABSTRACT_CLASS(wxWindowMac, wxWindowBase)
+#else // __WXMAC__
+ IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
+#endif // __WXUNIVERSAL__/__WXMAC__
+
+#if !USE_SHARED_LIBRARY
+
+BEGIN_EVENT_TABLE(wxWindowMac, wxWindowBase)
+ EVT_NC_PAINT(wxWindowMac::OnNcPaint)
+ EVT_ERASE_BACKGROUND(wxWindowMac::OnEraseBackground)
+ EVT_SYS_COLOUR_CHANGED(wxWindowMac::OnSysColourChanged)
+ EVT_INIT_DIALOG(wxWindowMac::OnInitDialog)
+ EVT_SET_FOCUS(wxWindowMac::OnSetFocus)
+ EVT_MOUSE_EVENTS(wxWindowMac::OnMouseEvent)
+END_EVENT_TABLE()
+
+#endif
+
+#define wxMAC_DEBUG_REDRAW 0
+#ifndef wxMAC_DEBUG_REDRAW
+#define wxMAC_DEBUG_REDRAW 0
+#endif
+
+#define wxMAC_USE_THEME_BORDER 0
+
+
+// ===========================================================================
+// implementation
+// ===========================================================================
+
+
+// ----------------------------------------------------------------------------
+// constructors and such
+// ----------------------------------------------------------------------------
+
+void wxWindowMac::Init()
+{
+ m_backgroundTransparent = FALSE;
+
+ // as all windows are created with WS_VISIBLE style...
+ m_isShown = TRUE;
+
+ m_x = 0;
+ m_y = 0 ;
+ m_width = 0 ;
+ m_height = 0 ;
+
+ m_hScrollBar = NULL ;
+ m_vScrollBar = NULL ;
+}
+
+// Destructor
+wxWindowMac::~wxWindowMac()
+{
+ SendDestroyEvent();
+
+ // deleting a window while it is shown invalidates the region
+ if ( IsShown() ) {
+ wxWindowMac* iter = this ;
+ while( iter ) {
+ if ( iter->IsTopLevel() )
+ {
+ Refresh() ;
+ break ;
+ }
+ iter = iter->GetParent() ;
+
+ }
+ }
+
+ m_isBeingDeleted = TRUE;
+
+#ifndef __WXUNIVERSAL__
+ // VS: make sure there's no wxFrame with last focus set to us:
+ for ( wxWindow *win = GetParent(); win; win = win->GetParent() )
+ {
+ wxFrame *frame = wxDynamicCast(win, wxFrame);
+ if ( frame )
+ {
+ if ( frame->GetLastFocus() == this )
+ {
+ frame->SetLastFocus((wxWindow*)NULL);
+ }
+ break;
+ }
+ }
+#endif // __WXUNIVERSAL__
+
+ if ( s_lastMouseWindow == this )
+ {
+ s_lastMouseWindow = NULL ;
+ }
+
+ wxFrame* frame = wxDynamicCast( wxGetTopLevelParent( this ) , wxFrame ) ;
+ if ( frame )
+ {
+ if ( frame->GetLastFocus() == this )
+ frame->SetLastFocus( NULL ) ;
+ }
+
+ if ( gFocusWindow == this )
+ {
+ gFocusWindow = NULL ;
+ }
+
+ DestroyChildren();
+
+ // delete our drop target if we've got one
+#if wxUSE_DRAG_AND_DROP
+ if ( m_dropTarget != NULL )
+ {
+ delete m_dropTarget;
+ m_dropTarget = NULL;
+ }
+#endif // wxUSE_DRAG_AND_DROP
+}
+
+// Constructor
+bool wxWindowMac::Create(wxWindowMac *parent, wxWindowID id,
+ const wxPoint& pos,
+ const wxSize& size,
+ long style,
+ const wxString& name)
+{
+ wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindowMac without parent") );
+
+#if wxUSE_STATBOX
+ // wxGTK doesn't allow to create controls with static box as the parent so
+ // this will result in a crash when the program is ported to wxGTK - warn
+ // about it
+ //
+ // the correct solution is to create the controls as siblings of the
+ // static box
+ wxASSERT_MSG( !wxDynamicCast(parent, wxStaticBox),
+ _T("wxStaticBox can't be used as a window parent!") );
+#endif // wxUSE_STATBOX
+
+ if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
+ return FALSE;
+
+ parent->AddChild(this);
+
+ m_x = (int)pos.x;
+ m_y = (int)pos.y;
+ AdjustForParentClientOrigin(m_x, m_y, wxSIZE_USE_EXISTING);
+ m_width = WidthDefault( size.x );
+ m_height = HeightDefault( size.y ) ;
+#ifndef __WXUNIVERSAL__
+ // Don't give scrollbars to wxControls unless they ask for them
+ if ( (! IsKindOf(CLASSINFO(wxControl)) && ! IsKindOf(CLASSINFO(wxStatusBar))) ||
+ (IsKindOf(CLASSINFO(wxControl)) && ( style & wxHSCROLL || style & wxVSCROLL)))
+ {
+ MacCreateScrollBars( style ) ;
+ }
+#endif
+
+ wxWindowCreateEvent event(this);
+ GetEventHandler()->AddPendingEvent(event);
+
+ return TRUE;
+}
+
+void wxWindowMac::SetFocus()
+{
+ if ( gFocusWindow == this )
+ return ;
+
+ if ( AcceptsFocus() )
+ {
+ if (gFocusWindow )
+ {
+#if wxUSE_CARET
+ // Deal with caret
+ if ( gFocusWindow->m_caret )
+ {
+ gFocusWindow->m_caret->OnKillFocus();
+ }
+#endif // wxUSE_CARET
+#ifndef __WXUNIVERSAL__
+ wxControl* control = wxDynamicCast( gFocusWindow , wxControl ) ;
+ if ( control && control->GetMacControl() )
+ {
+ UMASetKeyboardFocus( (WindowRef) gFocusWindow->MacGetRootWindow() , (ControlHandle) control->GetMacControl() , kControlFocusNoPart ) ;
+ control->MacRedrawControl() ;
+ }
+#endif
+ // Without testing the window id, for some reason
+ // a kill focus event can still be sent to
+ // the control just being focussed.
+ int thisId = this->m_windowId;
+ int gFocusWindowId = gFocusWindow->m_windowId;
+ if (gFocusWindowId != thisId)
+ {
+ wxFocusEvent event(wxEVT_KILL_FOCUS, gFocusWindow->m_windowId);
+ event.SetEventObject(gFocusWindow);
+ gFocusWindow->GetEventHandler()->ProcessEvent(event) ;
+ }
+ }
+ gFocusWindow = this ;
+ {
+ #if wxUSE_CARET
+ // Deal with caret
+ if ( m_caret )
+ {
+ m_caret->OnSetFocus();
+ }
+ #endif // wxUSE_CARET
+ // panel wants to track the window which was the last to have focus in it
+ wxChildFocusEvent eventFocus(this);
+ GetEventHandler()->ProcessEvent(eventFocus);
+
+ #ifndef __WXUNIVERSAL__
+ wxControl* control = wxDynamicCast( gFocusWindow , wxControl ) ;
+ if ( control && control->GetMacControl() )
+ {
+ UMASetKeyboardFocus( (WindowRef) gFocusWindow->MacGetRootWindow() , (ControlHandle) control->GetMacControl() , kControlFocusNextPart ) ;
+ }
+ #endif
+ wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId);
+ event.SetEventObject(this);
+ GetEventHandler()->ProcessEvent(event) ;
+ }
+ }
+}
+
+bool wxWindowMac::Enable(bool enable)
+{
+ if ( !wxWindowBase::Enable(enable) )
+ return FALSE;
+
+ MacSuperEnabled( enable ) ;
+
+ return TRUE;
+}
+
+void wxWindowMac::DoCaptureMouse()
+{
+ wxTheApp->s_captureWindow = this ;
+}
+
+wxWindow* wxWindowBase::GetCapture()
+{
+ return wxTheApp->s_captureWindow ;
+}
+
+void wxWindowMac::DoReleaseMouse()
+{
+ wxTheApp->s_captureWindow = NULL ;
+}
+
+#if wxUSE_DRAG_AND_DROP
+
+void wxWindowMac::SetDropTarget(wxDropTarget *pDropTarget)
+{
+ if ( m_dropTarget != 0 ) {
+ delete m_dropTarget;
+ }
+
+ m_dropTarget = pDropTarget;
+ if ( m_dropTarget != 0 )
+ {
+ // TODO
+ }
+}
+
+#endif
+
+// Old style file-manager drag&drop
+void wxWindowMac::DragAcceptFiles(bool accept)
+{
+ // TODO
+}
+
+// Get total size
+void wxWindowMac::DoGetSize(int *x, int *y) const
+{
+ if(x) *x = m_width ;
+ if(y) *y = m_height ;
+}
+
+void wxWindowMac::DoGetPosition(int *x, int *y) const
+{
+ int xx,yy;
+
+ xx = m_x ;
+ yy = m_y ;
+ if ( !IsTopLevel() && GetParent())
+ {
+ wxPoint pt(GetParent()->GetClientAreaOrigin());
+ xx -= pt.x;
+ yy -= pt.y;
+ }
+ if(x) *x = xx;
+ if(y) *y = yy;
+}
+
+#if wxUSE_MENUS
+bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y)
+{
+ menu->SetInvokingWindow(this);
+ menu->UpdateUI();
+ ClientToScreen( &x , &y ) ;
+
+ menu->MacBeforeDisplay( true ) ;
+ long menuResult = ::PopUpMenuSelect((MenuHandle) menu->GetHMenu() ,y,x, 0) ;
+ if ( HiWord(menuResult) != 0 )
+ {
+ MenuCommand id ;
+ GetMenuItemCommandID( GetMenuHandle(HiWord(menuResult)) , LoWord(menuResult) , &id ) ;
+ wxMenuItem* item = NULL ;
+ wxMenu* realmenu ;
+ item = menu->FindItem(id, &realmenu) ;
+ if (item->IsCheckable())
+ {
+ item->Check( !item->IsChecked() ) ;
+ }
+ menu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ;
+ }
+ menu->MacAfterDisplay( true ) ;
+
+ menu->SetInvokingWindow(NULL);
+
+ return TRUE;
+}
+#endif
+
+void wxWindowMac::DoScreenToClient(int *x, int *y) const
+{
+ WindowRef window = (WindowRef) MacGetRootWindow() ;
+
+ Point localwhere = {0,0} ;
+
+ if(x) localwhere.h = * x ;
+ if(y) localwhere.v = * y ;
+
+ GrafPtr port ;
+ ::GetPort( &port ) ;
+ ::SetPort( UMAGetWindowPort( window ) ) ;
+ ::GlobalToLocal( &localwhere ) ;
+ ::SetPort( port ) ;
+
+ if(x) *x = localwhere.h ;
+ if(y) *y = localwhere.v ;
+
+ MacRootWindowToWindow( x , y ) ;
+ if ( x )
+ *x -= MacGetLeftBorderSize() ;
+ if ( y )
+ *y -= MacGetTopBorderSize() ;
+}
+
+void wxWindowMac::DoClientToScreen(int *x, int *y) const
+{
+ WindowRef window = (WindowRef) MacGetRootWindow() ;
+
+ if ( x )
+ *x += MacGetLeftBorderSize() ;
+ if ( y )
+ *y += MacGetTopBorderSize() ;
+
+ MacWindowToRootWindow( x , y ) ;
+
+ Point localwhere = { 0,0 };
+ if(x) localwhere.h = * x ;
+ if(y) localwhere.v = * y ;
+
+ GrafPtr port ;
+ ::GetPort( &port ) ;
+ ::SetPort( UMAGetWindowPort( window ) ) ;
+
+ ::LocalToGlobal( &localwhere ) ;
+ ::SetPort( port ) ;
+ if(x) *x = localwhere.h ;
+ if(y) *y = localwhere.v ;
+}
+
+void wxWindowMac::MacClientToRootWindow( int *x , int *y ) const
+{
+ wxPoint origin = GetClientAreaOrigin() ;
+ if(x) *x += origin.x ;
+ if(y) *y += origin.y ;
+
+ MacWindowToRootWindow( x , y ) ;
+}
+
+void wxWindowMac::MacRootWindowToClient( int *x , int *y ) const
+{
+ wxPoint origin = GetClientAreaOrigin() ;
+ MacRootWindowToWindow( x , y ) ;
+ if(x) *x -= origin.x ;
+ if(y) *y -= origin.y ;
+}
+
+void wxWindowMac::MacWindowToRootWindow( int *x , int *y ) const
+{
+ if ( !IsTopLevel() )
+ {
+ if(x) *x += m_x ;
+ if(y) *y += m_y ;
+ GetParent()->MacWindowToRootWindow( x , y ) ;
+ }
+}
+
+void wxWindowMac::MacRootWindowToWindow( int *x , int *y ) const
+{
+ if ( !IsTopLevel() )
+ {
+ if(x) *x -= m_x ;
+ if(y) *y -= m_y ;
+ GetParent()->MacRootWindowToWindow( x , y ) ;
+ }
+}
+
+bool wxWindowMac::SetCursor(const wxCursor& cursor)
+{
+ if (m_cursor == cursor)
+ return FALSE;
+
+ if (wxNullCursor == cursor)
+ {
+ if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR ) )
+ return FALSE ;
+ }
+ else
+ {
+ if ( ! wxWindowBase::SetCursor( cursor ) )
+ return FALSE ;
+ }
+
+ wxASSERT_MSG( m_cursor.Ok(),
+ wxT("cursor must be valid after call to the base version"));
+
+ Point pt ;
+ wxWindowMac *mouseWin ;
+ GetMouse( &pt ) ;
+
+ // Change the cursor NOW if we're within the correct window
+
+ if ( MacGetWindowFromPoint( wxPoint( pt.h , pt.v ) , &mouseWin ) )
+ {
+ if ( mouseWin == this && !wxIsBusy() )
+ {
+ m_cursor.MacInstall() ;
+ }
+ }
+
+ return TRUE ;
+}
+
+
+// Get size *available for subwindows* i.e. excluding menu bar etc.
+void wxWindowMac::DoGetClientSize(int *x, int *y) const
+{
+ int ww, hh;
+ ww = m_width ;
+ hh = m_height ;
+
+ ww -= MacGetLeftBorderSize( ) + MacGetRightBorderSize( ) ;
+ hh -= MacGetTopBorderSize( ) + MacGetBottomBorderSize( );
+
+ if ( (m_vScrollBar && m_vScrollBar->IsShown()) || (m_hScrollBar && m_hScrollBar->IsShown()) )
+ {
+ int x1 = 0 ;
+ int y1 = 0 ;
+ int w = m_width ;
+ int h = m_height ;
+
+ MacClientToRootWindow( &x1 , &y1 ) ;
+ MacClientToRootWindow( &w , &h ) ;
+
+ wxWindowMac *iter = (wxWindowMac*)this ;
+
+ int totW = 10000 , totH = 10000;
+ while( iter )
+ {
+ if ( iter->IsTopLevel() )
+ {
+ totW = iter->m_width ;
+ totH = iter->m_height ;
+ break ;
+ }
+
+ iter = iter->GetParent() ;
+ }
+
+ if (m_hScrollBar && m_hScrollBar->IsShown() )
+ {
+ hh -= MAC_SCROLLBAR_SIZE;
+ if ( h-y1 >= totH )
+ {
+ hh += 1 ;
+ }
+ }
+ if (m_vScrollBar && m_vScrollBar->IsShown() )
+ {
+ ww -= MAC_SCROLLBAR_SIZE;
+ if ( w-x1 >= totW )
+ {
+ ww += 1 ;
+ }
+ }
+ }
+ if(x) *x = ww;
+ if(y) *y = hh;
+}
+
+
+// ----------------------------------------------------------------------------
+// tooltips
+// ----------------------------------------------------------------------------
+
+#if wxUSE_TOOLTIPS
+
+void wxWindowMac::DoSetToolTip(wxToolTip *tooltip)
+{
+ wxWindowBase::DoSetToolTip(tooltip);
+
+ if ( m_tooltip )
+ m_tooltip->SetWindow(this);
+}
+
+#endif // wxUSE_TOOLTIPS
+
+void wxWindowMac::DoMoveWindow(int x, int y, int width, int height)
+{
+ int former_x = m_x ;
+ int former_y = m_y ;
+ int former_w = m_width ;
+ int former_h = m_height ;
+
+ int actualWidth = width;
+ int actualHeight = height;
+ int actualX = x;
+ int actualY = y;
+
+ if ((m_minWidth != -1) && (actualWidth < m_minWidth))
+ actualWidth = m_minWidth;
+ if ((m_minHeight != -1) && (actualHeight < m_minHeight))
+ actualHeight = m_minHeight;
+ if ((m_maxWidth != -1) && (actualWidth > m_maxWidth))
+ actualWidth = m_maxWidth;
+ if ((m_maxHeight != -1) && (actualHeight > m_maxHeight))
+ actualHeight = m_maxHeight;
+
+ bool doMove = false ;
+ bool doResize = false ;
+
+ if ( actualX != former_x || actualY != former_y )
+ {
+ doMove = true ;
+ }
+ if ( actualWidth != former_w || actualHeight != former_h )
+ {
+ doResize = true ;
+ }
+
+ if ( doMove || doResize )
+ {
+ // erase former position
+
+ bool partialRepaint = false ;
+
+ if ( !HasFlag(wxFULL_REPAINT_ON_RESIZE) )
+ {
+ wxPoint oldPos( m_x , m_y ) ;
+ wxPoint newPos( actualX , actualY ) ;
+ MacWindowToRootWindow( &oldPos.x , &oldPos.y ) ;
+ MacWindowToRootWindow( &newPos.x , &newPos.y ) ;
+ if ( oldPos == newPos )
+ {
+ partialRepaint = true ;
+ RgnHandle oldRgn,newRgn,diffRgn ;
+ oldRgn = NewRgn() ;
+ newRgn = NewRgn() ;
+ diffRgn = NewRgn() ;
+
+ // invalidate the differences between the old and the new area
+
+ SetRectRgn(oldRgn , oldPos.x , oldPos.y , oldPos.x + m_width , oldPos.y + m_height ) ;
+ SetRectRgn(newRgn , newPos.x , newPos.y , newPos.x + actualWidth , newPos.y + actualHeight ) ;
+ DiffRgn( newRgn , oldRgn , diffRgn ) ;
+ InvalWindowRgn( (WindowRef) MacGetRootWindow() , diffRgn ) ;
+ DiffRgn( oldRgn , newRgn , diffRgn ) ;
+ InvalWindowRgn( (WindowRef) MacGetRootWindow() , diffRgn ) ;
+
+ // we also must invalidate the border areas, someone might optimize this one day to invalidate only the really
+ // changing pixels...
+
+ if ( MacGetLeftBorderSize() != 0 || MacGetRightBorderSize() != 0 ||
+ MacGetTopBorderSize() != 0 || MacGetBottomBorderSize() != 0 )
+ {
+ RgnHandle innerOldRgn, innerNewRgn ;
+ innerOldRgn = NewRgn() ;
+ innerNewRgn = NewRgn() ;
+
+ SetRectRgn(innerOldRgn , oldPos.x + MacGetLeftBorderSize() , oldPos.y + MacGetTopBorderSize() ,
+ oldPos.x + m_width - MacGetRightBorderSize() , oldPos.y + m_height - MacGetBottomBorderSize() ) ;
+ DiffRgn( oldRgn , innerOldRgn , diffRgn ) ;
+ InvalWindowRgn( (WindowRef) MacGetRootWindow() , diffRgn ) ;
+
+ SetRectRgn(innerNewRgn , newPos.x + MacGetLeftBorderSize() , newPos.y + MacGetTopBorderSize() ,
+ newPos.x + actualWidth - MacGetRightBorderSize() , newPos.y + actualHeight - MacGetBottomBorderSize() ) ;
+ DiffRgn( newRgn , innerNewRgn , diffRgn ) ;
+ InvalWindowRgn( (WindowRef) MacGetRootWindow() , diffRgn ) ;
+
+ DisposeRgn( innerOldRgn ) ;
+ DisposeRgn( innerNewRgn ) ;
+ }
+
+ DisposeRgn(oldRgn) ;
+ DisposeRgn(newRgn) ;
+ DisposeRgn(diffRgn) ;
+ }
+ }
+
+ if ( !partialRepaint )
+ Refresh() ;
+
+ m_x = actualX ;
+ m_y = actualY ;
+ m_width = actualWidth ;
+ m_height = actualHeight ;
+
+ // update any low-level frame-relative positions
+
+ MacUpdateDimensions() ;
+ // erase new position
+
+ if ( !partialRepaint )
+ Refresh() ;
+ if ( doMove )
+ wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
+
+ MacRepositionScrollBars() ;
+ if ( doMove )
+ {
+ wxPoint point(m_x, m_y);
+ wxMoveEvent event(point, m_windowId);
+ event.SetEventObject(this);
+ GetEventHandler()->ProcessEvent(event) ;
+ }
+ if ( doResize )
+ {
+ MacRepositionScrollBars() ;
+ wxSize size(m_width, m_height);
+ wxSizeEvent event(size, m_windowId);
+ event.SetEventObject(this);
+ GetEventHandler()->ProcessEvent(event);
+ }
+ }
+
+}
+
+// set the size of the window: if the dimensions are positive, just use them,
+// but if any of them is equal to -1, it means that we must find the value for
+// it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in
+// which case -1 is a valid value for x and y)
+//
+// If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate
+// the width/height to best suit our contents, otherwise we reuse the current
+// width/height
+void wxWindowMac::DoSetSize(int x, int y, int width, int height, int sizeFlags)
+{
+ // get the current size and position...
+ int currentX, currentY;
+ GetPosition(¤tX, ¤tY);
+
+ int currentW,currentH;
+ GetSize(¤tW, ¤tH);
+
+ // ... and don't do anything (avoiding flicker) if it's already ok
+ if ( x == currentX && y == currentY &&
+ width == currentW && height == currentH )
+ {
+ MacRepositionScrollBars() ; // we might have a real position shift
+ return;
+ }
+
+ if ( x == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
+ x = currentX;
+ if ( y == -1 && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
+ y = currentY;
+
+ AdjustForParentClientOrigin(x, y, sizeFlags);
+
+ wxSize size(-1, -1);
+ if ( width == -1 )
+ {
+ if ( sizeFlags & wxSIZE_AUTO_WIDTH )
+ {
+ size = DoGetBestSize();
+ width = size.x;
+ }
+ else
+ {
+ // just take the current one
+ width = currentW;
+ }
+ }
+
+ if ( height == -1 )
+ {
+ if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
+ {
+ if ( size.x == -1 )
+ {
+ size = DoGetBestSize();
+ }
+ //else: already called DoGetBestSize() above
+
+ height = size.y;
+ }
+ else
+ {
+ // just take the current one
+ height = currentH;
+ }
+ }
+
+ DoMoveWindow(x, y, width, height);
+
+}
+// For implementation purposes - sometimes decorations make the client area
+// smaller
+
+wxPoint wxWindowMac::GetClientAreaOrigin() const
+{
+ return wxPoint(MacGetLeftBorderSize( ) , MacGetTopBorderSize( ) );
+}
+
+void wxWindowMac::SetTitle(const wxString& title)
+{
+ m_label = title ;
+}
+
+wxString wxWindowMac::GetTitle() const
+{
+ return m_label ;
+}
+
+bool wxWindowMac::Show(bool show)
+{
+ if ( !wxWindowBase::Show(show) )
+ return FALSE;
+
+ MacSuperShown( show ) ;
+ Refresh() ;
+
+ return TRUE;
+}
+
+void wxWindowMac::MacSuperShown( bool show )
+{
+ wxWindowListNode *node = GetChildren().GetFirst();
+ while ( node )
+ {
+ wxWindowMac *child = node->GetData();
+ if ( child->m_isShown )
+ child->MacSuperShown( show ) ;
+ node = node->GetNext();
+ }
+}
+
+void wxWindowMac::MacSuperEnabled( bool enabled )
+{
+ if ( !IsTopLevel() )
+ {
+ // to be absolutely correct we'd have to invalidate (with eraseBkground
+ // because unter MacOSX the frames are drawn with an addXXX mode)
+ // the borders area
+ }
+ wxWindowListNode *node = GetChildren().GetFirst();
+ while ( node )
+ {
+ wxWindowMac *child = (wxWindowMac *)node->GetData();
+ if ( child->m_isShown )
+ child->MacSuperEnabled( enabled ) ;
+ node = node->GetNext();
+ }
+}
+
+bool wxWindowMac::MacIsReallyShown() const
+{
+ if ( m_isShown && (m_parent != NULL && !IsTopLevel() ) ) {
+ return m_parent->MacIsReallyShown();
+ }
+ return m_isShown;
+/*
+ bool status = m_isShown ;
+ wxWindowMac * win = this ;
+ while ( status && win->m_parent != NULL )
+ {
+ win = win->m_parent ;
+ status = win->m_isShown ;
+ }
+ return status ;
+*/
+}
+
+int wxWindowMac::GetCharHeight() const
+{
+ wxClientDC dc ( (wxWindowMac*)this ) ;
+ return dc.GetCharHeight() ;
+}
+
+int wxWindowMac::GetCharWidth() const
+{
+ wxClientDC dc ( (wxWindowMac*)this ) ;
+ return dc.GetCharWidth() ;
+}
+
+void wxWindowMac::GetTextExtent(const wxString& string, int *x, int *y,
+ int *descent, int *externalLeading, const wxFont *theFont ) const
+{
+ const wxFont *fontToUse = theFont;
+ if ( !fontToUse )
+ fontToUse = &m_font;
+
+ wxClientDC dc( (wxWindowMac*) this ) ;
+ long lx,ly,ld,le ;
+ dc.GetTextExtent( string , &lx , &ly , &ld, &le, (wxFont *)fontToUse ) ;
+ if ( externalLeading )
+ *externalLeading = le ;
+ if ( descent )
+ *descent = ld ;
+ if ( x )
+ *x = lx ;
+ if ( y )
+ *y = ly ;
+}
+
+/*
+ * Rect is given in client coordinates, for further reading, read wxTopLevelWindowMac::InvalidateRect
+ * we always intersect with the entire window, not only with the client area
+ */
+
+void wxWindowMac::Refresh(bool eraseBack, const wxRect *rect)
+{
+ if ( MacGetTopLevelWindow() == NULL )
+ return ;
+
+ if ( !MacIsReallyShown() )
+ return ;
+
+ wxPoint client = GetClientAreaOrigin();
+ int x1 = -client.x;
+ int y1 = -client.y;
+ int x2 = m_width - client.x;
+ int y2 = m_height - client.y;
+
+ if (IsKindOf( CLASSINFO(wxButton)))
+ {
+ // buttons have an "aura"
+ y1 -= 5;
+ x1 -= 5;
+ y2 += 5;
+ x2 += 5;
+ }
+
+ Rect clientrect = { y1, x1, y2, x2 };
+
+ if ( rect )
+ {
+ Rect r = { rect->y , rect->x , rect->y + rect->height , rect->x + rect->width } ;
+ SectRect( &clientrect , &r , &clientrect ) ;
+ }
+
+ if ( !EmptyRect( &clientrect ) )
+ {
+ int top = 0 , left = 0 ;
+
+ MacClientToRootWindow( &left , &top ) ;
+ OffsetRect( &clientrect , left , top ) ;
+
+ MacGetTopLevelWindow()->MacInvalidate( &clientrect , eraseBack ) ;
+ }
+}
+
+wxWindowMac *wxGetActiveWindow()
+{
+ // actually this is a windows-only concept
+ return NULL;
+}
+
+// Coordinates relative to the window
+void wxWindowMac::WarpPointer (int x_pos, int y_pos)
+{
+ // We really don't move the mouse programmatically under Mac.
+}
+
+const wxBrush& wxWindowMac::MacGetBackgroundBrush()
+{
+ if ( m_backgroundColour == wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE) )
+ {
+ m_macBackgroundBrush.SetMacTheme( kThemeBrushDocumentWindowBackground ) ;
+ }
+ else if ( m_backgroundColour == wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE ) )
+ {
+ // on mac we have the difficult situation, that 3dface gray can be different colours, depending whether
+ // it is on a notebook panel or not, in order to take care of that we walk up the hierarchy until we have
+ // either a non gray background color or a non control window
+
+ WindowRef window = (WindowRef) MacGetRootWindow() ;
+
+ wxWindowMac* parent = GetParent() ;
+ while( parent )
+ {
+ if ( parent->MacGetRootWindow() != window )
+ {
+ // we are in a different window on the mac system
+ parent = NULL ;
+ break ;
+ }
+
+ {
+ if ( parent->m_backgroundColour != wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE )
+ && parent->m_backgroundColour != wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE) )
+ {
+ // if we have any other colours in the hierarchy
+ m_macBackgroundBrush.SetColour( parent->m_backgroundColour ) ;
+ break ;
+ }
+ // if we have the normal colours in the hierarchy but another control etc. -> use it's background
+ if ( parent->IsKindOf( CLASSINFO( wxNotebook ) ) || parent->IsKindOf( CLASSINFO( wxTabCtrl ) ))
+ {
+ Rect extent = { 0 , 0 , 0 , 0 } ;
+ int x , y ;
+ x = y = 0 ;
+ wxSize size = parent->GetSize() ;
+ parent->MacClientToRootWindow( &x , &y ) ;
+ extent.left = x ;
+ extent.top = y ;
+ extent.top-- ;
+ extent.right = x + size.x ;
+ extent.bottom = y + size.y ;
+ m_macBackgroundBrush.SetMacThemeBackground( kThemeBackgroundTabPane , (WXRECTPTR) &extent ) ; // todo eventually change for inactive
+ break ;
+ }
+ }
+ parent = parent->GetParent() ;
+ }
+ if ( !parent )
+ {
+ m_macBackgroundBrush.SetMacTheme( kThemeBrushDialogBackgroundActive ) ; // todo eventually change for inactive
+ }
+ }
+ else
+ {
+ m_macBackgroundBrush.SetColour( m_backgroundColour ) ;
+ }
+
+ return m_macBackgroundBrush ;
+}
+
+void wxWindowMac::OnEraseBackground(wxEraseEvent& event)
+{
+ event.GetDC()->Clear() ;
+}
+
+void wxWindowMac::OnNcPaint( wxNcPaintEvent& event )
+{
+ wxWindowDC dc(this) ;
+ wxMacPortSetter helper(&dc) ;
+
+ MacPaintBorders( dc.m_macLocalOrigin.x , dc.m_macLocalOrigin.y) ;
+}
+
+int wxWindowMac::GetScrollPos(int orient) const
+{
+ if ( orient == wxHORIZONTAL )
+ {
+ if ( m_hScrollBar )
+ return m_hScrollBar->GetThumbPosition() ;
+ }
+ else
+ {
+ if ( m_vScrollBar )
+ return m_vScrollBar->GetThumbPosition() ;
+ }
+ return 0;
+}
+
+// This now returns the whole range, not just the number
+// of positions that we can scroll.
+int wxWindowMac::GetScrollRange(int orient) const
+{
+ if ( orient == wxHORIZONTAL )
+ {
+ if ( m_hScrollBar )
+ return m_hScrollBar->GetRange() ;
+ }
+ else
+ {
+ if ( m_vScrollBar )
+ return m_vScrollBar->GetRange() ;
+ }
+ return 0;
+}
+
+int wxWindowMac::GetScrollThumb(int orient) const
+{
+ if ( orient == wxHORIZONTAL )
+ {
+ if ( m_hScrollBar )
+ return m_hScrollBar->GetThumbSize() ;
+ }
+ else
+ {
+ if ( m_vScrollBar )
+ return m_vScrollBar->GetThumbSize() ;
+ }
+ return 0;
+}
+
+void wxWindowMac::SetScrollPos(int orient, int pos, bool refresh)
+{
+ if ( orient == wxHORIZONTAL )
+ {
+ if ( m_hScrollBar )
+ m_hScrollBar->SetThumbPosition( pos ) ;
+ }
+ else
+ {
+ if ( m_vScrollBar )
+ m_vScrollBar->SetThumbPosition( pos ) ;
+ }
+}
+
+void wxWindowMac::MacPaintBorders( int left , int top )
+{
+ if( IsTopLevel() )
+ return ;
+
+ int major,minor;
+ wxGetOsVersion( &major, &minor );
+
+ RGBColor white = { 0xFFFF, 0xFFFF , 0xFFFF } ;
+ RGBColor face = { 0xDDDD, 0xDDDD , 0xDDDD } ;
+
+ RGBColor darkShadow = { 0x0000, 0x0000 , 0x0000 } ;
+ RGBColor lightShadow = { 0x4444, 0x4444 , 0x4444 } ;
+ // OS X has lighter border edges than classic:
+ if (major >= 10)
+ {
+ darkShadow.red = 0x8E8E;
+ darkShadow.green = 0x8E8E;
+ darkShadow.blue = 0x8E8E;
+ lightShadow.red = 0xBDBD;
+ lightShadow.green = 0xBDBD;
+ lightShadow.blue = 0xBDBD;
+ }
+
+ PenNormal() ;
+
+ if (HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) )
+ {
+#if wxMAC_USE_THEME_BORDER
+ Rect rect = { top , left , m_height + top , m_width + left } ;
+ SInt32 border = 0 ;
+ /*
+ GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ;
+ InsetRect( &rect , border , border );
+ DrawThemeListBoxFrame(&rect,IsEnabled() ? kThemeStateActive : kThemeStateInactive) ;
+ */
+
+ DrawThemePrimaryGroup(&rect ,IsEnabled() ? kThemeStateActive : kThemeStateInactive) ;
+#else
+ bool sunken = HasFlag( wxSUNKEN_BORDER ) ;
+ RGBForeColor( &face );
+ MoveTo( left + 0 , top + m_height - 2 );
+ LineTo( left + 0 , top + 0 );
+ LineTo( left + m_width - 2 , top + 0 );
+
+ MoveTo( left + 2 , top + m_height - 3 );
+ LineTo( left + m_width - 3 , top + m_height - 3 );
+ LineTo( left + m_width - 3 , top + 2 );
+
+ RGBForeColor( sunken ? &face : &darkShadow );
+ MoveTo( left + 0 , top + m_height - 1 );
+ LineTo( left + m_width - 1 , top + m_height - 1 );
+ LineTo( left + m_width - 1 , top + 0 );
+
+ RGBForeColor( sunken ? &lightShadow : &white );
+ MoveTo( left + 1 , top + m_height - 3 );
+ LineTo( left + 1, top + 1 );
+ LineTo( left + m_width - 3 , top + 1 );
+
+ RGBForeColor( sunken ? &white : &lightShadow );
+ MoveTo( left + 1 , top + m_height - 2 );
+ LineTo( left + m_width - 2 , top + m_height - 2 );
+ LineTo( left + m_width - 2 , top + 1 );
+
+ RGBForeColor( sunken ? &darkShadow : &face );
+ MoveTo( left + 2 , top + m_height - 4 );
+ LineTo( left + 2 , top + 2 );
+ LineTo( left + m_width - 4 , top + 2 );
+#endif
+ }
+ else if (HasFlag(wxSIMPLE_BORDER))
+ {
+ Rect rect = { top , left , m_height + top , m_width + left } ;
+ RGBForeColor( &darkShadow ) ;
+ FrameRect( &rect ) ;
+ }
+}
+
+void wxWindowMac::RemoveChild( wxWindowBase *child )
+{
+ if ( child == m_hScrollBar )
+ m_hScrollBar = NULL ;
+ if ( child == m_vScrollBar )
+ m_vScrollBar = NULL ;
+
+ wxWindowBase::RemoveChild( child ) ;
+}
+
+// New function that will replace some of the above.
+void wxWindowMac::SetScrollbar(int orient, int pos, int thumbVisible,
+ int range, bool refresh)
+{
+ if ( orient == wxHORIZONTAL )
+ {
+ if ( m_hScrollBar )
+ {
+ if ( range == 0 || thumbVisible >= range )
+ {
+ if ( m_hScrollBar->IsShown() )
+ m_hScrollBar->Show(false) ;
+ }
+ else
+ {
+ if ( !m_hScrollBar->IsShown() )
+ m_hScrollBar->Show(true) ;
+ m_hScrollBar->SetScrollbar( pos , thumbVisible , range , thumbVisible , refresh ) ;
+ }
+ }
+ }
+ else
+ {
+ if ( m_vScrollBar )
+ {
+ if ( range == 0 || thumbVisible >= range )
+ {
+ if ( m_vScrollBar->IsShown() )
+ m_vScrollBar->Show(false) ;
+ }
+ else
+ {
+ if ( !m_vScrollBar->IsShown() )
+ m_vScrollBar->Show(true) ;
+ m_vScrollBar->SetScrollbar( pos , thumbVisible , range , thumbVisible , refresh ) ;
+ }
+ }
+ }
+ MacRepositionScrollBars() ;
+}
+
+// Does a physical scroll
+void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect)
+{
+ if( dx == 0 && dy ==0 )
+ return ;
+
+
+ {
+ wxClientDC dc(this) ;
+ wxMacPortSetter helper(&dc) ;
+
+ int width , height ;
+ GetClientSize( &width , &height ) ;
+
+ Rect scrollrect = { dc.YLOG2DEVMAC(0) , dc.XLOG2DEVMAC(0) , dc.YLOG2DEVMAC(height) , dc.XLOG2DEVMAC(width) } ;
+ RgnHandle updateRgn = NewRgn() ;
+ ClipRect( &scrollrect ) ;
+ if ( rect )
+ {
+ Rect r = { dc.YLOG2DEVMAC(rect->y) , dc.XLOG2DEVMAC(rect->x) , dc.YLOG2DEVMAC(rect->y + rect->height) ,
+ dc.XLOG2DEVMAC(rect->x + rect->width) } ;
+ SectRect( &scrollrect , &r , &scrollrect ) ;
+ }
+ ScrollRect( &scrollrect , dx , dy , updateRgn ) ;
+ // we also have to scroll the update rgn in this rectangle
+ // in order not to loose updates
+ WindowRef rootWindow = (WindowRef) MacGetRootWindow() ;
+ RgnHandle formerUpdateRgn = NewRgn() ;
+ RgnHandle scrollRgn = NewRgn() ;
+ RectRgn( scrollRgn , &scrollrect ) ;
+ GetWindowUpdateRgn( rootWindow , formerUpdateRgn ) ;
+ Point pt = {0,0} ;
+ LocalToGlobal( &pt ) ;
+ OffsetRgn( formerUpdateRgn , -pt.h , -pt.v ) ;
+ SectRgn( formerUpdateRgn , scrollRgn , formerUpdateRgn ) ;
+ if ( !EmptyRgn( formerUpdateRgn ) )
+ {
+ MacOffsetRgn( formerUpdateRgn , dx , dy ) ;
+ SectRgn( formerUpdateRgn , scrollRgn , formerUpdateRgn ) ;
+ InvalWindowRgn(rootWindow , formerUpdateRgn ) ;
+ }
+ InvalWindowRgn(rootWindow , updateRgn ) ;
+ DisposeRgn( updateRgn ) ;
+ DisposeRgn( formerUpdateRgn ) ;
+ DisposeRgn( scrollRgn ) ;
+ }
+
+ for (wxWindowListNode *node = GetChildren().GetFirst(); node; node = node->GetNext())
+ {
+ wxWindowMac *child = node->GetData();
+ if (child == m_vScrollBar) continue;
+ if (child == m_hScrollBar) continue;
+ if (child->IsTopLevel()) continue;
+
+ int x,y;
+ child->GetPosition( &x, &y );
+ int w,h;
+ child->GetSize( &w, &h );
+ if (rect)
+ {
+ wxRect rc(x,y,w,h);
+ if (rect->Intersects(rc))
+ child->SetSize( x+dx, y+dy, w, h );
+ }
+ else
+ {
+ child->SetSize( x+dx, y+dy, w, h );
+ }
+ }
+
+ Update() ;
+
+}
+
+void wxWindowMac::MacOnScroll(wxScrollEvent &event )
+{
+ if ( event.m_eventObject == m_vScrollBar || event.m_eventObject == m_hScrollBar )
+ {
+ wxScrollWinEvent wevent;
+ wevent.SetPosition(event.GetPosition());
+ wevent.SetOrientation(event.GetOrientation());
+ wevent.m_eventObject = this;
+
+ if (event.m_eventType == wxEVT_SCROLL_TOP)
+ wevent.m_eventType = wxEVT_SCROLLWIN_TOP;
+ else if (event.m_eventType == wxEVT_SCROLL_BOTTOM)
+ wevent.m_eventType = wxEVT_SCROLLWIN_BOTTOM;
+ else if (event.m_eventType == wxEVT_SCROLL_LINEUP)
+ wevent.m_eventType = wxEVT_SCROLLWIN_LINEUP;
+ else if (event.m_eventType == wxEVT_SCROLL_LINEDOWN)
+ wevent.m_eventType = wxEVT_SCROLLWIN_LINEDOWN;
+ else if (event.m_eventType == wxEVT_SCROLL_PAGEUP)
+ wevent.m_eventType = wxEVT_SCROLLWIN_PAGEUP;
+ else if (event.m_eventType == wxEVT_SCROLL_PAGEDOWN)
+ wevent.m_eventType = wxEVT_SCROLLWIN_PAGEDOWN;
+ else if (event.m_eventType == wxEVT_SCROLL_THUMBTRACK)
+ wevent.m_eventType = wxEVT_SCROLLWIN_THUMBTRACK;
+ else if (event.m_eventType == wxEVT_SCROLL_THUMBRELEASE)
+ wevent.m_eventType = wxEVT_SCROLLWIN_THUMBRELEASE;
+
+ GetEventHandler()->ProcessEvent(wevent);
+ }
+}
+
+// Get the window with the focus
+wxWindowMac *wxWindowBase::FindFocus()
+{
+ return gFocusWindow ;
+}
+
+void wxWindowMac::OnSetFocus(wxFocusEvent& event)
+{
+ // panel wants to track the window which was the last to have focus in it,
+ // so we want to set ourselves as the window which last had focus
+ //
+ // notice that it's also important to do it upwards the tree becaus
+ // otherwise when the top level panel gets focus, it won't set it back to
+ // us, but to some other sibling
+
+ // CS:don't know if this is still needed:
+ //wxChildFocusEvent eventFocus(this);
+ //(void)GetEventHandler()->ProcessEvent(eventFocus);
+
+ event.Skip();
+}
+
+// Setup background and foreground colours correctly
+void wxWindowMac::SetupColours()
+{
+ if ( GetParent() )
+ SetBackgroundColour(GetParent()->GetBackgroundColour());
+}
+
+void wxWindowMac::OnInternalIdle()
+{
+ // This calls the UI-update mechanism (querying windows for
+ // menu/toolbar/control state information)
+ if (wxUpdateUIEvent::CanUpdate(this))
+ UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
+}
+
+// Raise the window to the top of the Z order
+void wxWindowMac::Raise()
+{
+}
+
+// Lower the window to the bottom of the Z order
+void wxWindowMac::Lower()
+{
+}
+
+void wxWindowMac::DoSetClientSize(int width, int height)
+{
+ if ( width != -1 || height != -1 )
+ {
+
+ if ( width != -1 && m_vScrollBar )
+ width += MAC_SCROLLBAR_SIZE ;
+ if ( height != -1 && m_vScrollBar )
+ height += MAC_SCROLLBAR_SIZE ;
+
+ width += MacGetLeftBorderSize( ) + MacGetRightBorderSize( ) ;
+ height += MacGetTopBorderSize( ) + MacGetBottomBorderSize( ) ;
+
+ DoSetSize( -1 , -1 , width , height ) ;
+ }
+}
+
+
+wxWindowMac* wxWindowMac::s_lastMouseWindow = NULL ;
+
+bool wxWindowMac::MacGetWindowFromPointSub( const wxPoint &point , wxWindowMac** outWin )
+{
+ if ( IsTopLevel() )
+ {
+ if ((point.x < 0) || (point.y < 0) ||
+ (point.x > (m_width)) || (point.y > (m_height)))
+ return FALSE;
+ }
+ else
+ {
+ if ((point.x < m_x) || (point.y < m_y) ||
+ (point.x > (m_x + m_width)) || (point.y > (m_y + m_height)))
+ return FALSE;
+ }
+
+ WindowRef window = (WindowRef) MacGetRootWindow() ;
+
+ wxPoint newPoint( point ) ;
+
+ if ( !IsTopLevel() )
+ {
+ newPoint.x -= m_x;
+ newPoint.y -= m_y;
+ }
+
+ for (wxWindowListNode *node = GetChildren().GetFirst(); node; node = node->GetNext())
+ {
+ wxWindowMac *child = node->GetData();
+ // added the m_isShown test --dmazzoni
+ if ( child->MacGetRootWindow() == window && child->m_isShown )
+ {
+ if (child->MacGetWindowFromPointSub(newPoint , outWin ))
+ return TRUE;
+ }
+ }
+
+ *outWin = this ;
+ return TRUE;
+}
+
+bool wxWindowMac::MacGetWindowFromPoint( const wxPoint &screenpoint , wxWindowMac** outWin )
+{
+ WindowRef window ;
+
+ Point pt = { screenpoint.y , screenpoint.x } ;
+ if ( ::FindWindow( pt , &window ) == 3 )
+ {
+
+ wxWindowMac* win = wxFindWinFromMacWindow( window ) ;
+ if ( win )
+ {
+ // No, this yields the CLIENT are, we need the whole frame. RR.
+ // point = win->ScreenToClient( point ) ;
+
+ GrafPtr port;
+ ::GetPort( &port ) ;
+ ::SetPort( UMAGetWindowPort( window ) ) ;
+ ::GlobalToLocal( &pt ) ;
+ ::SetPort( port ) ;
+
+ wxPoint point( pt.h, pt.v ) ;
+
+ return win->MacGetWindowFromPointSub( point , outWin ) ;
+ }
+ }
+ return FALSE ;
+}
+
+static wxWindow *gs_lastWhich = NULL;
+
+bool wxWindowMac::MacSetupCursor( const wxPoint& pt)
+{
+ // first trigger a set cursor event
+
+ wxPoint clientorigin = GetClientAreaOrigin() ;
+ wxSize clientsize = GetClientSize() ;
+ wxCursor cursor ;
+ if ( wxRect2DInt( clientorigin.x , clientorigin.y , clientsize.x , clientsize.y ).Contains( wxPoint2DInt( pt ) ) )
+ {
+ wxSetCursorEvent event( pt.x , pt.y );
+
+ bool processedEvtSetCursor = GetEventHandler()->ProcessEvent(event);
+ if ( processedEvtSetCursor && event.HasCursor() )
+ {
+ cursor = event.GetCursor() ;
+ }
+ else
+ {
+
+ // the test for processedEvtSetCursor is here to prevent using m_cursor
+ // if the user code caught EVT_SET_CURSOR() and returned nothing from
+ // it - this is a way to say that our cursor shouldn't be used for this
+ // point
+ if ( !processedEvtSetCursor && m_cursor.Ok() )
+ {
+ cursor = m_cursor ;
+ }
+ if ( wxIsBusy() )
+ {
+ }
+ else
+ {
+ if ( !GetParent() )
+ cursor = *wxSTANDARD_CURSOR ;
+ }
+ }
+ if ( cursor.Ok() )
+ cursor.MacInstall() ;
+ }
+ return cursor.Ok() ;
+}
+
+bool wxWindowMac::MacDispatchMouseEvent(wxMouseEvent& event)
+{
+ if ((event.m_x < m_x) || (event.m_y < m_y) ||
+ (event.m_x > (m_x + m_width)) || (event.m_y > (m_y + m_height)))
+ return FALSE;
+
+
+ if ( IsKindOf( CLASSINFO ( wxStaticBox ) ) /* || IsKindOf( CLASSINFO( wxSpinCtrl ) ) */)
+ return FALSE ;
+
+ WindowRef window = (WindowRef) MacGetRootWindow() ;
+
+ event.m_x -= m_x;
+ event.m_y -= m_y;
+
+ int x = event.m_x ;
+ int y = event.m_y ;
+
+ for (wxWindowListNode *node = GetChildren().GetFirst(); node; node = node->GetNext())
+ {
+ wxWindowMac *child = node->GetData();
+ if ( child->MacGetRootWindow() == window && child->IsShown() && child->IsEnabled() )
+ {
+ if (child->MacDispatchMouseEvent(event))
+ return TRUE;
+ }
+ }
+
+ wxWindow* cursorTarget = this ;
+ wxPoint cursorPoint( x , y ) ;
+
+ while( cursorTarget && !cursorTarget->MacSetupCursor( cursorPoint ) )
+ {
+ cursorTarget = cursorTarget->GetParent() ;
+ if ( cursorTarget )
+ cursorPoint += cursorTarget->GetPosition() ;
+ }
+ event.m_x = x ;
+ event.m_y = y ;
+ event.SetEventObject( this ) ;
+
+ if ( event.GetEventType() == wxEVT_LEFT_DOWN )
+ {
+ // set focus to this window
+ if (AcceptsFocus() && FindFocus()!=this)
+ SetFocus();
+ }
+
+#if wxUSE_TOOLTIPS
+ if ( event.GetEventType() == wxEVT_MOTION
+ || event.GetEventType() == wxEVT_ENTER_WINDOW
+ || event.GetEventType() == wxEVT_LEAVE_WINDOW )
+ wxToolTip::RelayEvent( this , event);
+#endif // wxUSE_TOOLTIPS
+
+ if (gs_lastWhich != this)
+ {
+ gs_lastWhich = this;
+
+ // Double clicks must always occur on the same window
+ if (event.GetEventType() == wxEVT_LEFT_DCLICK)
+ event.SetEventType( wxEVT_LEFT_DOWN );
+ if (event.GetEventType() == wxEVT_RIGHT_DCLICK)
+ event.SetEventType( wxEVT_RIGHT_DOWN );
+
+ // Same for mouse up events
+ if (event.GetEventType() == wxEVT_LEFT_UP)
+ return TRUE;
+ if (event.GetEventType() == wxEVT_RIGHT_UP)
+ return TRUE;
+ }
+
+ GetEventHandler()->ProcessEvent( event ) ;
+
+ return TRUE;
+}
+
+wxString wxWindowMac::MacGetToolTipString( wxPoint &pt )
+{
+ if ( m_tooltip )
+ {
+ return m_tooltip->GetTip() ;
+ }
+ return wxEmptyString ;
+}
+
+void wxWindowMac::Update()
+{
+ wxRegion visRgn = MacGetVisibleRegion( false ) ;
+ int top = 0 , left = 0 ;
+ MacWindowToRootWindow( &left , &top ) ;
+ WindowRef rootWindow = (WindowRef) MacGetRootWindow() ;
+ RgnHandle updateRgn = NewRgn() ;
+ // getting the update region in macos local coordinates
+ GetWindowUpdateRgn( rootWindow , updateRgn ) ;
+ GrafPtr port ;
+ ::GetPort( &port ) ;
+ ::SetPort( UMAGetWindowPort( rootWindow ) ) ;
+ Point pt = {0,0} ;
+ LocalToGlobal( &pt ) ;
+ ::SetPort( port ) ;
+ OffsetRgn( updateRgn , -pt.h , -pt.v ) ;
+ // translate to window local coordinates
+ OffsetRgn( updateRgn , -left , -top ) ;
+ SectRgn( updateRgn , (RgnHandle) visRgn.GetWXHRGN() , updateRgn ) ;
+ MacRedraw( updateRgn , 0 , true ) ;
+ // for flushing and validating we need macos-local coordinates again
+ OffsetRgn( updateRgn , left , top ) ;
+#if TARGET_API_MAC_CARBON
+ if ( QDIsPortBuffered( GetWindowPort( rootWindow ) ) )
+ {
+ QDFlushPortBuffer( GetWindowPort( rootWindow ) , updateRgn ) ;
+ }
+#endif
+ ValidWindowRgn( rootWindow , updateRgn ) ;
+ DisposeRgn( updateRgn ) ;
+}
+
+wxTopLevelWindowMac* wxWindowMac::MacGetTopLevelWindow() const
+{
+ wxTopLevelWindowMac* win = NULL ;
+ WindowRef window = (WindowRef) MacGetRootWindow() ;
+ if ( window )
+ {
+ win = wxFindWinFromMacWindow( window ) ;
+ }
+ return win ;
+}
+
+const wxRegion& wxWindowMac::MacGetVisibleRegion( bool respectChildrenAndSiblings )
+{
+ RgnHandle visRgn = NewRgn() ;
+ RgnHandle tempRgn = NewRgn() ;
+ RgnHandle tempStaticBoxRgn = NewRgn() ;
+
+ if ( MacIsReallyShown() )
+ {
+ SetRectRgn( visRgn , 0 , 0 , m_width , m_height ) ;
+
+ //TODO : as soon as the new scheme has proven to work correctly, move this to wxStaticBox
+ if ( IsKindOf( CLASSINFO( wxStaticBox ) ) )
+ {
+ int borderTop = 14 ;
+ int borderOther = 4 ;
+ if ( UMAGetSystemVersion() >= 0x1030 )
+ borderTop += 2 ;
+
+ SetRectRgn( tempStaticBoxRgn , borderOther , borderTop , m_width - borderOther , m_height - borderOther ) ;
+ DiffRgn( visRgn , tempStaticBoxRgn , visRgn ) ;
+ }
+
+ if ( !IsTopLevel() )
+ {
+ wxWindow* parent = GetParent() ;
+ while( parent )
+ {
+ wxSize size = parent->GetSize() ;
+ int x , y ;
+ x = y = 0 ;
+ parent->MacWindowToRootWindow( &x, &y ) ;
+ MacRootWindowToWindow( &x , &y ) ;
+
+ SetRectRgn( tempRgn ,
+ x + parent->MacGetLeftBorderSize() , y + parent->MacGetTopBorderSize() ,
+ x + size.x - parent->MacGetRightBorderSize(),
+ y + size.y - parent->MacGetBottomBorderSize()) ;
+
+ SectRgn( visRgn , tempRgn , visRgn ) ;
+ if ( parent->IsTopLevel() )
+ break ;
+ parent = parent->GetParent() ;
+ }
+ }
+ if ( respectChildrenAndSiblings )
+ {
+ if ( GetWindowStyle() & wxCLIP_CHILDREN )
+ {
+ for (wxWindowListNode *node = GetChildren().GetFirst(); node; node = node->GetNext())
+ {
+ wxWindowMac *child = node->GetData();
+
+ if ( !child->IsTopLevel() && child->IsShown() )
+ {
+ SetRectRgn( tempRgn , child->m_x , child->m_y , child->m_x + child->m_width , child->m_y + child->m_height ) ;
+ if ( child->IsKindOf( CLASSINFO( wxStaticBox ) ) )
+ {
+ int borderTop = 14 ;
+ int borderOther = 4 ;
+ if ( UMAGetSystemVersion() >= 0x1030 )
+ borderTop += 2 ;
+
+ SetRectRgn( tempStaticBoxRgn , child->m_x + borderOther , child->m_y + borderTop , child->m_x + child->m_width - borderOther , child->m_y + child->m_height - borderOther ) ;
+ DiffRgn( tempRgn , tempStaticBoxRgn , tempRgn ) ;
+ }
+ DiffRgn( visRgn , tempRgn , visRgn ) ;
+ }
+ }
+ }
+
+ if ( (GetWindowStyle() & wxCLIP_SIBLINGS) && GetParent() )
+ {
+ bool thisWindowThrough = false ;
+ for (wxWindowListNode *node = GetParent()->GetChildren().GetFirst(); node; node = node->GetNext())
+ {
+ wxWindowMac *sibling = node->GetData();
+ if ( sibling == this )
+ {
+ thisWindowThrough = true ;
+ continue ;
+ }
+ if( !thisWindowThrough )
+ {
+ continue ;
+ }
+
+ if ( !sibling->IsTopLevel() && sibling->IsShown() )
+ {
+ SetRectRgn( tempRgn , sibling->m_x - m_x , sibling->m_y - m_y , sibling->m_x + sibling->m_width - m_x , sibling->m_y + sibling->m_height - m_y ) ;
+ if ( sibling->IsKindOf( CLASSINFO( wxStaticBox ) ) )
+ {
+ int borderTop = 14 ;
+ int borderOther = 4 ;
+ if ( UMAGetSystemVersion() >= 0x1030 )
+ borderTop += 2 ;
+
+ SetRectRgn( tempStaticBoxRgn , sibling->m_x - m_x + borderOther , sibling->m_y - m_y + borderTop , sibling->m_x + sibling->m_width - m_x - borderOther , sibling->m_y + sibling->m_height - m_y - borderOther ) ;
+ DiffRgn( tempRgn , tempStaticBoxRgn , tempRgn ) ;
+ }
+ DiffRgn( visRgn , tempRgn , visRgn ) ;
+ }
+ }
+ }
+ }
+ }
+ m_macVisibleRegion = visRgn ;
+ DisposeRgn( visRgn ) ;
+ DisposeRgn( tempRgn ) ;
+ DisposeRgn( tempStaticBoxRgn ) ;
+ return m_macVisibleRegion ;
+}
+
+void wxWindowMac::MacRedraw( WXHRGN updatergnr , long time, bool erase)
+{
+ RgnHandle updatergn = (RgnHandle) updatergnr ;
+ // updatergn is always already clipped to our boundaries
+ // it is in window coordinates, not in client coordinates
+
+ WindowRef window = (WindowRef) MacGetRootWindow() ;
+
+ {
+ // ownUpdateRgn is the area that this window has to repaint, it is in window coordinates
+ RgnHandle ownUpdateRgn = NewRgn() ;
+ CopyRgn( updatergn , ownUpdateRgn ) ;
+
+ SectRgn( ownUpdateRgn , (RgnHandle) MacGetVisibleRegion().GetWXHRGN() , ownUpdateRgn ) ;
+
+ // newupdate is the update region in client coordinates
+ RgnHandle newupdate = NewRgn() ;
+ wxSize point = GetClientSize() ;
+ wxPoint origin = GetClientAreaOrigin() ;
+ SetRectRgn( newupdate , origin.x , origin.y , origin.x + point.x , origin.y+point.y ) ;
+ SectRgn( newupdate , ownUpdateRgn , newupdate ) ;
+ OffsetRgn( newupdate , -origin.x , -origin.y ) ;
+ m_updateRegion = newupdate ;
+ DisposeRgn( newupdate ) ; // it's been cloned to m_updateRegion
+
+ if ( erase && !EmptyRgn(ownUpdateRgn) )
+ {
+ wxWindowDC dc(this);
+ if (!EmptyRgn(ownUpdateRgn))
+ dc.SetClippingRegion(wxRegion(ownUpdateRgn));
+ wxEraseEvent eevent( GetId(), &dc );
+ eevent.SetEventObject( this );
+ GetEventHandler()->ProcessEvent( eevent );
+
+ wxNcPaintEvent eventNc( GetId() );
+ eventNc.SetEventObject( this );
+ GetEventHandler()->ProcessEvent( eventNc );
+ }
+ DisposeRgn( ownUpdateRgn ) ;
+ if ( !m_updateRegion.Empty() )
+ {
+ wxWindowList hiddenWindows ;
+ for (wxWindowListNode *node = GetChildren().GetFirst(); node; node = node->GetNext())
+ {
+ wxControl *child = wxDynamicCast( ( wxWindow*)node->GetData() , wxControl ) ;
+
+ if ( child && child->MacGetRootWindow() == window && child->IsShown() && child->GetMacControl() )
+ {
+ SetControlVisibility( (ControlHandle) child->GetMacControl() , false , false ) ;
+ hiddenWindows.Append( child ) ;
+ }
+ }
+
+ wxPaintEvent event;
+ event.m_timeStamp = time ;
+ event.SetEventObject(this);
+ GetEventHandler()->ProcessEvent(event);
+
+ for (wxWindowListNode *node = hiddenWindows.GetFirst(); node; node = node->GetNext())
+ {
+ wxControl *child = wxDynamicCast( ( wxWindow*)node->GetData() , wxControl ) ;
+
+ if ( child && child->GetMacControl() )
+ {
+ SetControlVisibility( (ControlHandle) child->GetMacControl() , true , false ) ;
+ }
+ }
+ }
+ }
+
+ // now intersect for each of the children their rect with the updateRgn and call MacRedraw recursively
+
+ RgnHandle childupdate = NewRgn() ;
+ for (wxWindowListNode *node = GetChildren().GetFirst(); node; node = node->GetNext())
+ {
+ // calculate the update region for the child windows by intersecting the window rectangle with our own
+ // passed in update region and then offset it to be client-wise window coordinates again
+ wxWindowMac *child = node->GetData();
+ SetRectRgn( childupdate , child->m_x , child->m_y , child->m_x + child->m_width , child->m_y + child->m_height ) ;
+ SectRgn( childupdate , updatergn , childupdate ) ;
+ OffsetRgn( childupdate , -child->m_x , -child->m_y ) ;
+ if ( child->MacGetRootWindow() == window && child->IsShown() && !EmptyRgn( childupdate ) )
+ {
+ // because dialogs may also be children
+ child->MacRedraw( childupdate , time , erase ) ;
+ }
+ }
+ DisposeRgn( childupdate ) ;
+ // eventually a draw grow box here
+
+}
+
+WXHWND wxWindowMac::MacGetRootWindow() const
+{
+ wxWindowMac *iter = (wxWindowMac*)this ;
+
+ while( iter )
+ {
+ if ( iter->IsTopLevel() )
+ return ((wxTopLevelWindow*)iter)->MacGetWindowRef() ;
+
+ iter = iter->GetParent() ;
+ }
+ wxASSERT_MSG( 1 , wxT("No valid mac root window") ) ;
+ return NULL ;
+}
+
+void wxWindowMac::MacCreateScrollBars( long style )
+{
+ wxASSERT_MSG( m_vScrollBar == NULL && m_hScrollBar == NULL , wxT("attempt to create window twice") ) ;
+
+ bool hasBoth = ( style & wxVSCROLL ) && ( style & wxHSCROLL ) ;
+ int adjust = hasBoth ? MAC_SCROLLBAR_SIZE - 1: 0 ;
+ int width, height ;
+ GetClientSize( &width , &height ) ;
+
+ wxPoint vPoint(width-MAC_SCROLLBAR_SIZE, 0) ;
+ wxSize vSize(MAC_SCROLLBAR_SIZE, height - adjust) ;
+ wxPoint hPoint(0 , height-MAC_SCROLLBAR_SIZE ) ;
+ wxSize hSize( width - adjust, MAC_SCROLLBAR_SIZE) ;
+
+ m_vScrollBar = new wxScrollBar(this, wxWINDOW_VSCROLL, vPoint,
+ vSize , wxVERTICAL);
+
+ if ( style & wxVSCROLL )
+ {
+
+ }
+ else
+ {
+ m_vScrollBar->Show(false) ;
+ }
+ m_hScrollBar = new wxScrollBar(this, wxWINDOW_HSCROLL, hPoint,
+ hSize , wxHORIZONTAL);
+ if ( style & wxHSCROLL )
+ {
+ }
+ else
+ {
+ m_hScrollBar->Show(false) ;
+ }
+
+ // because the create does not take into account the client area origin
+ MacRepositionScrollBars() ; // we might have a real position shift
+}
+
+void wxWindowMac::MacRepositionScrollBars()
+{
+ bool hasBoth = ( m_hScrollBar && m_hScrollBar->IsShown()) && ( m_vScrollBar && m_vScrollBar->IsShown()) ;
+ int adjust = hasBoth ? MAC_SCROLLBAR_SIZE - 1 : 0 ;
+
+ // get real client area
+
+ int width = m_width ;
+ int height = m_height ;
+
+ width -= MacGetLeftBorderSize() + MacGetRightBorderSize();
+ height -= MacGetTopBorderSize() + MacGetBottomBorderSize();
+
+ wxPoint vPoint(width-MAC_SCROLLBAR_SIZE, 0) ;
+ wxSize vSize(MAC_SCROLLBAR_SIZE, height - adjust) ;
+ wxPoint hPoint(0 , height-MAC_SCROLLBAR_SIZE ) ;
+ wxSize hSize( width - adjust, MAC_SCROLLBAR_SIZE) ;
+
+ int x = 0 ;
+ int y = 0 ;
+ int w = m_width ;
+ int h = m_height ;
+
+ MacClientToRootWindow( &x , &y ) ;
+ MacClientToRootWindow( &w , &h ) ;
+
+ wxWindowMac *iter = (wxWindowMac*)this ;
+
+ int totW = 10000 , totH = 10000;
+ while( iter )
+ {
+ if ( iter->IsTopLevel() )
+ {
+ totW = iter->m_width ;
+ totH = iter->m_height ;
+ break ;
+ }
+
+ iter = iter->GetParent() ;
+ }
+
+ if ( x == 0 )
+ {
+ hPoint.x = -1 ;
+ hSize.x += 1 ;
+ }
+ if ( y == 0 )
+ {
+ vPoint.y = -1 ;
+ vSize.y += 1 ;
+ }
+
+ if ( w-x >= totW )
+ {
+ hSize.x += 1 ;
+ vPoint.x += 1 ;
+ }
+
+ if ( h-y >= totH )
+ {
+ vSize.y += 1 ;
+ hPoint.y += 1 ;
+ }
+
+ if ( m_vScrollBar )
+ {
+ m_vScrollBar->SetSize( vPoint.x , vPoint.y, vSize.x, vSize.y , wxSIZE_ALLOW_MINUS_ONE);
+ }
+ if ( m_hScrollBar )
+ {
+ m_hScrollBar->SetSize( hPoint.x , hPoint.y, hSize.x, hSize.y, wxSIZE_ALLOW_MINUS_ONE);
+ }
+}
+
+bool wxWindowMac::AcceptsFocus() const
+{
+ return MacCanFocus() && wxWindowBase::AcceptsFocus();
+}
+
+WXWidget wxWindowMac::MacGetContainerForEmbedding()
+{
+ return GetParent()->MacGetContainerForEmbedding() ;
+}
+
+void wxWindowMac::MacSuperChangedPosition()
+{
+ // only window-absolute structures have to be moved i.e. controls
+
+ wxWindowListNode *node = GetChildren().GetFirst();
+ while ( node )
+ {
+ wxWindowMac *child = node->GetData();
+ child->MacSuperChangedPosition() ;
+ node = node->GetNext();
+ }
+}
+
+void wxWindowMac::MacTopLevelWindowChangedPosition()
+{
+ // only screen-absolute structures have to be moved i.e. glcanvas
+
+ wxWindowListNode *node = GetChildren().GetFirst();
+ while ( node )
+ {
+ wxWindowMac *child = node->GetData();
+ child->MacTopLevelWindowChangedPosition() ;
+ node = node->GetNext();
+ }
+}
+long wxWindowMac::MacGetLeftBorderSize( ) const
+{
+ if( IsTopLevel() )
+ return 0 ;
+
+ if (m_windowStyle & wxRAISED_BORDER || m_windowStyle & wxSUNKEN_BORDER )
+ {
+ SInt32 border = 3 ;
+#if wxMAC_USE_THEME_BORDER
+#if TARGET_CARBON
+ GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ;
+#endif
+#endif
+ return border ;
+ }
+ else if ( m_windowStyle &wxDOUBLE_BORDER)
+ {
+ SInt32 border = 3 ;
+#if wxMAC_USE_THEME_BORDER
+#if TARGET_CARBON
+ GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ;
+#endif
+#endif
+ return border ;
+ }
+ else if (m_windowStyle &wxSIMPLE_BORDER)
+ {
+ return 1 ;
+ }
+ return 0 ;
+}
+
+long wxWindowMac::MacGetRightBorderSize( ) const
+{
+ // they are all symmetric in mac themes
+ return MacGetLeftBorderSize() ;
+}
+
+long wxWindowMac::MacGetTopBorderSize( ) const
+{
+ // they are all symmetric in mac themes
+ return MacGetLeftBorderSize() ;
+}
+
+long wxWindowMac::MacGetBottomBorderSize( ) const
+{
+ // they are all symmetric in mac themes
+ return MacGetLeftBorderSize() ;
+}
+
+long wxWindowMac::MacRemoveBordersFromStyle( long style )
+{
+ return style & ~( wxDOUBLE_BORDER | wxSUNKEN_BORDER | wxRAISED_BORDER | wxBORDER | wxSTATIC_BORDER ) ;
+}
+
+// Find the wxWindowMac at the current mouse position, returning the mouse
+// position.
+wxWindowMac* wxFindWindowAtPointer(wxPoint& pt)
+{
+ pt = wxGetMousePosition();
+ wxWindowMac* found = wxFindWindowAtPoint(pt);
+ return found;
+}
+
+// Get the current mouse position.
+wxPoint wxGetMousePosition()
+{
+ int x, y;
+ wxGetMousePosition(& x, & y);
+ return wxPoint(x, y);
+}
+
+void wxWindowMac::OnMouseEvent( wxMouseEvent &event )
+{
+ if ( event.GetEventType() == wxEVT_RIGHT_DOWN )
+ {
+ // copied from wxGTK : CS
+ // generate a "context menu" event: this is similar to wxEVT_RIGHT_DOWN
+ // except that:
+ //
+ // (a) it's a command event and so is propagated to the parent
+ // (b) under MSW it can be generated from kbd too
+ // (c) it uses screen coords (because of (a))
+ wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU,
+ this->GetId(),
+ this->ClientToScreen(event.GetPosition()));
+ if ( ! GetEventHandler()->ProcessEvent(evtCtx) )
+ event.Skip() ;
+ }
+ else
+ {
+ event.Skip() ;
+ }
+}
+