pda.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:22k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * pda.c : PDA Gtk2 plugin for vlc
  3.  *****************************************************************************
  4.  * Copyright (C) 2002 the VideoLAN team
  5.  * $Id: 2b74125970b4cfd0019d2b28bc1e1fe33a3f4d61 $
  6.  *
  7.  * Authors: Jean-Paul Saman <jpsaman  _at_ videolan _dot_ org>
  8.  *          Marc Ariberti <marcari@videolan.org>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  23.  *****************************************************************************/
  24. /*****************************************************************************
  25.  * Preamble
  26.  *****************************************************************************/
  27. #include <errno.h>                                                 /* ENOMEM */
  28. #ifdef HAVE_CONFIG_H
  29. # include "config.h"
  30. #endif
  31. #include <vlc_common.h>
  32. #include <vlc_plugin.h>
  33. #include <vlc_input.h>
  34. #include <vlc_interface.h>
  35. #include <vlc_playlist.h>
  36. #include <gtk/gtk.h>
  37. #include "pda_callbacks.h"
  38. #include "pda_interface.h"
  39. #include "pda_support.h"
  40. #include "pda.h"
  41. /*****************************************************************************
  42.  * Local prototypes.
  43.  *****************************************************************************/
  44. static int  Open         ( vlc_object_t * );
  45. static void Close        ( vlc_object_t * );
  46. static void Run          ( intf_thread_t * );
  47. static int Manage        ( intf_thread_t *p_intf );
  48. void GtkDisplayDate  ( GtkAdjustment *p_adj, gpointer userdata );
  49. gint GtkModeManage   ( intf_thread_t * p_intf );
  50. /*****************************************************************************
  51.  * Module descriptor
  52.  *****************************************************************************/
  53. #define AUTOPLAYFILE_TEXT  N_("Autoplay selected file")
  54. #define AUTOPLAYFILE_LONGTEXT N_("Automatically play a file when selected in the "
  55.         "file selection list")
  56. /*****************************************************************************
  57.  * Module descriptor
  58.  *****************************************************************************/
  59. vlc_module_begin ()
  60.     set_description( N_("PDA Linux Gtk2+ interface") )
  61.     set_category( CAT_INTERFACE )
  62.     set_subcategory( SUBCAT_INTERFACE_MAIN )
  63.     set_capability( "interface", 0 )
  64.     set_callbacks( Open, Close )
  65.     add_shortcut( "pda" )
  66. vlc_module_end ()
  67. /*****************************************************************************
  68.  * Open: initialize and create window
  69.  *****************************************************************************/
  70. static int Open( vlc_object_t *p_this )
  71. {
  72.     intf_thread_t *p_intf = (intf_thread_t *)p_this;
  73.     /* Allocate instance and initialize some members */
  74.     p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
  75.     if( p_intf->p_sys == NULL )
  76.         return VLC_ENOMEM;
  77. #ifdef NEED_GTK2_MAIN
  78.     msg_Dbg( p_intf, "Using gui-helper" );
  79.     p_intf->p_sys->p_gtk_main =
  80.         module_need( p_this, "gui-helper", "gtk2", true );
  81.     if( p_intf->p_sys->p_gtk_main == NULL )
  82.     {
  83.         free( p_intf->p_sys );
  84.         return VLC_ENOMOD;
  85.     }
  86. #endif
  87.     /* Initialize Gtk+ thread */
  88.     p_intf->p_sys->p_input = NULL;
  89.     p_intf->p_sys->b_autoplayfile = 1;
  90.     p_intf->p_sys->b_playing = 0;
  91.     p_intf->p_sys->b_slider_free = 1;
  92.     p_intf->pf_run = Run;
  93.     return VLC_SUCCESS;
  94. }
  95. /*****************************************************************************
  96.  * Close: destroy interface window
  97.  *****************************************************************************/
  98. static void Close( vlc_object_t *p_this )
  99. {
  100.     intf_thread_t *p_intf = (intf_thread_t *)p_this;
  101.     if( p_intf->p_sys->p_input )
  102.     {
  103.         vlc_object_release( p_intf->p_sys->p_input );
  104.     }
  105. #ifdef NEED_GTK2_MAIN
  106.     msg_Dbg( p_intf, "Releasing gui-helper" );
  107.     module_unneed( p_intf, p_intf->p_sys->p_gtk_main );
  108. #endif
  109.     /* Destroy structure */
  110.     free( p_intf->p_sys );
  111. }
  112. /*****************************************************************************
  113.  * Run: Gtk+ thread
  114.  *****************************************************************************
  115.  * this part of the interface is in a separate thread so that we can call
  116.  * gtk_main() from within it without annoying the rest of the program.
  117.  *****************************************************************************/
  118. static void Run( intf_thread_t *p_intf )
  119. {
  120. #ifndef NEED_GTK2_MAIN
  121.     /* gtk_init needs to know the command line. We don't care, so we
  122.      * give it an empty one */
  123.     char  *p_args[] = { "", NULL };
  124.     char **pp_args  = p_args;
  125.     int    i_args   = 1;
  126.     int    i_dummy;
  127. #endif
  128.     playlist_t        *p_playlist;
  129.     GtkCellRenderer   *p_renderer = NULL;
  130.     GtkTreeViewColumn *p_column   = NULL;
  131.     GtkListStore      *p_filelist = NULL;
  132.     GtkListStore      *p_playlist_store = NULL;
  133.     int canc = vlc_savecancel();
  134. #ifndef NEED_GTK2_MAIN
  135.     gtk_set_locale ();
  136.     msg_Dbg( p_intf, "Starting pda GTK2+ interface" );
  137.     gtk_init( &i_args, &pp_args );
  138. #else
  139.     /* Initialize Gtk+ */
  140.     msg_Dbg( p_intf, "Starting pda GTK2+ interface thread" );
  141.     gdk_threads_enter();
  142. #endif
  143.     /* Create some useful widgets that will certainly be used */
  144.     add_pixmap_directory(config_GetDataDir());
  145.     p_intf->p_sys->p_window = create_pda();
  146.     if (p_intf->p_sys->p_window == NULL)
  147.     {
  148.         msg_Err( p_intf, "unable to create pda interface" );
  149.     }
  150.     /* Store p_intf to keep an eye on it */
  151.     gtk_object_set_data( GTK_OBJECT(p_intf->p_sys->p_window),
  152.                          "p_intf", p_intf );
  153.     /* Set the title of the main window */
  154.     gtk_window_set_title( GTK_WINDOW(p_intf->p_sys->p_window),
  155.                           VOUT_TITLE " (PDA Linux interface)");
  156.     /* Get the notebook object */
  157.     p_intf->p_sys->p_notebook = GTK_NOTEBOOK( gtk_object_get_data(
  158.         GTK_OBJECT( p_intf->p_sys->p_window ), "notebook" ) );
  159.     /* Get the slider object */
  160.     p_intf->p_sys->p_slider = (GtkHScale*) lookup_widget( p_intf->p_sys->p_window, "timeSlider" );
  161.     p_intf->p_sys->p_slider_label = (GtkLabel*) lookup_widget( p_intf->p_sys->p_window, "timeLabel" );
  162.     if (p_intf->p_sys->p_slider == NULL)
  163.         msg_Err( p_intf, "Time slider widget not found." );
  164.     if (p_intf->p_sys->p_slider_label == NULL)
  165.         msg_Err( p_intf, "Time label widget not found." );
  166.     /* Connect the date display to the slider */
  167.     p_intf->p_sys->p_adj = gtk_range_get_adjustment( GTK_RANGE(p_intf->p_sys->p_slider) );
  168.     if (p_intf->p_sys->p_adj == NULL)
  169.         msg_Err( p_intf, "Adjustment range not found." );
  170.     g_signal_connect( GTK_OBJECT( p_intf->p_sys->p_adj ), "value_changed",
  171.                          G_CALLBACK( GtkDisplayDate ), p_intf );
  172.     p_intf->p_sys->f_adj_oldvalue = 0;
  173.     p_intf->p_sys->i_adj_oldvalue = 0;
  174.     /* BEGIN OF FILEVIEW GTK_TREE_VIEW */
  175.     p_intf->p_sys->p_tvfile = NULL;
  176.     p_intf->p_sys->p_tvfile = (GtkTreeView *) lookup_widget( p_intf->p_sys->p_window,
  177.                                                              "tvFileList");
  178.     if (NULL == p_intf->p_sys->p_tvfile)
  179.        msg_Err(p_intf, "Error obtaining pointer to File List");
  180.     /* Insert columns 0 */
  181.     p_renderer = gtk_cell_renderer_text_new ();
  182.     gtk_tree_view_insert_column_with_attributes(p_intf->p_sys->p_tvfile, 0, (gchar *) N_("Filename"), p_renderer, NULL);
  183.     p_column = gtk_tree_view_get_column(p_intf->p_sys->p_tvfile, 0 );
  184.     gtk_tree_view_column_add_attribute(p_column, p_renderer, "text", 0 );
  185.     gtk_tree_view_column_set_sort_column_id(p_column, 0);
  186.     /* Insert columns 1 */
  187.     p_renderer = gtk_cell_renderer_text_new ();
  188.     gtk_tree_view_insert_column_with_attributes(p_intf->p_sys->p_tvfile, 1, (gchar *) N_("Permissions"), p_renderer, NULL);
  189.     p_column = gtk_tree_view_get_column(p_intf->p_sys->p_tvfile, 1 );
  190.     gtk_tree_view_column_add_attribute(p_column, p_renderer, "text", 1 );
  191.     gtk_tree_view_column_set_sort_column_id(p_column, 1);
  192.     /* Insert columns 2 */
  193.     p_renderer = gtk_cell_renderer_text_new ();
  194.     gtk_tree_view_insert_column_with_attributes(p_intf->p_sys->p_tvfile, 2, (gchar *) N_("Size"), p_renderer, NULL);
  195.     p_column = gtk_tree_view_get_column(p_intf->p_sys->p_tvfile, 2 );
  196.     gtk_tree_view_column_add_attribute(p_column, p_renderer, "text", 2 );
  197.     gtk_tree_view_column_set_sort_column_id(p_column, 2);
  198.     /* Insert columns 3 */
  199.     p_renderer = gtk_cell_renderer_text_new ();
  200.     gtk_tree_view_insert_column_with_attributes(p_intf->p_sys->p_tvfile, 3, (gchar *) N_("Owner"), p_renderer, NULL);
  201.     p_column = gtk_tree_view_get_column(p_intf->p_sys->p_tvfile, 3 );
  202.     gtk_tree_view_column_add_attribute(p_column, p_renderer, "text", 3 );
  203.     gtk_tree_view_column_set_sort_column_id(p_column, 3);
  204.     /* Insert columns 4 */
  205.     p_renderer = gtk_cell_renderer_text_new ();
  206.     gtk_tree_view_insert_column_with_attributes(p_intf->p_sys->p_tvfile, 4, (gchar *) N_("Group"), p_renderer, NULL);
  207.     p_column = gtk_tree_view_get_column(p_intf->p_sys->p_tvfile, 4 );
  208.     gtk_tree_view_column_add_attribute(p_column, p_renderer, "text", 4 );
  209.     gtk_tree_view_column_set_sort_column_id(p_column, 4);
  210.     /* Get new directory listing */
  211.     p_filelist = gtk_list_store_new (5,
  212.                 G_TYPE_STRING, /* Filename */
  213.                 G_TYPE_STRING, /* permissions */
  214.                 G_TYPE_UINT64, /* File size */
  215.                 G_TYPE_STRING, /* Owner */
  216.                 G_TYPE_STRING);/* Group */
  217.     ReadDirectory(p_intf, p_filelist, (char*)".");
  218.     gtk_tree_view_set_model(GTK_TREE_VIEW(p_intf->p_sys->p_tvfile), GTK_TREE_MODEL(p_filelist));
  219.     g_object_unref(p_filelist);     /* Model will be released by GtkTreeView */
  220.     gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(p_intf->p_sys->p_tvfile)),GTK_SELECTION_MULTIPLE);
  221.     /* Column properties */
  222.     gtk_tree_view_set_headers_visible(p_intf->p_sys->p_tvfile, TRUE);
  223.     gtk_tree_view_columns_autosize(p_intf->p_sys->p_tvfile);
  224.     gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(p_intf->p_sys->p_tvfile),TRUE);
  225.     /* END OF FILEVIEW GTK_TREE_VIEW */
  226.     /* BEGIN OF PLAYLIST GTK_TREE_VIEW */
  227.     p_intf->p_sys->p_tvplaylist = NULL;
  228.     p_intf->p_sys->p_tvplaylist = (GtkTreeView *) lookup_widget( p_intf->p_sys->p_window, "tvPlaylist");
  229.     if (NULL == p_intf->p_sys->p_tvplaylist)
  230.        msg_Err(p_intf, "Error obtaining pointer to Play List");
  231.     /* Columns 1 */
  232.     p_renderer = gtk_cell_renderer_text_new ();
  233.     gtk_tree_view_insert_column_with_attributes(p_intf->p_sys->p_tvplaylist, 0, (gchar *) N_("Filename"), p_renderer, NULL);
  234.     p_column = gtk_tree_view_get_column(p_intf->p_sys->p_tvplaylist, 0 );
  235.     gtk_tree_view_column_add_attribute(p_column, p_renderer, "text", 0 );
  236.     gtk_tree_view_column_set_sort_column_id(p_column, 0);
  237.     /* Column 2 */
  238.     p_renderer = gtk_cell_renderer_text_new ();
  239.     gtk_tree_view_insert_column_with_attributes(p_intf->p_sys->p_tvplaylist, 1, (gchar *) N_("Time"), p_renderer, NULL);
  240.     p_column = gtk_tree_view_get_column(p_intf->p_sys->p_tvplaylist, 1 );
  241.     gtk_tree_view_column_add_attribute(p_column, p_renderer, "text", 1 );
  242.     gtk_tree_view_column_set_sort_column_id(p_column, 1);
  243. #if 0
  244.     /* Column 3 - is a hidden column used for reliable deleting items from the underlying playlist */
  245.     p_renderer = gtk_cell_renderer_text_new ();
  246.     gtk_tree_view_insert_column_with_attributes(p_intf->p_sys->p_tvplaylist, 2, (gchar *) N_("Index"), p_renderer, NULL);
  247.     p_column = gtk_tree_view_get_column(p_intf->p_sys->p_tvplaylist, 2 );
  248.     gtk_tree_view_column_add_attribute(p_column, p_renderer, "text", 2 );
  249.     gtk_tree_view_column_set_sort_column_id(p_column, 2);
  250. #endif
  251.     /* update the playlist */
  252.     p_playlist = pl_Hold( p_intf );
  253.     p_playlist_store = gtk_list_store_new (3,
  254.                 G_TYPE_STRING, /* Filename */
  255.                 G_TYPE_STRING, /* Time */
  256.                 G_TYPE_UINT);  /* Hidden index */
  257.     PlaylistRebuildListStore(p_intf,p_playlist_store, p_playlist);
  258.     gtk_tree_view_set_model(GTK_TREE_VIEW(p_intf->p_sys->p_tvplaylist), GTK_TREE_MODEL(p_playlist_store));
  259.     g_object_unref(p_playlist_store);
  260.     pl_Release( p_intf ); /* Free the playlist */
  261.     gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(p_intf->p_sys->p_tvplaylist)),GTK_SELECTION_MULTIPLE);
  262.     /* Column properties */
  263.     gtk_tree_view_set_headers_visible(p_intf->p_sys->p_tvplaylist, TRUE);
  264.     gtk_tree_view_columns_autosize(p_intf->p_sys->p_tvplaylist);
  265.     gtk_tree_view_set_headers_clickable(p_intf->p_sys->p_tvplaylist, TRUE);
  266.     /* END OF PLAYLIST GTK_TREE_VIEW */
  267.     /* Hide the Preference TAB for now. */
  268.     GtkWidget *p_preference_tab = NULL;
  269.     p_preference_tab = gtk_notebook_get_nth_page(p_intf->p_sys->p_notebook,5);
  270.     if (p_preference_tab != NULL)
  271.       gtk_widget_hide(p_preference_tab);
  272.     /* Show the control window */
  273.     gtk_widget_show( p_intf->p_sys->p_window );
  274. #ifdef NEED_GTK2_MAIN
  275.     msg_Dbg( p_intf, "Manage GTK keyboard events using threads" );
  276.     while( vlc_object_alive( p_intf ) )
  277.     {
  278.         Manage( p_intf );
  279.         /* Sleep to avoid using all CPU - since some interfaces need to
  280.          * access keyboard events, a 100ms delay is a good compromise */
  281.         gdk_threads_leave();
  282.         if (vlc_CPU() & CPU_CAPABILITY_FPU)
  283.             msleep( INTF_IDLE_SLEEP );
  284.         else
  285.             msleep( 1000 );
  286.         gdk_threads_enter();
  287.     }
  288. #else
  289.     msg_Dbg( p_intf, "Manage GTK keyboard events using timeouts" );
  290.     /* Sleep to avoid using all CPU - since some interfaces needs to access
  291.      * keyboard events, a 1000ms delay is a good compromise */
  292.     if (vlc_CPU() & CPU_CAPABILITY_FPU)
  293.         i_dummy = gtk_timeout_add( INTF_IDLE_SLEEP / 1000, (GtkFunction)Manage, p_intf );
  294.     else
  295.         i_dummy = gtk_timeout_add( 1000, (GtkFunction)Manage, p_intf );
  296.     /* Enter Gtk mode */
  297.     gtk_main();
  298.     /* Remove the timeout */
  299.     gtk_timeout_remove( i_dummy );
  300. #endif
  301.     gtk_object_destroy( GTK_OBJECT(p_intf->p_sys->p_window) );
  302. #ifdef NEED_GTK2_MAIN
  303.     gdk_threads_leave();
  304. #endif
  305.     vlc_restorecancel(canc);
  306. }
  307. /* following functions are local */
  308. /*****************************************************************************
  309.  * Manage: manage main thread messages
  310.  *****************************************************************************
  311.  * In this function, called approx. 10 times a second, we check what the
  312.  * main program wanted to tell us.
  313.  *****************************************************************************/
  314. static int Manage( intf_thread_t *p_intf )
  315. {
  316.     GtkListStore *p_liststore;
  317.     /* Update the input */
  318.     if( p_intf->p_sys->p_input == NULL )
  319.     {
  320.         p_intf->p_sys->p_input = vlc_object_find( p_intf, VLC_OBJECT_INPUT,
  321.                                                           FIND_ANYWHERE );
  322.     }
  323.     else if( p_intf->p_sys->p_input->b_dead )
  324.     {
  325.         vlc_object_release( p_intf->p_sys->p_input );
  326.         p_intf->p_sys->p_input = NULL;
  327.     }
  328.     if( p_intf->p_sys->p_input )
  329.     {
  330.         input_thread_t *p_input = p_intf->p_sys->p_input;
  331.         int64_t i_time = 0, i_length = 0;
  332.         if( vlc_object_alive (p_input) )
  333.         {
  334.             playlist_t *p_playlist;
  335.             GtkModeManage( p_intf );
  336.             p_intf->p_sys->b_playing = 1;
  337.             /* update playlist interface */
  338.             p_playlist = pl_Hold( p_intf );
  339.             if (p_playlist != NULL)
  340.             {
  341.                 p_liststore = gtk_list_store_new (3,
  342.                                             G_TYPE_STRING,
  343.                                             G_TYPE_STRING,
  344.                                             G_TYPE_UINT);  /* Hidden index */
  345.                 PlaylistRebuildListStore(p_intf, p_liststore, p_playlist);
  346.                 gtk_tree_view_set_model(p_intf->p_sys->p_tvplaylist, (GtkTreeModel*) p_liststore);
  347.                 g_object_unref(p_liststore);
  348.                 pl_Release( p_intf );
  349.             }
  350.             /* Manage the slider */
  351.             i_time = var_GetTime( p_intf->p_sys->p_input, "time" );
  352.             i_length = var_GetTime( p_intf->p_sys->p_input, "length" );
  353.             if (vlc_CPU() & CPU_CAPABILITY_FPU)
  354.             {
  355.                 /* Manage the slider for CPU_CAPABILITY_FPU hardware */
  356.                 if( p_intf->p_sys->b_playing )
  357.                 {
  358.                     float newvalue = p_intf->p_sys->p_adj->value;
  359.                     /* If the user hasn't touched the slider since the last time,
  360.                      * then the input can safely change it */
  361.                     if( newvalue == p_intf->p_sys->f_adj_oldvalue )
  362.                     {
  363.                         /* Update the value */
  364.                         p_intf->p_sys->p_adj->value =
  365.                         p_intf->p_sys->f_adj_oldvalue =
  366.                             ( 100 * i_time ) / i_length;
  367.                         g_signal_emit_by_name( GTK_OBJECT( p_intf->p_sys->p_adj ),
  368.                                                  "value_changed" );
  369.                     }
  370.                     /* Otherwise, send message to the input if the user has
  371.                      * finished dragging the slider */
  372.                     else if( p_intf->p_sys->b_slider_free )
  373.                     {
  374.                         double f_pos = (double)newvalue / 100.0;
  375.                         /* release the lock to be able to seek */
  376.                         var_SetFloat( p_input, "position", f_pos );
  377.                         /* Update the old value */
  378.                         p_intf->p_sys->f_adj_oldvalue = newvalue;
  379.                     }
  380.                 }
  381.             }
  382.             else
  383.             {
  384.                 /* Manage the slider without CPU_CAPABILITY_FPU hardware */
  385.                 if( p_intf->p_sys->b_playing )
  386.                 {
  387.                     off_t newvalue = p_intf->p_sys->p_adj->value;
  388.                     /* If the user hasn't touched the slider since the last time,
  389.                      * then the input can safely change it */
  390.                     if( newvalue == p_intf->p_sys->i_adj_oldvalue )
  391.                     {
  392.                         /* Update the value */
  393.                         p_intf->p_sys->p_adj->value =
  394.                         p_intf->p_sys->i_adj_oldvalue =
  395.                             ( 100 * i_time ) / i_length;
  396.                         g_signal_emit_by_name( GTK_OBJECT( p_intf->p_sys->p_adj ),
  397.                                                  "value_changed" );
  398.                     }
  399.                     /* Otherwise, send message to the input if the user has
  400.                      * finished dragging the slider */
  401.                     else if( p_intf->p_sys->b_slider_free )
  402.                     {
  403.                         double f_pos = (double)newvalue / 100.0;
  404.                         /* release the lock to be able to seek */
  405.                         var_SetFloat( p_input, "position", f_pos );
  406.                         /* Update the old value */
  407.                         p_intf->p_sys->i_adj_oldvalue = newvalue;
  408.                     }
  409.                 }
  410.             }
  411.         }
  412.     }
  413.     else if( p_intf->p_sys->b_playing && vlc_object_alive( p_intf ) )
  414.     {
  415.         GtkModeManage( p_intf );
  416.         p_intf->p_sys->b_playing = 0;
  417.     }
  418. #ifndef NEED_GTK2_MAIN
  419.     if( !vlc_object_alive( p_intf ) )
  420.     {
  421.         /* Prepare to die, young Skywalker */
  422.         gtk_main_quit();
  423.         return FALSE;
  424.     }
  425. #endif
  426.     return TRUE;
  427. }
  428. /*****************************************************************************
  429.  * GtkDisplayDate: display stream date
  430.  *****************************************************************************
  431.  * This function displays the current date related to the position in
  432.  * the stream. It is called whenever the slider changes its value.
  433.  * The lock has to be taken before you call the function.
  434.  *****************************************************************************/
  435. void GtkDisplayDate( GtkAdjustment *p_adj, gpointer userdata )
  436. {
  437.     (void)p_adj;
  438.     intf_thread_t *p_intf;
  439.     p_intf = (intf_thread_t*) userdata;
  440.     if (p_intf == NULL)
  441.         return;
  442.     if( p_intf->p_sys->p_input )
  443.     {
  444.         char psz_time[ MSTRTIME_MAX_SIZE ];
  445.         int64_t i_seconds;
  446.         i_seconds = var_GetTime( p_intf->p_sys->p_input, "time" ) / INT64_C(1000000 );
  447.         secstotimestr( psz_time, i_seconds );
  448.         gtk_label_set_text( GTK_LABEL( p_intf->p_sys->p_slider_label ),
  449.                             psz_time );
  450.      }
  451. }
  452. /*****************************************************************************
  453.  * GtkModeManage: actualize the aspect of the interface whenever the input
  454.  *                changes.
  455.  *****************************************************************************
  456.  * The lock has to be taken before you call the function.
  457.  *****************************************************************************/
  458. gint GtkModeManage( intf_thread_t * p_intf )
  459. {
  460.     GtkWidget *     p_slider = NULL;
  461.     bool      b_control;
  462.     if ( p_intf->p_sys->p_window == NULL )
  463.         msg_Err( p_intf, "Main widget not found" );
  464.     p_slider = lookup_widget( p_intf->p_sys->p_window, "timeSlider");
  465.     if (p_slider == NULL)
  466.         msg_Err( p_intf, "Slider widget not found" );
  467.     /* controls unavailable */
  468.     b_control = 0;
  469.     /* show the box related to current input mode */
  470.     if( p_intf->p_sys->p_input )
  471.     {
  472.         /* initialize and show slider for seekable streams */
  473.         {
  474.             gtk_widget_show( GTK_WIDGET( p_slider ) );
  475.         }
  476.         /* control buttons for free pace streams */
  477.         b_control = var_GetBool( p_intf->p_sys->p_input, "can-rate" );
  478.         msg_Dbg( p_intf, "stream has changed, refreshing interface" );
  479.     }
  480.     /* set control items */
  481.     gtk_widget_set_sensitive( lookup_widget( p_intf->p_sys->p_window, "tbRewind"), b_control );
  482.     gtk_widget_set_sensitive( lookup_widget( p_intf->p_sys->p_window, "tbPause"), b_control );
  483.     gtk_widget_set_sensitive( lookup_widget( p_intf->p_sys->p_window, "tbForward"), b_control );
  484.     return TRUE;
  485. }