xosd.c 10.6 KB
Newer Older
1 2 3 4
/*****************************************************************************
 * xosd.c : X On Screen Display interface
 *****************************************************************************
 * Copyright (C) 2001 VideoLAN
5
 * $Id$
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
 *
 * Authors: Loc Minier <lool@videolan.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
 *****************************************************************************/

/*****************************************************************************
 * Preamble
 *****************************************************************************/
#include <stdlib.h>                                      /* malloc(), free() */
#include <string.h>

#include <xosd.h>

#include <vlc/intf.h>

#ifdef HAVE_UNISTD_H
#    include <unistd.h>
#endif

/*****************************************************************************
 * intf_sys_t: description and status of rc interface
 *****************************************************************************/
struct intf_sys_t
{
    xosd * p_osd;               /* libxosd handle */
Clément Stenac's avatar
Clément Stenac committed
44
    vlc_bool_t  b_need_update;   /* Update display ? */
45 46 47 48 49 50 51 52
};

#define MAX_LINE_LENGTH 256

/*****************************************************************************
 * Local prototypes.
 *****************************************************************************/
static int  Open         ( vlc_object_t * );
53
static void Close        ( vlc_object_t * );
54

55
static void Run          ( intf_thread_t * );
56

Clément Stenac's avatar
Clément Stenac committed
57 58 59
static int PlaylistNext( vlc_object_t *p_this, const char *psz_variable,
                vlc_value_t oval, vlc_value_t nval, void *param );

60 61 62
/*****************************************************************************
 * Module descriptor
 *****************************************************************************/
Christophe Massiot's avatar
Christophe Massiot committed
63
#define POSITION_TEXT N_("Flip vertical position")
64 65 66
#define POSITION_LONGTEXT N_("Display xosd output on the bottom of the " \
                             "screen instead of the top")

Christophe Massiot's avatar
Christophe Massiot committed
67
#define TXT_OFS_TEXT N_("Vertical offset")
68 69
#define TXT_OFS_LONGTEXT N_("Vertical offset in pixels of the displayed text")

Christophe Massiot's avatar
Christophe Massiot committed
70
#define SHD_OFS_TEXT N_("Shadow offset")
71 72
#define SHD_OFS_LONGTEXT N_("Offset in pixels of the shadow")

Christophe Massiot's avatar
Christophe Massiot committed
73
#define FONT_TEXT N_("Font")
74
#define FONT_LONGTEXT N_("Font used to display text in the xosd output")
Clément Stenac's avatar
Clément Stenac committed
75 76 77
/* FIXME FIXME FIXME: Gettextize */
#define COLOUR_TEXT ("Colour")
#define COLOUR_LONGTEXT ("Colour used to display text in the xosd output")
78 79

vlc_module_begin();
Gildas Bazin's avatar
 
Gildas Bazin committed
80
    set_description( _("XOSD interface") );
81
    add_bool( "xosd-position", 1, NULL, POSITION_TEXT, POSITION_LONGTEXT, VLC_TRUE );
Clément Stenac's avatar
Clément Stenac committed
82 83
    add_integer( "xosd-text-offset", 30, NULL, TXT_OFS_TEXT, TXT_OFS_LONGTEXT, VLC_TRUE );
    add_integer( "xosd-shadow-offset", 2, NULL,
84
                 SHD_OFS_TEXT, SHD_OFS_LONGTEXT, VLC_TRUE );
Clément Stenac's avatar
Clément Stenac committed
85 86
    add_string( "xosd-font",
                "-adobe-helvetica-bold-r-normal-*-*-160-*-*-p-*-iso8859-1",
87
                NULL, FONT_TEXT, FONT_LONGTEXT, VLC_TRUE );
Clément Stenac's avatar
Clément Stenac committed
88 89
    add_string( "xosd-colour", "LawnGreen",
                    NULL, COLOUR_TEXT, COLOUR_LONGTEXT, VLC_TRUE );
Gildas Bazin's avatar
 
Gildas Bazin committed
90
    set_capability( "interface", 10 );
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
    set_callbacks( Open, Close );
vlc_module_end();

/*****************************************************************************
 * Open: initialize and create stuff
 *****************************************************************************/
