Fix vf_tcdump's compilation
[mplayer/kovensky.git] / libvo / vo_caca.c
blob4494c5ec2229c58d49d3aa62f4e1fea37ff2867f
1 /*
2 * video output driver for libcaca
4 * by Pigeon <pigeon@pigeond.net>
6 * Some functions/codes/ideas are from x11 and aalib vo
8 * TODO: support draw_alpha?
10 * This file is part of MPlayer.
12 * MPlayer is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * MPlayer is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License along
23 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <sys/stat.h>
30 #include <unistd.h>
31 #include <string.h>
32 #include <time.h>
33 #include <errno.h>
35 #include "config.h"
36 #include "video_out.h"
37 #include "video_out_internal.h"
38 #include "sub.h"
40 #include "osdep/keycodes.h"
41 #include "mp_msg.h"
42 #include "mp_fifo.h"
44 #include <caca.h>
46 static const vo_info_t info = {
47 "libcaca",
48 "caca",
49 "Pigeon <pigeon@pigeond.net>",
53 const LIBVO_EXTERN (caca)
55 /* caca stuff */
56 static caca_canvas_t *canvas;
57 static caca_display_t *display;
58 static caca_dither_t *dither = NULL;
59 static const char *dither_antialias = "default";
60 static const char *dither_charset = "default";
61 static const char *dither_color = "default";
62 static const char *dither_algo = "none";
64 /* image infos */
65 static int image_format;
66 static int image_width;
67 static int image_height;
69 static int screen_w, screen_h;
71 /* We want 24bpp always for now */
72 static unsigned int bpp = 24;
73 static unsigned int depth = 3;
74 static unsigned int rmask = 0xff0000;
75 static unsigned int gmask = 0x00ff00;
76 static unsigned int bmask = 0x0000ff;
77 static unsigned int amask = 0;
79 #define MESSAGE_SIZE 512
80 #define MESSAGE_DURATION 5
82 static time_t stoposd = 0;
83 static int showosdmessage = 0;
84 static char osdmessagetext[MESSAGE_SIZE];
85 static char posbar[MESSAGE_SIZE];
87 static int osdx = 0, osdy = 0;
88 static int posbary = 2;
90 static void osdmessage(int duration, const char *fmt, ...)
93 * for outputting a centered string at the bottom
94 * of our window for a while
96 va_list ar;
97 char m[MESSAGE_SIZE];
99 va_start(ar, fmt);
100 vsprintf(m, fmt, ar);
101 va_end(ar);
102 strcpy(osdmessagetext, m);
104 showosdmessage = 1;
105 stoposd = time(NULL) + duration;
106 osdx = (screen_w - strlen (osdmessagetext)) / 2;
107 posbar[0] = '\0';
110 static void osdpercent(int duration, int min, int max, int val, const char *desc, const char *unit)
113 * prints a bar for setting values
115 float step;
116 int where, i;
118 step = (float)screen_w / (float)(max - min);
119 where = (val - min) * step;
120 osdmessage (duration, "%s: %i%s", desc, val, unit);
121 posbar[0] = '|';
122 posbar[screen_w - 1] = '|';
124 for (i = 0; i < screen_w; i++)
126 if (i == where)
127 posbar[i] = '#';
128 else
129 posbar[i] = '-';
132 if (where != 0)
133 posbar[0] = '|';
135 if (where != (screen_w - 1))
136 posbar[screen_w - 1] = '|';
138 posbar[screen_w] = '\0';
141 static int resize(void)
143 screen_w = caca_get_canvas_width(canvas);
144 screen_h = caca_get_canvas_height(canvas);
146 if (dither)
147 caca_free_dither(dither);
149 dither = caca_create_dither(bpp, image_width, image_height,
150 depth * image_width, rmask, gmask, bmask,
151 amask);
153 /* Default libcaca features */
154 caca_set_dither_antialias(dither, dither_antialias);
155 caca_set_dither_charset(dither, dither_charset);
156 caca_set_dither_color(dither, dither_color);
157 caca_set_dither_algorithm(dither, dither_algo);
159 if (!dither)
160 mp_msg(MSGT_VO, MSGL_FATAL, "vo_caca: caca_create_dither failed!\n");
161 return 0;
164 static int config(uint32_t width, uint32_t height, uint32_t d_width,
165 uint32_t d_height, uint32_t flags, char *title, uint32_t format)
167 image_height = height;
168 image_width = width;
169 image_format = format;
171 showosdmessage = 0;
172 posbar[0] = '\0';
174 return resize ();
177 static int draw_frame(uint8_t *src[])
179 caca_dither_bitmap(canvas, 0, 0, screen_w, screen_h, dither, src[0]);
180 return 0;
183 static int draw_slice(uint8_t *src[], int stride[], int w, int h, int x, int y)
185 return 0;
188 static void flip_page(void)
191 if (showosdmessage)
193 if (time(NULL) >= stoposd)
195 showosdmessage = 0;
196 if (*posbar)
197 posbar[0] = '\0';
198 } else {
199 caca_put_str(canvas, osdx, osdy, osdmessagetext);
200 if (*posbar)
201 caca_put_str(canvas, 0, posbary, posbar);
204 caca_refresh_display(display);
207 static void set_next_str(const char * const *list, const char ** str,
208 const char ** msg) {
209 int ind;
210 for(ind = 0; list[ind]; ind+=2) {
211 if(strcmp(list[ind], *str) == 0)
213 if(list[ind+2] == NULL)
214 ind = -2;
215 *str = list[ind+2];
216 *msg = list[ind+3];
217 return;
221 *str = list[0];
222 *msg = list[1];
225 static void check_events (void)
227 caca_event_t cev;
228 if (!caca_get_event(display, CACA_EVENT_ANY, &cev, 1))
229 return;
231 switch (cev.type)
233 case CACA_EVENT_RESIZE:
234 caca_refresh_display(display);
235 resize();
236 break;
238 case CACA_EVENT_KEY_RELEASE:
240 int key = cev.data.key.ch;
241 const char *msg_name;
243 switch (key)
245 case 'e':
246 case 'E':
247 /* Toggle dithering algorithm */
248 set_next_str(caca_get_dither_algorithm_list(dither), &dither_algo, &msg_name);
249 caca_set_dither_algorithm(dither, dither_algo);
250 osdmessage(MESSAGE_DURATION, "Using %s", msg_name);
251 break;
253 case 'a':
254 case 'A':
255 /* Toggle antialiasing method */
256 set_next_str(caca_get_dither_antialias_list(dither), &dither_antialias, &msg_name);
257 caca_set_dither_antialias(dither, dither_antialias);
258 osdmessage(MESSAGE_DURATION, "Using %s", msg_name);
259 break;
261 case 'h':
262 case 'H':
263 /* Toggle charset method */
264 set_next_str(caca_get_dither_charset_list(dither), &dither_charset, &msg_name);
265 caca_set_dither_charset(dither, dither_charset);
266 osdmessage(MESSAGE_DURATION, "Using %s", msg_name);
267 break;
269 case 'c':
270 case 'C':
271 /* Toggle color method */
272 set_next_str(caca_get_dither_color_list(dither), &dither_color, &msg_name);
273 caca_set_dither_color(dither, dither_color);
274 osdmessage(MESSAGE_DURATION, "Using %s", msg_name);
275 break;
277 case CACA_KEY_UP:
278 mplayer_put_key(KEY_UP);
279 break;
280 case CACA_KEY_DOWN:
281 mplayer_put_key(KEY_DOWN);
282 break;
283 case CACA_KEY_LEFT:
284 mplayer_put_key(KEY_LEFT);
285 break;
286 case CACA_KEY_RIGHT:
287 mplayer_put_key(KEY_RIGHT);
288 break;
289 case CACA_KEY_ESCAPE:
290 mplayer_put_key(KEY_ESC);
291 break;
292 case CACA_KEY_PAGEUP:
293 mplayer_put_key(KEY_PAGE_UP);
294 break;
295 case CACA_KEY_PAGEDOWN:
296 mplayer_put_key(KEY_PAGE_DOWN);
297 break;
298 case CACA_KEY_RETURN:
299 mplayer_put_key(KEY_ENTER);
300 break;
301 case CACA_KEY_HOME:
302 mplayer_put_key(KEY_HOME);
303 break;
304 case CACA_KEY_END:
305 mplayer_put_key(KEY_END);
306 break;
307 default:
308 if (key <= 255)
309 mplayer_put_key (key);
310 break;
316 static void uninit(void)
318 caca_free_dither(dither);
319 dither = NULL;
320 caca_free_display(display);
321 caca_free_canvas(canvas);
325 static void draw_osd(void)
327 if (vo_osd_progbar_type != -1)
328 osdpercent(MESSAGE_DURATION, 0, 255,
329 vo_osd_progbar_value, sub_osd_names[vo_osd_progbar_type],
330 "");
333 static int preinit(const char *arg)
335 const char *caca_driver = NULL;
336 if (arg)
338 char const * const *list = caca_get_display_driver_list();
339 int i;
340 for (i=0; list[i]; i+=2)
342 if (strcmp(arg, "list"))
344 if (strcmp(arg, list[i])) continue;
345 caca_driver = arg;
347 else
348 mp_msg(MSGT_VO, MSGL_INFO, "vo_caca: %s\t%s\n", list[i], list[i+1]);
350 if (!strcmp(arg, "list")) return ENOSYS;
351 if (!caca_driver)
353 mp_msg(MSGT_VO, MSGL_ERR, "vo_caca: invalid subdevice, use -vo caca:list to display available drivers\n");
354 return ENOSYS;
358 if ((canvas = caca_create_canvas(0, 0)) == NULL)
360 mp_msg(MSGT_VO, MSGL_ERR, "vo_caca: failed to create canvas\n");
361 return ENOSYS;
364 if (caca_driver)
366 if ((display = caca_create_display_with_driver(canvas, caca_driver)) == NULL)
368 mp_msg(MSGT_VO, MSGL_ERR, "vo_caca: failed to create display\n");
369 return ENOSYS;
372 else
373 if ((display = caca_create_display(canvas)) == NULL)
375 mp_msg(MSGT_VO, MSGL_ERR, "vo_caca: failed to create display\n");
376 return ENOSYS;
379 caca_set_display_title(display, "MPlayer");
381 return 0;
384 static int query_format(uint32_t format)
386 if (format == IMGFMT_BGR24)
387 return VFCAP_OSD | VFCAP_CSP_SUPPORTED;
389 return 0;
392 static int control(uint32_t request, void *data)
394 switch(request)
396 case VOCTRL_QUERY_FORMAT:
397 return query_format(*((uint32_t *)data));
398 default:
399 return VO_NOTIMPL;