]> git.sesse.net Git - vlc/blob - modules/gui/minimal_macosx/intf.m
minimal_macosx: updated copyright headers
[vlc] / modules / gui / minimal_macosx / intf.m
1 /*****************************************************************************
2  * intf.m: MacOS X interface module
3  *****************************************************************************
4  * Copyright (C) 2002-2012 VLC authors and VideoLAN
5  * $Id$
6  *
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>
11  *
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.
16  *
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.
21  *
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  *****************************************************************************/
26
27 /*****************************************************************************
28  * Preamble
29  *****************************************************************************/
30 #import <stdlib.h>                                      /* malloc(), free() */
31 #import <sys/param.h>                                    /* for MAXPATHLEN */
32 #import <string.h>
33 #ifdef HAVE_CONFIG_H
34 # import "config.h"
35 #endif
36
37 #import <vlc_playlist.h>
38 #import <vlc_vout_window.h>
39
40 #import "intf.h"
41 #import "VLCMinimalVoutWindow.h"
42
43 /*****************************************************************************
44  * Local prototypes.
45  *****************************************************************************/
46 static void Run (intf_thread_t *p_intf);
47
48 /*****************************************************************************
49  * OpenIntf: initialize interface
50  *****************************************************************************/
51 int OpenIntf (vlc_object_t *p_this)
52 {
53     intf_thread_t *p_intf = (intf_thread_t*) p_this;
54         
55     p_intf->p_sys = malloc(sizeof(intf_sys_t));
56     if (p_intf->p_sys == NULL)
57         return VLC_ENOMEM;
58
59     memset(p_intf->p_sys, 0, sizeof(*p_intf->p_sys));
60
61     Run(p_intf);
62
63     return VLC_SUCCESS;
64 }
65
66 /*****************************************************************************
67  * CloseIntf: destroy interface
68  *****************************************************************************/
69 void CloseIntf (vlc_object_t *p_this)
70 {
71     intf_thread_t *p_intf = (intf_thread_t*) p_this;
72
73     free(p_intf->p_sys);
74 }
75
76 /* Dock Connection */
77 typedef struct CPSProcessSerNum
78 {
79         UInt32                lo;
80         UInt32                hi;
81 } CPSProcessSerNum;
82
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);
86
87 /*****************************************************************************
88  * KillerThread: Thread that kill the application
89  *****************************************************************************/
90 static void * KillerThread(void *user_data)
91 {
92     NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init];
93
94     intf_thread_t *p_intf = user_data;
95
96     vlc_mutex_init(&p_intf->p_sys->lock);
97     vlc_cond_init(&p_intf->p_sys->wait);
98
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);
103
104     vlc_mutex_destroy(&p_intf->p_sys->lock);
105     vlc_cond_destroy(&p_intf->p_sys->wait);
106
107     /* We are dead, terminate */
108     [NSApp terminate: nil];
109     [o_pool release];
110     return NULL;
111 }
112
113 /*****************************************************************************
114  * Run: main loop
115  *****************************************************************************/
116 static void Run(intf_thread_t *p_intf)
117 {
118     sigset_t set;
119
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. */
124     sigemptyset(&set);
125     sigaddset(&set, SIGTERM);
126     pthread_sigmask(SIG_UNBLOCK, &set, NULL);
127
128     /* Setup a thread that will monitor the module killing */
129     pthread_t killer_thread;
130     pthread_create(&killer_thread, NULL, KillerThread, p_intf);
131
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];
139     [NSApp run];
140
141     pthread_join(killer_thread, NULL);
142
143     [pool release];
144 }
145
146 /*****************************************************************************
147  * Vout window management
148  *****************************************************************************/
149 static int WindowControl(vout_window_t *, int i_query, va_list);
150
151 int WindowOpen(vout_window_t *p_wnd, const vout_window_cfg_t *cfg)
152 {
153     NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
154
155     NSRect proposedVideoViewPosition = NSMakeRect(cfg->x, cfg->y, cfg->width, cfg->height);
156
157     VLCMinimalVoutWindow *o_window = [[VLCMinimalVoutWindow alloc] initWithContentRect:proposedVideoViewPosition];
158     [o_window makeKeyAndOrderFront:nil];
159
160     if (!o_window) {
161         msg_Err(p_wnd, "window creation failed");
162         [o_pool release];
163         return VLC_EGENERIC;
164     }
165
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];
168
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];
172
173     p_wnd->control = WindowControl;
174
175     [o_pool release];
176     return VLC_SUCCESS;
177 }
178
179 static int WindowControl(vout_window_t *p_wnd, int i_query, va_list args)
180 {
181     NSWindow * o_window = [(id)p_wnd->handle.nsobject window];
182     if (!o_window) {
183         msg_Err(p_wnd, "failed to recover cocoa window");
184         return VLC_EGENERIC;
185     }
186
187     switch (i_query) {
188         case VOUT_WINDOW_SET_STATE:
189         {
190             unsigned i_state = va_arg(args, unsigned);
191
192             [o_window setLevel: i_state];
193
194             return VLC_SUCCESS;
195         }
196         case VOUT_WINDOW_SET_SIZE:
197         {
198             NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
199
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];
206
207             [o_pool release];
208             return VLC_SUCCESS;
209         }
210         case VOUT_WINDOW_SET_FULLSCREEN:
211         {
212             NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
213             int i_full = va_arg(args, int);
214
215             if (i_full)
216                 [o_window performSelectorOnMainThread:@selector(enterFullscreen) withObject:nil waitUntilDone:NO];
217             else
218                 [o_window performSelectorOnMainThread:@selector(leaveFullscreen) withObject:nil waitUntilDone:NO];
219
220             [o_pool release];
221             return VLC_SUCCESS;
222         }
223         default:
224             msg_Warn(p_wnd, "unsupported control query");
225             return VLC_EGENERIC;
226     }
227 }
228
229 void WindowClose(vout_window_t *p_wnd)
230 {
231     NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
232
233     NSWindow * o_window = [(id)p_wnd->handle.nsobject window];
234     if (o_window)
235         [o_window release];
236
237     [o_pool release];
238 }
239