Mercurial > mplayer.hg
comparison libvo/osx_objc_common.m @ 35086:8848682f4035
Split out an objective-C common OS X layer, to be reused by -vo gl.
author | reimar |
---|---|
date | Thu, 13 Sep 2012 19:20:47 +0000 |
parents | libvo/vo_corevideo.m@5a9728bbb51e |
children | 9fcfc9c5f038 |
comparison
equal
deleted
inserted
replaced
35085:5a9728bbb51e | 35086:8848682f4035 |
---|---|
1 /* | |
2 * CoreVideo video output driver | |
3 * Copyright (c) 2005 Nicolas Plourde <nicolasplourde@gmail.com> | |
4 * | |
5 * This file is part of MPlayer. | |
6 * | |
7 * MPlayer is free software; you can redistribute it and/or modify | |
8 * it under the terms of the GNU General Public License as published by | |
9 * the Free Software Foundation; either version 2 of the License, or | |
10 * (at your option) any later version. | |
11 * | |
12 * MPlayer is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 * GNU General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU General Public License along | |
18 * with MPlayer; if not, write to the Free Software Foundation, Inc., | |
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
20 */ | |
21 | |
22 #import "osx_objc_common.h" | |
23 #include <Carbon/Carbon.h> | |
24 #include <CoreServices/CoreServices.h> | |
25 //special workaround for Apple bug #6267445 | |
26 //(OSServices Power API disabled in OSServices.h for 64bit systems) | |
27 #ifndef __POWER__ | |
28 #include <CoreServices/../Frameworks/OSServices.framework/Headers/Power.h> | |
29 #endif | |
30 | |
31 //MPLAYER | |
32 #include "config.h" | |
33 #include "video_out.h" | |
34 #include "aspect.h" | |
35 #include "mp_msg.h" | |
36 #include "mp_fifo.h" | |
37 | |
38 #include "input/input.h" | |
39 #include "input/mouse.h" | |
40 | |
41 #include "osdep/keycodes.h" | |
42 #include "osx_common.h" | |
43 | |
44 static float winAlpha = 1; | |
45 | |
46 static BOOL isLeopardOrLater; | |
47 | |
48 static NSAutoreleasePool *autoreleasepool; | |
49 static MPCommonOpenGLView *oglv; | |
50 | |
51 int vo_osx_init(void) | |
52 { | |
53 autoreleasepool = [[NSAutoreleasePool alloc] init]; | |
54 oglv = [[MPCommonOpenGLView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100) pixelFormat:[MPCommonOpenGLView defaultPixelFormat]]; | |
55 [oglv autorelease]; | |
56 [oglv display]; | |
57 [oglv preinit]; | |
58 return 1; | |
59 } | |
60 | |
61 void vo_osx_uninit(void) | |
62 { | |
63 NSAutoreleasePool *finalPool; | |
64 oglv = nil; | |
65 [autoreleasepool release]; | |
66 finalPool = [[NSAutoreleasePool alloc] init]; | |
67 [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil inMode:NSDefaultRunLoopMode dequeue:YES]; | |
68 [finalPool release]; | |
69 } | |
70 | |
71 int vo_osx_config(uint32_t width, uint32_t height, uint32_t flags) | |
72 { | |
73 [oglv config:width:height:flags]; | |
74 return 1; | |
75 } | |
76 | |
77 void vo_osx_ontop(void) | |
78 { | |
79 vo_ontop = !vo_ontop; | |
80 [oglv ontop]; | |
81 } | |
82 | |
83 void vo_osx_fullscreen(void) | |
84 { | |
85 vo_fs = !vo_fs; | |
86 [oglv fullscreen:YES]; | |
87 } | |
88 | |
89 int vo_osx_check_events(void) | |
90 { | |
91 [oglv check_events]; | |
92 return 0; | |
93 } | |
94 | |
95 void vo_osx_update_xinerama_info(void) | |
96 { | |
97 [oglv update_screen_info]; | |
98 } | |
99 | |
100 @implementation MPCommonOpenGLView | |
101 - (void) update_screen_info | |
102 { | |
103 int screen_id = xinerama_screen; | |
104 NSArray *screen_array = [NSScreen screens]; | |
105 NSScreen *screen_handle; | |
106 NSRect screen_frame; | |
107 | |
108 if(screen_id >= (int)[screen_array count]) | |
109 { | |
110 mp_msg(MSGT_VO, MSGL_INFO, "[vo_corevideo] Device ID %d does not exist, falling back to main device\n", screen_id); | |
111 screen_id = -1; | |
112 } | |
113 if (screen_id < 0 && [self window]) | |
114 screen_handle = [[self window] screen]; | |
115 else | |
116 screen_handle = [screen_array objectAtIndex:(screen_id < 0 ? 0 : screen_id)]; | |
117 | |
118 screen_frame = [screen_handle frame]; | |
119 vo_screenwidth = screen_frame.size.width; | |
120 vo_screenheight = screen_frame.size.height; | |
121 xinerama_x = screen_frame.origin.x; | |
122 xinerama_y = screen_frame.origin.y; | |
123 aspect_save_screenres(vo_screenwidth, vo_screenheight); | |
124 } | |
125 | |
126 - (void) preinit | |
127 { | |
128 NSOpenGLContext *glContext; | |
129 GLint swapInterval = 1; | |
130 | |
131 NSApplicationLoad(); | |
132 NSApp = [NSApplication sharedApplication]; | |
133 isLeopardOrLater = floor(NSAppKitVersionNumber) > 824; | |
134 | |
135 osx_foreground_hack(); | |
136 | |
137 // Install an event handler so the Quit menu entry works | |
138 // The proper way using NSApp setDelegate: and | |
139 // applicationShouldTerminate: does not work, | |
140 // probably NSApplication never installs its handler. | |
141 [[NSAppleEventManager sharedAppleEventManager] | |
142 setEventHandler:self | |
143 andSelector:@selector(handleQuitEvent:withReplyEvent:) | |
144 forEventClass:kCoreEventClass | |
145 andEventID:kAEQuitApplication]; | |
146 | |
147 //init menu | |
148 [self initMenu]; | |
149 | |
150 //create window | |
151 window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 100, 100) | |
152 styleMask:NSTitledWindowMask|NSTexturedBackgroundWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask | |
153 backing:NSBackingStoreBuffered defer:NO]; | |
154 | |
155 [window autorelease]; | |
156 [window setDelegate:self]; | |
157 [window setContentView:self]; | |
158 [window setInitialFirstResponder:self]; | |
159 [window setAcceptsMouseMovedEvents:YES]; | |
160 [window setTitle:@"MPlayer - The Movie Player"]; | |
161 | |
162 winSizeMult = 1; | |
163 | |
164 //create OpenGL Context | |
165 glContext = [[NSOpenGLContext alloc] initWithFormat:[NSOpenGLView defaultPixelFormat] shareContext:nil]; | |
166 | |
167 [self setOpenGLContext:glContext]; | |
168 [glContext setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval]; | |
169 [glContext setView:self]; | |
170 [glContext makeCurrentContext]; | |
171 [glContext release]; | |
172 } | |
173 | |
174 - (void) dealloc | |
175 { | |
176 [self setOpenGLContext:nil]; | |
177 [super dealloc]; | |
178 } | |
179 | |
180 - (void) config:(uint32_t)width:(uint32_t)height:(uint32_t)flags | |
181 { | |
182 config_movie_aspect((float)width/height); | |
183 | |
184 vo_dwidth = width *= self->winSizeMult; | |
185 vo_dheight = height *= self->winSizeMult; | |
186 | |
187 //config window | |
188 [window setContentSize:NSMakeSize(vo_dwidth, vo_dheight)]; | |
189 | |
190 // Do not use visibleFrame - taking the menu bar and dock into account | |
191 // would be nicer in principle, but currently only results in the window | |
192 // being placed strangely off-center since vo_dx/vo_dy calculation is | |
193 // not aware of it. | |
194 // Also flip vo_dy since the screen origin is in the bottom left on OSX. | |
195 [self update_screen_info]; | |
196 [window setFrameTopLeftPoint:NSMakePoint( | |
197 vo_dx, | |
198 2*xinerama_y + vo_screenheight - vo_dy)]; | |
199 | |
200 vo_fs = flags & VOFLAG_FULLSCREEN; | |
201 | |
202 [self rootwin]; | |
203 | |
204 if(vo_fs) | |
205 [self fullscreen: NO]; | |
206 | |
207 [self ontop]; | |
208 | |
209 if (!(flags & VOFLAG_HIDDEN)) | |
210 //show window | |
211 [window makeKeyAndOrderFront:self]; | |
212 } | |
213 | |
214 /* | |
215 Init Menu | |
216 */ | |
217 - (void)initMenu | |
218 { | |
219 NSMenu *mainMenu = [[NSMenu alloc] init]; | |
220 NSMenu *menu, *aspectMenu; | |
221 NSMenuItem *menuItem; | |
222 | |
223 menu = [[NSMenu alloc] init]; | |
224 menuItem = [[NSMenuItem alloc] init]; | |
225 [menuItem setSubmenu:menu]; | |
226 [mainMenu addItem:menuItem]; | |
227 // Note: setAppleMenu seems to be unnecessary from 10.6 on, | |
228 // but is needed for all earlier versions or the menu is | |
229 // messed up. | |
230 // Round-about way with performSelector used to avoid compiler | |
231 // warnings. | |
232 [NSApp performSelector:@selector(setAppleMenu:) withObject:menu]; | |
233 | |
234 //Create Movie Menu | |
235 menu = [[NSMenu alloc] initWithTitle:@"Movie"]; | |
236 menuItem = [[NSMenuItem alloc] initWithTitle:@"Half Size" action:@selector(menuAction:) keyEquivalent:@"0"]; [menu addItem:menuItem]; | |
237 kHalfScreenCmd = menuItem; | |
238 menuItem = [[NSMenuItem alloc] initWithTitle:@"Normal Size" action:@selector(menuAction:) keyEquivalent:@"1"]; [menu addItem:menuItem]; | |
239 kNormalScreenCmd = menuItem; | |
240 menuItem = [[NSMenuItem alloc] initWithTitle:@"Double Size" action:@selector(menuAction:) keyEquivalent:@"2"]; [menu addItem:menuItem]; | |
241 kDoubleScreenCmd = menuItem; | |
242 menuItem = [[NSMenuItem alloc] initWithTitle:@"Full Size" action:@selector(menuAction:) keyEquivalent:@"f"]; [menu addItem:menuItem]; | |
243 kFullScreenCmd = menuItem; | |
244 menuItem = [NSMenuItem separatorItem]; [menu addItem:menuItem]; | |
245 | |
246 aspectMenu = [[NSMenu alloc] initWithTitle:@"Aspect Ratio"]; | |
247 menuItem = [[NSMenuItem alloc] initWithTitle:@"Keep" action:@selector(menuAction:) keyEquivalent:@""]; [aspectMenu addItem:menuItem]; | |
248 if(vo_keepaspect) [menuItem setState:NSOnState]; | |
249 kKeepAspectCmd = menuItem; | |
250 menuItem = [[NSMenuItem alloc] initWithTitle:@"Pan-Scan" action:@selector(menuAction:) keyEquivalent:@""]; [aspectMenu addItem:menuItem]; | |
251 if(vo_panscan) [menuItem setState:NSOnState]; | |
252 kPanScanCmd = menuItem; | |
253 menuItem = [NSMenuItem separatorItem]; [aspectMenu addItem:menuItem]; | |
254 menuItem = [[NSMenuItem alloc] initWithTitle:@"Original" action:@selector(menuAction:) keyEquivalent:@""]; [aspectMenu addItem:menuItem]; | |
255 kAspectOrgCmd = menuItem; | |
256 menuItem = [[NSMenuItem alloc] initWithTitle:@"4:3" action:@selector(menuAction:) keyEquivalent:@""]; [aspectMenu addItem:menuItem]; | |
257 kAspectFullCmd = menuItem; | |
258 menuItem = [[NSMenuItem alloc] initWithTitle:@"16:9" action:@selector(menuAction:) keyEquivalent:@""]; [aspectMenu addItem:menuItem]; | |
259 kAspectWideCmd = menuItem; | |
260 menuItem = [[NSMenuItem alloc] initWithTitle:@"Aspect Ratio" action:nil keyEquivalent:@""]; | |
261 [menuItem setSubmenu:aspectMenu]; | |
262 [menu addItem:menuItem]; | |
263 [aspectMenu release]; | |
264 | |
265 //Add to menubar | |
266 menuItem = [[NSMenuItem alloc] initWithTitle:@"Movie" action:nil keyEquivalent:@""]; | |
267 [menuItem setSubmenu:menu]; | |
268 [mainMenu addItem:menuItem]; | |
269 | |
270 //Create Window Menu | |
271 menu = [[NSMenu alloc] initWithTitle:@"Window"]; | |
272 | |
273 menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; [menu addItem:menuItem]; | |
274 menuItem = [[NSMenuItem alloc] initWithTitle:@"Zoom" action:@selector(performZoom:) keyEquivalent:@""]; [menu addItem:menuItem]; | |
275 | |
276 //Add to menubar | |
277 menuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""]; | |
278 [menuItem setSubmenu:menu]; | |
279 [mainMenu addItem:menuItem]; | |
280 [NSApp setWindowsMenu:menu]; | |
281 [NSApp setMainMenu:mainMenu]; | |
282 | |
283 [menu release]; | |
284 [menuItem release]; | |
285 } | |
286 | |
287 - (void)set_winSizeMult:(float)mult | |
288 { | |
289 NSRect frame; | |
290 int d_width, d_height; | |
291 aspect(&d_width, &d_height, A_NOZOOM); | |
292 | |
293 if (vo_fs) { | |
294 vo_fs = !vo_fs; | |
295 [self fullscreen:NO]; | |
296 } | |
297 | |
298 winSizeMult = mult; | |
299 frame.size.width = d_width * mult; | |
300 frame.size.height = d_height * mult; | |
301 [window setContentSize: frame.size]; | |
302 [self reshape]; | |
303 } | |
304 | |
305 /* | |
306 Menu Action | |
307 */ | |
308 - (void)menuAction:(id)sender | |
309 { | |
310 if(sender == kHalfScreenCmd) | |
311 [self set_winSizeMult: 0.5]; | |
312 if(sender == kNormalScreenCmd) | |
313 [self set_winSizeMult: 1]; | |
314 if(sender == kDoubleScreenCmd) | |
315 [self set_winSizeMult: 2]; | |
316 if(sender == kFullScreenCmd) | |
317 { | |
318 vo_fs = !vo_fs; | |
319 [self fullscreen:NO]; | |
320 } | |
321 | |
322 if(sender == kKeepAspectCmd) | |
323 { | |
324 vo_keepaspect = !vo_keepaspect; | |
325 if(vo_keepaspect) | |
326 [kKeepAspectCmd setState:NSOnState]; | |
327 else | |
328 [kKeepAspectCmd setState:NSOffState]; | |
329 | |
330 [self reshape]; | |
331 } | |
332 | |
333 if(sender == kPanScanCmd) | |
334 { | |
335 vo_panscan = !vo_panscan; | |
336 if(vo_panscan) | |
337 [kPanScanCmd setState:NSOnState]; | |
338 else | |
339 [kPanScanCmd setState:NSOffState]; | |
340 | |
341 panscan_calc(); | |
342 } | |
343 | |
344 if(sender == kAspectOrgCmd) | |
345 change_movie_aspect(-1); | |
346 | |
347 if(sender == kAspectFullCmd) | |
348 change_movie_aspect(4.0f/3.0f); | |
349 | |
350 if(sender == kAspectWideCmd) | |
351 change_movie_aspect(16.0f/9.0f); | |
352 } | |
353 | |
354 /* | |
355 Toggle Fullscreen | |
356 */ | |
357 - (void) fullscreen: (BOOL) animate | |
358 { | |
359 static NSRect old_frame; | |
360 static NSRect old_view_frame; | |
361 | |
362 panscan_calc(); | |
363 | |
364 //go fullscreen | |
365 if(vo_fs) | |
366 { | |
367 if(!vo_rootwin) | |
368 { | |
369 SetSystemUIMode( kUIModeAllHidden, kUIOptionAutoShowMenuBar); | |
370 CGDisplayHideCursor(kCGDirectMainDisplay); | |
371 mouseHide = YES; | |
372 } | |
373 | |
374 old_frame = [window frame]; //save main window size & position | |
375 [self update_screen_info]; | |
376 | |
377 [window setFrame:NSMakeRect(xinerama_x, xinerama_y, vo_screenwidth, vo_screenheight) display:YES animate:animate]; //zoom-in window with nice useless sfx | |
378 old_view_frame = [self bounds]; | |
379 | |
380 [self setFrame:NSMakeRect(0, 0, vo_screenwidth, vo_screenheight)]; | |
381 [self setNeedsDisplay:YES]; | |
382 [window setHasShadow:NO]; | |
383 } | |
384 else | |
385 { | |
386 SetSystemUIMode( kUIModeNormal, 0); | |
387 | |
388 CGDisplayShowCursor(kCGDirectMainDisplay); | |
389 mouseHide = NO; | |
390 | |
391 //revert window to previous setting | |
392 [self setFrame:old_view_frame]; | |
393 [self setNeedsDisplay:YES]; | |
394 [window setHasShadow:YES]; | |
395 [window setFrame:old_frame display:YES animate:animate];//zoom-out window with nice useless sfx | |
396 } | |
397 } | |
398 | |
399 /* | |
400 Toggle ontop | |
401 */ | |
402 - (void) ontop | |
403 { | |
404 if(vo_ontop) | |
405 { | |
406 [window setLevel:NSScreenSaverWindowLevel]; | |
407 } | |
408 else | |
409 { | |
410 [window setLevel:NSNormalWindowLevel]; | |
411 } | |
412 } | |
413 | |
414 /* | |
415 Toggle rootwin | |
416 */ | |
417 - (void) rootwin | |
418 { | |
419 if(vo_rootwin) | |
420 { | |
421 [window setLevel:CGWindowLevelForKey(kCGDesktopWindowLevelKey)]; | |
422 [window orderBack:self]; | |
423 } | |
424 else | |
425 { | |
426 [window setLevel:NSNormalWindowLevel]; | |
427 } | |
428 } | |
429 | |
430 /* | |
431 Check event for new event | |
432 */ | |
433 - (void) check_events | |
434 { | |
435 NSEvent *event; | |
436 int curTime = TickCount()/60; | |
437 | |
438 //automatically hide mouse cursor (and future on-screen control?) | |
439 if(vo_fs && !mouseHide && !vo_rootwin) | |
440 { | |
441 if(curTime - lastMouseHide >= 5 || lastMouseHide == 0) | |
442 { | |
443 CGDisplayHideCursor(kCGDirectMainDisplay); | |
444 mouseHide = TRUE; | |
445 lastMouseHide = curTime; | |
446 } | |
447 } | |
448 | |
449 //update activity every 30 seconds to prevent | |
450 //screensaver from starting up. | |
451 if(curTime - lastScreensaverUpdate >= 30 || lastScreensaverUpdate == 0) | |
452 { | |
453 UpdateSystemActivity(UsrActivity); | |
454 lastScreensaverUpdate = curTime; | |
455 } | |
456 | |
457 event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil inMode:NSEventTrackingRunLoopMode dequeue:YES]; | |
458 if (event == nil) | |
459 return; | |
460 [NSApp sendEvent:event]; | |
461 // Without SDL's bootstrap code (include SDL.h in mplayer.c), | |
462 // on Leopard, we have trouble to get the play window automatically focused | |
463 // when the app is actived. The Following code fix this problem. | |
464 #ifndef CONFIG_SDL | |
465 if (isLeopardOrLater && [event type] == NSAppKitDefined | |
466 && [event subtype] == NSApplicationActivatedEventType) { | |
467 [window makeMainWindow]; | |
468 [window makeKeyAndOrderFront:self]; | |
469 } | |
470 #endif | |
471 } | |
472 | |
473 /* | |
474 From NSView, respond to key equivalents. | |
475 */ | |
476 - (BOOL)performKeyEquivalent:(NSEvent *)theEvent | |
477 { | |
478 switch([theEvent keyCode]) | |
479 { | |
480 case 0x21: [window setAlphaValue: winAlpha-=0.05]; return YES; | |
481 case 0x1e: [window setAlphaValue: winAlpha+=0.05]; return YES; | |
482 } | |
483 return NO; | |
484 } | |
485 | |
486 /* | |
487 Process key event | |
488 */ | |
489 - (void) keyDown: (NSEvent *) theEvent | |
490 { | |
491 int key = convert_key([theEvent keyCode], *[[theEvent characters] UTF8String]); | |
492 if (key != -1) | |
493 mplayer_put_key(key); | |
494 } | |
495 | |
496 /* | |
497 Process mouse button event | |
498 */ | |
499 - (void) mouseMoved: (NSEvent *) theEvent | |
500 { | |
501 if(vo_fs && !vo_rootwin) | |
502 { | |
503 CGDisplayShowCursor(kCGDirectMainDisplay); | |
504 mouseHide = NO; | |
505 } | |
506 if (enable_mouse_movements && !vo_rootwin) { | |
507 NSPoint p =[self convertPoint:[theEvent locationInWindow] fromView:nil]; | |
508 if ([self mouse:p inRect:[self frame]]) { | |
509 vo_mouse_movement(p.x, [self frame].size.height - p.y); | |
510 } | |
511 } | |
512 } | |
513 | |
514 - (void) mouseDown: (NSEvent *) theEvent | |
515 { | |
516 [self mouseEvent: theEvent]; | |
517 } | |
518 | |
519 - (void) mouseUp: (NSEvent *) theEvent | |
520 { | |
521 [self mouseEvent: theEvent]; | |
522 } | |
523 | |
524 - (void) rightMouseDown: (NSEvent *) theEvent | |
525 { | |
526 [self mouseEvent: theEvent]; | |
527 } | |
528 | |
529 - (void) rightMouseUp: (NSEvent *) theEvent | |
530 { | |
531 [self mouseEvent: theEvent]; | |
532 } | |
533 | |
534 - (void) otherMouseDown: (NSEvent *) theEvent | |
535 { | |
536 [self mouseEvent: theEvent]; | |
537 } | |
538 | |
539 - (void) otherMouseUp: (NSEvent *) theEvent | |
540 { | |
541 [self mouseEvent: theEvent]; | |
542 } | |
543 | |
544 - (void) scrollWheel: (NSEvent *) theEvent | |
545 { | |
546 if([theEvent deltaY] > 0) | |
547 mplayer_put_key(MOUSE_BTN3); | |
548 else | |
549 mplayer_put_key(MOUSE_BTN4); | |
550 } | |
551 | |
552 - (void) mouseEvent: (NSEvent *) theEvent | |
553 { | |
554 if ( [theEvent buttonNumber] >= 0 && [theEvent buttonNumber] <= 9 ) | |
555 { | |
556 int buttonNumber = [theEvent buttonNumber]; | |
557 // Fix to mplayer defined button order: left, middle, right | |
558 if (buttonNumber == 1) | |
559 buttonNumber = 2; | |
560 else if (buttonNumber == 2) | |
561 buttonNumber = 1; | |
562 switch([theEvent type]) | |
563 { | |
564 case NSLeftMouseDown: | |
565 case NSRightMouseDown: | |
566 case NSOtherMouseDown: | |
567 mplayer_put_key((MOUSE_BTN0 + buttonNumber) | MP_KEY_DOWN); | |
568 break; | |
569 case NSLeftMouseUp: | |
570 case NSRightMouseUp: | |
571 case NSOtherMouseUp: | |
572 mplayer_put_key(MOUSE_BTN0 + buttonNumber); | |
573 break; | |
574 } | |
575 } | |
576 } | |
577 | |
578 /* | |
579 NSResponder | |
580 */ | |
581 - (BOOL) acceptsFirstResponder | |
582 { | |
583 return YES; | |
584 } | |
585 | |
586 - (BOOL) becomeFirstResponder | |
587 { | |
588 return YES; | |
589 } | |
590 | |
591 - (BOOL) resignFirstResponder | |
592 { | |
593 return YES; | |
594 } | |
595 | |
596 - (BOOL)windowShouldClose:(id)sender | |
597 { | |
598 mplayer_put_key(KEY_CLOSE_WIN); | |
599 // We have to wait for MPlayer to handle this, | |
600 // otherwise we are in trouble if the | |
601 // KEY_CLOSE_WIN handler is disabled | |
602 return NO; | |
603 } | |
604 | |
605 - (void)handleQuitEvent:(NSAppleEventDescriptor*)e withReplyEvent:(NSAppleEventDescriptor*)r | |
606 { | |
607 mplayer_put_key(KEY_CLOSE_WIN); | |
608 } | |
609 @end |