]> git.saurik.com Git - wxWidgets.git/blob - src/mac/uma.cpp
Tries to fix wxListBox focus problems.
[wxWidgets.git] / src / mac / uma.cpp
1 #include "wx/defs.h"
2 #include "wx/dc.h"
3 #include "wx/mac/uma.h"
4
5 #ifndef __DARWIN__
6 #include <Navigation.h>
7 #endif
8
9 // since we have decided that we only support 8.6 upwards we are
10 // checking for these minimum requirements in the startup code of
11 // the application so all wxWindows code can safely assume that appearance 1.1
12 // windows manager, control manager, navigation services etc. are
13 // present
14
15 static bool sUMAHasAppearance = false ;
16 static long sUMAAppearanceVersion = 0 ;
17 extern int gAGABackgroundColor ;
18 bool UMAHasAppearance() { return sUMAHasAppearance ; }
19 long UMAGetAppearanceVersion() { return sUMAAppearanceVersion ; }
20
21 static bool sUMAHasWindowManager = false ;
22 static long sUMAWindowManagerAttr = 0 ;
23
24 bool UMAHasWindowManager() { return sUMAHasWindowManager ; }
25 long UMAGetWindowManagerAttr() { return sUMAWindowManagerAttr ; }
26
27 void UMACleanupToolbox()
28 {
29 if ( sUMAHasAppearance )
30 {
31 UnregisterAppearanceClient() ;
32 }
33 if ( NavServicesAvailable() )
34 {
35 NavUnload() ;
36 }
37 }
38 void UMAInitToolbox( UInt16 inMoreMastersCalls )
39 {
40 #if !TARGET_CARBON
41 ::MaxApplZone();
42 for (long i = 1; i <= inMoreMastersCalls; i++)
43 ::MoreMasters();
44
45 ::InitGraf(&qd.thePort);
46 ::InitFonts();
47 ::InitMenus();
48 ::TEInit();
49 ::InitDialogs(0L);
50 ::FlushEvents(everyEvent, 0);
51 ::InitCursor();
52 long total,contig;
53 PurgeSpace(&total, &contig);
54 #else
55 InitCursor();
56 #endif
57
58 long theAppearance ;
59 if ( Gestalt( gestaltAppearanceAttr, &theAppearance ) == noErr )
60 {
61 sUMAHasAppearance = true ;
62 RegisterAppearanceClient();
63 if ( Gestalt( gestaltAppearanceVersion, &theAppearance ) == noErr )
64 {
65 sUMAAppearanceVersion = theAppearance ;
66 }
67 else
68 {
69 sUMAAppearanceVersion = 0x0100 ;
70 }
71 }
72 if ( Gestalt( gestaltWindowMgrAttr, &sUMAWindowManagerAttr ) == noErr )
73 {
74 sUMAHasWindowManager = sUMAWindowManagerAttr & gestaltWindowMgrPresent ;
75 }
76
77 #ifndef __DARWIN__
78 #if TARGET_CARBON
79 // Call currently implicitely done : InitFloatingWindows() ;
80 #else
81 if ( sUMAHasWindowManager )
82 InitFloatingWindows() ;
83 else
84 InitWindows();
85 #endif
86 #endif
87
88 if ( NavServicesAvailable() )
89 {
90 NavLoad() ;
91 }
92 }
93
94 // process manager
95 long UMAGetProcessMode()
96 {
97 OSErr err ;
98 ProcessInfoRec processinfo;
99 ProcessSerialNumber procno ;
100
101 procno.highLongOfPSN = NULL ;
102 procno.lowLongOfPSN = kCurrentProcess ;
103 processinfo.processInfoLength = sizeof(ProcessInfoRec);
104 processinfo.processName = NULL;
105 processinfo.processAppSpec = NULL;
106
107 err = ::GetProcessInformation( &procno , &processinfo ) ;
108 wxASSERT( err == noErr ) ;
109 return processinfo.processMode ;
110 }
111
112 bool UMAGetProcessModeDoesActivateOnFGSwitch()
113 {
114 return UMAGetProcessMode() & modeDoesActivateOnFGSwitch ;
115 }
116
117 // menu manager
118
119 void UMASetMenuTitle( MenuRef menu , StringPtr title )
120 {
121 #if !TARGET_CARBON
122 long size = GetHandleSize( (Handle) menu ) ;
123 const long headersize = 14 ;
124 int oldlen = (**menu).menuData[0] + 1;
125 int newlen = title[0] + 1 ;
126
127 if ( oldlen < newlen )
128 {
129 // enlarge before adjusting
130 SetHandleSize( (Handle) menu , size + (newlen - oldlen ) );
131 }
132
133 if ( oldlen != newlen )
134 memmove( (char*) (**menu).menuData + newlen , (char*) (**menu).menuData + oldlen , size - headersize - oldlen ) ;
135
136 memcpy( (char*) (**menu).menuData , title , newlen ) ;
137 if ( oldlen > newlen )
138 {
139 // shrink after
140 SetHandleSize( (Handle) menu , size + (newlen - oldlen ) ) ;
141 }
142 #else
143 SetMenuTitle( menu , title ) ;
144 #endif
145 }
146
147 UInt32 UMAMenuEvent( EventRecord *inEvent )
148 {
149 return MenuEvent( inEvent ) ;
150 }
151
152 void UMAEnableMenuItem( MenuRef inMenu , MenuItemIndex inItem )
153 {
154 EnableMenuItem( inMenu , inItem ) ;
155 }
156
157 void UMADisableMenuItem( MenuRef inMenu , MenuItemIndex inItem )
158 {
159 DisableMenuItem( inMenu , inItem ) ;
160 }
161
162 void UMAAppendSubMenuItem( MenuRef menu , StringPtr l , SInt16 id )
163 {
164 Str255 label ;
165 memcpy( label , l , l[0]+1 ) ;
166 // hardcoded adding of the submenu combination for mac
167
168 int theEnd = label[0] + 1;
169 if (theEnd > 251)
170 theEnd = 251; // mac allows only 255 characters
171 label[theEnd++] = '/';
172 label[theEnd++] = hMenuCmd;
173 label[theEnd++] = '!';
174 label[theEnd++] = id ;
175 label[theEnd] = 0x00;
176 label[0] = theEnd;
177 MacAppendMenu(menu, label);
178 }
179
180 void UMAInsertSubMenuItem( MenuRef menu , StringPtr l , MenuItemIndex item , SInt16 id )
181 {
182 Str255 label ;
183 memcpy( label , l , l[0]+1 ) ;
184 // hardcoded adding of the submenu combination for mac
185
186 int theEnd = label[0] + 1;
187 if (theEnd > 251)
188 theEnd = 251; // mac allows only 255 characters
189 label[theEnd++] = '/';
190 label[theEnd++] = hMenuCmd;
191 label[theEnd++] = '!';
192 label[theEnd++] = id;
193 label[theEnd] = 0x00;
194 label[0] = theEnd;
195 MacInsertMenuItem(menu, label , item);
196 }
197
198 void UMAAppendMenuItem( MenuRef menu , StringPtr l , SInt16 key, UInt8 modifiers )
199 {
200 Str255 label ;
201 memcpy( label , l , l[0]+1 ) ;
202 if ( key )
203 {
204 int pos = label[0] ;
205 label[++pos] = '/';
206 label[++pos] = toupper( key );
207 label[0] = pos ;
208 }
209 MacAppendMenu( menu , label ) ;
210 }
211
212 void UMAInsertMenuItem( MenuRef menu , StringPtr l , MenuItemIndex item , SInt16 key, UInt8 modifiers )
213 {
214 Str255 label ;
215 memcpy( label , l , l[0]+1 ) ;
216 if ( key )
217 {
218 int pos = label[0] ;
219 label[++pos] = '/';
220 label[++pos] = toupper( key );
221 label[0] = pos ;
222 }
223 MacInsertMenuItem( menu , label , item) ;
224 }
225
226 // quickdraw
227
228 int gPrOpenCounter = 0 ;
229
230 #if TARGET_CARBON && PM_USE_SESSION_APIS
231 OSStatus UMAPrOpen(PMPrintSession *macPrintSession)
232 #else
233 OSStatus UMAPrOpen()
234 #endif
235 {
236 #if !TARGET_CARBON
237 OSErr err = noErr ;
238 ++gPrOpenCounter ;
239 if ( gPrOpenCounter == 1 )
240 {
241 PrOpen() ;
242 err = PrError() ;
243 wxASSERT( err == noErr ) ;
244 }
245 return err ;
246 #else
247 OSStatus err = noErr ;
248 ++gPrOpenCounter ;
249 if ( gPrOpenCounter == 1 )
250 {
251 #if PM_USE_SESSION_APIS
252 err = PMCreateSession(macPrintSession) ;
253 #else
254 err = PMBegin() ;
255 #endif
256 wxASSERT( err == noErr ) ;
257 }
258 return err ;
259 #endif
260 }
261
262 #if TARGET_CARBON && PM_USE_SESSION_APIS
263 OSStatus UMAPrClose(PMPrintSession *macPrintSession)
264 #else
265 OSStatus UMAPrClose()
266 #endif
267 {
268 #if !TARGET_CARBON
269 OSErr err = noErr ;
270 wxASSERT( gPrOpenCounter >= 1 ) ;
271 if ( gPrOpenCounter == 1 )
272 {
273 PrClose() ;
274 err = PrError() ;
275 wxASSERT( err == noErr ) ;
276 }
277 --gPrOpenCounter ;
278 return err ;
279 #else
280 OSStatus err = noErr ;
281 wxASSERT( gPrOpenCounter >= 1 ) ;
282 if ( gPrOpenCounter == 1 )
283 {
284 #if PM_USE_SESSION_APIS
285 err = PMRelease(*macPrintSession) ;
286 *macPrintSession = kPMNoReference;
287 #else
288 err = PMEnd() ;
289 #endif
290 }
291 --gPrOpenCounter ;
292 return err ;
293 #endif
294 }
295
296 #if !TARGET_CARBON
297
298 pascal QDGlobalsPtr GetQDGlobalsPtr (void) ;
299 pascal QDGlobalsPtr GetQDGlobalsPtr (void)
300 {
301 return QDGlobalsPtr (* (Ptr*) LMGetCurrentA5 ( ) - 0xCA);
302 }
303
304 #endif
305
306 void UMAShowWatchCursor()
307 {
308 OSErr err = noErr;
309
310 CursHandle watchFob = GetCursor (watchCursor);
311
312 if (!watchFob)
313 err = nilHandleErr;
314 else
315 {
316 #if TARGET_CARBON
317 // Cursor preservedArrow;
318 // GetQDGlobalsArrow (&preservedArrow);
319 // SetQDGlobalsArrow (*watchFob);
320 // InitCursor ( );
321 // SetQDGlobalsArrow (&preservedArrow);
322 SetCursor (*watchFob);
323 #else
324 SetCursor (*watchFob);
325 #endif
326 }
327 }
328
329 void UMAShowArrowCursor()
330 {
331 #if TARGET_CARBON
332 Cursor arrow;
333 SetCursor (GetQDGlobalsArrow (&arrow));
334 #else
335 SetCursor (&(qd.arrow));
336 #endif
337 }
338
339 // window manager
340
341 GrafPtr UMAGetWindowPort( WindowRef inWindowRef )
342 {
343 wxASSERT( inWindowRef != NULL ) ;
344 #if TARGET_CARBON
345 return GetWindowPort( inWindowRef ) ;
346 #else
347 return (GrafPtr) inWindowRef ;
348 #endif
349 }
350
351 void UMADisposeWindow( WindowRef inWindowRef )
352 {
353 wxASSERT( inWindowRef != NULL ) ;
354 DisposeWindow( inWindowRef ) ;
355 }
356
357 void UMASetWTitleC( WindowRef inWindowRef , const char *title )
358 {
359 Str255 ptitle ;
360 strncpy( (char*)ptitle , title , 96 ) ;
361 ptitle[96] = 0 ;
362 #if TARGET_CARBON
363 c2pstrcpy( ptitle, (char *)ptitle ) ;
364 #else
365 c2pstr( (char*)ptitle ) ;
366 #endif
367 SetWTitle( inWindowRef , ptitle ) ;
368 }
369
370 void UMAGetWTitleC( WindowRef inWindowRef , char *title )
371 {
372 GetWTitle( inWindowRef , (unsigned char*)title ) ;
373 #if TARGET_CARBON
374 p2cstrcpy( title, (unsigned char *)title ) ;
375 #else
376 p2cstr( (unsigned char*)title ) ;
377 #endif
378 }
379
380 // appearance additions
381
382 void UMAActivateControl( ControlHandle inControl )
383 {
384 if ( !IsControlActive( inControl ) )
385 {
386 bool visible = IsControlVisible( inControl ) ;
387 if ( visible )
388 SetControlVisibility( inControl , false , false ) ;
389 ::ActivateControl( inControl ) ;
390 if ( visible ) {
391 SetControlVisibility( inControl , true , false ) ;
392 Rect ctrlBounds ;
393 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
394 }
395 }
396 }
397
398 void UMADrawControl( ControlHandle inControl )
399 {
400 WindowRef theWindow = GetControlOwner(inControl) ;
401 RgnHandle updateRgn = NewRgn() ;
402 GetWindowUpdateRgn( theWindow , updateRgn ) ;
403 Point zero = { 0 , 0 } ;
404 LocalToGlobal( &zero ) ;
405 OffsetRgn( updateRgn , -zero.h , -zero.v ) ;
406 ::DrawControlInCurrentPort( inControl ) ;
407 InvalWindowRgn( theWindow, updateRgn) ;
408 DisposeRgn( updateRgn ) ;
409
410 }
411
412 void UMAMoveControl( ControlHandle inControl , short x , short y )
413 {
414 bool visible = IsControlVisible( inControl ) ;
415 if ( visible ) {
416 SetControlVisibility( inControl , false , false ) ;
417 Rect ctrlBounds ;
418 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
419 }
420 ::MoveControl( inControl , x , y ) ;
421 if ( visible ) {
422 SetControlVisibility( inControl , true , false ) ;
423 Rect ctrlBounds ;
424 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
425 }
426 }
427
428 void UMASizeControl( 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 ::SizeControl( inControl , x , y ) ;
437 if ( visible ) {
438 SetControlVisibility( inControl , true , false ) ;
439 Rect ctrlBounds ;
440 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
441 }
442 }
443
444 void UMADeactivateControl( ControlHandle inControl )
445 {
446 if ( IsControlActive( inControl ) )
447 {
448 bool visible = IsControlVisible( inControl ) ;
449 if ( visible )
450 SetControlVisibility( inControl , false , false ) ;
451 ::DeactivateControl( inControl ) ;
452 if ( visible ) {
453 SetControlVisibility( inControl , true , false ) ;
454 Rect ctrlBounds ;
455 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
456 }
457 }
458 }
459 // shows the control and adds the region to the update region
460 void UMAShowControl (ControlHandle inControl)
461 {
462 SetControlVisibility( inControl , true , false ) ;
463 Rect ctrlBounds ;
464 InvalWindowRect(GetControlOwner(inControl),GetControlBounds(inControl,&ctrlBounds) ) ;
465 }
466
467 // keyboard focus
468 OSErr UMASetKeyboardFocus (WindowPtr inWindow,
469 ControlHandle inControl,
470 ControlFocusPart inPart)
471 {
472 OSErr err = noErr;
473 GrafPtr port ;
474 GetPort( &port ) ;
475
476 SetPortWindowPort( inWindow ) ;
477
478 SetOrigin( 0 , 0 ) ;
479 err = SetKeyboardFocus( inWindow , inControl , inPart ) ;
480 SetPort( port ) ;
481 return err ;
482 }
483
484
485
486
487 // events
488 void UMAUpdateControls( WindowPtr inWindow , RgnHandle inRgn )
489 {
490 RgnHandle updateRgn = NewRgn() ;
491 GetWindowUpdateRgn( inWindow , updateRgn ) ;
492
493 Point zero = { 0 , 0 } ;
494 LocalToGlobal( &zero ) ;
495 OffsetRgn( updateRgn , -zero.h , -zero.v ) ;
496
497 UpdateControls( inWindow , inRgn ) ;
498 InvalWindowRgn( inWindow, updateRgn) ;
499 DisposeRgn( updateRgn ) ;
500
501 }
502
503 bool UMAIsWindowFloating( WindowRef inWindow )
504 {
505 WindowClass cl ;
506
507 GetWindowClass( inWindow , &cl ) ;
508 return cl == kFloatingWindowClass ;
509 }
510
511 bool UMAIsWindowModal( WindowRef inWindow )
512 {
513 WindowClass cl ;
514
515 GetWindowClass( inWindow , &cl ) ;
516 return cl < kFloatingWindowClass ;
517 }
518
519 // others
520
521 void UMAHighlightAndActivateWindow( WindowRef inWindowRef , bool inActivate )
522 {
523 if ( inWindowRef )
524 {
525 // bool isHighlighted = IsWindowHighlited( inWindowRef ) ;
526 // if ( inActivate != isHightlited )
527 GrafPtr port ;
528 GetPort( &port ) ;
529 SetPortWindowPort( inWindowRef ) ;
530 SetOrigin( 0 , 0 ) ;
531 HiliteWindow( inWindowRef , inActivate ) ;
532 ControlHandle control = NULL ;
533 ::GetRootControl( inWindowRef , & control ) ;
534 if ( control )
535 {
536 if ( inActivate )
537 UMAActivateControl( control ) ;
538 else
539 UMADeactivateControl( control ) ;
540 }
541 SetPort( port ) ;
542 }
543 }
544 OSStatus UMADrawThemePlacard( const Rect *inRect , ThemeDrawState inState )
545 {
546 return ::DrawThemePlacard( inRect , inState ) ;
547 }
548