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