Reimplement libvlc_video_set_parent back-end as a plugin
[vlc.git] / 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 library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2.0
11  * of the License, or (at your option) any later version.
12  *
13  * This library 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 General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, 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.h>
33 #include <vlc_window.h>
34
35 static int  Open (vlc_object_t *);
36 static void Close (vlc_object_t *);
37
38 /*
39  * Module descriptor
40  */
41 vlc_module_begin ()
42     set_shortname (N_("Drawable"))
43     set_description (N_("External embedded video window"))
44     set_category (CAT_VIDEO)
45     set_subcategory (SUBCAT_VIDEO_VOUT)
46 #ifdef WIN32
47     set_capability ("hwnd", 70)
48 #else
49     set_capability ("xwindow", 70)
50 #endif
51     set_callbacks (Open, Close)
52
53 vlc_module_end ()
54
55 static int Control (vout_window_t *, int, va_list);
56
57 /**
58  * Find the drawable set by libvlc application.
59  */
60 static int Open (vlc_object_t *obj)
61 {
62     static vlc_mutex_t serializer = VLC_STATIC_MUTEX;
63     vout_window_t *wnd = (vout_window_t *)obj;
64     int drawable = 0;
65
66     if (var_Create (obj->p_libvlc, "drawable-busy", VLC_VAR_BOOL))
67         return VLC_ENOMEM;
68
69     vlc_mutex_lock (&serializer);
70     /* Note: We cannot simply clear the drawable variable.
71      * It would break libvlc_video_get_parent(). */
72     if (!var_GetBool (obj->p_libvlc, "drawable-busy"))
73     {
74         /* TODO: implement separate variables for XIDs and HWNDs */
75         drawable = var_GetInteger (obj->p_libvlc, "drawable");
76         if (drawable != 0)
77             var_SetBool (obj->p_libvlc, "drawable-busy", true);
78     }
79     vlc_mutex_unlock (&serializer);
80
81     if (drawable == 0)
82     {
83         var_Destroy (obj->p_libvlc, "drawable-busy");
84         return VLC_EGENERIC;
85     }
86
87 #ifdef WIN32
88     /* FIXME: don't loose critical bits on Win64 */
89     wnd->handle.hwnd = (void *)drawable;
90 #else
91     /* FIXME: check that X server matches --x11-display (if specified) */
92     /* FIXME: get X drawable dimensions */
93     wnd->handle.xid = drawable;
94 #endif
95     /* FIXME: get window size (in platform-dependent ways) */
96
97     wnd->control = Control;
98     return VLC_SUCCESS;
99 }
100
101
102 /**
103  * Release the drawable.
104  */
105 static void Close (vlc_object_t *obj)
106 {
107     /* This is atomic with regards to var_GetBool() in Open(): */
108     var_SetBool (obj->p_libvlc, "drawable-busy", false);
109
110     /* Variables are reference-counted... */
111     var_Destroy (obj->p_libvlc, "drawable-busy");
112 }
113
114
115 static int Control (vout_window_t *wnd, int query, va_list ap)
116 {
117     switch (query)
118     {
119         case VOUT_GET_SIZE:
120         {
121             unsigned int *pi_width = va_arg (ap, unsigned int *);
122             unsigned int *pi_height = va_arg (ap, unsigned int *);
123             *pi_width = wnd->width;
124             *pi_height = wnd->height;
125             return VLC_SUCCESS;
126         }
127
128         case VOUT_SET_SIZE: /* not allowed */
129         case VOUT_SET_STAY_ON_TOP: /* not allowed either, would be ugly */
130             return VLC_EGENERIC;
131     }
132
133     msg_Warn (wnd, "unsupported control query %d", query);
134     return VLC_EGENERIC;
135 }
136