/*****************************************************************************
- * caca.c: Color ASCII Art video output plugin using libcaca
+ * caca.c: Color ASCII Art "vout display" module using libcaca
*****************************************************************************
- * Copyright (C) 2003, 2004 the VideoLAN team
+ * Copyright (C) 2003-2009 the VideoLAN team
* $Id$
*
* 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
* it under the terms of the GNU General Public License as published by
/*****************************************************************************
* Preamble
*****************************************************************************/
-#include <errno.h> /* ENOMEM */
-#include <stdlib.h> /* free() */
-#include <string.h> /* strerror() */
-#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)
+#ifdef HAVE_CONFIG_H
+# include "config.h"
#endif
-#include <vlc/vlc.h>
-#include <vlc_vout.h>
-#include <vlc_interface.h>
-#include <vlc_keys.h>
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_vout_display.h>
+#include <vlc_picture_pool.h>
-/*****************************************************************************
- * 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 * );
+#include <caca.h>
/*****************************************************************************
* Module descriptor
*****************************************************************************/
-vlc_module_begin();
- set_shortname( "Caca" );
- set_category( CAT_VIDEO );
- set_subcategory( SUBCAT_VIDEO_VOUT );
- set_description( _("Color ASCII art video output") );
- set_capability( "video output", 12 );
- set_callbacks( Create, Destroy );
-vlc_module_end();
+static int Open (vlc_object_t *);
+static void Close(vlc_object_t *);
+
+vlc_module_begin()
+ set_shortname("Caca")
+ set_category(CAT_VIDEO)
+ set_subcategory(SUBCAT_VIDEO_VOUT)
+ 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
- *****************************************************************************
- * This structure is part of the video output thread descriptor.
- * It describes the libcaca specific properties of an output thread.
+ * Local prototypes
*****************************************************************************/
-struct vout_sys_t
-{
- cucul_canvas_t *p_cv;
- caca_display_t *p_dp;
- cucul_dither_t *p_dither;
+static picture_pool_t *Pool (vout_display_t *, unsigned);
+static void Prepare(vout_display_t *, picture_t *);
+static void Display(vout_display_t *, picture_t *);
+static int Control(vout_display_t *, int, va_list);
+
+/* */
+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.
- *****************************************************************************/
-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;
SMALL_RECT rect;
COORD coord;
HANDLE hstdout;
- if( !AllocConsole() )
- {
- msg_Err( p_vout, "cannot create console" );
+ if (!AllocConsole()) {
+ msg_Err(vd, "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" );
+ CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
+ if (!hstdout || hstdout == INVALID_HANDLE_VALUE) {
+ msg_Err(vd, "cannot create screen buffer");
FreeConsole();
return VLC_EGENERIC;
}
- if( !SetConsoleActiveScreenBuffer( hstdout) )
- {
- msg_Err( p_vout, "cannot set active screen buffer" );
+ if (!SetConsoleActiveScreenBuffer(hstdout)) {
+ msg_Err(vd, "cannot set active screen buffer");
FreeConsole();
return VLC_EGENERIC;
}
- coord = GetLargestConsoleWindowSize( hstdout );
- msg_Dbg( p_vout, "SetConsoleWindowInfo: %ix%i", coord.X, coord.Y );
+ coord = GetLargestConsoleWindowSize(hstdout);
+ msg_Dbg(vd, "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 );
+ if (!SetConsoleScreenBufferSize(hstdout, coord))
+ msg_Warn(vd, "SetConsoleScreenBufferSize %i %i",
+ coord.X, coord.Y);
/* Get the current screen buffer size and window position. */
- if( GetConsoleScreenBufferInfo( hstdout, &csbiInfo ) )
- {
+ 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 );
+ if (!SetConsoleWindowInfo(hstdout, TRUE, &rect))
+ msg_Dbg(vd, "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;
+ vd->sys = sys = calloc(1, sizeof(*sys));
+ if (!sys)
+ goto error;
+
+ sys->cv = cucul_create_canvas(0, 0);
+ if (!sys->cv) {
+ msg_Err(vd, "cannot initialize libcucul");
+ goto error;
}
- p_vout->p_sys->p_cv = cucul_create_canvas(0, 0);
- if( !p_vout->p_sys->p_cv )
- {
- msg_Err( p_vout, "cannot initialize libcucul" );
- free( p_vout->p_sys );
- return VLC_EGENERIC;
- }
+ const char *driver = NULL;
+#ifdef __APPLE__
+ // Make sure we don't try to open a window.
+ driver = "ncurses";
+#endif
- p_vout->p_sys->p_dp = caca_create_display( p_vout->p_sys->p_cv );
- if( !p_vout->p_sys->p_dp )
- {
- msg_Err( p_vout, "cannot initialize libcaca" );
- cucul_free_canvas( p_vout->p_sys->p_cv );
- free( p_vout->p_sys );
- return VLC_EGENERIC;
+ sys->dp = caca_create_display_with_driver(sys->cv, driver);
+ if (!sys->dp) {
+ msg_Err(vd, "cannot initialize libcaca");
+ goto error;
+ }
+ vout_display_DeleteWindow(vd, NULL);
+
+ if (vd->cfg->display.title)
+ caca_set_display_title(sys->dp,
+ vd->cfg->display.title);
+ else
+ caca_set_display_title(sys->dp,
+ VOUT_TITLE "(Colour AsCii Art)");
+
+ /* Fix format */
+ video_format_t fmt = vd->fmt;
+ 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)" );
+ /* TODO */
+ vout_display_info_t info = vd->info;
+
+ /* Setup vout_display now that everything is fine */
+ vd->fmt = fmt;
+ vd->info = info;
- p_vout->pf_init = Init;
- p_vout->pf_end = End;
- p_vout->pf_manage = Manage;
- p_vout->pf_render = Render;
- p_vout->pf_display = Display;
+ vd->pool = Pool;
+ 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;
+
+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
- *****************************************************************************/
-static int Init( vout_thread_t *p_vout )
+/**
+ * Close a libcaca video output
+ */
+static void Close(vlc_object_t *object)
{
- int i_index;
- picture_t *p_pic = NULL;
-
- I_OUTPUTPICTURES = 0;
-
- p_vout->output.i_chroma = VLC_FOURCC('R','V','3','2');
- 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;
- }
+ vout_display_t *vd = (vout_display_t *)object;
+ vout_display_sys_t *sys = vd->sys;
- /* Find an empty picture slot */
- for( i_index = 0 ; i_index < VOUT_MAX_PICTURES ; i_index++ )
- {
- if( p_vout->p_picture[ i_index ].i_status == FREE_PICTURE )
- {
- p_pic = p_vout->p_picture + i_index;
- break;
- }
- }
+ if (sys->pool)
+ picture_pool_Delete(sys->pool);
+ if (sys->dither)
+ cucul_free_dither(sys->dither);
+ caca_free_display(sys->dp);
+ cucul_free_canvas(sys->cv);
- if( p_pic == NULL )
- {
- return VLC_EGENERIC;
+#if defined(WIN32) && !defined(UNDER_CE)
+ FreeConsole();
+#endif
+
+ free(sys);
+}
+
+/**
+ * Return a pool of direct buffers
+ */
+static picture_pool_t *Pool(vout_display_t *vd, unsigned count)
+{
+ vout_display_sys_t *sys = vd->sys;
+
+ if (!sys->pool)
+ sys->pool = picture_pool_NewFromFormat(&vd->fmt, count);
+ return 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 */
- 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;
- p_pic->i_planes = 1;
- p_pic->p->p_pixels = malloc( p_pic->p->i_pitch * p_pic->p->i_lines );
+ vout_display_place_t place;
+ Place(vd, &place);
- p_pic->i_status = DESTROYED_PICTURE;
- p_pic->i_type = DIRECT_PICTURE;
+ cucul_set_color_ansi(sys->cv, CUCUL_COLOR_DEFAULT, CUCUL_COLOR_BLACK);
+ cucul_clear_canvas(sys->cv);
- PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic;
- I_OUTPUTPICTURES++;
+ const int crop_offset = vd->source.i_y_offset * picture->p->i_pitch +
+ 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
- *****************************************************************************/
-static void End( vout_thread_t *p_vout )
+/**
+ * Control for vout display
+ */
+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
- *****************************************************************************
- * Terminate an output method created by AaCreateOutputMethod
- *****************************************************************************/
-static void Destroy( vlc_object_t *p_this )
+/**
+ * Refresh the display and send resize event
+ */
+static void Refresh(vout_display_t *vd)
{
- 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();
-#endif
+ /* */
+ const unsigned width = caca_get_display_width(sys->dp);
+ const unsigned 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, false);
}
-/*****************************************************************************
- * Manage: handle libcaca events
- *****************************************************************************
- * This function should be called regularly by video output thread. It manages
- * console events. It returns a non null value on error.
- *****************************************************************************/
-static int Manage( vout_thread_t *p_vout )
+/**
+ * Compute the place in canvas unit.
+ */
+static void Place(vout_display_t *vd, vout_display_place_t *place)
{
-#ifdef CACA_API_VERSION_1
- struct caca_event ev;
-#else
- int ev;
-#endif
+ vout_display_sys_t *sys = vd->sys;
+
+ vout_display_PlacePicture(place, &vd->source, vd->cfg, false);
+
+ 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) )
- {
- playlist_t *p_playlist;
- vlc_value_t val;
+/* */
+static const struct {
+ int caca;
+ int vlc;
+} keys[] = {
+
+ { CACA_KEY_CTRL_A, KEY_MODIFIER_CTRL | 'a' },
+ { CACA_KEY_CTRL_B, KEY_MODIFIER_CTRL | 'b' },
+ { CACA_KEY_CTRL_C, KEY_MODIFIER_CTRL | 'c' },
+ { CACA_KEY_CTRL_D, KEY_MODIFIER_CTRL | 'd' },
+ { CACA_KEY_CTRL_E, KEY_MODIFIER_CTRL | 'e' },
+ { CACA_KEY_CTRL_F, KEY_MODIFIER_CTRL | 'f' },
+ { CACA_KEY_CTRL_G, KEY_MODIFIER_CTRL | 'g' },
+ { CACA_KEY_BACKSPACE, KEY_BACKSPACE },
+ { CACA_KEY_TAB, KEY_TAB },
+ { CACA_KEY_CTRL_J, KEY_MODIFIER_CTRL | 'j' },
+ { CACA_KEY_CTRL_K, KEY_MODIFIER_CTRL | 'k' },
+ { CACA_KEY_CTRL_L, KEY_MODIFIER_CTRL | 'l' },
+ { CACA_KEY_RETURN, KEY_ENTER },
+
+ { CACA_KEY_CTRL_N, KEY_MODIFIER_CTRL | 'n' },
+ { CACA_KEY_CTRL_O, KEY_MODIFIER_CTRL | 'o' },
+ { CACA_KEY_CTRL_P, KEY_MODIFIER_CTRL | 'p' },
+ { CACA_KEY_CTRL_Q, KEY_MODIFIER_CTRL | 'q' },
+ { CACA_KEY_CTRL_R, KEY_MODIFIER_CTRL | 'r' },
+
+ { CACA_KEY_PAUSE, -1 },
+ { CACA_KEY_CTRL_T, KEY_MODIFIER_CTRL | 't' },
+ { CACA_KEY_CTRL_U, KEY_MODIFIER_CTRL | 'u' },
+ { CACA_KEY_CTRL_V, KEY_MODIFIER_CTRL | 'v' },
+ { CACA_KEY_CTRL_W, KEY_MODIFIER_CTRL | 'w' },
+ { CACA_KEY_CTRL_X, KEY_MODIFIER_CTRL | 'x' },
+ { CACA_KEY_CTRL_Y, KEY_MODIFIER_CTRL | 'y' },
+ { 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 },
+
+ /* */
+ { -1, -1 }
+};
-#ifdef CACA_API_VERSION_1
- switch( ev.type )
-#else
- switch( ev )
-#endif
- {
- case CACA_EVENT_KEY_RELEASE:
-#ifdef CACA_API_VERSION_1
- switch( ev.data.key.ch )
-#else
- switch( ev & 0x00ffffff )
-#endif
- {
- case 'q':
- val.i_int = KEY_MODIFIER_CTRL | 'q';
- break;
- case ' ':
- val.i_int = KEY_SPACE;
- break;
- default:
- continue;
- }
+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 }
+};
- var_Set( p_vout->p_libvlc, "key-pressed", val );
+/**
+ * Proccess pending event
+ */
+static void Manage(vout_display_t *vd)
+{
+ vout_display_sys_t *sys = vd->sys;
+
+ 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;
+ }
case CACA_EVENT_RESIZE:
- /* Acknowledge the resize */
- caca_refresh_display( p_vout->p_sys->p_dp );
+ vout_display_SendEventDisplaySize(vd, caca_get_event_resize_width(&ev),
+ caca_get_event_resize_height(&ev), false);
break;
-#ifdef CACA_API_VERSION_1
- case CACA_EVENT_MOUSE_MOTION:
- val.i_int = ev.data.mouse.x * 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 = ev.data.mouse.y * 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 = VLC_TRUE;
- var_Set( p_vout, "mouse-moved", val );
+ case CACA_EVENT_MOUSE_MOTION: {
+ vout_display_place_t place;
+ Place(vd, &place);
+
+ const unsigned x = vd->source.i_x_offset +
+ (int64_t)(caca_get_event_mouse_x(&ev) - place.x) *
+ vd->source.i_visible_width / place.width;
+ const unsigned y = vd->source.i_y_offset +
+ (int64_t)(caca_get_event_mouse_y(&ev) - place.y) *
+ vd->source.i_visible_height / place.height;
+
+ caca_set_mouse(sys->dp, 1);
+ vout_display_SendEventMouseMoved(vd, x, y);
break;
- case CACA_EVENT_MOUSE_RELEASE:
- val.b_bool = VLC_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 );
+ }
+ case CACA_EVENT_MOUSE_PRESS:
+ case CACA_EVENT_MOUSE_RELEASE: {
+ caca_set_mouse(sys->dp, 1);
+ const int caca = caca_get_event_mouse_button(&ev);
+ for (int i = 0; mouses[i].caca != -1; i++) {
+ 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;
+ }
}
- p_vout->p_libvlc->b_die = VLC_TRUE;
break;
}
-#endif
+ case CACA_EVENT_QUIT:
+ vout_display_SendEventClose(vd);
+ break;
default:
break;
}
}
-
- return VLC_SUCCESS;
-}
-
-/*****************************************************************************
- * Render: render previously calculated output
- *****************************************************************************/
-static void Render( vout_thread_t *p_vout, picture_t *p_pic )
-{
- cucul_set_color( 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 )
-{
- caca_refresh_display( p_vout->p_sys->p_dp );
}