4 * Video driver for libcaca
6 * by Pigeon <pigeon@pigeond.net>
8 * Some functions/codes/ideas are from x11 and aalib vo
10 * TODO: support those draw_alpha stuff?
23 #include "video_out.h"
24 #include "video_out_internal.h"
27 #include "osdep/keycodes.h"
32 #ifdef CACA_API_VERSION_1
33 /* Include the pre-1.x compatibility header.
34 * Once libcaca 1.x is widespread, vo_caca should be fully
35 * converted to the new API. A patch exists:
36 * http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/2006-July/044674.html
41 static const vo_info_t info
= {
44 "Pigeon <pigeon@pigeond.net>",
48 const LIBVO_EXTERN (caca
)
51 static struct caca_bitmap
*cbitmap
= NULL
;
54 static int image_format
;
55 static int image_width
;
56 static int image_height
;
58 static int screen_w
, screen_h
;
60 /* We want 24bpp always for now */
61 static unsigned int bpp
= 24;
62 static unsigned int depth
= 3;
63 static unsigned int rmask
= 0xff0000;
64 static unsigned int gmask
= 0x00ff00;
65 static unsigned int bmask
= 0x0000ff;
66 static unsigned int amask
= 0;
68 #define MESSAGE_SIZE 512
69 #define MESSAGE_DURATION 5
71 static time_t stoposd
= 0;
72 static int showosdmessage
= 0;
73 static char osdmessagetext
[MESSAGE_SIZE
];
74 static char posbar
[MESSAGE_SIZE
];
76 static int osdx
= 0, osdy
= 0;
77 static int posbary
= 2;
79 static void osdmessage(int duration
, const char *fmt
, ...)
82 * for outputting a centered string at the bottom
83 * of our window for a while
91 strcpy(osdmessagetext
, m
);
94 stoposd
= time(NULL
) + duration
;
95 osdx
= (screen_w
- strlen (osdmessagetext
)) / 2;
99 static void osdpercent(int duration
, int min
, int max
, int val
, const char *desc
, const char *unit
)
102 * prints a bar for setting values
107 step
= (float)screen_w
/ (float)(max
- min
);
108 where
= (val
- min
) * step
;
109 osdmessage (duration
, "%s: %i%s", desc
, val
, unit
);
111 posbar
[screen_w
- 1] = '|';
113 for (i
= 0; i
< screen_w
; i
++)
124 if (where
!= (screen_w
- 1))
125 posbar
[screen_w
- 1] = '|';
127 posbar
[screen_w
] = '\0';
132 screen_w
= caca_get_width();
133 screen_h
= caca_get_height();
136 caca_free_bitmap(cbitmap
);
138 cbitmap
= caca_create_bitmap(bpp
, image_width
, image_height
,
139 depth
* image_width
, rmask
, gmask
, bmask
,
143 mp_msg(MSGT_VO
, MSGL_FATAL
, "vo_caca: caca_create_bitmap failed!\n");
148 static int config(uint32_t width
, uint32_t height
, uint32_t d_width
,
149 uint32_t d_height
, uint32_t flags
, char *title
, uint32_t format
)
151 image_height
= height
;
153 image_format
= format
;
161 static int draw_frame(uint8_t *src
[])
163 caca_draw_bitmap(0, 0, screen_w
, screen_h
, cbitmap
, src
[0]);
167 static int draw_slice(uint8_t *src
[], int stride
[], int w
, int h
, int x
, int y
)
172 static void flip_page(void)
177 if (time(NULL
) >= stoposd
)
183 caca_putstr(osdx
, osdy
, osdmessagetext
);
186 caca_putstr(0, posbary
, posbar
);
193 static void check_events (void)
197 if ((cev
= caca_get_event(CACA_EVENT_ANY
)))
199 if (cev
& CACA_EVENT_RESIZE
)
203 } else if (cev
& CACA_EVENT_KEY_RELEASE
)
205 int key
= (cev
& 0x00ffffff);
206 enum caca_feature cf
;
211 /* Toggle dithering method */
212 cf
= 1 + caca_get_feature(CACA_DITHERING
);
213 if (cf
> CACA_DITHERING_MAX
)
214 cf
= CACA_DITHERING_MIN
;
215 caca_set_feature(cf
);
216 osdmessage(MESSAGE_DURATION
, "Using %s", caca_get_feature_name(cf
));
221 /* Toggle antialiasing method */
222 cf
= 1 + caca_get_feature(CACA_ANTIALIASING
);
223 if (cf
> CACA_ANTIALIASING_MAX
)
224 cf
= CACA_ANTIALIASING_MIN
;
225 caca_set_feature(cf
);
226 osdmessage(MESSAGE_DURATION
, "Using %s", caca_get_feature_name(cf
));
231 /* Toggle background method */
232 cf
= 1 + caca_get_feature(CACA_BACKGROUND
);
233 if (cf
> CACA_BACKGROUND_MAX
)
234 cf
= CACA_BACKGROUND_MIN
;
235 caca_set_feature(cf
);
236 osdmessage(MESSAGE_DURATION
, "Using %s", caca_get_feature_name(cf
));
240 mplayer_put_key(KEY_UP
);
243 mplayer_put_key(KEY_DOWN
);
246 mplayer_put_key(KEY_LEFT
);
249 mplayer_put_key(KEY_RIGHT
);
251 case CACA_KEY_ESCAPE
:
252 mplayer_put_key(KEY_ESC
);
254 case CACA_KEY_PAGEUP
:
255 mplayer_put_key(KEY_PAGE_UP
);
257 case CACA_KEY_PAGEDOWN
:
258 mplayer_put_key(KEY_PAGE_DOWN
);
260 case CACA_KEY_RETURN
:
261 mplayer_put_key(KEY_ENTER
);
264 mplayer_put_key(KEY_HOME
);
267 mplayer_put_key(KEY_END
);
271 mplayer_put_key (key
);
278 static void uninit(void)
280 caca_free_bitmap(cbitmap
);
286 static void draw_osd(void)
288 if (vo_osd_progbar_type
!= -1)
289 osdpercent(MESSAGE_DURATION
, 0, 255,
290 vo_osd_progbar_value
, sub_osd_names
[vo_osd_progbar_type
],
294 static int preinit(const char *arg
)
298 mp_msg(MSGT_VO
, MSGL_ERR
, "vo_caca: Unknown subdevice: %s\n", arg
);
304 mp_msg(MSGT_VO
, MSGL_ERR
, "vo_caca: failed to initialize\n");
308 caca_set_window_title("MPlayer");
310 /* Default libcaca features */
311 caca_set_feature(CACA_ANTIALIASING_PREFILTER
);
312 caca_set_feature(CACA_DITHERING_RANDOM
);
317 static int query_format(uint32_t format
)
319 if (format
== IMGFMT_BGR24
)
320 return VFCAP_OSD
| VFCAP_CSP_SUPPORTED
;
325 static int control(uint32_t request
, void *data
, ...)
329 case VOCTRL_QUERY_FORMAT
:
330 return query_format(*((uint32_t *)data
));