]> git.sesse.net Git - vlc/blob - plugins/macosx/intf_macosx.c
Cleaning code and a small fix to make quit work on OSX
[vlc] / plugins / macosx / intf_macosx.c
1 /*****************************************************************************
2  * intf_macosx.c: MacOS X interface plugin
3  *****************************************************************************
4  * Copyright (C) 2001 VideoLAN
5  *
6  * Authors: 
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  * 
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
21  *****************************************************************************/
22
23 #define MODULE_NAME macosx
24 #include "modules_inner.h"
25
26 /*****************************************************************************
27  * Preamble
28  *****************************************************************************/
29 #include "defs.h"
30
31 #include <stdlib.h>                                      /* malloc(), free() */
32
33 #include "config.h"
34 #include "common.h"
35 #include "threads.h"
36 #include "mtime.h"
37 #include "tests.h"
38
39 #include "intf_msg.h"
40 #include "interface.h"
41
42 #include "modules.h"
43
44 #include "stream_control.h"
45 #include "input_ext-intf.h"
46
47 #include "intf_playlist.h"
48 #include "audio_output.h"
49
50 #include "main.h"
51
52 #include <Carbon/Carbon.h>
53
54 //how often to have callback to main loop.  Target of 30fps then 30hz + maybe some more...
55 //it doesn't really scale if we move to 2x the hz...  something else is slowing us down...
56
57 #define kMainLoopFrequency  (kEventDurationSecond / 45)         //45 for good measure
58
59 #define PLAYING         0
60 #define PAUSED          1
61
62 // Menu defs
63 enum
64 {
65 /*    kMenuApple  = 128,
66     kMenuFile   = 129,
67     kMenuControls   = 130,
68
69     kAppleAbout = 1, 
70     kAppleQuit = 7, //is this always the same?
71
72     kFileNew   = 1, 
73     kFileOpen   = 2, 
74     kFileCloseDivisor   = 3,
75     kFileClose   = 4,
76
77     kControlsPlayORPause   = 1, 
78     kControlsStop   = 2, 
79     kControlsForward   = 3, 
80     kControlsRewind   = 4, 
81     kControlsChapterDiv   = 5, 
82     kControlsChapterNext   = 6, 
83     kControlsChapterPrevious   = 7, 
84     kControlsDVDdiv   = 8, 
85     kControlsDVDMenu   = 9, 
86     kControlsVolumeDiv   = 10, 
87     kControlsVolumeUp   = 11, 
88     kControlsVolumeDown   = 12, 
89     kControlsVolumeMute   = 13, 
90     kControlsEjectDiv   = 14, 
91     kControlsEject   = 15 
92 */
93
94     kMenuApple  = 128,
95     kMenuFile   = 129,
96     kMenuControls   = 130,
97
98     kAppleAbout = 1, 
99     kAppleQuit = 8, //is this always the same?
100
101     kFileNew   = 1, 
102     kFileOpen,
103     kFileCloseDivisor,
104     kFileClose,
105     kFileQuitHack,
106
107     kControlsPlayORPause   = 1, 
108     kControlsStop,
109     kControlsForward,
110     kControlsRewind,
111     kControlsChapterDiv,
112     kControlsChapterNext,
113     kControlsChapterPrevious,
114     kControlsDVDdiv,
115     kControlsDVDMenu,
116     kControlsVolumeDiv,
117     kControlsVolumeUp,
118     kControlsVolumeDown,
119     kControlsVolumeMute,
120     kControlsEjectDiv,
121     kControlsEject 
122
123
124 #if 0
125 //virtual key codes ; raw subtract 0x40 from these values
126 //http://devworld.apple.com/techpubs/mac/Text/Text-577.html#HEADING577-0
127     kLeftArrow = 0x7B,
128     kRightArrow = 0x7C,
129     kDownArrow = 0x7D,
130     kUpArrow = 0x7E,
131
132 //http://devworld.apple.com/techpubs/mac/Text/Text-571.html#MARKER-9-18    
133     kPeriod = 47, //(decimal)
134     kSpace = 49, //(decimal)
135     kEscape = 53 //(decimal)
136 #endif
137
138 };
139
140 /*****************************************************************************
141  * intf_sys_t: description and status of the interface
142  *****************************************************************************/
143 typedef struct intf_sys_s
144 {
145     EventLoopTimerRef manageTimer;
146     
147 } intf_sys_t;
148
149 /*****************************************************************************
150  * Local prototypes.
151  *****************************************************************************/
152 static int  intf_Probe     ( probedata_t *p_data );
153 static int  intf_Open      ( intf_thread_t *p_intf );
154 static void intf_Close     ( intf_thread_t *p_intf );
155 static void intf_Run       ( intf_thread_t *p_intf );
156
157 /* OS Specific */
158
159 void CarbonManageCallback ( EventLoopTimerRef inTimer, void *inUserData );
160
161 #ifndef CarbonEvents
162 void EventLoop( intf_thread_t *p_intf );
163 void DoEvent( intf_thread_t *p_intf , EventRecord *event);
164 void DoMenuCommand( intf_thread_t *p_intf , long menuResult);
165 void DrawWindow(WindowRef window);
166 #else
167 /*
168 pascal OSErr    QuitEventHandler(const AppleEvent *theEvent, AppleEvent *theReply, SInt32 refCon);
169 static pascal OSStatus MyKeyHandler( EventHandlerCallRef inCallRef, EventRef inEvent, void* userData );
170 static pascal OSStatus MyWindowEventHandler(EventHandlerCallRef myHandler, EventRef event, void* userData);
171 */
172 #endif
173
174 /*****************************************************************************
175  * Functions exported as capabilities. They are declared as static so that
176  * we don't pollute the namespace too much.
177  *****************************************************************************/
178 void _M( intf_getfunctions )( function_list_t * p_function_list )
179 {
180     p_function_list->pf_probe = intf_Probe;
181     p_function_list->functions.intf.pf_open  = intf_Open;
182     p_function_list->functions.intf.pf_close = intf_Close;
183     p_function_list->functions.intf.pf_run   = intf_Run;
184 }
185
186 /*****************************************************************************
187  * intf_Probe: probe the interface and return a score
188  *****************************************************************************
189  * This function checks the interface can be run and returns a score to the
190  * plugin manager so that it can select the best plugin.
191  *****************************************************************************/
192 static int intf_Probe( probedata_t *p_data )
193 {
194     if( TestMethod( INTF_METHOD_VAR, "macosx" ) )
195     {
196         return( 999 );
197     }
198
199     /* Under MacOS X, this plugin always works */
200     return( 100 );
201 }
202
203 /*****************************************************************************
204  * intf_Open: initialize interface
205  *****************************************************************************/
206 static int intf_Open( intf_thread_t *p_intf )
207 {
208     MenuHandle menu;
209 //    MenuRef windMenu;
210
211     /* Allocate instance and initialize some members */
212     p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
213     if( p_intf->p_sys == NULL )
214     {
215         return( 1 );
216     };
217
218     /* Init Mac stuff */
219     InitCursor();
220     SetQDGlobalsRandomSeed( TickCount() );
221
222 // neat menu but don't know if we want it.
223 // Install the Windows menu. Free of charge!
224 //    CreateStandardWindowMenu( 0, &windMenu );
225 //    InsertMenu( windMenu, 0 );
226 //    DrawMenuBar();
227
228     menu = NewMenu( kMenuApple, "\p\024" );
229     AppendMenu( menu, "\pAbout VLCÉ/A" );
230     InsertMenu( menu, 0 );
231
232     menu = NewMenu( kMenuFile, "\pFile" );
233     AppendMenu( menu, "\pNew Viewer Window/N" );
234     AppendMenu( menu, "\pOpenÉ/O" );
235     AppendMenu( menu, "\p(-" );
236     AppendMenu( menu, "\pClose/W" );
237     //standard OS X application menu quit isn't working nicely
238     AppendMenu( menu, "\pQuit/Q" );
239     InsertMenu( menu, 0 );
240
241 //BIG HONKING MENU - in order Mac OS 9 dvd player
242 //can't get key codes right for menus... argh that's why they use resources!
243
244     menu = NewMenu( kMenuControls, "\pControls" );
245
246     AppendMenu( menu, "\pPlay/," );
247 //    SetMenuItemCommandKey(menu, 0, false, kSpace);
248 //    SetMenuItemModifiers( menu, 0, kMenuNoCommandModifier);
249
250     AppendMenu( menu, "\pStop/." );
251
252     AppendMenu( menu, "\pFast Forward/f" );
253 //    SetMenuItemCommandKey(menu, 2, false, kRightArrow);
254
255     AppendMenu( menu, "\pRewind/r" );
256 //    SetMenuItemCommandKey(menu, 3, false, kLeftArrow);
257
258     AppendMenu( menu, "\p(-" ); //4
259
260     AppendMenu( menu, "\pNext Chapter/c" );
261 //    SetMenuItemCommandKey(menu, 5, false, kRightArrow);
262 //    SetMenuItemModifiers( menu, 5, kMenuNoCommandModifier);
263
264     AppendMenu( menu, "\pPrevious Chapter/p" );
265 //    SetMenuItemCommandKey(menu, 6, false, kLeftArrow);
266 //    SetMenuItemModifiers( menu, 6, kMenuNoCommandModifier);
267
268     AppendMenu( menu, "\p(-" ); //7
269
270     AppendMenu( menu, "\pDVD Menu/v" );
271 //    SetMenuItemCommandKey(menu, 8, false, kEscape);
272 //    SetMenuItemModifiers( menu, 8, kMenuNoCommandModifier);
273
274     AppendMenu( menu, "\p(-" ); //9
275
276     AppendMenu( menu, "\pVolume Up/u" );
277 //    SetMenuItemCommandKey(menu, 10, false, kUpArrow);
278
279     AppendMenu( menu, "\pVolume Down/d" );
280 //    SetMenuItemCommandKey(menu, 11, false, kDownArrow);
281
282     AppendMenu( menu, "\pMute/M" ); //12
283
284     AppendMenu( menu, "\p(-" ); //13
285
286     AppendMenu( menu, "\pEject/E" ); //14
287
288     InsertMenu( menu, 0 );
289
290
291
292     DrawMenuBar();
293
294     return( 0 );
295 }
296
297 /*****************************************************************************
298  * intf_Close: destroy interface
299  *****************************************************************************/
300 static void intf_Close( intf_thread_t *p_intf )
301 {
302     /* Destroy structure */
303     free( p_intf->p_sys );
304 }
305
306 /*****************************************************************************
307  * intf_Run: main loop
308  *****************************************************************************/
309 static void intf_Run( intf_thread_t *p_intf )
310 {
311     OSStatus err;
312
313     EventLoopTimerUPP manageUPP;
314
315 /*
316 Eventually we want to use Carbon events, or maybe even write this app in Cocoa
317 */
318
319 //    EventTypeSpec windowEventType = { kEventClassWindow, kEventWindowClose };
320 //    EventHandlerUPP windowHandlerUPP;
321
322     //kinda going out of bounds here... need to bring window creation to this file.
323 //    main_t *p_main;
324
325 /*
326     EventTypeSpec keyboardEventType = { kEventClassKeyboard, kEventRawKeyDown };
327     EventHandlerUPP keyboardHandlerUPP;
328 */
329
330     manageUPP = NewEventLoopTimerUPP ( CarbonManageCallback );
331     err = InstallEventLoopTimer ( GetCurrentEventLoop(), 0, kMainLoopFrequency, manageUPP, (void *) p_intf, &p_intf->p_sys->manageTimer );
332     assert(err == noErr);
333     DisposeEventLoopTimerUPP(manageUPP);
334
335 /*    windowHandlerUPP = NewEventHandlerUPP ( MyWindowEventHandler );
336     err = InstallWindowEventHandler ( p_main->p_vout->p_sys->p_window , windowHandlerUPP, GetEventTypeCount(windowEventType), &windowEventType, (void *) p_intf, NULL );
337     assert(err == noErr);
338     DisposeEventHandlerUPP(windowHandlerUPP);
339 */
340
341
342 #ifndef CarbonEvents
343     //UGLY Event Loop!
344     EventLoop( p_intf );
345 #else
346     //Our big event loop !-)
347     RunApplicationEventLoop();
348 #endif
349     err = RemoveEventLoopTimer(p_intf->p_sys->manageTimer);
350     assert(err == noErr);
351 }
352
353
354
355 void CarbonManageCallback ( EventLoopTimerRef inTimer, void *inUserData )
356 {
357     intf_thread_t * p_intf = (intf_thread_t *) inUserData;
358
359     /* Manage core vlc functions through the callback */
360     p_intf->pf_manage( p_intf );
361     
362     if ( p_intf->b_die )
363     {
364         QuitApplicationEventLoop();
365     }
366 }
367
368 #ifndef CarbonEvents
369
370 void EventLoop( intf_thread_t *p_intf )
371 {
372     Boolean     gotEvent;
373     EventRecord event;
374     
375     do
376     {
377     p_intf->pf_manage( p_intf );
378         gotEvent = WaitNextEvent(everyEvent,&event,32767,nil);
379         if (gotEvent)
380             DoEvent( p_intf, &event);
381     } while (! p_intf->b_die );
382     
383     //ExitToShell();                                    
384 }
385
386
387 void DoEvent( intf_thread_t *p_intf , EventRecord *event)
388 {
389     short       part;
390     Boolean     hit;
391     char        key;
392     Rect        tempRect;
393     WindowRef   whichWindow;
394         
395     switch (event->what) 
396     {
397         case mouseDown:
398             part = FindWindow(event->where, &whichWindow);
399             switch (part)
400             {
401                 case inMenuBar:  /* process a moused menu command */
402                     DoMenuCommand( p_intf, MenuSelect(event->where));
403                     break;
404                     
405                 case inSysWindow:
406                     break;
407                 
408                 case inContent:
409                     if (whichWindow != FrontWindow()) 
410                         SelectWindow(whichWindow);
411                     break;
412                 
413                 case inDrag:    /* pass screenBits.bounds */
414                     GetRegionBounds(GetGrayRgn(), &tempRect);
415                     DragWindow(whichWindow, event->where, &tempRect);
416                     break;
417                     
418                 case inGrow:
419                     break;
420                     
421                 case inGoAway:
422                     p_intf->b_die = true;
423                     return;
424                     //DisposeWindow(whichWindow);
425                     //ExitToShell();
426                     break;
427                     
428                 case inZoomIn:
429                 case inZoomOut:
430                     hit = TrackBox(whichWindow, event->where, part);
431                     if (hit) 
432                     {
433                         SetPort(GetWindowPort(whichWindow));   // window must be current port
434                         EraseRect(GetWindowPortBounds(whichWindow, &tempRect));   // inval/erase because of ZoomWindow bug
435                         ZoomWindow(whichWindow, part, true);
436                         InvalWindowRect(whichWindow, GetWindowPortBounds(whichWindow, &tempRect));      
437                     }
438                     break;
439                 }
440                 break;
441                 
442                 case keyDown:
443                 case autoKey:
444                     key = event->message & charCodeMask;
445                     if (event->modifiers & cmdKey)
446                         if (event->what == keyDown)
447                             DoMenuCommand( p_intf, MenuKey(key));
448                             
449                 case activateEvt:              /* if you needed to do something special */
450                     break;
451                     
452                 case updateEvt:
453                         DrawWindow((WindowRef) event->message);
454                         break;
455                         
456                 case kHighLevelEvent:
457                         AEProcessAppleEvent( event );
458                         break;
459                 
460                 case diskEvt:
461                         break;
462         }
463 }
464
465 void DoMenuCommand( intf_thread_t *p_intf , long menuResult)
466 {
467     short       menuID;         /* the resource ID of the selected menu */
468     short       menuItem;       /* the item number of the selected menu */
469         
470     static int vol_val; // remember the current volume
471     static int playback_status;         // remember playback state
472
473     menuID = HiWord(menuResult);    /* use macros to get item & menu number */
474     menuItem = LoWord(menuResult);
475
476     switch (menuID) 
477     {
478         case kMenuApple:
479             switch (menuItem) 
480             {
481                 case kAppleAbout:
482                     //Fixme
483                     SysBeep(30);
484                     //DoAboutBox();
485                     break;
486                     
487                 case kAppleQuit:
488                     p_intf->b_die = true;
489                     //hrmm...
490                     ExitToShell();
491                     return;
492                     break;
493                                 
494                 default:
495                     break;
496             }
497             break;
498         
499         case kMenuFile:
500             switch (menuItem) 
501             {
502                 case kFileNew:
503                     //Fixme
504                     SysBeep(30);
505                     //DoAboutBox();
506                     break;
507
508                 case kFileOpen:
509                     //Fixme
510 /*
511             const char **device;
512             char device_method_and_name[B_FILE_NAME_LENGTH + 4];
513             if(p_message->FindString("device", device) != B_ERROR)
514                 {
515                 sprintf(device_method_and_name, "dvd:%s", *device); 
516                 intf_PlaylistAdd( p_main->p_playlist, PLAYLIST_END, device_method_and_name );
517                 }
518
519 */
520                     SysBeep(30);
521                     //DoAboutBox();
522                     break;
523
524                 case kFileClose:
525                     HideWindow( FrontWindow() );
526                     //Fixme
527                     SysBeep(30);
528                     //DoAboutBox();
529                     break;
530                     
531                 case kFileQuitHack:
532                     p_intf->b_die = true;
533                     break;
534                     
535                 default:
536                     break;
537             }
538             break;
539                 
540         case kMenuControls:
541             switch (menuItem) 
542             {
543                 case kControlsPlayORPause:
544                 // pause the playback
545                     if (p_intf->p_input != NULL )
546                     {
547                             // mute the volume if currently playing
548                             if (playback_status == PLAYING)
549                             {
550                                     if (p_main->p_aout != NULL)
551                                     {
552                                             p_main->p_aout->vol = 0;
553                                     }
554                                     playback_status = PAUSED;
555                             }
556                             else
557                             // restore the volume
558                             {
559                                     if (p_main->p_aout != NULL)
560                                     {
561                                             p_main->p_aout->vol = vol_val;
562                                     }
563                                     playback_status = PLAYING;
564                             }
565                             //snooze(400000);
566                             input_SetStatus(p_intf->p_input, INPUT_STATUS_PAUSE);
567                     }
568                     break;
569
570                 case kControlsStop:
571                 // this currently stops playback not nicely
572                     if (p_intf->p_input != NULL )
573                     {
574                             // silence the sound, otherwise very horrible
575                             if (p_main->p_aout != NULL)
576                             {
577                                     p_main->p_aout->vol = 0;
578                             }
579                             //snooze(400000);
580                             input_SetStatus(p_intf->p_input, INPUT_STATUS_END);
581                     }
582                     break;
583
584                 case kControlsForward:
585                 // cycle the fast playback modes
586                     if (p_intf->p_input != NULL )
587                     {
588                             if (p_main->p_aout != NULL)
589                             {
590                                     p_main->p_aout->vol = 0;
591                             }
592                             //snooze(400000);
593                             input_SetStatus(p_intf->p_input, INPUT_STATUS_FASTER);
594                     }
595                     break;
596
597                 case kControlsRewind:
598                 // cycle the slow playback modes
599                     if (p_intf->p_input != NULL )
600                     {
601                             if (p_main->p_aout != NULL)
602                             {
603                                     p_main->p_aout->vol = 0;
604                             }
605                             //snooze(400000);
606                             input_SetStatus(p_intf->p_input, INPUT_STATUS_SLOWER);
607                     }
608                     break;
609                 
610                 case kControlsChapterNext:
611                     if( p_intf->p_input != NULL )
612                     {
613                         /* FIXME: temporary hack */
614                         p_intf->p_input->b_eof = 1;
615                     }
616                     break;
617
618                 case kControlsChapterPrevious:
619                     if( p_intf->p_input != NULL )
620                     {
621                         /* FIXME: temporary hack */
622                         intf_PlaylistPrev( p_main->p_playlist );
623                         intf_PlaylistPrev( p_main->p_playlist );
624                         p_intf->p_input->b_eof = 1;
625                     }
626                     break;
627
628                 case kControlsDVDMenu:
629                     //Fixme
630                     SysBeep(30);
631                     break;
632
633                 case kControlsVolumeUp:
634                 // adjust the volume
635                     if (p_main->p_aout != NULL) 
636                     {
637                         p_main->p_aout->vol++;
638                     }
639                     break;
640
641                 case kControlsVolumeDown:
642                 // adjust the volume
643                     if (p_main->p_aout != NULL) 
644                     {
645                         p_main->p_aout->vol--;
646                     }
647                     break;
648
649                 case kControlsVolumeMute:
650                 // mute
651                     if (p_main->p_aout != NULL) 
652                         {
653                                     if (p_main->p_aout->vol == 0)
654                                     {
655                                             //p_vol->SetEnabled(true);
656                                             p_main->p_aout->vol = vol_val;
657                                     }   
658                                     else
659                                     {
660                                             //p_vol->SetEnabled(false);
661                                             vol_val = p_main->p_aout->vol;
662                                             p_main->p_aout->vol = 0;
663                                     }
664                             }
665                             break;
666
667                 case kControlsEject:
668                     //Fixme
669                     SysBeep(30);
670                     break;
671                     
672                 default:
673                     break;
674             }
675             break;
676
677         default:
678             break;
679     }
680     HiliteMenu(0);      /* unhighlight what MenuSelect (or MenuKey) hilited */
681 }
682
683 void DrawWindow(WindowRef window)
684 {
685     Rect                tempRect;
686     GrafPtr             curPort;
687         
688     GetPort(&curPort);
689     SetPort(GetWindowPort(window));
690     BeginUpdate(window);
691     EraseRect(GetWindowPortBounds(window, &tempRect));
692     DrawControls(window);
693     DrawGrowIcon(window);
694     EndUpdate(window);
695     SetPort(curPort);
696 }
697
698
699 #else
700
701 static pascal OSStatus MyEventHandler(EventHandlerCallRef myHandler, EventRef event, void* userData)
702 {
703     WindowRef                     window;
704     Rect                          bounds;
705     UInt32                        whatHappened;
706     HICommand                     commandStruct;
707     MenuRef                       theMenuRef;
708     UInt16                        theMenuItem;
709     OSStatus                      result = eventNotHandledErr; // report failure by default
710     
711     GetEventParameter(event, kEventParamDirectObject, typeWindowRef, NULL, sizeof(window), NULL, &window);
712     
713     whatHappened = GetEventKind(event);
714     
715     switch (whatHappened)
716     {
717         case kEventWindowActivated:
718             break;
719         
720         case kEventWindowDeactivated:
721             break;
722         
723         case kEventWindowDrawContent:
724             //DoUpdate(window);
725             result = noErr;
726             break;
727
728         case kEventWindowBoundsChanged:
729             InvalWindowRect(window, GetWindowPortBounds(window, &bounds));
730             //DoUpdate(window);
731             result = noErr;
732             break;
733
734         case kEventWindowClickContentRgn:
735             /*DoContentClick(window);
736             DoUpdate(window);
737             AdjustMenus();*/
738             result = noErr;
739             break;
740
741         case kEventCommandProcess:
742             GetEventParameter (event, kEventParamDirectObject, 
743                                         typeHICommand, NULL, sizeof(HICommand), 
744                                         NULL, &commandStruct);
745             theMenuRef = commandStruct.menu.menuRef;
746
747             if (theMenuRef == GetMenuHandle(kMenuApple)) 
748                 {
749                     // Because the event didn't occur *in* the window, the 
750                     // window reference isn't valid until we set it here 
751                     window = FrontWindow(); 
752
753                     theMenuItem = commandStruct.menu.menuItemIndex;
754                     switch ( theMenuItem ) 
755                             {
756                                 case iStop:
757                                         SetLight(window, true);
758                                         break;
759                                 case iGo:
760                                         SetLight(window, false);
761                                         break;
762                             }
763                     DoUpdate(window);
764                     AdjustMenus();
765                     result = noErr;
766                 }
767             */
768             break; 
769
770         case kEventMouseMoved:
771             /*
772             CursorRgn = NewRgn();
773             GetEventParameter (event, kEventParamMouseLocation, typeQDPoint,
774                                         NULL, sizeof(Point), NULL, &wheresMyMouse);
775             AdjustCursor(wheresMyMouse, CursorRgn);
776             DisposeRgn(CursorRgn);
777             */
778             result = noErr;
779             break;
780
781         default: 
782             // If nobody handled the event, it gets propagated to the
783             // application-level handler.
784             break;
785     }
786     return result;
787 }
788 #endif