]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/uma.cpp
changed layout hints to proper determining aqua layout presence before
[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 #if !TARGET_CARBON
146 long size = GetHandleSize( (Handle) menu ) ;
147 const long headersize = 14 ;
148 int oldlen = (**menu).menuData[0] + 1;
149 int newlen = title[0] + 1 ;
150
151 if ( oldlen < newlen )
152 {
153 // enlarge before adjusting
154 SetHandleSize( (Handle) menu , size + (newlen - oldlen ) );
155 }
156
157 if ( oldlen != newlen )
158 memmove( (char*) (**menu).menuData + newlen , (char*) (**menu).menuData + oldlen , size - headersize - oldlen ) ;
159
160 memcpy( (char*) (**menu).menuData , title , newlen ) ;
161 if ( oldlen > newlen )
162 {
163 // shrink after
164 SetHandleSize( (Handle) menu , size + (newlen - oldlen ) ) ;
165 }
166 #else
167 SetMenuTitle( menu , title ) ;
168 #endif
169 }
170
171 UInt32 UMAMenuEvent( EventRecord *inEvent )
172 {
173 return MenuEvent( inEvent ) ;
174 }
175
176 void UMAEnableMenuItem( MenuRef inMenu , MenuItemIndex inItem )
177 {
178 EnableMenuItem( inMenu , inItem ) ;
179 }
180
181 void UMADisableMenuItem( MenuRef inMenu , MenuItemIndex inItem )
182 {
183 DisableMenuItem( inMenu , inItem ) ;
184 }
185
186 void UMAAppendSubMenuItem( MenuRef menu , StringPtr l , SInt16 id )
187 {
188 Str255 label ;
189 memcpy( label , l , l[0]+1 ) ;
190 // hardcoded adding of the submenu combination for mac
191
192 int theEnd = label[0] + 1;
193 if (theEnd > 251)
194 theEnd = 251; // mac allows only 255 characters
195 label[theEnd++] = '/';
196 label[theEnd++] = hMenuCmd;
197 label[theEnd++] = '!';
198 label[theEnd++] = id ;
199 label[theEnd] = 0x00;
200 label[0] = theEnd;
201 MacAppendMenu(menu, label);
202 }
203
204 void UMAInsertSubMenuItem( MenuRef menu , StringPtr l , MenuItemIndex item , SInt16 id )
205 {
206 Str255 label ;
207 memcpy( label , l , l[0]+1 ) ;
208 // hardcoded adding of the submenu combination for mac
209
210 int theEnd = label[0] + 1;
211 if (theEnd > 251)
212 theEnd = 251; // mac allows only 255 characters
213 label[theEnd++] = '/';
214 label[theEnd++] = hMenuCmd;
215 label[theEnd++] = '!';
216 label[theEnd++] = id;
217 label[theEnd] = 0x00;
218 label[0] = theEnd;
219 MacInsertMenuItem(menu, label , item);
220 }
221
222 void UMAAppendMenuItem( MenuRef menu , StringPtr l , SInt16 key, UInt8 modifiers )
223 {
224 Str255 label ;
225 memcpy( label , l , l[0]+1 ) ;
226 if ( key )
227 {
228 int pos = label[0] ;
229 label[++pos] = '/';
230 label[++pos] = toupper( key );
231 label[0] = pos ;
232 }
233 MacAppendMenu( menu , label ) ;
234 }
235
236 void UMAInsertMenuItem( MenuRef menu , StringPtr l , MenuItemIndex item , SInt16 key, UInt8 modifiers )
237 {
238 Str255 label ;
239 memcpy( label , l , l[0]+1 ) ;
240 if ( key )
241 {
242 int pos = label[0] ;
243 label[++pos] = '/';
244 label[++pos] = toupper( key );
245 label[0] = pos ;
246 }
247 MacInsertMenuItem( menu , label , item) ;
248 }
249
250 // quickdraw
251
252 int gPrOpenCounter = 0 ;
253
254 #if TARGET_CARBON && PM_USE_SESSION_APIS
255 OSStatus UMAPrOpen(PMPrintSession *macPrintSession)
256 #else
257 OSStatus UMAPrOpen()
258 #endif
259 {
260 #if !TARGET_CARBON
261 OSErr err = noErr ;
262 ++gPrOpenCounter ;
263 if ( gPrOpenCounter == 1 )
264 {
265 PrOpen() ;
266 err = PrError() ;
267 wxASSERT( err == noErr ) ;
268 }
269 return err ;
270 #else
271 OSStatus err = noErr ;
272 ++gPrOpenCounter ;
273 if ( gPrOpenCounter == 1 )
274 {
275 #if PM_USE_SESSION_APIS
276 err = PMCreateSession(macPrintSession) ;
277 #else
278 err = PMBegin() ;
279 #endif
280 wxASSERT( err == noErr ) ;
281 }
282 return err ;
283 #endif
284 }
285
286 #if TARGET_CARBON && PM_USE_SESSION_APIS
287 OSStatus UMAPrClose(PMPrintSession *macPrintSession)
288 #else
289 OSStatus UMAPrClose()
290 #endif
291 {
292 #if !TARGET_CARBON
293 OSErr err = noErr ;
294 wxASSERT( gPrOpenCounter >= 1 ) ;
295 if ( gPrOpenCounter == 1 )
296 {
297 PrClose() ;
298 err = PrError() ;
299 wxASSERT( err == noErr ) ;
300 }
301 --gPrOpenCounter ;
302 return err ;
303 #else
304 OSStatus err = noErr ;
305 wxASSERT( gPrOpenCounter >= 1 ) ;
306 if ( gPrOpenCounter == 1 )
307 {
308 #if PM_USE_SESSION_APIS
309 err = PMRelease(*macPrintSession) ;
310 *macPrintSession = kPMNoReference;
311 #else
312 err = PMEnd() ;
313 #endif
314 }
315 --gPrOpenCounter ;
316 return err ;
317 #endif
318 }
319
320 #if !TARGET_CARBON
321
322 pascal QDGlobalsPtr GetQDGlobalsPtr (void) ;
323 pascal QDGlobalsPtr GetQDGlobalsPtr (void)
324 {
325 return QDGlobalsPtr (* (Ptr*) LMGetCurrentA5 ( ) - 0xCA);
326 }
327
328 #endif
329
330 void UMAShowWatchCursor()
331 {
332 OSErr err = noErr;
333
334 CursHandle watchFob = GetCursor (watchCursor);
335
336 if (!watchFob)
337 err = nilHandleErr;
338 else
339 {
340 #if TARGET_CARBON
341 // Cursor preservedArrow;
342 // GetQDGlobalsArrow (&preservedArrow);
343 // SetQDGlobalsArrow (*watchFob);
344 // InitCursor ( );
345 // SetQDGlobalsArrow (&preservedArrow);
346 SetCursor (*watchFob);
347 #else
348 SetCursor (*watchFob);
349 #endif
350 }
351 }
352
353 void UMAShowArrowCursor()
354 {
355 #if TARGET_CARBON
356 Cursor arrow;
357 SetCursor (GetQDGlobalsArrow (&arrow));
358 #else
359 SetCursor (&(qd.arrow));
360 #endif
361 }
362
363 // window manager
364
365 GrafPtr UMAGetWindowPort( WindowRef inWindowRef )
366 {
367 wxASSERT( inWindowRef != NULL ) ;
368 #if TARGET_CARBON
369 return GetWindowPort( inWindowRef ) ;
370 #else
371 return (GrafPtr) inWindowRef ;
372 #endif
373 }
374
375 void UMADisposeWindow( WindowRef inWindowRef )
376 {
377 wxASSERT( inWindowRef != NULL ) ;
378 DisposeWindow( inWindowRef ) ;
379 }
380
381 void UMASetWTitleC( WindowRef inWindowRef , const char *title )
382 {
383 Str255 ptitle ;
384 strncpy( (char*)ptitle , title , 96 ) ;
385 ptitle[96] = 0 ;
386 #if TARGET_CARBON
387 c2pstrcpy( ptitle, (char *)ptitle ) ;
388 #else
389 c2pstr( (char*)ptitle ) ;
390 #endif
391 SetWTitle( inWindowRef , ptitle ) ;
392 }
393
394 void UMAGetWTitleC( WindowRef inWindowRef , char *title )
395 {
396 GetWTitle( inWindowRef , (unsigned char*)title ) ;
397 #if TARGET_CARBON
398 p2cstrcpy( title, (unsigned char *)title ) ;
399 #else
400 p2cstr( (unsigned char*)title ) ;
401 #endif
402 }
403
404 // appearance additions
405
406 void UMAActivateControl( ControlHandle inControl )
407 {
408 // we have to add the control after again to the update rgn
409 // otherwise updates get lost
410 if ( !IsControlActive( inControl ) )
411 {
412 bool visible = IsControlVisible( inControl ) ;
413 if ( visible )
414 SetControlVisibility( inControl , false , false ) ;
415 ::ActivateControl( inControl ) ;
416 if ( visible ) {
417 SetControlVisibility( inControl , true , false ) ;
418 Rect ctrlBounds ;
419 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
420 }
421 }
422 }
423
424 void UMADrawControl( ControlHandle inControl )
425 {
426 WindowRef theWindow = GetControlOwner(inControl) ;
427 RgnHandle updateRgn = NewRgn() ;
428 GetWindowUpdateRgn( theWindow , updateRgn ) ;
429 Point zero = { 0 , 0 } ;
430 LocalToGlobal( &zero ) ;
431 OffsetRgn( updateRgn , -zero.h , -zero.v ) ;
432 ::DrawControlInCurrentPort( inControl ) ;
433 InvalWindowRgn( theWindow, updateRgn) ;
434 DisposeRgn( updateRgn ) ;
435 }
436
437 void UMAMoveControl( ControlHandle inControl , short x , short y )
438 {
439 bool visible = IsControlVisible( inControl ) ;
440 if ( visible ) {
441 SetControlVisibility( inControl , false , false ) ;
442 Rect ctrlBounds ;
443 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
444 }
445 ::MoveControl( inControl , x , y ) ;
446 if ( visible ) {
447 SetControlVisibility( inControl , true , false ) ;
448 Rect ctrlBounds ;
449 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
450 }
451 }
452
453 void UMASizeControl( ControlHandle inControl , short x , short y )
454 {
455 bool visible = IsControlVisible( inControl ) ;
456 if ( visible ) {
457 SetControlVisibility( inControl , false , false ) ;
458 Rect ctrlBounds ;
459 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
460 }
461 ::SizeControl( inControl , x , y ) ;
462 if ( visible ) {
463 SetControlVisibility( inControl , true , false ) ;
464 Rect ctrlBounds ;
465 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
466 }
467 }
468
469 void UMADeactivateControl( ControlHandle inControl )
470 {
471 // we have to add the control after again to the update rgn
472 // otherwise updates get lost
473 bool visible = IsControlVisible( inControl ) ;
474 if ( visible )
475 SetControlVisibility( inControl , false , false ) ;
476 ::DeactivateControl( inControl ) ;
477 if ( visible ) {
478 SetControlVisibility( inControl , true , false ) ;
479 Rect ctrlBounds ;
480 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
481 }
482 }
483 // shows the control and adds the region to the update region
484 void UMAShowControl (ControlHandle inControl)
485 {
486 SetControlVisibility( inControl , true , false ) ;
487 Rect ctrlBounds ;
488 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
489 }
490
491 // shows the control and adds the region to the update region
492 void UMAHideControl (ControlHandle inControl)
493 {
494 SetControlVisibility( inControl , false , false ) ;
495 Rect ctrlBounds ;
496 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
497 }
498 // keyboard focus
499 OSErr UMASetKeyboardFocus (WindowPtr inWindow,
500 ControlHandle inControl,
501 ControlFocusPart inPart)
502 {
503 OSErr err = noErr;
504 GrafPtr port ;
505 GetPort( &port ) ;
506
507 SetPortWindowPort( inWindow ) ;
508
509 err = SetKeyboardFocus( inWindow , inControl , inPart ) ;
510 SetPort( port ) ;
511 return err ;
512 }
513
514
515
516
517 // events
518 void UMAUpdateControls( WindowPtr inWindow , RgnHandle inRgn )
519 {
520 RgnHandle updateRgn = NewRgn() ;
521 GetWindowUpdateRgn( inWindow , updateRgn ) ;
522
523 Point zero = { 0 , 0 } ;
524 LocalToGlobal( &zero ) ;
525 OffsetRgn( updateRgn , -zero.h , -zero.v ) ;
526
527 UpdateControls( inWindow , inRgn ) ;
528 InvalWindowRgn( inWindow, updateRgn) ;
529 DisposeRgn( updateRgn ) ;
530
531 }
532
533 bool UMAIsWindowFloating( WindowRef inWindow )
534 {
535 WindowClass cl ;
536
537 GetWindowClass( inWindow , &cl ) ;
538 return cl == kFloatingWindowClass ;
539 }
540
541 bool UMAIsWindowModal( WindowRef inWindow )
542 {
543 WindowClass cl ;
544
545 GetWindowClass( inWindow , &cl ) ;
546 return cl < kFloatingWindowClass ;
547 }
548
549 // others
550
551 void UMAHighlightAndActivateWindow( WindowRef inWindowRef , bool inActivate )
552 {
553 if ( inWindowRef )
554 {
555 // bool isHighlighted = IsWindowHighlited( inWindowRef ) ;
556 // if ( inActivate != isHightlited )
557 GrafPtr port ;
558 GetPort( &port ) ;
559 SetPortWindowPort( inWindowRef ) ;
560 HiliteWindow( inWindowRef , inActivate ) ;
561 ControlHandle control = NULL ;
562 ::GetRootControl( inWindowRef , & control ) ;
563 if ( control )
564 {
565 if ( inActivate )
566 UMAActivateControl( control ) ;
567 else
568 UMADeactivateControl( control ) ;
569 }
570 SetPort( port ) ;
571 }
572 }
573 OSStatus UMADrawThemePlacard( const Rect *inRect , ThemeDrawState inState )
574 {
575 return ::DrawThemePlacard( inRect , inState ) ;
576 }
577
578 static OSStatus helpMenuStatus = noErr ;
579 static MenuRef helpMenuHandle = NULL ;
580 static MenuItemIndex firstCustomItemIndex = 0 ;
581
582 OSStatus UMAGetHelpMenu(
583 MenuRef * outHelpMenu,
584 MenuItemIndex * outFirstCustomItemIndex)
585 {
586 #if TARGET_CARBON
587 return HMGetHelpMenu( outHelpMenu , outFirstCustomItemIndex ) ;
588 #else
589 if ( helpMenuHandle == NULL )
590 {
591 helpMenuStatus = HMGetHelpMenuHandle( &helpMenuHandle ) ;
592 if ( helpMenuStatus == noErr )
593 {
594 firstCustomItemIndex = CountMenuItems( helpMenuHandle ) + 1 ;
595 }
596 }
597 if ( outFirstCustomItemIndex )
598 {
599 *outFirstCustomItemIndex = firstCustomItemIndex ;
600 }
601 *outHelpMenu = helpMenuHandle ;
602 return helpMenuStatus ;
603 #endif
604 }