File: intf.m

package info (click to toggle)
vlc 2.2.7-1~deb8u1
  • links: PTS, VCS
  • area: main
  • in suites: jessie
  • size: 191,124 kB
  • sloc: ansic: 356,116; cpp: 94,295; objc: 34,063; sh: 6,765; makefile: 4,272; xml: 1,538; asm: 1,251; python: 240; perl: 77; sed: 16
file content (237 lines) | stat: -rw-r--r-- 8,262 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
/*****************************************************************************
 * intf.m: MacOS X interface module
 *****************************************************************************
 * Copyright (C) 2002-2012 VLC authors and VideoLAN
 * $Id: b2fab4ffd610ece7b5a0765b190cff2d7bad7d4b $
 *
 * Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
 *          Felix Paul Kühne <fkuehne at videolan dot org>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

/*****************************************************************************
 * Preamble
 *****************************************************************************/
#import <stdlib.h>                                      /* malloc(), free() */
#import <sys/param.h>                                    /* for MAXPATHLEN */
#import <string.h>
#ifdef HAVE_CONFIG_H
# import "config.h"
#endif

#import <vlc_playlist.h>
#import <vlc_vout_window.h>

#import "intf.h"
#import "VLCMinimalVoutWindow.h"

/*****************************************************************************
 * Local prototypes.
 *****************************************************************************/
static void Run (intf_thread_t *p_intf);

/*****************************************************************************
 * OpenIntf: initialize interface
 *****************************************************************************/
int OpenIntf (vlc_object_t *p_this)
{
    intf_thread_t *p_intf = (intf_thread_t*) p_this;

    p_intf->p_sys = malloc(sizeof(intf_sys_t));
    if (p_intf->p_sys == NULL)
        return VLC_ENOMEM;

    memset(p_intf->p_sys, 0, sizeof(*p_intf->p_sys));

    Run(p_intf);

    return VLC_SUCCESS;
}

/*****************************************************************************
 * CloseIntf: destroy interface
 *****************************************************************************/
void CloseIntf (vlc_object_t *p_this)
{
    intf_thread_t *p_intf = (intf_thread_t*) p_this;

    free(p_intf->p_sys);
}

/* Dock Connection */
typedef struct CPSProcessSerNum
{
        UInt32                lo;
        UInt32                hi;
} CPSProcessSerNum;

extern OSErr    CPSGetCurrentProcess(CPSProcessSerNum *psn);
extern OSErr    CPSEnableForegroundOperation(CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
extern OSErr    CPSSetFrontProcess(CPSProcessSerNum *psn);

/*****************************************************************************
 * KillerThread: Thread that kill the application
 *****************************************************************************/
static void * KillerThread(void *user_data)
{
    NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init];

    intf_thread_t *p_intf = user_data;

    vlc_mutex_init(&p_intf->p_sys->lock);
    vlc_cond_init(&p_intf->p_sys->wait);

    vlc_mutex_lock (&p_intf->p_sys->lock);
    while(vlc_object_alive(p_intf))
        vlc_cond_wait(&p_intf->p_sys->wait, &p_intf->p_sys->lock);
    vlc_mutex_unlock(&p_intf->p_sys->lock);

    vlc_mutex_destroy(&p_intf->p_sys->lock);
    vlc_cond_destroy(&p_intf->p_sys->wait);

    /* We are dead, terminate */
    [NSApp terminate: nil];
    [o_pool release];
    return NULL;
}

/*****************************************************************************
 * Run: main loop
 *****************************************************************************/
static void Run(intf_thread_t *p_intf)
{
    sigset_t set;

    /* Make sure the "force quit" menu item does quit instantly.
     * VLC overrides SIGTERM which is sent by the "force quit"
     * menu item to make sure deamon mode quits gracefully, so
     * we un-override SIGTERM here. */
    sigemptyset(&set);
    sigaddset(&set, SIGTERM);
    pthread_sigmask(SIG_UNBLOCK, &set, NULL);

    /* Setup a thread that will monitor the module killing */
    pthread_t killer_thread;
    pthread_create(&killer_thread, NULL, KillerThread, p_intf);

    CPSProcessSerNum PSN;
    NSAutoreleasePool   *pool = [[NSAutoreleasePool alloc] init];
    [NSApplication sharedApplication];
    if (!CPSGetCurrentProcess(&PSN))
        if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
            if (!CPSSetFrontProcess(&PSN))
                [NSApplication sharedApplication];
    [NSApp run];

    pthread_join(killer_thread, NULL);

    [pool release];
}

/*****************************************************************************
 * Vout window management
 *****************************************************************************/
static int WindowControl(vout_window_t *, int i_query, va_list);

int WindowOpen(vout_window_t *p_wnd, const vout_window_cfg_t *cfg)
{
    NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];

    NSRect proposedVideoViewPosition = NSMakeRect(cfg->x, cfg->y, cfg->width, cfg->height);

    VLCMinimalVoutWindow *o_window = [[VLCMinimalVoutWindow alloc] initWithContentRect:proposedVideoViewPosition];
    [o_window makeKeyAndOrderFront:nil];

    if (!o_window) {
        msg_Err(p_wnd, "window creation failed");
        [o_pool release];
        return VLC_EGENERIC;
    }

    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);
    p_wnd->handle.nsobject = [o_window contentView];

    // TODO: find a cleaner way for "start in fullscreen"
    if (var_GetBool(pl_Get(p_wnd), "fullscreen"))
        [o_window performSelectorOnMainThread:@selector(enterFullscreen) withObject:nil waitUntilDone:NO];

    p_wnd->control = WindowControl;

    [o_pool release];
    return VLC_SUCCESS;
}

static int WindowControl(vout_window_t *p_wnd, int i_query, va_list args)
{
    NSWindow * o_window = [(id)p_wnd->handle.nsobject window];
    if (!o_window) {
        msg_Err(p_wnd, "failed to recover cocoa window");
        return VLC_EGENERIC;
    }

    switch (i_query) {
        case VOUT_WINDOW_SET_STATE:
        {
            unsigned i_state = va_arg(args, unsigned);

            [o_window setLevel: i_state];

            return VLC_SUCCESS;
        }
        case VOUT_WINDOW_SET_SIZE:
        {
            NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];

            NSRect theFrame = [o_window frame];
            unsigned int i_width  = va_arg(args, unsigned int);
            unsigned int i_height = va_arg(args, unsigned int);
            theFrame.size.width = i_width;
            theFrame.size.height = i_height;
            [o_window setFrame: theFrame display: YES animate: YES];

            [o_pool release];
            return VLC_SUCCESS;
        }
        case VOUT_WINDOW_SET_FULLSCREEN:
        {
            NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];
            int i_full = va_arg(args, int);

            if (i_full)
                [o_window performSelectorOnMainThread:@selector(enterFullscreen) withObject:nil waitUntilDone:NO];
            else
                [o_window performSelectorOnMainThread:@selector(leaveFullscreen) withObject:nil waitUntilDone:NO];

            [o_pool release];
            return VLC_SUCCESS;
        }
        default:
            msg_Warn(p_wnd, "unsupported control query");
            return VLC_EGENERIC;
    }
}

void WindowClose(vout_window_t *p_wnd)
{
    NSAutoreleasePool *o_pool = [[NSAutoreleasePool alloc] init];

    NSWindow * o_window = [(id)p_wnd->handle.nsobject window];
    if (o_window)
        [o_window release];

    [o_pool release];
}