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