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

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * xosd.c : X On Screen Display interface
  3.  *****************************************************************************
  4.  * Copyright (C) 2001 the VideoLAN team
  5.  * $Id: cce06a676aaf4cc6e902696fa3483b27b9e7eabd $
  6.  *
  7.  * Authors: Loïc Minier <lool@videolan.org>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  22.  *****************************************************************************/
  23. /*****************************************************************************
  24.  * Preamble
  25.  *****************************************************************************/
  26. #ifdef HAVE_CONFIG_H
  27. # include "config.h"
  28. #endif
  29. #include <vlc_common.h>
  30. #include <vlc_plugin.h>
  31. #include <vlc_playlist.h>
  32. #include <vlc_input.h>
  33. #include <vlc_interface.h>
  34. #include <xosd.h>
  35. /*****************************************************************************
  36.  * intf_sys_t: description and status of rc interface
  37.  *****************************************************************************/
  38. struct intf_sys_t
  39. {
  40.     xosd *      p_osd;          /* libxosd handle */
  41.     bool        b_need_update;  /* Update display ? */
  42.     vlc_mutex_t lock;           /* lock for the condition variable */
  43.     vlc_cond_t  cond;           /* condition variable to know when to update */
  44. };
  45. #define MAX_LINE_LENGTH 256
  46. /*****************************************************************************
  47.  * Local prototypes.
  48.  *****************************************************************************/
  49. static int  Open        ( vlc_object_t * );
  50. static void Close       ( vlc_object_t * );
  51. static void Run         ( intf_thread_t * );
  52. static int PlaylistNext ( vlc_object_t *p_this, const char *psz_variable,
  53.                           vlc_value_t oval, vlc_value_t nval, void *param );
  54. /*****************************************************************************
  55.  * Module descriptor
  56.  *****************************************************************************/
  57. #define POSITION_TEXT N_("Flip vertical position")
  58. #define POSITION_LONGTEXT N_("Display XOSD output at the bottom of the " 
  59.                              "screen instead of the top.")
  60. #define TXT_OFS_TEXT N_("Vertical offset")
  61. #define TXT_OFS_LONGTEXT N_("Vertical offset between the border of the screen "
  62.                             "and the displayed text (in pixels, defaults to "
  63.                             "30 pixels)." )
  64. #define SHD_OFS_TEXT N_("Shadow offset")
  65. #define SHD_OFS_LONGTEXT N_("Offset between the text and the shadow (in " 
  66.                             "pixels, defaults to 2 pixels)." )
  67. #define FONT_TEXT N_("Font")
  68. #define FONT_LONGTEXT N_("Font used to display text in the XOSD output.")
  69. #define COLOUR_TEXT N_("Color")
  70. #define COLOUR_LONGTEXT N_("Color used to display text in the XOSD output.")
  71. vlc_module_begin ()
  72.     set_category( CAT_INTERFACE )
  73.     set_subcategory( SUBCAT_INTERFACE_CONTROL )
  74.     set_description( N_("XOSD interface") )
  75.     set_shortname( "XOSD" )
  76.     add_bool( "xosd-position", 1, NULL, POSITION_TEXT, POSITION_LONGTEXT, true )
  77.     add_integer( "xosd-text-offset", 30, NULL, TXT_OFS_TEXT, TXT_OFS_LONGTEXT, true )
  78.     add_integer( "xosd-shadow-offset", 2, NULL,
  79.                  SHD_OFS_TEXT, SHD_OFS_LONGTEXT, true )
  80.     add_string( "xosd-font",
  81.                 "-adobe-helvetica-bold-r-normal-*-*-160-*-*-p-*-iso8859-1",
  82.                 NULL, FONT_TEXT, FONT_LONGTEXT, true )
  83.     add_string( "xosd-colour", "LawnGreen",
  84.                     NULL, COLOUR_TEXT, COLOUR_LONGTEXT, true )
  85.     set_capability( "interface", 10 )
  86.     set_callbacks( Open, Close )
  87. vlc_module_end ()
  88. /*****************************************************************************
  89.  * Open: initialize and create stuff
  90.  *****************************************************************************/
  91. static int Open( vlc_object_t *p_this )
  92. {
  93.     intf_thread_t *p_intf = (intf_thread_t *)p_this;
  94.     intf_sys_t *p_sys;
  95.     xosd *p_osd;
  96.     char *psz_font, *psz_colour;
  97.     if( getenv( "DISPLAY" ) == NULL )
  98.     {
  99.         msg_Err( p_intf, "no display, please set the DISPLAY variable" );
  100.         return VLC_EGENERIC;
  101.     }
  102.     /* Allocate instance and initialize some members */
  103.     p_sys = p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
  104.     if( p_sys == NULL )
  105.         return VLC_ENOMEM;
  106.     /* Initialize library */
  107.     psz_font = config_GetPsz( p_intf, "xosd-font" );
  108.     psz_colour = config_GetPsz( p_intf, "xosd-colour" );
  109.     p_osd = xosd_create( 1 );
  110.     if( p_osd == NULL )
  111.     {
  112.         msg_Err( p_intf, "couldn't initialize libxosd" );
  113.         free( psz_colour );
  114.         free( psz_font );
  115.         free( p_sys );
  116.         return VLC_EGENERIC;
  117.     }
  118.     p_sys->p_osd = p_osd;
  119.     /* Set user preferences */
  120.     xosd_set_outline_colour( p_osd, "black" );
  121.     xosd_set_font( p_osd, psz_font );
  122.     xosd_set_colour( p_osd, psz_colour );
  123.     xosd_set_timeout( p_osd, 3 );
  124.     xosd_set_pos( p_osd, config_GetInt( p_intf, "xosd-position" ) ?
  125.                                         XOSD_bottom: XOSD_top );
  126.     xosd_set_horizontal_offset( p_osd,
  127.                     config_GetInt( p_intf, "xosd-text-offset" ) );
  128.     xosd_set_vertical_offset( p_osd,
  129.                     config_GetInt( p_intf, "xosd-text-offset" ) );
  130.     xosd_set_shadow_offset( p_osd,
  131.                     config_GetInt( p_intf, "xosd-shadow-offset" ));
  132.     /* Initialize to NULL */
  133.     xosd_display( p_osd, 0, XOSD_string, "XOSD interface initialized" );
  134.     free( psz_colour );
  135.     free( psz_font );
  136.     // Initialize mutex and condition variable before adding the callbacks
  137.     vlc_mutex_init( &p_sys->lock );
  138.     vlc_cond_init( &p_sys->cond );
  139.     // Add the callbacks
  140.     playlist_t *p_playlist = pl_Hold( p_intf );
  141.     var_AddCallback( p_playlist, "item-current", PlaylistNext, p_this );
  142.     var_AddCallback( p_playlist, "item-change", PlaylistNext, p_this );
  143.     pl_Release( p_intf );
  144.     p_sys->b_need_update = true;
  145.     p_intf->pf_run = Run;
  146.     return VLC_SUCCESS;
  147. }
  148. /*****************************************************************************
  149.  * Close: destroy interface stuff
  150.  *****************************************************************************/
  151. static void Close( vlc_object_t *p_this )
  152. {
  153.     intf_thread_t *p_intf = (intf_thread_t *)p_this;
  154.     playlist_t *p_playlist = pl_Hold( p_intf );
  155.     var_DelCallback( p_playlist, "item-current", PlaylistNext, p_this );
  156.     var_DelCallback( p_playlist, "item-change", PlaylistNext, p_this );
  157.     pl_Release( p_intf );
  158.     /* Uninitialize library */
  159.     xosd_destroy( p_intf->p_sys->p_osd );
  160.     /* Destroy structure */
  161.     vlc_cond_destroy( &p_intf->p_sys->cond );
  162.     vlc_mutex_destroy( &p_intf->p_sys->lock );
  163.     free( p_intf->p_sys );
  164. }
  165. /*****************************************************************************
  166.  * Run: xosd thread
  167.  *****************************************************************************
  168.  * This part of the interface runs in a separate thread
  169.  *****************************************************************************/
  170. static void Run( intf_thread_t *p_intf )
  171. {
  172.     playlist_t *p_playlist;
  173.     playlist_item_t *p_item = NULL;
  174.     char *psz_display = NULL;
  175.     int cancel = vlc_savecancel();
  176.     while( true )
  177.     {
  178.         // Wait for a signal
  179.         vlc_restorecancel( cancel );
  180.         vlc_mutex_lock( &p_intf->p_sys->lock );
  181.         mutex_cleanup_push( &p_intf->p_sys->lock );
  182.         while( !p_intf->p_sys->b_need_update )
  183.             vlc_cond_wait( &p_intf->p_sys->cond, &p_intf->p_sys->lock );
  184.         p_intf->p_sys->b_need_update = false;
  185.         vlc_cleanup_run();
  186.         // Compute the signal
  187.         cancel = vlc_savecancel();
  188.         p_playlist = pl_Hold( p_intf );
  189.         PL_LOCK;
  190.         // If the playlist is empty don't do anything
  191.         if( playlist_IsEmpty( p_playlist ) )
  192.         {
  193.             PL_UNLOCK;
  194.             pl_Release( p_intf );
  195.             continue;
  196.         }
  197.         free( psz_display );
  198.         int i_status = playlist_Status( p_playlist );
  199.         if( i_status == PLAYLIST_STOPPED )
  200.         {
  201.             psz_display = strdup(_("Stop"));
  202.         }
  203.         else if( i_status == PLAYLIST_PAUSED )
  204.         {
  205.             psz_display = strdup(_("Pause"));
  206.         }
  207.         else
  208.         {
  209.             p_item = playlist_CurrentPlayingItem( p_playlist );
  210.             if( !p_item )
  211.             {
  212.                 psz_display = NULL;
  213.                 PL_UNLOCK;
  214.                 pl_Release( p_intf );
  215.                 continue;
  216.             }
  217.             input_item_t *p_input = p_item->p_input;
  218.             mtime_t i_duration = input_item_GetDuration( p_input );
  219.             if( i_duration != -1 )
  220.             {
  221.                 char psz_durationstr[MSTRTIME_MAX_SIZE];
  222.                 secstotimestr( psz_durationstr, i_duration / 1000000 );
  223.                 if( asprintf( &psz_display, "%s (%s)", p_input->psz_name, psz_durationstr ) == -1 )
  224.                     psz_display = NULL;
  225.             }
  226.             else
  227.                 psz_display = strdup( p_input->psz_name );
  228.         }
  229.         PL_UNLOCK;
  230.         pl_Release( p_intf );
  231.         /* Display */
  232.         xosd_display( p_intf->p_sys->p_osd, 0, /* first line */
  233.                       XOSD_string, psz_display );
  234.     }
  235. }
  236. static int PlaylistNext( vlc_object_t *p_this, const char *psz_variable,
  237.                 vlc_value_t oval, vlc_value_t nval, void *param )
  238. {
  239.     (void)p_this;    (void)psz_variable;    (void)oval;    (void)nval;
  240.     intf_thread_t *p_intf = (intf_thread_t *)param;
  241.     // Send the signal using the condition variable
  242.     vlc_mutex_lock( &p_intf->p_sys->lock );
  243.     p_intf->p_sys->b_need_update = true;
  244.     vlc_cond_signal( &p_intf->p_sys->cond );
  245.     vlc_mutex_unlock( &p_intf->p_sys->lock );
  246.     return VLC_SUCCESS;
  247. }