]> git.sesse.net Git - vlc/blob - src/video_output/window.c
sftp: change item b_net
[vlc] / src / video_output / window.c
1 /*****************************************************************************
2  * window.c: "vout window" managment
3  *****************************************************************************
4  * Copyright (C) 2009 Laurent Aimar
5  * $Id$
6  *
7  * Authors: Laurent Aimar <fenrir _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 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30 #include <assert.h>
31
32 #include <vlc_common.h>
33 #include <vlc_vout_window.h>
34 #include <vlc_modules.h>
35 #include "inhibit.h"
36 #include <libvlc.h>
37
38 typedef struct
39 {
40     vout_window_t wnd;
41     module_t *module;
42     vlc_inhibit_t *inhibit;
43 } window_t;
44
45 static int vout_window_start(void *func, va_list ap)
46 {
47     int (*activate)(vout_window_t *, const vout_window_cfg_t *) = func;
48     vout_window_t *wnd = va_arg(ap, vout_window_t *);
49     const vout_window_cfg_t *cfg = va_arg(ap, const vout_window_cfg_t *);
50
51     return activate(wnd, cfg);
52 }
53
54 vout_window_t *vout_window_New(vlc_object_t *obj, const char *module,
55                                const vout_window_cfg_t *cfg,
56                                const vout_window_owner_t *owner)
57 {
58     window_t *w = vlc_custom_create(obj, sizeof(*w), "window");
59     vout_window_t *window = &w->wnd;
60
61     memset(&window->handle, 0, sizeof(window->handle));
62     window->control = NULL;
63     window->sys = NULL;
64
65     if (owner != NULL)
66         window->owner = *owner;
67     else
68         window->owner.resized = NULL;
69
70     w->module = vlc_module_load(window, "vout window", module,
71                                 module && *module,
72                                 vout_window_start, window, cfg);
73     if (!w->module) {
74         vlc_object_release(window);
75         return NULL;
76     }
77
78     /* Hook for screensaver inhibition */
79     if (var_InheritBool(obj, "disable-screensaver") &&
80         window->type == VOUT_WINDOW_TYPE_XID) {
81         w->inhibit = vlc_inhibit_Create(VLC_OBJECT (window));
82         if (w->inhibit != NULL)
83             vlc_inhibit_Set(w->inhibit, VLC_INHIBIT_VIDEO);
84             /* FIXME: ^ wait for vout activation, pause */
85     }
86     else
87         w->inhibit = NULL;
88     return window;
89 }
90
91 static void vout_window_stop(void *func, va_list ap)
92 {
93     int (*deactivate)(vout_window_t *) = func;
94     vout_window_t *wnd = va_arg(ap, vout_window_t *);
95
96     deactivate(wnd);
97 }
98
99 void vout_window_Delete(vout_window_t *window)
100 {
101     if (!window)
102         return;
103
104     window_t *w = (window_t *)window;
105     if (w->inhibit)
106     {
107         vlc_inhibit_Set (w->inhibit, VLC_INHIBIT_NONE);
108         vlc_inhibit_Destroy (w->inhibit);
109     }
110
111     vlc_module_unload(w->module, vout_window_stop, window);
112     vlc_object_release(window);
113 }
114
115 /* Video output display integration */
116 #include <vlc_vout.h>
117 #include <vlc_vout_display.h>
118 #include "window.h"
119 #include "event.h"
120
121 typedef struct vout_display_window
122 {
123     vout_display_t *vd;
124     unsigned width;
125     unsigned height;
126
127     vlc_mutex_t lock;
128 } vout_display_window_t;
129
130 static void vout_display_window_ResizeNotify(vout_window_t *window,
131                                              unsigned width, unsigned height)
132 {
133     vout_display_window_t *state = window->owner.sys;
134
135     msg_Dbg(window, "resized to %ux%u", width, height);
136     vlc_mutex_lock(&state->lock);
137     state->width = width;
138     state->height = height;
139
140     if (state->vd != NULL)
141         vout_display_SendEventDisplaySize(state->vd, width, height);
142     vlc_mutex_unlock(&state->lock);
143 }
144
145 static void vout_display_window_CloseNotify(vout_window_t *window)
146 {
147     vout_thread_t *vout = (vout_thread_t *)window->p_parent;
148
149     vout_SendEventClose(vout);
150 }
151
152 /**
153  * Creates a video window, initially without any attached display.
154  */
155 vout_window_t *vout_display_window_New(vout_thread_t *vout,
156                                        const vout_window_cfg_t *cfg)
157 {
158     vout_display_window_t *state = malloc(sizeof (*state));
159     if (state == NULL)
160         return NULL;
161
162     state->vd = NULL;
163     state->width = cfg->width;
164     state->height = cfg->height;
165     vlc_mutex_init(&state->lock);
166
167     vout_window_owner_t owner = {
168         .sys = state,
169         .resized = vout_display_window_ResizeNotify,
170         .closed = vout_display_window_CloseNotify,
171     };
172     vout_window_t *window;
173
174     window = vout_window_New((vlc_object_t *)vout, "$window", cfg, &owner);
175     if (window == NULL) {
176         vlc_mutex_destroy(&state->lock);
177         free(state);
178     }
179     return window;
180 }
181
182 /**
183  * Attaches a window to a display. Window events will be dispatched to the
184  * display until they are detached.
185  */
186 void vout_display_window_Attach(vout_window_t *window, vout_display_t *vd)
187 {
188     vout_display_window_t *state = window->owner.sys;
189
190     vout_window_SetSize(window,
191                         vd->cfg->display.width, vd->cfg->display.height);
192
193     vlc_mutex_lock(&state->lock);
194     state->vd = vd;
195
196     vout_display_SendEventDisplaySize(vd, state->width, state->height);
197     vlc_mutex_unlock(&state->lock);
198 }
199
200 /**
201  * Detaches a window from a display. Window events will no longer be dispatched
202  * (except those that do not need a display).
203  */
204 void vout_display_window_Detach(vout_window_t *window)
205 {
206     vout_display_window_t *state = window->owner.sys;
207
208     vlc_mutex_lock(&state->lock);
209     state->vd = NULL;
210     vlc_mutex_unlock(&state->lock);
211 }
212
213 /**
214  * Destroys a video window.
215  * \note The window must be detached.
216  */
217 void vout_display_window_Delete(vout_window_t *window)
218 {
219     vout_display_window_t *state = window->owner.sys;
220
221     vout_window_Delete(window);
222
223     assert(state->vd == NULL);
224     vlc_mutex_destroy(&state->lock);
225     free(state);
226 }