qt: playlist: use item title if available
[vlc.git] / modules / gui / minimal_macosx / intf.m
1 /*****************************************************************************
2  * intf.m: macOS minimal interface module
3  *****************************************************************************
4  * Copyright (C) 2002-2017 VLC authors and VideoLAN
5  *
6  * Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
7  *          Felix Paul K├╝hne <fkuehne at videolan dot org>
8  *
9  * This program is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #import <stdlib.h>
28 #import <string.h>
29 #import <unistd.h>
30
31 #ifdef HAVE_CONFIG_H
32 # import "config.h"
33 #endif
34
35 #import <vlc_common.h>
36 #import <vlc_interface.h>
37 #import <vlc_vout_window.h>
38
39 #import "VLCMinimalVoutWindow.h"
40
41 /*****************************************************************************
42  * Local prototypes.
43  *****************************************************************************/
44 static void Run (intf_thread_t *p_intf);
45
46 /*****************************************************************************
47  * OpenIntf: initialize interface
48  *****************************************************************************/
49 int OpenIntf (vlc_object_t *p_this)
50 {
51     intf_thread_t *p_intf = (intf_thread_t*) p_this;
52     msg_Dbg(p_intf, "Using minimal macosx interface");
53
54     p_intf->p_sys = NULL;
55
56     Run(p_intf);
57
58     return VLC_SUCCESS;
59 }
60
61 /*****************************************************************************
62  * CloseIntf: destroy interface
63  *****************************************************************************/
64 void CloseIntf (vlc_object_t *p_this)
65 {
66     intf_thread_t *p_intf = (intf_thread_t*) p_this;
67
68     free(p_intf->p_sys);
69 }
70
71 /* Dock Connection */
72 typedef struct CPSProcessSerNum
73 {
74         UInt32                lo;
75         UInt32                hi;
76 } CPSProcessSerNum;
77
78 extern OSErr    CPSGetCurrentProcess(CPSProcessSerNum *psn);
79 extern OSErr    CPSEnableForegroundOperation(CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
80 extern OSErr    CPSSetFrontProcess(CPSProcessSerNum *psn);
81
82
83 /*****************************************************************************
84  * Run: main loop
85  *****************************************************************************/
86 static void Run(intf_thread_t *p_intf)
87 {
88     CPSProcessSerNum PSN;
89     @autoreleasepool {
90         [NSApplication sharedApplication];
91         if (!CPSGetCurrentProcess(&PSN))
92             if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
93                 if (!CPSSetFrontProcess(&PSN))
94                     [NSApplication sharedApplication];
95     }
96 }
97
98 /*****************************************************************************
99  * Vout window management
100  *****************************************************************************/
101
102 static int WindowEnable(vout_window_t *p_wnd, const vout_window_cfg_t *cfg)
103 {
104     @autoreleasepool {
105         VLCMinimalVoutWindow __block *o_window;
106         NSRect proposedVideoViewPosition = NSMakeRect(cfg->x, cfg->y, cfg->width, cfg->height);
107
108         dispatch_sync(dispatch_get_main_queue(), ^{
109             o_window = [[VLCMinimalVoutWindow alloc] initWithContentRect:proposedVideoViewPosition];
110             [o_window makeKeyAndOrderFront:nil];
111         });
112
113         if (!o_window) {
114             msg_Err(p_wnd, "window creation failed");
115             return VLC_EGENERIC;
116         }
117
118         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);
119         p_wnd->handle.nsobject = (void *)CFBridgingRetain([o_window contentView]);
120     }
121
122     if (cfg->is_fullscreen)
123         vout_window_SetFullScreen(p_wnd, NULL);
124     return VLC_SUCCESS;
125 }
126
127 static void WindowDisable(vout_window_t *p_wnd)
128 {
129     @autoreleasepool {
130         NSWindow * o_window = [(__bridge id)p_wnd->handle.nsobject window];
131         if (o_window)
132             o_window = nil;
133     }
134 }
135
136 static void WindowResize(vout_window_t *p_wnd,
137                          unsigned i_width, unsigned i_height)
138 {
139     NSWindow* o_window = [(__bridge id)p_wnd->handle.nsobject window];
140
141     @autoreleasepool {
142         dispatch_sync(dispatch_get_main_queue(), ^{
143             NSRect theFrame = [o_window frame];
144             theFrame.size.width = i_width;
145             theFrame.size.height = i_height;
146             [o_window setFrame:theFrame display:YES animate:YES];
147         });
148     }
149 }
150
151 static void WindowSetState(vout_window_t *p_wnd, unsigned state)
152 {
153     NSWindow* o_window = [(__bridge id)p_wnd->handle.nsobject window];
154
155     [o_window setLevel:state];
156 }
157
158 static void WindowUnsetFullscreen(vout_window_t *p_wnd)
159 {
160     NSWindow* o_window = [(__bridge id)p_wnd->handle.nsobject window];
161
162     @autoreleasepool {
163         dispatch_sync(dispatch_get_main_queue(), ^{
164             [(VLCMinimalVoutWindow*)o_window leaveFullscreen];
165         });
166     }
167 }
168
169 static void WindowSetFullscreen(vout_window_t *p_wnd, const char *psz_id)
170 {
171     NSWindow* o_window = [(__bridge id)p_wnd->handle.nsobject window];
172
173     @autoreleasepool {
174         dispatch_sync(dispatch_get_main_queue(), ^{
175             [(VLCMinimalVoutWindow*)o_window enterFullscreen];
176         });
177     }
178 }
179
180 static void WindowClose(vout_window_t *);
181
182 static const struct vout_window_operations ops = {
183     WindowEnable,
184     WindowDisable,
185     WindowResize,
186     NULL,
187     WindowSetState,
188     WindowUnsetFullscreen,
189     WindowSetFullscreen,
190     NULL,
191 };
192
193 int WindowOpen(vout_window_t *p_wnd)
194 {
195     p_wnd->type = VOUT_WINDOW_TYPE_NSOBJECT;
196     p_wnd->ops = &ops;
197     return VLC_SUCCESS;
198 }