manpage: Remove "MPlayer only" notes
[mplayer/glamo.git] / libvo / vo_dfbmga.c
bloba0a9d07760f48f3406e90dea3ca4f0fd000a6da0
1 /*
2 * MPlayer video driver for DirectFB / Matrox G200/G400/G450/G550
4 * copyright (C) 2002-2008 Ville Syrjala <syrjala@sci.fi>
5 * Originally based on vo_directfb.c by Jiri Svoboda <Jiri.Svoboda@seznam.cz>.
7 * This file is part of MPlayer.
9 * MPlayer is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * MPlayer 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 GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with MPlayer; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include <directfb.h>
25 #include <directfb_version.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
30 #include "config.h"
31 #include "video_out.h"
32 #include "video_out_internal.h"
33 #include "fastmemcpy.h"
34 #include "sub.h"
35 #include "mp_msg.h"
36 #include "aspect.h"
37 #include "mp_fifo.h"
39 static const vo_info_t info = {
40 "DirectFB / Matrox G200/G400/G450/G550",
41 "dfbmga",
42 "Ville Syrjala <syrjala@sci.fi>",
46 const LIBVO_EXTERN(dfbmga)
48 static IDirectFB *dfb;
50 static IDirectFBDisplayLayer *crtc1;
51 static IDirectFBDisplayLayer *bes;
52 static IDirectFBDisplayLayer *crtc2;
53 static IDirectFBDisplayLayer *spic;
55 static int num_bufs;
56 static int current_buf;
57 static int current_ip_buf;
58 static IDirectFBSurface *bufs[3];
60 static IDirectFBSurface *frame;
61 static IDirectFBSurface *subframe;
63 static IDirectFBSurface *besframe;
64 static IDirectFBSurface *c1frame;
65 static IDirectFBSurface *c2frame;
66 static IDirectFBSurface *spicframe;
68 static DFBSurfacePixelFormat frame_format;
69 static DFBSurfacePixelFormat subframe_format;
71 static DFBRectangle besrect;
72 static DFBRectangle c1rect;
73 static DFBRectangle c2rect;
74 static DFBRectangle *subrect;
76 static IDirectFBInputDevice *keyboard;
77 static IDirectFBInputDevice *remote;
78 static IDirectFBEventBuffer *buffer;
80 static int blit_done;
81 static int c1stretch;
82 static int c2stretch;
84 static int use_bes;
85 static int use_crtc1;
86 static int use_crtc2;
87 static int use_spic;
88 static int use_input;
89 static int use_remote;
90 static int field_parity;
91 static int flipping;
92 static DFBDisplayLayerBufferMode buffermode;
93 static int tvnorm;
95 static int osd_changed;
96 static int osd_dirty;
97 static int osd_current;
98 static int osd_max;
100 static int is_g200;
102 static uint32_t in_width;
103 static uint32_t in_height;
104 static uint32_t buf_height;
105 static uint32_t screen_width;
106 static uint32_t screen_height;
107 static uint32_t sub_width;
108 static uint32_t sub_height;
110 static char *
111 pixelformat_name( DFBSurfacePixelFormat format )
113 switch(format) {
114 case DSPF_ARGB:
115 return "ARGB";
116 case DSPF_RGB32:
117 return "RGB32";
118 case DSPF_RGB16:
119 return "RGB16";
120 case DSPF_ARGB1555:
121 return "ARGB1555";
122 case DSPF_YUY2:
123 return "YUY2";
124 case DSPF_UYVY:
125 return "UYVY";
126 case DSPF_YV12:
127 return "YV12";
128 case DSPF_I420:
129 return "I420";
130 case DSPF_ALUT44:
131 return "ALUT44";
132 case DSPF_NV12:
133 return "NV12";
134 case DSPF_NV21:
135 return "NV21";
136 default:
137 return "Unknown pixel format";
141 static DFBSurfacePixelFormat
142 imgfmt_to_pixelformat( uint32_t format )
144 switch (format) {
145 case IMGFMT_BGR32:
146 return DSPF_RGB32;
147 case IMGFMT_BGR16:
148 return DSPF_RGB16;
149 case IMGFMT_BGR15:
150 return DSPF_ARGB1555;
151 case IMGFMT_YUY2:
152 return DSPF_YUY2;
153 case IMGFMT_UYVY:
154 return DSPF_UYVY;
155 case IMGFMT_YV12:
156 return DSPF_YV12;
157 case IMGFMT_I420:
158 case IMGFMT_IYUV:
159 return DSPF_I420;
160 case IMGFMT_NV12:
161 return DSPF_NV12;
162 case IMGFMT_NV21:
163 return DSPF_NV21;
164 default:
165 return DSPF_UNKNOWN;
169 struct layer_enum
171 const char *name;
172 IDirectFBDisplayLayer **layer;
173 DFBResult res;
176 static DFBEnumerationResult
177 get_layer_by_name( DFBDisplayLayerID id,
178 DFBDisplayLayerDescription desc,
179 void *data )
181 struct layer_enum *l = (struct layer_enum *) data;
183 if (!strcmp( l->name, desc.name ))
184 if ((l->res = dfb->GetDisplayLayer( dfb, id, l->layer )) == DFB_OK)
185 return DFENUM_CANCEL;
187 return DFENUM_OK;
190 static int
191 preinit( const char *arg )
193 DFBResult res;
194 int force_input = -1;
196 /* Some defaults */
197 use_bes = 0;
198 use_crtc1 = 0;
199 use_crtc2 = 1;
200 use_spic = 1;
201 field_parity = -1;
202 buffermode = DLBM_TRIPLE;
203 osd_max = 4;
204 flipping = 1;
205 tvnorm = -1;
207 use_input = !getenv( "DISPLAY" );
209 if (vo_subdevice) {
210 int show_help = 0;
211 int opt_no = 0;
212 while (*vo_subdevice != '\0') {
213 if (!strncmp(vo_subdevice, "bes", 3)) {
214 use_bes = !opt_no;
215 vo_subdevice += 3;
216 opt_no = 0;
217 } else if (!strncmp(vo_subdevice, "crtc1", 5)) {
218 use_crtc1 = !opt_no;
219 vo_subdevice += 5;
220 opt_no = 0;
221 } else if (!strncmp(vo_subdevice, "crtc2", 5)) {
222 use_crtc2 = !opt_no;
223 vo_subdevice += 5;
224 opt_no = 0;
225 } else if (!strncmp(vo_subdevice, "spic", 4)) {
226 use_spic = !opt_no;
227 vo_subdevice += 4;
228 opt_no = 0;
229 } else if (!strncmp(vo_subdevice, "input", 5)) {
230 force_input = !opt_no;
231 vo_subdevice += 5;
232 opt_no = 0;
233 } else if (!strncmp(vo_subdevice, "remote", 6)) {
234 use_remote = !opt_no;
235 vo_subdevice += 6;
236 opt_no = 0;
237 } else if (!strncmp(vo_subdevice, "buffermode=", 11)) {
238 if (opt_no) {
239 show_help = 1;
240 break;
242 vo_subdevice += 11;
243 if (!strncmp(vo_subdevice, "single", 6)) {
244 buffermode = DLBM_FRONTONLY;
245 osd_max = 1;
246 flipping = 0;
247 vo_subdevice += 6;
248 } else if (!strncmp(vo_subdevice, "double", 6)) {
249 buffermode = DLBM_BACKVIDEO;
250 osd_max = 2;
251 flipping = 1;
252 vo_subdevice += 6;
253 } else if (!strncmp(vo_subdevice, "triple", 6)) {
254 buffermode = DLBM_TRIPLE;
255 osd_max = 4;
256 flipping = 1;
257 vo_subdevice += 6;
258 } else {
259 show_help = 1;
260 break;
262 opt_no = 0;
263 } else if (!strncmp(vo_subdevice, "fieldparity=", 12)) {
264 if (opt_no) {
265 show_help = 1;
266 break;
268 vo_subdevice += 12;
269 if (!strncmp(vo_subdevice, "top", 3)) {
270 field_parity = 0;
271 vo_subdevice += 3;
272 } else if (!strncmp(vo_subdevice, "bottom", 6)) {
273 field_parity = 1;
274 vo_subdevice += 6;
275 } else {
276 show_help = 1;
277 break;
279 opt_no = 0;
280 } else if (!strncmp(vo_subdevice, "tvnorm=", 7)) {
281 if (opt_no) {
282 show_help = 1;
283 break;
285 vo_subdevice += 7;
286 if (!strncmp(vo_subdevice, "pal", 3)) {
287 tvnorm = 0;
288 vo_subdevice += 3;
289 } else if (!strncmp(vo_subdevice, "ntsc" , 4)) {
290 tvnorm = 1;
291 vo_subdevice += 4;
292 } else if (!strncmp(vo_subdevice, "auto" , 4)) {
293 tvnorm = 2;
294 vo_subdevice += 4;
295 } else {
296 show_help = 1;
297 break;
299 opt_no = 0;
300 } else if (!strncmp(vo_subdevice, "no", 2)) {
301 if (opt_no) {
302 show_help = 1;
303 break;
305 vo_subdevice += 2;
306 opt_no = 1;
307 } else if (*vo_subdevice == ':') {
308 if (opt_no) {
309 show_help = 1;
310 break;
312 vo_subdevice++;
313 opt_no = 0;
314 } else {
315 show_help = 1;
316 break;
319 if (show_help) {
320 mp_msg( MSGT_VO, MSGL_ERR,
321 "\nvo_dfbmga command line help:\n"
322 "Example: mplayer -vo dfbmga:nocrtc2:bes:buffermode=single\n"
323 "\nOptions (use 'no' prefix to disable):\n"
324 " bes Use Backend Scaler\n"
325 " crtc1 Use CRTC1\n"
326 " crtc2 Use CRTC2\n"
327 " spic Use hardware sub-picture for OSD\n"
328 " input Use DirectFB for keyboard input\n"
329 " remote Use DirectFB for remote control input\n"
330 "\nOther options:\n"
331 " buffermode=(single|double|triple)\n"
332 " single Use single buffering\n"
333 " double Use double buffering\n"
334 " triple Use triple buffering\n"
335 " fieldparity=(top|bottom)\n"
336 " top Top field first\n"
337 " bottom Bottom field first\n"
338 " tvnorm=(pal|ntsc|auto)\n"
339 " pal Force PAL\n"
340 " ntsc Force NTSC\n"
341 " auto Select according to FPS\n"
342 "\n" );
343 return -1;
346 if (!use_bes && !use_crtc1 && !use_crtc2) {
347 mp_msg( MSGT_VO, MSGL_ERR, "vo_dfbmga: No output selected\n" );
348 return -1;
350 if (use_bes && use_crtc1) {
351 mp_msg( MSGT_VO, MSGL_ERR, "vo_dfbmga: Both BES and CRTC1 outputs selected\n" );
352 return -1;
355 if ((res = DirectFBInit( NULL, NULL )) != DFB_OK) {
356 mp_msg( MSGT_VO, MSGL_ERR,
357 "vo_dfbmga: DirectFBInit() failed - %s\n",
358 DirectFBErrorString( res ) );
359 return -1;
362 switch (tvnorm) {
363 case 0:
364 DirectFBSetOption( "matrox-tv-standard", "pal" );
365 mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: Forced TV standard to PAL\n" );
366 break;
367 case 1:
368 DirectFBSetOption( "matrox-tv-standard", "ntsc" );
369 mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: Forced TV standard to NTSC\n" );
370 break;
371 case 2:
372 if (vo_fps > 27) {
373 DirectFBSetOption( "matrox-tv-standard", "ntsc" );
374 mp_msg( MSGT_VO, MSGL_INFO,
375 "vo_dfbmga: Selected TV standard based upon FPS: NTSC\n" );
376 } else {
377 DirectFBSetOption( "matrox-tv-standard", "pal" );
378 mp_msg( MSGT_VO, MSGL_INFO,
379 "vo_dfbmga: Selected TV standard based upon FPS: PAL\n" );
381 break;
384 if ((res = DirectFBCreate( &dfb )) != DFB_OK) {
385 mp_msg( MSGT_VO, MSGL_ERR,
386 "vo_dfbmga: DirectFBCreate() failed - %s\n",
387 DirectFBErrorString( res ) );
388 return -1;
391 if (use_crtc1 || use_bes) {
392 struct layer_enum l = {
393 "FBDev Primary Layer",
394 &crtc1,
395 DFB_UNSUPPORTED
397 dfb->EnumDisplayLayers( dfb, get_layer_by_name, &l );
398 if (l.res != DFB_OK) {
399 mp_msg( MSGT_VO, MSGL_ERR, "vo_dfbmga: Can't get CRTC1 layer - %s\n",
400 DirectFBErrorString( l.res ) );
401 uninit();
402 return -1;
404 if ((res = crtc1->SetCooperativeLevel( crtc1, DLSCL_EXCLUSIVE )) != DFB_OK) {
405 mp_msg( MSGT_VO, MSGL_ERR, "Can't get exclusive access to CRTC1 layer - %s\n",
406 DirectFBErrorString( res ) );
407 uninit();
408 return -1;
410 use_input = 1;
413 if (force_input != -1)
414 use_input = force_input;
416 if (use_bes) {
417 DFBDisplayLayerConfig dlc;
418 DFBDisplayLayerConfigFlags failed;
419 struct layer_enum l = {
420 "Matrox Backend Scaler",
421 &bes,
422 DFB_UNSUPPORTED
425 dfb->EnumDisplayLayers( dfb, get_layer_by_name, &l );
426 if (l.res != DFB_OK) {
427 mp_msg( MSGT_VO, MSGL_ERR, "Can't get BES layer - %s\n",
428 DirectFBErrorString( l.res ) );
429 uninit();
430 return -1;
432 if ((res = bes->SetCooperativeLevel( bes, DLSCL_EXCLUSIVE )) != DFB_OK) {
433 mp_msg( MSGT_VO, MSGL_ERR, "Can't get exclusive access to BES - %s\n",
434 DirectFBErrorString( res ) );
435 uninit();
436 return -1;
438 dlc.flags = DLCONF_PIXELFORMAT;
439 dlc.pixelformat = DSPF_RGB16;
440 if (bes->TestConfiguration( bes, &dlc, &failed ) != DFB_OK) {
441 is_g200 = 1;
442 use_crtc2 = 0;
446 if (use_crtc2) {
447 struct layer_enum l = {
448 "Matrox CRTC2 Layer",
449 &crtc2,
450 DFB_UNSUPPORTED
453 dfb->EnumDisplayLayers( dfb, get_layer_by_name, &l );
454 if (l.res != DFB_OK) {
455 mp_msg( MSGT_VO, MSGL_ERR, "Can't get CRTC2 layer - %s\n",
456 DirectFBErrorString( l.res ) );
457 uninit();
458 return -1;
460 if ((res = crtc2->SetCooperativeLevel( crtc2, DLSCL_EXCLUSIVE )) != DFB_OK) {
461 mp_msg( MSGT_VO, MSGL_ERR, "Can't get exclusive access to CRTC2 - %s\n",
462 DirectFBErrorString( res ) );
463 uninit();
464 return -1;
468 if (use_input || use_remote) {
469 if ((res = dfb->CreateEventBuffer( dfb, &buffer )) != DFB_OK) {
470 mp_msg( MSGT_VO, MSGL_ERR,
471 "vo_dfbmga: Can't create event buffer - %s\n",
472 DirectFBErrorString( res ) );
473 uninit();
474 return -1;
478 if (use_input) {
479 if ((res = dfb->GetInputDevice( dfb, DIDID_KEYBOARD, &keyboard )) != DFB_OK) {
480 mp_msg( MSGT_VO, MSGL_ERR,
481 "vo_dfbmga: Can't get keyboard - %s\n",
482 DirectFBErrorString( res ) );
483 uninit();
484 return -1;
486 if ((res = keyboard->AttachEventBuffer( keyboard, buffer )) != DFB_OK) {
487 mp_msg( MSGT_VO, MSGL_ERR,
488 "vo_dfbmga: Can't attach event buffer to keyboard - %s\n",
489 DirectFBErrorString( res ) );
490 uninit();
491 return -1;
494 if (use_remote) {
495 if ((res = dfb->GetInputDevice( dfb, DIDID_REMOTE, &remote )) != DFB_OK) {
496 mp_msg( MSGT_VO, MSGL_ERR,
497 "vo_dfbmga: Can't get remote control - %s\n",
498 DirectFBErrorString( res ) );
499 uninit();
500 return -1;
502 if ((res = remote->AttachEventBuffer( remote, buffer )) != DFB_OK) {
503 mp_msg( MSGT_VO, MSGL_ERR,
504 "vo_dfbmga: Can't attach event buffer to remote control - %s\n",
505 DirectFBErrorString( res ) );
506 uninit();
507 return -1;
511 return 0;
514 static void release_config( void )
516 if (spicframe)
517 spicframe->Release( spicframe );
518 if (spic)
519 spic->Release( spic );
520 if (c2frame)
521 c2frame->Release( c2frame );
522 if (c1frame)
523 c1frame->Release( c1frame );
524 if (besframe)
525 besframe->Release( besframe );
526 if (bufs[0])
527 bufs[0]->Release( bufs[0] );
528 if (bufs[1])
529 bufs[1]->Release( bufs[1] );
530 if (bufs[2])
531 bufs[2]->Release( bufs[2] );
533 spicframe = NULL;
534 spic = NULL;
535 c2frame = NULL;
536 c1frame = NULL;
537 besframe = NULL;
538 bufs[0] = NULL;
539 bufs[1] = NULL;
540 bufs[2] = NULL;
543 static int
544 config( uint32_t width, uint32_t height,
545 uint32_t d_width, uint32_t d_height,
546 uint32_t flags,
547 char *title,
548 uint32_t format )
550 DFBResult res;
552 DFBDisplayLayerConfig dlc;
553 DFBDisplayLayerConfigFlags failed;
555 uint32_t out_width;
556 uint32_t out_height;
558 release_config();
560 in_width = width;
561 in_height = height;
563 aspect_save_orig(width, height);
564 aspect_save_prescale(d_width, d_height);
566 dlc.pixelformat = imgfmt_to_pixelformat( format );
569 /* Draw to a temporary surface */
570 DFBSurfaceDescription dsc;
572 dsc.flags = DSDESC_WIDTH | DSDESC_HEIGHT |
573 DSDESC_PIXELFORMAT;
574 dsc.width = (in_width + 15) & ~15;
575 dsc.height = (in_height + 15) & ~15;
576 dsc.pixelformat = dlc.pixelformat;
578 /* Don't waste video memory since we don't need direct stretchblit */
579 if (use_bes) {
580 dsc.flags |= DSDESC_CAPS;
581 dsc.caps = DSCAPS_SYSTEMONLY;
584 for (num_bufs = 0; num_bufs < 3; num_bufs++) {
585 if ((res = dfb->CreateSurface( dfb, &dsc, &bufs[num_bufs] )) != DFB_OK) {
586 if (num_bufs == 0) {
587 mp_msg( MSGT_VO, MSGL_ERR,
588 "vo_dfbmga: Can't create surfaces - %s!\n",
589 DirectFBErrorString( res ) );
590 return -1;
592 break;
595 frame = bufs[0];
596 current_buf = 0;
597 current_ip_buf = 0;
598 buf_height = dsc.height;
600 frame->GetPixelFormat( frame, &frame_format );
601 mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: Video surface %dx%d %s\n",
602 in_width, in_height,
603 pixelformat_name( frame_format ) );
607 * BES
609 if (use_bes) {
610 aspect_save_screenres( 0x10000, 0x10000 );
611 aspect( &out_width, &out_height, A_ZOOM );
612 besrect.x = (0x10000 - out_width) * in_width / out_width / 2;
613 besrect.y = (0x10000 - out_height) * in_height / out_height / 2;
614 besrect.w = in_width;
615 besrect.h = in_height;
617 dlc.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE;
618 dlc.width = besrect.w + besrect.x * 2;
619 dlc.height = besrect.h + besrect.y * 2;
620 dlc.buffermode = buffermode;
622 if ((res = bes->TestConfiguration( bes, &dlc, &failed )) != DFB_OK) {
623 mp_msg( MSGT_VO, MSGL_ERR,
624 "vo_dfbmga: Invalid BES configuration - %s!\n",
625 DirectFBErrorString( res ) );
626 return -1;
628 if ((res = bes->SetConfiguration( bes, &dlc )) != DFB_OK) {
629 mp_msg( MSGT_VO, MSGL_ERR,
630 "vo_dfbmga: BES configuration failed - %s!\n",
631 DirectFBErrorString( res ) );
632 return -1;
634 bes->GetSurface( bes, &besframe );
635 besframe->SetBlittingFlags( besframe, DSBLIT_NOFX );
637 bes->SetScreenLocation( bes, 0.0, 0.0, 1.0, 1.0 );
639 besframe->Clear( besframe, 0, 0, 0, 0xff );
640 besframe->Flip( besframe, NULL, 0 );
641 besframe->Clear( besframe, 0, 0, 0, 0xff );
642 besframe->Flip( besframe, NULL, 0 );
643 besframe->Clear( besframe, 0, 0, 0, 0xff );
645 mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: BES using %s buffering\n",
646 dlc.buffermode == DLBM_TRIPLE ? "triple" :
647 dlc.buffermode == DLBM_BACKVIDEO ? "double" : "single" );
648 mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: BES surface %dx%d %s\n", dlc.width, dlc.height, pixelformat_name( dlc.pixelformat ) );
652 * CRTC1
654 if (use_crtc1) {
655 dlc.flags = DLCONF_BUFFERMODE;
656 dlc.buffermode = buffermode;
658 if ((res = crtc1->TestConfiguration( crtc1, &dlc, &failed )) != DFB_OK) {
659 mp_msg( MSGT_VO, MSGL_ERR,
660 "vo_dfbmga: Invalid CRTC1 configuration - %s!\n",
661 DirectFBErrorString( res ) );
662 return -1;
664 if ((res = crtc1->SetConfiguration( crtc1, &dlc )) != DFB_OK) {
665 mp_msg( MSGT_VO, MSGL_ERR,
666 "vo_dfbmga: CRTC1 configuration failed - %s!\n",
667 DirectFBErrorString( res ) );
668 return -1;
670 if ((res = crtc1->GetConfiguration( crtc1, &dlc )) != DFB_OK) {
671 mp_msg( MSGT_VO, MSGL_ERR,
672 "vo_dfbmga: Getting CRTC1 configuration failed - %s!\n",
673 DirectFBErrorString( res ) );
674 return -1;
677 crtc1->GetSurface( crtc1, &c1frame );
678 c1frame->SetBlittingFlags( c1frame, DSBLIT_NOFX );
679 c1frame->SetColor( c1frame, 0, 0, 0, 0xff );
681 c1frame->GetSize( c1frame, &screen_width, &screen_height );
683 aspect_save_screenres( screen_width, screen_height );
684 aspect( &out_width, &out_height, (flags & VOFLAG_FULLSCREEN) ? A_ZOOM : A_NOZOOM );
686 if (in_width != out_width || in_height != out_height)
687 c1stretch = 1;
688 else
689 c1stretch = 0;
691 c1rect.x = (screen_width - out_width) / 2;
692 c1rect.y = (screen_height - out_height) / 2;
693 c1rect.w = out_width;
694 c1rect.h = out_height;
696 c1frame->Clear( c1frame, 0, 0, 0, 0xff );
697 c1frame->Flip( c1frame, NULL, 0 );
698 c1frame->Clear( c1frame, 0, 0, 0, 0xff );
699 c1frame->Flip( c1frame, NULL, 0 );
700 c1frame->Clear( c1frame, 0, 0, 0, 0xff );
702 mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: CRTC1 using %s buffering\n",
703 dlc.buffermode == DLBM_TRIPLE ? "triple" :
704 dlc.buffermode == DLBM_BACKVIDEO ? "double" : "single" );
705 mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: CRTC1 surface %dx%d %s\n", screen_width, screen_height, pixelformat_name( dlc.pixelformat ) );
709 * CRTC2
711 if (use_crtc2) {
712 dlc.flags = DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE | DLCONF_OPTIONS;
713 dlc.buffermode = buffermode;
714 dlc.options = DLOP_NONE;
716 if (field_parity != -1) {
717 dlc.options |= DLOP_FIELD_PARITY;
719 mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: Field parity set to: ");
720 switch (field_parity) {
721 case -1:
722 mp_msg( MSGT_VO, MSGL_INFO, "Don't care\n");
723 break;
724 case 0:
725 mp_msg( MSGT_VO, MSGL_INFO, "Top field first\n");
726 break;
727 case 1:
728 mp_msg( MSGT_VO, MSGL_INFO, "Bottom field first\n");
729 break;
732 switch (dlc.pixelformat) {
733 case DSPF_I420:
734 case DSPF_YV12:
735 /* sub-picture supported */
736 break;
738 case DSPF_YUY2:
739 case DSPF_UYVY:
740 /* Blit to YUY2/UYVY not supported */
741 dlc.pixelformat = DSPF_ARGB;
743 /* fall through */
744 default:
745 /* sub-picture not supported */
746 use_spic = 0;
749 if ((res = crtc2->TestConfiguration( crtc2, &dlc, &failed )) != DFB_OK) {
750 mp_msg( MSGT_VO, MSGL_ERR,
751 "vo_dfbmga: Invalid CRTC2 configuration - %s!\n",
752 DirectFBErrorString( res ) );
753 return -1;
755 if ((res = crtc2->SetConfiguration( crtc2, &dlc )) != DFB_OK) {
756 mp_msg( MSGT_VO, MSGL_ERR,
757 "vo_dfbmga: CRTC2 configuration failed - %s!\n",
758 DirectFBErrorString( res ) );
759 return -1;
762 if (field_parity != -1)
763 crtc2->SetFieldParity( crtc2, field_parity );
765 crtc2->GetSurface( crtc2, &c2frame );
766 c2frame->SetBlittingFlags( c2frame, DSBLIT_NOFX );
767 c2frame->SetColor( c2frame, 0, 0, 0, 0xff );
769 c2frame->GetSize( c2frame, &screen_width, &screen_height );
771 /* Don't stretch only slightly smaller videos */
772 if ((in_width > (0.95 * screen_width)) &&
773 (in_width < screen_width))
774 out_width = in_width;
775 else
776 out_width = screen_width;
777 if ((in_height > (0.95 * screen_height)) &&
778 (in_height < screen_height))
779 out_height = in_height;
780 else
781 out_height = screen_height;
783 aspect_save_screenres( out_width, out_height );
784 aspect( &out_width, &out_height, (flags & VOFLAG_FULLSCREEN) ? A_ZOOM : A_NOZOOM );
786 if (in_width != out_width ||
787 in_height != out_height)
788 c2stretch = 1;
789 else
790 c2stretch = 0;
792 c2rect.x = (screen_width - out_width) / 2;
793 c2rect.y = (screen_height - out_height) / 2;
794 c2rect.w = out_width;
795 c2rect.h = out_height;
797 c2frame->Clear( c2frame, 0, 0, 0, 0xff );
798 c2frame->Flip( c2frame, NULL, 0 );
799 c2frame->Clear( c2frame, 0, 0, 0, 0xff );
800 c2frame->Flip( c2frame, NULL, 0 );
801 c2frame->Clear( c2frame, 0, 0, 0, 0xff );
803 mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: CRTC2 using %s buffering\n",
804 dlc.buffermode == DLBM_TRIPLE ? "triple" :
805 dlc.buffermode == DLBM_BACKVIDEO ? "double" : "single" );
806 mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: CRTC2 surface %dx%d %s\n", screen_width, screen_height, pixelformat_name( dlc.pixelformat ) );
807 } else {
808 use_spic = 0;
812 * Sub-picture
814 if (use_spic) {
815 /* Draw OSD to sub-picture surface */
816 IDirectFBPalette *palette;
817 DFBColor color;
818 int i;
819 struct layer_enum l = {
820 "Matrox CRTC2 Sub-Picture",
821 &spic,
822 DFB_UNSUPPORTED
824 dfb->EnumDisplayLayers( dfb, get_layer_by_name, &l );
825 if (l.res != DFB_OK) {
826 mp_msg( MSGT_VO, MSGL_ERR, "vo_dfbmga: Can't get sub-picture layer - %s\n",
827 DirectFBErrorString( l.res ) );
828 return -1;
830 if ((res = spic->SetCooperativeLevel( spic, DLSCL_EXCLUSIVE )) != DFB_OK) {
831 mp_msg( MSGT_VO, MSGL_ERR, "Can't get exclusive access to sub-picture - %s\n",
832 DirectFBErrorString( res ) );
833 return -1;
836 dlc.flags = DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE;
837 dlc.pixelformat = DSPF_ALUT44;
838 dlc.buffermode = buffermode;
839 dlc.flags |= DLCONF_OPTIONS;
840 dlc.options = DLOP_ALPHACHANNEL;
842 if ((res = spic->TestConfiguration( spic, &dlc, &failed )) != DFB_OK) {
843 mp_msg( MSGT_VO, MSGL_ERR,
844 "vo_dfbmga: Invalid sub-picture configuration - %s!\n",
845 DirectFBErrorString( res ) );
846 return -1;
848 if ((res = spic->SetConfiguration( spic, &dlc )) != DFB_OK) {
849 mp_msg( MSGT_VO, MSGL_ERR,
850 "vo_dfbmga: Sub-picture configuration failed - %s!\n",
851 DirectFBErrorString( res ) );
852 return -1;
855 spic->GetSurface( spic, &spicframe );
857 spicframe->GetPalette( spicframe, &palette );
858 color.a = 0xff;
859 for (i = 0; i < 16; i++) {
860 color.r = i * 17;
861 color.g = i * 17;
862 color.b = i * 17;
863 palette->SetEntries( palette, &color, 1, i );
865 palette->Release( palette );
867 spicframe->Clear( spicframe, 0, 0, 0, 0 );
868 spicframe->Flip( spicframe, NULL, 0 );
869 spicframe->Clear( spicframe, 0, 0, 0, 0 );
870 spicframe->Flip( spicframe, NULL, 0 );
871 spicframe->Clear( spicframe, 0, 0, 0, 0 );
873 mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: Sub-picture layer using %s buffering\n",
874 dlc.buffermode == DLBM_TRIPLE ? "triple" :
875 dlc.buffermode == DLBM_BACKVIDEO ? "double" : "single" );
877 subframe = spicframe;
878 subrect = NULL;
879 } else if (use_crtc2) {
880 /* Draw OSD to CRTC2 surface */
881 subframe = c2frame;
882 subrect = &c2rect;
883 } else if (use_crtc1) {
884 /* Draw OSD to CRTC1 surface */
885 subframe = c1frame;
886 subrect = &c1rect;
887 } else {
888 /* Draw OSD to BES surface */
889 subframe = besframe;
890 subrect = &besrect;
893 subframe->GetSize( subframe, &sub_width, &sub_height );
894 subframe->GetPixelFormat( subframe, &subframe_format );
895 mp_msg( MSGT_VO, MSGL_INFO, "vo_dfbmga: Sub-picture surface %dx%d %s (%s)\n",
896 sub_width, sub_height,
897 pixelformat_name( subframe_format ),
898 use_crtc2 ? (use_spic ? "Sub-picture layer" : "CRTC2") :
899 use_crtc1 ? "CRTC1" : "BES" );
901 osd_dirty = 0;
902 osd_current = 1;
903 blit_done = 0;
905 return 0;
908 static int
909 query_format( uint32_t format )
911 switch (format) {
912 case IMGFMT_YV12:
913 case IMGFMT_I420:
914 case IMGFMT_IYUV:
915 if (is_g200 || use_crtc1)
916 return 0;
917 break;
918 case IMGFMT_BGR32:
919 case IMGFMT_BGR16:
920 case IMGFMT_BGR15:
921 if (is_g200 && use_bes)
922 return 0;
923 break;
924 case IMGFMT_UYVY:
925 if (is_g200)
926 return 0;
927 break;
928 case IMGFMT_YUY2:
929 break;
930 case IMGFMT_NV12:
931 case IMGFMT_NV21:
932 if (use_crtc1 || use_crtc2)
933 return 0;
934 break;
935 default:
936 return 0;
939 return VFCAP_HWSCALE_UP |
940 VFCAP_HWSCALE_DOWN |
941 VFCAP_CSP_SUPPORTED_BY_HW |
942 VFCAP_CSP_SUPPORTED |
943 VFCAP_OSD;
946 static void
947 vo_draw_alpha_alut44( int w, int h,
948 unsigned char* src,
949 unsigned char *srca,
950 int srcstride,
951 unsigned char* dst,
952 int dststride )
954 int x;
956 while (h--) {
957 for (x = 0; x < w; x++) {
958 if (srca[x])
959 dst[x] = ((255 - srca[x]) & 0xF0) | (src[x] >> 4);
961 src += srcstride;
962 srca += srcstride;
963 dst += dststride;
967 static void
968 clear_alpha( int x0, int y0,
969 int w, int h )
971 if (use_spic && !flipping && vo_osd_changed_flag)
972 subframe->FillRectangle( subframe, x0, y0, w, h );
975 static void
976 draw_alpha( int x0, int y0,
977 int w, int h,
978 unsigned char *src,
979 unsigned char *srca,
980 int stride )
982 uint8_t *dst;
983 void *ptr;
984 int pitch;
986 if (use_spic) {
987 if (!osd_changed || (!flipping && !vo_osd_changed_flag))
988 return;
989 osd_dirty |= osd_current;
990 } else {
991 if (x0 < subrect->x ||
992 y0 < subrect->y ||
993 x0 + w > subrect->x + subrect->w ||
994 y0 + h > subrect->y + subrect->h)
995 osd_dirty |= osd_current;
998 if (subframe->Lock( subframe, DSLF_READ | DSLF_WRITE, &ptr, &pitch ) != DFB_OK)
999 return;
1000 dst = ptr;
1002 switch (subframe_format) {
1003 case DSPF_ALUT44:
1004 vo_draw_alpha_alut44( w, h, src, srca, stride,
1005 dst + pitch * y0 + x0,
1006 pitch );
1007 break;
1008 case DSPF_RGB32:
1009 case DSPF_ARGB:
1010 vo_draw_alpha_rgb32( w, h, src, srca, stride,
1011 dst + pitch * y0 + 4 * x0,
1012 pitch );
1013 break;
1014 case DSPF_RGB16:
1015 vo_draw_alpha_rgb16( w, h, src, srca, stride,
1016 dst + pitch * y0 + 2 * x0,
1017 pitch );
1018 break;
1019 case DSPF_ARGB1555:
1020 vo_draw_alpha_rgb15( w, h, src, srca, stride,
1021 dst + pitch * y0 + 2 * x0,
1022 pitch );
1023 break;
1024 case DSPF_YUY2:
1025 vo_draw_alpha_yuy2( w, h, src, srca, stride,
1026 dst + pitch * y0 + 2 * x0,
1027 pitch );
1028 break;
1029 case DSPF_UYVY:
1030 vo_draw_alpha_yuy2( w, h, src, srca, stride,
1031 dst + pitch * y0 + 2 * x0 + 1,
1032 pitch );
1033 break;
1034 case DSPF_NV12:
1035 case DSPF_NV21:
1036 case DSPF_I420:
1037 case DSPF_YV12:
1038 vo_draw_alpha_yv12( w, h, src, srca, stride,
1039 dst + pitch * y0 + x0,
1040 pitch );
1041 break;
1044 subframe->Unlock( subframe );
1047 static int
1048 draw_frame( uint8_t * src[] )
1050 return -1;
1053 static int
1054 draw_slice( uint8_t * src[], int stride[], int w, int h, int x, int y )
1056 uint8_t *dst;
1057 void *ptr;
1058 int pitch;
1060 if (frame->Lock( frame, DSLF_WRITE, &ptr, &pitch ) != DFB_OK)
1061 return VO_FALSE;
1062 dst = ptr;
1064 memcpy_pic( dst + pitch * y + x, src[0],
1065 w, h, pitch, stride[0] );
1067 dst += pitch * buf_height;
1069 y /= 2;
1070 h /= 2;
1072 if (frame_format == DSPF_NV12 || frame_format == DSPF_NV21) {
1073 memcpy_pic( dst + pitch * y + x, src[1],
1074 w, h, pitch, stride[1] );
1075 } else {
1076 x /= 2;
1077 w /= 2;
1078 pitch /= 2;
1080 if (frame_format == DSPF_I420 )
1081 memcpy_pic( dst + pitch * y + x, src[1],
1082 w, h, pitch, stride[1] );
1083 else
1084 memcpy_pic( dst + pitch * y + x, src[2],
1085 w, h, pitch, stride[2] );
1087 dst += pitch * buf_height / 2;
1089 if (frame_format == DSPF_I420 )
1090 memcpy_pic( dst + pitch * y + x, src[2],
1091 w, h, pitch, stride[2] );
1092 else
1093 memcpy_pic( dst + pitch * y + x, src[1],
1094 w, h, pitch, stride[1] );
1097 frame->Unlock( frame );
1099 return VO_TRUE;
1102 static void
1103 blit_to_screen( void )
1105 IDirectFBSurface *blitsrc = frame;
1106 DFBRectangle *srect = NULL;
1108 if (use_bes) {
1109 if (vo_vsync && !flipping)
1110 bes->WaitForSync( bes );
1112 besframe->Blit( besframe, blitsrc, NULL, besrect.x, besrect.y );
1113 blitsrc = besframe;
1114 srect = &besrect;
1117 if (use_crtc1) {
1118 if (vo_vsync && !flipping)
1119 crtc1->WaitForSync( crtc1 );
1121 if (c1stretch)
1122 c1frame->StretchBlit( c1frame, blitsrc, srect, &c1rect );
1123 else
1124 c1frame->Blit( c1frame, blitsrc, srect, c1rect.x, c1rect.y );
1127 if (use_crtc2) {
1128 if (vo_vsync && !flipping)
1129 crtc2->WaitForSync( crtc2 );
1131 if (c2stretch)
1132 c2frame->StretchBlit( c2frame, blitsrc, srect, &c2rect );
1133 else
1134 c2frame->Blit( c2frame, blitsrc, srect, c2rect.x, c2rect.y );
1138 static void
1139 draw_osd( void )
1141 frame = bufs[current_buf];
1142 frame->Unlock( frame );
1144 osd_changed = vo_osd_changed( 0 );
1145 if (osd_dirty & osd_current) {
1146 if (use_spic) {
1147 if (flipping)
1148 subframe->Clear( subframe, 0, 0, 0, 0 );
1149 } else {
1150 /* Clear black bars around the picture */
1151 subframe->FillRectangle( subframe,
1152 0, 0,
1153 sub_width, subrect->y );
1154 subframe->FillRectangle( subframe,
1155 0, subrect->y + subrect->h,
1156 sub_width, subrect->y );
1157 subframe->FillRectangle( subframe,
1158 0, subrect->y,
1159 subrect->x, subrect->h );
1160 subframe->FillRectangle( subframe,
1161 subrect->x + subrect->w, subrect->y,
1162 subrect->x, subrect->h );
1164 osd_dirty &= ~osd_current;
1167 blit_to_screen();
1168 blit_done = 1;
1170 vo_remove_text( sub_width, sub_height, clear_alpha );
1171 vo_draw_text( sub_width, sub_height, draw_alpha );
1173 if (use_spic && flipping && osd_changed) {
1174 subframe->Flip( subframe, NULL, 0 );
1175 osd_current <<= 1;
1176 if (osd_current > osd_max)
1177 osd_current = 1;
1181 static void
1182 flip_page( void )
1184 if (!blit_done)
1185 blit_to_screen();
1187 if (flipping) {
1188 if (use_crtc2)
1189 c2frame->Flip( c2frame, NULL, vo_vsync ? DSFLIP_WAITFORSYNC : DSFLIP_ONSYNC );
1190 if (use_crtc1)
1191 c1frame->Flip( c1frame, NULL, vo_vsync ? DSFLIP_WAITFORSYNC : DSFLIP_ONSYNC );
1192 if (use_bes)
1193 besframe->Flip( besframe, NULL, vo_vsync ? DSFLIP_WAITFORSYNC : DSFLIP_ONSYNC );
1195 if (!use_spic) {
1196 osd_current <<= 1;
1197 if (osd_current > osd_max)
1198 osd_current = 1;
1202 blit_done = 0;
1203 current_buf = 0;
1206 static void
1207 uninit( void )
1209 release_config();
1211 if (buffer)
1212 buffer->Release( buffer );
1213 if (remote)
1214 remote->Release( remote );
1215 if (keyboard)
1216 keyboard->Release( keyboard );
1217 if (crtc2)
1218 crtc2->Release( crtc2 );
1219 if (bes)
1220 bes->Release( bes );
1221 if (crtc1)
1222 crtc1->Release( crtc1 );
1223 if (dfb)
1224 dfb->Release( dfb );
1226 buffer = NULL;
1227 remote = NULL;
1228 keyboard = NULL;
1229 crtc2 = NULL;
1230 bes = NULL;
1231 crtc1 = NULL;
1232 dfb = NULL;
1235 static uint32_t
1236 get_image( mp_image_t *mpi )
1238 int buf = current_buf;
1239 uint8_t *dst;
1240 void *ptr;
1241 int pitch;
1243 if (mpi->flags & MP_IMGFLAG_READABLE &&
1244 (mpi->type == MP_IMGTYPE_IPB || mpi->type == MP_IMGTYPE_IP)) {
1245 if (num_bufs < 2)
1246 return VO_FALSE;
1248 current_ip_buf ^= 1;
1250 if (mpi->type == MP_IMGTYPE_IPB && num_bufs < 3 && current_ip_buf)
1251 return VO_FALSE;
1253 buf = current_ip_buf;
1255 if (mpi->type == MP_IMGTYPE_IPB)
1256 buf++;
1258 frame = bufs[buf];
1259 frame->Unlock( frame );
1261 /* Always use DSLF_READ to preserve system memory copy */
1262 if (frame->Lock( frame, DSLF_WRITE | DSLF_READ,
1263 &ptr, &pitch ) != DFB_OK)
1264 return VO_FALSE;
1265 dst = ptr;
1267 if ((mpi->width == pitch) ||
1268 (mpi->flags & (MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_ACCEPT_WIDTH))) {
1270 mpi->planes[0] = dst;
1271 mpi->width = in_width;
1272 mpi->stride[0] = pitch;
1274 if (mpi->flags & MP_IMGFLAG_PLANAR) {
1275 if (mpi->num_planes > 2) {
1276 mpi->stride[1] = mpi->stride[2] = pitch / 2;
1278 if (mpi->flags & MP_IMGFLAG_SWAPPED) {
1279 /* I420 */
1280 mpi->planes[1] = dst + buf_height * pitch;
1281 mpi->planes[2] = mpi->planes[1] + buf_height * pitch / 4;
1282 } else {
1283 /* YV12 */
1284 mpi->planes[2] = dst + buf_height * pitch;
1285 mpi->planes[1] = mpi->planes[2] + buf_height * pitch / 4;
1287 } else {
1288 /* NV12/NV21 */
1289 mpi->stride[1] = pitch;
1290 mpi->planes[1] = dst + buf_height * pitch;
1294 mpi->flags |= MP_IMGFLAG_DIRECT;
1295 mpi->priv = (void *) buf;
1296 current_buf = buf;
1298 return VO_TRUE;
1301 frame->Unlock( frame );
1303 return VO_FALSE;
1308 static uint32_t
1309 draw_image( mp_image_t *mpi )
1311 if (mpi->flags & MP_IMGFLAG_DIRECT) {
1312 current_buf = (int) mpi->priv;
1313 return VO_TRUE;
1315 if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK)
1316 return VO_TRUE;
1318 if (mpi->flags & MP_IMGFLAG_PLANAR)
1319 return draw_slice( mpi->planes, mpi->stride,
1320 mpi->w, mpi->h, 0, 0 );
1321 else {
1322 void *dst;
1323 int pitch;
1325 if (frame->Lock( frame, DSLF_WRITE, &dst, &pitch ) != DFB_OK)
1326 return VO_FALSE;
1327 memcpy_pic( dst, mpi->planes[0],
1328 mpi->w * (mpi->bpp / 8), mpi->h,
1329 pitch, mpi->stride[0] );
1330 frame->Unlock( frame );
1332 return VO_TRUE;
1336 static int
1337 set_equalizer( char *data, int value )
1339 DFBResult res;
1340 DFBColorAdjustment ca;
1341 float factor = (float) 0xffff / 200.0;
1343 ca.flags = DCAF_NONE;
1345 if (!strcasecmp( data, "brightness" )) {
1346 ca.flags |= DCAF_BRIGHTNESS;
1347 ca.brightness = value * factor + 0x8000;
1349 if (!strcasecmp( data, "contrast" )) {
1350 ca.flags |= DCAF_CONTRAST;
1351 ca.contrast = value * factor + 0x8000;
1353 if (!strcasecmp( data, "hue" )) {
1354 ca.flags |= DCAF_HUE;
1355 ca.hue = value * factor + 0x8000;
1357 if (!strcasecmp( data, "saturation" )) {
1358 ca.flags |= DCAF_SATURATION;
1359 ca.saturation = value * factor + 0x8000;
1362 /* Prefer CRTC2 over BES */
1363 if (use_crtc2)
1364 res = crtc2->SetColorAdjustment( crtc2, &ca );
1365 else if (use_crtc1)
1366 res = crtc1->SetColorAdjustment( crtc1, &ca );
1367 else
1368 res = bes->SetColorAdjustment( bes, &ca );
1370 if (res != DFB_OK)
1371 return VO_FALSE;
1373 return VO_TRUE;
1376 static int
1377 get_equalizer( char *data, int *value )
1379 DFBResult res;
1380 DFBColorAdjustment ca;
1381 float factor = 200.0 / (float) 0xffff;
1383 /* Prefer CRTC2 over BES */
1384 if (use_crtc2)
1385 res = crtc2->GetColorAdjustment( crtc2, &ca );
1386 else if (use_crtc1)
1387 res = crtc1->GetColorAdjustment( crtc1, &ca );
1388 else
1389 res = bes->GetColorAdjustment( bes, &ca );
1391 if (res != DFB_OK)
1392 return VO_FALSE;
1394 if (!strcasecmp( data, "brightness" ) &&
1395 (ca.flags & DCAF_BRIGHTNESS))
1396 *value = (ca.brightness - 0x8000) * factor;
1397 if (!strcasecmp( data, "contrast" ) &&
1398 (ca.flags & DCAF_CONTRAST))
1399 *value = (ca.contrast - 0x8000) * factor;
1400 if (!strcasecmp( data, "hue" ) &&
1401 (ca.flags & DCAF_HUE))
1402 *value = (ca.hue - 0x8000) * factor;
1403 if (!strcasecmp( data, "saturation" ) &&
1404 (ca.flags & DCAF_SATURATION))
1405 *value = (ca.saturation - 0x8000) * factor;
1407 return VO_TRUE;
1410 static int
1411 control( uint32_t request, void *data)
1413 switch (request) {
1414 case VOCTRL_QUERY_FORMAT:
1415 return query_format( *((uint32_t *) data) );
1417 case VOCTRL_GET_IMAGE:
1418 return get_image( data );
1420 case VOCTRL_DRAW_IMAGE:
1421 return draw_image( data );
1423 case VOCTRL_SET_EQUALIZER:
1425 struct voctrl_set_equalizer_args *args = data;
1426 return set_equalizer(args->name, args->value);
1428 case VOCTRL_GET_EQUALIZER:
1430 struct voctrl_get_equalizer_args *args = data;
1431 return get_equalizer(args->name, args->valueptr);
1435 return VO_NOTIMPL;
1438 #include "osdep/keycodes.h"
1440 static void
1441 check_events( void )
1443 DFBInputEvent event;
1445 if (!buffer)
1446 return;
1448 if (buffer->GetEvent( buffer, DFB_EVENT( &event )) == DFB_OK) {
1449 if (event.type == DIET_KEYPRESS) {
1450 switch (event.key_symbol) {
1451 case DIKS_ESCAPE:
1452 mplayer_put_key( KEY_ESC );
1453 break;
1454 case DIKS_PAGE_UP:
1455 mplayer_put_key( KEY_PAGE_UP );
1456 break;
1457 case DIKS_PAGE_DOWN:
1458 mplayer_put_key( KEY_PAGE_DOWN );
1459 break;
1460 case DIKS_CURSOR_UP:
1461 mplayer_put_key( KEY_UP );
1462 break;
1463 case DIKS_CURSOR_DOWN:
1464 mplayer_put_key( KEY_DOWN );
1465 break;
1466 case DIKS_CURSOR_LEFT:
1467 mplayer_put_key( KEY_LEFT );
1468 break;
1469 case DIKS_CURSOR_RIGHT:
1470 mplayer_put_key( KEY_RIGHT );
1471 break;
1472 case DIKS_INSERT:
1473 mplayer_put_key( KEY_INSERT );
1474 break;
1475 case DIKS_DELETE:
1476 mplayer_put_key( KEY_DELETE );
1477 break;
1478 case DIKS_HOME:
1479 mplayer_put_key( KEY_HOME );
1480 break;
1481 case DIKS_END:
1482 mplayer_put_key( KEY_END );
1483 break;
1485 case DIKS_POWER:
1486 mplayer_put_key( KEY_POWER );
1487 break;
1488 case DIKS_MENU:
1489 mplayer_put_key( KEY_MENU );
1490 break;
1491 case DIKS_PLAY:
1492 mplayer_put_key( KEY_PLAY );
1493 break;
1494 case DIKS_STOP:
1495 mplayer_put_key( KEY_STOP );
1496 break;
1497 case DIKS_PAUSE:
1498 mplayer_put_key( KEY_PAUSE );
1499 break;
1500 case DIKS_PLAYPAUSE:
1501 mplayer_put_key( KEY_PLAYPAUSE );
1502 break;
1503 case DIKS_FORWARD:
1504 mplayer_put_key( KEY_FORWARD );
1505 break;
1506 case DIKS_NEXT:
1507 mplayer_put_key( KEY_NEXT );
1508 break;
1509 case DIKS_REWIND:
1510 mplayer_put_key( KEY_REWIND );
1511 break;
1512 case DIKS_PREVIOUS:
1513 mplayer_put_key( KEY_PREV );
1514 break;
1515 case DIKS_VOLUME_UP:
1516 mplayer_put_key( KEY_VOLUME_UP );
1517 break;
1518 case DIKS_VOLUME_DOWN:
1519 mplayer_put_key( KEY_VOLUME_DOWN );
1520 break;
1521 case DIKS_MUTE:
1522 mplayer_put_key( KEY_MUTE );
1523 break;
1525 default:
1526 mplayer_put_key( event.key_symbol );
1532 * empty buffer, because of repeating
1533 * keyboard repeat is faster than key handling and this causes problems during seek
1534 * temporary workabout. should be solved in the future
1536 buffer->Reset( buffer );