]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/mac/carbon/uma.cpp
started macosx compliant implementation
[wxWidgets.git] / src / mac / carbon / 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#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
18static bool sUMAHasAppearance = false ;
19static long sUMAAppearanceVersion = 0 ;
20extern int gAGABackgroundColor ;
21bool UMAHasAppearance() { return sUMAHasAppearance ; }
22long UMAGetAppearanceVersion() { return sUMAAppearanceVersion ; }
23
24static bool sUMAHasWindowManager = false ;
25static long sUMAWindowManagerAttr = 0 ;
26
27bool UMAHasWindowManager() { return sUMAHasWindowManager ; }
28long UMAGetWindowManagerAttr() { return sUMAWindowManagerAttr ; }
29
30void 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}
44void 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
110long 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
127bool UMAGetProcessModeDoesActivateOnFGSwitch()
128{
129 return UMAGetProcessMode() & modeDoesActivateOnFGSwitch ;
130}
131
132// menu manager
133
134void 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
162UInt32 UMAMenuEvent( EventRecord *inEvent )
163{
164 return MenuEvent( inEvent ) ;
165}
166
167void UMAEnableMenuItem( MenuRef inMenu , MenuItemIndex inItem )
168{
169 EnableMenuItem( inMenu , inItem ) ;
170}
171
172void UMADisableMenuItem( MenuRef inMenu , MenuItemIndex inItem )
173{
174 DisableMenuItem( inMenu , inItem ) ;
175}
176
177void 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
195void 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
213void 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
227void 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
243int gPrOpenCounter = 0 ;
244
245#if TARGET_CARBON && PM_USE_SESSION_APIS
246OSStatus UMAPrOpen(PMPrintSession *macPrintSession)
247#else
248OSStatus 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
278OSStatus UMAPrClose(PMPrintSession *macPrintSession)
279#else
280OSStatus 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
313pascal QDGlobalsPtr GetQDGlobalsPtr (void) ;
314pascal QDGlobalsPtr GetQDGlobalsPtr (void)
315{
316 return QDGlobalsPtr (* (Ptr*) LMGetCurrentA5 ( ) - 0xCA);
317}
318
319#endif
320
321void 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
344void 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
356GrafPtr 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
366void UMADisposeWindow( WindowRef inWindowRef )
367{
368 wxASSERT( inWindowRef != NULL ) ;
369 DisposeWindow( inWindowRef ) ;
370}
371
372void 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
385void 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
397void 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
415void 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
428void 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
444void 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
460void 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
475void 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
483void UMAHideControl (ControlHandle inControl)
484{
485 SetControlVisibility( inControl , false , false ) ;
486 Rect ctrlBounds ;
487 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
488}
489// keyboard focus
490OSErr 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 SetOrigin( 0 , 0 ) ;
501 err = SetKeyboardFocus( inWindow , inControl , inPart ) ;
502 SetPort( port ) ;
503 return err ;
504}
505
506
507
508
509// events
510void UMAUpdateControls( WindowPtr inWindow , RgnHandle inRgn )
511{
512 RgnHandle updateRgn = NewRgn() ;
513 GetWindowUpdateRgn( inWindow , updateRgn ) ;
514
515 Point zero = { 0 , 0 } ;
516 LocalToGlobal( &zero ) ;
517 OffsetRgn( updateRgn , -zero.h , -zero.v ) ;
518
519 UpdateControls( inWindow , inRgn ) ;
520 InvalWindowRgn( inWindow, updateRgn) ;
521 DisposeRgn( updateRgn ) ;
522
523}
524
525bool UMAIsWindowFloating( WindowRef inWindow )
526{
527 WindowClass cl ;
528
529 GetWindowClass( inWindow , &cl ) ;
530 return cl == kFloatingWindowClass ;
531}
532
533bool UMAIsWindowModal( WindowRef inWindow )
534{
535 WindowClass cl ;
536
537 GetWindowClass( inWindow , &cl ) ;
538 return cl < kFloatingWindowClass ;
539}
540
541// others
542
543void UMAHighlightAndActivateWindow( WindowRef inWindowRef , bool inActivate )
544{
545 if ( inWindowRef )
546 {
547// bool isHighlighted = IsWindowHighlited( inWindowRef ) ;
548// if ( inActivate != isHightlited )
549 GrafPtr port ;
550 GetPort( &port ) ;
551 SetPortWindowPort( inWindowRef ) ;
552 SetOrigin( 0 , 0 ) ;
553 HiliteWindow( inWindowRef , inActivate ) ;
554 ControlHandle control = NULL ;
555 ::GetRootControl( inWindowRef , & control ) ;
556 if ( control )
557 {
558 if ( inActivate )
559 UMAActivateControl( control ) ;
560 else
561 UMADeactivateControl( control ) ;
562 }
563 SetPort( port ) ;
564 }
565}
566OSStatus UMADrawThemePlacard( const Rect *inRect , ThemeDrawState inState )
567{
568 return ::DrawThemePlacard( inRect , inState ) ;
569}
570
571static OSStatus helpMenuStatus = noErr ;
572static MenuRef helpMenuHandle = NULL ;
573static MenuItemIndex firstCustomItemIndex = 0 ;
574
575OSStatus UMAGetHelpMenu(
576 MenuRef * outHelpMenu,
577 MenuItemIndex * outFirstCustomItemIndex)
578{
579#if TARGET_CARBON
580 return HMGetHelpMenu( outHelpMenu , outFirstCustomItemIndex ) ;
581#else
582 if ( helpMenuHandle == NULL )
583 {
584 helpMenuStatus = HMGetHelpMenuHandle( &helpMenuHandle ) ;
585 if ( helpMenuStatus == noErr )
586 {
587 firstCustomItemIndex = CountMenuItems( helpMenuHandle ) + 1 ;
588 }
589 }
590 if ( outFirstCustomItemIndex )
591 {
592 *outFirstCustomItemIndex = firstCustomItemIndex ;
593 }
594 *outHelpMenu = helpMenuHandle ;
595 return helpMenuStatus ;
596#endif
597}