]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/mac/carbon/uma.cpp
1. applied (heavily modified) patch for reading CUR files by Chris
[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
18
19static bool sUMAHasAppearance = false ;
20static long sUMAAppearanceVersion = 0 ;
21static bool sUMAHasAquaLayout = false ;
22extern int gAGABackgroundColor ;
23bool UMAHasAppearance() { return sUMAHasAppearance ; }
24long UMAGetAppearanceVersion() { return sUMAAppearanceVersion ; }
25
26static bool sUMAHasWindowManager = false ;
27static long sUMAWindowManagerAttr = 0 ;
28
29bool UMAHasWindowManager() { return sUMAHasWindowManager ; }
30long UMAGetWindowManagerAttr() { return sUMAWindowManagerAttr ; }
31bool UMAHasAquaLayout() { return sUMAHasAquaLayout ; }
32
33
34void 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}
48void 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
119long 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
136bool UMAGetProcessModeDoesActivateOnFGSwitch()
137{
138 return UMAGetProcessMode() & modeDoesActivateOnFGSwitch ;
139}
140
141// menu manager
142
143void 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
171UInt32 UMAMenuEvent( EventRecord *inEvent )
172{
173 return MenuEvent( inEvent ) ;
174}
175
176void UMAEnableMenuItem( MenuRef inMenu , MenuItemIndex inItem )
177{
178 EnableMenuItem( inMenu , inItem ) ;
179}
180
181void UMADisableMenuItem( MenuRef inMenu , MenuItemIndex inItem )
182{
183 DisableMenuItem( inMenu , inItem ) ;
184}
185
186void 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
204void 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
222void 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
236void 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
252int gPrOpenCounter = 0 ;
253
254#if TARGET_CARBON && PM_USE_SESSION_APIS
255OSStatus UMAPrOpen(PMPrintSession *macPrintSession)
256#else
257OSStatus 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
287OSStatus UMAPrClose(PMPrintSession *macPrintSession)
288#else
289OSStatus 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
322pascal QDGlobalsPtr GetQDGlobalsPtr (void) ;
323pascal QDGlobalsPtr GetQDGlobalsPtr (void)
324{
325 return QDGlobalsPtr (* (Ptr*) LMGetCurrentA5 ( ) - 0xCA);
326}
327
328#endif
329
330void 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
353void 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
365GrafPtr 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
375void UMADisposeWindow( WindowRef inWindowRef )
376{
377 wxASSERT( inWindowRef != NULL ) ;
378 DisposeWindow( inWindowRef ) ;
379}
380
381void 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
394void 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
406void 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
424void 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
437void 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
453void 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
469void 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
484void 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
492void UMAHideControl (ControlHandle inControl)
493{
494 SetControlVisibility( inControl , false , false ) ;
495 Rect ctrlBounds ;
496 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
497}
498// keyboard focus
499OSErr 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
518void 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
533bool UMAIsWindowFloating( WindowRef inWindow )
534{
535 WindowClass cl ;
536
537 GetWindowClass( inWindow , &cl ) ;
538 return cl == kFloatingWindowClass ;
539}
540
541bool UMAIsWindowModal( WindowRef inWindow )
542{
543 WindowClass cl ;
544
545 GetWindowClass( inWindow , &cl ) ;
546 return cl < kFloatingWindowClass ;
547}
548
549// others
550
551void 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}
573OSStatus UMADrawThemePlacard( const Rect *inRect , ThemeDrawState inState )
574{
575 return ::DrawThemePlacard( inRect , inState ) ;
576}
577
578static OSStatus helpMenuStatus = noErr ;
579static MenuRef helpMenuHandle = NULL ;
580static MenuItemIndex firstCustomItemIndex = 0 ;
581
582OSStatus 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}