]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/mac/uma.cpp
applied copy constructor fix to assignment operator as well
[wxWidgets.git] / src / mac / uma.cpp
... / ...
CommitLineData
1#include "wx/defs.h"
2#include "wx/dc.h"
3#include "wx/mac/uma.h"
4#include <MacTextEditor.h>
5
6#ifndef __DARWIN__
7# include <Navigation.h>
8# if defined(TARGET_CARBON)
9# if PM_USE_SESSION_APIS
10# include <PMCore.h>
11# endif
12# include <PMApplication.h>
13# else
14# include <Printing.h>
15# endif
16#endif
17
18// since we have decided that we only support 8.6 upwards we are
19// checking for these minimum requirements in the startup code of
20// the application so all wxWindows code can safely assume that appearance 1.1
21// windows manager, control manager, navigation services etc. are
22// present
23
24static bool sUMAHasAppearance = false ;
25static long sUMAAppearanceVersion = 0 ;
26static bool sUMAHasAquaLayout = false ;
27static bool sUMASystemInitialized = false ;
28
29extern int gAGABackgroundColor ;
30bool UMAHasAppearance() { return sUMAHasAppearance ; }
31long UMAGetAppearanceVersion() { return sUMAAppearanceVersion ; }
32
33static bool sUMAHasWindowManager = false ;
34static long sUMAWindowManagerAttr = 0 ;
35
36bool UMAHasWindowManager() { return sUMAHasWindowManager ; }
37long UMAGetWindowManagerAttr() { return sUMAWindowManagerAttr ; }
38bool UMAHasAquaLayout() { return sUMAHasAquaLayout ; }
39bool UMASystemIsInitialized() { return sUMASystemInitialized ; }
40
41void UMACleanupToolbox()
42{
43 if ( sUMAHasAppearance )
44 {
45 UnregisterAppearanceClient() ;
46 }
47 if ( NavServicesAvailable() )
48 {
49 NavUnload() ;
50 }
51 if ( TXNTerminateTextension != (void*) kUnresolvedCFragSymbolAddress )
52 TXNTerminateTextension( ) ;
53}
54void UMAInitToolbox( UInt16 inMoreMastersCalls )
55{
56#if !TARGET_CARBON
57 ::MaxApplZone();
58 for (long i = 1; i <= inMoreMastersCalls; i++)
59 ::MoreMasters();
60
61 ::InitGraf(&qd.thePort);
62 ::InitFonts();
63 ::InitMenus();
64 ::TEInit();
65 ::InitDialogs(0L);
66 ::FlushEvents(everyEvent, 0);
67 ::InitCursor();
68 long total,contig;
69 PurgeSpace(&total, &contig);
70#else
71 InitCursor();
72#endif
73
74 long theAppearance ;
75 if ( Gestalt( gestaltAppearanceAttr, &theAppearance ) == noErr )
76 {
77 sUMAHasAppearance = true ;
78 RegisterAppearanceClient();
79 if ( Gestalt( gestaltAppearanceVersion, &theAppearance ) == noErr )
80 {
81 sUMAAppearanceVersion = theAppearance ;
82 }
83 else
84 {
85 sUMAAppearanceVersion = 0x0100 ;
86 }
87 }
88 if ( Gestalt( gestaltWindowMgrAttr, &sUMAWindowManagerAttr ) == noErr )
89 {
90 sUMAHasWindowManager = sUMAWindowManagerAttr & gestaltWindowMgrPresent ;
91 }
92
93#if TARGET_CARBON
94// Call currently implicitely done : InitFloatingWindows() ;
95#else
96 if ( sUMAHasWindowManager )
97 InitFloatingWindows() ;
98 else
99 InitWindows();
100#endif
101
102 if ( NavServicesAvailable() )
103 {
104 NavLoad() ;
105 }
106
107 if ( TXNInitTextension != (void*) kUnresolvedCFragSymbolAddress )
108 {
109 FontFamilyID fontId ;
110 Str255 fontName ;
111 SInt16 fontSize ;
112 Style fontStyle ;
113 GetThemeFont(kThemeSmallSystemFont , GetApplicationScript() , fontName , &fontSize , &fontStyle ) ;
114 GetFNum( fontName, &fontId );
115
116 TXNMacOSPreferredFontDescription fontDescriptions[] =
117 {
118 { fontId , (fontSize << 16) ,kTXNDefaultFontStyle, kTXNSystemDefaultEncoding } ,
119 } ;
120 int noOfFontDescriptions = sizeof( fontDescriptions ) / sizeof(TXNMacOSPreferredFontDescription) ;
121#if TARGET_CARBON
122 --noOfFontDescriptions ;
123#endif
124 // kTXNAlwaysUseQuickDrawTextMask might be desirable because of speed increases but it crashes the app under OS X upon key stroke
125 TXNInitTextension(fontDescriptions, noOfFontDescriptions, ( kTXNWantMoviesMask | kTXNWantSoundMask | kTXNWantGraphicsMask));
126 }
127
128 long menuMgrAttr ;
129 Gestalt( gestaltMenuMgrAttr , &menuMgrAttr ) ;
130 if ( menuMgrAttr & gestaltMenuMgrAquaLayoutMask )
131 sUMAHasAquaLayout = true ;
132 sUMASystemInitialized = true ;
133
134}
135
136/*
137Boolean CanUseATSUI()
138 {
139 long result;
140 OSErr err = Gestalt(gestaltATSUVersion, &result);
141 return (err == noErr);
142 }
143*/
144// process manager
145long UMAGetProcessMode()
146{
147 OSErr err ;
148 ProcessInfoRec processinfo;
149 ProcessSerialNumber procno ;
150
151 procno.highLongOfPSN = NULL ;
152 procno.lowLongOfPSN = kCurrentProcess ;
153 processinfo.processInfoLength = sizeof(ProcessInfoRec);
154 processinfo.processName = NULL;
155 processinfo.processAppSpec = NULL;
156
157 err = ::GetProcessInformation( &procno , &processinfo ) ;
158 wxASSERT( err == noErr ) ;
159 return processinfo.processMode ;
160}
161
162bool UMAGetProcessModeDoesActivateOnFGSwitch()
163{
164 return UMAGetProcessMode() & modeDoesActivateOnFGSwitch ;
165}
166
167// menu manager
168
169void UMASetMenuTitle( MenuRef menu , StringPtr title )
170{
171/*
172#if !TARGET_CARBON
173 long size = GetHandleSize( (Handle) menu ) ;
174 const long headersize = 14 ;
175 int oldlen = (**menu).menuData[0] + 1;
176 int newlen = title[0] + 1 ;
177
178 if ( oldlen < newlen )
179 {
180 // enlarge before adjusting
181 SetHandleSize( (Handle) menu , size + (newlen - oldlen ) );
182 }
183
184 if ( oldlen != newlen )
185 memmove( (char*) (**menu).menuData + newlen , (char*) (**menu).menuData + oldlen , size - headersize - oldlen ) ;
186
187 memcpy( (char*) (**menu).menuData , title , newlen ) ;
188 if ( oldlen > newlen )
189 {
190 // shrink after
191 SetHandleSize( (Handle) menu , size + (newlen - oldlen ) ) ;
192 }
193#else
194*/
195 SetMenuTitle( menu , title ) ;
196//#endif
197}
198
199UInt32 UMAMenuEvent( EventRecord *inEvent )
200{
201 return MenuEvent( inEvent ) ;
202}
203
204void UMAEnableMenuItem( MenuRef inMenu , MenuItemIndex inItem )
205{
206 EnableMenuItem( inMenu , inItem ) ;
207}
208
209void UMADisableMenuItem( MenuRef inMenu , MenuItemIndex inItem )
210{
211 DisableMenuItem( inMenu , inItem ) ;
212}
213
214void UMAAppendSubMenuItem( MenuRef menu , StringPtr l , SInt16 id )
215{
216 Str255 label ;
217 memcpy( label , l , l[0]+1 ) ;
218 // hardcoded adding of the submenu combination for mac
219
220 int theEnd = label[0] + 1;
221 if (theEnd > 251)
222 theEnd = 251; // mac allows only 255 characters
223 label[theEnd++] = '/';
224 label[theEnd++] = hMenuCmd;
225 label[theEnd++] = '!';
226 label[theEnd++] = id ;
227 label[theEnd] = 0x00;
228 label[0] = theEnd;
229 MacAppendMenu(menu, label);
230}
231
232void UMAInsertSubMenuItem( MenuRef menu , StringPtr l , MenuItemIndex item , SInt16 id )
233{
234 Str255 label ;
235 memcpy( label , l , l[0]+1 ) ;
236 // hardcoded adding of the submenu combination for mac
237
238 int theEnd = label[0] + 1;
239 if (theEnd > 251)
240 theEnd = 251; // mac allows only 255 characters
241 label[theEnd++] = '/';
242 label[theEnd++] = hMenuCmd;
243 label[theEnd++] = '!';
244 label[theEnd++] = id;
245 label[theEnd] = 0x00;
246 label[0] = theEnd;
247 MacInsertMenuItem(menu, label , item);
248}
249
250void UMAAppendMenuItem( MenuRef menu , StringPtr l , SInt16 key, UInt8 modifiers )
251{
252 Str255 label ;
253 memcpy( label , l , l[0]+1 ) ;
254 if ( key )
255 {
256 int pos = label[0] ;
257 label[++pos] = '/';
258 label[++pos] = toupper( key );
259 label[0] = pos ;
260 }
261 MacAppendMenu( menu , label ) ;
262}
263
264void UMAInsertMenuItem( MenuRef menu , StringPtr l , MenuItemIndex item , SInt16 key, UInt8 modifiers )
265{
266 Str255 label ;
267 memcpy( label , l , l[0]+1 ) ;
268 if ( key )
269 {
270 int pos = label[0] ;
271 label[++pos] = '/';
272 label[++pos] = toupper( key );
273 label[0] = pos ;
274 }
275 MacInsertMenuItem( menu , label , item) ;
276}
277
278// quickdraw
279
280int gPrOpenCounter = 0 ;
281
282OSStatus UMAPrOpen(void *macPrintSession)
283{
284#if !TARGET_CARBON
285 OSErr err = noErr ;
286 ++gPrOpenCounter ;
287 if ( gPrOpenCounter == 1 )
288 {
289 PrOpen() ;
290 err = PrError() ;
291 wxASSERT( err == noErr ) ;
292 }
293 return err ;
294#else
295 OSStatus err = noErr ;
296 ++gPrOpenCounter ;
297 if ( gPrOpenCounter == 1 )
298 {
299 #if PM_USE_SESSION_APIS
300 err = PMCreateSession((PMPrintSession *)macPrintSession) ;
301 #else
302 err = PMBegin() ;
303 #endif
304 wxASSERT( err == noErr ) ;
305 }
306 return err ;
307#endif
308}
309
310OSStatus UMAPrClose(void *macPrintSession)
311{
312#if !TARGET_CARBON
313 OSErr err = noErr ;
314 wxASSERT( gPrOpenCounter >= 1 ) ;
315 if ( gPrOpenCounter == 1 )
316 {
317 PrClose() ;
318 err = PrError() ;
319 wxASSERT( err == noErr ) ;
320 }
321 --gPrOpenCounter ;
322 return err ;
323#else
324 OSStatus err = noErr ;
325 wxASSERT( gPrOpenCounter >= 1 ) ;
326 if ( gPrOpenCounter == 1 )
327 {
328 #if PM_USE_SESSION_APIS
329 err = PMRelease(*(PMPrintSession *)macPrintSession) ;
330 *(PMPrintSession *)macPrintSession = kPMNoReference;
331 #else
332 err = PMEnd() ;
333 #endif
334 }
335 --gPrOpenCounter ;
336 return err ;
337#endif
338}
339
340#if !TARGET_CARBON
341
342pascal QDGlobalsPtr GetQDGlobalsPtr (void) ;
343pascal QDGlobalsPtr GetQDGlobalsPtr (void)
344{
345 return QDGlobalsPtr (* (Ptr*) LMGetCurrentA5 ( ) - 0xCA);
346}
347
348#endif
349
350void UMAShowWatchCursor()
351{
352 OSErr err = noErr;
353
354 CursHandle watchFob = GetCursor (watchCursor);
355
356 if (!watchFob)
357 err = nilHandleErr;
358 else
359 {
360 #if TARGET_CARBON
361// Cursor preservedArrow;
362// GetQDGlobalsArrow (&preservedArrow);
363// SetQDGlobalsArrow (*watchFob);
364// InitCursor ( );
365// SetQDGlobalsArrow (&preservedArrow);
366 SetCursor (*watchFob);
367 #else
368 SetCursor (*watchFob);
369 #endif
370 }
371}
372
373void UMAShowArrowCursor()
374{
375#if TARGET_CARBON
376 Cursor arrow;
377 SetCursor (GetQDGlobalsArrow (&arrow));
378#else
379 SetCursor (&(qd.arrow));
380#endif
381}
382
383// window manager
384
385GrafPtr UMAGetWindowPort( WindowRef inWindowRef )
386{
387 wxASSERT( inWindowRef != NULL ) ;
388#if TARGET_CARBON
389 return (GrafPtr) GetWindowPort( inWindowRef ) ;
390#else
391 return (GrafPtr) inWindowRef ;
392#endif
393}
394
395void UMADisposeWindow( WindowRef inWindowRef )
396{
397 wxASSERT( inWindowRef != NULL ) ;
398 DisposeWindow( inWindowRef ) ;
399}
400
401void UMASetWTitleC( WindowRef inWindowRef , const char *title )
402{
403 Str255 ptitle ;
404 strncpy( (char*)ptitle , title , 96 ) ;
405 ptitle[96] = 0 ;
406#if TARGET_CARBON
407 c2pstrcpy( ptitle, (char *)ptitle ) ;
408#else
409 c2pstr( (char*)ptitle ) ;
410#endif
411 SetWTitle( inWindowRef , ptitle ) ;
412}
413
414void UMAGetWTitleC( WindowRef inWindowRef , char *title )
415{
416 GetWTitle( inWindowRef , (unsigned char*)title ) ;
417#if TARGET_CARBON
418 p2cstrcpy( title, (unsigned char *)title ) ;
419#else
420 p2cstr( (unsigned char*)title ) ;
421#endif
422}
423
424// appearance additions
425
426void UMAActivateControl( ControlHandle inControl )
427{
428 // we have to add the control after again to the update rgn
429 // otherwise updates get lost
430 if ( !IsControlActive( inControl ) )
431 {
432 bool visible = IsControlVisible( inControl ) ;
433 if ( visible )
434 SetControlVisibility( inControl , false , false ) ;
435 ::ActivateControl( inControl ) ;
436 if ( visible ) {
437 SetControlVisibility( inControl , true , false ) ;
438 Rect ctrlBounds ;
439 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
440 }
441 }
442}
443
444void UMADrawControl( ControlHandle inControl )
445{
446 WindowRef theWindow = GetControlOwner(inControl) ;
447 RgnHandle updateRgn = NewRgn() ;
448 GetWindowUpdateRgn( theWindow , updateRgn ) ;
449 Point zero = { 0 , 0 } ;
450 LocalToGlobal( &zero ) ;
451 OffsetRgn( updateRgn , -zero.h , -zero.v ) ;
452 ::DrawControlInCurrentPort( inControl ) ;
453 InvalWindowRgn( theWindow, updateRgn) ;
454 DisposeRgn( updateRgn ) ;
455}
456
457void UMAMoveControl( ControlHandle inControl , short x , short y )
458{
459 bool visible = IsControlVisible( inControl ) ;
460 if ( visible ) {
461 SetControlVisibility( inControl , false , false ) ;
462 Rect ctrlBounds ;
463 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
464 }
465 ::MoveControl( inControl , x , y ) ;
466 if ( visible ) {
467 SetControlVisibility( inControl , true , false ) ;
468 Rect ctrlBounds ;
469 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
470 }
471}
472
473void UMASizeControl( ControlHandle inControl , short x , short y )
474{
475 bool visible = IsControlVisible( inControl ) ;
476 if ( visible ) {
477 SetControlVisibility( inControl , false , false ) ;
478 Rect ctrlBounds ;
479 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
480 }
481 ::SizeControl( inControl , x , y ) ;
482 if ( visible ) {
483 SetControlVisibility( inControl , true , false ) ;
484 Rect ctrlBounds ;
485 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
486 }
487}
488
489void UMADeactivateControl( ControlHandle inControl )
490{
491 // we have to add the control after again to the update rgn
492 // otherwise updates get lost
493 bool visible = IsControlVisible( inControl ) ;
494 if ( visible )
495 SetControlVisibility( inControl , false , false ) ;
496 ::DeactivateControl( inControl ) ;
497 if ( visible ) {
498 SetControlVisibility( inControl , true , false ) ;
499 Rect ctrlBounds ;
500 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
501 }
502}
503// shows the control and adds the region to the update region
504void UMAShowControl (ControlHandle inControl)
505{
506 SetControlVisibility( inControl , true , false ) ;
507 Rect ctrlBounds ;
508 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
509}
510
511// shows the control and adds the region to the update region
512void UMAHideControl (ControlHandle inControl)
513{
514 SetControlVisibility( inControl , false , false ) ;
515 Rect ctrlBounds ;
516 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
517}
518// keyboard focus
519OSErr UMASetKeyboardFocus (WindowPtr inWindow,
520 ControlHandle inControl,
521 ControlFocusPart inPart)
522{
523 OSErr err = noErr;
524 GrafPtr port ;
525 GetPort( &port ) ;
526
527 SetPortWindowPort( inWindow ) ;
528
529 err = SetKeyboardFocus( inWindow , inControl , inPart ) ;
530 SetPort( port ) ;
531 return err ;
532}
533
534
535
536
537// events
538void UMAUpdateControls( WindowPtr inWindow , RgnHandle inRgn )
539{
540 RgnHandle updateRgn = NewRgn() ;
541 GetWindowUpdateRgn( inWindow , updateRgn ) ;
542
543 Point zero = { 0 , 0 } ;
544 LocalToGlobal( &zero ) ;
545 OffsetRgn( updateRgn , -zero.h , -zero.v ) ;
546
547 UpdateControls( inWindow , inRgn ) ;
548 InvalWindowRgn( inWindow, updateRgn) ;
549 DisposeRgn( updateRgn ) ;
550
551}
552
553bool UMAIsWindowFloating( WindowRef inWindow )
554{
555 WindowClass cl ;
556
557 GetWindowClass( inWindow , &cl ) ;
558 return cl == kFloatingWindowClass ;
559}
560
561bool UMAIsWindowModal( WindowRef inWindow )
562{
563 WindowClass cl ;
564
565 GetWindowClass( inWindow , &cl ) ;
566 return cl < kFloatingWindowClass ;
567}
568
569// others
570
571void UMAHighlightAndActivateWindow( WindowRef inWindowRef , bool inActivate )
572{
573 if ( inWindowRef )
574 {
575// bool isHighlighted = IsWindowHighlited( inWindowRef ) ;
576// if ( inActivate != isHightlited )
577 GrafPtr port ;
578 GetPort( &port ) ;
579 SetPortWindowPort( inWindowRef ) ;
580 HiliteWindow( inWindowRef , inActivate ) ;
581 ControlHandle control = NULL ;
582 ::GetRootControl( inWindowRef , & control ) ;
583 if ( control )
584 {
585 if ( inActivate )
586 UMAActivateControl( control ) ;
587 else
588 UMADeactivateControl( control ) ;
589 }
590 SetPort( port ) ;
591 }
592}
593OSStatus UMADrawThemePlacard( const Rect *inRect , ThemeDrawState inState )
594{
595 return ::DrawThemePlacard( inRect , inState ) ;
596}
597
598#if !TARGET_CARBON
599static OSStatus helpMenuStatus = noErr ;
600static MenuItemIndex firstCustomItemIndex = 0 ;
601#endif
602
603OSStatus UMAGetHelpMenu(
604 MenuRef * outHelpMenu,
605 MenuItemIndex * outFirstCustomItemIndex)
606{
607#if TARGET_CARBON
608 return HMGetHelpMenu( outHelpMenu , outFirstCustomItemIndex ) ;
609#else
610 MenuRef helpMenuHandle ;
611 helpMenuStatus = HMGetHelpMenuHandle( &helpMenuHandle ) ;
612 if ( firstCustomItemIndex == 0 && helpMenuStatus == noErr )
613 {
614 firstCustomItemIndex = CountMenuItems( helpMenuHandle ) + 1 ;
615 }
616 if ( outFirstCustomItemIndex )
617 {
618 *outFirstCustomItemIndex = firstCustomItemIndex ;
619 }
620 *outHelpMenu = helpMenuHandle ;
621 return helpMenuStatus ;
622#endif
623}
624
625wxMacPortStateHelper::wxMacPortStateHelper( GrafPtr newport)
626{
627 m_clip = NULL ;
628 Setup( newport ) ;
629}
630
631wxMacPortStateHelper::wxMacPortStateHelper()
632{
633 m_clip = NULL ;
634}
635
636void wxMacPortStateHelper::Setup( GrafPtr newport )
637{
638 GetPort( &m_oldPort ) ;
639 SetPort( newport ) ;
640 wxASSERT_MSG( m_clip == NULL , "Cannot call setup twice" ) ;
641 m_clip = NewRgn() ;
642 GetClip( m_clip );
643 m_textFont = GetPortTextFont( (CGrafPtr) newport);
644 m_textSize = GetPortTextSize( (CGrafPtr) newport);
645 m_textStyle = GetPortTextFace( (CGrafPtr) newport);
646 m_textMode = GetPortTextMode( (CGrafPtr) newport);
647 GetThemeDrawingState( &m_drawingState ) ;
648 m_currentPort = newport ;
649}
650void wxMacPortStateHelper::Clear()
651{
652 if ( m_clip )
653 {
654 DisposeRgn( m_clip ) ;
655 DisposeThemeDrawingState( m_drawingState ) ;
656 m_clip = NULL ;
657 }
658}
659
660wxMacPortStateHelper::~wxMacPortStateHelper()
661{
662 if ( m_clip )
663 {
664 SetPort( m_currentPort ) ;
665 SetClip( m_clip ) ;
666 DisposeRgn( m_clip ) ;
667 TextFont( m_textFont );
668 TextSize( m_textSize );
669 TextFace( m_textStyle );
670 TextMode( m_textMode );
671 SetThemeDrawingState( m_drawingState , true ) ;
672 SetPort( m_oldPort ) ;
673 }
674}
675