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