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.
36 #include "video_out.h"
37 #include "video_out_internal.h"
40 #include "osdep/keycodes.h"
45 #ifdef CACA_API_VERSION_1
46 /* Include the pre-1.x compatibility header.
47 * Once libcaca 1.x is widespread, vo_caca should be fully
48 * converted to the new API. A patch exists:
49 * http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/2006-July/044674.html
54 static const vo_info_t info
= {
57 "Pigeon <pigeon@pigeond.net>",
61 const LIBVO_EXTERN (caca
)
64 static struct caca_bitmap
*cbitmap
= NULL
;
67 static int image_format
;
68 static int image_width
;
69 static int image_height
;
71 static int screen_w
, screen_h
;
73 /* We want 24bpp always for now */
74 static unsigned int bpp
= 24;
75 static unsigned int depth
= 3;
76 static unsigned int rmask
= 0xff0000;
77 static unsigned int gmask
= 0x00ff00;
78 static unsigned int bmask
= 0x0000ff;
79 static unsigned int amask
= 0;
81 #define MESSAGE_SIZE 512
82 #define MESSAGE_DURATION 5
84 static time_t stoposd
= 0;
85 static int showosdmessage
= 0;
86 static char osdmessagetext
[MESSAGE_SIZE
];
87 static char posbar
[MESSAGE_SIZE
];
89 static int osdx
= 0, osdy
= 0;
90 static int posbary
= 2;
92 static void osdmessage(int duration
, const char *fmt
, ...)
95 * for outputting a centered string at the bottom
96 * of our window for a while
102 vsprintf(m
, fmt
, ar
);
104 strcpy(osdmessagetext
, m
);
107 stoposd
= time(NULL
) + duration
;
108 osdx
= (screen_w
- strlen (osdmessagetext
)) / 2;
112 static void osdpercent(int duration
, int min
, int max
, int val
, const char *desc
, const char *unit
)
115 * prints a bar for setting values
120 step
= (float)screen_w
/ (float)(max
- min
);
121 where
= (val
- min
) * step
;
122 osdmessage (duration
, "%s: %i%s", desc
, val
, unit
);
124 posbar
[screen_w
- 1] = '|';
126 for (i
= 0; i
< screen_w
; i
++)
137 if (where
!= (screen_w
- 1))
138 posbar
[screen_w
- 1] = '|';
140 posbar
[screen_w
] = '\0';
143 static int resize(void)
145 screen_w
= caca_get_width();
146 screen_h
= caca_get_height();
149 caca_free_bitmap(cbitmap
);
151 cbitmap
= caca_create_bitmap(bpp
, image_width
, image_height
,
152 depth
* image_width
, rmask
, gmask
, bmask
,
156 mp_msg(MSGT_VO
, MSGL_FATAL
, "vo_caca: caca_create_bitmap failed!\n");
161 static int config(uint32_t width
, uint32_t height
, uint32_t d_width
,
162 uint32_t d_height
, uint32_t flags
, char *title
, uint32_t format
)
164 image_height
= height
;
166 image_format
= format
;
174 static int draw_frame(uint8_t *src
[])
176 caca_draw_bitmap(0, 0, screen_w
, screen_h
, cbitmap
, src
[0]);
180 static int draw_slice(uint8_t *src
[], int stride
[], int w
, int h
, int x
, int y
)
185 static void flip_page(void)
190 if (time(NULL
) >= stoposd
)
196 caca_putstr(osdx
, osdy
, osdmessagetext
);
199 caca_putstr(0, posbary
, posbar
);
206 static void check_events (void)
210 if ((cev
= caca_get_event(CACA_EVENT_ANY
)))
212 if (cev
& CACA_EVENT_RESIZE
)
216 } else if (cev
& CACA_EVENT_KEY_RELEASE
)
218 int key
= (cev
& 0x00ffffff);
219 enum caca_feature cf
;
224 /* Toggle dithering method */
225 cf
= 1 + caca_get_feature(CACA_DITHERING
);
226 if (cf
> CACA_DITHERING_MAX
)
227 cf
= CACA_DITHERING_MIN
;
228 caca_set_feature(cf
);
229 osdmessage(MESSAGE_DURATION
, "Using %s", caca_get_feature_name(cf
));
234 /* Toggle antialiasing method */
235 cf
= 1 + caca_get_feature(CACA_ANTIALIASING
);
236 if (cf
> CACA_ANTIALIASING_MAX
)
237 cf
= CACA_ANTIALIASING_MIN
;
238 caca_set_feature(cf
);
239 osdmessage(MESSAGE_DURATION
, "Using %s", caca_get_feature_name(cf
));
244 /* Toggle background method */
245 cf
= 1 + caca_get_feature(CACA_BACKGROUND
);
246 if (cf
> CACA_BACKGROUND_MAX
)
247 cf
= CACA_BACKGROUND_MIN
;
248 caca_set_feature(cf
);
249 osdmessage(MESSAGE_DURATION
, "Using %s", caca_get_feature_name(cf
));
253 mplayer_put_key(KEY_UP
);
256 mplayer_put_key(KEY_DOWN
);
259 mplayer_put_key(KEY_LEFT
);
262 mplayer_put_key(KEY_RIGHT
);
264 case CACA_KEY_ESCAPE
:
265 mplayer_put_key(KEY_ESC
);
267 case CACA_KEY_PAGEUP
:
268 mplayer_put_key(KEY_PAGE_UP
);
270 case CACA_KEY_PAGEDOWN
:
271 mplayer_put_key(KEY_PAGE_DOWN
);
273 case CACA_KEY_RETURN
:
274 mplayer_put_key(KEY_ENTER
);
277 mplayer_put_key(KEY_HOME
);
280 mplayer_put_key(KEY_END
);
284 mplayer_put_key (key
);
291 static void uninit(void)
293 caca_free_bitmap(cbitmap
);
299 static void draw_osd(void)
301 if (vo_osd_progbar_type
!= -1)
302 osdpercent(MESSAGE_DURATION
, 0, 255,
303 vo_osd_progbar_value
, sub_osd_names
[vo_osd_progbar_type
],
307 static int preinit(const char *arg
)
311 mp_msg(MSGT_VO
, MSGL_ERR
, "vo_caca: Unknown subdevice: %s\n", arg
);
317 mp_msg(MSGT_VO
, MSGL_ERR
, "vo_caca: failed to initialize\n");
321 caca_set_window_title("MPlayer");
323 /* Default libcaca features */
324 caca_set_feature(CACA_ANTIALIASING_PREFILTER
);
325 caca_set_feature(CACA_DITHERING_RANDOM
);
330 static int query_format(uint32_t format
)
332 if (format
== IMGFMT_BGR24
)
333 return VFCAP_OSD
| VFCAP_CSP_SUPPORTED
;
338 static int control(uint32_t request
, void *data
)
342 case VOCTRL_QUERY_FORMAT
:
343 return query_format(*((uint32_t *)data
));