X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fvideo_output%2Fcaca.c;h=888414a9eaa1784566a5f279e637396f9b66e89b;hb=3c4e97e35871880fdf5b18a7b344de614702b09c;hp=8e804c4a8e9c627ee2e355ad9c571006533a1e0a;hpb=9d3e0fb5bca5d1245c34c08bac54bfdb231a53f9;p=vlc diff --git a/modules/video_output/caca.c b/modules/video_output/caca.c index 8e804c4a8e..888414a9ea 100644 --- a/modules/video_output/caca.c +++ b/modules/video_output/caca.c @@ -1,8 +1,8 @@ /***************************************************************************** * caca.c: Color ASCII Art video output plugin using libcaca ***************************************************************************** - * Copyright (C) 2003 VideoLAN - * $Id: caca.c,v 1.3 2003/11/22 16:18:05 sam Exp $ + * Copyright (C) 2003, 2004 the VideoLAN team + * $Id$ * * Authors: Sam Hocevar * @@ -18,23 +18,49 @@ * * 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. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ /***************************************************************************** * Preamble *****************************************************************************/ -#include /* ENOMEM */ -#include /* free() */ -#include /* strerror() */ -#include +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif -#include -#include -#include +#include +#include +#include +#include +#include #include +#include + +#ifndef CACA_API_VERSION_1 + /* Upward compatibility macros */ + typedef char cucul_canvas_t; + typedef struct caca_bitmap cucul_dither_t; + typedef char caca_display_t; +# define CUCUL_COLOR_DEFAULT CACA_COLOR_LIGHTGRAY +# define CUCUL_COLOR_BLACK CACA_COLOR_BLACK +# define cucul_clear_canvas(x) caca_clear() +# define cucul_create_canvas(x,y) "" /* kinda hacky */ +# define cucul_create_dither caca_create_bitmap +# define cucul_dither_bitmap(x,y,z,t,u,v,w) caca_draw_bitmap(y,z,t,u,v,w) +# define cucul_free_dither caca_free_bitmap +# define cucul_free_canvas(x) +# define cucul_get_canvas_width(x) caca_get_width() +# define cucul_get_canvas_height(x) caca_get_height() +# define cucul_set_color(x,y,z) caca_set_color(y,z) +# define caca_create_display(x) (caca_init() ? NULL : "") /* hacky, too */ +# define caca_free_display(x) caca_end() +# define caca_get_event(x,y,z,t) *(z) = caca_get_event(y) +# define caca_refresh_display(x) caca_refresh() +# define caca_set_display_title(x,y) caca_set_window_title(y) +#endif + /***************************************************************************** * Local prototypes *****************************************************************************/ @@ -50,19 +76,11 @@ static void Display ( vout_thread_t *, picture_t * ); /***************************************************************************** * Module descriptor *****************************************************************************/ -#define MODE_TEXT N_("dithering mode") -#define MODE_LONGTEXT N_("Choose the libcaca dithering mode") - -static char *mode_list[] = { "none", "ordered", "random" }; -static char *mode_list_text[] = { N_("No dithering"), N_("Ordered dithering"), - N_("Random dithering") }; - vlc_module_begin(); - add_category_hint( N_("Dithering"), NULL, VLC_FALSE ); - add_string( "caca-dithering", "ordered", NULL, MODE_TEXT, - MODE_LONGTEXT, VLC_FALSE ); - change_string_list( mode_list, mode_list_text, 0 ); - set_description( _("colour ASCII art video output") ); + set_shortname( "Caca" ); + set_category( CAT_VIDEO ); + set_subcategory( SUBCAT_VIDEO_VOUT ); + set_description( N_("Color ASCII art video output") ); set_capability( "video output", 12 ); set_callbacks( Create, Destroy ); vlc_module_end(); @@ -75,7 +93,9 @@ vlc_module_end(); *****************************************************************************/ struct vout_sys_t { - struct caca_bitmap *p_bitmap; + cucul_canvas_t *p_cv; + caca_display_t *p_dp; + cucul_dither_t *p_dither; }; /***************************************************************************** @@ -86,39 +106,84 @@ struct vout_sys_t static int Create( vlc_object_t *p_this ) { vout_thread_t *p_vout = (vout_thread_t *)p_this; - enum caca_dithering dither = CACA_DITHER_ORDERED; - vlc_value_t val; + +#if defined( WIN32 ) && !defined( UNDER_CE ) + CONSOLE_SCREEN_BUFFER_INFO csbiInfo; + SMALL_RECT rect; + COORD coord; + HANDLE hstdout; + + if( !AllocConsole() ) + { + msg_Err( p_vout, "cannot create console" ); + return VLC_EGENERIC; + } + + hstdout = + CreateConsoleScreenBuffer( GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, CONSOLE_TEXTMODE_BUFFER, NULL ); + if( !hstdout || hstdout == INVALID_HANDLE_VALUE ) + { + msg_Err( p_vout, "cannot create screen buffer" ); + FreeConsole(); + return VLC_EGENERIC; + } + + if( !SetConsoleActiveScreenBuffer( hstdout) ) + { + msg_Err( p_vout, "cannot set active screen buffer" ); + FreeConsole(); + return VLC_EGENERIC; + } + + coord = GetLargestConsoleWindowSize( hstdout ); + msg_Dbg( p_vout, "SetConsoleWindowInfo: %ix%i", coord.X, coord.Y ); + + /* Force size for now */ + coord.X = 100; + coord.Y = 40; + + if( !SetConsoleScreenBufferSize( hstdout, coord ) ) + msg_Warn( p_vout, "SetConsoleScreenBufferSize %i %i", + coord.X, coord.Y ); + + /* Get the current screen buffer size and window position. */ + if( GetConsoleScreenBufferInfo( hstdout, &csbiInfo ) ) + { + rect.Top = 0; rect.Left = 0; + rect.Right = csbiInfo.dwMaximumWindowSize.X - 1; + rect.Bottom = csbiInfo.dwMaximumWindowSize.Y - 1; + if( !SetConsoleWindowInfo( hstdout, TRUE, &rect ) ) + msg_Dbg( p_vout, "SetConsoleWindowInfo failed: %ix%i", + rect.Right, rect.Bottom ); + } +#endif /* Allocate structure */ p_vout->p_sys = malloc( sizeof( vout_sys_t ) ); if( p_vout->p_sys == NULL ) - { - msg_Err( p_vout, "out of memory" ); return VLC_ENOMEM; - } - if( caca_init() ) + p_vout->p_sys->p_cv = cucul_create_canvas(0, 0); + if( !p_vout->p_sys->p_cv ) { - msg_Err( p_vout, "cannot initialize libcaca" ); + msg_Err( p_vout, "cannot initialize libcucul" ); free( p_vout->p_sys ); return VLC_EGENERIC; } - var_Create( p_vout, "caca-dithering", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); - var_Get( p_vout, "caca-dithering", &val ); - if( val.psz_string ) + p_vout->p_sys->p_dp = caca_create_display( p_vout->p_sys->p_cv ); + if( !p_vout->p_sys->p_dp ) { - if( !strcmp( val.psz_string, "none" ) ) - { - dither = CACA_DITHER_NONE; - } - else if( !strcmp( val.psz_string, "random" ) ) - { - dither = CACA_DITHER_RANDOM; - } - free( val.psz_string ); + msg_Err( p_vout, "cannot initialize libcaca" ); + cucul_free_canvas( p_vout->p_sys->p_cv ); + free( p_vout->p_sys ); + return VLC_EGENERIC; } - caca_set_dithering( dither ); + + caca_set_display_title( p_vout->p_sys->p_dp, + VOUT_TITLE " - Colour AsCii Art (caca)" ); p_vout->pf_init = Init; p_vout->pf_end = End; @@ -148,18 +213,16 @@ static int Init( vout_thread_t *p_vout ) p_vout->output.i_gmask = 0x0000ff00; p_vout->output.i_bmask = 0x000000ff; - /* Create the libcaca bitmap */ - p_vout->p_sys->p_bitmap = - caca_create_bitmap( 32, - p_vout->output.i_width, - p_vout->output.i_height, - 4 * ((p_vout->output.i_width + 15) & ~15), - p_vout->output.i_rmask, - p_vout->output.i_gmask, - p_vout->output.i_bmask ); - if( !p_vout->p_sys->p_bitmap ) + /* Create the libcaca dither object */ + p_vout->p_sys->p_dither = cucul_create_dither + ( 32, p_vout->output.i_width, p_vout->output.i_height, + 4 * ((p_vout->output.i_width + 15) & ~15), + p_vout->output.i_rmask, p_vout->output.i_gmask, + p_vout->output.i_bmask, 0x00000000 ); + + if( !p_vout->p_sys->p_dither ) { - msg_Err( p_vout, "could not create libcaca bitmap" ); + msg_Err( p_vout, "could not create libcaca dither object" ); return VLC_EGENERIC; } @@ -180,6 +243,7 @@ static int Init( vout_thread_t *p_vout ) /* Allocate the picture */ p_pic->p->i_lines = p_vout->output.i_height; + p_pic->p->i_visible_lines = p_vout->output.i_height; p_pic->p->i_pitch = 4 * ((p_vout->output.i_width + 15) & ~15); p_pic->p->i_pixel_pitch = 4; p_pic->p->i_visible_pitch = 4 * p_vout->output.i_width; @@ -200,7 +264,7 @@ static int Init( vout_thread_t *p_vout ) *****************************************************************************/ static void End( vout_thread_t *p_vout ) { - caca_free_bitmap( p_vout->p_sys->p_bitmap ); + cucul_free_dither( p_vout->p_sys->p_dither ); } /***************************************************************************** @@ -212,7 +276,13 @@ static void Destroy( vlc_object_t *p_this ) { vout_thread_t *p_vout = (vout_thread_t *)p_this; - caca_end(); + caca_free_display( p_vout->p_sys->p_dp ); + cucul_free_canvas( p_vout->p_sys->p_cv ); + +#if defined( WIN32 ) && !defined( UNDER_CE ) + FreeConsole(); +#endif + free( p_vout->p_sys ); } @@ -224,14 +294,37 @@ static void Destroy( vlc_object_t *p_this ) *****************************************************************************/ static int Manage( vout_thread_t *p_vout ) { - int event; - vlc_value_t val; +#ifdef CACA_API_VERSION_1 + struct caca_event ev; +#else + int ev; +#endif - while(( event = caca_get_event() )) + while( caca_get_event(p_vout->p_sys->p_dp, CACA_EVENT_ANY, &ev, 0) ) { - if( event & CACA_EVENT_KEY_PRESS ) + playlist_t *p_playlist; + vlc_value_t val; + +#ifdef CACA_API_VERSION_1 +#ifdef CACA_EVENT_OPAQUE + switch( caca_get_event_type( &ev ) ) +#else + switch( ev.type ) +#endif /* CACA_EVENT_OPAQUE */ +#else + switch( ev ) +#endif { - switch( event & 0xffff ) + case CACA_EVENT_KEY_RELEASE: +#ifdef CACA_API_VERSION_1 +#ifdef CACA_EVENT_OPAQUE + switch( caca_get_event_key_ch( &ev ) ) +#else + switch( ev.data.key.ch ) +#endif /* CACA_EVENT_OPAQUE */ +#else + switch( ev & 0x00ffffff ) +#endif { case 'q': val.i_int = KEY_MODIFIER_CTRL | 'q'; @@ -242,9 +335,56 @@ static int Manage( vout_thread_t *p_vout ) default: continue; } - } - var_Set( p_vout->p_vlc, "key-pressed", val ); + var_Set( p_vout->p_libvlc, "key-pressed", val ); + break; + case CACA_EVENT_RESIZE: + /* Acknowledge the resize */ + caca_refresh_display( p_vout->p_sys->p_dp ); + break; +#ifdef CACA_API_VERSION_1 + case CACA_EVENT_MOUSE_MOTION: + val.i_int = +#ifdef CACA_EVENT_OPAQUE + caca_get_event_mouse_x( &ev ) +#else + ev.data.mouse.x +#endif /* CACA_EVENT_OPAQUE */ + * p_vout->render.i_width + / cucul_get_canvas_width( p_vout->p_sys->p_cv ); + var_Set( p_vout, "mouse-x", val ); + val.i_int = +#ifdef CACA_EVENT_OPAQUE + caca_get_event_mouse_y( &ev ) +#else + ev.data.mouse.y +#endif /* CACA_EVENT_OPAQUE */ + * p_vout->render.i_height + / cucul_get_canvas_height( p_vout->p_sys->p_cv ); + var_Set( p_vout, "mouse-y", val ); + val.b_bool = true; + var_Set( p_vout, "mouse-moved", val ); + break; + case CACA_EVENT_MOUSE_RELEASE: + val.b_bool = true; + var_Set( p_vout, "mouse-clicked", val ); + break; + case CACA_EVENT_QUIT: + { + p_playlist = vlc_object_find( p_vout, + VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); + if( p_playlist ) + { + playlist_Stop( p_playlist ); + vlc_object_release( p_playlist ); + } + vlc_object_kill( p_vout->p_libvlc ); + break; + } +#endif + default: + break; + } } return VLC_SUCCESS; @@ -255,9 +395,13 @@ static int Manage( vout_thread_t *p_vout ) *****************************************************************************/ static void Render( vout_thread_t *p_vout, picture_t *p_pic ) { - caca_clear(); - caca_draw_bitmap( 0, 0, caca_get_width() - 1, caca_get_height() - 1, - p_vout->p_sys->p_bitmap, p_pic->p->p_pixels ); + cucul_set_color_ansi( p_vout->p_sys->p_cv, + CUCUL_COLOR_DEFAULT, CUCUL_COLOR_BLACK ); + cucul_clear_canvas( p_vout->p_sys->p_cv ); + cucul_dither_bitmap( p_vout->p_sys->p_cv, 0, 0, + cucul_get_canvas_width( p_vout->p_sys->p_cv ) - 1, + cucul_get_canvas_height( p_vout->p_sys->p_cv ) - 1, + p_vout->p_sys->p_dither, p_pic->p->p_pixels ); } /***************************************************************************** @@ -265,6 +409,7 @@ static void Render( vout_thread_t *p_vout, picture_t *p_pic ) *****************************************************************************/ static void Display( vout_thread_t *p_vout, picture_t *p_pic ) { - caca_refresh(); + VLC_UNUSED(p_pic); + caca_refresh_display( p_vout->p_sys->p_dp ); }