core: remove the 360 video viewpoint zoom
[vlc.git] / modules / video_output / win32 / wingdi.c
blobea4b237e2f0016fd366cf6c8d81a7a22865d762d
1 /*****************************************************************************
2 * wingdi.c : Win32 / WinCE GDI video output plugin for vlc
3 *****************************************************************************
4 * Copyright (C) 2002-2009 VLC authors and VideoLAN
5 * $Id$
7 * Authors: Gildas Bazin <gbazin@videolan.org>
8 * Samuel Hocevar <sam@zoy.org>
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 /*****************************************************************************
26 * Preamble
27 *****************************************************************************/
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32 #include <assert.h>
34 #include <vlc_common.h>
35 #include <vlc_plugin.h>
36 #include <vlc_vout_display.h>
38 #include <windows.h>
40 #include "common.h"
42 /*****************************************************************************
43 * Module descriptor
44 *****************************************************************************/
45 static int Open (vlc_object_t *);
46 static void Close(vlc_object_t *);
48 vlc_module_begin ()
49 set_category(CAT_VIDEO)
50 set_subcategory(SUBCAT_VIDEO_VOUT)
51 set_shortname("GDI")
52 set_description(N_("Windows GDI video output"))
53 set_capability("vout display", 110)
54 set_callbacks(Open, Close)
55 vlc_module_end ()
58 /*****************************************************************************
59 * Local prototypes
60 *****************************************************************************/
61 static picture_pool_t *Pool (vout_display_t *, unsigned);
62 static void Display(vout_display_t *, picture_t *, subpicture_t *subpicture);
63 static int Control(vout_display_t *, int, va_list);
64 static void Manage (vout_display_t *);
66 static int Init(vout_display_t *, video_format_t *, int, int);
67 static void Clean(vout_display_t *);
69 /* */
70 static int Open(vlc_object_t *object)
72 vout_display_t *vd = (vout_display_t *)object;
73 vout_display_sys_t *sys;
75 vd->sys = sys = calloc(1, sizeof(*sys));
76 if (!sys)
77 return VLC_ENOMEM;
79 if (CommonInit(vd))
80 goto error;
82 /* */
83 video_format_t fmt = vd->fmt;
84 if (Init(vd, &fmt, fmt.i_width, fmt.i_height))
85 goto error;
87 vout_display_info_t info = vd->info;
88 info.is_slow = false;
89 info.has_double_click = true;
90 info.has_hide_mouse = false;
91 info.has_pictures_invalid = true;
93 /* */
94 vd->fmt = fmt;
95 vd->info = info;
97 vd->pool = Pool;
98 vd->prepare = NULL;
99 vd->display = Display;
100 vd->manage = Manage;
101 vd->control = Control;
102 return VLC_SUCCESS;
104 error:
105 Close(VLC_OBJECT(vd));
106 return VLC_EGENERIC;
109 /* */
110 static void Close(vlc_object_t *object)
112 vout_display_t *vd = (vout_display_t *)object;
114 Clean(vd);
116 CommonClean(vd);
118 free(vd->sys);
121 /* */
122 static picture_pool_t *Pool(vout_display_t *vd, unsigned count)
124 VLC_UNUSED(count);
125 return vd->sys->pool;
128 static void Display(vout_display_t *vd, picture_t *picture, subpicture_t *subpicture)
130 vout_display_sys_t *sys = vd->sys;
132 #define rect_src vd->sys->rect_src
133 #define rect_src_clipped vd->sys->rect_src_clipped
134 #define rect_dest vd->sys->rect_dest
135 #define rect_dest_clipped vd->sys->rect_dest_clipped
136 RECT rect_dst = rect_dest_clipped;
137 HDC hdc = GetDC(sys->hvideownd);
139 OffsetRect(&rect_dst, -rect_dest.left, -rect_dest.top);
140 SelectObject(sys->off_dc, sys->off_bitmap);
142 if (rect_dest_clipped.right - rect_dest_clipped.left !=
143 rect_src_clipped.right - rect_src_clipped.left ||
144 rect_dest_clipped.bottom - rect_dest_clipped.top !=
145 rect_src_clipped.bottom - rect_src_clipped.top) {
146 StretchBlt(hdc, rect_dst.left, rect_dst.top,
147 rect_dst.right, rect_dst.bottom,
148 sys->off_dc,
149 rect_src_clipped.left, rect_src_clipped.top,
150 rect_src_clipped.right, rect_src_clipped.bottom,
151 SRCCOPY);
152 } else {
153 BitBlt(hdc, rect_dst.left, rect_dst.top,
154 rect_dst.right, rect_dst.bottom,
155 sys->off_dc,
156 rect_src_clipped.left, rect_src_clipped.top,
157 SRCCOPY);
160 ReleaseDC(sys->hvideownd, hdc);
161 #undef rect_src
162 #undef rect_src_clipped
163 #undef rect_dest
164 #undef rect_dest_clipped
165 /* TODO */
166 picture_Release(picture);
167 VLC_UNUSED(subpicture);
169 CommonDisplay(vd);
172 static int Control(vout_display_t *vd, int query, va_list args)
174 switch (query) {
175 case VOUT_DISPLAY_RESET_PICTURES:
176 vlc_assert_unreachable();
177 return VLC_EGENERIC;
178 default:
179 return CommonControl(vd, query, args);
184 static void Manage(vout_display_t *vd)
186 CommonManage(vd);
189 static int Init(vout_display_t *vd,
190 video_format_t *fmt, int width, int height)
192 vout_display_sys_t *sys = vd->sys;
194 /* */
195 RECT *display = &sys->rect_display;
196 display->left = 0;
197 display->top = 0;
198 display->right = GetSystemMetrics(SM_CXSCREEN);;
199 display->bottom = GetSystemMetrics(SM_CYSCREEN);;
201 /* Initialize an offscreen bitmap for direct buffer operations. */
203 /* */
204 HDC window_dc = GetDC(sys->hvideownd);
206 /* */
207 sys->i_depth = GetDeviceCaps(window_dc, PLANES) *
208 GetDeviceCaps(window_dc, BITSPIXEL);
210 /* */
211 msg_Dbg(vd, "GDI depth is %i", sys->i_depth);
212 switch (sys->i_depth) {
213 case 8:
214 fmt->i_chroma = VLC_CODEC_RGB8;
215 break;
216 case 15:
217 fmt->i_chroma = VLC_CODEC_RGB15;
218 fmt->i_rmask = 0x7c00;
219 fmt->i_gmask = 0x03e0;
220 fmt->i_bmask = 0x001f;
221 break;
222 case 16:
223 fmt->i_chroma = VLC_CODEC_RGB16;
224 fmt->i_rmask = 0xf800;
225 fmt->i_gmask = 0x07e0;
226 fmt->i_bmask = 0x001f;
227 break;
228 case 24:
229 fmt->i_chroma = VLC_CODEC_RGB24;
230 fmt->i_rmask = 0x00ff0000;
231 fmt->i_gmask = 0x0000ff00;
232 fmt->i_bmask = 0x000000ff;
233 break;
234 case 32:
235 fmt->i_chroma = VLC_CODEC_RGB32;
236 fmt->i_rmask = 0x00ff0000;
237 fmt->i_gmask = 0x0000ff00;
238 fmt->i_bmask = 0x000000ff;
239 break;
240 default:
241 msg_Err(vd, "screen depth %i not supported", sys->i_depth);
242 return VLC_EGENERIC;
244 fmt->i_width = width;
245 fmt->i_height = height;
247 void *p_pic_buffer;
248 int i_pic_pitch;
249 /* Initialize offscreen bitmap */
250 BITMAPINFO *bi = &sys->bitmapinfo;
251 memset(bi, 0, sizeof(BITMAPINFO) + 3 * sizeof(RGBQUAD));
252 if (sys->i_depth > 8) {
253 ((DWORD*)bi->bmiColors)[0] = fmt->i_rmask;
254 ((DWORD*)bi->bmiColors)[1] = fmt->i_gmask;
255 ((DWORD*)bi->bmiColors)[2] = fmt->i_bmask;;
258 BITMAPINFOHEADER *bih = &sys->bitmapinfo.bmiHeader;
259 bih->biSize = sizeof(BITMAPINFOHEADER);
260 bih->biSizeImage = 0;
261 bih->biPlanes = 1;
262 bih->biCompression = (sys->i_depth == 15 ||
263 sys->i_depth == 16) ? BI_BITFIELDS : BI_RGB;
264 bih->biBitCount = sys->i_depth;
265 bih->biWidth = fmt->i_width;
266 bih->biHeight = -fmt->i_height;
267 bih->biClrImportant = 0;
268 bih->biClrUsed = 0;
269 bih->biXPelsPerMeter = 0;
270 bih->biYPelsPerMeter = 0;
272 i_pic_pitch = bih->biBitCount * bih->biWidth / 8;
273 sys->off_bitmap = CreateDIBSection(window_dc,
274 (BITMAPINFO *)bih,
275 DIB_RGB_COLORS,
276 &p_pic_buffer, NULL, 0);
278 sys->off_dc = CreateCompatibleDC(window_dc);
280 SelectObject(sys->off_dc, sys->off_bitmap);
281 ReleaseDC(sys->hvideownd, window_dc);
283 EventThreadUpdateTitle(sys->event, VOUT_TITLE " (WinGDI output)");
285 /* */
286 picture_resource_t rsc;
287 memset(&rsc, 0, sizeof(rsc));
288 rsc.p[0].p_pixels = p_pic_buffer;
289 rsc.p[0].i_lines = fmt->i_height;
290 rsc.p[0].i_pitch = i_pic_pitch;;
292 picture_t *picture = picture_NewFromResource(fmt, &rsc);
293 if (picture != NULL)
294 sys->pool = picture_pool_New(1, &picture);
295 else
296 sys->pool = NULL;
298 UpdateRects(vd, NULL, NULL, true);
300 return VLC_SUCCESS;
303 static void Clean(vout_display_t *vd)
305 vout_display_sys_t *sys = vd->sys;
307 if (sys->pool)
308 picture_pool_Release(sys->pool);
309 sys->pool = NULL;
311 if (sys->off_dc)
312 DeleteDC(sys->off_dc);
313 if (sys->off_bitmap)
314 DeleteObject(sys->off_bitmap);