static int Open( vlc_object_t *p_this )
{
    intf_thread_t *p_intf = (intf_thread_t *)p_this;

    /* Allocate instance and initialize some members */
    p_intf->p_sys = (intf_sys_t *)malloc( sizeof( intf_sys_t ) );
    if( p_intf->p_sys == NULL )
    {
        msg_Err( p_intf, "out of memory" );
106 107 108 109 110 111 112
        return VLC_ENOMEM;
    }

    if( getenv( "DISPLAY" ) == NULL )
    {
        msg_Err( p_intf, "no display, please set the DISPLAY variable" );
        return VLC_EGENERIC;
113 114 115 116
    }

    /* Initialize library */
    p_intf->p_sys->p_osd =
117
#if defined(HAVE_XOSD_VERSION_0) || defined(HAVE_XOSD_VERSION_1)
118
        xosd_init( config_GetPsz( p_intf, "xosd-font" ),
Clément Stenac's avatar
Clément Stenac committed
119 120
                   config_GetPsz( p_intf,"xosd-colour" ), 3,
                   XOSD_top, 0, 1 );
121
#else
122
        xosd_init( config_GetPsz( p_intf, "xosd-font" ),
Clément Stenac's avatar
Clément Stenac committed
123 124
                   config_GetPsz( p_intf,"xosd-colour" ), 3,
                    XOSD_top, 0, 0, 1 );
125
#endif
126

127 128 129 130 131 132
    if( p_intf->p_sys->p_osd == NULL )
    {
        msg_Err( p_intf, "couldn't initialize libxosd" );
        return VLC_EGENERIC;
    }

Clément Stenac's avatar
Clément Stenac committed
133 134 135 136 137 138 139 140 141 142
    playlist_t *p_playlist =
            (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
                                           FIND_ANYWHERE );
    if( p_playlist == NULL )
    {
        return VLC_EGENERIC;
    }

    var_AddCallback( p_playlist, "playlist-current", PlaylistNext, p_this );
    var_AddCallback( p_playlist, "item-change", PlaylistNext, p_this );
143

Clément Stenac's avatar
Clément Stenac committed
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
    vlc_object_release( p_playlist );

    /* Set user preferences */
    xosd_set_font( p_intf->p_sys->p_osd,
                    config_GetPsz( p_intf, "xosd-font" ) );
    xosd_set_outline_colour( p_intf->p_sys->p_osd,"black" );
#ifdef HAVE_XOSD_VERSION_2
    xosd_set_horizontal_offset( p_intf->p_sys->p_osd,
                    config_GetInt( p_intf, "xosd-text-offset" ) );
    xosd_set_vertical_offset( p_intf->p_sys->p_osd,
                    config_GetInt( p_intf, "xosd-text-offset" ) );
#else
    xosd_set_offset( p_intf->p_sys->p_osd,
                    config_GetInt( p_intf, "xosd-text-offset" ) );
#endif
    xosd_set_shadow_offset( p_intf->p_sys->p_osd,
                    config_GetInt( p_intf, "xosd-shadow-offset" ));
    xosd_set_pos( p_intf->p_sys->p_osd,
                    config_GetInt( p_intf, "xosd-position" ) ?
                                         XOSD_bottom: XOSD_top );

    /* Initialize to NULL */
166 167 168 169 170 171 172
    xosd_display( p_intf->p_sys->p_osd,
                  0,
                  XOSD_string,
                  "xosd interface initialized" );

    p_intf->pf_run = Run;

Clément Stenac's avatar
Clément Stenac committed
173 174
    p_intf->p_sys->b_need_update = VLC_TRUE;

175
    return VLC_SUCCESS;
176 177 178 179 180 181
}

/*****************************************************************************
 * Close: destroy interface stuff
 *****************************************************************************/
static void Close( vlc_object_t *p_this )
182
{
183 184 185
    intf_thread_t *p_intf = (intf_thread_t *)p_this;

    /* Uninitialize library */
Clément Stenac's avatar
Clément Stenac committed
186
    xosd_destroy( p_intf->p_sys->p_osd );
187 188 189 190 191 192 193 194 195 196 197 198

    /* Destroy structure */
    free( p_intf->p_sys );
}

