]> git.sesse.net Git - vlc/blob - modules/video_output/drawable.c
Wav: No tabs in source code
[vlc] / modules / video_output / drawable.c
1 /**
2  * @file drawable.c
3  * @brief Legacy monolithic LibVLC video window provider
4  */
5 /*****************************************************************************
6  * Copyright © 2009 Rémi Denis-Courmont
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation; either version 2.1 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21  *****************************************************************************/
22
23 #ifdef HAVE_CONFIG_H
24 # include <config.h>
25 #endif
26
27 #include <stdarg.h>
28 #include <assert.h>
29
30 #include <vlc_common.h>
31 #include <vlc_plugin.h>
32 #include <vlc_vout_window.h>
33
34 #define HWND_TEXT N_("Window handle (HWND)")
35 #define HWND_LONGTEXT N_( \
36     "Video will be embedded in this pre-existing window. " \
37     "If zero, a new window will be created.")
38
39 static int  Open (vout_window_t *, const vout_window_cfg_t *);
40 static void Close(vout_window_t *);
41
42 /*
43  * Module descriptor
44  */
45 vlc_module_begin ()
46     set_shortname (N_("Drawable"))
47     set_description (N_("Embedded window video"))
48     set_category (CAT_VIDEO)
49     set_subcategory (SUBCAT_VIDEO_VOUT)
50     set_capability ("vout window hwnd", 0)
51     set_callbacks (Open, Close)
52     add_shortcut ("embed-hwnd")
53
54     add_integer ("drawable-hwnd", 0, HWND_TEXT, HWND_LONGTEXT, true)
55         change_volatile ()
56 vlc_module_end ()
57
58 static int Control (vout_window_t *, int, va_list);
59
60 /* Keep a list of busy drawables, so we don't overlap videos if there are
61  * more than one video track in the stream. */
62 static vlc_mutex_t serializer = VLC_STATIC_MUTEX;
63 static uintptr_t *used = NULL;
64
65 /**
66  * Find the drawable set by libvlc application.
67  */
68 static int Open (vout_window_t *wnd, const vout_window_cfg_t *cfg)
69 {
70     VLC_UNUSED (cfg);
71     uintptr_t val = var_InheritInteger (wnd, "drawable-hwnd");
72     if (val == 0)
73         return VLC_EGENERIC;
74
75     uintptr_t *tab;
76     size_t n = 0;
77
78     vlc_mutex_lock (&serializer);
79     if (used != NULL)
80         for (/*n = 0*/; used[n]; n++)
81             if (used[n] == val)
82             {
83                 msg_Warn (wnd, "HWND 0x%zX is busy", val);
84                 val = 0;
85                 goto skip;
86             }
87
88     tab = realloc (used, sizeof (*used) * (n + 2));
89     if (likely(tab != NULL))
90     {
91         used = tab;
92         used[n] = val;
93         used[n + 1] = 0;
94     }
95     else
96         val = 0;
97 skip:
98     vlc_mutex_unlock (&serializer);
99
100     if (val == 0)
101         return VLC_EGENERIC;
102
103     wnd->handle.hwnd = (void *)val;
104     wnd->control = Control;
105     wnd->sys = (void *)val;
106     return VLC_SUCCESS;
107 }
108
109 /**
110  * Release the drawable.
111  */
112 static void Close (vout_window_t *wnd)
113 {
114     uintptr_t val = (uintptr_t)wnd->sys;
115     size_t n = 0;
116
117     /* Remove this drawable from the list of busy ones */
118     vlc_mutex_lock (&serializer);
119     assert (used != NULL);
120     while (used[n] != val)
121     {
122         assert (used[n]);
123         n++;
124     }
125     do
126         used[n] = used[n + 1];
127     while (used[++n] != 0);
128
129     if (n == 0)
130     {
131          free (used);
132          used = NULL;
133     }
134     vlc_mutex_unlock (&serializer);
135 }
136
137
138 static int Control (vout_window_t *wnd, int query, va_list ap)
139 {
140     VLC_UNUSED( ap );
141
142     switch (query)
143     {
144         case VOUT_WINDOW_SET_SIZE:   /* not allowed */
145         case VOUT_WINDOW_SET_STATE: /* not allowed either, would be ugly */
146             return VLC_EGENERIC;
147         default:
148             msg_Warn (wnd, "unsupported control query %d", query);
149             return VLC_EGENERIC;
150     }
151 }