source: libcaca/trunk/caca-php/php_caca.c @ 3149

Last change on this file since 3149 was 3149, checked in by nico, 12 years ago
  • Add new php specific function caca_load_builtin_font(string name)
  • Add php bindings for caca_get_dither_antialias_list, caca_render_canvas
  • Add a new sample program examples/render.php
File size: 57.7 KB
Line 
1/*
2 *  php-caca      Php binding for Libcaca
3 *  Copyright (c) 2008 Vion Nicolas <nico@picapo.net>
4 *
5 *
6 *  This library is free software. It comes without any warranty, to
7 *  the extent permitted by applicable law. You can redistribute it
8 *  and/or modify it under the terms of the Do What The Fuck You Want
9 *  To Public License, Version 2, as published by Sam Hocevar. See
10 *  http://sam.zoy.org/wtfpl/COPYING for more details.
11 */
12
13#ifdef HAVE_CONFIG_H
14#include "config.h"
15#endif
16
17#include "php.h"
18#include "php_caca.h"
19#include <gd.h>
20
21static function_entry caca_functions[] = {
22        PHP_FE(caca_create_canvas, NULL)
23        PHP_FE(caca_set_canvas_size, NULL)
24        PHP_FE(caca_get_canvas_width, NULL)
25        PHP_FE(caca_get_canvas_height, NULL)
26        PHP_FE(caca_get_canvas_chars, NULL)
27        PHP_FE(caca_get_canvas_attrs, NULL)
28        PHP_FE(caca_rand, NULL)
29        PHP_FE(caca_get_version, NULL)
30        PHP_FE(caca_gotoxy, NULL)
31        PHP_FE(caca_get_cursor_x, NULL)
32        PHP_FE(caca_get_cursor_y, NULL)
33        PHP_FE(caca_put_char, NULL)
34        PHP_FE(caca_get_char, NULL)
35        PHP_FE(caca_put_str, NULL)
36        PHP_FE(caca_clear_canvas, NULL)
37        PHP_FE(caca_set_canvas_handle, NULL)
38        PHP_FE(caca_get_canvas_handle_x, NULL)
39        PHP_FE(caca_get_canvas_handle_y, NULL)
40        PHP_FE(caca_blit, NULL)
41        PHP_FE(caca_set_canvas_boundaries, NULL)
42        PHP_FE(caca_invert, NULL)
43        PHP_FE(caca_flip, NULL)
44        PHP_FE(caca_flop, NULL)
45        PHP_FE(caca_rotate_180, NULL)
46        PHP_FE(caca_rotate_left, NULL)
47        PHP_FE(caca_rotate_right, NULL)
48        PHP_FE(caca_stretch_left, NULL)
49        PHP_FE(caca_stretch_right, NULL)
50        PHP_FE(caca_get_attr, NULL)
51        PHP_FE(caca_set_attr, NULL)
52        PHP_FE(caca_put_attr, NULL)
53        PHP_FE(caca_set_color_ansi, NULL)
54        PHP_FE(caca_set_color_argb, NULL)
55        PHP_FE(caca_attr_to_ansi, NULL)
56        PHP_FE(caca_attr_to_ansi_fg, NULL)
57        PHP_FE(caca_attr_to_ansi_bg, NULL)
58        PHP_FE(caca_attr_to_rgb12_fg, NULL)
59        PHP_FE(caca_attr_to_rgb12_bg, NULL)
60        PHP_FE(caca_attr_to_argb64, NULL)
61        PHP_FE(caca_utf8_to_utf32, NULL)
62        PHP_FE(caca_utf32_to_utf8, NULL)
63        PHP_FE(caca_utf32_to_cp437, NULL)
64        PHP_FE(caca_cp437_to_utf32, NULL)
65        PHP_FE(caca_utf32_to_ascii, NULL)
66        PHP_FE(caca_utf32_is_fullwidth, NULL)
67        PHP_FE(caca_draw_line, NULL)
68        PHP_FE(caca_draw_polyline, NULL)
69        PHP_FE(caca_draw_thin_line, NULL)
70        PHP_FE(caca_draw_thin_polyline, NULL)
71        PHP_FE(caca_draw_circle, NULL)
72        PHP_FE(caca_draw_ellipse, NULL)
73        PHP_FE(caca_draw_thin_ellipse, NULL)
74        PHP_FE(caca_fill_ellipse, NULL)
75        PHP_FE(caca_draw_box, NULL)
76        PHP_FE(caca_draw_thin_box, NULL)
77        PHP_FE(caca_draw_cp437_box, NULL)
78        PHP_FE(caca_fill_box, NULL)
79        PHP_FE(caca_draw_triangle, NULL)
80        PHP_FE(caca_draw_thin_triangle, NULL)
81        PHP_FE(caca_fill_triangle, NULL)
82        PHP_FE(caca_get_frame_count, NULL)
83        PHP_FE(caca_set_frame, NULL)
84        PHP_FE(caca_set_frame_name, NULL)
85        PHP_FE(caca_create_frame, NULL)
86        PHP_FE(caca_free_frame, NULL)
87        PHP_FE(caca_create_dither, NULL)
88        PHP_FE(caca_set_dither_palette, NULL)
89        PHP_FE(caca_set_dither_brightness, NULL)
90        PHP_FE(caca_get_dither_brightness, NULL)
91        PHP_FE(caca_set_dither_gamma, NULL)
92        PHP_FE(caca_get_dither_gamma, NULL)
93        PHP_FE(caca_set_dither_contrast, NULL)
94        PHP_FE(caca_get_dither_contrast, NULL)
95        PHP_FE(caca_set_dither_antialias, NULL)
96        PHP_FE(caca_get_dither_antialias_list, NULL)
97        PHP_FE(caca_get_dither_antialias, NULL)
98        PHP_FE(caca_set_dither_color, NULL)
99        PHP_FE(caca_get_dither_color_list, NULL)
100        PHP_FE(caca_get_dither_color, NULL)
101        PHP_FE(caca_set_dither_charset, NULL)
102        PHP_FE(caca_get_dither_charset_list, NULL)
103        PHP_FE(caca_get_dither_charset, NULL)
104        PHP_FE(caca_set_dither_algorithm, NULL)
105        PHP_FE(caca_get_dither_algorithm_list, NULL)
106        PHP_FE(caca_get_dither_algorithm, NULL)
107        PHP_FE(caca_dither_bitmap, NULL)
108        PHP_FE(caca_load_font, NULL)
109        PHP_FE(caca_load_builtin_font, NULL)
110        PHP_FE(caca_get_font_list, NULL)
111        PHP_FE(caca_get_font_width, NULL)
112        PHP_FE(caca_get_font_height, NULL)
113        PHP_FE(caca_get_font_blocks, NULL)
114        PHP_FE(caca_render_canvas, NULL)
115        PHP_FE(caca_canvas_set_figfont, NULL)
116        PHP_FE(caca_put_figchar, NULL)
117        PHP_FE(caca_flush_figlet, NULL)
118        PHP_FE(caca_file_open, NULL)
119        PHP_FE(caca_file_close, NULL)
120        PHP_FE(caca_file_tell, NULL)
121        PHP_FE(caca_file_read, NULL)
122        PHP_FE(caca_file_write, NULL)
123        PHP_FE(caca_file_gets, NULL)
124        PHP_FE(caca_file_eof, NULL)
125        PHP_FE(caca_import_string, NULL)
126        PHP_FE(caca_import_file, NULL)
127        PHP_FE(caca_get_import_list, NULL)
128        PHP_FE(caca_export_string, NULL)
129        PHP_FE(caca_get_export_list, NULL)
130        PHP_FE(caca_create_display, NULL)
131        PHP_FE(caca_create_display_with_driver, NULL)
132        PHP_FE(caca_get_display_driver_list, NULL)
133        PHP_FE(caca_get_display_driver, NULL)
134        PHP_FE(caca_set_display_driver, NULL)
135        PHP_FE(caca_get_canvas, NULL)
136        PHP_FE(caca_refresh_display, NULL)
137        PHP_FE(caca_set_display_time, NULL)
138        PHP_FE(caca_get_display_time, NULL)
139        PHP_FE(caca_get_display_width, NULL)
140        PHP_FE(caca_get_display_height, NULL)
141        PHP_FE(caca_set_display_title, NULL)
142        PHP_FE(caca_set_mouse, NULL)
143        PHP_FE(caca_set_cursor, NULL)
144        PHP_FE(caca_get_event, NULL)
145        PHP_FE(caca_get_mouse_x, NULL)
146        PHP_FE(caca_get_mouse_y, NULL)
147        PHP_FE(caca_get_event_type, NULL)
148        PHP_FE(caca_get_event_key_ch, NULL)
149        PHP_FE(caca_get_event_mouse_button, NULL)
150        PHP_FE(caca_get_event_mouse_x, NULL)
151        PHP_FE(caca_get_event_mouse_y, NULL)
152        PHP_FE(caca_get_event_resize_width, NULL)
153        PHP_FE(caca_get_event_resize_height, NULL)
154
155        {NULL, NULL, NULL}
156};
157
158zend_module_entry caca_module_entry = {
159#if ZEND_MODULE_API_NO >= 20010901
160        STANDARD_MODULE_HEADER,
161#endif
162        PHP_CACA_EXTNAME,
163        caca_functions,
164        PHP_MINIT(caca),
165        NULL,
166        NULL,
167        NULL,
168        PHP_MINFO(caca),
169#if ZEND_MODULE_API_NO >= 20010901
170        PHP_CACA_VERSION,
171#endif
172        STANDARD_MODULE_PROPERTIES
173};
174
175#ifdef COMPILE_DL_CACA
176ZEND_GET_MODULE(caca)
177#endif
178
179PHP_MINFO_FUNCTION(caca) {
180        php_info_print_table_start();
181        php_info_print_table_row(2, "Caca library version", caca_get_version());
182        php_info_print_table_end();
183}
184
185//-------- Caca's ressources destructors -----------//
186
187static void php_caca_canvas_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) {
188        caca_free_canvas(rsrc->ptr);
189}
190
191static void php_caca_dither_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) {
192        caca_free_dither(rsrc->ptr);
193}
194
195static void php_caca_font_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) {
196        caca_free_font(rsrc->ptr);
197}
198
199static void php_caca_file_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) {
200}
201
202static void php_caca_display_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) {
203        caca_free_display(rsrc->ptr);
204}
205
206static void php_caca_event_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) {
207        efree((caca_event_t *) rsrc->ptr);
208}
209
210//-------- Initialization ---------//
211
212PHP_MINIT_FUNCTION(caca) {
213
214        le_caca_canvas = zend_register_list_destructors_ex(php_caca_canvas_dtor, NULL, PHP_CACA_CANVAS_RES_NAME, module_number);
215        le_caca_dither = zend_register_list_destructors_ex(php_caca_dither_dtor, NULL, PHP_CACA_DITHER_RES_NAME, module_number);
216        le_caca_font = zend_register_list_destructors_ex(php_caca_font_dtor, NULL, PHP_CACA_FONT_RES_NAME, module_number);
217        le_caca_file = zend_register_list_destructors_ex(php_caca_file_dtor, NULL, PHP_CACA_FILE_RES_NAME, module_number);
218        le_caca_display = zend_register_list_destructors_ex(php_caca_display_dtor, NULL, PHP_CACA_DISPLAY_RES_NAME, module_number);
219        le_caca_event = zend_register_list_destructors_ex(php_caca_event_dtor, NULL, PHP_CACA_EVENT_RES_NAME, module_number);
220       
221        REGISTER_LONG_CONSTANT("CACA_BLACK", CACA_BLACK, CONST_CS | CONST_PERSISTENT);
222        REGISTER_LONG_CONSTANT("CACA_BLUE", CACA_BLUE, CONST_CS | CONST_PERSISTENT);
223        REGISTER_LONG_CONSTANT("CACA_GREEN", CACA_GREEN, CONST_CS | CONST_PERSISTENT);
224        REGISTER_LONG_CONSTANT("CACA_CYAN", CACA_CYAN, CONST_CS | CONST_PERSISTENT);
225        REGISTER_LONG_CONSTANT("CACA_RED", CACA_RED, CONST_CS | CONST_PERSISTENT);
226        REGISTER_LONG_CONSTANT("CACA_MAGENTA", CACA_MAGENTA, CONST_CS | CONST_PERSISTENT);
227        REGISTER_LONG_CONSTANT("CACA_BROWN", CACA_BROWN, CONST_CS | CONST_PERSISTENT);
228        REGISTER_LONG_CONSTANT("CACA_LIGHTGRAY", CACA_LIGHTGRAY, CONST_CS | CONST_PERSISTENT);
229        REGISTER_LONG_CONSTANT("CACA_DARKGRAY", CACA_DARKGRAY, CONST_CS | CONST_PERSISTENT);
230        REGISTER_LONG_CONSTANT("CACA_LIGHTBLUE", CACA_LIGHTBLUE, CONST_CS | CONST_PERSISTENT);
231        REGISTER_LONG_CONSTANT("CACA_LIGHTGREEN", CACA_LIGHTGREEN, CONST_CS | CONST_PERSISTENT);
232        REGISTER_LONG_CONSTANT("CACA_LIGHTCYAN", CACA_LIGHTCYAN, CONST_CS | CONST_PERSISTENT);
233        REGISTER_LONG_CONSTANT("CACA_LIGHTRED", CACA_LIGHTRED, CONST_CS | CONST_PERSISTENT);
234        REGISTER_LONG_CONSTANT("CACA_LIGHTMAGENTA", CACA_LIGHTMAGENTA, CONST_CS | CONST_PERSISTENT);
235        REGISTER_LONG_CONSTANT("CACA_YELLOW", CACA_YELLOW, CONST_CS | CONST_PERSISTENT);
236        REGISTER_LONG_CONSTANT("CACA_WHITE", CACA_WHITE, CONST_CS | CONST_PERSISTENT);
237        REGISTER_LONG_CONSTANT("CACA_DEFAULT", CACA_DEFAULT, CONST_CS | CONST_PERSISTENT);
238        REGISTER_LONG_CONSTANT("CACA_TRANSPARENT", CACA_TRANSPARENT, CONST_CS | CONST_PERSISTENT);
239        REGISTER_LONG_CONSTANT("CACA_BOLD", CACA_BOLD, CONST_CS | CONST_PERSISTENT);
240        REGISTER_LONG_CONSTANT("CACA_ITALICS", CACA_ITALICS, CONST_CS | CONST_PERSISTENT);
241        REGISTER_LONG_CONSTANT("CACA_UNDERLINE", CACA_UNDERLINE, CONST_CS | CONST_PERSISTENT);
242        REGISTER_LONG_CONSTANT("CACA_BLINK", CACA_BLINK, CONST_CS | CONST_PERSISTENT);
243
244        REGISTER_LONG_CONSTANT("CACA_EVENT_NONE", CACA_EVENT_NONE, CONST_CS | CONST_PERSISTENT);
245        REGISTER_LONG_CONSTANT("CACA_EVENT_KEY_PRESS", CACA_EVENT_KEY_PRESS, CONST_CS | CONST_PERSISTENT);
246        REGISTER_LONG_CONSTANT("CACA_EVENT_KEY_RELEASE", CACA_EVENT_KEY_RELEASE, CONST_CS | CONST_PERSISTENT);
247        REGISTER_LONG_CONSTANT("CACA_EVENT_MOUSE_PRESS", CACA_EVENT_MOUSE_PRESS, CONST_CS | CONST_PERSISTENT);
248        REGISTER_LONG_CONSTANT("CACA_EVENT_MOUSE_RELEASE", CACA_EVENT_MOUSE_RELEASE, CONST_CS | CONST_PERSISTENT);
249        REGISTER_LONG_CONSTANT("CACA_EVENT_MOUSE_MOTION", CACA_EVENT_MOUSE_MOTION, CONST_CS | CONST_PERSISTENT);
250        REGISTER_LONG_CONSTANT("CACA_EVENT_RESIZE", CACA_EVENT_RESIZE, CONST_CS | CONST_PERSISTENT);
251        REGISTER_LONG_CONSTANT("CACA_EVENT_QUIT", CACA_EVENT_QUIT, CONST_CS | CONST_PERSISTENT);
252        REGISTER_LONG_CONSTANT("CACA_EVENT_ANY", CACA_EVENT_ANY, CONST_CS | CONST_PERSISTENT);
253
254        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_A", CACA_KEY_CTRL_A, CONST_CS | CONST_PERSISTENT);
255        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_B", CACA_KEY_CTRL_B, CONST_CS | CONST_PERSISTENT);
256        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_C", CACA_KEY_CTRL_C, CONST_CS | CONST_PERSISTENT);
257        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_D", CACA_KEY_CTRL_D, CONST_CS | CONST_PERSISTENT);
258        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_E", CACA_KEY_CTRL_E, CONST_CS | CONST_PERSISTENT);
259        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_F", CACA_KEY_CTRL_F, CONST_CS | CONST_PERSISTENT);
260        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_G", CACA_KEY_CTRL_G, CONST_CS | CONST_PERSISTENT);
261        REGISTER_LONG_CONSTANT("CACA_KEY_BACKSPACE", CACA_KEY_BACKSPACE, CONST_CS | CONST_PERSISTENT);
262        REGISTER_LONG_CONSTANT("CACA_KEY_TAB", CACA_KEY_TAB, CONST_CS | CONST_PERSISTENT);
263        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_J", CACA_KEY_CTRL_J, CONST_CS | CONST_PERSISTENT);
264        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_K", CACA_KEY_CTRL_K, CONST_CS | CONST_PERSISTENT);
265        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_L", CACA_KEY_CTRL_L, CONST_CS | CONST_PERSISTENT);
266        REGISTER_LONG_CONSTANT("CACA_KEY_RETURN", CACA_KEY_RETURN, CONST_CS | CONST_PERSISTENT);
267        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_N", CACA_KEY_CTRL_N, CONST_CS | CONST_PERSISTENT);
268        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_O", CACA_KEY_CTRL_O, CONST_CS | CONST_PERSISTENT);
269        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_P", CACA_KEY_CTRL_P, CONST_CS | CONST_PERSISTENT);
270        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_Q", CACA_KEY_CTRL_Q, CONST_CS | CONST_PERSISTENT);
271        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_R", CACA_KEY_CTRL_R, CONST_CS | CONST_PERSISTENT);
272        REGISTER_LONG_CONSTANT("CACA_KEY_PAUSE", CACA_KEY_PAUSE, CONST_CS | CONST_PERSISTENT);
273        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_T", CACA_KEY_CTRL_T, CONST_CS | CONST_PERSISTENT);
274        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_U", CACA_KEY_CTRL_U, CONST_CS | CONST_PERSISTENT);
275        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_V", CACA_KEY_CTRL_V, CONST_CS | CONST_PERSISTENT);
276        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_W", CACA_KEY_CTRL_W, CONST_CS | CONST_PERSISTENT);
277        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_X", CACA_KEY_CTRL_X, CONST_CS | CONST_PERSISTENT);
278        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_Y", CACA_KEY_CTRL_Y, CONST_CS | CONST_PERSISTENT);
279        REGISTER_LONG_CONSTANT("CACA_KEY_CTRL_Z", CACA_KEY_CTRL_Z, CONST_CS | CONST_PERSISTENT);
280        REGISTER_LONG_CONSTANT("CACA_KEY_ESCAPE", CACA_KEY_ESCAPE, CONST_CS | CONST_PERSISTENT);
281        REGISTER_LONG_CONSTANT("CACA_KEY_DELETE", CACA_KEY_DELETE, CONST_CS | CONST_PERSISTENT);
282        REGISTER_LONG_CONSTANT("CACA_KEY_UP", CACA_KEY_UP, CONST_CS | CONST_PERSISTENT);
283        REGISTER_LONG_CONSTANT("CACA_KEY_DOWN", CACA_KEY_DOWN, CONST_CS | CONST_PERSISTENT);
284        REGISTER_LONG_CONSTANT("CACA_KEY_LEFT", CACA_KEY_LEFT, CONST_CS | CONST_PERSISTENT);
285        REGISTER_LONG_CONSTANT("CACA_KEY_RIGHT", CACA_KEY_RIGHT, CONST_CS | CONST_PERSISTENT);
286        REGISTER_LONG_CONSTANT("CACA_KEY_INSERT", CACA_KEY_INSERT, CONST_CS | CONST_PERSISTENT);
287        REGISTER_LONG_CONSTANT("CACA_KEY_HOME", CACA_KEY_HOME, CONST_CS | CONST_PERSISTENT);
288        REGISTER_LONG_CONSTANT("CACA_KEY_END", CACA_KEY_END, CONST_CS | CONST_PERSISTENT);
289        REGISTER_LONG_CONSTANT("CACA_KEY_PAGEUP", CACA_KEY_PAGEUP, CONST_CS | CONST_PERSISTENT);
290        REGISTER_LONG_CONSTANT("CACA_KEY_PAGEDOWN", CACA_KEY_PAGEDOWN, CONST_CS | CONST_PERSISTENT);
291        REGISTER_LONG_CONSTANT("CACA_KEY_F1", CACA_KEY_F1, CONST_CS | CONST_PERSISTENT);
292        REGISTER_LONG_CONSTANT("CACA_KEY_F2", CACA_KEY_F2, CONST_CS | CONST_PERSISTENT);
293        REGISTER_LONG_CONSTANT("CACA_KEY_F3", CACA_KEY_F3, CONST_CS | CONST_PERSISTENT);
294        REGISTER_LONG_CONSTANT("CACA_KEY_F4", CACA_KEY_F4, CONST_CS | CONST_PERSISTENT);
295        REGISTER_LONG_CONSTANT("CACA_KEY_F5", CACA_KEY_F5, CONST_CS | CONST_PERSISTENT);
296        REGISTER_LONG_CONSTANT("CACA_KEY_F6", CACA_KEY_F6, CONST_CS | CONST_PERSISTENT);
297        REGISTER_LONG_CONSTANT("CACA_KEY_F7", CACA_KEY_F7, CONST_CS | CONST_PERSISTENT);
298        REGISTER_LONG_CONSTANT("CACA_KEY_F8", CACA_KEY_F8, CONST_CS | CONST_PERSISTENT);
299        REGISTER_LONG_CONSTANT("CACA_KEY_F9", CACA_KEY_F9, CONST_CS | CONST_PERSISTENT);
300        REGISTER_LONG_CONSTANT("CACA_KEY_F10", CACA_KEY_F10, CONST_CS | CONST_PERSISTENT);
301        REGISTER_LONG_CONSTANT("CACA_KEY_F11", CACA_KEY_F11, CONST_CS | CONST_PERSISTENT);
302        REGISTER_LONG_CONSTANT("CACA_KEY_F12", CACA_KEY_F12, CONST_CS | CONST_PERSISTENT);
303        REGISTER_LONG_CONSTANT("CACA_KEY_F13", CACA_KEY_F13, CONST_CS | CONST_PERSISTENT);
304        REGISTER_LONG_CONSTANT("CACA_KEY_F14", CACA_KEY_F14, CONST_CS | CONST_PERSISTENT);
305        REGISTER_LONG_CONSTANT("CACA_KEY_F15", CACA_KEY_F15, CONST_CS | CONST_PERSISTENT);
306
307        return SUCCESS;
308}
309
310//---------- Some usefull macros ---------------//
311
312#define FETCH_CANVAS(canvas) \
313        zval *_zval; \
314        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) { \
315                RETURN_FALSE; \
316        } \
317        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
318
319#define FETCH_DISPLAY(display) \
320        zval *_zval; \
321        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) { \
322                RETURN_FALSE; \
323        } \
324        ZEND_FETCH_RESOURCE(display, caca_display_t*, &_zval, -1, PHP_CACA_DISPLAY_RES_NAME, le_caca_display);
325
326#define FETCH_EVENT(event) \
327        zval *_zval; \
328        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) { \
329                RETURN_FALSE; \
330        } \
331        ZEND_FETCH_RESOURCE(event, caca_event_t*, &_zval, -1, PHP_CACA_EVENT_RES_NAME, le_caca_event);
332
333#define FETCH_LONG(l) \
334        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &l) == FAILURE) { \
335                RETURN_FALSE; \
336        }
337
338#define RETURN_CHAR(c) \
339        char *str = emalloc(2); \
340        str[0] = c; \
341        str[1] = '\0'; \
342        RETURN_STRING(str, 0);
343
344#define RETURN_SUCCESS(i) \
345        RETURN_BOOL((i) == 0);
346
347//---------- Some usefull functions --------------------//
348
349//Fetch external php resources such as gd resouces
350
351void *fetch_external_resource(zval *_zval, char const *type_name) {
352        int resource_id = _zval->value.lval;
353        int resource_type;
354        void *result = zend_list_find(resource_id, &resource_type);
355        if (!result)
356                return NULL;
357        char *resource_type_name = zend_rsrc_list_get_rsrc_type(resource_id);
358        return (strcmp(resource_type_name, type_name) == 0) ? result : NULL;
359}
360
361//Fetch buffer of pixels from gdImage
362
363void *gd_get_pixels(gdImage *img) {
364        void *result;
365        int j, pitch;           
366        if (img->trueColor)  {
367                pitch = img->sx * sizeof(int);
368                result = malloc(img->sy * pitch);
369                for (j = 0; j < img->sy; j++)
370                        memcpy(result + (j * pitch), (const void *) img->tpixels[j], pitch);
371        }
372        else {
373                pitch = img->sx * sizeof(char);
374                result = malloc(img->sy * pitch);
375                for (j = 0; j < img->sy; j++)
376                        memcpy(result + (j * pitch), (const void *) img->pixels[j], pitch);
377        }
378        return result;
379}
380
381int gd_load_palette(gdImage *img, caca_dither_t *dither) {
382        if (!img || img->trueColor || gdMaxColors != 256) {
383                return -1;
384        }
385
386        uint32_t r[256], g[256], b[256], a[256];
387        int i;
388        for (i = 0; i < 256; i++) {
389                r[i] = img->red[i] << 4;
390                g[i] = img->green[i] << 4;
391                b[i] = img->blue[i] << 4;
392                a[i] = img->alpha[i] << 4;
393        }
394
395        return caca_set_dither_palette(dither, &r[0], &g[0], &b[0], &a[0]);
396}
397
398//------- Caca's functions ----------------//
399
400PHP_FUNCTION(caca_create_canvas) {
401        long width, height = 0;
402        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &width, &height) == FAILURE) {
403                RETURN_FALSE;
404        }
405        caca_canvas_t *canvas = caca_create_canvas(width, height);
406        if (!canvas) {
407                RETURN_FALSE;
408        }
409        ZEND_REGISTER_RESOURCE(return_value, canvas, le_caca_canvas);
410}
411
412PHP_FUNCTION(caca_set_canvas_size) {
413        zval *_zval;
414        long width, height = 0;
415        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll", &_zval, &width, &height) == FAILURE) {
416                RETURN_FALSE;
417        }
418        caca_canvas_t *canvas;
419        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
420        RETURN_SUCCESS(caca_set_canvas_size(canvas, width, height));
421}
422
423PHP_FUNCTION(caca_get_canvas_width) {
424        caca_canvas_t *canvas;
425        FETCH_CANVAS(canvas);
426        RETURN_LONG(caca_get_canvas_width(canvas));
427}
428
429PHP_FUNCTION(caca_get_canvas_height) {
430        caca_canvas_t *canvas;
431        FETCH_CANVAS(canvas);
432        RETURN_LONG(caca_get_canvas_height(canvas));
433}
434
435PHP_FUNCTION(caca_get_canvas_chars) {
436        caca_canvas_t *canvas;
437        FETCH_CANVAS(canvas);
438        RETURN_STRING((char *) caca_get_canvas_chars(canvas), 1);
439}
440
441PHP_FUNCTION(caca_get_canvas_attrs) {
442        caca_canvas_t *canvas;
443        FETCH_CANVAS(canvas);
444        RETURN_STRING((char *) caca_get_canvas_attrs(canvas), 1);
445}
446
447PHP_FUNCTION(caca_rand) {
448        long min, max = 0;
449        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &min, &max) == FAILURE) {
450                RETURN_FALSE;
451        }
452        RETURN_LONG(caca_rand(min, max));
453}
454
455PHP_FUNCTION(caca_get_version) {
456        RETURN_STRING((char *) caca_get_version(), 1);
457}
458
459PHP_FUNCTION(caca_gotoxy) {
460        zval *_zval;
461        long x, y = 0;
462        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll", &_zval, &x, &y) == FAILURE) {
463                RETURN_FALSE;
464        }
465        caca_canvas_t *canvas;
466        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
467        RETURN_SUCCESS(caca_gotoxy(canvas, x, y));
468}
469
470PHP_FUNCTION(caca_get_cursor_x) {
471        caca_canvas_t *canvas;
472        FETCH_CANVAS(canvas);
473        RETURN_LONG(caca_get_cursor_x(canvas));
474}
475
476PHP_FUNCTION(caca_get_cursor_y) {
477        caca_canvas_t *canvas;
478        FETCH_CANVAS(canvas);
479        RETURN_LONG(caca_get_cursor_y(canvas));
480}
481
482PHP_FUNCTION(caca_put_char) {
483        zval *_zval;
484        long x, y, c;
485        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlll", &_zval, &x, &y, &c) == FAILURE) {
486                RETURN_FALSE;
487        }
488        caca_canvas_t *canvas;
489        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
490        RETURN_SUCCESS(caca_put_char(canvas, x, y, c));
491}
492
493PHP_FUNCTION(caca_get_char) {
494        zval *_zval;
495        long x, y = 0;
496        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll", &_zval, &x, &y) == FAILURE) {
497                RETURN_FALSE;
498        }
499        caca_canvas_t *canvas;
500        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
501        RETURN_CHAR(caca_get_char(canvas, x, y));
502}
503
504PHP_FUNCTION(caca_put_str) {
505        zval *_zval;
506        char *str;
507        long x, y, str_len = 0;
508        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlls", &_zval, &x, &y, &str, &str_len) == FAILURE) {
509                RETURN_FALSE;
510        }
511        caca_canvas_t *canvas;
512        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
513        RETURN_SUCCESS(caca_put_str(canvas, x, y, str));
514}
515
516PHP_FUNCTION(caca_clear_canvas) {
517        caca_canvas_t *canvas;
518        FETCH_CANVAS(canvas);
519        RETURN_LONG(caca_clear_canvas(canvas));
520}
521
522PHP_FUNCTION(caca_set_canvas_handle) {
523        zval *_zval;
524        long x, y = 0;
525        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll", &_zval, &x, &y) == FAILURE) {
526                RETURN_FALSE;
527        }
528        caca_canvas_t *canvas;
529        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
530        RETURN_SUCCESS(caca_set_canvas_handle(canvas, x, y));
531}
532
533PHP_FUNCTION(caca_get_canvas_handle_x) {
534        caca_canvas_t *canvas;
535        FETCH_CANVAS(canvas);
536        RETURN_LONG(caca_get_canvas_handle_x(canvas));
537}
538
539PHP_FUNCTION(caca_get_canvas_handle_y) {
540        caca_canvas_t *canvas;
541        FETCH_CANVAS(canvas);
542        RETURN_LONG(caca_get_canvas_handle_y(canvas));
543}
544
545PHP_FUNCTION(caca_blit) {
546        zval *_zval1, *_zval2, *_zval3 = NULL;
547        long x, y = 0;
548        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rllr|r", &_zval1, &x, &y, &_zval2, &_zval3) == FAILURE) {
549                RETURN_FALSE;
550        }
551        caca_canvas_t *dst, *src, *mask = NULL;
552        ZEND_FETCH_RESOURCE(dst, caca_canvas_t*, &_zval1, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
553        ZEND_FETCH_RESOURCE(src, caca_canvas_t*, &_zval2, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
554        if (_zval3) {
555                ZEND_FETCH_RESOURCE(mask, caca_canvas_t*, &_zval3, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
556        }
557        RETURN_SUCCESS(caca_blit(dst, x, y, src, NULL));
558}
559
560PHP_FUNCTION(caca_set_canvas_boundaries) {
561        zval *_zval;
562        long x, y, width, height = 0;
563        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rllll", &_zval, &x, &y, &width, &height) == FAILURE) {
564                RETURN_FALSE;
565        }
566        caca_canvas_t *canvas;
567        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
568        RETURN_SUCCESS(caca_set_canvas_boundaries(canvas, x, y, width, height));
569}
570
571PHP_FUNCTION(caca_invert) {
572        caca_canvas_t *canvas;
573        FETCH_CANVAS(canvas);
574        RETURN_SUCCESS(caca_invert(canvas));
575}
576
577PHP_FUNCTION(caca_flip) {
578        caca_canvas_t *canvas;
579        FETCH_CANVAS(canvas);
580        RETURN_SUCCESS(caca_flip(canvas));
581}
582
583PHP_FUNCTION(caca_flop) {
584        caca_canvas_t *canvas;
585        FETCH_CANVAS(canvas);
586        RETURN_SUCCESS(caca_flop(canvas));
587}
588
589PHP_FUNCTION(caca_rotate_180) {
590        caca_canvas_t *canvas;
591        FETCH_CANVAS(canvas);
592        RETURN_SUCCESS(caca_rotate_180(canvas));
593}
594
595PHP_FUNCTION(caca_rotate_left) {
596        caca_canvas_t *canvas;
597        FETCH_CANVAS(canvas);
598        RETURN_SUCCESS(caca_rotate_left(canvas));
599}
600
601PHP_FUNCTION(caca_rotate_right) {
602        caca_canvas_t *canvas;
603        FETCH_CANVAS(canvas);
604        RETURN_SUCCESS(caca_rotate_right(canvas));
605}
606
607PHP_FUNCTION(caca_stretch_left) {
608        caca_canvas_t *canvas;
609        FETCH_CANVAS(canvas);
610        RETURN_SUCCESS(caca_stretch_left(canvas));
611}
612
613PHP_FUNCTION(caca_stretch_right) {
614        caca_canvas_t *canvas;
615        FETCH_CANVAS(canvas);
616        RETURN_SUCCESS(caca_stretch_right(canvas));
617}
618
619PHP_FUNCTION(caca_get_attr) {
620        zval *_zval;
621        long x, y = 0;
622        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll", &_zval, &x, &y) == FAILURE) {
623                RETURN_FALSE;
624        }
625        caca_canvas_t *canvas;
626        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
627        RETURN_LONG(caca_get_attr(canvas, x, y));
628}
629
630PHP_FUNCTION(caca_set_attr) {
631        zval *_zval;
632        long attr = 0;
633        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll", &_zval, &attr) == FAILURE) {
634                RETURN_FALSE;
635        }
636        caca_canvas_t *canvas;
637        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
638        RETURN_SUCCESS(caca_set_attr(canvas, attr));
639}
640
641PHP_FUNCTION(caca_put_attr) {
642        zval *_zval;
643        long x, y, attr = 0;
644        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlll", &_zval, &x, &y, &attr) == FAILURE) {
645                RETURN_FALSE;
646        }
647        caca_canvas_t *canvas;
648        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
649        RETURN_SUCCESS(caca_put_attr(canvas, x, y, attr));
650}
651
652PHP_FUNCTION(caca_set_color_ansi) {
653        zval *_zval;
654        long foreground, background = 0;
655        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll", &_zval, &foreground, &background) == FAILURE) {
656                RETURN_FALSE;
657        }
658        caca_canvas_t *canvas;
659        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
660        RETURN_SUCCESS(caca_set_color_ansi(canvas, foreground, background));
661}
662
663PHP_FUNCTION(caca_set_color_argb) {
664        zval *_zval;
665        long foreground, background = 0;
666        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rll", &_zval, &foreground, &background) == FAILURE) {
667                RETURN_FALSE;
668        }
669        caca_canvas_t *canvas;
670        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
671        RETURN_SUCCESS(caca_set_color_argb(canvas, foreground, background));
672}
673
674PHP_FUNCTION(caca_attr_to_ansi) {
675        long l;
676        FETCH_LONG(l);
677        RETURN_LONG(caca_attr_to_ansi(l));
678}
679
680PHP_FUNCTION(caca_attr_to_ansi_fg) {
681        long l;
682        FETCH_LONG(l);
683        RETURN_LONG(caca_attr_to_ansi_fg(l));
684}
685
686PHP_FUNCTION(caca_attr_to_ansi_bg) {
687        long l;
688        FETCH_LONG(l);
689        RETURN_LONG(caca_attr_to_ansi_bg(l));
690}
691
692PHP_FUNCTION(caca_attr_to_rgb12_fg) {
693        long l;
694        FETCH_LONG(l);
695        RETURN_LONG(caca_attr_to_rgb12_fg(l));
696}
697
698PHP_FUNCTION(caca_attr_to_rgb12_bg) {
699        long l;
700        FETCH_LONG(l);
701        RETURN_LONG(caca_attr_to_rgb12_bg(l));
702}
703
704PHP_FUNCTION(caca_attr_to_argb64) {
705        //TODO: write or delete
706}
707
708PHP_FUNCTION(caca_utf8_to_utf32) {
709        //TODO: write or delete
710}
711
712PHP_FUNCTION(caca_utf32_to_utf8) {
713        //TODO: write or delete
714}
715
716PHP_FUNCTION(caca_utf32_to_cp437) {
717        long l;
718        FETCH_LONG(l);
719        RETURN_LONG(caca_utf32_to_cp437(l));
720}
721
722PHP_FUNCTION(caca_cp437_to_utf32) {
723        long l;
724        FETCH_LONG(l);
725        RETURN_LONG(caca_cp437_to_utf32(l));
726}
727
728PHP_FUNCTION(caca_utf32_to_ascii) {
729        long l;
730        FETCH_LONG(l);
731        RETURN_CHAR(caca_utf32_to_ascii(l));
732}
733
734PHP_FUNCTION(caca_utf32_is_fullwidth) {
735}
736
737PHP_FUNCTION(caca_draw_line) {
738        zval *_zval;
739        long xa, ya, xb, yb, c;
740        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlllll", &_zval, &xa, &ya, &xb, &yb, &c) == FAILURE) {
741                RETURN_FALSE;
742        }
743        caca_canvas_t *canvas;
744        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
745        RETURN_SUCCESS(caca_draw_line(canvas, xa, ya, xb, yb, c));
746}
747
748PHP_FUNCTION(caca_draw_polyline) {
749        zval *zval_res, *zval_arr;
750        long c;
751
752        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ral", &zval_res, &zval_arr, &c) == FAILURE) {
753                RETURN_FALSE;
754        }
755
756        caca_canvas_t *canvas;
757        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &zval_res, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
758
759        HashTable *arr_hash = Z_ARRVAL_P(zval_arr);
760        int lenmax = zend_hash_num_elements(arr_hash);
761        int *tbl_x, *tbl_y;
762        int tbl_count = 0;
763        tbl_x = malloc(sizeof(int) * lenmax);
764        tbl_y = malloc(sizeof(int) * lenmax);
765       
766        HashPosition pos;
767        zval **pt, **x, **y;
768        for (
769                zend_hash_internal_pointer_reset_ex(arr_hash, &pos);
770                zend_hash_get_current_data_ex(arr_hash, (void**) &pt, &pos) == SUCCESS;
771                zend_hash_move_forward_ex(arr_hash, &pos)
772        ) {
773                if (
774                        Z_TYPE_P(*pt) == IS_ARRAY
775                        && (zend_hash_index_find(Z_ARRVAL_P(*pt), 0, (void**) &x) != FAILURE)
776                        && (zend_hash_index_find(Z_ARRVAL_P(*pt), 1, (void**) &y) != FAILURE)
777                ) {
778                        convert_to_long_ex(x);
779                        convert_to_long_ex(y);
780                        tbl_x[tbl_count] = Z_LVAL_PP(x);
781                        tbl_y[tbl_count] = Z_LVAL_PP(y);
782                        tbl_count++;
783                }
784        }
785        int res = caca_draw_polyline(canvas, tbl_x, tbl_y, tbl_count - 1, c);
786        free(tbl_x);
787        free(tbl_y);
788        RETURN_SUCCESS(res);
789}
790
791PHP_FUNCTION(caca_draw_thin_line) {
792        zval *_zval;
793        long xa, ya, xb, yb = 0;
794        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rllll", &_zval, &xa, &ya, &xb, &yb) == FAILURE) {
795                RETURN_FALSE;
796        }
797        caca_canvas_t *canvas;
798        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
799        RETURN_SUCCESS(caca_draw_thin_line(canvas, xa, ya, xb, yb));
800}
801
802PHP_FUNCTION(caca_draw_thin_polyline) {
803        zval *zval_res, *zval_arr;
804        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra", &zval_res, &zval_arr) == FAILURE) {
805                RETURN_FALSE;
806        }
807
808        caca_canvas_t *canvas;
809        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &zval_res, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
810
811        HashTable *arr_hash = Z_ARRVAL_P(zval_arr);
812        int lenmax = zend_hash_num_elements(arr_hash);
813        int *tbl_x, *tbl_y;
814        int tbl_count = 0;
815        tbl_x = malloc(sizeof(int) * lenmax);
816        tbl_y = malloc(sizeof(int) * lenmax);
817
818        if (!tbl_x || !tbl_y) {
819                RETURN_FALSE;
820        }
821       
822        HashPosition pos;
823        zval **pt, **x, **y;
824        for (
825                zend_hash_internal_pointer_reset_ex(arr_hash, &pos);
826                zend_hash_get_current_data_ex(arr_hash, (void**) &pt, &pos) == SUCCESS;
827                zend_hash_move_forward_ex(arr_hash, &pos)
828        ) {
829                if (
830                        Z_TYPE_P(*pt) == IS_ARRAY
831                        && (zend_hash_index_find(Z_ARRVAL_P(*pt), 0, (void**) &x) != FAILURE)
832                        && (zend_hash_index_find(Z_ARRVAL_P(*pt), 1, (void**) &y) != FAILURE)
833                ) {
834                        convert_to_long_ex(x);
835                        convert_to_long_ex(y);
836                        tbl_x[tbl_count] = Z_LVAL_PP(x);
837                        tbl_y[tbl_count] = Z_LVAL_PP(y);
838                        tbl_count++;
839                }
840        }
841        int res = caca_draw_thin_polyline(canvas, tbl_x, tbl_y, tbl_count - 1);
842        free(tbl_x);
843        free(tbl_y);
844        RETURN_SUCCESS(res);
845}
846
847PHP_FUNCTION(caca_draw_circle) {
848        zval *_zval;
849        long x, y, r, c;
850        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rllll", &_zval, &x, &y, &r, &c) == FAILURE) {
851                RETURN_FALSE;
852        }
853        caca_canvas_t *canvas;
854        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
855        RETURN_SUCCESS(caca_draw_circle(canvas, x, y, r, c));
856}
857
858PHP_FUNCTION(caca_draw_ellipse) {
859        zval *_zval;
860        long xa, ya, xb, yb, c = 0;
861        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlllll", &_zval, &xa, &ya, &xb, &yb, &c) == FAILURE) {
862                RETURN_FALSE;
863        }
864        caca_canvas_t *canvas;
865        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
866        RETURN_SUCCESS(caca_draw_ellipse(canvas, xa, ya, xb, yb, c));
867}
868
869PHP_FUNCTION(caca_draw_thin_ellipse) {
870        zval *_zval;
871        long xa, ya, xb, yb = 0;
872        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rllll", &_zval, &xa, &ya, &xb, &yb) == FAILURE) {
873                RETURN_FALSE;
874        }
875        caca_canvas_t *canvas;
876        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
877        RETURN_SUCCESS(caca_draw_thin_ellipse(canvas, xa, ya, xb, yb));
878}
879
880PHP_FUNCTION(caca_fill_ellipse) {
881        zval *_zval;
882        long xa, ya, xb, yb, c;
883        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlllll", &_zval, &xa, &ya, &xb, &yb, &c) == FAILURE) {
884                RETURN_FALSE;
885        }
886        caca_canvas_t *canvas;
887        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
888        RETURN_SUCCESS(caca_fill_ellipse(canvas, xa, ya, xb, yb, c));
889}
890
891PHP_FUNCTION(caca_draw_box) {
892        zval *_zval;
893        long xa, ya, xb, yb, c;
894        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlllll", &_zval, &xa, &ya, &xb, &yb, &c) == FAILURE) {
895                RETURN_FALSE;
896        }
897        caca_canvas_t *canvas;
898        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
899        RETURN_SUCCESS(caca_draw_box(canvas, xa, ya, xb, yb, c));
900}
901
902PHP_FUNCTION(caca_draw_thin_box) {
903        zval *_zval;
904        long xa, ya, xb, yb = 0;
905        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rllll", &_zval, &xa, &ya, &xb, &yb) == FAILURE) {
906                RETURN_FALSE;
907        }
908        caca_canvas_t *canvas;
909        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
910        RETURN_SUCCESS(caca_draw_thin_box(canvas, xa, ya, xb, yb));
911}
912
913PHP_FUNCTION(caca_draw_cp437_box) {
914        zval *_zval;
915        long xa, ya, xb, yb;
916        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rllll", &_zval, &xa, &ya, &xb, &yb) == FAILURE) {
917                RETURN_FALSE;
918        }
919        caca_canvas_t *canvas;
920        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
921        RETURN_SUCCESS(caca_draw_cp437_box(canvas, xa, ya, xb, yb));
922}
923
924PHP_FUNCTION(caca_fill_box) {
925        zval *_zval;
926        long xa, ya, xb, yb, c;
927        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlllll", &_zval, &xa, &ya, &xb, &yb, &c) == FAILURE) {
928                RETURN_FALSE;
929        }
930        caca_canvas_t *canvas;
931        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
932        RETURN_SUCCESS(caca_fill_box(canvas, xa, ya, xb, yb, c));
933}
934
935PHP_FUNCTION(caca_draw_triangle) {
936        zval *_zval;
937        long xa, ya, xb, yb, xc, yc, c;
938        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlllllll", &_zval, &xa, &ya, &xb, &yb, &xc, &yc, &c) == FAILURE) {
939                RETURN_FALSE;
940        }
941        caca_canvas_t *canvas;
942        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
943        RETURN_SUCCESS(caca_draw_triangle(canvas, xa, ya, xb, yb, xc, yc, c));
944}
945
946PHP_FUNCTION(caca_draw_thin_triangle) {
947        zval *_zval;
948        long xa, ya, xb, yb, xc, yc = 0;
949        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rllllll", &_zval, &xa, &ya, &xb, &yb, &xc, &yc) == FAILURE) {
950                RETURN_FALSE;
951        }
952        caca_canvas_t *canvas;
953        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
954        RETURN_SUCCESS(caca_draw_thin_triangle(canvas, xa, ya, xb, yb, xc, yc));
955}
956
957PHP_FUNCTION(caca_fill_triangle) {
958        zval *_zval;
959        long xa, ya, xb, yb, xc, yc, c = 0;
960        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlllllll", &_zval, &xa, &ya, &xb, &yb, &xc, &yc, &c) == FAILURE) {
961                RETURN_FALSE;
962        }
963        caca_canvas_t *canvas;
964        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
965        RETURN_SUCCESS(caca_fill_triangle(canvas, xa, ya, xb, yb, xc, yc, c));
966}
967
968PHP_FUNCTION(caca_get_frame_count) {
969        zval *_zval;
970        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
971                RETURN_FALSE;
972        }
973        caca_canvas_t *canvas;
974        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
975        RETURN_LONG(caca_get_canvas_count(canvas));
976}
977
978PHP_FUNCTION(caca_set_frame) {
979        zval *_zval;
980        long id;
981        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &_zval, &id) == FAILURE) {
982                RETURN_FALSE;
983        }
984        caca_canvas_t *canvas;
985        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
986        RETURN_SUCCESS(caca_set_frame(canvas, id));
987}
988
989PHP_FUNCTION(caca_set_frame_name) {
990        zval *_zval;
991        char *str;
992        long str_len;
993        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &_zval, &str, &str_len) == FAILURE) {
994                RETURN_FALSE;
995        }
996        caca_canvas_t *canvas;
997        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
998        RETURN_SUCCESS(caca_set_frame_name(canvas, str));
999}
1000
1001PHP_FUNCTION(caca_create_frame) {
1002        zval *_zval;
1003        long id;
1004        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &_zval, &id) == FAILURE) {
1005                RETURN_FALSE;
1006        }
1007        caca_canvas_t *canvas;
1008        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
1009        RETURN_SUCCESS(caca_create_frame(canvas, id));
1010}
1011
1012PHP_FUNCTION(caca_free_frame) {
1013        zval *_zval;
1014        long id;
1015        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &_zval, &id) == FAILURE) {
1016                RETURN_FALSE;
1017        }
1018        caca_canvas_t *canvas;
1019        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
1020        RETURN_SUCCESS(caca_free_frame(canvas, id));
1021}
1022
1023PHP_FUNCTION(caca_create_dither) {
1024        zval *_zval;
1025        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1026                RETURN_FALSE;
1027        }
1028
1029        gdImage *img = fetch_external_resource(_zval, "gd");
1030        if (!img) {
1031                RETURN_FALSE;
1032        }
1033
1034        caca_dither_t *dither;
1035        if (img->trueColor)
1036                dither = caca_create_dither(sizeof(int) * 8, img->sx, img->sy, img->sx * sizeof(int), 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000);
1037        else
1038                dither = caca_create_dither(sizeof(char) * 8, img->sx, img->sy, img->sx * sizeof(char), 0, 0, 0, 0);
1039
1040        if (!dither) {
1041                RETURN_FALSE;
1042        }
1043
1044        ZEND_REGISTER_RESOURCE(return_value, dither, le_caca_dither);
1045}
1046
1047PHP_FUNCTION(caca_set_dither_palette) {
1048        zval *zval_res, *arr;
1049        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra", &zval_res, &arr) == FAILURE) {
1050                RETURN_FALSE;
1051        }
1052
1053        caca_dither_t *dither;
1054        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &zval_res, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_dither);
1055
1056        uint32_t tbl[4][256];
1057        zval **color, **value;
1058        int i, j;
1059        for (i = 0; i < 256; i++) {
1060                if (zend_hash_index_find(Z_ARRVAL_P(arr), i, (void**) &color) == FAILURE || Z_TYPE_P(*color) != IS_ARRAY) {
1061                        RETURN_FALSE;
1062                }
1063                for (j = 0; j < 4; j++) {
1064                        if (zend_hash_index_find(Z_ARRVAL_P(*color), j, (void**) &value) == FAILURE) {
1065                                RETURN_FALSE;
1066                        }
1067                        convert_to_long_ex(value);
1068                        tbl[j][i] = Z_LVAL_PP(value);
1069                }
1070        }
1071        RETURN_SUCCESS(caca_set_dither_palette(dither, tbl[0], tbl[1], tbl[2], tbl[3]));
1072}
1073
1074PHP_FUNCTION(caca_set_dither_brightness) {
1075        zval *_zval;
1076        double value;
1077        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rd", &_zval, &value) == FAILURE) {
1078                RETURN_FALSE;
1079        }
1080        caca_dither_t *dither;
1081        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1082        RETURN_SUCCESS(caca_set_dither_brightness(dither, value));
1083}
1084
1085PHP_FUNCTION(caca_get_dither_brightness) {
1086        zval *_zval;
1087        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1088                RETURN_FALSE;
1089        }
1090        caca_dither_t *dither;
1091        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1092        RETURN_DOUBLE(caca_get_dither_brightness(dither));
1093}
1094
1095PHP_FUNCTION(caca_set_dither_gamma) {
1096        zval *_zval;
1097        double value;
1098        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rd", &_zval, &value) == FAILURE) {
1099                RETURN_FALSE;
1100        }
1101        caca_dither_t *dither;
1102        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1103        RETURN_SUCCESS(caca_set_dither_gamma(dither, value));
1104}
1105
1106PHP_FUNCTION(caca_get_dither_gamma) {
1107        zval *_zval;
1108        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1109                RETURN_FALSE;
1110        }
1111        caca_dither_t *dither;
1112        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1113        RETURN_DOUBLE(caca_get_dither_gamma(dither));
1114}
1115
1116PHP_FUNCTION(caca_set_dither_contrast) {
1117        zval *_zval;
1118        double value;
1119        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rd", &_zval, &value) == FAILURE) {
1120                RETURN_FALSE;
1121        }
1122        caca_dither_t *dither;
1123        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1124        RETURN_SUCCESS(caca_set_dither_contrast(dither, value));
1125}
1126
1127PHP_FUNCTION(caca_get_dither_contrast) {
1128        zval *_zval;
1129        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1130                RETURN_FALSE;
1131        }
1132        caca_dither_t *dither;
1133        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1134        RETURN_DOUBLE(caca_get_dither_contrast(dither));
1135}
1136
1137PHP_FUNCTION(caca_set_dither_antialias) {
1138        zval *_zval;
1139        int str_len;
1140        char *str;
1141        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &_zval, &str, &str_len) == FAILURE) {
1142                RETURN_FALSE;
1143        }
1144        caca_dither_t *dither;
1145        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1146        RETURN_SUCCESS(caca_set_dither_antialias(dither, str));
1147}
1148
1149PHP_FUNCTION(caca_get_dither_antialias_list) {
1150        zval *_zval;
1151        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1152                RETURN_FALSE;
1153        }
1154        caca_dither_t *dither;
1155        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1156
1157        char const * const *list = caca_get_dither_antialias_list(dither);
1158        int i;
1159        array_init(return_value);       
1160        for(i = 0; list[i]; i += 1)
1161                add_next_index_string(return_value, (char*) list[i], 1);
1162}
1163
1164PHP_FUNCTION(caca_get_dither_antialias) {
1165        zval *_zval;
1166        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1167                RETURN_FALSE;
1168        }
1169        caca_dither_t *dither;
1170        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1171        RETURN_STRING((char *) caca_get_dither_antialias(dither), 1);
1172}
1173
1174PHP_FUNCTION(caca_set_dither_color) {
1175        zval *_zval;
1176        int str_len;
1177        char *str;
1178        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &_zval, &str, &str_len) == FAILURE) {
1179                RETURN_FALSE;
1180        }
1181        caca_dither_t *dither;
1182        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1183        RETURN_SUCCESS(caca_set_dither_color(dither, str));
1184}
1185
1186PHP_FUNCTION(caca_get_dither_color_list) {
1187        zval *_zval;
1188        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1189                RETURN_FALSE;
1190        }
1191        caca_dither_t *dither;
1192        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1193
1194        char const * const *list = caca_get_dither_antialias_list(dither);
1195        int i;
1196        array_init(return_value);       
1197        for(i = 0; list[i]; i += 2)
1198                add_assoc_string(return_value, (char*) list[i], (char*) list[i + 1], 1);
1199}
1200
1201PHP_FUNCTION(caca_get_dither_color) {
1202        zval *_zval;
1203        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1204                RETURN_FALSE;
1205        }
1206        caca_dither_t *dither;
1207        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1208        RETURN_STRING((char *) caca_get_dither_color(dither), 1);
1209}
1210
1211PHP_FUNCTION(caca_set_dither_charset) {
1212        zval *_zval;
1213        int str_len;
1214        char *str;
1215        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &_zval, &str, &str_len) == FAILURE) {
1216                RETURN_FALSE;
1217        }
1218        caca_dither_t *dither;
1219        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1220        RETURN_SUCCESS(caca_set_dither_charset(dither, str));
1221}
1222
1223PHP_FUNCTION(caca_get_dither_charset_list) {
1224        zval *_zval;
1225        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1226                RETURN_FALSE;
1227        }
1228        caca_dither_t *dither;
1229        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1230
1231        char const * const *list = caca_get_dither_charset_list(dither);
1232        int i;
1233        array_init(return_value);       
1234        for(i = 0; list[i]; i += 2)
1235                add_assoc_string(return_value, (char*) list[i], (char*) list[i + 1], 1);
1236}
1237
1238PHP_FUNCTION(caca_get_dither_charset) {
1239        zval *_zval;
1240        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1241                RETURN_FALSE;
1242        }
1243        caca_dither_t *dither;
1244        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1245        RETURN_STRING((char *) caca_get_dither_charset(dither), 1);
1246}
1247
1248PHP_FUNCTION(caca_set_dither_algorithm) {
1249        zval *_zval;
1250        int str_len;
1251        char *str;
1252        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &_zval, &str, &str_len) == FAILURE) {
1253                RETURN_FALSE;
1254        }
1255        caca_dither_t *dither;
1256        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1257        RETURN_SUCCESS(caca_set_dither_algorithm(dither, str));
1258}
1259
1260PHP_FUNCTION(caca_get_dither_algorithm_list) {
1261        zval *_zval;
1262        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1263                RETURN_FALSE;
1264        }
1265        caca_dither_t *dither;
1266        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1267
1268        char const * const *list = caca_get_dither_algorithm_list(dither);
1269        int i;
1270        array_init(return_value);       
1271        for(i = 0; list[i]; i += 2)
1272                add_assoc_string(return_value, (char*) list[i], (char*) list[i + 1], 1);
1273}
1274
1275PHP_FUNCTION(caca_get_dither_algorithm) {
1276        zval *_zval;
1277        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1278                RETURN_FALSE;
1279        }
1280        caca_dither_t *dither;
1281        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1282        RETURN_STRING((char *) caca_get_dither_algorithm(dither), 1);
1283}
1284
1285PHP_FUNCTION(caca_dither_bitmap) {
1286        zval *_zval1, *_zval2, *_zval3;
1287        long x, y, w, h = 0;
1288        zend_bool load_palette = 1;
1289        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rllllrr|b", &_zval1, &x, &y, &w, &h, &_zval2, &_zval3, &load_palette) == FAILURE) {
1290                RETURN_FALSE;
1291        }
1292
1293        caca_canvas_t *canvas;
1294        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval1, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
1295        caca_dither_t *dither;
1296        ZEND_FETCH_RESOURCE(dither, caca_dither_t*, &_zval2, -1, PHP_CACA_DITHER_RES_NAME, le_caca_dither);
1297
1298        gdImage *img = fetch_external_resource(_zval3, "gd");
1299        if (!img) {
1300                RETURN_FALSE;
1301        }
1302
1303        void *pixels = gd_get_pixels(img);
1304        if (!pixels) {
1305                RETURN_FALSE;
1306        }
1307
1308        //load palette if image is not true color
1309        if (load_palette && !img->trueColor && gd_load_palette(img, dither) != 0) {
1310                RETURN_FALSE;
1311        }
1312
1313        caca_dither_bitmap(canvas, x, y, w, h, dither, pixels);
1314        free(pixels);
1315        RETURN_TRUE;
1316}
1317
1318PHP_FUNCTION(caca_load_font) {
1319        char *str;
1320        long str_len;
1321        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
1322                RETURN_FALSE;
1323        }
1324        caca_font_t *font = caca_load_font(str, str_len);
1325        if (!font) {
1326                RETURN_FALSE;
1327        }
1328        ZEND_REGISTER_RESOURCE(return_value, font, le_caca_font);
1329}
1330
1331PHP_FUNCTION(caca_load_builtin_font) {
1332        char *str;
1333        long str_len;
1334        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
1335                RETURN_FALSE;
1336        }
1337        caca_font_t *font = caca_load_font(str, 0);
1338        if (!font) {
1339                RETURN_FALSE;
1340        }
1341        ZEND_REGISTER_RESOURCE(return_value, font, le_caca_font);
1342}
1343
1344PHP_FUNCTION(caca_get_font_list) {
1345        char const * const *list = caca_get_font_list();
1346        int i;
1347        array_init(return_value);       
1348        for(i = 0; list[i]; i += 1)
1349                add_next_index_string(return_value, (char*) list[i], 1);
1350}
1351
1352PHP_FUNCTION(caca_get_font_width) {
1353        zval *_zval;
1354        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1355                RETURN_FALSE;
1356        }
1357        caca_font_t *font;
1358        ZEND_FETCH_RESOURCE(font, caca_font_t*, &_zval, -1, PHP_CACA_FONT_RES_NAME, le_caca_font);
1359        RETURN_LONG(caca_get_font_width(font));
1360}
1361
1362PHP_FUNCTION(caca_get_font_height) {
1363        zval *_zval;
1364        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1365                RETURN_FALSE;
1366        }
1367        caca_font_t *font;
1368        ZEND_FETCH_RESOURCE(font, caca_font_t*, &_zval, -1, PHP_CACA_FONT_RES_NAME, le_caca_font);
1369        RETURN_LONG(caca_get_font_height(font));
1370}
1371
1372PHP_FUNCTION(caca_get_font_blocks) {
1373        zval *_zval;
1374        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1375                RETURN_FALSE;
1376        }
1377        caca_font_t *font;
1378        ZEND_FETCH_RESOURCE(font, caca_font_t*, &_zval, -1, PHP_CACA_FONT_RES_NAME, le_caca_font);
1379
1380        uint32_t const *list = caca_get_font_blocks(font);
1381
1382        int i;
1383        array_init(return_value);       
1384        for(i = 0; list[i]; i += 1)
1385                add_next_index_long(return_value, list[i]);
1386}
1387
1388PHP_FUNCTION(caca_render_canvas) {
1389        zval *_zval1, *_zval2, *_zval3;
1390        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rrr", &_zval1, &_zval2, &_zval3) == FAILURE) {
1391                RETURN_FALSE;
1392        }
1393        caca_canvas_t *canvas;
1394        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval1, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
1395        caca_font_t *font;
1396        ZEND_FETCH_RESOURCE(font, caca_font_t*, &_zval2, -1, PHP_CACA_FONT_RES_NAME, le_caca_font);
1397
1398        gdImage *img = fetch_external_resource(_zval3, "gd");
1399        if (!img || !img->trueColor) {
1400                RETURN_FALSE;
1401        }
1402
1403        int pitch = img->sx * sizeof(int);
1404        void *buffer = malloc(pitch * img->sy);
1405        if (!buffer) {
1406                RETURN_FALSE;
1407        }
1408
1409        caca_render_canvas(canvas, font, buffer, img->sx, img->sy, pitch);
1410        int i;
1411        for (i = 0; i < img->sy; i++)
1412                memcpy(img->tpixels[i], buffer + (i * pitch), pitch);
1413       
1414        //TODO: fix colors order
1415        free(buffer);
1416        RETURN_TRUE;
1417}
1418
1419PHP_FUNCTION(caca_canvas_set_figfont) {
1420        zval *_zval;
1421        char *font;
1422        long font_len;
1423        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &_zval, &font, &font_len) == FAILURE) {
1424                RETURN_FALSE;
1425        }
1426        caca_canvas_t *canvas;
1427        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
1428        RETURN_SUCCESS(caca_canvas_set_figfont(canvas, font));
1429}
1430
1431PHP_FUNCTION(caca_put_figchar) {
1432        zval *_zval;
1433        long c;
1434        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &_zval, &c) == FAILURE) {
1435                RETURN_FALSE;
1436        }
1437        caca_canvas_t *canvas;
1438        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
1439
1440        RETURN_SUCCESS(caca_put_figchar(canvas, c));
1441}
1442
1443PHP_FUNCTION(caca_flush_figlet) {
1444        zval *_zval;
1445        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1446                RETURN_FALSE;
1447        }
1448        caca_canvas_t *canvas;
1449        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
1450        RETURN_SUCCESS(caca_flush_figlet(canvas));
1451}
1452
1453PHP_FUNCTION(caca_file_open) {
1454        char *path, *mode;
1455        long path_len, mode_len;
1456        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &path, &path_len, &mode, &mode_len) == FAILURE) {
1457                RETURN_FALSE;
1458        }
1459        caca_file_t *file = caca_file_open(path, mode);
1460        if (!file) {
1461                RETURN_FALSE;
1462        }
1463        ZEND_REGISTER_RESOURCE(return_value, file, le_caca_file);
1464}
1465
1466PHP_FUNCTION(caca_file_close) {
1467        zval *_zval;
1468        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1469                RETURN_FALSE;
1470        }
1471        caca_file_t *file;
1472        ZEND_FETCH_RESOURCE(file, caca_file_t*, &_zval, -1, PHP_CACA_FILE_RES_NAME, le_caca_file);
1473        //TODO: check that file was not already closed
1474        RETURN_SUCCESS(caca_file_close(file));
1475}
1476
1477PHP_FUNCTION(caca_file_tell) {
1478        zval *_zval;
1479        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1480                RETURN_FALSE;
1481        }
1482        caca_file_t *file;
1483        ZEND_FETCH_RESOURCE(file, caca_file_t*, &_zval, -1, PHP_CACA_FILE_RES_NAME, le_caca_file);
1484        RETURN_LONG(caca_file_tell(file));
1485}
1486
1487PHP_FUNCTION(caca_file_read) {
1488        zval *_zval;
1489        long len;
1490        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &_zval, &len) == FAILURE) {
1491                RETURN_FALSE;
1492        }
1493        caca_file_t *file;
1494        ZEND_FETCH_RESOURCE(file, caca_file_t*, &_zval, -1, PHP_CACA_FILE_RES_NAME, le_caca_file);
1495
1496        if (len < 1) {
1497                RETURN_FALSE;
1498        }
1499        char *buffer = emalloc(len);
1500        if (!buffer) {
1501                RETURN_FALSE;
1502        }
1503        caca_file_read(file, buffer, len);
1504
1505        return_value->type = IS_STRING;
1506        return_value->value.str.len = len;
1507        return_value->value.str.val = buffer;
1508}
1509
1510PHP_FUNCTION(caca_file_write) {
1511        zval *_zval;
1512        char *buf;
1513        long buf_len = 0;
1514        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &_zval, &buf, &buf_len) == FAILURE) {
1515                RETURN_FALSE;
1516        }
1517        caca_file_t *file;
1518        ZEND_FETCH_RESOURCE(file, caca_file_t*, &_zval, -1, PHP_CACA_FILE_RES_NAME, le_caca_file);
1519        RETURN_LONG(caca_file_write(file, buf, buf_len));
1520}
1521
1522PHP_FUNCTION(caca_file_gets) {
1523        zval *_zval;
1524        long len = 0;
1525        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &_zval, &len) == FAILURE) {
1526                RETURN_FALSE;
1527        }
1528        caca_file_t *file;
1529        ZEND_FETCH_RESOURCE(file, caca_file_t*, &_zval, -1, PHP_CACA_FILE_RES_NAME, le_caca_file);
1530
1531        if (len < 1) {
1532                RETURN_FALSE;
1533        }
1534        char *buffer = emalloc(len);
1535        if (!buffer) {
1536                RETURN_FALSE;
1537        }
1538        char *result = caca_file_gets(file, buffer, len);
1539        if (!result) {
1540                RETURN_FALSE;
1541        }
1542        return_value->type = IS_STRING;
1543        return_value->value.str.len = len;
1544        return_value->value.str.val = result;
1545}
1546
1547PHP_FUNCTION(caca_file_eof) {
1548        zval *_zval;
1549        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1550                RETURN_FALSE;
1551        }
1552        caca_file_t *file;
1553        ZEND_FETCH_RESOURCE(file, caca_file_t*, &_zval, -1, PHP_CACA_FILE_RES_NAME, le_caca_file);
1554        RETURN_BOOL(caca_file_eof(file) != 0);
1555}
1556
1557PHP_FUNCTION(caca_import_string) {
1558        zval *_zval;
1559        char *src, *format;
1560        long src_len, format_len = 0;
1561        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &_zval, &src, &src_len, &format, &format_len) == FAILURE) {
1562                RETURN_FALSE;
1563        }
1564        caca_canvas_t *canvas;
1565        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
1566
1567        RETURN_LONG(caca_import_memory(canvas, src, src_len, format));
1568}
1569
1570PHP_FUNCTION(caca_import_file) {
1571        zval *_zval;
1572        char *filename, *format;
1573        long filename_len, format_len = 0;
1574        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &_zval, &filename, &filename_len, &format, &format_len) == FAILURE) {
1575                RETURN_FALSE;
1576        }
1577        caca_canvas_t *canvas;
1578        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
1579
1580        RETURN_LONG(caca_import_file(canvas, filename, format));
1581}
1582
1583PHP_FUNCTION(caca_get_import_list) {
1584        char const * const *list = caca_get_import_list();
1585        int i;
1586        array_init(return_value);       
1587        for(i = 0; list[i]; i += 2)
1588                add_assoc_string(return_value, (char*) list[i], (char*) list[i + 1], 1);
1589}
1590
1591PHP_FUNCTION(caca_export_string) {
1592        zval *_zval;
1593        char *type;
1594        long type_len;
1595        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &_zval, &type, &type_len) == FAILURE) {
1596                RETURN_FALSE;
1597        }
1598        caca_canvas_t *canvas;
1599        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
1600
1601        void *buffer, *copy;
1602        size_t len;
1603        buffer = caca_export_memory(canvas, type, &len);
1604        copy = emalloc(len);
1605        if (!buffer || !copy) {
1606                RETURN_FALSE;
1607        }
1608        memcpy(copy, buffer, len);
1609        free(buffer);
1610
1611        return_value->type = IS_STRING;
1612        return_value->value.str.len = len;
1613        return_value->value.str.val = copy;
1614}
1615
1616PHP_FUNCTION(caca_get_export_list) {
1617        char const * const *list = caca_get_export_list();
1618        int i;
1619        array_init(return_value);       
1620        for(i = 0; list[i]; i += 2)
1621                add_assoc_string(return_value, (char*) list[i], (char*) list[i + 1], 1);
1622}
1623
1624PHP_FUNCTION(caca_create_display) {
1625        caca_canvas_t *canvas;
1626        FETCH_CANVAS(canvas);
1627
1628        caca_display_t *display = caca_create_display(canvas);
1629        if (!display) {
1630                RETURN_FALSE;
1631        }
1632        ZEND_REGISTER_RESOURCE(return_value, display, le_caca_display);
1633}
1634
1635PHP_FUNCTION(caca_create_display_with_driver) {
1636        zval *_zval;
1637        char *str;
1638        long str_len = 0;
1639        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &_zval, &str, &str_len) == FAILURE) {
1640                RETURN_FALSE;
1641        }
1642        caca_canvas_t *canvas;
1643        ZEND_FETCH_RESOURCE(canvas, caca_canvas_t*, &_zval, -1, PHP_CACA_CANVAS_RES_NAME, le_caca_canvas);
1644
1645        caca_display_t *display = caca_create_display_with_driver(canvas, str);
1646        if (!display) {
1647                RETURN_FALSE;
1648        }
1649        ZEND_REGISTER_RESOURCE(return_value, display, le_caca_display);
1650}
1651
1652PHP_FUNCTION(caca_get_display_driver_list) {
1653        char const * const *list = caca_get_display_driver_list();
1654        int i;
1655        array_init(return_value);       
1656        for(i = 0; list[i]; i += 2)
1657                add_assoc_string(return_value, (char*) list[i], (char*) list[i + 1], 1);
1658}
1659
1660PHP_FUNCTION(caca_get_display_driver) {
1661        zval *_zval;
1662        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1663                RETURN_FALSE;
1664        }
1665        caca_display_t *display;
1666        ZEND_FETCH_RESOURCE(display, caca_display_t*, &_zval, -1, PHP_CACA_DISPLAY_RES_NAME, le_caca_display);
1667        RETURN_STRING((char *) caca_get_display_driver(display), 1);
1668}
1669
1670PHP_FUNCTION(caca_set_display_driver) {
1671        zval *_zval;
1672        char *str;
1673        long str_len;
1674        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &_zval, &str, &str_len) == FAILURE) {
1675                RETURN_FALSE;
1676        }
1677        caca_display_t *display;
1678        ZEND_FETCH_RESOURCE(display, caca_display_t*, &_zval, -1, PHP_CACA_DISPLAY_RES_NAME, le_caca_display);
1679        RETURN_SUCESS(caca_set_display_driver(display, str));
1680}
1681
1682PHP_FUNCTION(caca_get_canvas) {
1683        zval *_zval;
1684        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &_zval) == FAILURE) {
1685                RETURN_FALSE;
1686        }
1687        caca_display_t *display;
1688        ZEND_FETCH_RESOURCE(display, caca_display_t*, &_zval, -1, PHP_CACA_DISPLAY_RES_NAME, le_caca_display);
1689        caca_canvas_t *canvas = caca_get_canvas(display);
1690        if (!canvas) {
1691                RETURN_FALSE;
1692        }
1693        ZEND_REGISTER_RESOURCE(return_value, canvas, le_caca_canvas);
1694}
1695
1696PHP_FUNCTION(caca_refresh_display) {
1697        caca_display_t *display;
1698        FETCH_DISPLAY(display);
1699        RETURN_SUCCESS(caca_refresh_display(display));
1700}
1701
1702PHP_FUNCTION(caca_set_display_time) {
1703        zval *_zval;
1704        long value = 0;
1705        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &_zval, &value) == FAILURE) {
1706                RETURN_FALSE;
1707        }
1708        caca_display_t *display;
1709        ZEND_FETCH_RESOURCE(display, caca_display_t*, &_zval, -1, PHP_CACA_DISPLAY_RES_NAME, le_caca_display);
1710        RETURN_SUCCESS(caca_set_display_time(display, value));
1711}
1712
1713PHP_FUNCTION(caca_get_display_time) {
1714        caca_display_t *display;
1715        FETCH_DISPLAY(display);
1716        RETURN_LONG(caca_get_display_time(display));
1717}
1718
1719PHP_FUNCTION(caca_get_display_width) {
1720        caca_display_t *display;
1721        FETCH_DISPLAY(display);
1722        RETURN_LONG(caca_get_display_width(display));
1723}
1724
1725PHP_FUNCTION(caca_get_display_height) {
1726        caca_display_t *display;
1727        FETCH_DISPLAY(display);
1728        RETURN_LONG(caca_get_display_height(display));
1729}
1730
1731PHP_FUNCTION(caca_set_display_title) {
1732        zval *_zval;
1733        char *str;
1734        long str_len = 0;
1735        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &_zval, &str, &str_len) == FAILURE) {
1736                RETURN_FALSE;
1737        }
1738        caca_display_t *display;
1739        ZEND_FETCH_RESOURCE(display, caca_display_t*, &_zval, -1, PHP_CACA_DISPLAY_RES_NAME, le_caca_display);
1740        RETURN_SUCCESS(caca_set_display(display, str));
1741}
1742
1743PHP_FUNCTION(caca_set_mouse) {
1744        zval *_zval;
1745        long value = 0;
1746        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &_zval, &value) == FAILURE) {
1747                RETURN_FALSE;
1748        }
1749        caca_display_t *display;
1750        ZEND_FETCH_RESOURCE(display, caca_display_t*, &_zval, -1, PHP_CACA_DISPLAY_RES_NAME, le_caca_display);
1751        RETURN_SUCCESS(caca_set_mouse(display, value));
1752}
1753
1754PHP_FUNCTION(caca_set_cursor) {
1755        zval *_zval;
1756        long value = 0;
1757        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &_zval, &value) == FAILURE) {
1758                RETURN_FALSE;
1759        }
1760        caca_display_t *display;
1761        ZEND_FETCH_RESOURCE(display, caca_display_t*, &_zval, -1, PHP_CACA_DISPLAY_RES_NAME, le_caca_display);
1762        RETURN_SUCCESS(caca_set_cursor(display, value));
1763}
1764
1765PHP_FUNCTION(caca_get_event) {
1766        zval *_zval = NULL;
1767        long g, aa = 0;
1768        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|l", &_zval, &g, &aa) == FAILURE) {
1769                RETURN_FALSE;
1770        }
1771        caca_display_t *display;
1772        ZEND_FETCH_RESOURCE(display, caca_display_t*, &_zval, -1, PHP_CACA_DISPLAY_RES_NAME, le_caca_display);
1773
1774        caca_event_t *event = emalloc(sizeof(caca_event_t));
1775        if (!event) {
1776                RETURN_FALSE;
1777        }
1778
1779        caca_get_event(display, g, event, aa);
1780
1781        if (caca_get_event_type(event) == CACA_EVENT_NONE) {
1782                efree(event);   
1783                RETURN_FALSE;
1784        }
1785        ZEND_REGISTER_RESOURCE(return_value, event, le_caca_event);
1786}
1787
1788PHP_FUNCTION(caca_get_mouse_x) {
1789        caca_display_t *display;
1790        FETCH_DISPLAY(display);
1791        RETURN_LONG(caca_get_mouse_x(display));
1792}
1793
1794PHP_FUNCTION(caca_get_mouse_y) {
1795        caca_display_t *display;
1796        FETCH_DISPLAY(display);
1797        RETURN_LONG(caca_get_mouse_y(display));
1798}
1799
1800PHP_FUNCTION(caca_get_event_type) {
1801        caca_event_t *event;
1802        FETCH_EVENT(event);
1803        RETURN_LONG(caca_get_event_type(event));
1804}
1805
1806PHP_FUNCTION(caca_get_event_key_ch) {
1807        caca_event_t *event;
1808        FETCH_EVENT(event);
1809        RETURN_LONG(caca_get_event_key_ch(event));
1810}
1811
1812PHP_FUNCTION(caca_get_event_mouse_button) {
1813        caca_event_t *event;
1814        FETCH_EVENT(event);
1815        RETURN_LONG(caca_get_event_mouse_button(event));
1816}
1817
1818PHP_FUNCTION(caca_get_event_mouse_x) {
1819        caca_event_t *event;
1820        FETCH_EVENT(event);
1821        RETURN_LONG(caca_get_event_mouse_x(event));
1822}
1823
1824PHP_FUNCTION(caca_get_event_mouse_y) {
1825        caca_event_t *event;
1826        FETCH_EVENT(event);
1827        RETURN_LONG(caca_get_event_mouse_y(event));
1828}
1829
1830PHP_FUNCTION(caca_get_event_resize_width) {
1831        caca_event_t *event;
1832        FETCH_EVENT(event);
1833        RETURN_LONG(caca_get_event_resize_width(event));
1834}
1835
1836PHP_FUNCTION(caca_get_event_resize_height) {
1837        caca_event_t *event;
1838        FETCH_EVENT(event);
1839        RETURN_LONG(caca_get_event_resize_height(event));
1840}
1841
Note: See TracBrowser for help on using the repository browser.