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"
31 #ifdef CACA_API_VERSION_1
32 /* Include the pre-1.x compatibility header.
33 * Once libcaca 1.x is widespread, vo_caca should be fully
34 * converted to the new API. A patch exists:
35 * http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/2006-July/044674.html
40 static vo_info_t info
= {
43 "Pigeon <pigeon@pigeond.net>",
50 static struct caca_bitmap
*cbitmap
= NULL
;
53 static int image_format
;
54 static int image_width
;
55 static int image_height
;
57 static int screen_w
, screen_h
;
59 /* We want 24bpp always for now */
60 static unsigned int bpp
= 24;
61 static unsigned int depth
= 3;
62 static unsigned int rmask
= 0xff0000;
63 static unsigned int gmask
= 0x00ff00;
64 static unsigned int bmask
= 0x0000ff;
65 static unsigned int amask
= 0;
67 #define MESSAGE_SIZE 512
68 #define MESSAGE_DURATION 5
70 static time_t stoposd
= 0;
71 static int showosdmessage
= 0;
72 static char osdmessagetext
[MESSAGE_SIZE
];
73 static char posbar
[MESSAGE_SIZE
];
75 static int osdx
= 0, osdy
= 0;
76 static int posbary
= 2;
78 static void osdmessage(int duration
, const char *fmt
, ...)
81 * for outputting a centered string at the bottom
82 * of our window for a while
90 strcpy(osdmessagetext
, m
);
93 stoposd
= time(NULL
) + duration
;
94 osdx
= (screen_w
- strlen (osdmessagetext
)) / 2;
98 static void osdpercent(int duration
, int min
, int max
, int val
, const char *desc
, const char *unit
)
101 * prints a bar for setting values
106 step
= (float)screen_w
/ (float)(max
- min
);
107 where
= (val
- min
) * step
;
108 osdmessage (duration
, "%s: %i%s", desc
, val
, unit
);
110 posbar
[screen_w
- 1] = '|';
112 for (i
= 0; i
< screen_w
; i
++)
123 if (where
!= (screen_w
- 1))
124 posbar
[screen_w
- 1] = '|';
126 posbar
[screen_w
] = '\0';
131 screen_w
= caca_get_width();
132 screen_h
= caca_get_height();
135 caca_free_bitmap(cbitmap
);
137 cbitmap
= caca_create_bitmap(bpp
, image_width
, image_height
,
138 depth
* image_width
, rmask
, gmask
, bmask
,
142 mp_msg(MSGT_VO
, MSGL_FATAL
, "vo_caca: caca_create_bitmap failed!\n");
147 static int config(uint32_t width
, uint32_t height
, uint32_t d_width
,
148 uint32_t d_height
, uint32_t flags
, char *title
, uint32_t format
)
150 image_height
= height
;
152 image_format
= format
;
160 static int draw_frame(uint8_t *src
[])
162 caca_draw_bitmap(0, 0, screen_w
, screen_h
, cbitmap
, src
[0]);
166 static int draw_slice(uint8_t *src
[], int stride
[], int w
, int h
, int x
, int y
)
171 static void flip_page(void)
176 if (time(NULL
) >= stoposd
)
182 caca_putstr(osdx
, osdy
, osdmessagetext
);
185 caca_putstr(0, posbary
, posbar
);
192 static void check_events (void)
196 if ((cev
= caca_get_event(CACA_EVENT_ANY
)))
198 if (cev
& CACA_EVENT_RESIZE
)
202 } else if (cev
& CACA_EVENT_KEY_RELEASE
)
204 int key
= (cev
& 0x00ffffff);
205 enum caca_feature cf
;
210 /* Toggle dithering method */
211 cf
= 1 + caca_get_feature(CACA_DITHERING
);
212 if (cf
> CACA_DITHERING_MAX
)
213 cf
= CACA_DITHERING_MIN
;
214 caca_set_feature(cf
);
215 osdmessage(MESSAGE_DURATION
, "Using %s", caca_get_feature_name(cf
));
220 /* Toggle antialiasing method */
221 cf
= 1 + caca_get_feature(CACA_ANTIALIASING
);
222 if (cf
> CACA_ANTIALIASING_MAX
)
223 cf
= CACA_ANTIALIASING_MIN
;
224 caca_set_feature(cf
);
225 osdmessage(MESSAGE_DURATION
, "Using %s", caca_get_feature_name(cf
));
230 /* Toggle background method */
231 cf
= 1 + caca_get_feature(CACA_BACKGROUND
);
232 if (cf
> CACA_BACKGROUND_MAX
)
233 cf
= CACA_BACKGROUND_MIN
;
234 caca_set_feature(cf
);
235 osdmessage(MESSAGE_DURATION
, "Using %s", caca_get_feature_name(cf
));
239 mplayer_put_key(KEY_UP
);
242 mplayer_put_key(KEY_DOWN
);
245 mplayer_put_key(KEY_LEFT
);
248 mplayer_put_key(KEY_RIGHT
);
250 case CACA_KEY_ESCAPE
:
251 mplayer_put_key(KEY_ESC
);
253 case CACA_KEY_PAGEUP
:
254 mplayer_put_key(KEY_PAGE_UP
);
256 case CACA_KEY_PAGEDOWN
:
257 mplayer_put_key(KEY_PAGE_DOWN
);
259 case CACA_KEY_RETURN
:
260 mplayer_put_key(KEY_ENTER
);
263 mplayer_put_key(KEY_HOME
);
266 mplayer_put_key(KEY_END
);
270 mplayer_put_key (key
);
277 static void uninit(void)
279 caca_free_bitmap(cbitmap
);
285 static void draw_osd(void)
287 if (vo_osd_progbar_type
!= -1)
288 osdpercent(MESSAGE_DURATION
, 0, 255,
289 vo_osd_progbar_value
, __sub_osd_names
[vo_osd_progbar_type
],
293 static int preinit(const char *arg
)
297 mp_msg(MSGT_VO
, MSGL_ERR
, "vo_caca: Unknown subdevice: %s\n", arg
);
303 mp_msg(MSGT_VO
, MSGL_ERR
, "vo_caca: failed to initialize\n");
307 caca_set_window_title("MPlayer");
309 /* Default libcaca features */
310 caca_set_feature(CACA_ANTIALIASING_PREFILTER
);
311 caca_set_feature(CACA_DITHERING_RANDOM
);
316 static int query_format(uint32_t format
)
318 if (format
== IMGFMT_BGR24
)
319 return VFCAP_OSD
| VFCAP_CSP_SUPPORTED
;
324 static int control(uint32_t request
, void *data
, ...)
328 case VOCTRL_QUERY_FORMAT
:
329 return query_format(*((uint32_t *)data
));