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

intf.c

00001 /*****************************************************************************
00002  * intf.c: Video CD interface to handle user interaction and still time
00003  *****************************************************************************
00004  * Copyright (C) 2002,2003 the VideoLAN team
00005  * $Id: intf.c 11664 2005-07-09 06:17:09Z courmisch $
00006  *
00007  * Author: Rocky Bernstein <[email protected]>
00008  *   from DVD code by Stéphane Borel <[email protected]>
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 <vlc/vlc.h>
00029 #include <vlc/intf.h>
00030 #include <vlc/input.h>
00031 
00032 #include "vlc_keys.h"
00033 
00034 #include "vcd.h"
00035 #include "vcdplayer.h"
00036 #include "intf.h"
00037 
00038 /*****************************************************************************
00039  * Local prototypes.
00040  *****************************************************************************/
00041 static int  InitThread     ( intf_thread_t *p_intf );
00042 static int  KeyEvent       ( vlc_object_t *, char const *,
00043                              vlc_value_t, vlc_value_t, void * );
00044 
00045 /* Exported functions */
00046 static void RunIntf        ( intf_thread_t *p_intf );
00047 
00048 /*****************************************************************************
00049  * OpenIntf: initialize dummy interface
00050  *****************************************************************************/
00051 int VCDOpenIntf ( vlc_object_t *p_this )
00052 {
00053     intf_thread_t *p_intf = (intf_thread_t *)p_this;
00054 
00055     msg_Dbg( p_intf, "VCDOpenIntf" );
00056 
00057     /* Allocate instance and initialize some members */
00058     p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
00059     if( p_intf->p_sys == NULL )
00060     {
00061         return( VLC_EGENERIC );
00062     };
00063 
00064     p_intf->pf_run = RunIntf;
00065 
00066     var_AddCallback( p_intf->p_vlc, "key-pressed", KeyEvent, p_intf );
00067     p_intf->p_sys->m_still_time = 0;
00068     p_intf->p_sys->b_infinite_still = 0;
00069     p_intf->p_sys->b_still = 0;
00070 
00071     return( VLC_SUCCESS );
00072 }
00073 
00074 /*****************************************************************************
00075  * CloseIntf: destroy dummy interface
00076  *****************************************************************************/
00077 void VCDCloseIntf ( vlc_object_t *p_this )
00078 {
00079     intf_thread_t *p_intf = (intf_thread_t *)p_this;
00080     var_DelCallback( p_intf->p_vlc, "key-pressed", KeyEvent, p_intf );
00081 
00082     /* Destroy structure */
00083     free( p_intf->p_sys );
00084 }
00085 
00086 
00087 /*****************************************************************************
00088  * RunIntf: main loop
00089  *****************************************************************************/
00090 static void 
00091 RunIntf( intf_thread_t *p_intf )
00092 {
00093     vlc_object_t      * p_vout = NULL;
00094     mtime_t             mtime = 0;
00095     mtime_t             mlast = 0;
00096     vcdplayer_t       * p_vcdplayer;
00097     input_thread_t    * p_input;
00098     access_t          * p_access;
00099 
00100     /* What you add to the last input number entry. It accumulates all of
00101        the 10_ADD keypresses */
00102     int number_addend = 0;
00103 
00104     if( InitThread( p_intf ) < 0 )
00105     {
00106         msg_Err( p_intf, "can't initialize intf" );
00107         return;
00108     }
00109 
00110     p_input = p_intf->p_sys->p_input;
00111 
00112     while ( !p_intf->p_sys->p_vcdplayer )
00113     {
00114         msleep( INTF_IDLE_SLEEP );
00115     }
00116     
00117     p_vcdplayer = p_intf->p_sys->p_vcdplayer;
00118     p_access    = p_vcdplayer->p_access;
00119 
00120     dbg_print( INPUT_DBG_CALL, "intf initialized" );
00121 
00122     /* Main loop */
00123     while( !p_intf->b_die )
00124     {
00125       vlc_mutex_lock( &p_intf->change_lock );
00126 
00127         /*
00128          * Have we timed-out in showing a still frame?
00129          */
00130         if( p_intf->p_sys->b_still && !p_intf->p_sys->b_infinite_still )
00131         {
00132             if( p_intf->p_sys->m_still_time > 0 )
00133             {
00134                 /* Update remaining still time */
00135                 dbg_print(INPUT_DBG_STILL, "updating still time");
00136                 mtime = mdate();
00137                 if( mlast )
00138                 {
00139                     p_intf->p_sys->m_still_time -= mtime - mlast;
00140                 }
00141 
00142                 mlast = mtime;
00143             }
00144             else
00145             {
00146                 /* Still time has elapsed; set to continue playing. */
00147                 dbg_print(INPUT_DBG_STILL, "wait time done - setting play");
00148                 var_SetInteger( p_intf->p_sys->p_input, "state", PLAYING_S );
00149                 p_intf->p_sys->m_still_time = 0;
00150                 p_intf->p_sys->b_still = 0;
00151                 mlast = 0;
00152             }
00153         }
00154 
00155       /*
00156        * Do we have a keyboard event?
00157        */
00158       if( p_vout && p_intf->p_sys->b_key_pressed )
00159         {
00160           vlc_value_t val;
00161           int i, i_action = -1;
00162           struct hotkey *p_hotkeys = p_intf->p_vlc->p_hotkeys;
00163 
00164           p_intf->p_sys->b_key_pressed = VLC_FALSE;
00165 
00166           /* Find action triggered by hotkey (if any) */
00167           var_Get( p_intf->p_vlc, "key-pressed", &val );
00168 
00169           dbg_print( INPUT_DBG_EVENT, "Key pressed %d", val.i_int );
00170 
00171           for( i = 0; p_hotkeys[i].psz_action != NULL; i++ )
00172             {
00173               if( p_hotkeys[i].i_key == val.i_int )
00174                 {
00175                   i_action = p_hotkeys[i].i_action;
00176                 }
00177             }
00178 
00179           if( i_action != -1) {
00180             switch (i_action) {
00181 
00182             case ACTIONID_NAV_LEFT:
00183               dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_LEFT - prev (%d)",
00184                          number_addend );
00185               do {
00186                 vcdplayer_play_prev( p_access );
00187               }        while (number_addend-- > 0);
00188               break;
00189 
00190             case ACTIONID_NAV_RIGHT:
00191               dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_RIGHT - next (%d)",
00192                          number_addend );
00193               do {
00194                 vcdplayer_play_next( p_access );
00195               } while (number_addend-- > 0);
00196               break;
00197 
00198             case ACTIONID_NAV_UP:
00199               dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_UP - return" );
00200               do {
00201                 vcdplayer_play_return( p_access );
00202               } while (number_addend-- > 0);
00203               break;
00204 
00205             case ACTIONID_NAV_DOWN:
00206               dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_DOWN - default"  );
00207               vcdplayer_play_default( p_access );
00208               break;
00209 
00210             case ACTIONID_NAV_ACTIVATE:
00211               {
00212                 vcdinfo_itemid_t itemid;
00213                 itemid.type=p_vcdplayer->play_item.type;
00214 
00215                 dbg_print( INPUT_DBG_EVENT, "ACTIONID_NAV_ACTIVATE" );
00216 
00217                 if ( vcdplayer_pbc_is_on( p_vcdplayer ) 
00218                      && number_addend != 0 ) {
00219                   lid_t next_num=vcdinfo_selection_get_lid(p_vcdplayer->vcd,
00220                                                            p_vcdplayer->i_lid,
00221                                                            number_addend);
00222                   if (VCDINFO_INVALID_LID != next_num) {
00223                     itemid.num  = next_num;
00224                     itemid.type = VCDINFO_ITEM_TYPE_LID;
00225                     vcdplayer_play( p_access, itemid );
00226                   }
00227                 } else {
00228                   itemid.num = number_addend;
00229                   vcdplayer_play( p_access, itemid );
00230                 }
00231                 break;
00232               }
00233             }
00234             number_addend = 0;
00235 
00236             /* Any keypress gets rid of still frame waiting.
00237                FIXME - should handle just the ones that cause an action.
00238             */
00239             if( p_intf->p_sys->b_still )
00240               {
00241                 dbg_print(INPUT_DBG_STILL, "Playing still after activate");
00242                 var_SetInteger( p_intf->p_sys->p_input, "state", PLAYING_S );
00243                 p_intf->p_sys->b_still = 0;
00244                 p_intf->p_sys->b_infinite_still = 0;
00245                 p_intf->p_sys->m_still_time = 0;
00246               }
00247 
00248           } else {
00249             unsigned int digit_entered=0;
00250 
00251             switch (val.i_int) {
00252             case '9':
00253               digit_entered++;
00254             case '8':
00255               digit_entered++;
00256             case '7':
00257               digit_entered++;
00258             case '6':
00259               digit_entered++;
00260             case '5':
00261               digit_entered++;
00262             case '4':
00263               digit_entered++;
00264             case '3':
00265               digit_entered++;
00266             case '2':
00267               digit_entered++;
00268             case '1':
00269               digit_entered++;
00270             case '0':
00271               {
00272                 number_addend *= 10;
00273                 number_addend += digit_entered;
00274                 dbg_print( INPUT_DBG_EVENT,
00275                            "Added %d. Number is now: %d\n",
00276                            digit_entered, number_addend);
00277                 break;
00278               }
00279             }
00280           }
00281         }
00282 
00283 
00284       vlc_mutex_unlock( &p_intf->change_lock );
00285 
00286       if( p_vout == NULL )
00287         {
00288           p_vout = vlc_object_find( p_intf->p_sys->p_input,
00289                                     VLC_OBJECT_VOUT, FIND_CHILD );
00290           if( p_vout )
00291             {
00292               var_AddCallback( p_vout, "key-pressed", KeyEvent, p_intf );
00293             }
00294         }
00295 
00296 
00297       /* Wait a bit */
00298       msleep( INTF_IDLE_SLEEP );
00299     }
00300 
00301     if( p_vout )
00302     {
00303         var_DelCallback( p_vout, "key-pressed", KeyEvent, p_intf );
00304         vlc_object_release( p_vout );
00305     }
00306 
00307     vlc_object_release( p_intf->p_sys->p_input );
00308 }
00309 
00310 /*****************************************************************************
00311  * InitThread:
00312  *****************************************************************************/
00313 static int InitThread( intf_thread_t * p_intf )
00314 {
00315     /* We might need some locking here */
00316     if( !p_intf->b_die )
00317     {
00318         input_thread_t * p_input;
00319 
00320         p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT, FIND_PARENT );
00321 
00322         /* Maybe the input just died */
00323         if( p_input == NULL )
00324         {
00325             return VLC_EGENERIC;
00326         }
00327 
00328         vlc_mutex_lock( &p_intf->change_lock );
00329 
00330         p_intf->p_sys->p_input     = p_input;
00331         p_intf->p_sys->p_vcdplayer = NULL;
00332 
00333         p_intf->p_sys->b_move  = VLC_FALSE;
00334         p_intf->p_sys->b_click = VLC_FALSE;
00335         p_intf->p_sys->b_key_pressed = VLC_FALSE;
00336 
00337         vlc_mutex_unlock( &p_intf->change_lock );
00338 
00339         return VLC_SUCCESS;
00340     }
00341     else
00342     {
00343         return VLC_EGENERIC;
00344     }
00345 }
00346 
00347 /*****************************************************************************
00348  * KeyEvent: callback for keyboard events
00349  *****************************************************************************/
00350 static int KeyEvent( vlc_object_t *p_this, char const *psz_var,
00351                        vlc_value_t oldval, vlc_value_t newval, void *p_data )
00352 {
00353     intf_thread_t *p_intf = (intf_thread_t *)p_data;
00354     vlc_mutex_lock( &p_intf->change_lock );
00355 
00356     p_intf->p_sys->b_key_pressed = VLC_TRUE;
00357 
00358     vlc_mutex_unlock( &p_intf->change_lock );
00359 
00360     return VLC_SUCCESS;
00361 }
00362 
00363 /*****************************************************************************
00364  * vcdIntfStillTime: function provided to demux plugin to request
00365  * still images
00366  *****************************************************************************/
00367 int vcdIntfStillTime( intf_thread_t *p_intf, uint8_t i_sec )
00368 {
00369     vlc_mutex_lock( &p_intf->change_lock );
00370 
00371     p_intf->p_sys->b_still = 1;
00372     if( 255 == i_sec )
00373     {
00374         p_intf->p_sys->b_infinite_still = VLC_TRUE;
00375     }
00376     else 
00377     {
00378         p_intf->p_sys->m_still_time = MILLISECONDS_PER_SEC * i_sec;
00379     }
00380     vlc_mutex_unlock( &p_intf->change_lock );
00381 
00382     return VLC_SUCCESS;
00383 }
00384 
00385 /*****************************************************************************
00386  * vcdIntfStillTime: function provided to reset still image
00387  *****************************************************************************/
00388 int vcdIntfResetStillTime( intf_thread_t *p_intf )
00389 {
00390     vlc_mutex_lock( &p_intf->change_lock );
00391     p_intf->p_sys->m_still_time = 0;
00392     var_SetInteger( p_intf->p_sys->p_input, "state", PLAYING_S );
00393     vlc_mutex_unlock( &p_intf->change_lock );
00394 
00395     return VLC_SUCCESS;
00396 }

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