]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/mac/carbon/uma.cpp
Various fixes for Textctrl and Popup Menus.
[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# 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
27static bool sUMAHasAppearance = false ;
28static long sUMAAppearanceVersion = 0 ;
29static bool sUMAHasAquaLayout = false ;
30static bool sUMASystemInitialized = false ;
31
32extern int gAGABackgroundColor ;
33bool UMAHasAppearance() { return sUMAHasAppearance ; }
34long UMAGetAppearanceVersion() { return sUMAAppearanceVersion ; }
35
36static bool sUMAHasWindowManager = false ;
37static long sUMAWindowManagerAttr = 0 ;
38
39bool UMAHasWindowManager() { return sUMAHasWindowManager ; }
40long UMAGetWindowManagerAttr() { return sUMAWindowManagerAttr ; }
41bool UMAHasAquaLayout() { return sUMAHasAquaLayout ; }
42bool UMASystemIsInitialized() { return sUMASystemInitialized ; }
43
44void 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}
58void 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/*
128Boolean CanUseATSUI()
129 {
130 long result;
131 OSErr err = Gestalt(gestaltATSUVersion, &result);
132 return (err == noErr);
133 }
134*/
135// process manager
136long 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
153bool UMAGetProcessModeDoesActivateOnFGSwitch()
154{
155 return UMAGetProcessMode() & modeDoesActivateOnFGSwitch ;
156}
157
158// menu manager
159
160void 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
190UInt32 UMAMenuEvent( EventRecord *inEvent )
191{
192 return MenuEvent( inEvent ) ;
193}
194
195void UMAEnableMenuItem( MenuRef inMenu , MenuItemIndex inItem )
196{
197 EnableMenuItem( inMenu , inItem ) ;
198}
199
200void UMADisableMenuItem( MenuRef inMenu , MenuItemIndex inItem )
201{
202 DisableMenuItem( inMenu , inItem ) ;
203}
204
205void 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
223void 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
241void 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
255void 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
271int gPrOpenCounter = 0 ;
272
273OSStatus 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
301OSStatus 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
333pascal QDGlobalsPtr GetQDGlobalsPtr (void) ;
334pascal QDGlobalsPtr GetQDGlobalsPtr (void)
335{
336 return QDGlobalsPtr (* (Ptr*) LMGetCurrentA5 ( ) - 0xCA);
337}
338
339#endif
340
341void 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
364void 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
376GrafPtr 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
386void UMADisposeWindow( WindowRef inWindowRef )
387{
388 wxASSERT( inWindowRef != NULL ) ;
389 DisposeWindow( inWindowRef ) ;
390}
391
392void 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
405void 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
417void 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
435void 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
448void 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
464void 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
480void 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
495void 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
503void UMAHideControl (ControlHandle inControl)
504{
505 SetControlVisibility( inControl , false , false ) ;
506 Rect ctrlBounds ;
507 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
508}
509// keyboard focus
510OSErr 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
529void 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
544bool UMAIsWindowFloating( WindowRef inWindow )
545{
546 WindowClass cl ;
547
548 GetWindowClass( inWindow , &cl ) ;
549 return cl == kFloatingWindowClass ;
550}
551
552bool UMAIsWindowModal( WindowRef inWindow )
553{
554 WindowClass cl ;
555
556 GetWindowClass( inWindow , &cl ) ;
557 return cl < kFloatingWindowClass ;
558}
559
560// others
561
562void 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}
584OSStatus UMADrawThemePlacard( const Rect *inRect , ThemeDrawState inState )
585{
586 return ::DrawThemePlacard( inRect , inState ) ;
587}
588
589#if !TARGET_CARBON
590static OSStatus helpMenuStatus = noErr ;
591static MenuItemIndex firstCustomItemIndex = 0 ;
592#endif
593
594OSStatus 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
616wxMacPortStateHelper::wxMacPortStateHelper( GrafPtr newport)
617{
618 m_clip = NULL ;
619 Setup( newport ) ;
620}
621
622wxMacPortStateHelper::wxMacPortStateHelper()
623{
624 m_clip = NULL ;
625}
626
627void 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}
641void wxMacPortStateHelper::Clear()
642{
643 if ( m_clip )
644 {
645 DisposeRgn( m_clip ) ;
646 DisposeThemeDrawingState( m_drawingState ) ;
647 m_clip = NULL ;
648 }
649}
650
651wxMacPortStateHelper::~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