X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fvideo_output%2Fcaca.c;h=6de1ca19a27898fd10f6947bd3a7eecb2d6bb392;hb=12ade3e3bc975d5426ba4af155b7372c31093b31;hp=c6588a3d6e4d279998ff58cd0bc03acb0155f05d;hpb=3d6ee48d4aacb1fbd5c2741b7b319a62a47009d9;p=vlc diff --git a/modules/video_output/caca.c b/modules/video_output/caca.c index c6588a3d6e..6de1ca19a2 100644 --- a/modules/video_output/caca.c +++ b/modules/video_output/caca.c @@ -1,10 +1,11 @@ /***************************************************************************** - * caca.c: Color ASCII Art video output plugin using libcaca + * caca.c: Color ASCII Art "vout display" module using libcaca ***************************************************************************** - * Copyright (C) 2003 VideoLAN - * $Id: caca.c,v 1.4 2003/12/04 16:49:43 sam Exp $ + * Copyright (C) 2003-2009 the VideoLAN team + * $Id$ * * Authors: Sam Hocevar + * Laurent Aimar * * 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 @@ -18,268 +19,514 @@ * * 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 - -#include -#include -#include -#include +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif -/***************************************************************************** - * Local prototypes - *****************************************************************************/ -static int Create ( vlc_object_t * ); -static void Destroy ( vlc_object_t * ); +#include +#include +#include +#include -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 /***************************************************************************** * Module descriptor *****************************************************************************/ -#define MODE_TEXT N_("dithering mode") -#define MODE_LONGTEXT N_("Choose the libcaca dithering mode") - -static char *mode_list[] = { "none", - "ordered2", - "ordered4", - "ordered8", - "random" }; -static char *mode_list_text[] = { N_("No dithering"), - N_("2x2 ordered dithering"), - N_("4x4 ordered dithering"), - N_("8x8 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_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 -{ - struct caca_bitmap *p_bitmap; +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; - enum caca_dithering dither = CACA_DITHERING_ORDERED4; - vlc_value_t val; + vout_display_t *vd = (vout_display_t *)object; + vout_display_sys_t *sys; - /* 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 defined(WIN32) && !defined(UNDER_CE) + CONSOLE_SCREEN_BUFFER_INFO csbiInfo; + SMALL_RECT rect; + COORD coord; + HANDLE hstdout; - if( caca_init() ) - { - msg_Err( p_vout, "cannot initialize libcaca" ); - free( p_vout->p_sys ); + if (!AllocConsole()) { + msg_Err(vd, "cannot create console"); 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 ) - { - if( !strcmp( val.psz_string, "none" ) ) - { - dither = CACA_DITHERING_NONE; - } - else if( !strcmp( val.psz_string, "ordered2" ) ) - { - dither = CACA_DITHERING_ORDERED2; - } - else if( !strcmp( val.psz_string, "ordered4" ) ) - { - dither = CACA_DITHERING_ORDERED4; - } - else if( !strcmp( val.psz_string, "random" ) ) - { - dither = CACA_DITHERING_RANDOM; - } - free( val.psz_string ); + 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(vd, "cannot create screen buffer"); + FreeConsole(); + return VLC_EGENERIC; } - caca_set_dithering( dither ); - - 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; - - return VLC_SUCCESS; -} -/***************************************************************************** - * Init: initialize libcaca video output thread - *****************************************************************************/ -static int Init( vout_thread_t *p_vout ) -{ - 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 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 ) - { - msg_Err( p_vout, "could not create libcaca bitmap" ); + if (!SetConsoleActiveScreenBuffer(hstdout)) { + msg_Err(vd, "cannot set active screen buffer"); + FreeConsole(); return VLC_EGENERIC; } - /* 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; - } + 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(vd, "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(vd, "SetConsoleWindowInfo failed: %ix%i", + rect.Right, rect.Bottom); } +#endif - if( p_pic == NULL ) - { - return VLC_EGENERIC; + /* Allocate structure */ + 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; } - /* Allocate the picture */ - p_pic->p->i_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 ); + const char *driver = NULL; +#ifdef __APPLE__ + // Make sure we don't try to open a window. + driver = "ncurses"; +#endif - p_pic->i_status = DESTROYED_PICTURE; - p_pic->i_type = DIRECT_PICTURE; + 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; + } + + /* TODO */ + vout_display_info_t info = vd->info; - PP_OUTPUTPICTURE[ I_OUTPUTPICTURES ] = p_pic; - I_OUTPUTPICTURES++; + /* Setup vout_display now that everything is fine */ + vd->fmt = fmt; + vd->info = info; + + 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; } -/***************************************************************************** - * End: terminate libcaca video output thread - *****************************************************************************/ -static void End( vout_thread_t *p_vout ) +/** + * Close a libcaca video output + */ +static void Close(vlc_object_t *object) { - caca_free_bitmap( p_vout->p_sys->p_bitmap ); + vout_display_t *vd = (vout_display_t *)object; + vout_display_sys_t *sys = vd->sys; + + 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 defined(WIN32) && !defined(UNDER_CE) + FreeConsole(); +#endif + + free(sys); } -/***************************************************************************** - * Destroy: destroy libcaca video output thread - ***************************************************************************** - * Terminate an output method created by AaCreateOutputMethod - *****************************************************************************/ -static void Destroy( vlc_object_t *p_this ) +/** + * Return a pool of direct buffers + */ +static picture_pool_t *Pool(vout_display_t *vd, unsigned count) { - vout_thread_t *p_vout = (vout_thread_t *)p_this; + vout_display_sys_t *sys = vd->sys; - caca_end(); - free( p_vout->p_sys ); + if (!sys->pool) + sys->pool = picture_pool_NewFromFormat(&vd->fmt, count); + return sys->pool; } -/***************************************************************************** - * 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 ) +/** + * Prepare a picture for display */ +static void Prepare(vout_display_t *vd, picture_t *picture) { - int event; - vlc_value_t val; - - while(( event = caca_get_event() )) - { - if( event & CACA_EVENT_KEY_PRESS ) - { - switch( event & 0xffff ) - { - case 'q': - val.i_int = KEY_MODIFIER_CTRL | 'q'; - break; - case ' ': - val.i_int = KEY_SPACE; - break; - default: - continue; - } + 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; } + } + + vout_display_place_t place; + Place(vd, &place); + + cucul_set_color_ansi(sys->cv, CUCUL_COLOR_DEFAULT, CUCUL_COLOR_BLACK); + cucul_clear_canvas(sys->cv); + + 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]); +} + +/** + * Display a picture + */ +static void Display(vout_display_t *vd, picture_t *picture) +{ + Refresh(vd); + picture_Release(picture); +} + +/** + * Control for vout display + */ +static int Control(vout_display_t *vd, int query, va_list args) +{ + vout_display_sys_t *sys = vd->sys; + + switch (query) { + case VOUT_DISPLAY_HIDE_MOUSE: + caca_set_mouse(sys->dp, 0); + return VLC_SUCCESS; - var_Set( p_vout->p_vlc, "key-pressed", val ); + 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; } - 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; + } } -/***************************************************************************** - * Render: render previously calculated output - *****************************************************************************/ -static void Render( vout_thread_t *p_vout, picture_t *p_pic ) +/** + * Refresh the display and send resize event + */ +static void Refresh(vout_display_t *vd) +{ + vout_display_sys_t *sys = vd->sys; + + /* */ + caca_refresh_display(sys->dp); + + /* */ + const unsigned width = caca_get_display_width(sys->dp); + const unsigned height = caca_get_display_height(sys->dp); + + if (width != vd->cfg->display.width || + height != vd->cfg->display.height) + vout_display_SendEventDisplaySize(vd, width, height, false); +} + +/** + * Compute the place in canvas unit. + */ +static void Place(vout_display_t *vd, vout_display_place_t *place) { - 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 ); + 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; + } } -/***************************************************************************** - * Display: displays previously rendered output - *****************************************************************************/ -static void Display( vout_thread_t *p_vout, picture_t *p_pic ) +/* */ +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 } +}; + +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) { - caca_refresh(); + 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: + vout_display_SendEventDisplaySize(vd, caca_get_event_resize_width(&ev), + caca_get_event_resize_height(&ev), false); + break; + 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_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; + } + } + break; + } + case CACA_EVENT_QUIT: + vout_display_SendEventClose(vd); + break; + default: + break; + } + } }