1 /*****************************************************************************
2 * intf.m: MacOS X interface module
3 *****************************************************************************
4 * Copyright (C) 2002-2012 VLC authors and VideoLAN
7 * Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
8 * Felix Paul Kühne <fkuehne at videolan dot org>
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
28 #import <stdlib.h> /* malloc(), free() */
29 #import <sys/param.h> /* for MAXPATHLEN */
35 #import <vlc_playlist.h>
36 #import <vlc_vout_window.h>
39 #import "VLCMinimalVoutWindow.h"
41 /*****************************************************************************
43 *****************************************************************************/
44 static void Run (intf_thread_t *p_intf);
46 /*****************************************************************************
47 * OpenIntf: initialize interface
48 *****************************************************************************/
49 int OpenIntf (vlc_object_t *p_this)
51 intf_thread_t *p_intf = (intf_thread_t*) p_this;
53 p_intf->p_sys = malloc(sizeof(intf_sys_t));
54 if (p_intf->p_sys == NULL)
57 memset(p_intf->p_sys, 0, sizeof(*p_intf->p_sys));
64 /*****************************************************************************
65 * CloseIntf: destroy interface
66 *****************************************************************************/
67 void CloseIntf (vlc_object_t *p_this)
69 intf_thread_t *p_intf = (intf_thread_t*) p_this;
75 typedef struct CPSProcessSerNum
81 extern OSErr CPSGetCurrentProcess(CPSProcessSerNum *psn);
82 extern OSErr CPSEnableForegroundOperation(CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
83 extern OSErr CPSSetFrontProcess(CPSProcessSerNum *psn);
85 /*****************************************************************************
86 * KillerThread: Thread that kill the application
87 *****************************************************************************/
88 static void * KillerThread(void *user_data)
90 NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init];
92 intf_thread_t *p_intf = user_data;
94 vlc_mutex_init(&p_intf->p_sys->lock);
95 vlc_cond_init(&p_intf->p_sys->wait);
97 vlc_mutex_lock (&p_intf->p_sys->lock);
98 while(vlc_object_alive(p_intf))
99 vlc_cond_wait(&p_intf->p_sys->wait, &p_intf->p_sys->lock);
100 vlc_mutex_unlock(&p_intf->p_sys->lock);
102 vlc_mutex_destroy(&p_intf->p_sys->lock);
103 vlc_cond_destroy(&p_intf->p_sys->wait);
105 /* We are dead, terminate */
106 [NSApp terminate: nil];
111 /*****************************************************************************
113 *****************************************************************************/
114 static void Run(intf_thread_t *p_intf)
118 /* Make sure the "force quit" menu item does quit instantly.
119 * VLC overrides SIGTERM which is sent by the "force quit"
120 * menu item to make sure deamon mode quits gracefully, so
121 * we un-override SIGTERM here. */
123 sigaddset(&set, SIGTERM);
124 pthread_sigmask(SIG_UNBLOCK, &set, NULL);
126 /* Setup a thread that will monitor the module killing */
127 pthread_t killer_thread;
128 pthread_create(&killer_thread, NULL, KillerThread, p_intf);
130 CPSProcessSerNum PSN;
131 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
132 [NSApplication sharedApplication];
133 if (!CPSGetCurrentProcess(&PSN))
134 if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
135 if (!CPSSetFrontProcess(&PSN))
136 [NSApplication sharedApplication];
139 pthread_join(killer_thread, NULL);
144 /*****************************************************************************
145 * Vout window management
146 *****************************************************************************/
147 static int WindowControl(vout_window_t *, int i_query, va_list);
149 int WindowOpen(vout_window_t *p_wnd, const vout_window_cfg_t *cfg)
151 if (cfg->type != VOUT_WINDOW_TYPE_INVALID
152 && cfg->type != VOUT_WINDOW_TYPE_NSOBJECT)
155 NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
157 NSRect proposedVideoViewPosition = NSMakeRect(cfg->x, cfg->y, cfg->width, cfg->height);
159 VLCMinimalVoutWindow *o_window = [[VLCMinimalVoutWindow alloc] initWithContentRect:proposedVideoViewPosition];
160 [o_window makeKeyAndOrderFront:nil];
163 msg_Err(p_wnd, "window creation failed");
168 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);
169 p_wnd->handle.nsobject = [o_window contentView];
171 // TODO: find a cleaner way for "start in fullscreen"
172 if (var_GetBool(pl_Get(p_wnd), "fullscreen"))
173 [o_window performSelectorOnMainThread:@selector(enterFullscreen) withObject:nil waitUntilDone:NO];
175 p_wnd->type = VOUT_WINDOW_TYPE_NSOBJECT;
176 p_wnd->control = WindowControl;
182 static int WindowControl(vout_window_t *p_wnd, int i_query, va_list args)
184 NSWindow * o_window = [(id)p_wnd->handle.nsobject window];
186 msg_Err(p_wnd, "failed to recover cocoa window");
191 case VOUT_WINDOW_SET_STATE:
193 unsigned i_state = va_arg(args, unsigned);
195 [o_window setLevel: i_state];
199 case VOUT_WINDOW_SET_SIZE:
201 NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
203 NSRect theFrame = [o_window frame];
204 unsigned int i_width = va_arg(args, unsigned int);
205 unsigned int i_height = va_arg(args, unsigned int);
206 theFrame.size.width = i_width;
207 theFrame.size.height = i_height;
208 [o_window setFrame: theFrame display: YES animate: YES];
213 case VOUT_WINDOW_SET_FULLSCREEN:
215 NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
216 int i_full = va_arg(args, int);
219 [o_window performSelectorOnMainThread:@selector(enterFullscreen) withObject:nil waitUntilDone:NO];
221 [o_window performSelectorOnMainThread:@selector(leaveFullscreen) withObject:nil waitUntilDone:NO];
227 msg_Warn(p_wnd, "unsupported control query");
232 void WindowClose(vout_window_t *p_wnd)
234 NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
236 NSWindow * o_window = [(id)p_wnd->handle.nsobject window];