direct: set visible picture dimensions
[vlc/gmpfix.git] / modules / video_output / directfb.c
blobb4ae978c15370303f937436ee18a57315f7372a7
1 /*****************************************************************************
2 * directfb.c: DirectFB video output display method
3 *****************************************************************************
4 * Copyright © 2005-2009 VLC authors and VideoLAN
6 * Authors: Iuri Diniz <iuridiniz@gmail.com>
7 * Laurent Aimar <fenrir@videolan.org>
9 * This code is based in sdl.c and fb.c, thanks for VideoLAN team.
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation; either version 2.1 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public License
22 * along with this program; if not, write to the Free Software Foundation,
23 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24 *****************************************************************************/
26 /*****************************************************************************
27 * Preamble
28 *****************************************************************************/
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
33 #include <vlc_common.h>
34 #include <vlc_plugin.h>
35 #include <vlc_vout_display.h>
36 #include <vlc_picture_pool.h>
38 #include <directfb.h>
40 /*****************************************************************************
41 * Module descriptor
42 *****************************************************************************/
43 static int Open (vlc_object_t *);
44 static void Close(vlc_object_t *);
46 vlc_module_begin()
47 set_shortname("DirectFB")
48 set_category(CAT_VIDEO)
49 set_subcategory(SUBCAT_VIDEO_VOUT)
50 set_description(N_("DirectFB video output http://www.directfb.org/"))
51 set_capability("vout display", 35)
52 add_shortcut("directfb")
53 set_callbacks(Open, Close)
54 vlc_module_end()
56 /*****************************************************************************
57 * Local prototypes
58 *****************************************************************************/
59 static picture_pool_t *Pool (vout_display_t *, unsigned);
60 static void Display(vout_display_t *, picture_t *, subpicture_t *);
61 static int Control(vout_display_t *, int, va_list);
63 /* */
64 struct vout_display_sys_t {
65 IDirectFB *directfb;
66 IDirectFBSurface *primary;
68 picture_pool_t *pool;
71 /* */
72 static int Open(vlc_object_t *object)
74 vout_display_t *vd = (vout_display_t *)object;
75 vout_display_sys_t *sys;
77 vd->sys = sys = calloc(1, sizeof(*sys));
78 if (!sys)
79 return VLC_ENOMEM;
81 if (DirectFBInit(NULL,NULL) != DFB_OK) {
82 msg_Err(vd, "Cannot init DirectFB");
83 free(sys);
84 return VLC_EGENERIC;
87 DFBSurfaceDescription dsc;
88 /*dsc.flags = DSDESC_CAPS | DSDESC_HEIGHT | DSDESC_WIDTH;*/
89 dsc.flags = DSDESC_CAPS;
90 dsc.caps = DSCAPS_PRIMARY | DSCAPS_FLIPPING;
91 /*dsc.width = 352;*/
92 /*dsc.height = 240;*/
94 IDirectFB *directfb = NULL;
95 if (DirectFBCreate(&directfb) != DFB_OK || !directfb)
96 goto error;
97 sys->directfb = directfb;
99 IDirectFBSurface *primary = NULL;
100 if (directfb->CreateSurface(directfb, &dsc, &primary) || !primary)
101 goto error;
102 sys->primary = primary;
104 /* */
105 int width;
106 int height;
108 primary->GetSize(primary, &width, &height);
109 primary->FillRectangle(primary, 0, 0, width, height);
110 primary->Flip(primary, NULL, 0);
112 vout_display_DeleteWindow(vd, NULL);
114 /* */
115 video_format_t fmt;
116 video_format_ApplyRotation(&fmt, &vd->fmt);
118 DFBSurfacePixelFormat pixel_format;
119 sys->primary->GetPixelFormat(sys->primary, &pixel_format);
120 switch (pixel_format) {
121 case DSPF_RGB332:
122 fmt.i_chroma = VLC_CODEC_RGB8;
123 fmt.i_rmask = 0x7 << 5;
124 fmt.i_gmask = 0x7 << 2;
125 fmt.i_bmask = 0x3 << 0;
126 break;
127 case DSPF_RGB16: fmt.i_chroma = VLC_CODEC_RGB16; break;
128 case DSPF_RGB24: fmt.i_chroma = VLC_CODEC_RGB24; break;
129 case DSPF_RGB32: fmt.i_chroma = VLC_CODEC_RGB32; break;
130 default:
131 msg_Err(vd, "unknown screen depth %i", pixel_format);
132 Close(VLC_OBJECT(vd));
133 return VLC_EGENERIC;
136 video_format_FixRgb(&fmt);
138 fmt.i_width = width;
139 fmt.i_height = height;
140 fmt.i_visible_width = width;
141 fmt.i_visible_height = height;
143 /* */
144 vout_display_info_t info = vd->info;
145 info.has_hide_mouse = true;
147 /* */
148 vd->fmt = fmt;
149 vd->info = info;
150 vd->pool = Pool;
151 vd->prepare = NULL;
152 vd->display = Display;
153 vd->control = Control;
154 vd->manage = NULL;
156 /* */
157 vout_display_SendEventFullscreen(vd, true);
158 vout_display_SendEventDisplaySize(vd, fmt.i_width, fmt.i_height, true);
159 return VLC_SUCCESS;
161 error:
162 msg_Err(vd, "Cannot create primary surface");
163 Close(VLC_OBJECT(vd));
164 return VLC_EGENERIC;
167 static void Close(vlc_object_t *object)
169 vout_display_t *vd = (vout_display_t *)object;
170 vout_display_sys_t *sys = vd->sys;
172 if (sys->pool)
173 picture_pool_Delete(sys->pool);
175 IDirectFBSurface *primary = sys->primary;
176 if (primary)
177 primary->Release(primary);
179 IDirectFB *directfb = sys->directfb;
180 if (directfb)
181 directfb->Release(directfb);
183 free(sys);
186 /* */
187 static picture_pool_t *Pool(vout_display_t *vd, unsigned count)
189 vout_display_sys_t *sys = vd->sys;
191 if (!sys->pool)
192 sys->pool = picture_pool_NewFromFormat(&vd->fmt, count);
193 return sys->pool;
196 static void Display(vout_display_t *vd, picture_t *picture, subpicture_t *subpicture)
198 vout_display_sys_t *sys = vd->sys;
200 IDirectFBSurface *primary = sys->primary;
202 void *pixels;
203 int pitch;
204 if (primary->Lock(primary, DSLF_WRITE, &pixels, &pitch) == DFB_OK) {
205 picture_resource_t rsc;
207 memset(&rsc, 0, sizeof(rsc));
208 rsc.p[0].p_pixels = pixels;
209 rsc.p[0].i_lines = vd->fmt.i_height;
210 rsc.p[0].i_pitch = pitch;
212 picture_t *direct = picture_NewFromResource(&vd->fmt, &rsc);
213 if (direct) {
214 picture_Copy(direct, picture);
215 picture_Release(direct);
218 if (primary->Unlock(primary) == DFB_OK)
219 primary->Flip(primary, NULL, 0);
221 picture_Release(picture);
222 VLC_UNUSED(subpicture);
225 static int Control(vout_display_t *vd, int query, va_list args)
227 switch (query) {
228 case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE: {
229 const vout_display_cfg_t *cfg = va_arg(args, const vout_display_cfg_t *);
230 if (cfg->display.width != vd->fmt.i_width ||
231 cfg->display.height != vd->fmt.i_height)
232 return VLC_EGENERIC;
233 return VLC_SUCCESS;
235 default:
236 msg_Err(vd, "Unsupported query in vout display directfb");
237 return VLC_EGENERIC;