/*****************************************************************************
 * Run: xosd thread
 *****************************************************************************
 * This part of the interface runs in a separate thread
 *****************************************************************************/
static void Run( intf_thread_t *p_intf )
{
Clément Stenac's avatar
Clément Stenac committed
199 200 201 202 203 204
    int i_size,i_index;
    playlist_t *p_playlist;
    playlist_item_t *p_item = NULL;
    input_item_t item;
    char psz_duration[MSTRTIME_MAX_SIZE+2];
    char *psz_display = NULL;
205 206 207

    while( !p_intf->b_die )
    {
Clément Stenac's avatar
Clément Stenac committed
208
        if( p_intf->p_sys->b_need_update == VLC_TRUE )
209
        {
Clément Stenac's avatar
Clément Stenac committed
210 211 212 213
            p_intf->p_sys->b_need_update = VLC_FALSE;
            p_playlist = (playlist_t *)vlc_object_find( p_intf,
                                      VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
            if( !p_playlist )
214
            {
Clément Stenac's avatar
Clément Stenac committed
215 216
                continue;
            }
217

Clément Stenac's avatar
Clément Stenac committed
218 219 220 221
            if( p_playlist->i_size < 0 || p_playlist->i_index < 0 )
            {
                vlc_object_release( p_playlist );
                continue;
222
            }
Clément Stenac's avatar
Clément Stenac committed
223 224 225 226 227
            if( psz_display )
            {
                free( psz_display );
                psz_display = NULL;
            }
Clément Stenac's avatar
Clément Stenac committed
228
            if( p_playlist->status.i_status == PLAYLIST_STOPPED )
Clément Stenac's avatar
Clément Stenac committed
229 230 231 232 233
            {
                psz_display = (char *)malloc( sizeof(char )*strlen(_("Stop")));
                sprintf( psz_display,_("Stop") );
                vlc_object_release( p_playlist );
            }
Clément Stenac's avatar
Clément Stenac committed
234
            else if( p_playlist->status.i_status == PLAYLIST_PAUSED )
Clément Stenac's avatar
Clément Stenac committed
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
            {
                psz_display = (char *)malloc( sizeof(char )*strlen(_("Pause")));
                sprintf( psz_display,_("Pause") );
                vlc_object_release( p_playlist );
            }
            else
            {
    //           vlc_mutex_lock(&p_playlist->object_lock );
                 p_item = playlist_ItemGetByPos( p_playlist,
                                 p_playlist->i_index );
                item = p_item->input;
                if( !p_item )
                {
                    vlc_object_release( p_playlist );
     //            vlc_mutex_unlock(&p_playlist->object_lock );
                    continue;
                }
                i_size = p_playlist->i_size;
                i_index = p_playlist->i_index+1;
    //            vlc_mutex_unlock(&p_playlist->object_lock );

                vlc_object_release( p_playlist );

                if( item.i_duration != -1 )
                {
                    char psz_durationstr[MSTRTIME_MAX_SIZE];
                    secstotimestr( psz_durationstr, item.i_duration/1000000 );
                    sprintf( psz_duration, "(%s)", psz_durationstr );
                }
                else
                {
                    sprintf( psz_duration," " );
                }

                psz_display = (char *)malloc( sizeof(char )*
                                          (strlen( item.psz_name ) +
                                          MSTRTIME_MAX_SIZE + 2+6 + 10 +10 ));
                sprintf( psz_display," %i/%i - %s %s",
                         i_index,i_size, item.psz_name, psz_duration);
            }

            /* Display */
            xosd_display( p_intf->p_sys->p_osd,
                            0,                               /* first line */
                            XOSD_string,
                            psz_display );
281 282 283 284
        }

        msleep( INTF_IDLE_SLEEP );
    }
Clément Stenac's avatar
Clément Stenac committed
285
}
286

Clément Stenac's avatar
Clément Stenac committed
287 288 289 290
static int PlaylistNext( vlc_object_t *p_this, const char *psz_variable,
                vlc_value_t oval, vlc_value_t nval, void *param )
{
    intf_thread_t *p_intf = (intf_thread_t *)param;
291

Clément Stenac's avatar
Clément Stenac committed
292 293
    p_intf->p_sys->b_need_update = VLC_TRUE;
    return VLC_SUCCESS;
294 295
}