]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/uma.cpp
adding wxPartRegion and catching errors
[wxWidgets.git] / src / mac / carbon / uma.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mac/carbon/uma.cpp
3 // Purpose: UMA support
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Stefan Csomor
9 // Licence: The wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/wxprec.h"
13
14 #include "wx/mac/uma.h"
15
16 #if wxUSE_GUI
17
18 #include "wx/toplevel.h"
19 #include "wx/dc.h"
20
21 #include "wx/mac/uma.h"
22
23 // since we have decided that we only support 8.6 upwards we are
24 // checking for these minimum requirements in the startup code of
25 // the application so all wxWidgets code can safely assume that appearance 1.1
26 // windows manager, control manager, navigation services etc. are
27 // present
28
29 static SInt32 sUMASystemVersion = 0 ;
30
31 long UMAGetSystemVersion() { return sUMASystemVersion ; }
32
33 void UMACleanupToolbox()
34 {
35 }
36
37 void UMAInitToolbox( UInt16 WXUNUSED(inMoreMastersCalls),
38 bool WXUNUSED(isEmbedded) )
39 {
40 if ( Gestalt(gestaltSystemVersion, &sUMASystemVersion) != noErr)
41 sUMASystemVersion = 0x0000 ;
42
43 #ifndef __LP64__
44 {
45 FontFamilyID fontId ;
46 Str255 fontName ;
47 SInt16 fontSize ;
48 Style fontStyle ;
49
50 GetThemeFont(kThemeSmallSystemFont , GetApplicationScript() , fontName , &fontSize , &fontStyle ) ;
51 GetFNum( fontName, &fontId );
52
53 TXNMacOSPreferredFontDescription fontDescriptions[] =
54 {
55 { fontId , (fontSize << 16) , kTXNDefaultFontStyle, kTXNSystemDefaultEncoding }
56 } ;
57 int noOfFontDescriptions = sizeof( fontDescriptions ) / sizeof(TXNMacOSPreferredFontDescription) ;
58
59 OptionBits options = 0 ;
60
61 if ( UMAGetSystemVersion() < 0x1000 )
62 options |= kTXNAlwaysUseQuickDrawTextMask ;
63
64 TXNInitTextension( fontDescriptions, noOfFontDescriptions, options );
65 }
66 #endif
67
68 UMASetSystemIsInitialized( true );
69 }
70
71 // process manager
72 long UMAGetProcessMode()
73 {
74 OSErr err ;
75 ProcessInfoRec processinfo;
76 ProcessSerialNumber procno ;
77
78 procno.highLongOfPSN = 0 ;
79 procno.lowLongOfPSN = kCurrentProcess ;
80 processinfo.processInfoLength = sizeof(ProcessInfoRec);
81 processinfo.processName = NULL;
82 #ifndef __LP64__
83 processinfo.processAppSpec = NULL;
84 #endif
85
86 err = ::GetProcessInformation( &procno , &processinfo ) ;
87 wxASSERT( err == noErr ) ;
88
89 return processinfo.processMode ;
90 }
91
92 bool UMAGetProcessModeDoesActivateOnFGSwitch()
93 {
94 return UMAGetProcessMode() & modeDoesActivateOnFGSwitch ;
95 }
96
97 // menu manager
98
99 #if wxMAC_USE_COCOA == 0
100
101 MenuRef UMANewMenu( SInt16 id , const wxString& title , wxFontEncoding encoding )
102 {
103 wxString str = wxStripMenuCodes( title ) ;
104 MenuRef menu ;
105
106 CreateNewMenu( id , 0 , &menu ) ;
107 SetMenuTitleWithCFString( menu , wxMacCFStringHolder(str , encoding ) ) ;
108
109 return menu ;
110 }
111
112 void UMASetMenuTitle( MenuRef menu , const wxString& title , wxFontEncoding encoding )
113 {
114 wxString str = wxStripMenuCodes( title ) ;
115
116 SetMenuTitleWithCFString( menu , wxMacCFStringHolder(str , encoding) ) ;
117 }
118
119 void UMASetMenuItemText( MenuRef menu, MenuItemIndex item, const wxString& title, wxFontEncoding encoding )
120 {
121 // we don't strip the accels here anymore, must be done before
122 wxString str = title ;
123
124 SetMenuItemTextWithCFString( menu , item , wxMacCFStringHolder(str , encoding) ) ;
125 }
126
127 UInt32 UMAMenuEvent( EventRecord *inEvent )
128 {
129 return MenuEvent( inEvent ) ;
130 }
131
132 void UMAEnableMenuItem( MenuRef inMenu , MenuItemIndex inItem , bool enable)
133 {
134 if ( enable )
135 EnableMenuItem( inMenu , inItem ) ;
136 else
137 DisableMenuItem( inMenu , inItem ) ;
138 }
139
140 void UMAAppendSubMenuItem( MenuRef menu , const wxString& title, wxFontEncoding encoding , SInt16 id )
141 {
142 AppendMenuItemTextWithCFString( menu,
143 CFSTR("A"), 0, 0,NULL);
144 UMASetMenuItemText( menu, (SInt16) ::CountMenuItems(menu), title , encoding );
145 SetMenuItemHierarchicalID( menu , CountMenuItems( menu ) , id ) ;
146 }
147
148 void UMAInsertSubMenuItem( MenuRef menu , const wxString& title, wxFontEncoding encoding , MenuItemIndex item , SInt16 id )
149 {
150 InsertMenuItemTextWithCFString( menu,
151 CFSTR("A"), item, 0, 0);
152
153 UMASetMenuItemText( menu, item+1, title , encoding );
154 SetMenuItemHierarchicalID( menu , item+1 , id ) ;
155 }
156
157 void UMASetMenuItemShortcut( MenuRef menu , MenuItemIndex item , wxAcceleratorEntry *entry )
158 {
159 if ( !entry )
160 return ;
161
162 UInt8 modifiers = 0 ;
163 SInt16 key = entry->GetKeyCode() ;
164 if ( key )
165 {
166 bool explicitCommandKey = (entry->GetFlags() & wxACCEL_CTRL);
167
168 if (entry->GetFlags() & wxACCEL_ALT)
169 modifiers |= kMenuOptionModifier ;
170
171 if (entry->GetFlags() & wxACCEL_SHIFT)
172 modifiers |= kMenuShiftModifier ;
173
174 SInt16 glyph = 0 ;
175 SInt16 macKey = key ;
176 if ( key >= WXK_F1 && key <= WXK_F15 )
177 {
178 if ( !explicitCommandKey )
179 modifiers |= kMenuNoCommandModifier ;
180
181 // for some reasons this must be 0 right now
182 // everything else leads to just the first function key item
183 // to be selected. Thanks to Ryan Wilcox for finding out.
184 macKey = 0 ;
185 glyph = kMenuF1Glyph + ( key - WXK_F1 ) ;
186 if ( key >= WXK_F13 )
187 glyph += 12 ;
188 }
189 else
190 {
191 switch ( key )
192 {
193 case WXK_BACK :
194 macKey = kBackspaceCharCode ;
195 glyph = kMenuDeleteLeftGlyph ;
196 break ;
197
198 case WXK_TAB :
199 macKey = kTabCharCode ;
200 glyph = kMenuTabRightGlyph ;
201 break ;
202
203 case kEnterCharCode :
204 macKey = kEnterCharCode ;
205 glyph = kMenuEnterGlyph ;
206 break ;
207
208 case WXK_RETURN :
209 macKey = kReturnCharCode ;
210 glyph = kMenuReturnGlyph ;
211 break ;
212
213 case WXK_ESCAPE :
214 macKey = kEscapeCharCode ;
215 glyph = kMenuEscapeGlyph ;
216 break ;
217
218 case WXK_SPACE :
219 macKey = ' ' ;
220 glyph = kMenuSpaceGlyph ;
221 break ;
222
223 case WXK_DELETE :
224 macKey = kDeleteCharCode ;
225 glyph = kMenuDeleteRightGlyph ;
226 break ;
227
228 case WXK_CLEAR :
229 macKey = kClearCharCode ;
230 glyph = kMenuClearGlyph ;
231 break ;
232
233 case WXK_PAGEUP :
234 macKey = kPageUpCharCode ;
235 glyph = kMenuPageUpGlyph ;
236 break ;
237
238 case WXK_PAGEDOWN :
239 macKey = kPageDownCharCode ;
240 glyph = kMenuPageDownGlyph ;
241 break ;
242
243 case WXK_LEFT :
244 macKey = kLeftArrowCharCode ;
245 glyph = kMenuLeftArrowGlyph ;
246 break ;
247
248 case WXK_UP :
249 macKey = kUpArrowCharCode ;
250 glyph = kMenuUpArrowGlyph ;
251 break ;
252
253 case WXK_RIGHT :
254 macKey = kRightArrowCharCode ;
255 glyph = kMenuRightArrowGlyph ;
256 break ;
257
258 case WXK_DOWN :
259 macKey = kDownArrowCharCode ;
260 glyph = kMenuDownArrowGlyph ;
261 break ;
262
263 case WXK_HOME :
264 macKey = kHomeCharCode ;
265 glyph = kMenuNorthwestArrowGlyph ;
266 break ;
267
268 case WXK_END :
269 macKey = kEndCharCode ;
270 glyph = kMenuSoutheastArrowGlyph ;
271 break ;
272 default :
273 macKey = toupper( key ) ;
274 break ;
275 }
276
277 // we now allow non command key shortcuts
278 // remove in case this gives problems
279 if ( !explicitCommandKey )
280 modifiers |= kMenuNoCommandModifier ;
281 }
282
283 // 1d and 1e have special meaning to SetItemCmd, so
284 // do not use for these character codes.
285 if (key != WXK_UP && key != WXK_RIGHT && key != WXK_DOWN && key != WXK_LEFT)
286 SetItemCmd( menu, item , macKey );
287
288 SetMenuItemModifiers( menu, item , modifiers ) ;
289
290 if ( glyph )
291 SetMenuItemKeyGlyph( menu, item , glyph ) ;
292 }
293 }
294
295 void UMAAppendMenuItem( MenuRef menu , const wxString& title, wxFontEncoding encoding , wxAcceleratorEntry *entry )
296 {
297 AppendMenuItemTextWithCFString( menu,
298 CFSTR("A"), 0, 0,NULL);
299 // don't attempt to interpret metacharacters like a '-' at the beginning (would become a separator otherwise)
300 ChangeMenuItemAttributes( menu , ::CountMenuItems(menu), kMenuItemAttrIgnoreMeta , 0 ) ;
301 UMASetMenuItemText(menu, (SInt16) ::CountMenuItems(menu), title , encoding );
302 UMASetMenuItemShortcut( menu , (SInt16) ::CountMenuItems(menu), entry ) ;
303 }
304
305 void UMAInsertMenuItem( MenuRef menu , const wxString& title, wxFontEncoding encoding , MenuItemIndex item , wxAcceleratorEntry *entry )
306 {
307 InsertMenuItemTextWithCFString( menu,
308 CFSTR("A"), item, 0, 0);
309
310 // don't attempt to interpret metacharacters like a '-' at the beginning (would become a separator otherwise)
311 ChangeMenuItemAttributes( menu , item+1, kMenuItemAttrIgnoreMeta , 0 ) ;
312 UMASetMenuItemText(menu, item+1 , title , encoding );
313 UMASetMenuItemShortcut( menu , item+1 , entry ) ;
314 }
315
316 #endif
317
318 #if wxMAC_USE_COCOA == 0
319
320 void UMAShowWatchCursor()
321 {
322 SetThemeCursor(kThemeWatchCursor);
323 }
324
325 void UMAShowArrowCursor()
326 {
327 SetThemeCursor(kThemeArrowCursor);
328 }
329
330 static OSStatus UMAGetHelpMenu(
331 MenuRef * outHelpMenu,
332 MenuItemIndex * outFirstCustomItemIndex,
333 bool allowHelpMenuCreation);
334
335 static OSStatus UMAGetHelpMenu(
336 MenuRef * outHelpMenu,
337 MenuItemIndex * outFirstCustomItemIndex,
338 bool allowHelpMenuCreation)
339 {
340 static bool s_createdHelpMenu = false ;
341
342 if ( !s_createdHelpMenu && !allowHelpMenuCreation )
343 {
344 return paramErr ;
345 }
346
347 OSStatus status = HMGetHelpMenu( outHelpMenu , outFirstCustomItemIndex ) ;
348 s_createdHelpMenu = ( status == noErr ) ;
349 return status ;
350 }
351
352 OSStatus UMAGetHelpMenu(
353 MenuRef * outHelpMenu,
354 MenuItemIndex * outFirstCustomItemIndex)
355 {
356 return UMAGetHelpMenu( outHelpMenu , outFirstCustomItemIndex , true );
357 }
358
359 OSStatus UMAGetHelpMenuDontCreate(
360 MenuRef * outHelpMenu,
361 MenuItemIndex * outFirstCustomItemIndex)
362 {
363 return UMAGetHelpMenu( outHelpMenu , outFirstCustomItemIndex , false );
364 }
365
366 #endif
367
368 // window manager
369
370 #if wxMAC_USE_QUICKDRAW
371
372 GrafPtr UMAGetWindowPort( WindowRef inWindowRef )
373 {
374 wxASSERT( inWindowRef != NULL ) ;
375
376 return (GrafPtr) GetWindowPort( inWindowRef ) ;
377 }
378
379 void UMADisposeWindow( WindowRef inWindowRef )
380 {
381 wxASSERT( inWindowRef != NULL ) ;
382
383 DisposeWindow( inWindowRef ) ;
384 }
385
386 void UMASetWTitle( WindowRef inWindowRef , const wxString& title , wxFontEncoding encoding )
387 {
388 SetWindowTitleWithCFString( inWindowRef , wxMacCFStringHolder(title , encoding) ) ;
389 }
390
391 // appearance additions
392
393 void UMASetControlTitle( ControlRef inControl , const wxString& title , wxFontEncoding encoding )
394 {
395 SetControlTitleWithCFString( inControl , wxMacCFStringHolder(title , encoding) ) ;
396 }
397
398 void UMAActivateControl( ControlRef inControl )
399 {
400 ::ActivateControl( inControl ) ;
401 }
402
403 void UMAMoveControl( ControlRef inControl , short x , short y )
404 {
405 ::MoveControl( inControl , x , y ) ;
406 }
407
408 void UMASizeControl( ControlRef inControl , short x , short y )
409 {
410 ::SizeControl( inControl , x , y ) ;
411 }
412
413 void UMADeactivateControl( ControlRef inControl )
414 {
415 ::DeactivateControl( inControl ) ;
416 }
417
418 // shows the control and adds the region to the update region
419 void UMAShowControl( ControlRef inControl )
420 {
421 SetControlVisibility( inControl , true , false ) ;
422 HIViewSetNeedsDisplay( inControl, true );
423 }
424
425 // hides the control and adds the region to the update region
426 void UMAHideControl( ControlRef inControl )
427 {
428 SetControlVisibility( inControl , false , false ) ;
429 HIViewSetNeedsDisplay( inControl, true );
430 }
431
432 // keyboard focus
433 OSErr UMASetKeyboardFocus( WindowPtr inWindow,
434 ControlRef inControl,
435 ControlFocusPart inPart )
436 {
437 OSErr err = noErr;
438 #ifndef __LP64__
439 GrafPtr port ;
440
441 GetPort( &port ) ;
442 SetPortWindowPort( inWindow ) ;
443 #endif
444
445 err = SetKeyboardFocus( inWindow , inControl , inPart ) ;
446 #ifndef __LP64__
447 SetPort( port ) ;
448 #endif
449
450 return err ;
451 }
452
453 bool UMAIsWindowFloating( WindowRef inWindow )
454 {
455 WindowClass cl ;
456
457 GetWindowClass( inWindow , &cl ) ;
458 return cl == kFloatingWindowClass ;
459 }
460
461 bool UMAIsWindowModal( WindowRef inWindow )
462 {
463 WindowClass cl ;
464
465 GetWindowClass( inWindow , &cl ) ;
466 return cl < kFloatingWindowClass ;
467 }
468
469 // others
470
471 void UMAHighlightAndActivateWindow( WindowRef inWindowRef , bool inActivate )
472 {
473 if ( inWindowRef )
474 {
475 // bool isHighlighted = IsWindowHighlited( inWindowRef ) ;
476 // if ( inActivate != isHighlighted )
477 #ifndef __LP64__
478 GrafPtr port ;
479 GetPort( &port ) ;
480 SetPortWindowPort( inWindowRef ) ;
481 #endif
482 HiliteWindow( inWindowRef , inActivate ) ;
483 ControlRef control = NULL ;
484 ::GetRootControl( inWindowRef , &control ) ;
485 if ( control )
486 {
487 if ( inActivate )
488 UMAActivateControl( control ) ;
489 else
490 UMADeactivateControl( control ) ;
491 }
492 #ifndef __LP64__
493 SetPort( port ) ;
494 #endif
495 }
496 }
497
498 OSStatus UMADrawThemePlacard( const Rect *inRect , ThemeDrawState inState )
499 {
500 #ifndef __LP64__
501 return ::DrawThemePlacard( inRect , inState ) ;
502 #else
503 return noErr;
504 #endif
505 }
506
507 Rect * UMAGetControlBoundsInWindowCoords( ControlRef theControl, Rect *bounds )
508 {
509 GetControlBounds( theControl , bounds ) ;
510
511 WindowRef tlwref = GetControlOwner( theControl ) ;
512
513 wxTopLevelWindowMac* tlwwx = wxFindWinFromMacWindow( tlwref ) ;
514 if ( tlwwx != NULL )
515 {
516 ControlRef rootControl = tlwwx->GetPeer()->GetControlRef() ;
517 HIPoint hiPoint = CGPointMake( 0 , 0 ) ;
518 HIViewConvertPoint( &hiPoint , HIViewGetSuperview(theControl) , rootControl ) ;
519 OffsetRect( bounds , (short) hiPoint.x , (short) hiPoint.y ) ;
520 }
521
522 return bounds ;
523 }
524
525 #endif
526
527 #ifndef __LP64__
528
529 wxMacPortStateHelper::wxMacPortStateHelper( GrafPtr newport )
530 {
531 m_clip = NULL ;
532 Setup( newport ) ;
533 }
534
535 wxMacPortStateHelper::wxMacPortStateHelper()
536 {
537 m_clip = NULL ;
538 }
539
540 void wxMacPortStateHelper::Setup( GrafPtr newport )
541 {
542 GetPort( &m_oldPort ) ;
543 SetPort( newport ) ;
544 SetOrigin(0, 0);
545
546 wxASSERT_MSG( m_clip == NULL , wxT("Cannot call setup twice") ) ;
547 m_clip = NewRgn() ;
548 GetClip( m_clip );
549 m_textFont = GetPortTextFont( (CGrafPtr) newport );
550 m_textSize = GetPortTextSize( (CGrafPtr) newport );
551 m_textStyle = GetPortTextFace( (CGrafPtr) newport );
552 m_textMode = GetPortTextMode( (CGrafPtr) newport );
553 GetThemeDrawingState( &m_drawingState ) ;
554 m_currentPort = newport ;
555 }
556
557 void wxMacPortStateHelper::Clear()
558 {
559 if ( m_clip )
560 {
561 DisposeRgn( m_clip ) ;
562 DisposeThemeDrawingState( m_drawingState ) ;
563 m_clip = NULL ;
564 }
565 }
566
567 wxMacPortStateHelper::~wxMacPortStateHelper()
568 {
569 if ( m_clip )
570 {
571 SetPort( m_currentPort ) ;
572 SetClip( m_clip ) ;
573 DisposeRgn( m_clip ) ;
574 TextFont( m_textFont );
575 TextSize( m_textSize );
576 TextFace( m_textStyle );
577 TextMode( m_textMode );
578 SetThemeDrawingState( m_drawingState , true ) ;
579 SetPort( m_oldPort ) ;
580 }
581 }
582
583 #endif
584
585 size_t UMAPutBytesCFRefCallback( void *info, const void *bytes, size_t count )
586 {
587 CFMutableDataRef data = (CFMutableDataRef) info;
588 if ( data )
589 {
590 CFDataAppendBytes( data, (const UInt8*) bytes, count );
591 }
592 return count;
593 }
594
595 void UMAReleaseCFDataProviderCallback(void *info,
596 const void *WXUNUSED(data),
597 size_t WXUNUSED(count))
598 {
599 if ( info )
600 CFRelease( (CFDataRef) info );
601 }
602
603 void UMAReleaseCFDataConsumerCallback( void *info )
604 {
605 if ( info )
606 CFRelease( (CFDataRef) info );
607 }
608
609 CGDataProviderRef UMACGDataProviderCreateWithCFData( CFDataRef data )
610 {
611 if ( data == NULL )
612 return NULL;
613
614 return CGDataProviderCreateWithCFData( data );
615 }
616
617 CGDataConsumerRef UMACGDataConsumerCreateWithCFData( CFMutableDataRef data )
618 {
619 if ( data == NULL )
620 return NULL;
621
622 return CGDataConsumerCreateWithCFData( data );
623 }
624 #endif // wxUSE_GUI
625
626 #if wxUSE_BASE
627
628 static bool sUMASystemInitialized = false ;
629
630 bool UMASystemIsInitialized()
631 {
632 return sUMASystemInitialized ;
633 }
634
635 void UMASetSystemIsInitialized(bool val)
636 {
637 sUMASystemInitialized = val;
638 }
639
640 #endif // wxUSE_BASE