1 /*****************************************************************************
2 * intf.m: MacOS X interface module
3 *****************************************************************************
4 * Copyright (C) 2002-2012 VLC authors and VideoLAN
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 Paul 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 #import <stdlib.h> /* malloc(), free() */
31 #import <sys/param.h> /* for MAXPATHLEN */
37 #import <vlc_playlist.h>
38 #import <vlc_vout_window.h>
41 #import "VLCMinimalVoutWindow.h"
43 /*****************************************************************************
45 *****************************************************************************/
46 static void Run (intf_thread_t *p_intf);
48 /*****************************************************************************
49 * OpenIntf: initialize interface
50 *****************************************************************************/
51 int OpenIntf (vlc_object_t *p_this)
53 intf_thread_t *p_intf = (intf_thread_t*) p_this;
55 p_intf->p_sys = malloc(sizeof(intf_sys_t));
56 if (p_intf->p_sys == NULL)
59 memset(p_intf->p_sys, 0, sizeof(*p_intf->p_sys));
66 /*****************************************************************************
67 * CloseIntf: destroy interface
68 *****************************************************************************/
69 void CloseIntf (vlc_object_t *p_this)
71 intf_thread_t *p_intf = (intf_thread_t*) p_this;
77 typedef struct CPSProcessSerNum
83 extern OSErr CPSGetCurrentProcess(CPSProcessSerNum *psn);
84 extern OSErr CPSEnableForegroundOperation(CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
85 extern OSErr CPSSetFrontProcess(CPSProcessSerNum *psn);
87 /*****************************************************************************
88 * KillerThread: Thread that kill the application
89 *****************************************************************************/
90 static void * KillerThread(void *user_data)
92 NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init];
94 intf_thread_t *p_intf = user_data;
96 vlc_mutex_init(&p_intf->p_sys->lock);
97 vlc_cond_init(&p_intf->p_sys->wait);
99 vlc_mutex_lock (&p_intf->p_sys->lock);
100 while(vlc_object_alive(p_intf))
101 vlc_cond_wait(&p_intf->p_sys->wait, &p_intf->p_sys->lock);
102 vlc_mutex_unlock(&p_intf->p_sys->lock);
104 vlc_mutex_destroy(&p_intf->p_sys->lock);
105 vlc_cond_destroy(&p_intf->p_sys->wait);
107 /* We are dead, terminate */
108 [NSApp terminate: nil];
113 /*****************************************************************************
115 *****************************************************************************/
116 static void Run(intf_thread_t *p_intf)
120 /* Make sure the "force quit" menu item does quit instantly.
121 * VLC overrides SIGTERM which is sent by the "force quit"
122 * menu item to make sure deamon mode quits gracefully, so
123 * we un-override SIGTERM here. */
125 sigaddset(&set, SIGTERM);
126 pthread_sigmask(SIG_UNBLOCK, &set, NULL);
128 /* Setup a thread that will monitor the module killing */
129 pthread_t killer_thread;
130 pthread_create(&killer_thread, NULL, KillerThread, p_intf);
132 CPSProcessSerNum PSN;
133 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
134 [NSApplication sharedApplication];
135 if (!CPSGetCurrentProcess(&PSN))
136 if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
137 if (!CPSSetFrontProcess(&PSN))
138 [NSApplication sharedApplication];
141 pthread_join(killer_thread, NULL);
146 /*****************************************************************************
147 * Vout window management
148 *****************************************************************************/
149 static int WindowControl(vout_window_t *, int i_query, va_list);
151 int WindowOpen(vout_window_t *p_wnd, const vout_window_cfg_t *cfg)
153 NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
155 NSRect proposedVideoViewPosition = NSMakeRect(cfg->x, cfg->y, cfg->width, cfg->height);
157 VLCMinimalVoutWindow *o_window = [[VLCMinimalVoutWindow alloc] initWithContentRect:proposedVideoViewPosition];
158 [o_window makeKeyAndOrderFront:nil];
161 msg_Err(p_wnd, "window creation failed");
166 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);
167 p_wnd->handle.nsobject = [o_window contentView];
169 // TODO: find a cleaner way for "start in fullscreen"
170 if (var_GetBool(pl_Get(p_wnd), "fullscreen"))
171 [o_window performSelectorOnMainThread:@selector(enterFullscreen) withObject:nil waitUntilDone:NO];
173 p_wnd->control = WindowControl;
179 static int WindowControl(vout_window_t *p_wnd, int i_query, va_list args)
181 NSWindow * o_window = [(id)p_wnd->handle.nsobject window];
183 msg_Err(p_wnd, "failed to recover cocoa window");
188 case VOUT_WINDOW_SET_STATE:
190 unsigned i_state = va_arg(args, unsigned);
192 [o_window setLevel: i_state];
196 case VOUT_WINDOW_SET_SIZE:
198 NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
200 NSRect theFrame = [o_window frame];
201 unsigned int i_width = va_arg(args, unsigned int);
202 unsigned int i_height = va_arg(args, unsigned int);
203 theFrame.size.width = i_width;
204 theFrame.size.height = i_height;
205 [o_window setFrame: theFrame display: YES animate: YES];
210 case VOUT_WINDOW_SET_FULLSCREEN:
212 NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
213 int i_full = va_arg(args, int);
216 [o_window performSelectorOnMainThread:@selector(enterFullscreen) withObject:nil waitUntilDone:NO];
218 [o_window performSelectorOnMainThread:@selector(leaveFullscreen) withObject:nil waitUntilDone:NO];
224 msg_Warn(p_wnd, "unsupported control query");
229 void WindowClose(vout_window_t *p_wnd)
231 NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
233 NSWindow * o_window = [(id)p_wnd->handle.nsobject window];