00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <stdlib.h>
00029
00030 #include <vlc/vlc.h>
00031 #include <vlc/intf.h>
00032 #include <vlc/input.h>
00033 #include <vlc/vout.h>
00034 #include <vlc/aout.h>
00035 #include <vlc_osd.h>
00036
00037 #include "vlc_keys.h"
00038
00039 #define BUFFER_SIZE 10
00040
00041 #define CHANNELS_NUMBER 4
00042 #define VOLUME_TEXT_CHAN p_intf->p_sys->p_channels[ 0 ]
00043 #define VOLUME_WIDGET_CHAN p_intf->p_sys->p_channels[ 1 ]
00044 #define POSITION_TEXT_CHAN p_intf->p_sys->p_channels[ 2 ]
00045 #define POSITION_WIDGET_CHAN p_intf->p_sys->p_channels[ 3 ]
00046
00047
00048
00049 struct intf_sys_t
00050 {
00051 vlc_mutex_t change_lock;
00052
00053
00054
00055 int p_keys[ BUFFER_SIZE ];
00056
00057 int i_size;
00058 int p_channels[ CHANNELS_NUMBER ];
00059
00060 input_thread_t * p_input;
00061 vout_thread_t * p_vout;
00062 };
00063
00064
00065
00066
00067 static int Open ( vlc_object_t * );
00068 static void Close ( vlc_object_t * );
00069 static void Run ( intf_thread_t * );
00070 static int GetKey ( intf_thread_t *);
00071 static int KeyEvent( vlc_object_t *, char const *,
00072 vlc_value_t, vlc_value_t, void * );
00073 static int ActionKeyCB( vlc_object_t *, char const *,
00074 vlc_value_t, vlc_value_t, void * );
00075 static void PlayBookmark( intf_thread_t *, int );
00076 static void SetBookmark ( intf_thread_t *, int );
00077 static void DisplayPosition( intf_thread_t *, vout_thread_t *, input_thread_t * );
00078 static void DisplayVolume ( intf_thread_t *, vout_thread_t *, audio_volume_t );
00079 static void ClearChannels ( intf_thread_t *, vout_thread_t * );
00080
00081
00082
00083
00084 #define BOOKMARK1_TEXT N_("Playlist bookmark 1")
00085 #define BOOKMARK2_TEXT N_("Playlist bookmark 2")
00086 #define BOOKMARK3_TEXT N_("Playlist bookmark 3")
00087 #define BOOKMARK4_TEXT N_("Playlist bookmark 4")
00088 #define BOOKMARK5_TEXT N_("Playlist bookmark 5")
00089 #define BOOKMARK6_TEXT N_("Playlist bookmark 6")
00090 #define BOOKMARK7_TEXT N_("Playlist bookmark 7")
00091 #define BOOKMARK8_TEXT N_("Playlist bookmark 8")
00092 #define BOOKMARK9_TEXT N_("Playlist bookmark 9")
00093 #define BOOKMARK10_TEXT N_("Playlist bookmark 10")
00094 #define BOOKMARK_LONGTEXT N_( \
00095 "This option allows you to define playlist bookmarks.")
00096
00097 vlc_module_begin();
00098 set_description( _("Hotkeys management interface") );
00099 add_string( "bookmark1", NULL, NULL,
00100 BOOKMARK1_TEXT, BOOKMARK_LONGTEXT, VLC_FALSE );
00101 add_string( "bookmark2", NULL, NULL,
00102 BOOKMARK2_TEXT, BOOKMARK_LONGTEXT, VLC_FALSE );
00103 add_string( "bookmark3", NULL, NULL,
00104 BOOKMARK3_TEXT, BOOKMARK_LONGTEXT, VLC_FALSE );
00105 add_string( "bookmark4", NULL, NULL,
00106 BOOKMARK4_TEXT, BOOKMARK_LONGTEXT, VLC_FALSE );
00107 add_string( "bookmark5", NULL, NULL,
00108 BOOKMARK5_TEXT, BOOKMARK_LONGTEXT, VLC_FALSE );
00109 add_string( "bookmark6", NULL, NULL,
00110 BOOKMARK6_TEXT, BOOKMARK_LONGTEXT, VLC_FALSE );
00111 add_string( "bookmark7", NULL, NULL,
00112 BOOKMARK7_TEXT, BOOKMARK_LONGTEXT, VLC_FALSE );
00113 add_string( "bookmark8", NULL, NULL,
00114 BOOKMARK8_TEXT, BOOKMARK_LONGTEXT, VLC_FALSE );
00115 add_string( "bookmark9", NULL, NULL,
00116 BOOKMARK9_TEXT, BOOKMARK_LONGTEXT, VLC_FALSE );
00117 add_string( "bookmark10", NULL, NULL,
00118 BOOKMARK10_TEXT, BOOKMARK_LONGTEXT, VLC_FALSE );
00119
00120 set_capability( "interface", 0 );
00121 set_callbacks( Open, Close );
00122 vlc_module_end();
00123
00124
00125
00126
00127 static int Open( vlc_object_t *p_this )
00128 {
00129 intf_thread_t *p_intf = (intf_thread_t *)p_this;
00130
00131
00132 p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
00133 if( p_intf->p_sys == NULL )
00134 {
00135 msg_Err( p_intf, "out of memory" );
00136 return 1;
00137 }
00138 vlc_mutex_init( p_intf, &p_intf->p_sys->change_lock );
00139 p_intf->p_sys->i_size = 0;
00140 p_intf->pf_run = Run;
00141
00142 p_intf->p_sys->p_input = NULL;
00143 p_intf->p_sys->p_vout = NULL;
00144
00145 var_AddCallback( p_intf->p_vlc, "key-pressed", KeyEvent, p_intf );
00146 return 0;
00147 }
00148
00149
00150
00151
00152 static void Close( vlc_object_t *p_this )
00153 {
00154 intf_thread_t *p_intf = (intf_thread_t *)p_this;
00155
00156 var_DelCallback( p_intf->p_vlc, "key-pressed", KeyEvent, p_intf );
00157 if( p_intf->p_sys->p_input )
00158 {
00159 vlc_object_release( p_intf->p_sys->p_input );
00160 }
00161 if( p_intf->p_sys->p_vout )
00162 {
00163 vlc_object_release( p_intf->p_sys->p_vout );
00164 }
00165
00166 free( p_intf->p_sys );
00167 }
00168
00169
00170
00171
00172 static void Run( intf_thread_t *p_intf )
00173 {
00174 playlist_t *p_playlist = NULL;
00175 input_thread_t *p_input = NULL;
00176 vout_thread_t *p_vout = NULL;
00177 vout_thread_t *p_last_vout = NULL;
00178 struct hotkey *p_hotkeys = p_intf->p_vlc->p_hotkeys;
00179 vlc_value_t val;
00180 int i;
00181
00182
00183 for( i = 0; p_hotkeys[i].psz_action != NULL; i++ )
00184 {
00185 var_Create( p_intf->p_vlc, p_hotkeys[i].psz_action,
00186 VLC_VAR_HOTKEY | VLC_VAR_DOINHERIT );
00187
00188 var_AddCallback( p_intf->p_vlc, p_hotkeys[i].psz_action,
00189 ActionKeyCB, NULL );
00190 var_Get( p_intf->p_vlc, p_hotkeys[i].psz_action, &val );
00191 var_Set( p_intf->p_vlc, p_hotkeys[i].psz_action, val );
00192 }
00193
00194 while( !p_intf->b_die )
00195 {
00196 int i_key, i_action;
00197 int i_times = 0;
00198
00199
00200 msleep( INTF_IDLE_SLEEP );
00201
00202
00203 if( p_intf->p_sys->p_input == NULL )
00204 {
00205 p_intf->p_sys->p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT,
00206 FIND_ANYWHERE );
00207 }
00208 else if( p_intf->p_sys->p_input->b_dead )
00209 {
00210 vlc_object_release( p_intf->p_sys->p_input );
00211 p_intf->p_sys->p_input = NULL;
00212 }
00213 p_input = p_intf->p_sys->p_input;
00214
00215
00216 p_last_vout = p_intf->p_sys->p_vout;
00217 if( p_vout == NULL )
00218 {
00219 p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT, FIND_ANYWHERE );
00220 p_intf->p_sys->p_vout = p_vout;
00221 }
00222 else if( p_vout->b_die )
00223 {
00224 vlc_object_release( p_vout );
00225 p_vout = NULL;
00226 p_intf->p_sys->p_vout = NULL;
00227 }
00228
00229
00230 if( p_vout && p_vout != p_last_vout )
00231 {
00232 for( i = 0; i < CHANNELS_NUMBER; i++ )
00233 {
00234 spu_Control( p_vout->p_spu, SPU_CHANNEL_REGISTER,
00235 &p_intf->p_sys->p_channels[ i ] );
00236 }
00237 }
00238
00239
00240 i_action = 0;
00241 i_key = GetKey( p_intf );
00242 for( i = 0; i_key != -1 && p_hotkeys[i].psz_action != NULL; i++ )
00243 {
00244 if( p_hotkeys[i].i_key == i_key )
00245 {
00246 i_action = p_hotkeys[i].i_action;
00247 i_times = p_hotkeys[i].i_times;
00248 p_hotkeys[i].i_times = 0;
00249 }
00250 }
00251
00252 if( !i_action )
00253 {
00254
00255 msleep( INTF_IDLE_SLEEP );
00256 continue;
00257 }
00258
00259 if( i_action == ACTIONID_QUIT )
00260 {
00261 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
00262 FIND_ANYWHERE );
00263 if( p_playlist )
00264 {
00265 playlist_Stop( p_playlist );
00266 vlc_object_release( p_playlist );
00267 }
00268
00269 p_intf->p_vlc->b_die = VLC_TRUE;
00270 ClearChannels( p_intf, p_vout );
00271 vout_OSDMessage( p_intf, DEFAULT_CHAN, _( "Quit" ) );
00272 continue;
00273 }
00274 else if( i_action == ACTIONID_VOL_UP )
00275 {
00276 audio_volume_t i_newvol;
00277 aout_VolumeUp( p_intf, 1, &i_newvol );
00278 DisplayVolume( p_intf, p_vout, i_newvol );
00279 }
00280 else if( i_action == ACTIONID_VOL_DOWN )
00281 {
00282 audio_volume_t i_newvol;
00283 aout_VolumeDown( p_intf, 1, &i_newvol );
00284 DisplayVolume( p_intf, p_vout, i_newvol );
00285 }
00286 else if( i_action == ACTIONID_VOL_MUTE )
00287 {
00288 audio_volume_t i_newvol = -1;
00289 aout_VolumeMute( p_intf, &i_newvol );
00290 if( p_vout )
00291 {
00292 if( i_newvol == 0 )
00293 {
00294 ClearChannels( p_intf, p_vout );
00295 vout_OSDIcon( VLC_OBJECT( p_intf ), DEFAULT_CHAN,
00296 OSD_MUTE_ICON );
00297 }
00298 else
00299 {
00300 DisplayVolume( p_intf, p_vout, i_newvol );
00301 }
00302 }
00303 }
00304 else if( i_action == ACTIONID_INTF_SHOW )
00305 {
00306 val.b_bool = VLC_TRUE;
00307 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
00308 FIND_ANYWHERE );
00309 if( p_playlist )
00310 {
00311 var_Set( p_playlist, "intf-show", val );
00312 vlc_object_release( p_playlist );
00313 }
00314 }
00315 else if( i_action == ACTIONID_INTF_HIDE )
00316 {
00317 val.b_bool = VLC_FALSE;
00318 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
00319 FIND_ANYWHERE );
00320 if( p_playlist )
00321 {
00322 var_Set( p_playlist, "intf-show", val );
00323 vlc_object_release( p_playlist );
00324 }
00325 }
00326 else if( i_action == ACTIONID_SNAPSHOT )
00327 {
00328 if( p_vout ) vout_Control( p_vout, VOUT_SNAPSHOT );
00329 }
00330 else if( i_action == ACTIONID_FULLSCREEN )
00331 {
00332 if( p_vout )
00333 {
00334 var_Get( p_vout, "fullscreen", &val ); val.b_bool = !val.b_bool;
00335 var_Set( p_vout, "fullscreen", val );
00336 }
00337 else
00338 {
00339 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
00340 FIND_ANYWHERE );
00341 if( p_playlist )
00342 {
00343 var_Get( p_playlist, "fullscreen", &val ); val.b_bool = !val.b_bool;
00344 var_Set( p_playlist, "fullscreen", val );
00345 vlc_object_release( p_playlist );
00346 }
00347 }
00348 }
00349 else if( i_action == ACTIONID_PLAY_PAUSE )
00350 {
00351 val.i_int = PLAYING_S;
00352 if( p_input )
00353 {
00354 var_Get( p_input, "state", &val );
00355 }
00356 if( p_input && val.i_int != PAUSE_S )
00357 {
00358 ClearChannels( p_intf, p_vout );
00359 vout_OSDIcon( VLC_OBJECT( p_intf ), DEFAULT_CHAN,
00360 OSD_PAUSE_ICON );
00361 val.i_int = PAUSE_S;
00362 var_Set( p_input, "state", val );
00363 }
00364 else
00365 {
00366 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
00367 FIND_ANYWHERE );
00368 if( p_playlist )
00369 {
00370 ClearChannels( p_intf, p_vout );
00371 vout_OSDIcon( VLC_OBJECT( p_intf ), DEFAULT_CHAN,
00372 OSD_PLAY_ICON );
00373 playlist_Play( p_playlist );
00374 vlc_object_release( p_playlist );
00375 }
00376 }
00377 }
00378 else if( p_input )
00379 {
00380
00381
00382
00383
00384 vlc_bool_t b_seekable = VLC_TRUE;
00385
00386 if( i_action == ACTIONID_PAUSE )
00387 {
00388 ClearChannels( p_intf, p_vout );
00389 vout_OSDIcon( VLC_OBJECT( p_intf ), DEFAULT_CHAN,
00390 OSD_PAUSE_ICON );
00391 val.i_int = PAUSE_S;
00392 var_Set( p_input, "state", val );
00393 }
00394 else if( i_action == ACTIONID_JUMP_BACKWARD_3SEC && b_seekable )
00395 {
00396 val.i_time = (-3000000L * ((mtime_t)(1 << i_times)));
00397 var_Set( p_input, "time-offset", val );
00398 DisplayPosition( p_intf, p_vout, p_input );
00399 }
00400 else if( i_action == ACTIONID_JUMP_FORWARD_3SEC && b_seekable )
00401 {
00402 val.i_time = (3000000L * ((mtime_t)(1 << i_times)));
00403 var_Set( p_input, "time-offset", val );
00404 DisplayPosition( p_intf, p_vout, p_input );
00405 }
00406 else if( i_action == ACTIONID_JUMP_BACKWARD_10SEC && b_seekable )
00407 {
00408 val.i_time = (-10000000L * ((mtime_t)(1 << i_times)));
00409 var_Set( p_input, "time-offset", val );
00410 DisplayPosition( p_intf, p_vout, p_input );
00411 }
00412 else if( i_action == ACTIONID_JUMP_FORWARD_10SEC && b_seekable )
00413 {
00414 val.i_time = (10000000L * ((mtime_t)(1 << i_times)));
00415 var_Set( p_input, "time-offset", val );
00416 DisplayPosition( p_intf, p_vout, p_input );
00417 }
00418 else if( i_action == ACTIONID_JUMP_BACKWARD_1MIN && b_seekable )
00419 {
00420 val.i_time = (-60000000L * ((mtime_t)(1 << i_times)));
00421 var_Set( p_input, "time-offset", val );
00422 DisplayPosition( p_intf, p_vout, p_input );
00423 }
00424 else if( i_action == ACTIONID_JUMP_FORWARD_1MIN && b_seekable )
00425 {
00426 val.i_time = (60000000L * ((mtime_t)(1 << i_times)));
00427 var_Set( p_input, "time-offset", val );
00428 DisplayPosition( p_intf, p_vout, p_input );
00429 }
00430 else if( i_action == ACTIONID_JUMP_BACKWARD_5MIN && b_seekable )
00431 {
00432 val.i_time = (-300000000L * ((mtime_t)(1 << i_times)));
00433 var_Set( p_input, "time-offset", val );
00434 DisplayPosition( p_intf, p_vout, p_input );
00435 }
00436 else if( i_action == ACTIONID_JUMP_FORWARD_5MIN && b_seekable )
00437 {
00438 val.i_time = (300000000L * ((mtime_t)(1 << i_times)));
00439 var_Set( p_input, "time-offset", val );
00440 DisplayPosition( p_intf, p_vout, p_input );
00441 }
00442 else if( i_action == ACTIONID_AUDIO_TRACK )
00443 {
00444 vlc_value_t val, list, list2;
00445 int i_count, i;
00446 var_Get( p_input, "audio-es", &val );
00447 var_Change( p_input, "audio-es", VLC_VAR_GETCHOICES,
00448 &list, &list2 );
00449 i_count = list.p_list->i_count;
00450 if( i_count <= 1 )
00451 {
00452 continue;
00453 }
00454 for( i = 0; i < i_count; i++ )
00455 {
00456 if( val.i_int == list.p_list->p_values[i].i_int )
00457 {
00458 break;
00459 }
00460 }
00461
00462 if( i == i_count )
00463 {
00464 msg_Warn( p_input,
00465 "invalid current audio track, selecting 0" );
00466 var_Set( p_input, "audio-es",
00467 list.p_list->p_values[0] );
00468 i = 0;
00469 }
00470 else if( i == i_count - 1 )
00471 {
00472 var_Set( p_input, "audio-es",
00473 list.p_list->p_values[1] );
00474 i = 1;
00475 }
00476 else
00477 {
00478 var_Set( p_input, "audio-es",
00479 list.p_list->p_values[i+1] );
00480 i++;
00481 }
00482 vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN,
00483 _("Audio track: %s"),
00484 list2.p_list->p_values[i].psz_string );
00485 }
00486 else if( i_action == ACTIONID_SUBTITLE_TRACK )
00487 {
00488 vlc_value_t val, list, list2;
00489 int i_count, i;
00490 var_Get( p_input, "spu-es", &val );
00491
00492 var_Change( p_input, "spu-es", VLC_VAR_GETCHOICES,
00493 &list, &list2 );
00494 i_count = list.p_list->i_count;
00495 if( i_count <= 1 )
00496 {
00497 vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN, _("Subtitle track: %s"), _("N/A") );
00498 continue;
00499 }
00500 for( i = 0; i < i_count; i++ )
00501 {
00502 if( val.i_int == list.p_list->p_values[i].i_int )
00503 {
00504 break;
00505 }
00506 }
00507
00508 if( i == i_count )
00509 {
00510 msg_Warn( p_input, "invalid current subtitle track, selecting 0" );
00511 var_Set( p_input, "spu-es", list.p_list->p_values[0] );
00512 i = 0;
00513 }
00514 else if( i == i_count - 1 )
00515 {
00516 var_Set( p_input, "spu-es", list.p_list->p_values[0] );
00517 i = 0;
00518 }
00519 else
00520 {
00521 var_Set( p_input, "spu-es", list.p_list->p_values[i+1] );
00522 i = i + 1;
00523 }
00524 vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN,
00525 _("Subtitle track: %s"),
00526 list2.p_list->p_values[i].psz_string );
00527 }
00528 else if( i_action == ACTIONID_NEXT )
00529 {
00530 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
00531 FIND_ANYWHERE );
00532 if( p_playlist )
00533 {
00534 vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN, _("Next") );
00535 playlist_Next( p_playlist );
00536 vlc_object_release( p_playlist );
00537 }
00538 }
00539 else if( i_action == ACTIONID_PREV )
00540 {
00541 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
00542 FIND_ANYWHERE );
00543 if( p_playlist )
00544 {
00545 vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN, _("Previous") );
00546 playlist_Prev( p_playlist );
00547 vlc_object_release( p_playlist );
00548 }
00549 }
00550 else if( i_action == ACTIONID_STOP )
00551 {
00552 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
00553 FIND_ANYWHERE );
00554 if( p_playlist )
00555 {
00556 playlist_Stop( p_playlist );
00557 vlc_object_release( p_playlist );
00558 }
00559 }
00560 else if( i_action == ACTIONID_FASTER )
00561 {
00562 vlc_value_t val;
00563 val.b_bool = VLC_TRUE;
00564 var_Set( p_input, "rate-faster", val );
00565 vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN, _("Faster") );
00566 }
00567 else if( i_action == ACTIONID_SLOWER )
00568 {
00569 vlc_value_t val;
00570 val.b_bool = VLC_TRUE;
00571 var_Set( p_input, "rate-slower", val );
00572 vout_OSDMessage( VLC_OBJECT(p_input), DEFAULT_CHAN, _("Slower") );
00573 }
00574 else if( i_action == ACTIONID_POSITION && b_seekable )
00575 {
00576 DisplayPosition( p_intf, p_vout, p_input );
00577 }
00578 else if( i_action >= ACTIONID_PLAY_BOOKMARK1 &&
00579 i_action <= ACTIONID_PLAY_BOOKMARK10 )
00580 {
00581 PlayBookmark( p_intf, i_action - ACTIONID_PLAY_BOOKMARK1 + 1 );
00582 }
00583 else if( i_action >= ACTIONID_SET_BOOKMARK1 &&
00584 i_action <= ACTIONID_SET_BOOKMARK10 )
00585 {
00586 SetBookmark( p_intf, i_action - ACTIONID_SET_BOOKMARK1 + 1 );
00587 }
00588
00589 else if( i_action == ACTIONID_TITLE_PREV )
00590 {
00591 val.b_bool = VLC_TRUE;
00592 var_Set( p_input, "prev-title", val );
00593 }
00594 else if( i_action == ACTIONID_TITLE_NEXT )
00595 {
00596 val.b_bool = VLC_TRUE;
00597 var_Set( p_input, "next-title", val );
00598 }
00599 else if( i_action == ACTIONID_CHAPTER_PREV )
00600 {
00601 val.b_bool = VLC_TRUE;
00602 var_Set( p_input, "prev-chapter", val );
00603 }
00604 else if( i_action == ACTIONID_CHAPTER_NEXT )
00605 {
00606 val.b_bool = VLC_TRUE;
00607 var_Set( p_input, "next-chapter", val );
00608 }
00609 else if( i_action == ACTIONID_DISC_MENU )
00610 {
00611 vlc_value_t val; val.i_int = 2;
00612 msg_Dbg( p_input, "set dvdmenu" );
00613 var_Set( p_input, "title 0", val);
00614 }
00615 else if( i_action == ACTIONID_SUBDELAY_DOWN )
00616 {
00617 int64_t i_delay = var_GetTime( p_input, "spu-delay" );
00618
00619 i_delay -= 50000;
00620
00621 var_SetTime( p_input, "spu-delay", i_delay );
00622 ClearChannels( p_intf, p_vout );
00623 vout_OSDMessage( p_intf, DEFAULT_CHAN, "Subtitle delay %i ms",
00624 (int)(i_delay/1000) );
00625 }
00626 else if( i_action == ACTIONID_SUBDELAY_UP )
00627 {
00628 int64_t i_delay = var_GetTime( p_input, "spu-delay" );
00629
00630 i_delay += 50000;
00631
00632 var_SetTime( p_input, "spu-delay", i_delay );
00633 ClearChannels( p_intf, p_vout );
00634 vout_OSDMessage( p_intf, DEFAULT_CHAN, "Subtitle delay %i ms",
00635 (int)(i_delay/1000) );
00636 }
00637 else if( i_action == ACTIONID_AUDIODELAY_DOWN )
00638 {
00639 int64_t i_delay = var_GetTime( p_input, "audio-delay" );
00640
00641 i_delay -= 50000;
00642
00643 var_SetTime( p_input, "audio-delay", i_delay );
00644 ClearChannels( p_intf, p_vout );
00645 vout_OSDMessage( p_intf, DEFAULT_CHAN, "Audio delay %i ms",
00646 (int)(i_delay/1000) );
00647 }
00648 else if( i_action == ACTIONID_AUDIODELAY_UP )
00649 {
00650 int64_t i_delay = var_GetTime( p_input, "audio-delay" );
00651
00652 i_delay += 50000;
00653
00654 var_SetTime( p_input, "audio-delay", i_delay );
00655 ClearChannels( p_intf, p_vout );
00656 vout_OSDMessage( p_intf, DEFAULT_CHAN, "Audio delay %i ms",
00657 (int)(i_delay/1000) );
00658 }
00659 else if( i_action == ACTIONID_PLAY )
00660 {
00661 p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
00662 FIND_ANYWHERE );
00663 if( p_playlist )
00664 {
00665 var_Get( p_input, "rate", &val );
00666 msg_Dbg( p_input, "rate %d", val.i_int );
00667 if( val.i_int != INPUT_RATE_DEFAULT )
00668 {
00669
00670 val.i_int = INPUT_RATE_DEFAULT;
00671 var_Set( p_input, "rate", val );
00672 }
00673 else
00674 {
00675 ClearChannels( p_intf, p_vout );
00676 vout_OSDIcon( VLC_OBJECT( p_intf ), DEFAULT_CHAN,
00677 OSD_PAUSE_ICON );
00678 playlist_Play( p_playlist );
00679 }
00680 vlc_object_release( p_playlist );
00681 }
00682 }
00683 }
00684 }
00685 }
00686
00687 static int GetKey( intf_thread_t *p_intf)
00688 {
00689 vlc_mutex_lock( &p_intf->p_sys->change_lock );
00690 if ( p_intf->p_sys->i_size == 0 )
00691 {
00692 vlc_mutex_unlock( &p_intf->p_sys->change_lock );
00693 return -1;
00694 }
00695 else
00696 {
00697 int i_return = p_intf->p_sys->p_keys[ 0 ];
00698 int i;
00699 p_intf->p_sys->i_size--;
00700 for ( i = 0; i < BUFFER_SIZE - 1; i++)
00701 {
00702 p_intf->p_sys->p_keys[ i ] = p_intf->p_sys->p_keys[ i + 1 ];
00703 }
00704 vlc_mutex_unlock( &p_intf->p_sys->change_lock );
00705 return i_return;
00706 }
00707 }
00708
00709
00710
00711
00712 static int KeyEvent( vlc_object_t *p_this, char const *psz_var,
00713 vlc_value_t oldval, vlc_value_t newval, void *p_data )
00714 {
00715 intf_thread_t *p_intf = (intf_thread_t *)p_data;
00716 vlc_mutex_lock( &p_intf->p_sys->change_lock );
00717 if ( p_intf->p_sys->i_size == BUFFER_SIZE )
00718 {
00719 msg_Warn( p_intf, "event buffer full, dropping keypress" );
00720 vlc_mutex_unlock( &p_intf->p_sys->change_lock );
00721 return VLC_EGENERIC;
00722 }
00723 else
00724 {
00725 p_intf->p_sys->p_keys[ p_intf->p_sys->i_size ] = newval.i_int;
00726 p_intf->p_sys->i_size++;
00727 }
00728 vlc_mutex_unlock( &p_intf->p_sys->change_lock );
00729
00730 return VLC_SUCCESS;
00731 }
00732
00733 static int ActionKeyCB( vlc_object_t *p_this, char const *psz_var,
00734 vlc_value_t oldval, vlc_value_t newval, void *p_data )
00735 {
00736 vlc_t *p_vlc = (vlc_t *)p_this;
00737 struct hotkey *p_hotkeys = p_vlc->p_hotkeys;
00738 mtime_t i_date;
00739 int i;
00740
00741 for( i = 0; p_hotkeys[i].psz_action != NULL; i++ )
00742 {
00743 if( !strcmp( p_hotkeys[i].psz_action, psz_var ) )
00744 {
00745 p_hotkeys[i].i_key = newval.i_int;
00746
00747 i_date = mdate();
00748 if( (p_hotkeys[i].i_delta_date > 0) &&
00749 (p_hotkeys[i].i_delta_date <= (i_date - p_hotkeys[i].i_last_date) ) )
00750 p_hotkeys[i].i_times = 0;
00751 else
00752 p_hotkeys[i].i_times++;
00753 p_hotkeys[i].i_last_date = i_date;
00754 }
00755 }
00756
00757 return VLC_SUCCESS;
00758 }
00759
00760 static void PlayBookmark( intf_thread_t *p_intf, int i_num )
00761 {
00762 vlc_value_t val;
00763 int i_position;
00764 char psz_bookmark_name[11];
00765 playlist_t *p_playlist =
00766 vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
00767
00768 sprintf( psz_bookmark_name, "bookmark%i", i_num );
00769 var_Create( p_intf, psz_bookmark_name, VLC_VAR_STRING|VLC_VAR_DOINHERIT );
00770 var_Get( p_intf, psz_bookmark_name, &val );
00771
00772 if( p_playlist )
00773 {
00774 char *psz_bookmark = strdup( val.psz_string );
00775 for( i_position = 0; i_position < p_playlist->i_size; i_position++)
00776 {
00777 if( !strcmp( psz_bookmark,
00778 p_playlist->pp_items[i_position]->input.psz_uri ) )
00779 {
00780 playlist_Goto( p_playlist, i_position );
00781 break;
00782 }
00783 }
00784 vlc_object_release( p_playlist );
00785 }
00786 }
00787
00788 static void SetBookmark( intf_thread_t *p_intf, int i_num )
00789 {
00790 playlist_t *p_playlist =
00791 vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
00792 if( p_playlist )
00793 {
00794 char psz_bookmark_name[11];
00795 sprintf( psz_bookmark_name, "bookmark%i", i_num );
00796 var_Create( p_intf, psz_bookmark_name,
00797 VLC_VAR_STRING|VLC_VAR_DOINHERIT );
00798 if( p_playlist->status.p_item )
00799 {
00800 config_PutPsz( p_intf, psz_bookmark_name,
00801 p_playlist->status.p_item->input.psz_uri);
00802 msg_Info( p_intf, "setting playlist bookmark %i to %s", i_num,
00803 p_playlist->status.p_item->input.psz_uri);
00804 config_SaveConfigFile( p_intf, "hotkeys" );
00805 }
00806 vlc_object_release( p_playlist );
00807 }
00808 }
00809
00810 static void DisplayPosition( intf_thread_t *p_intf, vout_thread_t *p_vout,
00811 input_thread_t *p_input )
00812 {
00813 char psz_duration[MSTRTIME_MAX_SIZE];
00814 char psz_time[MSTRTIME_MAX_SIZE];
00815 vlc_value_t time, pos;
00816 mtime_t i_seconds;
00817
00818 if( p_vout == NULL )
00819 {
00820 return;
00821 }
00822 ClearChannels( p_intf, p_vout );
00823
00824 var_Get( p_input, "time", &time );
00825 i_seconds = time.i_time / 1000000;
00826 secstotimestr ( psz_time, i_seconds );
00827
00828 var_Get( p_input, "length", &time );
00829 if( time.i_time > 0 )
00830 {
00831 secstotimestr( psz_duration, time.i_time / 1000000 );
00832 vout_OSDMessage( p_input, POSITION_TEXT_CHAN, "%s / %s",
00833 psz_time, psz_duration );
00834 }
00835 else if( i_seconds > 0 )
00836 {
00837 vout_OSDMessage( p_input, POSITION_TEXT_CHAN, psz_time );
00838 }
00839
00840 if( !p_vout->p_parent_intf || p_vout->b_fullscreen )
00841 {
00842 var_Get( p_input, "position", &pos );
00843 vout_OSDSlider( VLC_OBJECT( p_input ), POSITION_WIDGET_CHAN,
00844 pos.f_float * 100, OSD_HOR_SLIDER );
00845 }
00846 }
00847
00848 static void DisplayVolume( intf_thread_t *p_intf, vout_thread_t *p_vout,
00849 audio_volume_t i_vol )
00850 {
00851 if( p_vout == NULL )
00852 {
00853 return;
00854 }
00855 ClearChannels( p_intf, p_vout );
00856
00857 if( !p_vout->p_parent_intf || p_vout->b_fullscreen )
00858 {
00859 vout_OSDSlider( VLC_OBJECT( p_vout ), VOLUME_WIDGET_CHAN,
00860 i_vol*100/AOUT_VOLUME_MAX, OSD_VERT_SLIDER );
00861 }
00862 else
00863 {
00864 vout_OSDMessage( p_vout, VOLUME_TEXT_CHAN, "Volume %d%%",
00865 i_vol*400/AOUT_VOLUME_MAX );
00866 }
00867 }
00868
00869 static void ClearChannels( intf_thread_t *p_intf, vout_thread_t *p_vout )
00870 {
00871 int i;
00872
00873 if( p_vout )
00874 {
00875 spu_Control( p_vout->p_spu, SPU_CHANNEL_CLEAR, DEFAULT_CHAN );
00876 for( i = 0; i < CHANNELS_NUMBER; i++ )
00877 {
00878 spu_Control( p_vout->p_spu, SPU_CHANNEL_CLEAR,
00879 p_intf->p_sys->p_channels[ i ] );
00880 }
00881 }
00882 }