ncurses.c

来自「VLC媒体播放程序」· C语言 代码 · 共 1,156 行 · 第 1/3 页

C
1,156
字号
/***************************************************************************** * ncurses.c : NCurses plugin for vlc ***************************************************************************** * Copyright (C) 2001-2004 VideoLAN * $Id: ncurses.c,v 1.15 2004/02/22 15:57:41 fenrir Exp $ * * Authors: Sam Hocevar <sam@zoy.org> *          Laurent Aimar <fenrir@via.ecp.fr> * * 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 <errno.h>                                                 /* ENOMEM */#include <stdio.h>#include <time.h>#include <curses.h>#include <vlc/vlc.h>#include <vlc/intf.h>#include <vlc/vout.h>#ifdef HAVE_CDDAX#define CDDA_MRL "cddax://"#else#define CDDA_MRL "cdda://"#endif#ifdef HAVE_VCDX#define VCD_MRL "vcdx://"#else#define VCD_MRL "vcdx://"#endif/***************************************************************************** * Local prototypes. *****************************************************************************/static int  Open           ( vlc_object_t * );static void Close          ( vlc_object_t * );static void Run            ( intf_thread_t * );static void PlayPause      ( intf_thread_t * );static void Eject          ( intf_thread_t * );static int  HandleKey      ( intf_thread_t *, int );static void Redraw           ( intf_thread_t *, time_t * );static void ManageSlider   ( intf_thread_t * );/***************************************************************************** * Module descriptor *****************************************************************************/vlc_module_begin();    set_description( _("ncurses interface") );    set_capability( "interface", 10 );    set_callbacks( Open, Close );    add_shortcut( "curses" );vlc_module_end();/***************************************************************************** * intf_sys_t: description and status of ncurses interface *****************************************************************************/enum{    BOX_NONE,    BOX_HELP,    BOX_INFO,    BOX_LOG,    BOX_PLAYLIST};struct intf_sys_t{    playlist_t     *p_playlist;    input_thread_t *p_input;    float           f_slider;    float           f_slider_old;    WINDOW          *w;    int             i_box_type;    int             i_box_y;    int             i_box_lines;    int             i_box_lines_total;    int             i_box_start;    int             i_box_plidx;    /* Playlist index */    int             b_box_plidx_follow;    int             b_box_cleared;    msg_subscription_t* p_sub;                  /* message bank subscription */};static void DrawBox( WINDOW *win, int y, int x, int h, int w, char *title );static void DrawLine( WINDOW *win, int y, int x, int w );static void DrawEmptyLine( WINDOW *win, int y, int x, int w );/***************************************************************************** * Open: initialize and create window *****************************************************************************/static int Open( vlc_object_t *p_this ){    intf_thread_t *p_intf = (intf_thread_t *)p_this;    intf_sys_t    *p_sys;    vlc_value_t    val;    /* Allocate instance and initialize some members */    p_sys = p_intf->p_sys = malloc( sizeof( intf_sys_t ) );    p_sys->p_playlist = NULL;    p_sys->p_input = NULL;    p_sys->f_slider = 0.0;    p_sys->f_slider_old = 0.0;    p_sys->i_box_type = BOX_PLAYLIST;    p_sys->i_box_lines = 0;    p_sys->i_box_start= 0;    p_sys->i_box_lines_total = 0;    p_sys->b_box_plidx_follow = VLC_TRUE;    p_sys->b_box_cleared = VLC_FALSE;    p_sys->i_box_plidx = 0;    p_sys->p_sub = msg_Subscribe( p_intf );    /* Initialize the curses library */    p_sys->w = initscr();    keypad( p_sys->w, TRUE );    /* Don't do NL -> CR/NL */    nonl();    /* Take input chars one at a time */    cbreak();    /* Don't echo */    noecho();    curs_set(0);    timeout(0);    clear();    /* exported function */    p_intf->pf_run = Run;    /* Set quiet mode */    val.i_int = -1;    var_Set( p_intf->p_vlc, "verbose", val );    return VLC_SUCCESS;}/***************************************************************************** * Close: destroy interface window *****************************************************************************/static void Close( vlc_object_t *p_this ){    intf_thread_t *p_intf = (intf_thread_t *)p_this;    intf_sys_t    *p_sys = p_intf->p_sys;    if( p_sys->p_input )    {        vlc_object_release( p_sys->p_input );    }    if( p_sys->p_playlist )    {        vlc_object_release( p_sys->p_playlist );    }    /* Close the ncurses interface */    endwin();    msg_Unsubscribe( p_intf, p_sys->p_sub );    /* Destroy structure */    free( p_sys );}/***************************************************************************** * Run: ncurses thread *****************************************************************************/static void Run( intf_thread_t *p_intf ){    intf_sys_t    *p_sys = p_intf->p_sys;    int i_key;    time_t t_last_refresh;    /*     * force drawing the interface for the first time     */    t_last_refresh = ( time( 0 ) - 1);    while( !p_intf->b_die )    {        msleep( INTF_IDLE_SLEEP );        /* Update the input */        if( p_sys->p_playlist == NULL )        {            p_sys->p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );        }        if( p_sys->p_playlist )        {            vlc_mutex_lock( &p_sys->p_playlist->object_lock );            if( p_sys->p_input == NULL )            {                p_sys->p_input = p_sys->p_playlist->p_input;                if( p_sys->p_input )                {                    if( !p_sys->p_input->b_dead )                    {                        vlc_object_yield( p_sys->p_input );                    }                }            }            else if( p_sys->p_input->b_dead )            {                vlc_object_release( p_sys->p_input );                p_sys->p_input = NULL;                p_sys->f_slider = p_sys->f_slider_old = 0.0;                p_sys->b_box_cleared = VLC_FALSE;            }            vlc_mutex_unlock( &p_sys->p_playlist->object_lock );        }        if( p_sys->b_box_plidx_follow )        {            p_sys->i_box_plidx = p_sys->p_playlist->i_index;        }        while( ( i_key = getch()) != -1 )        {            /*             * HandleKey returns 1 if the screen needs to be redrawn             */            if ( HandleKey( p_intf, i_key ) )            {                Redraw( p_intf, &t_last_refresh );            }        }        /* Hack */        if( p_sys->f_slider > 0.0001 && !p_sys->b_box_cleared )        {            clear();            Redraw( p_intf, &t_last_refresh );            p_sys->b_box_cleared = VLC_TRUE;        }        /*         * redraw the screen every second         */        if ( (time(0) - t_last_refresh) >= 1 )        {            ManageSlider ( p_intf );            Redraw( p_intf, &t_last_refresh );        }    }}/* following functions are local */static int HandleKey( intf_thread_t *p_intf, int i_key ){    intf_sys_t *p_sys = p_intf->p_sys;    vlc_value_t val;    if( p_sys->i_box_type == BOX_PLAYLIST && p_sys->p_playlist )    {        int b_ret = VLC_TRUE;        switch( i_key )        {            /* Playlist sort */            case 'r':                playlist_Sort( p_sys->p_playlist, SORT_RANDOM, ORDER_NORMAL );                return 1;            case 'o':                playlist_Sort( p_sys->p_playlist, SORT_TITLE, ORDER_NORMAL );                return 1;            case 'O':                playlist_Sort( p_sys->p_playlist, SORT_TITLE, ORDER_REVERSE );                return 1;            /* Playlist navigation */            case KEY_HOME:                p_sys->i_box_plidx = 0;                break;            case KEY_END:                p_sys->i_box_plidx = p_sys->p_playlist->i_size - 1;                break;            case KEY_UP:                p_sys->i_box_plidx--;                break;            case KEY_DOWN:                p_sys->i_box_plidx++;                break;            case KEY_PPAGE:                p_sys->i_box_plidx -= p_sys->i_box_lines;                break;            case KEY_NPAGE:                p_sys->i_box_plidx += p_sys->i_box_lines;                break;            case KEY_BACKSPACE:            case KEY_DC:            {                int i_item = p_sys->p_playlist->i_index;                playlist_Delete( p_sys->p_playlist, p_sys->i_box_plidx );                if( i_item < p_sys->p_playlist->i_size && i_item != p_sys->p_playlist->i_index )                {                    playlist_Goto( p_sys->p_playlist, i_item );                }                break;            }            case KEY_ENTER:            case 0x0d:                playlist_Goto( p_sys->p_playlist, p_sys->i_box_plidx );                break;            default:                b_ret = VLC_FALSE;                break;        }        if( b_ret )        {            if( p_sys->i_box_plidx >= p_sys->p_playlist->i_size ) p_sys->i_box_plidx = p_sys->p_playlist->i_size - 1;            if( p_sys->i_box_plidx < 0 ) p_sys->i_box_plidx = 0;            if( p_sys->i_box_plidx == p_sys->p_playlist->i_index )                p_sys->b_box_plidx_follow = VLC_TRUE;            else                p_sys->b_box_plidx_follow = VLC_FALSE;            return 1;        }    }    else if( p_sys->i_box_type == BOX_HELP || p_sys->i_box_type == BOX_INFO )    {        switch( i_key )        {            case KEY_HOME:                p_sys->i_box_start = 0;                return 1;            case KEY_END:                p_sys->i_box_start = p_sys->i_box_lines_total - 1;                return 1;            case KEY_UP:                if( p_sys->i_box_start > 0 ) p_sys->i_box_start--;                return 1;            case KEY_DOWN:                if( p_sys->i_box_start < p_sys->i_box_lines_total - 1 )                {                    p_sys->i_box_start++;                }                return 1;            case KEY_PPAGE:                p_sys->i_box_start -= p_sys->i_box_lines;                if( p_sys->i_box_start < 0 ) p_sys->i_box_start = 0;                return 1;            case KEY_NPAGE:                p_sys->i_box_start += p_sys->i_box_lines;                if( p_sys->i_box_start >= p_sys->i_box_lines_total )                {                    p_sys->i_box_start = p_sys->i_box_lines_total - 1;                }                return 1;            default:                break;        }    }    else if( p_sys->i_box_type == BOX_NONE )    {        switch( i_key )        {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?