1 /*****************************************************************************
2 * wingdi.c : Win32 / WinCE GDI video output plugin for vlc
3 *****************************************************************************
4 * Copyright (C) 2002-2009 VLC authors and VideoLAN
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 /*****************************************************************************
27 *****************************************************************************/
34 #include <vlc_common.h>
35 #include <vlc_plugin.h>
36 #include <vlc_vout_display.h>
42 /*****************************************************************************
44 *****************************************************************************/
45 static int Open (vlc_object_t
*);
46 static void Close(vlc_object_t
*);
49 set_category(CAT_VIDEO
)
50 set_subcategory(SUBCAT_VIDEO_VOUT
)
52 set_description(N_("Windows GDI video output"))
53 set_capability("vout display", 110)
54 set_callbacks(Open
, Close
)
58 /*****************************************************************************
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
*);
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
));
83 video_format_t fmt
= vd
->fmt
;
84 if (Init(vd
, &fmt
, fmt
.i_width
, fmt
.i_height
))
87 vout_display_info_t info
= vd
->info
;
89 info
.has_double_click
= true;
90 info
.has_hide_mouse
= false;
91 info
.has_pictures_invalid
= true;
99 vd
->display
= Display
;
101 vd
->control
= Control
;
105 Close(VLC_OBJECT(vd
));
110 static void Close(vlc_object_t
*object
)
112 vout_display_t
*vd
= (vout_display_t
*)object
;
122 static picture_pool_t
*Pool(vout_display_t
*vd
, unsigned 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
,
149 rect_src_clipped
.left
, rect_src_clipped
.top
,
150 rect_src_clipped
.right
, rect_src_clipped
.bottom
,
153 BitBlt(hdc
, rect_dst
.left
, rect_dst
.top
,
154 rect_dst
.right
, rect_dst
.bottom
,
156 rect_src_clipped
.left
, rect_src_clipped
.top
,
160 ReleaseDC(sys
->hvideownd
, hdc
);
162 #undef rect_src_clipped
164 #undef rect_dest_clipped
166 picture_Release(picture
);
167 VLC_UNUSED(subpicture
);
172 static int Control(vout_display_t
*vd
, int query
, va_list args
)
175 case VOUT_DISPLAY_RESET_PICTURES
:
176 vlc_assert_unreachable();
179 return CommonControl(vd
, query
, args
);
184 static void Manage(vout_display_t
*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
;
195 RECT
*display
= &sys
->rect_display
;
198 display
->right
= GetSystemMetrics(SM_CXSCREEN
);;
199 display
->bottom
= GetSystemMetrics(SM_CYSCREEN
);;
201 /* Initialize an offscreen bitmap for direct buffer operations. */
204 HDC window_dc
= GetDC(sys
->hvideownd
);
207 sys
->i_depth
= GetDeviceCaps(window_dc
, PLANES
) *
208 GetDeviceCaps(window_dc
, BITSPIXEL
);
211 msg_Dbg(vd
, "GDI depth is %i", sys
->i_depth
);
212 switch (sys
->i_depth
) {
214 fmt
->i_chroma
= VLC_CODEC_RGB8
;
217 fmt
->i_chroma
= VLC_CODEC_RGB15
;
218 fmt
->i_rmask
= 0x7c00;
219 fmt
->i_gmask
= 0x03e0;
220 fmt
->i_bmask
= 0x001f;
223 fmt
->i_chroma
= VLC_CODEC_RGB16
;
224 fmt
->i_rmask
= 0xf800;
225 fmt
->i_gmask
= 0x07e0;
226 fmt
->i_bmask
= 0x001f;
229 fmt
->i_chroma
= VLC_CODEC_RGB24
;
230 fmt
->i_rmask
= 0x00ff0000;
231 fmt
->i_gmask
= 0x0000ff00;
232 fmt
->i_bmask
= 0x000000ff;
235 fmt
->i_chroma
= VLC_CODEC_RGB32
;
236 fmt
->i_rmask
= 0x00ff0000;
237 fmt
->i_gmask
= 0x0000ff00;
238 fmt
->i_bmask
= 0x000000ff;
241 msg_Err(vd
, "screen depth %i not supported", sys
->i_depth
);
244 fmt
->i_width
= width
;
245 fmt
->i_height
= height
;
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;
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;
269 bih
->biXPelsPerMeter
= 0;
270 bih
->biYPelsPerMeter
= 0;
272 i_pic_pitch
= bih
->biBitCount
* bih
->biWidth
/ 8;
273 sys
->off_bitmap
= CreateDIBSection(window_dc
,
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)");
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
);
294 sys
->pool
= picture_pool_New(1, &picture
);
298 UpdateRects(vd
, NULL
, NULL
, true);
303 static void Clean(vout_display_t
*vd
)
305 vout_display_sys_t
*sys
= vd
->sys
;
308 picture_pool_Release(sys
->pool
);
312 DeleteDC(sys
->off_dc
);
314 DeleteObject(sys
->off_bitmap
);