1 /*****************************************************************************
2 * intf.m: MacOS X interface module
3 *****************************************************************************
4 * Copyright (C) 2002-2007 the VideoLAN team
7 * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
8 * Christophe Massiot <massiot@via.ecp.fr>
9 * Derk-Jan Hartman <hartman at videolan.org>
10 * Felix Kühne <fkuehne at videolan dot org>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25 *****************************************************************************/
27 /*****************************************************************************
29 *****************************************************************************/
30 #include <stdlib.h> /* malloc(), free() */
31 #include <sys/param.h> /* for MAXPATHLEN */
37 #include <vlc_common.h>
41 #include <vlc_input.h>
42 #import <vlc_interface.h>
44 #include <vlc_vout_window.h>
47 #import "VLCMinimalVoutWindow.h"
49 /*****************************************************************************
51 *****************************************************************************/
52 static void Run ( intf_thread_t *p_intf );
54 /*****************************************************************************
55 * OpenIntf: initialize interface
56 *****************************************************************************/
57 int OpenIntf ( vlc_object_t *p_this )
59 intf_thread_t *p_intf = (intf_thread_t*) p_this;
61 p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
62 if( p_intf->p_sys == NULL )
67 memset( p_intf->p_sys, 0, sizeof( *p_intf->p_sys ) );
74 /*****************************************************************************
75 * CloseIntf: destroy interface
76 *****************************************************************************/
77 void CloseIntf ( vlc_object_t *p_this )
79 intf_thread_t *p_intf = (intf_thread_t*) p_this;
81 free( p_intf->p_sys );
85 typedef struct CPSProcessSerNum
91 extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn);
92 extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
93 extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn);
95 /*****************************************************************************
96 * KillerThread: Thread that kill the application
97 *****************************************************************************/
98 static void * KillerThread( void *user_data )
100 NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init];
102 intf_thread_t *p_intf = user_data;
104 vlc_mutex_init( &p_intf->p_sys->lock );
105 vlc_cond_init( &p_intf->p_sys->wait );
107 vlc_mutex_lock ( &p_intf->p_sys->lock );
108 while( vlc_object_alive( p_intf ) )
109 vlc_cond_wait( &p_intf->p_sys->wait, &p_intf->p_sys->lock );
110 vlc_mutex_unlock( &p_intf->p_sys->lock );
112 vlc_mutex_destroy( &p_intf->p_sys->lock );
113 vlc_cond_destroy( &p_intf->p_sys->wait );
115 /* We are dead, terminate */
116 [NSApp terminate: nil];
121 /*****************************************************************************
123 *****************************************************************************/
124 static void Run( intf_thread_t *p_intf )
128 /* Make sure the "force quit" menu item does quit instantly.
129 * VLC overrides SIGTERM which is sent by the "force quit"
130 * menu item to make sure deamon mode quits gracefully, so
131 * we un-override SIGTERM here. */
133 sigaddset( &set, SIGTERM );
134 pthread_sigmask( SIG_UNBLOCK, &set, NULL );
136 /* Setup a thread that will monitor the module killing */
137 pthread_t killer_thread;
138 pthread_create( &killer_thread, NULL, KillerThread, p_intf );
140 CPSProcessSerNum PSN;
141 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
142 [NSApplication sharedApplication];
143 if (!CPSGetCurrentProcess(&PSN))
144 if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
145 if (!CPSSetFrontProcess(&PSN))
146 [NSApplication sharedApplication];
149 pthread_join( killer_thread, NULL );
154 /*****************************************************************************
155 * Vout window management
156 *****************************************************************************/
157 static int WindowControl(vout_window_t *, int i_query, va_list);
159 int WindowOpen(vout_window_t *p_wnd, const vout_window_cfg_t *cfg)
161 NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
163 NSRect proposedVideoViewPosition = NSMakeRect(cfg->x, cfg->y, cfg->width, cfg->height);
165 VLCMinimalVoutWindow *o_window = [[VLCMinimalVoutWindow alloc] initWithContentRect:proposedVideoViewPosition];
166 [o_window makeKeyAndOrderFront:nil];
169 msg_Err(p_wnd, "window creation failed");
174 msg_Dbg(p_wnd, "returning video window with proposed position x=%i, y=%i, width=%i, height=%i", cfg->x, cfg->y, cfg->width, cfg->height);
175 p_wnd->handle.nsobject = [o_window contentView];
177 // TODO: find a cleaner way for "start in fullscreen"
178 if (var_GetBool(pl_Get(p_wnd), "fullscreen"))
179 [o_window performSelectorOnMainThread:@selector(enterFullscreen) withObject:nil waitUntilDone:NO];
181 p_wnd->control = WindowControl;
187 static int WindowControl(vout_window_t *p_wnd, int i_query, va_list args)
189 NSWindow * o_window = [(id)p_wnd->handle.nsobject window];
191 msg_Err(p_wnd, "failed to recover cocoa window");
196 case VOUT_WINDOW_SET_STATE:
198 unsigned i_state = va_arg(args, unsigned);
200 [o_window setLevel: i_state];
204 case VOUT_WINDOW_SET_SIZE:
206 NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
208 NSRect theFrame = [o_window frame];
209 unsigned int i_width = va_arg(args, unsigned int);
210 unsigned int i_height = va_arg(args, unsigned int);
211 theFrame.size.width = i_width;
212 theFrame.size.height = i_height;
213 [o_window setFrame: theFrame display: YES animate: YES];
218 case VOUT_WINDOW_SET_FULLSCREEN:
220 NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
221 int i_full = va_arg(args, int);
224 [o_window performSelectorOnMainThread:@selector(enterFullscreen) withObject:nil waitUntilDone:NO];
226 [o_window performSelectorOnMainThread:@selector(leaveFullscreen) withObject:nil waitUntilDone:NO];
232 msg_Warn(p_wnd, "unsupported control query");
237 void WindowClose(vout_window_t *p_wnd)
239 NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
241 NSWindow * o_window = [(id)p_wnd->handle.nsobject window];