]> git.saurik.com Git - wxWidgets.git/blob - src/mac/uma.cpp
Adaptions for new redrawing
[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 if ( !IsControlActive( inControl ) )
400 {
401 bool visible = IsControlVisible( inControl ) ;
402 if ( visible )
403 SetControlVisibility( inControl , false , false ) ;
404 ::ActivateControl( inControl ) ;
405 if ( visible ) {
406 SetControlVisibility( inControl , true , false ) ;
407 Rect ctrlBounds ;
408 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
409 }
410 }
411 }
412
413 void UMADrawControl( ControlHandle inControl )
414 {
415 WindowRef theWindow = GetControlOwner(inControl) ;
416 RgnHandle updateRgn = NewRgn() ;
417 GetWindowUpdateRgn( theWindow , updateRgn ) ;
418 Point zero = { 0 , 0 } ;
419 LocalToGlobal( &zero ) ;
420 OffsetRgn( updateRgn , -zero.h , -zero.v ) ;
421 ::DrawControlInCurrentPort( inControl ) ;
422 InvalWindowRgn( theWindow, updateRgn) ;
423 DisposeRgn( updateRgn ) ;
424
425 }
426
427 void UMAMoveControl( ControlHandle inControl , short x , short y )
428 {
429 bool visible = IsControlVisible( inControl ) ;
430 if ( visible ) {
431 SetControlVisibility( inControl , false , false ) ;
432 Rect ctrlBounds ;
433 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
434 }
435 ::MoveControl( inControl , x , y ) ;
436 if ( visible ) {
437 SetControlVisibility( inControl , true , false ) ;
438 Rect ctrlBounds ;
439 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
440 }
441 }
442
443 void UMASizeControl( ControlHandle inControl , short x , short y )
444 {
445 bool visible = IsControlVisible( inControl ) ;
446 if ( visible ) {
447 SetControlVisibility( inControl , false , false ) ;
448 Rect ctrlBounds ;
449 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
450 }
451 ::SizeControl( inControl , x , y ) ;
452 if ( visible ) {
453 SetControlVisibility( inControl , true , false ) ;
454 Rect ctrlBounds ;
455 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
456 }
457 }
458
459 void UMADeactivateControl( ControlHandle inControl )
460 {
461 if ( IsControlActive( inControl ) )
462 {
463 bool visible = IsControlVisible( inControl ) ;
464 if ( visible )
465 SetControlVisibility( inControl , false , false ) ;
466 ::DeactivateControl( inControl ) ;
467 if ( visible ) {
468 SetControlVisibility( inControl , true , false ) ;
469 Rect ctrlBounds ;
470 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
471 }
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 // keyboard focus
483 OSErr UMASetKeyboardFocus (WindowPtr inWindow,
484 ControlHandle inControl,
485 ControlFocusPart inPart)
486 {
487 OSErr err = noErr;
488 GrafPtr port ;
489 GetPort( &port ) ;
490
491 SetPortWindowPort( inWindow ) ;
492
493 SetOrigin( 0 , 0 ) ;
494 err = SetKeyboardFocus( inWindow , inControl , inPart ) ;
495 SetPort( port ) ;
496 return err ;
497 }
498
499
500
501
502 // events
503 void UMAUpdateControls( WindowPtr inWindow , RgnHandle inRgn )
504 {
505 RgnHandle updateRgn = NewRgn() ;
506 GetWindowUpdateRgn( inWindow , updateRgn ) ;
507
508 Point zero = { 0 , 0 } ;
509 LocalToGlobal( &zero ) ;
510 OffsetRgn( updateRgn , -zero.h , -zero.v ) ;
511
512 UpdateControls( inWindow , inRgn ) ;
513 InvalWindowRgn( inWindow, updateRgn) ;
514 DisposeRgn( updateRgn ) ;
515
516 }
517
518 bool UMAIsWindowFloating( WindowRef inWindow )
519 {
520 WindowClass cl ;
521
522 GetWindowClass( inWindow , &cl ) ;
523 return cl == kFloatingWindowClass ;
524 }
525
526 bool UMAIsWindowModal( WindowRef inWindow )
527 {
528 WindowClass cl ;
529
530 GetWindowClass( inWindow , &cl ) ;
531 return cl < kFloatingWindowClass ;
532 }
533
534 // others
535
536 void UMAHighlightAndActivateWindow( WindowRef inWindowRef , bool inActivate )
537 {
538 if ( inWindowRef )
539 {
540 // bool isHighlighted = IsWindowHighlited( inWindowRef ) ;
541 // if ( inActivate != isHightlited )
542 GrafPtr port ;
543 GetPort( &port ) ;
544 SetPortWindowPort( inWindowRef ) ;
545 SetOrigin( 0 , 0 ) ;
546 HiliteWindow( inWindowRef , inActivate ) ;
547 ControlHandle control = NULL ;
548 ::GetRootControl( inWindowRef , & control ) ;
549 if ( control )
550 {
551 if ( inActivate )
552 UMAActivateControl( control ) ;
553 else
554 UMADeactivateControl( control ) ;
555 }
556 SetPort( port ) ;
557 }
558 }
559 OSStatus UMADrawThemePlacard( const Rect *inRect , ThemeDrawState inState )
560 {
561 return ::DrawThemePlacard( inRect , inState ) ;
562 }
563
564 static OSStatus helpMenuStatus = noErr ;
565 static MenuRef helpMenuHandle = NULL ;
566 static MenuItemIndex firstCustomItemIndex = 0 ;
567
568 OSStatus UMAGetHelpMenu(
569 MenuRef * outHelpMenu,
570 MenuItemIndex * outFirstCustomItemIndex)
571 {
572 #if TARGET_CARBON
573 return HMGetHelpMenu( outHelpMenu , outFirstCustomItemIndex ) ;
574 #else
575 if ( helpMenuHandle == NULL )
576 {
577 helpMenuStatus = HMGetHelpMenuHandle( &helpMenuHandle ) ;
578 if ( helpMenuStatus == noErr )
579 {
580 firstCustomItemIndex = CountMenuItems( helpMenuHandle ) + 1 ;
581 }
582 }
583 if ( outFirstCustomItemIndex )
584 {
585 *outFirstCustomItemIndex = firstCustomItemIndex ;
586 }
587 *outHelpMenu = helpMenuHandle ;
588 return helpMenuStatus ;
589 #endif
590 }