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 NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
153 NSRect proposedVideoViewPosition = NSMakeRect(cfg->x, cfg->y, cfg->width, cfg->height);
155 VLCMinimalVoutWindow *o_window = [[VLCMinimalVoutWindow alloc] initWithContentRect:proposedVideoViewPosition];
156 [o_window makeKeyAndOrderFront:nil];
159 msg_Err(p_wnd, "window creation failed");
164 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);
165 p_wnd->handle.nsobject = [o_window contentView];
167 // TODO: find a cleaner way for "start in fullscreen"
168 if (var_GetBool(pl_Get(p_wnd), "fullscreen"))
169 [o_window performSelectorOnMainThread:@selector(enterFullscreen) withObject:nil waitUntilDone:NO];
171 p_wnd->control = WindowControl;
177 static int WindowControl(vout_window_t *p_wnd, int i_query, va_list args)
179 NSWindow * o_window = [(id)p_wnd->handle.nsobject window];
181 msg_Err(p_wnd, "failed to recover cocoa window");
186 case VOUT_WINDOW_SET_STATE:
188 unsigned i_state = va_arg(args, unsigned);
190 [o_window setLevel: i_state];
194 case VOUT_WINDOW_SET_SIZE:
196 NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
198 NSRect theFrame = [o_window frame];
199 unsigned int i_width = va_arg(args, unsigned int);
200 unsigned int i_height = va_arg(args, unsigned int);
201 theFrame.size.width = i_width;
202 theFrame.size.height = i_height;
203 [o_window setFrame: theFrame display: YES animate: YES];
208 case VOUT_WINDOW_SET_FULLSCREEN:
210 NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
211 int i_full = va_arg(args, int);
214 [o_window performSelectorOnMainThread:@selector(enterFullscreen) withObject:nil waitUntilDone:NO];
216 [o_window performSelectorOnMainThread:@selector(leaveFullscreen) withObject:nil waitUntilDone:NO];
222 msg_Warn(p_wnd, "unsupported control query");
227 void WindowClose(vout_window_t *p_wnd)
229 NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
231 NSWindow * o_window = [(id)p_wnd->handle.nsobject window];