Commit 52af2d54 authored by Laurent Aimar's avatar Laurent Aimar

Converted vout caca to "vout display" API.

parent de33cab8
/***************************************************************************** /*****************************************************************************
* caca.c: Color ASCII Art video output plugin using libcaca * caca.c: Color ASCII Art "vout display" module using libcaca
***************************************************************************** *****************************************************************************
* Copyright (C) 2003-2009 the VideoLAN team * Copyright (C) 2003-2009 the VideoLAN team
* $Id$ * $Id$
* *
* Authors: Sam Hocevar <sam@zoy.org> * Authors: Sam Hocevar <sam@zoy.org>
* Laurent Aimar <fenrir _AT_ videolan _DOT_ org>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -31,393 +32,501 @@ ...@@ -31,393 +32,501 @@
#include <vlc_common.h> #include <vlc_common.h>
#include <vlc_plugin.h> #include <vlc_plugin.h>
#include <vlc_vout.h> #include <vlc_vout_display.h>
#include <vlc_interface.h> #include <vlc_picture_pool.h>
#include <vlc_playlist.h>
#include <vlc_keys.h>
#include <caca.h> #include <caca.h>
#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
*****************************************************************************/
static int Create ( vlc_object_t * );
static void Destroy ( vlc_object_t * );
static int Init ( vout_thread_t * );
static void End ( vout_thread_t * );
static int Manage ( vout_thread_t * );
static void Render ( vout_thread_t *, picture_t * );
static void Display ( vout_thread_t *, picture_t * );
/***************************************************************************** /*****************************************************************************
* Module descriptor * Module descriptor
*****************************************************************************/ *****************************************************************************/
vlc_module_begin () static int Open (vlc_object_t *);
set_shortname( "Caca" ) static void Close(vlc_object_t *);
set_category( CAT_VIDEO )
set_subcategory( SUBCAT_VIDEO_VOUT ) vlc_module_begin()
set_description( N_("Color ASCII art video output") ) set_shortname("Caca")
set_capability( "video output", 12 ) set_category(CAT_VIDEO)
set_callbacks( Create, Destroy ) set_subcategory(SUBCAT_VIDEO_VOUT)
vlc_module_end () set_description(N_("Color ASCII art video output"))
set_capability("vout display", 12)
set_callbacks(Open, Close)
vlc_module_end()
/***************************************************************************** /*****************************************************************************
* vout_sys_t: libcaca video output method descriptor * Local prototypes
*****************************************************************************
* This structure is part of the video output thread descriptor.
* It describes the libcaca specific properties of an output thread.
*****************************************************************************/ *****************************************************************************/
struct vout_sys_t static picture_t *Get (vout_display_t *);
{ static void Prepare(vout_display_t *, picture_t *);
cucul_canvas_t *p_cv; static void Display(vout_display_t *, picture_t *);
caca_display_t *p_dp; static int Control(vout_display_t *, int, va_list);
cucul_dither_t *p_dither;
/* */
static void Manage(vout_display_t *);
static void Refresh(vout_display_t *);
static void Place(vout_display_t *, vout_display_place_t *);
/* */
struct vout_display_sys_t {
cucul_canvas_t *cv;
caca_display_t *dp;
cucul_dither_t *dither;
picture_pool_t *pool;
}; };
/***************************************************************************** /**
* Create: allocates libcaca video output thread
*****************************************************************************
* This function initializes libcaca vout method. * This function initializes libcaca vout method.
*****************************************************************************/ */
static int Create( vlc_object_t *p_this ) static int Open(vlc_object_t *object)
{ {
vout_thread_t *p_vout = (vout_thread_t *)p_this; vout_display_t *vd = (vout_display_t *)object;
vout_display_sys_t *sys;
#if defined( WIN32 ) && !defined( UNDER_CE ) #if defined(WIN32) && !defined(UNDER_CE)
CONSOLE_SCREEN_BUFFER_INFO csbiInfo; CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
SMALL_RECT rect; SMALL_RECT rect;
COORD coord; COORD coord;
HANDLE hstdout; HANDLE hstdout;
if( !AllocConsole() ) if (!AllocConsole()) {
{ msg_Err(vd, "cannot create console");
msg_Err( p_vout, "cannot create console" );
return VLC_EGENERIC; return VLC_EGENERIC;
} }
hstdout = hstdout =
CreateConsoleScreenBuffer( GENERIC_READ | GENERIC_WRITE, CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, CONSOLE_TEXTMODE_BUFFER, NULL ); NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
if( !hstdout || hstdout == INVALID_HANDLE_VALUE ) if (!hstdout || hstdout == INVALID_HANDLE_VALUE) {
{ msg_Err(vd, "cannot create screen buffer");
msg_Err( p_vout, "cannot create screen buffer" );
FreeConsole(); FreeConsole();
return VLC_EGENERIC; return VLC_EGENERIC;
} }
if( !SetConsoleActiveScreenBuffer( hstdout) ) if (!SetConsoleActiveScreenBuffer(hstdout)) {
{ msg_Err(vd, "cannot set active screen buffer");
msg_Err( p_vout, "cannot set active screen buffer" );
FreeConsole(); FreeConsole();
return VLC_EGENERIC; return VLC_EGENERIC;
} }
coord = GetLargestConsoleWindowSize( hstdout ); coord = GetLargestConsoleWindowSize(hstdout);
msg_Dbg( p_vout, "SetConsoleWindowInfo: %ix%i", coord.X, coord.Y ); msg_Dbg(vd, "SetConsoleWindowInfo: %ix%i", coord.X, coord.Y);
/* Force size for now */ /* Force size for now */
coord.X = 100; coord.X = 100;
coord.Y = 40; coord.Y = 40;
if( !SetConsoleScreenBufferSize( hstdout, coord ) ) if (!SetConsoleScreenBufferSize(hstdout, coord))
msg_Warn( p_vout, "SetConsoleScreenBufferSize %i %i", msg_Warn(vd, "SetConsoleScreenBufferSize %i %i",
coord.X, coord.Y ); coord.X, coord.Y);
/* Get the current screen buffer size and window position. */ /* Get the current screen buffer size and window position. */
if( GetConsoleScreenBufferInfo( hstdout, &csbiInfo ) ) if (GetConsoleScreenBufferInfo(hstdout, &csbiInfo)) {
{
rect.Top = 0; rect.Left = 0; rect.Top = 0; rect.Left = 0;
rect.Right = csbiInfo.dwMaximumWindowSize.X - 1; rect.Right = csbiInfo.dwMaximumWindowSize.X - 1;
rect.Bottom = csbiInfo.dwMaximumWindowSize.Y - 1; rect.Bottom = csbiInfo.dwMaximumWindowSize.Y - 1;
if( !SetConsoleWindowInfo( hstdout, TRUE, &rect ) ) if (!SetConsoleWindowInfo(hstdout, TRUE, &rect))
msg_Dbg( p_vout, "SetConsoleWindowInfo failed: %ix%i", msg_Dbg(vd, "SetConsoleWindowInfo failed: %ix%i",
rect.Right, rect.Bottom ); rect.Right, rect.Bottom);
} }
#endif #endif
/* Allocate structure */ /* Allocate structure */
p_vout->p_sys = malloc( sizeof( vout_sys_t ) ); vd->sys = sys = calloc(1, sizeof(*sys));
if( p_vout->p_sys == NULL ) if (!sys)
{ goto error;
#if defined( WIN32 ) && !defined( UNDER_CE )
FreeConsole(); sys->cv = cucul_create_canvas(0, 0);
#endif if (!sys->cv) {
return VLC_ENOMEM; msg_Err(vd, "cannot initialize libcucul");
goto error;
} }
p_vout->p_sys->p_cv = cucul_create_canvas(0, 0); sys->dp = caca_create_display(sys->cv);
if( !p_vout->p_sys->p_cv ) if (!sys->dp) {
{ msg_Err(vd, "cannot initialize libcaca");
msg_Err( p_vout, "cannot initialize libcucul" ); goto error;
#if defined( WIN32 ) && !defined( UNDER_CE )
FreeConsole();
#endif
free( p_vout->p_sys );
return VLC_EGENERIC;
} }
p_vout->p_sys->p_dp = caca_create_display( p_vout->p_sys->p_cv ); if (vd->cfg->display.title)
if( !p_vout->p_sys->p_dp ) caca_set_display_title(sys->dp,
{ vd->cfg->display.title);
msg_Err( p_vout, "cannot initialize libcaca" ); else
cucul_free_canvas( p_vout->p_sys->p_cv ); caca_set_display_title(sys->dp,
#if defined( WIN32 ) && !defined( UNDER_CE ) VOUT_TITLE "(Colour AsCii Art)");
FreeConsole();
#endif /* Fix format */
free( p_vout->p_sys ); video_format_t fmt = vd->fmt;
return VLC_EGENERIC; if (fmt.i_chroma != VLC_CODEC_RGB32) {
fmt.i_chroma = VLC_CODEC_RGB32;
fmt.i_rmask = 0x00ff0000;
fmt.i_gmask = 0x0000ff00;
fmt.i_bmask = 0x000000ff;
} }
caca_set_display_title( p_vout->p_sys->p_dp, /* */
VOUT_TITLE " - Colour AsCii Art (caca)" ); sys->pool = picture_pool_NewFromFormat(&fmt, 1);
if (!sys->pool)
goto error;
p_vout->pf_init = Init; /* TODO */
p_vout->pf_end = End; vout_display_info_t info = vd->info;
p_vout->pf_manage = Manage;
p_vout->pf_render = Render; /* Setup vout_display now that everything is fine */
p_vout->pf_display = Display; vd->fmt = fmt;
vd->info = info;
vd->get = Get;
vd->prepare = Prepare;
vd->display = Display;
vd->control = Control;
vd->manage = Manage;
/* Fix initial state */
vout_display_SendEventFullscreen(vd, false);
Refresh(vd);
return VLC_SUCCESS; return VLC_SUCCESS;
error:
if (sys) {
if (sys->pool)
picture_pool_Delete(sys->pool);
if (sys->dither)
cucul_free_dither(sys->dither);
if (sys->dp)
caca_free_display(sys->dp);
if (sys->cv)
cucul_free_canvas(sys->cv);
free(sys);
}
#if defined(WIN32) && !defined(UNDER_CE)
FreeConsole();
#endif
return VLC_EGENERIC;
} }
/***************************************************************************** /**
* Init: initialize libcaca video output thread * Close a libcaca video output
*****************************************************************************/ */
static int Init( vout_thread_t *p_vout ) static void Close(vlc_object_t *object)
{ {
int i_index; vout_display_t *vd = (vout_display_t *)object;
picture_t *p_pic = NULL; vout_display_sys_t *sys = vd->sys;
I_OUTPUTPICTURES = 0;
p_vout->output.i_chroma = VLC_CODEC_RGB32;
p_vout->output.i_width = p_vout->render.i_width;
p_vout->output.i_height = p_vout->render.i_height;
p_vout->output.i_aspect = p_vout->render.i_aspect;
p_vout->output.i_rmask = 0x00ff0000;
p_vout->output.i_gmask = 0x0000ff00;
p_vout->output.i_bmask = 0x000000ff;
/* 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 dither object" );
return VLC_EGENERIC;
}
/* Find an empty picture slot */ picture_pool_Delete(sys->pool);
for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ ) if (sys->dither)
{ cucul_free_dither(sys->dither);
if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE ) caca_free_display(sys->dp);
{ cucul_free_canvas(sys->cv);
p_pic = p_vout->p_picture + i_index;
break;
}
}
if( p_pic == NULL ) #if defined(WIN32) && !defined(UNDER_CE)
{ FreeConsole();
return VLC_EGENERIC; #endif
free(sys);
}
/**
* Return a direct buffer
*/
static picture_t *Get(vout_display_t *vd)
{
vout_display_sys_t *sys = vd->sys;
return picture_pool_Get(sys->pool);
}
/**
* Prepare a picture for display */
static void Prepare(vout_display_t *vd, picture_t *picture)
{
vout_display_sys_t *sys = vd->sys;
if (!sys->dither) {
/* Create the libcaca dither object */
sys->dither = cucul_create_dither(32,
vd->source.i_visible_width,
vd->source.i_visible_height,
picture->p[0].i_pitch,
vd->fmt.i_rmask,
vd->fmt.i_gmask,
vd->fmt.i_bmask,
0x00000000);
if (!sys->dither) {
msg_Err(vd, "could not create libcaca dither object");
return;
}
} }
/* Allocate the picture */ vout_display_place_t place;
p_pic->p->i_lines = p_vout->output.i_height; Place(vd, &place);
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;
p_pic->i_planes = 1;
p_pic->p->p_pixels = malloc( p_pic->p->i_pitch * p_pic->p->i_lines );
p_pic->i_status = DESTROYED_PICTURE; cucul_set_color_ansi(sys->cv, CUCUL_COLOR_DEFAULT, CUCUL_COLOR_BLACK);
p_pic->i_type = DIRECT_PICTURE; cucul_clear_canvas(sys->cv);
PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic; const int crop_offset = vd->source.i_y_offset * picture->p->i_pitch +
I_OUTPUTPICTURES++; vd->source.i_x_offset * picture->p->i_pixel_pitch;
cucul_dither_bitmap(sys->cv, place.x, place.y,
place.width, place.height,
sys->dither,
&picture->p->p_pixels[crop_offset]);
}
return VLC_SUCCESS; /**
* Display a picture
*/
static void Display(vout_display_t *vd, picture_t *picture)
{
Refresh(vd);
picture_Release(picture);
} }
/***************************************************************************** /**
* End: terminate libcaca video output thread * Control for vout display
*****************************************************************************/ */
static void End( vout_thread_t *p_vout ) static int Control(vout_display_t *vd, int query, va_list args)
{ {
cucul_free_dither( p_vout->p_sys->p_dither ); vout_display_sys_t *sys = vd->sys;
switch (query) {
case VOUT_DISPLAY_HIDE_MOUSE:
caca_set_mouse(sys->dp, 0);
return VLC_SUCCESS;
case VOUT_DISPLAY_CHANGE_DISPLAY_SIZE: {
const vout_display_cfg_t *cfg = va_arg(args, const vout_display_cfg_t *);
caca_refresh_display(sys->dp);
/* Not quite good but not sure how to resize it */
if (cfg->display.width != caca_get_display_width(sys->dp) ||
cfg->display.height != caca_get_display_height(sys->dp))
return VLC_EGENERIC;
return VLC_SUCCESS;
}
case VOUT_DISPLAY_CHANGE_ZOOM:
case VOUT_DISPLAY_CHANGE_DISPLAY_FILLED:
case VOUT_DISPLAY_CHANGE_SOURCE_ASPECT:
return VLC_SUCCESS;
case VOUT_DISPLAY_CHANGE_SOURCE_CROP:
if (sys->dither)
cucul_free_dither(sys->dither);
sys->dither = NULL;
return VLC_SUCCESS;
default:
msg_Err(vd, "Unsupported query in vout display caca");
return VLC_EGENERIC;
}
} }
/***************************************************************************** /**
* Destroy: destroy libcaca video output thread * Refresh the display and send resize event
***************************************************************************** */
* Terminate an output method created by AaCreateOutputMethod static void Refresh(vout_display_t *vd)
*****************************************************************************/
static void Destroy( vlc_object_t *p_this )
{ {
vout_thread_t *p_vout = (vout_thread_t *)p_this; vout_display_sys_t *sys = vd->sys;
caca_free_display( p_vout->p_sys->p_dp ); /* */
cucul_free_canvas( p_vout->p_sys->p_cv ); caca_refresh_display(sys->dp);
#if defined( WIN32 ) && !defined( UNDER_CE ) /* */
FreeConsole(); const int width = caca_get_display_width(sys->dp);
#endif const int height = caca_get_display_height(sys->dp);
free( p_vout->p_sys ); if (width != vd->cfg->display.width ||
height != vd->cfg->display.height)
vout_display_SendEventDisplaySize(vd, width, height);
} }
/***************************************************************************** /**
* Manage: handle libcaca events * Compute the place in canvas unit.
***************************************************************************** */
* This function should be called regularly by video output thread. It manages static void Place(vout_display_t *vd, vout_display_place_t *place)
* console events. It returns a non null value on error.
*****************************************************************************/
static int Manage( vout_thread_t *p_vout )
{ {
#ifdef CACA_API_VERSION_1 vout_display_sys_t *sys = vd->sys;
struct caca_event ev;
#else vout_display_PlacePicture(place, &vd->source, vd->cfg, false);
int ev;
#endif const int canvas_width = cucul_get_canvas_width(sys->cv);
const int canvas_height = cucul_get_canvas_height(sys->cv);
const int display_width = caca_get_display_width(sys->dp);
const int display_height = caca_get_display_height(sys->dp);
if (display_width > 0 && display_height > 0) {
place->x = place->x * canvas_width / display_width;
place->y = place->y * canvas_height / display_height;
place->width = (place->width * canvas_width + display_width/2) / display_width;
place->height = (place->height * canvas_height + display_height/2) / display_height;
} else {
place->x = 0;
place->y = 0;
place->width = canvas_width;
place->height = display_height;
}
}
while( caca_get_event(p_vout->p_sys->p_dp, CACA_EVENT_ANY, &ev, 0) ) /* */
{ static const struct {
playlist_t *p_playlist; int caca;
vlc_value_t val; int vlc;
} keys[] = {
#ifdef CACA_API_VERSION_1
#ifdef CACA_EVENT_OPAQUE { CACA_KEY_CTRL_A, KEY_MODIFIER_CTRL | 'a' },
switch( caca_get_event_type( &ev ) ) { CACA_KEY_CTRL_B, KEY_MODIFIER_CTRL | 'b' },
#else { CACA_KEY_CTRL_C, KEY_MODIFIER_CTRL | 'c' },
switch( ev.type ) { CACA_KEY_CTRL_D, KEY_MODIFIER_CTRL | 'd' },
#endif /* CACA_EVENT_OPAQUE */ { CACA_KEY_CTRL_E, KEY_MODIFIER_CTRL | 'e' },
#else { CACA_KEY_CTRL_F, KEY_MODIFIER_CTRL | 'f' },
switch( ev ) { CACA_KEY_CTRL_G, KEY_MODIFIER_CTRL | 'g' },
#endif { CACA_KEY_BACKSPACE, KEY_BACKSPACE },
{ { CACA_KEY_TAB, KEY_TAB },
case CACA_EVENT_KEY_RELEASE: { CACA_KEY_CTRL_J, KEY_MODIFIER_CTRL | 'j' },
#ifdef CACA_API_VERSION_1 { CACA_KEY_CTRL_K, KEY_MODIFIER_CTRL | 'k' },
#ifdef CACA_EVENT_OPAQUE { CACA_KEY_CTRL_L, KEY_MODIFIER_CTRL | 'l' },
switch( caca_get_event_key_ch( &ev ) ) { CACA_KEY_RETURN, KEY_ENTER },
#else
switch( ev.data.key.ch ) { CACA_KEY_CTRL_N, KEY_MODIFIER_CTRL | 'n' },
#endif /* CACA_EVENT_OPAQUE */ { CACA_KEY_CTRL_O, KEY_MODIFIER_CTRL | 'o' },
#else { CACA_KEY_CTRL_P, KEY_MODIFIER_CTRL | 'p' },
switch( ev & 0x00ffffff ) { CACA_KEY_CTRL_Q, KEY_MODIFIER_CTRL | 'q' },
#endif { CACA_KEY_CTRL_R, KEY_MODIFIER_CTRL | 'r' },
{
case 'q': { CACA_KEY_PAUSE, -1 },
val.i_int = KEY_MODIFIER_CTRL | 'q'; { CACA_KEY_CTRL_T, KEY_MODIFIER_CTRL | 't' },
break; { CACA_KEY_CTRL_U, KEY_MODIFIER_CTRL | 'u' },
case ' ': { CACA_KEY_CTRL_V, KEY_MODIFIER_CTRL | 'v' },
val.i_int = KEY_SPACE; { CACA_KEY_CTRL_W, KEY_MODIFIER_CTRL | 'w' },
break; { CACA_KEY_CTRL_X, KEY_MODIFIER_CTRL | 'x' },
default: { CACA_KEY_CTRL_Y, KEY_MODIFIER_CTRL | 'y' },
continue; { CACA_KEY_CTRL_Z, KEY_MODIFIER_CTRL | 'z' },
}
{ CACA_KEY_ESCAPE, KEY_ESC },
{ CACA_KEY_DELETE, KEY_DELETE },
{ CACA_KEY_F1, KEY_F1 },
{ CACA_KEY_F2, KEY_F2 },
{ CACA_KEY_F3, KEY_F3 },
{ CACA_KEY_F4, KEY_F4 },
{ CACA_KEY_F5, KEY_F5 },
{ CACA_KEY_F6, KEY_F6 },
{ CACA_KEY_F7, KEY_F7 },
{ CACA_KEY_F8, KEY_F8 },
{ CACA_KEY_F9, KEY_F9 },
{ CACA_KEY_F10, KEY_F10 },
{ CACA_KEY_F11, KEY_F11 },
{ CACA_KEY_F12, KEY_F12 },
{ CACA_KEY_F13, -1 },
{ CACA_KEY_F14, -1 },
{ CACA_KEY_F15, -1 },
{ CACA_KEY_UP, KEY_UP },
{ CACA_KEY_DOWN, KEY_DOWN },
{ CACA_KEY_LEFT, KEY_LEFT },
{ CACA_KEY_RIGHT, KEY_RIGHT },
{ CACA_KEY_INSERT, KEY_INSERT },
{ CACA_KEY_HOME, KEY_HOME },
{ CACA_KEY_END, KEY_END },
{ CACA_KEY_PAGEUP, KEY_PAGEUP },
{ CACA_KEY_PAGEDOWN,KEY_PAGEDOWN },
{ ' ', KEY_SPACE },
/* */
{ -1, -1 }
};
static const struct {
int caca;
int vlc;
} mouses[] = {
{ 1, MOUSE_BUTTON_LEFT },
{ 2, MOUSE_BUTTON_CENTER },
{ 3, MOUSE_BUTTON_RIGHT },
{ 4, MOUSE_BUTTON_WHEEL_UP },
{ 5, MOUSE_BUTTON_WHEEL_DOWN },
/* */
{ -1, -1 }
};
/**
* Proccess pending event
*/
static void Manage(vout_display_t *vd)
{
vout_display_sys_t *sys = vd->sys;
var_Set( p_vout->p_libvlc, "key-pressed", val ); struct caca_event ev;
while (caca_get_event(sys->dp, CACA_EVENT_ANY, &ev, 0) > 0) {
switch (caca_get_event_type(&ev)) {
case CACA_EVENT_KEY_PRESS: {
const int caca = caca_get_event_key_ch(&ev);
for (int i = 0; keys[i].caca != -1; i++) {
if (keys[i].caca == caca) {
const int vlc = keys[i].vlc;
if (vlc >= 0)
vout_display_SendEventKey(vd, vlc);
return;
}
}
if (caca >= 0x20 && caca <= 0x7f) {
vout_display_SendEventKey(vd, caca);
return;
}
break; break;
}
case CACA_EVENT_RESIZE: case CACA_EVENT_RESIZE:
/* Acknowledge the resize */ vout_display_SendEventDisplaySize(vd, caca_get_event_resize_width(&ev),
caca_refresh_display( p_vout->p_sys->p_dp ); caca_get_event_resize_height(&ev));
break; break;
#ifdef CACA_API_VERSION_1 case CACA_EVENT_MOUSE_MOTION: {
case CACA_EVENT_MOUSE_MOTION: vout_display_place_t place;
val.i_int = Place(vd, &place);
#ifdef CACA_EVENT_OPAQUE
caca_get_event_mouse_x( &ev ) const unsigned x = vd->source.i_x_offset +
#else (int64_t)(caca_get_event_mouse_x(&ev) - place.x) *
ev.data.mouse.x vd->source.i_visible_width / place.width;
#endif /* CACA_EVENT_OPAQUE */ const unsigned y = vd->source.i_y_offset +
* p_vout->render.i_width (int64_t)(caca_get_event_mouse_y(&ev) - place.y) *
/ cucul_get_canvas_width( p_vout->p_sys->p_cv ); vd->source.i_visible_height / place.height;
var_Set( p_vout, "mouse-x", val );
val.i_int = caca_set_mouse(sys->dp, 1);
#ifdef CACA_EVENT_OPAQUE if (x >= vd->source.i_x_offset && x < vd->source.i_x_offset + vd->source.i_visible_width &&
caca_get_event_mouse_y( &ev ) y >= vd->source.i_y_offset && y < vd->source.i_y_offset + vd->source.i_visible_height) {
#else vout_display_SendEventMouseMoved(vd, x, y);
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 );
var_SetBool( p_vout, "mouse-moved", true );
break;
case CACA_EVENT_MOUSE_RELEASE:
var_SetBool( p_vout, "mouse-clicked", true );
break; break;
case CACA_EVENT_QUIT: }
{ case CACA_EVENT_MOUSE_PRESS:
p_playlist = pl_Hold( p_vout ); case CACA_EVENT_MOUSE_RELEASE: {
if( p_playlist ) caca_set_mouse(sys->dp, 1);
{ const int caca = caca_get_event_mouse_button(&ev);
playlist_Stop( p_playlist ); for (int i = 0; mouses[i].caca != -1; i++) {
pl_Release( p_vout ); if (mouses[i].caca == caca) {
if (caca_get_event_type(&ev) == CACA_EVENT_MOUSE_PRESS)
vout_display_SendEventMousePressed(vd, mouses[i].vlc);
else
vout_display_SendEventMouseReleased(vd, mouses[i].vlc);
return;
}
} }
libvlc_Quit( p_vout->p_libvlc );
break; break;
} }
#endif case CACA_EVENT_QUIT:
vout_display_SendEventClose(vd);
break;
default: default:
break; break;
} }
} }
return VLC_SUCCESS;
}
/*****************************************************************************
* Render: render previously calculated output
*****************************************************************************/
static void Render( vout_thread_t *p_vout, picture_t *p_pic )
{
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 );
}
/*****************************************************************************
* Display: displays previously rendered output
*****************************************************************************/
static void Display( vout_thread_t *p_vout, picture_t *p_pic )
{
VLC_UNUSED(p_pic);
caca_refresh_display( p_vout->p_sys->p_dp );
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment