127
145
static int Open ( vlc_object_t *p_this )
129
147
vout_thread_t * p_vout = (vout_thread_t *)p_this;
148
/* XXX: check for conflicts with the SDL audio output */
149
vlc_mutex_t *lock = var_AcquireMutex( "sdl" );
132
151
#ifdef HAVE_SETENV
133
152
char *psz_method;
136
var_Get( p_this->p_libvlc, "sdl", &lockval );
137
vlc_mutex_lock( lockval.p_address );
158
p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
159
if( p_vout->p_sys == NULL )
161
vlc_mutex_unlock( lock );
165
memset( p_vout->p_sys, 0, sizeof( vout_sys_t ) );
167
/* Check if SDL video module has been initialized */
139
168
if( SDL_WasInit( SDL_INIT_VIDEO ) != 0 )
141
vlc_mutex_unlock( lockval.p_address );
170
vlc_mutex_unlock( lock );
171
free( p_vout->p_sys );
142
172
return VLC_EGENERIC;
145
175
/* Allocate structure */
146
p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
147
if( p_vout->p_sys == NULL )
149
msg_Err( p_vout, "out of memory" );
150
vlc_mutex_unlock( lockval.p_address );
154
176
p_vout->pf_init = Init;
155
177
p_vout->pf_end = End;
156
178
p_vout->pf_manage = Manage;
157
179
p_vout->pf_render = NULL;
158
180
p_vout->pf_display = Display;
181
p_vout->pf_control = NULL;
160
183
#ifdef HAVE_SETENV
161
psz_method = config_GetPsz( p_vout, "vout" );
184
char* psz = psz_method = config_GetPsz( p_vout, "vout" );
164
187
while( *psz_method && *psz_method != ':' )
330
367
unsigned int i_width, i_height, i_x, i_y;
332
369
/* Process events */
333
while( SDL_PollEvent(&event) )
370
while( SDL_PollEvent( &event ) )
335
372
switch( event.type )
337
case SDL_VIDEORESIZE: /* Resizing of window */
338
/* Update dimensions */
374
/* Resizing of window */
375
case SDL_VIDEORESIZE:
339
376
p_vout->i_changes |= VOUT_SIZE_CHANGE;
340
377
p_vout->i_window_width = p_vout->p_sys->i_width = event.resize.w;
341
378
p_vout->i_window_height = p_vout->p_sys->i_height = event.resize.h;
344
382
case SDL_MOUSEMOTION:
345
383
vout_PlacePicture( p_vout, p_vout->p_sys->i_width,
346
384
p_vout->p_sys->i_height,
347
385
&i_x, &i_y, &i_width, &i_height );
349
val.i_int = ( event.motion.x - i_x )
350
* p_vout->render.i_width / i_width;
387
/* Compute the x coordinate and check if the value is
388
in [0,p_vout->fmt_in.i_visible_width] */
389
val.i_int = ( event.motion.x - i_x ) *
390
p_vout->fmt_in.i_visible_width / i_width +
391
p_vout->fmt_in.i_x_offset;
393
if( (int)(event.motion.x - i_x) < 0 )
395
else if( (unsigned int)val.i_int > p_vout->fmt_in.i_visible_width )
396
val.i_int = p_vout->fmt_in.i_visible_width;
351
398
var_Set( p_vout, "mouse-x", val );
352
val.i_int = ( event.motion.y - i_y )
353
* p_vout->render.i_height / i_height;
400
/* compute the y coordinate and check if the value is
401
in [0,p_vout->fmt_in.i_visible_height] */
402
val.i_int = ( event.motion.y - i_y ) *
403
p_vout->fmt_in.i_visible_height / i_height +
404
p_vout->fmt_in.i_y_offset;
406
if( (int)(event.motion.y - i_y) < 0 )
408
else if( (unsigned int)val.i_int > p_vout->fmt_in.i_visible_height )
409
val.i_int = p_vout->fmt_in.i_visible_height;
354
411
var_Set( p_vout, "mouse-y", val );
356
val.b_bool = VLC_TRUE;
357
414
var_Set( p_vout, "mouse-moved", val );
359
if( p_vout->p_sys->b_cursor &&
360
(abs(event.motion.xrel) > 2 || abs(event.motion.yrel) > 2) )
416
if( p_vout->p_sys->b_cursor )
362
418
if( p_vout->p_sys->b_cursor_autohidden )
408
496
p_vout->p_sys->i_lastpressed = mdate();
499
case SDL_BUTTON_MIDDLE:
500
var_Get( p_vout, "mouse-button-down", &val );
502
var_Set( p_vout, "mouse-button-down", val );
505
case SDL_BUTTON_RIGHT:
506
var_Get( p_vout, "mouse-button-down", &val );
508
var_Set( p_vout, "mouse-button-down", val );
513
/* Quit event (close the window) */
420
p_vout->p_vlc->b_die = 1;
423
case SDL_KEYDOWN: /* if a key is pressed */
425
switch( event.key.keysym.sym )
428
if( p_vout->b_fullscreen )
430
p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
434
p_vout->p_vlc->b_die = 1;
438
case SDLK_q: /* quit */
439
p_vout->p_vlc->b_die = 1;
442
case SDLK_f: /* switch to fullscreen */
443
p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE;
446
case SDLK_c: /* toggle grayscale */
447
p_vout->b_grayscale = ! p_vout->b_grayscale;
448
p_vout->i_changes |= VOUT_GRAYSCALE_CHANGE;
451
case SDLK_i: /* toggle info */
452
p_vout->b_info = ! p_vout->b_info;
453
p_vout->i_changes |= VOUT_INFO_CHANGE;
456
case SDLK_s: /* toggle scaling */
457
p_vout->b_scale = ! p_vout->b_scale;
458
p_vout->i_changes |= VOUT_SCALE_CHANGE;
461
case SDLK_SPACE: /* toggle interface */
462
p_vout->b_interface = ! p_vout->b_interface;
463
p_vout->i_changes |= VOUT_INTF_CHANGE;
468
intf_thread_t *p_intf;
469
p_intf = vlc_object_find( p_vout, VLC_OBJECT_INTF,
473
p_intf->b_menu_change = 1;
474
vlc_object_release( p_intf );
493
audio_volume_t i_volume;
494
if ( !aout_VolumeDown( p_vout, 1, &i_volume ) )
496
msg_Dbg( p_vout, "audio volume is now %d", i_volume );
500
msg_Dbg( p_vout, "audio volume: operation not supported" );
507
audio_volume_t i_volume;
508
if ( !aout_VolumeUp( p_vout, 1, &i_volume ) )
510
msg_Dbg( p_vout, "audio volume is now %d", i_volume );
514
msg_Dbg( p_vout, "audio volume: operation not supported" );
517
playlist_t *p_playlist = pl_Yield( p_vout );
518
if( p_playlist != NULL )
520
playlist_Stop( p_playlist );
521
pl_Release( p_vout );
524
#warning FIXME FIXME ?
531
/* convert the key if possible */
532
val.i_int = ConvertKey( event.key.keysym.sym );
536
/* Find the right caracter */
537
if( ( event.key.keysym.unicode & 0xff80 ) == 0 )
539
val.i_int = event.key.keysym.unicode & 0x7f;
540
/* FIXME: find a better solution than this
541
hack to find the right caracter */
542
if( val.i_int >= 1 && val.i_int <= 26 )
544
else if( val.i_int >= 65 && val.i_int <= 90 )
551
if( ( event.key.keysym.mod & KMOD_SHIFT ) )
553
val.i_int |= KEY_MODIFIER_SHIFT;
555
if( ( event.key.keysym.mod & KMOD_CTRL ) )
557
val.i_int |= KEY_MODIFIER_CTRL;
559
if( ( event.key.keysym.mod & KMOD_ALT ) )
561
val.i_int |= KEY_MODIFIER_ALT;
563
var_Set( p_vout->p_libvlc, "key-pressed", val );
572
638
/*****************************************************************************
639
* Key events handling
640
*****************************************************************************/
645
} sdlkeys_to_vlckeys[] =
656
{ SDLK_F10, KEY_F10 },
657
{ SDLK_F11, KEY_F11 },
658
{ SDLK_F12, KEY_F12 },
660
{ SDLK_RETURN, KEY_ENTER },
661
{ SDLK_KP_ENTER, KEY_ENTER },
662
{ SDLK_SPACE, KEY_SPACE },
663
{ SDLK_ESCAPE, KEY_ESC },
665
{ SDLK_MENU, KEY_MENU },
666
{ SDLK_LEFT, KEY_LEFT },
667
{ SDLK_RIGHT, KEY_RIGHT },
669
{ SDLK_DOWN, KEY_DOWN },
671
{ SDLK_HOME, KEY_HOME },
672
{ SDLK_END, KEY_END },
673
{ SDLK_PAGEUP, KEY_PAGEUP },
674
{ SDLK_PAGEDOWN, KEY_PAGEDOWN },
676
{ SDLK_INSERT, KEY_INSERT },
677
{ SDLK_DELETE, KEY_DELETE },
678
/*TODO: find a equivalent for SDL
679
{ , KEY_MEDIA_NEXT_TRACK }
680
{ , KEY_MEDIA_PREV_TRACK }
681
{ , KEY_VOLUME_MUTE }
682
{ , KEY_VOLUME_DOWN }
684
{ , KEY_MEDIA_PLAY_PAUSE }
685
{ , KEY_MEDIA_PLAY_PAUSE }*/
690
static int ConvertKey( SDLKey sdl_key )
693
for( i=0; sdlkeys_to_vlckeys[i].sdl_key != 0; i++ )
695
if( sdlkeys_to_vlckeys[i].sdl_key == sdl_key )
697
return sdlkeys_to_vlckeys[i].i_vlckey;
704
/*****************************************************************************
573
705
* Display: displays previously rendered output
574
706
*****************************************************************************
575
707
* This function sends the currently rendered image to the display.
647
790
SDL_LockSurface( p_vout->p_sys->p_display );
649
/* Choose the chroma we will try first. */
650
switch( p_vout->render.i_chroma )
652
case VLC_FOURCC('Y','U','Y','2'):
653
case VLC_FOURCC('Y','U','N','V'):
792
if( ( psz_chroma = config_GetPsz( p_vout, "sdl-chroma" ) ) )
794
if( strlen( psz_chroma ) >= 4 )
796
memcpy(&i_chroma, psz_chroma, 4);
797
msg_Dbg( p_vout, "Forcing chroma to 0x%.8x (%4.4s)", i_chroma, (char*)&i_chroma );
808
/* Choose the chroma we will try first. */
811
if( !psz_chroma ) i_chroma = 0;
812
switch( i_chroma ? i_chroma : p_vout->render.i_chroma )
814
case VLC_FOURCC('Y','U','Y','2'):
815
case VLC_FOURCC('Y','U','N','V'):
816
p_vout->output.i_chroma = VLC_FOURCC('Y','U','Y','2');
817
i_sdl_chroma = SDL_YUY2_OVERLAY;
819
case VLC_FOURCC('U','Y','V','Y'):
820
case VLC_FOURCC('U','Y','N','V'):
821
case VLC_FOURCC('Y','4','2','2'):
822
p_vout->output.i_chroma = VLC_FOURCC('U','Y','V','Y');
823
i_sdl_chroma = SDL_UYVY_OVERLAY;
825
case VLC_FOURCC('Y','V','Y','U'):
826
p_vout->output.i_chroma = VLC_FOURCC('Y','V','Y','U');
827
i_sdl_chroma = SDL_YVYU_OVERLAY;
829
case VLC_FOURCC('Y','V','1','2'):
830
case VLC_FOURCC('I','4','2','0'):
831
case VLC_FOURCC('I','Y','U','V'):
833
p_vout->output.i_chroma = VLC_FOURCC('Y','V','1','2');
834
i_sdl_chroma = SDL_YV12_OVERLAY;
837
free( psz_chroma ); psz_chroma = NULL;
839
p_vout->p_sys->p_overlay =
840
SDL_CreateYUVOverlay( 32, 32, i_sdl_chroma,
841
p_vout->p_sys->p_display );
842
/* FIXME: if the first overlay we find is software, don't stop,
843
* because we may find a hardware one later ... */
845
while( i_chroma && !p_vout->p_sys->p_overlay );
848
/* If this best choice failed, fall back to other chromas */
849
if( p_vout->p_sys->p_overlay == NULL )
851
p_vout->output.i_chroma = VLC_FOURCC('I','Y','U','V');
852
p_vout->p_sys->p_overlay =
853
SDL_CreateYUVOverlay( 32, 32, SDL_IYUV_OVERLAY,
854
p_vout->p_sys->p_display );
857
if( p_vout->p_sys->p_overlay == NULL )
859
p_vout->output.i_chroma = VLC_FOURCC('Y','V','1','2');
860
p_vout->p_sys->p_overlay =
861
SDL_CreateYUVOverlay( 32, 32, SDL_YV12_OVERLAY,
862
p_vout->p_sys->p_display );
865
if( p_vout->p_sys->p_overlay == NULL )
654
867
p_vout->output.i_chroma = VLC_FOURCC('Y','U','Y','2');
655
i_sdl_chroma = SDL_YUY2_OVERLAY;
657
case VLC_FOURCC('U','Y','V','Y'):
658
case VLC_FOURCC('U','Y','N','V'):
659
case VLC_FOURCC('Y','4','2','2'):
660
p_vout->output.i_chroma = VLC_FOURCC('U','Y','V','Y');
661
i_sdl_chroma = SDL_UYVY_OVERLAY;
663
case VLC_FOURCC('Y','V','Y','U'):
664
p_vout->output.i_chroma = VLC_FOURCC('Y','V','Y','U');
665
i_sdl_chroma = SDL_YVYU_OVERLAY;
667
case VLC_FOURCC('Y','V','1','2'):
668
case VLC_FOURCC('I','4','2','0'):
669
case VLC_FOURCC('I','Y','U','V'):
671
p_vout->output.i_chroma = VLC_FOURCC('Y','V','1','2');
672
i_sdl_chroma = SDL_YV12_OVERLAY;
676
p_vout->p_sys->p_overlay =
677
SDL_CreateYUVOverlay( 32, 32, i_sdl_chroma, p_vout->p_sys->p_display );
678
/* FIXME: if the first overlay we find is software, don't stop,
679
* because we may find a hardware one later ... */
681
/* If this best choice failed, fall back to other chromas */
682
if( p_vout->p_sys->p_overlay == NULL )
684
p_vout->output.i_chroma = VLC_FOURCC('I','Y','U','V');
685
p_vout->p_sys->p_overlay =
686
SDL_CreateYUVOverlay( 32, 32, SDL_IYUV_OVERLAY,
687
p_vout->p_sys->p_display );
690
if( p_vout->p_sys->p_overlay == NULL )
692
p_vout->output.i_chroma = VLC_FOURCC('Y','V','1','2');
693
p_vout->p_sys->p_overlay =
694
SDL_CreateYUVOverlay( 32, 32, SDL_YV12_OVERLAY,
695
p_vout->p_sys->p_display );
698
if( p_vout->p_sys->p_overlay == NULL )
700
p_vout->output.i_chroma = VLC_FOURCC('Y','U','Y','2');
701
p_vout->p_sys->p_overlay =
702
SDL_CreateYUVOverlay( 32, 32, SDL_YUY2_OVERLAY,
703
p_vout->p_sys->p_display );
706
if( p_vout->p_sys->p_overlay == NULL )
708
msg_Warn( p_vout, "no SDL overlay for 0x%.8x (%4.4s)",
709
p_vout->render.i_chroma, (char*)&p_vout->render.i_chroma );
868
p_vout->p_sys->p_overlay =
869
SDL_CreateYUVOverlay( 32, 32, SDL_YUY2_OVERLAY,
870
p_vout->p_sys->p_display );
874
if( p_vout->p_sys->p_overlay == NULL )
877
msg_Warn( p_vout, "no SDL overlay for 0x%.8x (%4.4s)",
878
p_vout->render.i_chroma,
879
(char*)&p_vout->render.i_chroma );
881
msg_Warn( p_vout, "SDL overlay disabled by the user" );
711
883
switch( p_vout->p_sys->p_display->format->BitsPerPixel )