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