]> git.sesse.net Git - vlc/blob - modules/video_output/msw/glwin32.c
c6173b8c3176a6cb4940ebb81f2336f4b7eea9f2
[vlc] / modules / video_output / msw / glwin32.c
1 /*****************************************************************************
2  * glwin32.c: Windows OpenGL provider
3  *****************************************************************************
4  * Copyright (C) 2001-2009 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Gildas Bazin <gbazin@videolan.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 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 General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23 #ifdef HAVE_CONFIG_H
24 # include "config.h"
25 #endif
26
27 #include <vlc_common.h>
28 #include <vlc_plugin.h>
29 #include <vlc_vout_display.h>
30
31 #include <windows.h>
32 #include <ddraw.h>
33 #include <commctrl.h>
34
35 #include <multimon.h>
36 #undef GetSystemMetrics
37
38 #ifndef MONITOR_DEFAULTTONEAREST
39 #   define MONITOR_DEFAULTTONEAREST 2
40 #endif
41
42 #include "../opengl.h"
43 #include "common.h"
44
45 /*****************************************************************************
46  * Module descriptor
47  *****************************************************************************/
48 static int  Open (vlc_object_t *);
49 static void Close(vlc_object_t *);
50
51 vlc_module_begin()
52     set_category(CAT_VIDEO)
53     set_subcategory(SUBCAT_VIDEO_VOUT)
54     set_shortname("OpenGL")
55     set_description(N_("OpenGL video output"))
56     set_capability("vout display", 20)
57     add_shortcut("glwin32", "opengl")
58     set_callbacks(Open, Close)
59 vlc_module_end()
60
61 /*****************************************************************************
62  * Local prototypes.
63  *****************************************************************************/
64 static picture_pool_t *Pool  (vout_display_t *, unsigned);
65 static void           Prepare(vout_display_t *, picture_t *);
66 static void           Display(vout_display_t *, picture_t *);
67 static int            Control(vout_display_t *, int, va_list);
68 static void           Manage (vout_display_t *);
69
70 static void           Swap   (vout_opengl_t *);
71
72 /**
73  * It creates an OpenGL vout display.
74  */
75 static int Open(vlc_object_t *object)
76 {
77     vout_display_t *vd = (vout_display_t *)object;
78     vout_display_sys_t *sys;
79
80     /* Allocate structure */
81     vd->sys = sys = calloc(1, sizeof(*sys));
82     if (!sys)
83         return VLC_ENOMEM;
84
85     /* */
86     if (CommonInit(vd))
87         goto error;
88
89     EventThreadUpdateTitle(sys->event, VOUT_TITLE " (OpenGL output)");
90
91     /* */
92     sys->hGLDC = GetDC(sys->hvideownd);
93
94     /* Set the pixel format for the DC */
95     PIXELFORMATDESCRIPTOR pfd;
96     memset(&pfd, 0, sizeof(pfd));
97     pfd.nSize = sizeof(pfd);
98     pfd.nVersion = 1;
99     pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
100     pfd.iPixelType = PFD_TYPE_RGBA;
101     pfd.cColorBits = 24;
102     pfd.cDepthBits = 16;
103     pfd.iLayerType = PFD_MAIN_PLANE;
104     SetPixelFormat(sys->hGLDC,
105                    ChoosePixelFormat(sys->hGLDC, &pfd), &pfd);
106
107     /* Create and enable the render context */
108     sys->hGLRC = wglCreateContext(sys->hGLDC);
109     wglMakeCurrent(sys->hGLDC, sys->hGLRC);
110
111     /* */
112     sys->gl.lock = NULL;
113     sys->gl.unlock = NULL;
114     sys->gl.swap = Swap;
115     sys->gl.sys = vd;
116
117     video_format_t fmt = vd->fmt;
118     if (vout_display_opengl_Init(&sys->vgl, &fmt, &sys->gl))
119         goto error;
120
121     vout_display_info_t info = vd->info;
122     info.has_double_click = true;
123     info.has_hide_mouse = false;
124     info.has_pictures_invalid = true;
125     info.has_event_thread = true;
126
127    /* Setup vout_display now that everything is fine */
128     vd->fmt  = fmt;
129     vd->info = info;
130
131     vd->pool    = Pool;
132     vd->prepare = Prepare;
133     vd->display = Display;
134     vd->control = Control;
135     vd->manage  = Manage;
136
137     return VLC_SUCCESS;
138
139 error:
140     Close(object);
141     return VLC_EGENERIC;
142 }
143
144 /**
145  * It destroys an OpenGL vout display.
146  */
147 static void Close(vlc_object_t *object)
148 {
149     vout_display_t *vd = (vout_display_t *)object;
150     vout_display_sys_t *sys = vd->sys;
151
152     if (sys->vgl.gl)
153         vout_display_opengl_Clean(&sys->vgl);
154
155     if (sys->hGLDC && sys->hGLRC)
156         wglMakeCurrent(NULL, NULL);
157     if (sys->hGLRC)
158         wglDeleteContext(sys->hGLRC);
159     if (sys->hGLDC)
160         ReleaseDC(sys->hvideownd, sys->hGLDC);
161
162     CommonClean(vd);
163
164     free(sys);
165 }
166
167 /* */
168 static picture_pool_t *Pool(vout_display_t *vd, unsigned count)
169 {
170     vout_display_sys_t *sys = vd->sys;
171     VLC_UNUSED(count);
172
173     if (!sys->pool)
174         sys->pool = vout_display_opengl_GetPool(&sys->vgl);
175     return sys->pool;
176 }
177
178 static void Prepare(vout_display_t *vd, picture_t *picture)
179 {
180     vout_display_sys_t *sys = vd->sys;
181
182     vout_display_opengl_Prepare(&sys->vgl, picture);
183 }
184
185 static void Display(vout_display_t *vd, picture_t *picture)
186 {
187     vout_display_sys_t *sys = vd->sys;
188
189     vout_display_opengl_Display(&sys->vgl, &vd->source);
190
191     picture_Release(picture);
192
193     CommonDisplay(vd);
194 }
195
196 static int Control(vout_display_t *vd, int query, va_list args)
197 {
198     switch (query) {
199     case VOUT_DISPLAY_GET_OPENGL: {
200         vout_opengl_t **gl = va_arg(args, vout_opengl_t **);
201         *gl = &vd->sys->gl;
202         return VLC_SUCCESS;
203     }
204     default:
205         return CommonControl(vd, query, args);
206     }
207 }
208
209 static void Manage (vout_display_t *vd)
210 {
211     vout_display_sys_t *sys = vd->sys;
212
213     CommonManage(vd);
214
215     const int width  = sys->rect_dest.right  - sys->rect_dest.left;
216     const int height = sys->rect_dest.bottom - sys->rect_dest.top;
217     glViewport(0, 0, width, height);
218 }
219
220 static void Swap(vout_opengl_t *gl)
221 {
222     vout_display_t *vd = gl->sys;
223
224     SwapBuffers(vd->sys->hGLDC);
225 }
226