Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

hotkeys.c

00001 /*****************************************************************************
00002  * hotkeys.c: Hotkey handling for vlc
00003  *****************************************************************************
00004  * Copyright (C) 2005 the VideoLAN team
00005  * $Id: hotkeys.c 12990 2005-10-28 00:13:28Z hartman $
00006  *
00007  * Authors: Sigmund Augdal Helberg <[email protected]>
00008  *          Jean-Paul Saman <jpsaman #_at_# m2x.nl>
00009  *
00010  * This program is free software; you can redistribute it and/or modify
00011  * it under the terms of the GNU General Public License as published by
00012  * the Free Software Foundation; either version 2 of the License, or
00013  * (at your option) any later version.
00014  *
00015  * This program is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  * GNU General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU General Public License
00021  * along with this program; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00023  *****************************************************************************/
00024 
00025 /*****************************************************************************
00026  * Preamble
00027  *****************************************************************************/
00028 #include <stdlib.h>                                      /* malloc(), free() */
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  * intf_sys_t: description and status of FB interface
00048  *****************************************************************************/
00049 struct intf_sys_t
00050 {
00051     vlc_mutex_t         change_lock;  /* mutex to keep the callback
00052                                        * and the main loop from
00053                                        * stepping on each others
00054                                        * toes */
00055     int                 p_keys[ BUFFER_SIZE ]; /* buffer that contains
00056                                                 * keyevents */
00057     int                 i_size;        /* number of events in buffer */
00058     int                 p_channels[ CHANNELS_NUMBER ]; /* contains registered
00059                                                         * channel IDs */
00060     input_thread_t *    p_input;       /* pointer to input */
00061     vout_thread_t *     p_vout;        /* pointer to vout object */
00062 };
00063 
00064 /*****************************************************************************
00065  * Local prototypes
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  * Module descriptor
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  * Open: initialize interface
00126  *****************************************************************************/
00127 static int Open( vlc_object_t *p_this )
00128 {
00129     intf_thread_t *p_intf = (intf_thread_t *)p_this;
00130 
00131     /* Allocate instance and initialize some members */
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  * Close: destroy interface
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     /* Destroy structure */
00166     free( p_intf->p_sys );
00167 }
00168 
00169 /*****************************************************************************
00170  * Run: main loop
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     /* Initialize hotkey structure */
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         /* Sleep a bit */
00200         msleep( INTF_IDLE_SLEEP );
00201 
00202         /* Update the input */
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         /* Update the vout */
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         /* Register OSD channels */
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         /* Find action triggered by hotkey */
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; /* times key pressed within max. delta time */
00248                 p_hotkeys[i].i_times = 0;
00249             }
00250         }
00251 
00252         if( !i_action )
00253         {
00254             /* No key pressed, sleep a bit more */
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             /* Playlist is stopped now kill vlc. */
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             /* FIXME --fenrir
00381              * How to get a valid value ?
00382              * That's not that easy with some special stream
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                 /* value of audio-es was not in choices list */
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                 /* value of spu-es was not in choices list */
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             /* Only makes sense with DVD */
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;    /* 50 ms */
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;    /* 50 ms */
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;    /* 50 ms */
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;    /* 50 ms */
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                         /* Return to normal speed */
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  * KeyEvent: callback for keyboard events
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             /* do hotkey accounting */
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 }

Generated on Tue Dec 20 10:14:30 2005 for vlc-0.8.4a by  doxygen 1.4.2